Sarıkaya Dev Logo

Build AI‑Powered RAG Apps with Laravel 11, LangChain PHP, and Pinecone

Mahmut Sarıkaya 5 min read 1 Views 0
Build AI‑Powered RAG Apps with Laravel 11, LangChain PHP, and Pinecone

Why RAG matters for modern Laravel apps

Imagine a user typing a vague query like "best practices for secure file uploads" and instantly receiving a curated answer drawn from your own documentation, code snippets, and support tickets. Retrieval‑Augmented Generation (RAG) makes that possible by combining a vector store with a large language model (LLM). In Laravel 11 projects, RAG can turn static help pages into an interactive, AI‑powered search that scales with your data.

System requirements and Laravel 11 setup

Before writing any code, confirm that your server runs PHP 8.2 or newer, Composer 2.5+, and has at least 4 GB of RAM for local LLM inference (if you host a model). Create a fresh Laravel 11 installation with the usual command:

composer create-project laravel/laravel ragnative "11.*"

After the project scaffolds, configure your .env file with a database connection (MySQL 8.0 recommended) and a cache driver like Redis, which speeds up vector look‑ups.

Adding LangChain PHP to the mix

LangChain PHP provides a fluent API for chaining LLM calls, document loaders, and retrievers. Install the package alongside the Pinecone SDK:

composer require langchain/langchain-php pinecone/pinecone-php

Next, publish the configuration files so you can store API keys safely:

php artisan vendor:publish --provider="LangChain\ServiceProvider"

Open config/langchain.php and set 'openai_key' to your OpenAI secret. The same file holds the Pinecone 'api_key' and 'environment' values.

Connecting Laravel to Pinecone vector database

Pinecone stores high‑dimensional embeddings and offers a RESTful search API. Create a dedicated index for your knowledge base. From the Pinecone console, define an index named laravel‑rag with a dimension of 1536 (the size of OpenAI text‑embedding‑ada‑002).

In Laravel, wrap the SDK in a service class:

namespace App\Services; use Pinecone\Client; class PineconeService { protected $client; public function __construct() { $this->client = new Client([ 'apiKey' => config('langchain.pinecone.api_key'), 'environment' => config('langchain.pinecone.environment'), ]); } public function upsert(array $vectors, string $index = 'laravel‑rag') { return $this->client->index($index)->upsert($vectors); } public function query(string $vector, int $topK = 5, string $index = 'laravel‑rag') { return $this->client->index($index)->query([ 'vector' => $vector, 'topK' => $topK, ]); } }

This service lets you push embeddings and retrieve the nearest neighbours with a single method call.

Preparing documents and generating embeddings

Laravel developers often keep guides in markdown files under resources/docs. Load them with a simple helper, then feed each chunk to OpenAI’s embedding endpoint.

use OpenAI\Client as OpenAIClient; use App\Services\PineconeService; class DocumentIndexer { protected $openai; protected $pinecone; public function __construct(OpenAIClient $openai, PineconeService $pinecone) { $this->openai = $openai; $this->pinecone = $pinecone; } public function indexAll() { $files = glob(resource_path('docs/*.md')); foreach ($files as $file) { $content = file_get_contents($file); $chunks = str_split($content, 1000); foreach ($chunks as $i => $chunk) { $embedding = $this->openai->embeddings()->create([ 'model' => 'text-embedding-ada-002', 'input' => $chunk, ])[0]->embedding; $vector = [ 'id' => basename($file)."_{$i}", 'values' => $embedding, 'metadata' => [ 'source' => $file, 'chunk' => $i, ], ]; $this->pinecone->upsert([$vector]); } } } }

Run php artisan tinker and execute (new App\Services\DocumentIndexer(app(OpenAI\Client::class), app(App\Services\PineconeService::class)))->indexAll(); to populate the index. The process usually finishes within a few minutes for a 5 MB documentation set.

Building the RAG chain inside Laravel

Now that embeddings live in Pinecone, combine them with an LLM to answer user questions. LangChain’s RetrieverChain abstracts the pattern:

use LangChain\Chains\RetrieverChain; use LangChain\LLMs\OpenAI; use App\Services\PineconeService; class RagService { protected $llm; protected $pinecone; public function __construct(OpenAI $llm, PineconeService $pinecone) { $this->llm = $llm; $this->pinecone = $pinecone; } public function answer(string $question): string { // 1. Convert question to embedding $qEmbedding = $this->llm->embeddings()->create([ 'model' => 'text-embedding-ada-002', 'input' => $question, ])[0]->embedding; // 2. Retrieve top 3 relevant chunks $results = $this->pinecone->query($qEmbedding, 3); $context = collect($results['matches'])->map(fn($m) => $m['metadata']['source'] . " (chunk " . $m['metadata']['chunk'] . ")"); // 3. Build prompt $prompt = "You are a Laravel expert. Use the following excerpts to answer the query.\n\n" . implode("\n---\n", $context) . "\n\nQuestion: {$question}\nAnswer:"; // 4. Generate answer return $this->llm->completion()->create([ 'model' => 'gpt-4o-mini', 'prompt' => $prompt, 'max_tokens' => 250, ])->text; } }

Expose this service through a simple controller route:

use App\Services\RagService; use Illuminate\Http\Request; Route::post('/api/rag', function (Request $request, RagService $rag) { $question = $request->input('question'); return ['answer' => $rag->answer($question)]; });

Front‑end developers can now call /api/rag via AJAX, delivering instant, context‑aware answers without leaving the Laravel ecosystem.

Performance tips and caching strategy

Embedding generation is the most time‑consuming step. Cache each chunk’s embedding in Redis with a key pattern like embed:{file}:{chunk}. When the same document changes, invalidate the key and re‑run the indexer.

For query latency, store the top‑k results for a given question hash for up to 30 seconds. A typical request then finishes in 120‑150 ms, well within the expectations of a modern web UI.

Conclusion

By stitching Laravel 11, LangChain PHP, and Pinecone together, you create a full‑stack RAG solution that lives entirely in your own codebase. The approach scales from a handful of markdown files to millions of support tickets, while keeping the developer experience familiar: Composer commands, service providers, and standard Laravel routing. Implement the steps above, monitor embedding costs, and you’ll have an AI‑powered search that feels native to your application.

Sources

OpenAI API Documentation, Pinecone Official Docs, LangChain PHP GitHub Repository

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #Laravel 11 #RAG #LangChain PHP #Pinecone vector database #AI‑powered search
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

7 + 0 =