{"slug": "building-local-rag-workflows-in-laravel-with-nativerag", "title": "Building Local RAG Workflows in Laravel with NativeRAG", "summary": "Developer Hamzi released NativeRAG, a Laravel package that builds small-to-medium retrieval-augmented generation workflows using local models via Ollama or LM Studio. The package provides chat completions, embeddings, vector search, streaming responses, model indexing, and conversation persistence, storing embeddings and conversations in the application's own database instead of requiring a separate vector database. It offers an Embeddable trait so Eloquent models can be chunked and indexed for contextual search.", "body_md": "AI features are becoming normal in web applications, but a lot of teams still hesitate when the first step requires sending private application data to an external API.\n\nThat is the problem NativeRAG tries to solve for Laravel developers.\n\nNativeRAG is a Laravel package for building small to medium retrieval-augmented generation workflows using local models through Ollama or LM Studio. It gives you chat completions, embeddings, vector search, streaming responses, model indexing, and conversation persistence without needing a separate vector database to get started.\n\nThe goal is simple: keep the Laravel developer experience familiar while making local AI workflows easier to wire into a real application.\n\nRetrieval-augmented generation usually has a few moving parts:\n\nIn many setups, those pieces quickly turn into multiple services. That can be the right architecture at scale, but it is not always what you want on day one.\n\nSometimes you just need to index Eloquent models, search relevant chunks, and ask a local model a question using that context.\n\nNativeRAG keeps those pieces inside Laravel as much as possible.\n\nThe package currently supports:\n\n`Embeddable` trait\nIt is not trying to replace a dedicated vector database for every use case. Instead, it gives Laravel applications a practical starting point for local RAG features.\n\nInstall the package with Composer:\n\n```\ncomposer require hamzi/nativerag\n```\n\nThen publish the configuration and migrations:\n\n```\nphp artisan vendor:publish --tag=\"nativerag-config\"\nphp artisan vendor:publish --tag=\"nativerag-migrations\"\nphp artisan migrate\n```\n\nThe package stores embeddings and conversations in your application database.\n\nYou can use Ollama as the default driver:\n\n```\nNATIVE_RAG_DRIVER=ollama\n\nOLLAMA_BASE_URL=http://localhost:11434\nOLLAMA_CHAT_MODEL=llama3\nOLLAMA_EMBEDDING_MODEL=nomic-embed-text\n```\n\nOr LM Studio:\n\n```\nNATIVE_RAG_DRIVER=lmstudio\n\nLMSTUDIO_BASE_URL=http://localhost:1234\nLMSTUDIO_CHAT_MODEL=meta-llama-3-8b-instruct\nLMSTUDIO_EMBEDDING_MODEL=nomic-embed-text\n```\n\nYou can also tune chunking and search behavior:\n\n```\nNATIVE_RAG_CHUNK_SIZE=1000\nNATIVE_RAG_CHUNK_OVERLAP=200\nNATIVE_RAG_MIN_SCORE=0.35\n```\n\nThe simplest use case is sending messages to a local chat model:\n\n``` php\nuse Hamzi\\NativeRag\\Facades\\NativeRag;\n\n$response = NativeRag::chat([\n    [\n        'role' => 'system',\n        'content' => 'You are a concise Laravel assistant.',\n    ],\n    [\n        'role' => 'user',\n        'content' => 'Explain service containers in simple terms.',\n    ],\n]);\n\necho $response->content;\n```\n\nThis keeps the API close to common chat message formats while still using Laravel's facade and manager patterns under the hood.\n\nOne of the most useful parts of the package is the `Embeddable` trait.\n\nYou can make a model searchable by implementing `EmbeddableContract` and returning the text that should be embedded:\n\n``` php\nnamespace App\\Models;\n\nuse Hamzi\\NativeRag\\Contracts\\EmbeddableContract;\nuse Hamzi\\NativeRag\\Traits\\Embeddable;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Article extends Model implements EmbeddableContract\n{\n    use Embeddable;\n\n    public function toEmbeddableString(): string\n    {\n        return \"Title: {$this->title}\\n\\nContent: {$this->content}\";\n    }\n}\n```\n\nWhen the model is saved, NativeRAG can chunk the text, generate embeddings, and store them in the embeddings table.\n\nThis is especially useful for documentation, knowledge bases, product content, internal notes, support articles, and other text-heavy records.\n\nOnce content is indexed, you can search using either a plain text query or a precomputed embedding vector:\n\n``` php\nuse Hamzi\\NativeRag\\Facades\\NativeRag;\n\n$results = NativeRag::search(\n    query: 'How do I run database migrations?',\n    limit: 5,\n    minScore: 0.4,\n);\n\nforeach ($results as $chunk) {\n    echo $chunk->chunk_content;\n}\n```\n\nFor many Laravel applications, this is enough to start building contextual AI features without introducing more infrastructure.\n\nA common flow looks like this:\n\nExample:\n\n``` php\nuse Hamzi\\NativeRag\\Facades\\NativeRag;\nuse Hamzi\\NativeRag\\Services\\PromptCompiler;\n\n$question = 'How can users reset their password?';\n\n$chunks = NativeRag::search($question, limit: 4);\n\n$context = $chunks\n    ->pluck('chunk_content')\n    ->implode(\"\\n\\n---\\n\\n\");\n\n$prompt = app(PromptCompiler::class)->buildRagPrompt(\n    systemInstruction: 'Answer using only the provided context.',\n    context: $context,\n    query: $question,\n);\n\n$response = NativeRag::chat([\n    ['role' => 'user', 'content' => $prompt],\n]);\n\necho $response->content;\n```\n\nThis pattern is intentionally straightforward. You can replace the prompt, filtering, scoring threshold, or context formatting based on your application's needs.\n\nFor UI experiences, waiting for a full response can feel slow. NativeRAG supports streaming through server-sent events:\n\n``` php\nuse Hamzi\\NativeRag\\Facades\\NativeRag;\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::post('/ai/stream', function () {\n    return NativeRag::stream([\n        [\n            'role' => 'user',\n            'content' => request('message'),\n        ],\n    ]);\n});\n```\n\nThat makes it easier to build chat interfaces with Livewire, Alpine.js, Vue, React, or any frontend that can consume an event stream.\n\nNativeRAG also includes conversation models for persistent chat history:\n\n``` php\nuse Hamzi\\NativeRag\\Models\\NativeRagConversation;\n\n$conversation = NativeRagConversation::create([\n    'name' => 'Support session',\n]);\n\n$conversation->addSystemMessage('You are a helpful support assistant.');\n\n$reply = $conversation->ask('How do I publish the config file?');\n\necho $reply->content;\n```\n\nThe conversation stores user and assistant messages, then sends the current history to the selected driver.\n\nHistory can be pruned by message count or an approximate token budget. System messages can also be preserved so the assistant keeps its instructions.\n\nEmbedding generation can take time, especially when indexing larger records. NativeRAG can dispatch embedding sync to Laravel queues:\n\n```\nNATIVE_RAG_QUEUE_INDEXING=true\nNATIVE_RAG_QUEUE_CONNECTION=redis\nNATIVE_RAG_QUEUE_NAME=default\n```\n\nThat lets normal application requests stay responsive while workers handle chunking and embedding generation in the background.\n\nRunning models locally gives you more control over where prompts, documents, and embeddings live. That is useful for internal tools and privacy-sensitive applications.\n\nBut local RAG also has tradeoffs:\n\nThe package gives you the Laravel plumbing. You still need to choose good models, test outputs, and decide what quality bar makes sense for your product.\n\nNativeRAG is a good fit when you want to:\n\nIt may not be the right fit if you already need distributed vector indexing, advanced ranking pipelines, or large-scale retrieval over millions of chunks.\n\nWhat I like about this approach is that it keeps the first version boring in the best way.\n\nYou install a Laravel package, publish config and migrations, add a trait to a model, and start searching your own data. The architecture can evolve later, but the early developer experience stays simple.\n\nFor many teams, that is exactly the right place to start.\n\nRepository:\n\n```\nhttps://github.com/hamdyelbatal122/nativerag\n```\n\nPackage:\n\n```\ncomposer require hamzi/nativerag\n```\n\n", "url": "https://wpnews.pro/news/building-local-rag-workflows-in-laravel-with-nativerag", "canonical_source": "https://dev.to/hamdyelbatal122/building-local-rag-workflows-in-laravel-with-nativerag-3gfd", "published_at": "2026-10-12 16:12:31+00:00", "updated_at": "2026-10-12 16:20:39.291930+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "developer-tools", "ai-infrastructure"], "entities": ["NativeRAG", "Laravel", "Ollama", "LM Studio", "Hamzi", "Composer", "Eloquent"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/building-local-rag-workflows-in-laravel-with-nativerag", "markdown": "https://wpnews.pro/news/building-local-rag-workflows-in-laravel-with-nativerag.md", "text": "https://wpnews.pro/news/building-local-rag-workflows-in-laravel-with-nativerag.txt", "jsonld": "https://wpnews.pro/news/building-local-rag-workflows-in-laravel-with-nativerag.jsonld"}}