<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: RagLeap</title>
    <description>The latest articles on DEV Community by RagLeap (@ragleap).</description>
    <link>https://dev.to/ragleap</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3859689%2F0ddcc260-cc95-431d-9ba2-4c3c8cbe0d06.png</url>
      <title>DEV Community: RagLeap</title>
      <link>https://dev.to/ragleap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ragleap"/>
    <language>en</language>
    <item>
      <title>v0.7.5 — Maintenance Snapshot: 5 Packages, 477 Tests Green</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Tue, 29 Sep 2026 06:45:56 +0000</pubDate>
      <link>https://dev.to/ragleap/v075-maintenance-snapshot-5-packages-477-tests-green-h2o</link>
      <guid>https://dev.to/ragleap/v075-maintenance-snapshot-5-packages-477-tests-green-h2o</guid>
      <description>&lt;p&gt;No core changes in this one — but if you maintain a monorepo, you know this is the important release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v0.7.5 is a snapshot since v0.7.0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you use only &lt;code&gt;ragleap-core&lt;/code&gt;, stay on v0.7.0. This is for monorepo users.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's bundled:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. ragleap-observability v0.3.0&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AlertManager + first real alert rule — verified with &lt;code&gt;curl /api/v1/rules&lt;/code&gt; = &lt;code&gt;ok&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prometheus fix: &lt;code&gt;strategy: Recreate&lt;/code&gt; to avoid PVC crash-loop&lt;/li&gt;
&lt;li&gt;Loki Deployment + Grafana datasource wiring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. ragleap-tools v0.2.0&lt;/strong&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python
from ragleap_tools import search_web
# BYOK - plug your own provider
result = search_web("ragleap observability", provider="tavily")




**

## 3. ragleap-rag
**

ingest(metadata={"source": "docs"}) — now supported
Fix: QdrantBackend cosine score normalization
Fix: WeaviateBackend custom port + named-vector search

## **4. Java Port v0.10.0**

+4 backends: Qdrant, Weaviate (live-verified), Milvus, Pinecone

## **5. Housekeeping**

clone-count badge automation (real traction &amp;gt; stars)
SBOM regenerated for compliance
477 tests passing

Why we care about SBOM + badges? Enterprise adoption needs it.

Repo: github.com/antonyrag/ragleap-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>opensource</category>
      <category>observability</category>
      <category>devops</category>
      <category>python</category>
    </item>
    <item>
      <title>ragleap-rag-java v0.9.0: Adding Milvus as 5th Vector Backend Without a Live Cluster</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Mon, 28 Sep 2026 04:58:38 +0000</pubDate>
      <link>https://dev.to/ragleap/ragleap-rag-java-v090-adding-milvus-as-5th-vector-backend-without-a-live-cluster-2c2e</link>
      <guid>https://dev.to/ragleap/ragleap-rag-java-v090-adding-milvus-as-5th-vector-backend-without-a-live-cluster-2c2e</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh1up2jbgkv55yceyd64g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh1up2jbgkv55yceyd64g.png" alt=" " width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We just shipped ragleap-rag-java v0.9.0 to Maven Central.&lt;/p&gt;

&lt;p&gt;Maven Central stats for September alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;736 total downloads&lt;/li&gt;
&lt;li&gt;55 unique sources&lt;/li&gt;
&lt;li&gt;21 companies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this release adds our 5th vector backend: Milvus.&lt;/p&gt;

&lt;p&gt;We now support: PgVector, FaissBackend, QdrantBackend, WeaviateBackend, and now MilvusBackend.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Milvus was tricky
&lt;/h4&gt;

&lt;p&gt;Unlike Qdrant/Weaviate, Milvus self-hosting needs 3 services: etcd, MinIO, milvus-standalone. On my current VPS with existing CPU contention, that's too resource-risky.&lt;/p&gt;

&lt;p&gt;So I did what I did for the Python version — be honest about it.&lt;/p&gt;

&lt;h4&gt;
  
  
  What I actually did
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt; Fetched and read Milvus REST v2 API docs directly — not from memory.&lt;/li&gt;
&lt;li&gt; Built MilvusBackend against the real spec.&lt;/li&gt;
&lt;li&gt; No UUID indirection needed: Milvus VarChar primary key accepts &lt;code&gt;documentId:chunkIndex&lt;/code&gt; directly. Simpler than other backends.&lt;/li&gt;
&lt;li&gt; 18 new tests via local HTTP stub server — same pattern this codebase uses for testing unavailable providers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is NOT live-verified against Zilliz Cloud / self-hosted Milvus, and the README says so. Same honest caveat Python MilvusBackend carries.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to use it
&lt;/h4&gt;

&lt;p&gt;// pom.xml&lt;br&gt;
&lt;br&gt;
  io.github.antonyrag&lt;br&gt;
  ragleap-rag&lt;br&gt;
  0.9.0&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;// Java&lt;br&gt;
var backend = new MilvusBackend(&lt;br&gt;
  "&lt;a href="http://localhost:19530" rel="noopener noreferrer"&gt;http://localhost:19530&lt;/a&gt;", // or Zilliz Cloud URL&lt;br&gt;
  "your_collection"&lt;br&gt;
);&lt;br&gt;
var rag = new RagleapRag(backend, embeddingConfig);&lt;/p&gt;

&lt;h4&gt;
  
  
  What's next
&lt;/h4&gt;

&lt;p&gt;Live verification when we have infra, but the API contract is solid — it's built from docs.&lt;/p&gt;

&lt;p&gt;If you build Java RAG, try it and star the repo:&lt;br&gt;
github.com/antonyrag/ragleap-core&lt;/p&gt;

&lt;p&gt;Good first issues are labeled — looking for contributors for Weaviate live tests and Milvus Cloud verification.&lt;/p&gt;

&lt;p&gt;Release: &lt;a href="https://github.com/antonyrag/ragleap-core/releases/tag/ragleap-rag-java-v0.9.0" rel="noopener noreferrer"&gt;https://github.com/antonyrag/ragleap-core/releases/tag/ragleap-rag-java-v0.9.0&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>milvus</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Prometheus 0 Targets and Loki 0 Logs — 5 Real Fixes from ragleap-core Observability Release</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Sun, 27 Sep 2026 04:36:45 +0000</pubDate>
      <link>https://dev.to/ragleap/prometheus-0-targets-and-loki-0-logs-5-real-fixes-from-ragleap-core-observability-release-18ak</link>
      <guid>https://dev.to/ragleap/prometheus-0-targets-and-loki-0-logs-5-real-fixes-from-ragleap-core-observability-release-18ak</guid>
      <description>&lt;p&gt;We shipped observability for ragleap-core v0.2.0 (v0.2.1 is docs patch).&lt;/p&gt;

&lt;p&gt;Stack: Prometheus + Grafana + Loki + Promtail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixes that actually mattered:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ConfigMap corrupted by missing newline&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
yaml
# Before: two docs merged
# After: Add \n at EOF


**

## 2. Prometheus kubernetes_sd_configs = 0 targets
**

Fix: Replace custom regex, use canonical *path* + cri stage

- source_labels: [__meta_kubernetes_pod_annotation_kubernetes_io_config_path]
  target_label: __path__
  regex: (.+)


**

## 3. Promtail -&amp;gt; Loki DNS
**

loki:
  client:
    url: http://loki-gateway.ragleap.svc.cluster.local:3100/loki/api/v1/push


## **4. postgres-exporter runAsNonRoot
**

securityContext:
  runAsUser: 65534
  runAsNonRoot: true

## **5. Position file starvation**

— Remove diagnostic job sharing positions.yamlVerification:

* kubectl -n ragleap get pods | grep -E 'prometheus|grafana|loki|promtail'
* curl prometheus:9090/api/v1/targets -&amp;gt; activeTargets &amp;gt; 0
* curl loki:3100/loki/api/v1/labels -&amp;gt; 21+ streams

**Release:** https://github.com/antonyrag/ragleap-core/releases/tag/ragleap-observaility-v0.2.0



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>observability</category>
      <category>prometheus</category>
    </item>
    <item>
      <title>Implementing 9 Agentic Patterns Without Losing Control — What I Fixed in v0.7.0</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Fri, 25 Sep 2026 15:05:24 +0000</pubDate>
      <link>https://dev.to/ragleap/implementing-9-agentic-patterns-without-losing-control-what-i-fixed-in-v070-1cl8</link>
      <guid>https://dev.to/ragleap/implementing-9-agentic-patterns-without-losing-control-what-i-fixed-in-v070-1cl8</guid>
      <description>&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-correction, ToT, Supervisor routing and why approval-gated actions + token budgets matter more than the patterns themselves.
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;When we started building agentic workflows, the problem wasn't adding patterns. Chain-of-Thought, Tree-of-Thought, Reflection — all are 50 lines of code. The problem is what happens after you add them.&lt;/p&gt;

&lt;p&gt;v0.7.0 is 9 patterns complete. But this post is not about the patterns. It's about the 4 things that broke while adding them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. The Tree-of-Thought empty-reply bug&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;ToT looks great on paper — branch, evaluate, prune. In practice, LLM returns empty string when token budget is tight and your evaluate node crashes with NoneType.&lt;/p&gt;

&lt;h1&gt;
  
  
  434 shipped ToT. #435 fixed it. We added token-budget aware pruning and empty-reply guard before scoring. Simple fix, but if you implement ToT without it, prod will fail silently.
&lt;/h1&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Actionable agents are dangerous by default
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;We added Webhook, Slack, Email senders (#438) and an LLM-driven action planner (#441) that can propose a real action.&lt;/p&gt;

&lt;p&gt;The key decision: the model can propose, never execute. Every action is gated through the existing HITL approval flow. No direct execution path.&lt;/p&gt;

&lt;p&gt;If you let your agent send Slack messages directly, you will spam a channel at 2 AM. We learned this in staging.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. Security is not a feature, it's the cleanup&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This release fixed:&lt;/p&gt;

&lt;p&gt;7 stack-trace-exposure alerts + 4 raw-exception leaks in API (#439, #440) — leaking internals to client is common when you add new patterns quickly.&lt;/p&gt;

&lt;p&gt;Runtime-created AI Employee roles are now auto-detected as sensitive if name/tags say so (#453) — closing a guardrail bypass.&lt;/p&gt;

&lt;p&gt;Docker Compose ports now bind to localhost by default (#459) — previously 0.0.0.0.&lt;/p&gt;

&lt;p&gt;Approval replies (YES/NO) now only count from configured owner; WhatsApp/Telegram webhooks fail-closed without signature (#460) — prevents anyone approving your agent's actions.&lt;/p&gt;

&lt;p&gt;Optional RAGLEAP_API_KEY global middleware auth (#485), off by default.&lt;/p&gt;

&lt;p&gt;None of these are sexy. All of them are required before you give an agent real tools.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Cost control &amp;gt; prompt optimization
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;We added usage ledger + token budget caps, global and per-role, including streaming responses (#455, #456).&lt;/p&gt;

&lt;p&gt;Without per-role caps, a single Supervisor -&amp;gt; Sub-agent loop (#437) can burn $3 in one query. We now kill the branch when budget hits, not after.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  What shipped in v0.7.0
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;Patterns: self-correction/reflection (#408), CoT (#433), ToT (#434, #435), supervisor routing (#436), sub-agent spawning (#437) — on top of tool registry, observability, HITL, memory from v0.6.0&lt;/p&gt;

&lt;p&gt;477 tests passing&lt;/p&gt;

&lt;p&gt;Repo clone-count badge, ∼35 community README translations, improved short-query language detection by @hardik47278 (#452)&lt;/p&gt;

&lt;p&gt;Full changelog: &lt;a href="https://github.com/antonyrag/ragleap-core/releases/tag/v0.7.0" rel="noopener noreferrer"&gt;https://github.com/antonyrag/ragleap-core/releases/tag/v0.7.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're implementing ToT or Supervisor pattern, don't start with the prompt. Start with: what happens when it returns empty, what happens when it loops, and who can approve its side effects.&lt;/p&gt;

&lt;p&gt;That’s the part no one writes about.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>opensource</category>
      <category>agenticpostgreschallenge</category>
      <category>llm</category>
    </item>
    <item>
      <title>RagLeap Core v0.4.0 - I Shipped 13 Commits in a Day to Make AI Employees Production-Ready</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Sun, 13 Sep 2026 08:50:55 +0000</pubDate>
      <link>https://dev.to/ragleap/ragleap-core-v040-i-shipped-13-commits-in-a-day-to-make-ai-employees-production-ready-2bbd</link>
      <guid>https://dev.to/ragleap/ragleap-core-v040-i-shipped-13-commits-in-a-day-to-make-ai-employees-production-ready-2bbd</guid>
      <description>&lt;p&gt;I just shipped &lt;strong&gt;RagLeap Core v0.4.0&lt;/strong&gt; after &lt;strong&gt;13 commits in a single day&lt;/strong&gt;. 480+ commits total, 12 stars, and now it's a production-ready AI Business OS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is RagLeap Core?&lt;/strong&gt;&lt;br&gt;
Self-hosted, MIT licensed AI Business OS — 46 autonomous AI Employees, Graph RAG (Neo4j), multi-channel, BYOK across 17 LLM providers + Ollama, 8 libs (Python + Java).&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/antonyrag/ragleap-core" rel="noopener noreferrer"&gt;https://github.com/antonyrag/ragleap-core&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔥 What shipped in v0.4.0 (Sep 12)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Silent Failures Are Now Loud - &lt;code&gt;fix(employees)&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Before: Embedding failures in memory system were failing silently. Your AI employee would just forget things.&lt;br&gt;
Now: We surface them. If embedding fails, you know WHY.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python
# Before: silent pass
# After: explicit error surfacing
raise EmbeddingFailure(reason, context)

2. Production RUNBOOK - Because Sh*t Happens

Added RUNBOOK.md for:

db-downneo4j-crash-loopbackup-failurecert-expiredSelf-hosted means YOU own ops. So I documented how to recover when things break. No more guessing at 2 AM.

3. Graph RAG Goes Cross-Chunk - feat(ragleap-graph)
Implemented cross-chunk relation extraction (#154).
Old: Entities linked only within same chunk
New: Relations extracted ACROSS chunks. If Doc says "API rate limit" in page 1 and "429 error" in page 5, Neo4j now links them.
This is real Graph RAG, not just vector search + buzzword.

4. Java Port - 2 More Modules Done
EmbeddingConfig -&amp;gt; JavaConnectionPool (db.py) -&amp;gt; JavaWhy Java? Regulated industries (HIPAA) need Java stack. We're at 9/8 libs now. Yes, more than planned.

5. ragleap-observability is LIVE on PyPI 📦javascriptpip install ragleap-observabilityWith live-verified status, postgres-exporter fix (runAsUser=65534), and proper publish CI job (#332).
Why v0.4.0 Matters

Most RAG demos die in production because:

Silent failures No ops story No observability v0.4.0 fixes all three. Honest truncation notices for streamed answers, RUNBOOK, PyPI observability.

Philosophy: Guardrailed autonomy for regulated industries. AI employees should be autonomous BUT you should be able to debug them.
Stack

Vector: pgvectorGraph: Neo4j (gracefully degrades if down)LLM: BYOK - 17 providers + OllamaLanguages: Python + JavaLicense: MIT - fully self-hostedWhat's Next?

Product Hunt launch this week50 stars goal (12 -&amp;gt; 50)Multi-hop graph traversal wired into retrievalIf you're building self-hosted AI, give it a star and tell me what breaks. I ship fixes same day - literally 13 commits yesterday.

Try it:bashgit clone https://github.com/antonyrag/ragleap-core
docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>python</category>
      <category>java</category>
    </item>
    <item>
      <title>Why We Put "What This Doesn't Do Yet" Right Next to the Feature List</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Tue, 04 Aug 2026 06:23:33 +0000</pubDate>
      <link>https://dev.to/ragleap/why-we-put-what-this-doesnt-do-yet-right-next-to-the-feature-list-5890</link>
      <guid>https://dev.to/ragleap/why-we-put-what-this-doesnt-do-yet-right-next-to-the-feature-list-5890</guid>
      <description>&lt;p&gt;Every RAG library launch post leads with capability. We're leading with scope, because scope is the thing that actually determines whether a library fits your project — and most launch posts quietly skip it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkdgz1vzjhceib6gvme52.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkdgz1vzjhceib6gvme52.jpg" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The technical case for narrow scope&lt;/p&gt;

&lt;p&gt;ragleap-rag does retrieval-augmented generation. It does not do agentic tool-calling, multi-step orchestration, or human-in-the-loop approval gates. That's not a v1.0 limitation we're apologizing for — it's a deliberate boundary, because bolting agent reasoning onto a retrieval library usually means neither part is done well.&lt;/p&gt;

&lt;p&gt;If you need that, it's a separate, not-yet-built package (ragleap-agents, ragleap-flows) on the roadmap — not a half-implemented feature living inside this one.&lt;/p&gt;

&lt;p&gt;What v0.11.1 actually ships&lt;/p&gt;

&lt;p&gt;Retrieval: hybrid dense (pgvector cosine) + sparse (Postgres full-text) fused via Reciprocal Rank Fusion. hybrid=False for dense-only when you want one query instead of two.&lt;/p&gt;

&lt;p&gt;Reranking: cross-encoder via ONNX Runtime, CPU-only, ~23MB. No torch, no CUDA — the model most reranking libraries pull in defaults to a 2GB+ install even if you never touch a GPU.&lt;/p&gt;

&lt;p&gt;Vector backends: 6 total, merged directly into core rather than kept as a separate package. pgvector and FAISS are live-verified against real services today. Pinecone, Weaviate, Qdrant, and Milvus are code-complete but not yet live-tested — we're not claiming parity until they are.&lt;/p&gt;

&lt;p&gt;Reliability: chained fallbacks (not just one), real per-call token/cost numbers pulled from the provider's own response, async twins for every method, connection pooling, Redis-backed distributed query caching for multi-process deployments.&lt;/p&gt;

&lt;p&gt;Ingestion: 28 file formats, URLs (via trafilatura for clean extraction), images (OCR + vision captioning), audio and video (ffmpeg extraction + pluggable transcription), concurrent mixed-type batch ingestion with per-item failure isolation.&lt;/p&gt;

&lt;p&gt;Testing: 238 automated tests, real CI on every PR, up from 72 at the last major checkpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feqryb96e0btz9rnj2emg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feqryb96e0btz9rnj2emg.jpg" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
pip install ragleap-rag&lt;/p&gt;

&lt;p&gt;from ragleap import RagLeap, ProviderConfig, EmbeddingConfig&lt;/p&gt;

&lt;p&gt;rag = RagLeap(&lt;br&gt;
    database_url="postgresql://user:pass@localhost/mydb",&lt;br&gt;
    embedder=EmbeddingConfig(provider="gemini", api_key="..."),&lt;br&gt;
    primary=ProviderConfig(provider="gemini", api_key="..."),&lt;br&gt;
)&lt;br&gt;
rag.init_schema()&lt;/p&gt;

&lt;p&gt;result = rag.ingest("handbook.pdf", raw_bytes)&lt;br&gt;
answer = rag.ask("What's our PTO policy?")&lt;br&gt;
What's next&lt;/p&gt;

&lt;p&gt;ragleap-graph (knowledge-graph-augmented retrieval via Neo4j) and ragleap-integrations (MCP-native + curated connectors) are next on the roadmap. ragleap-agents and ragleap-flows come after — deliberately sequenced, not rushed in to chase a feature-parity headline against LangChain.&lt;/p&gt;

&lt;p&gt;Repo: github.com/antonyrag/ragleap-core PyPI: pypi.org/project/ragleap-rag&lt;/p&gt;

&lt;p&gt;Genuinely interested in what breaks when you try it on something real — that's what the issue tracker is for.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>rag</category>
      <category>llm</category>
    </item>
    <item>
      <title>The Bottleneck Isn't the Model. It's the Prompt You Didn't Write.</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Thu, 16 Jul 2026 09:22:25 +0000</pubDate>
      <link>https://dev.to/ragleap/the-bottleneck-isnt-the-model-its-the-prompt-you-didnt-write-4b87</link>
      <guid>https://dev.to/ragleap/the-bottleneck-isnt-the-model-its-the-prompt-you-didnt-write-4b87</guid>
      <description>&lt;p&gt;Every few weeks there's a thread about some LLM "failing" at a task. Half the replies are someone else running the same task, getting a solid result, and just not saying what prompt they actually used.&lt;/p&gt;

&lt;p&gt;This isn't a defense of any particular model. It's a pattern worth naming: most "the AI got it wrong" reports are actually underspecified-request reports.&lt;/p&gt;

&lt;p&gt;The gap that always existed&lt;/p&gt;

&lt;p&gt;We've always had this problem with underspecified tickets. "Fix the login bug" without repro steps, expected behavior, or environment details gets you a fix — maybe not the right one. Nobody's surprised when that ticket produces a mismatched result. We just say the ticket needed more detail.&lt;/p&gt;

&lt;p&gt;LLMs get a different reaction to the same failure mode. Instead of "the prompt needed more detail," it's "the model isn't good enough yet." Sometimes that's true. Often it's the same underspecified-ticket problem wearing a new interface.&lt;/p&gt;

&lt;p&gt;What actually changes the output&lt;/p&gt;

&lt;p&gt;Not length. Specificity. Compare:&lt;/p&gt;

&lt;p&gt;"Write a function to validate user input"&lt;/p&gt;

&lt;p&gt;vs.&lt;/p&gt;

&lt;p&gt;"Write a function that validates a signup form:&lt;br&gt;
email (RFC 5322, not just regex-lite), password &lt;br&gt;
(min 12 chars, 1 number, 1 symbol), and username &lt;br&gt;
(alphanumeric + underscore, 3-20 chars). Return a &lt;br&gt;
list of specific error messages, not just true/false. &lt;br&gt;
Python, no external deps beyond stdlib."&lt;/p&gt;

&lt;p&gt;Same model. Wildly different output quality. Nothing about the model changed between those two requests — the constraint surface did.&lt;/p&gt;

&lt;p&gt;The unglamorous actual skill&lt;/p&gt;

&lt;p&gt;This is closer to writing a good spec or a good code review comment than it is to any "prompt engineering" secret technique. Explicit constraints. Explicit definition of done. Explicit scope boundaries (what NOT to do, sometimes matters more than what to do).&lt;/p&gt;

&lt;p&gt;Most of us already know how to do this — we do it for Jira tickets, PR descriptions, code review comments. The skill transfers almost directly. It just doesn't feel like it should, because talking to an LLM still feels conversational instead of like writing a spec.&lt;/p&gt;

&lt;p&gt;The actual debug step&lt;/p&gt;

&lt;p&gt;Before filing a "the model can't do this" bug report against reality: would a new hire, handed the literal text of your prompt and nothing else, have produced something meaningfully better?&lt;/p&gt;

&lt;p&gt;If not — that's not a model limitation. That's a spec problem, and it's fixable in the next five minutes, same as tightening a vague ticket.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F48g87kfvd8ihi6pycrg7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F48g87kfvd8ihi6pycrg7.jpg" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>rag</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Complete RagLeap Guide — Every Feature, Explained Step by Step</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Sat, 04 Jul 2026 10:03:20 +0000</pubDate>
      <link>https://dev.to/ragleap/the-complete-ragleap-guide-every-feature-explained-step-by-step-45eh</link>
      <guid>https://dev.to/ragleap/the-complete-ragleap-guide-every-feature-explained-step-by-step-45eh</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7cktdglz4703dph0fhvl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7cktdglz4703dph0fhvl.png" alt=" " width="1536" height="767"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How to set up and run an AI business manager that answers customers on WhatsApp, Telegram, Discord, and real phone calls — with its own memory, its own knowledge base, and an executive assistant for the owner.&lt;br&gt;
I'm the founder of RagLeap, and this is the complete technical walkthrough of everything it does — written for anyone evaluating it, setting it up, or curious how a multi-channel RAG + voice AI system is actually structured under the hood.&lt;br&gt;
Most AI chatbot tools do one thing: answer questions on a website widget. RagLeap is built differently — it's a full AI business manager that runs across five channels (Web, WhatsApp, Telegram, Discord, and real Voice calls via Twilio), backed by PostgreSQL + pgvector for embeddings and Neo4j for a knowledge graph layer, with a persistent memory system that survives across sessions and channels instead of resetting every conversation.&lt;br&gt;
This guide covers every part of the platform in the order you'd actually set it up.&lt;br&gt;
Table of Contents&lt;/p&gt;

&lt;p&gt;Dashboard — Your Home Screen&lt;br&gt;
RagLeap Manager — Your AI Executive Assistant&lt;br&gt;
AI Employees — A Specialized Team, Not One Bot&lt;br&gt;
Documents — Building Your AI's Knowledge Base (RAG)&lt;br&gt;
Integrations — Connecting Your Existing Tools&lt;br&gt;
n8n Workflows — No-Code Automation&lt;br&gt;
Voice AI — Answering Real Phone Calls&lt;br&gt;
WhatsApp Business Bot Setup&lt;br&gt;
Telegram Bot Setup&lt;br&gt;
Discord Bot Setup&lt;br&gt;
Database — Cloud vs. Self-Hosted&lt;br&gt;
Billing &amp;amp; Analytics — Credits and Costs&lt;br&gt;
Persistent Memory Dashboard&lt;br&gt;
Language Settings — 222+ Languages&lt;br&gt;
AI Settings — Model, Temperature, Your Own API Key&lt;br&gt;
Account — Plans, Team, Billing&lt;br&gt;
Audit History&lt;br&gt;
AI Chat — Testing Before You Deploy&lt;br&gt;
Embedding the Chatbot on Your Website&lt;br&gt;
FAQ&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dashboard — Your Home Screen
Every session starts on the Dashboard. It's a status check: is everything working, and what happened while you were away?
The top bar shows your current workspace name, document count, total workspace size, and a workspace switcher — relevant if you're managing multiple businesses or clients under one account.
On the page:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Getting Started checklist — Upload Documents, Configure AI, Start Chatting, Deploy Chatbot. Dismissible after onboarding.&lt;br&gt;
Quick stats — Documents count, Storage used, Queries Today, Current Workspace.&lt;br&gt;
RAG Quality panel — retrieval benchmark scores: nDCG@k, Hit@k, MRR@k, &lt;a href="mailto:Recall@k"&gt;Recall@k&lt;/a&gt;. This is an information-retrieval metric — it measures whether the right source document surfaces in the top-k results for a test query set, not whether the generated answer's wording is correct. Above ~0.9 is considered healthy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;RagLeap Manager — Your AI Executive Assistant
This is the feature that differentiates RagLeap from a typical RAG chatbot. Manager AI is a private assistant scoped only to the workspace owner — never exposed to customers — reachable via Web, Telegram, WhatsApp, or a direct phone call.
Capabilities:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Read access — every document (public and private), analytics, team permissions, database connections, channel config, credit balance&lt;br&gt;
Write access — configure channels, connect/query databases, generate and export reports (PDF/Excel/CSV), send emails, manage team members, change AI model/settings, deploy automations&lt;br&gt;
Analysis — sales, financial (P&amp;amp;L, cash flow), business strategy, and customer behavior analysis, run against your documents or a live connected database, in natural language&lt;/p&gt;

&lt;p&gt;Because it runs on the same persistent memory system as everything else, a conversation started on Telegram carries over to a phone call or the web app — it's one continuous context, not five disconnected sessions per channel.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI Employees — A Specialized Team, Not One Generic Bot
Every workspace is seeded with a set of AI Employee roles by default — each with its own permanent memory scope and area of expertise, rather than routing every query through one generic system prompt.
How the learning loop works:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Roles are seeded automatically on workspace creation&lt;br&gt;
Each role's skill context is injected into the active channel handler (voice, WhatsApp, web, Telegram) based on conversational intent&lt;br&gt;
learn_from_conversation() runs across every channel — real conversations write new permanent memory, not just session-scoped context&lt;br&gt;
A weekly Celery beat task reinforces learned patterns across all workspaces every Sunday&lt;/p&gt;

&lt;p&gt;Inspect roles and their memory entries at /ai-employees/.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Documents — Building Your AI's Knowledge Base (RAG)
This is the retrieval corpus everything else depends on. Upload documents → they're chunked → embedded → indexed → retrieved at query time with citations back to source.
Pipeline, in three steps:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Upload — PDF, DOCX, TXT, or a raw URL&lt;br&gt;
Processing — auto-chunked, embedded (Google Gemini embedding model, 3072 dimensions), and indexed&lt;br&gt;
Retrieval — queries in Chat return cited answers pulled from the indexed corpus&lt;/p&gt;

&lt;p&gt;Supported formats: PDF, DOC, DOCX, XLSX, XLS, CSV, XSL/XSLT, PPT, PPTX, HTML, JSON, XML, RTF, ODT, ODS, ODP, EML, ZIP, SQL, TXT, MD — up to 50MB/file.&lt;br&gt;
Visibility model: Public documents are retrievable by both customer-facing channels and Manager AI. Private documents are retrievable only by Manager AI — the correct place for financial data, contracts, or anything that shouldn't leak to a customer-facing bot.&lt;br&gt;
Post-indexing, the same nDCG@k / Hit@k / MRR@k / Recall@k benchmark from the Dashboard runs automatically here too.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Integrations — Connecting Your Existing Tools
Rather than requiring migration into RagLeap, Integrations connects to systems you're already running, with AI-suggested automations per channel and a developer-level automation layer for custom logic. Same Public/Private visibility model applies to connected databases here as it does to Documents.&lt;/li&gt;
&lt;li&gt;n8n Workflows — No-Code Automation
Direct integration with n8n — trigger workflows mid-conversation, on any channel:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;"Customer requested a callback" → create a CRM lead&lt;br&gt;
"Urgent order query" → post to Slack/Discord&lt;br&gt;
"Appointment confirmed" → send calendar invite / SMS&lt;/p&gt;

&lt;p&gt;Setup: connect your n8n instance at /n8n-workflows/, map trigger conditions to specific workflows. Runs identically across voice, WhatsApp, web chat, and Telegram once configured.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Voice AI — Answering Real Phone Calls
The most technically involved channel: a Twilio number routes into a pipeline of STT (Whisper or Deepgram) → RAG/AI response → TTS (OpenAI or ElevenLabs), with total round-trip latency in the 2–3 second range in production.
Call routing logic:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Owner Mode — call from your registered owner number → routes to Manager AI (full private access)&lt;br&gt;
Customer BPO Mode — any other number → routes to RAG-powered customer support, backed by your documents and live database&lt;/p&gt;

&lt;p&gt;Setup:&lt;/p&gt;

&lt;p&gt;Add Twilio Account SID, Auth Token, Phone Number → save&lt;br&gt;
Copy the generated webhook URL into Twilio Console → Phone Numbers → Voice URL&lt;br&gt;
Enable "Enable Twilio PSTN" → save&lt;br&gt;
Test: call from your owner number (Manager AI) vs. any other number (Customer BPO)&lt;/p&gt;

&lt;p&gt;Language auto-detection is real-time — a caller saying "switch to Tamil" or "speak in Hindi" mid-call triggers an instant language switch, no reconnection needed. TTS choice: OpenAI TTS (default, uses your existing key) or ElevenLabs (more natural, 200+ languages, needs its own key).&lt;br&gt;
A Live Voice Test Console lets you test the full pipeline in-browser before wiring up a real number, with live Response/Audio/Total/Status metrics (browser testing adds ~2s of buffering vs. a real call).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;WhatsApp Business Bot Setup
Two supported providers:
ProviderBest forApprox. costTwilioReliability, documentation~$0.005–0.08/msgGupshupCost, Indian company, fast +91 approval~$0.001–0.05/msg
Critical constraint: a phone number cannot run personal WhatsApp and WhatsApp Business API simultaneously. Once registered as a bot number, it's locked out of normal WhatsApp use. Use a dedicated SIM or VoIP/landline number that can receive an OTP.
Twilio: get a sandbox/production WhatsApp number → copy Account SID + Auth Token into RagLeap → test connection → set webhook to &lt;a href="https://ragleap.com/api/whatsapp/webhook/" rel="noopener noreferrer"&gt;https://ragleap.com/api/whatsapp/webhook/&lt;/a&gt; in Twilio Console.
Gupshup: create a WhatsApp app → copy API Key + App Name into RagLeap → test connection → set Callback URL to &lt;a href="https://ragleap.com/api/whatsapp/gupshup-webhook/" rel="noopener noreferrer"&gt;https://ragleap.com/api/whatsapp/gupshup-webhook/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Telegram Bot Setup
Fastest setup path, typically under two minutes:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Message &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt; on Telegram, send /newbot&lt;br&gt;
Copy the returned Bot Token&lt;br&gt;
Paste into RagLeap's Telegram Bot page, enable, save&lt;br&gt;
Register the webhook URL with Telegram's API (single browser GET or curl -X POST)&lt;br&gt;
Test by messaging your bot directly&lt;/p&gt;

&lt;p&gt;Most common failure mode: "Message Content Intent" not enabled, or a trailing space in the copied token.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Discord Bot Setup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create an application in the Discord Developer Portal, add a Bot user, copy the Bot Token&lt;br&gt;
Enable "Message Content Intent" under Privileged Gateway Intents&lt;br&gt;
Paste Bot Token + Application ID into RagLeap, enable, save&lt;br&gt;
Generate an OAuth2 invite URL (bot scope + Send Messages / Read Message History / View Channels), invite to your server&lt;br&gt;
Mention the bot or message in an accessible channel&lt;/p&gt;

&lt;p&gt;Note: these bots often show "offline" in the member list since they're webhook-based rather than maintaining a persistent gateway connection — this is expected and doesn't affect responsiveness.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Database — Cloud vs. Self-Hosted
FeatureCloudSelf-HostedSetup timeInstant~10 min (curl installer)Data locationRagLeap infraYour infra onlyNeo4j knowledge graphIncludedIncludedOffline capableNoYesBest forStartups, teamsRegulated industries (health, finance, legal)
Self-hosted is a one-time license fee rather than a subscription — relevant if data residency/compliance is a hard requirement.&lt;/li&gt;
&lt;li&gt;Billing &amp;amp; Analytics — Credits, API Costs, and Usage
Tracks AI credits, per-provider API key configuration, and cost breakdown.
Credits: 1 credit = 1 chat query on RagLeap's System AI; 0.1 credit = 1 embedding chunk. Bring your own API key and no credits are consumed — costs bill directly to your provider account instead.
Per-provider cost breakdown (Google Gemini, OpenAI, Anthropic Claude) shows API calls, tokens consumed, and estimated cost, with 7/30/90-day trend views.&lt;/li&gt;
&lt;li&gt;Persistent Memory Dashboard
The core differentiator vs. session-based chat tools: memory here is genuinely persistent, retrieved by semantic similarity rather than keyword match.
Pipeline:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Store — fact/preference saved as a memory entry (manual or automatic)&lt;br&gt;
Embed — vectorized for semantic search&lt;br&gt;
Retrieve — relevant memories surfaced by meaning at query time&lt;br&gt;
Inject — retrieved memories added to the AI's context window&lt;/p&gt;

&lt;p&gt;Two scopes: User-level (portable across all your workspaces) and Workspace-level (shared across your team, e.g. escalation rules, pricing policy). Auto-compression kicks in when an entry exceeds a configurable token threshold. Full CRUD from this page, plus JSONL export and bulk purge.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Language Settings — 222+ Languages, Auto-Detected
Documents are scanned for language distribution (token-weighted). Chat Language Preference supports 222+ built-in languages plus any custom ISO code (up to 2 total). Auto-detect query language, when enabled, matches the customer's actual input language; disabled, it locks to your preferred language regardless of input. This config is genuinely global — applies identically across Web, WhatsApp, Telegram, Discord, and Voice.&lt;/li&gt;
&lt;li&gt;AI Settings — Model, Temperature, and Bring Your Own API Key
Model choice: Google Gemini (default, fast), OpenAI GPT (complex analysis), Anthropic Claude (detailed reasoning).
BYOK isn't limited to the three named providers — also supports OpenRouter, Deepseek, Mistral, and a fully Custom API mode for any OpenAI-compatible endpoint: self-hosted models, Ollama, vLLM, or any third-party inference API reachable by URL.
Tuning: Temperature (0.0–1.0; 0.2–0.4 recommended for factual RAG), Top-K Results (chunks reviewed pre-answer; 3–8 typical). A Fallback Key Pool supports multiple keys with automatic failover on rate limits.&lt;/li&gt;
&lt;li&gt;Account — Plans, Team, and Billing
PlanPriceWorkspacesKey featuresStarter$29/mo1Web + AI ManagerPro$99/mo2+ WhatsApp + TelegramBusiness$199/mo3+ Voice, Team members, no brandingEnterprise$499/mo5+ SLA, dedicated support, custom integrations
Also free on your own server — single workspace, web embed, AI Manager with RagLeap branding, no subscription. Team Members (Business/Enterprise) support per-member permission control and group-based bulk permissions.&lt;/li&gt;
&lt;li&gt;Audit History
Every config/settings change is logged: timestamp, workspace, action type, description, and actor. Filterable by workspace, action type, time range. Necessary once more than one person has admin access.&lt;/li&gt;
&lt;li&gt;AI Chat — Testing Before You Deploy
Exactly what a customer sees — cited answers, suggested follow-ups generated from your document set. Follows whatever Language Settings config is active, no separate configuration needed. Team Chat, separately, is a plain internal message board with no AI involvement.&lt;/li&gt;
&lt;li&gt;Embedding the Chatbot on Your Website
Generates embed code in three modes: Widget Bubble (floating button, customizable position/shape/color/size), Fixed Side Panel (pinned left/right), and Full Page / Inline iframe. Branding shown on free/trial tiers, removable on paid plans.&lt;/li&gt;
&lt;li&gt;FAQ
Setup time? Under 15 minutes for a working AI — documents, one channel, test in AI Chat, go live. Voice/Memory/n8n layer on afterward.
Does it replace human support entirely? No — it handles the high-volume, predictable question set (pricing, hours, order status) across every channel in 222+ languages. Judgment-based or emotionally charged conversations still route to a human.
Can I run my own model? Yes — any OpenAI-compatible endpoint via Custom API, including self-hosted.
Data privacy? Private documents/databases are visible only to Manager AI, never customer-facing bots. Self-hosted keeps everything on your own infrastructure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Originally published on the RagLeap blog, with product screenshots for each section. Try it at ragleap.com.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>saas</category>
      <category>tutorial</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>How I Built a Production RAG System with Django and Neo4j — Complete Guide</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Sat, 20 Jun 2026 07:39:43 +0000</pubDate>
      <link>https://dev.to/ragleap/how-i-built-a-production-rag-system-with-django-and-neo4j-complete-guide-44d9</link>
      <guid>https://dev.to/ragleap/how-i-built-a-production-rag-system-with-django-and-neo4j-complete-guide-44d9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahl89tpj7aaoos9xl68z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahl89tpj7aaoos9xl68z.jpg" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most RAG tutorials show you how to build a demo. This is not that.&lt;/p&gt;

&lt;p&gt;This is how we built a production RAG system that handles real business queries — connecting to live databases, answering customer questions from actual documents, and running 24/7 across WhatsApp, voice calls, and web chat simultaneously.&lt;/p&gt;

&lt;p&gt;Here is everything we learned building RagLeap — a self-hosted AI business platform — from scratch.&lt;/p&gt;

&lt;p&gt;Why We Chose Django Over FastAPI&lt;/p&gt;

&lt;p&gt;Everyone building AI systems defaults to FastAPI. We chose Django. Here is why.&lt;/p&gt;

&lt;p&gt;When you are building a product — not a microservice — Django's batteries-included philosophy saves months:&lt;/p&gt;

&lt;p&gt;Authentication and multi-tenancy out of the box&lt;br&gt;
ORM that handles complex queries without raw SQL&lt;br&gt;
Admin panel for internal tooling&lt;br&gt;
Mature migration system&lt;br&gt;
Signals for event-driven architecture&lt;/p&gt;

&lt;p&gt;We built a custom TenantMiddleware that resolves the workspace from every request context. Every database query, every RAG retrieval, every AI response is automatically scoped to the correct workspace without the developer thinking about it.&lt;/p&gt;

&lt;p&gt;pythonclass TenantMiddleware:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, get_response):&lt;br&gt;
        self.get_response = get_response&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __call__(self, request):
    workspace_id = self.resolve_workspace(request)
    request.workspace = Workspace.objects.get(id=workspace_id)
    response = self.get_response(request)
    return response

def resolve_workspace(self, request):
    # Resolve from subdomain, token, or session
    if hasattr(request, 'auth'):
        return request.auth.workspace_id
    return request.session.get('workspace_id')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2sodqkg8smsyry0rbxxs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2sodqkg8smsyry0rbxxs.jpg" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why Neo4j Instead of a Vector Database&lt;/p&gt;

&lt;p&gt;This is the question we get asked most.&lt;/p&gt;

&lt;p&gt;Standard RAG works like this:&lt;/p&gt;

&lt;p&gt;Chunk documents&lt;br&gt;
Embed chunks&lt;br&gt;
Store in vector DB&lt;br&gt;
Retrieve by similarity&lt;/p&gt;

&lt;p&gt;It works fine for simple Q&amp;amp;A. It breaks down for complex business queries.&lt;/p&gt;

&lt;p&gt;Example: "Which customers complained about delivery last month and what products did they order?"&lt;/p&gt;

&lt;p&gt;A vector search returns chunks mentioning "complaints" and "delivery." But it cannot traverse the relationship between a complaint, the customer who made it, and the orders associated with that customer.&lt;/p&gt;

&lt;p&gt;That is a graph traversal problem — exactly what Neo4j solves.&lt;/p&gt;

&lt;p&gt;In RagLeap, we build a knowledge graph from uploaded documents:&lt;/p&gt;

&lt;p&gt;pythonfrom neo4j import GraphDatabase&lt;/p&gt;

&lt;p&gt;class KnowledgeGraphBuilder:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, uri, user, password):&lt;br&gt;
        self.driver = GraphDatabase.driver(uri, auth=(user, password))&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_entity(self, entity_type, properties, workspace_id):
    with self.driver.session() as session:
        session.run(
            f"""
            MERGE (e:{entity_type} {{id: $id, workspace_id: $workspace_id}})
            SET e += $properties
            RETURN e
            """,
            id=properties.get('id'),
            workspace_id=workspace_id,
            properties=properties
        )

def create_relationship(self, from_id, to_id, relationship_type, workspace_id):
    with self.driver.session() as session:
        session.run(
            """
            MATCH (a {id: $from_id, workspace_id: $workspace_id})
            MATCH (b {id: $to_id, workspace_id: $workspace_id})
            MERGE (a)-[r:RELATES_TO {type: $rel_type}]-&amp;gt;(b)
            RETURN r
            """,
            from_id=from_id,
            to_id=to_id,
            workspace_id=workspace_id,
            rel_type=relationship_type
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Entities (customers, products, orders, policies) become nodes. Relationships become edges. When a query comes in, we combine vector similarity search with graph traversal.&lt;/p&gt;

&lt;p&gt;The result: Answers that make sense for business queries, not just keyword matches.&lt;/p&gt;

&lt;p&gt;The Hybrid Retrieval Pipeline&lt;/p&gt;

&lt;p&gt;Here is our actual retrieval pipeline that combines vector search with graph traversal:&lt;/p&gt;

&lt;p&gt;pythonclass HybridRetriever:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, vector_store, graph_db, workspace_id):&lt;br&gt;
        self.vector_store = vector_store&lt;br&gt;
        self.graph_db = graph_db&lt;br&gt;
        self.workspace_id = workspace_id&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def retrieve(self, query, top_k=5):
    # Step 1: Vector similarity search
    vector_results = self.vector_store.similarity_search(
        query,
        k=top_k,
        filter={"workspace_id": self.workspace_id}
    )

    # Step 2: Extract entities from query
    entities = self.extract_entities(query)

    # Step 3: Graph traversal from extracted entities
    graph_results = []
    for entity in entities:
        related = self.graph_db.traverse(
            entity,
            max_depth=2,
            workspace_id=self.workspace_id
        )
        graph_results.extend(related)

    # Step 4: Merge and deduplicate results
    combined = self.merge_results(vector_results, graph_results)

    return combined

def extract_entities(self, query):
    # Simple NER — in production we use spaCy or LLM-based extraction
    # Returns list of entity IDs found in query
    pass

def merge_results(self, vector_results, graph_results):
    # Score and deduplicate
    seen = set()
    merged = []
    for result in vector_results + graph_results:
        if result.id not in seen:
            seen.add(result.id)
            merged.append(result)
    return merged[:10]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Celery for Async — The Backbone of Everything&lt;/p&gt;

&lt;p&gt;Almost everything in RagLeap that is not a synchronous API response goes through Celery:&lt;/p&gt;

&lt;p&gt;Document ingestion and knowledge graph building&lt;br&gt;
Email monitoring and reply drafting&lt;br&gt;
Voice call management&lt;br&gt;
Lead follow-up automation&lt;br&gt;
WhatsApp message processing&lt;/p&gt;

&lt;p&gt;We separate Celery beat (scheduler) from Celery workers (executors). Both run as separate Supervisor processes.&lt;/p&gt;

&lt;p&gt;python# tasks.py&lt;br&gt;
from celery import shared_task&lt;br&gt;
from .knowledge_graph import KnowledgeGraphBuilder&lt;br&gt;
from .document_processor import DocumentProcessor&lt;/p&gt;

&lt;p&gt;@shared_task(bind=True, max_retries=3)&lt;br&gt;
def process_document(self, document_id, workspace_id):&lt;br&gt;
    try:&lt;br&gt;
        processor = DocumentProcessor()&lt;br&gt;
        doc = processor.load(document_id)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Extract chunks
    chunks = processor.chunk(doc, chunk_size=512, overlap=50)

    # Embed and store in vector DB
    processor.embed_and_store(chunks, workspace_id)

    # Build knowledge graph
    builder = KnowledgeGraphBuilder()
    entities = processor.extract_entities(doc)
    builder.build_graph(entities, workspace_id)

    return {"status": "success", "chunks": len(chunks)}

except Exception as exc:
    raise self.retry(exc=exc, countdown=60)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Supervisor configuration for separate worker processes:&lt;/p&gt;

&lt;p&gt;ini# /etc/supervisor/conf.d/celery.conf&lt;br&gt;
[program:celery_worker]&lt;br&gt;
command=/path/to/venv/bin/celery -A myproject worker --loglevel=info --concurrency=2&lt;br&gt;
directory=/path/to/project&lt;br&gt;
environment=PATH="/usr/bin:/usr/local/bin"&lt;br&gt;
autostart=true&lt;br&gt;
autorestart=true&lt;/p&gt;

&lt;p&gt;[program:celery_beat]&lt;br&gt;
command=/path/to/venv/bin/celery -A myproject beat --loglevel=info&lt;br&gt;
directory=/path/to/project&lt;br&gt;
autostart=true&lt;br&gt;
autorestart=true&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzw74b4fs2eqnycpih623.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzw74b4fs2eqnycpih623.jpg" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multi-Channel Architecture&lt;/p&gt;

&lt;p&gt;One AI brain serving WhatsApp, Telegram, Voice calls, Email and web chat simultaneously.&lt;/p&gt;

&lt;p&gt;The key insight: normalize everything into the same internal format before it hits the AI.&lt;/p&gt;

&lt;p&gt;pythonclass MessageNormalizer:&lt;br&gt;
    def normalize(self, raw_message, channel):&lt;br&gt;
        return {&lt;br&gt;
            "content": self.extract_content(raw_message, channel),&lt;br&gt;
            "sender_id": self.extract_sender(raw_message, channel),&lt;br&gt;
            "channel": channel,&lt;br&gt;
            "timestamp": self.extract_timestamp(raw_message, channel),&lt;br&gt;
            "metadata": self.extract_metadata(raw_message, channel)&lt;br&gt;
        }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def extract_content(self, message, channel):
    extractors = {
        "whatsapp": lambda m: m.get("body", ""),
        "telegram": lambda m: m.get("text", ""),
        "voice": lambda m: m.get("transcript", ""),
        "email": lambda m: m.get("text_body", ""),
        "web": lambda m: m.get("message", "")
    }
    return extractors[channel](message)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Channel-specific formatting happens on the way out:&lt;/p&gt;

&lt;p&gt;pythonclass ResponseFormatter:&lt;br&gt;
    def format(self, ai_response, channel):&lt;br&gt;
        formatters = {&lt;br&gt;
            "whatsapp": self.format_whatsapp,&lt;br&gt;
            "voice": self.format_voice,&lt;br&gt;
            "email": self.format_email,&lt;br&gt;
            "web": self.format_html&lt;br&gt;
        }&lt;br&gt;
        return formatters&lt;a href="https://dev.toai_response"&gt;channel&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def format_voice(self, response):
    # Remove markdown, make it conversational
    clean = response.replace("**", "").replace("#", "")
    return clean

def format_whatsapp(self, response):
    # WhatsApp supports basic markdown
    return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4kesbzp9arf3bb590ito.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4kesbzp9arf3bb590ito.jpg" alt=" " width="1024" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running Everything on a $20/Month VPS&lt;/p&gt;

&lt;p&gt;The entire stack — Django, PostgreSQL, Neo4j, Redis, Celery, Nginx, Gunicorn — runs on a 4GB RAM VPS.&lt;/p&gt;

&lt;p&gt;Key optimizations:&lt;/p&gt;

&lt;p&gt;bash# PostgreSQL — /etc/postgresql/14/main/postgresql.conf&lt;br&gt;
shared_buffers = 512MB&lt;br&gt;
effective_cache_size = 1GB&lt;br&gt;
work_mem = 16MB&lt;/p&gt;

&lt;h1&gt;
  
  
  Neo4j — /etc/neo4j/neo4j.conf
&lt;/h1&gt;

&lt;p&gt;server.memory.heap.initial_size=256m&lt;br&gt;
server.memory.heap.max_size=512m&lt;br&gt;
server.memory.pagecache.size=256m&lt;/p&gt;

&lt;h1&gt;
  
  
  Gunicorn — 2-3 workers maximum
&lt;/h1&gt;

&lt;p&gt;gunicorn myproject.wsgi:application \&lt;br&gt;
  --workers 2 \&lt;br&gt;
  --worker-class gthread \&lt;br&gt;
  --threads 4 \&lt;br&gt;
  --bind 0.0.0.0:8000&lt;/p&gt;

&lt;p&gt;Redis memory limit:&lt;/p&gt;

&lt;p&gt;bash# /etc/redis/redis.conf&lt;br&gt;
maxmemory 256mb&lt;br&gt;
maxmemory-policy allkeys-lru&lt;/p&gt;

&lt;p&gt;Result: Full AI platform running on 4GB RAM with stable performance under production load.&lt;/p&gt;

&lt;p&gt;Database AI — Connecting to Live Data&lt;/p&gt;

&lt;p&gt;One of the hardest and most powerful features: letting AI query the user's actual database in natural language.&lt;/p&gt;

&lt;p&gt;The challenge: you cannot just give an LLM a database connection and ask it to write SQL. That is a security nightmare.&lt;/p&gt;

&lt;p&gt;Our approach:&lt;/p&gt;

&lt;p&gt;pythonclass DatabaseAI:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, connection_string, workspace_id):&lt;br&gt;
        self.engine = create_engine(connection_string)&lt;br&gt;
        self.workspace_id = workspace_id&lt;br&gt;
        self.schema = self.introspect_schema()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def introspect_schema(self):
    inspector = inspect(self.engine)
    schema = {}
    for table_name in inspector.get_table_names():
        columns = inspector.get_columns(table_name)
        schema[table_name] = {
            col['name']: str(col['type'])
            for col in columns
        }
    return schema

def natural_language_query(self, question):
    # Generate safe parameterized query from schema + question
    query_template = self.llm.generate_query(
        question=question,
        schema=self.schema,
        instruction="Generate a safe READ-ONLY SELECT query. No INSERT, UPDATE, DELETE or DROP."
    )

    # Validate query is read-only
    if self.is_safe_query(query_template):
        result = self.execute_safe(query_template)
        return self.format_result(result)
    else:
        return "I can only read data, not modify it."

def is_safe_query(self, query):
    forbidden = ['INSERT', 'UPDATE', 'DELETE', 'DROP', 'TRUNCATE', 'ALTER']
    query_upper = query.upper()
    return not any(word in query_upper for word in forbidden)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This lets a business owner message their AI: "How many orders came from Chennai this week?" — and get a real answer from their actual database.&lt;/p&gt;

&lt;p&gt;Memory System&lt;/p&gt;

&lt;p&gt;RagLeap maintains persistent memory across conversations using a summarization approach:&lt;/p&gt;

&lt;p&gt;pythonclass ConversationMemory:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, workspace_id, customer_id):&lt;br&gt;
        self.workspace_id = workspace_id&lt;br&gt;
        self.customer_id = customer_id&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def get_relevant_context(self, current_query):
    # Get recent messages
    recent = ConversationHistory.objects.filter(
        workspace_id=self.workspace_id,
        customer_id=self.customer_id
    ).order_by('-created_at')[:10]

    # Get relevant historical summaries from graph
    historical = self.graph_db.get_customer_context(
        customer_id=self.customer_id,
        query=current_query,
        workspace_id=self.workspace_id
    )

    return {
        "recent": [msg.to_dict() for msg in recent],
        "historical": historical
    }

def summarize_and_store(self, conversation_chunk):
    # Periodically compress old conversations
    summary = self.llm.summarize(conversation_chunk)
    self.graph_db.store_conversation_summary(
        customer_id=self.customer_id,
        summary=summary,
        workspace_id=self.workspace_id
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What We Would Do Differently&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Separate voice processing earlier.&lt;br&gt;
Voice has completely different latency requirements from text. Running it in the same Celery worker pool as document ingestion caused priority issues we had to solve later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Observability from day one.&lt;br&gt;
Adding proper logging, metrics, and tracing after the fact is painful. Build it in from the beginning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Schema design for multi-tenancy from migration 1.&lt;br&gt;
Adding workspace isolation to an existing schema costs weeks of refactoring.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Try RagLeap&lt;/p&gt;

&lt;p&gt;If you are building AI systems for businesses or looking for a self-hosted AI platform that actually connects to your data, RagLeap has a free self-hosted tier — single workspace, web embed chatbot, and AI Manager included.&lt;/p&gt;

&lt;p&gt;GitHub open source launch coming soon — follow along at ragleap.com.&lt;/p&gt;

</description>
      <category>django</category>
      <category>neo4j</category>
      <category>rag</category>
      <category>python</category>
    </item>
    <item>
      <title>How We Built a True Agentic AI Loop in Django (ReAct Pattern)</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Sat, 23 May 2026 19:03:47 +0000</pubDate>
      <link>https://dev.to/ragleap/how-we-built-a-true-agentic-ai-loop-in-django-react-pattern-134g</link>
      <guid>https://dev.to/ragleap/how-we-built-a-true-agentic-ai-loop-in-django-react-pattern-134g</guid>
      <description>&lt;p&gt;Everyone's building "AI agents." Very few are implementing the actual ReAct pattern correctly.&lt;/p&gt;

&lt;p&gt;Here's the core loop we use in RagLeap — and why each step matters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# RagLeap ReAct Loop (simplified)
&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;think&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# REASON: build multi-step plan
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# ACT: execute real tool calls
&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# OBSERVE: did it actually work?
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;healed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;# HEAL: analyse what broke
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;healed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;retry_plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;think&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;      &lt;span class="c1"&gt;# RE-REASON: new plan with error context
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retry_plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# RE-ACT: try again differently
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: the re-plan step injects the previous error as context. The agent doesn't just retry — it reasons about WHY it failed and builds a different plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What most implementations get wrong:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No verification step — they assume the action succeeded&lt;/li&gt;
&lt;li&gt;Retry = same plan again (useless)&lt;/li&gt;
&lt;li&gt;No memory between attempts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Our stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Django + Celery for async agent tasks&lt;/li&gt;
&lt;li&gt;Neo4j for knowledge graph / memory&lt;/li&gt;
&lt;li&gt;194 registered tool functions (email, CRM, database, voice)&lt;/li&gt;
&lt;li&gt;3-layer observability: AgentTrace DB + Guardrails + Live Dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hardest part wasn't the LLM calls — it was the adaptation loop and making sure tool calls actually executed (not just "said" they did).&lt;/p&gt;

&lt;p&gt;Full architecture writeup: ragleap.com/blog/true-agentic-ai/&lt;br&gt;
Platform: ragleap.com/agentic-ai-platform/&lt;/p&gt;

&lt;p&gt;What's the trickiest part of your agent implementation?&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e94vwcmx00p7h3c71za.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e94vwcmx00p7h3c71za.png" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>django</category>
      <category>agents</category>
    </item>
    <item>
      <title>Why We Chose Self-Hosted AI Over Cloud for Business Data Posted by the RagLeap team — building RagLeap, a private-server AI business platform</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Mon, 04 May 2026 03:34:55 +0000</pubDate>
      <link>https://dev.to/ragleap/why-we-chose-self-hosted-ai-over-cloud-for-business-data-posted-by-the-ragleap-team-building-1if8</link>
      <guid>https://dev.to/ragleap/why-we-chose-self-hosted-ai-over-cloud-for-business-data-posted-by-the-ragleap-team-building-1if8</guid>
      <description>&lt;p&gt;When we started building RagLeap, the easiest path was obvious: spin up an API, connect to OpenAI, store everything in a managed cloud database, and ship fast.&lt;br&gt;
We didn't do that.&lt;br&gt;
Here's why — and what we learned after talking to hundreds of businesses about where their data actually lives.&lt;/p&gt;

&lt;p&gt;The Problem Nobody Talks About&lt;br&gt;
Most AI business tools work like this:&lt;/p&gt;

&lt;p&gt;You upload your documents, customer data, order history&lt;br&gt;
It goes to their cloud servers&lt;br&gt;
Their AI processes it&lt;br&gt;
You get answers&lt;/p&gt;

&lt;p&gt;It works. But ask yourself: where is your data right now?&lt;br&gt;
For most SaaS AI tools, the honest answer is: on someone else's infrastructure, in a jurisdiction you didn't choose, processed by models you don't control, retained for periods you didn't agree to.&lt;br&gt;
For a solo developer or a small startup, this is fine. For a law firm, a hospital, a financial institution, or any business handling customer PII — it's a compliance nightmare waiting to happen.&lt;/p&gt;

&lt;p&gt;What Our Users Actually Told Us&lt;br&gt;
Before building RagLeap, we spoke to businesses across India, the Middle East, and Africa. Three things came up repeatedly:&lt;br&gt;
"We can't send customer data outside our country."&lt;br&gt;
Data residency laws are real and growing. PDPA in Thailand, PDPB in India, GDPR in Europe. A cloud AI tool hosted in US-East doesn't care about your local compliance requirements.&lt;br&gt;
"Our database has 10 years of business history. We're not uploading that anywhere."&lt;br&gt;
This was almost universal among established businesses. Their operational data — sales records, customer interactions, inventory, communications — sits in a PostgreSQL or MySQL database on their own server. They want AI to query it. They don't want to export it.&lt;br&gt;
"We tried [Cloud AI Tool X]. Our customers' WhatsApp messages were being processed in the US."&lt;br&gt;
For businesses in regulated industries, this ended the conversation immediately.&lt;/p&gt;

&lt;p&gt;The Self-Hosted Advantage — Beyond Just Privacy&lt;br&gt;
We expected privacy to be the main argument for self-hosting. It is. But we found three other advantages that surprised us:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cost at Scale
Cloud AI tools charge per message, per document, per user. A business handling 10,000 customer interactions per month on a cloud AI platform can pay $500-2,000/month just for usage fees — before the platform subscription.
On a self-hosted RagLeap instance, you bring your own API key. You pay OpenAI or Gemini directly, at API rates. For high-volume businesses, this is 60-80% cheaper.&lt;/li&gt;
&lt;li&gt;Full Customisation Without Waiting for a Feature Request
When your AI is running on your server, you control everything. Custom voice cloning, custom knowledge graph structure, custom RAG retrieval logic, custom webhook integrations. You don't wait for the SaaS vendor to add a feature you need.&lt;/li&gt;
&lt;li&gt;Your Data Becomes Your Moat
When you connect your 10-year database to a self-hosted AI, that institutional knowledge stays with you. It doesn't train their model. It doesn't improve their product. It doesn't get retained in their servers after you cancel. It's yours — and it makes your AI smarter than any generic cloud tool.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Self-Hosted Actually Looks Like in Practice&lt;br&gt;
A common misconception is that self-hosted AI requires a dedicated ML team. It doesn't anymore.&lt;br&gt;
RagLeap runs on a standard Ubuntu VPS with 4GB RAM. Installation is a single script. You connect your database, upload your documents, configure your WhatsApp or Telegram channel, and your AI is live — talking to customers in 222+ languages, querying your real data in real-time.&lt;br&gt;
The stack:&lt;/p&gt;

&lt;p&gt;Django for the backend API&lt;br&gt;
Neo4j for the knowledge graph (this is the RAG layer)&lt;br&gt;
PostgreSQL for operational data&lt;br&gt;
Celery for async task processing&lt;br&gt;
Nginx + Gunicorn for serving&lt;/p&gt;

&lt;p&gt;All of it runs on your VPS. Your data never leaves your server unless you explicitly send it to the AI provider API of your choice — and even that can be replaced with a local model if needed.&lt;/p&gt;

&lt;p&gt;When Cloud AI Makes Sense&lt;br&gt;
We're not anti-cloud. Cloud AI tools are excellent for:&lt;/p&gt;

&lt;p&gt;Prototyping and MVPs — get something working fast&lt;br&gt;
Individuals and tiny teams — the compliance overhead of self-hosting isn't worth it&lt;br&gt;
Non-sensitive use cases — public-facing chatbots, general Q&amp;amp;A, content generation&lt;/p&gt;

&lt;p&gt;If you're a solo developer building a personal project, use whatever is fastest. Self-hosting adds operational responsibility.&lt;br&gt;
But if you're building a product for businesses — especially in regulated industries — or if you're a business with sensitive operational data, the question isn't "should we self-host?" It's "why haven't we already?"&lt;/p&gt;

&lt;p&gt;The Practical Checklist&lt;br&gt;
Before choosing between cloud AI and self-hosted, ask:&lt;/p&gt;

&lt;p&gt;Does our data contain customer PII?&lt;br&gt;
 Are we in a regulated industry (finance, health, legal)?&lt;br&gt;
 Do we operate in a country with data residency requirements?&lt;br&gt;
 Is our core business data in an existing database we can't export?&lt;br&gt;
 Do we process more than 5,000 AI interactions per month?&lt;br&gt;
 Do we need customisation beyond what the SaaS tool offers?&lt;/p&gt;

&lt;p&gt;If you checked 2 or more boxes — self-hosted AI is worth serious consideration.&lt;/p&gt;

&lt;p&gt;Where We Landed&lt;br&gt;
RagLeap is our answer to this problem. It's a self-hosted AI platform that works as your AI Engineer, Customer Support agent, Personal Secretary, and Business Manager — all running on your own server.&lt;br&gt;
It connects to your existing database. It handles WhatsApp, Telegram, Discord, Email, and Voice. It speaks 222+ languages. It runs on a $20/month VPS.&lt;br&gt;
And your data stays exactly where it should — with you.&lt;/p&gt;

&lt;p&gt;If you're building AI for businesses that care about data sovereignty, we'd love to hear how you're approaching it. Drop a comment below.&lt;br&gt;
→ ragleap.com — Free self-hosted tier available&lt;/p&gt;

</description>
      <category>ai</category>
      <category>selfhosted</category>
      <category>python</category>
      <category>rpa</category>
    </item>
    <item>
      <title>Why We Chose Self-Hosted AI Over Cloud for Business Data</title>
      <dc:creator>RagLeap</dc:creator>
      <pubDate>Sun, 03 May 2026 09:05:04 +0000</pubDate>
      <link>https://dev.to/ragleap/why-we-chose-self-hosted-ai-over-cloud-for-business-data-1of7</link>
      <guid>https://dev.to/ragleap/why-we-chose-self-hosted-ai-over-cloud-for-business-data-1of7</guid>
      <description>&lt;p&gt;Posted by the RagLeap team — building RagLeap, a private-server AI business platform&lt;/p&gt;

&lt;p&gt;When we started building RagLeap, the easiest path was obvious: spin up an API, connect to OpenAI, store everything in a managed cloud database, and ship fast.&lt;br&gt;
We didn't do that.&lt;br&gt;
Here's why — and what we learned after talking to hundreds of businesses about where their data actually lives.&lt;/p&gt;

&lt;p&gt;The Problem Nobody Talks About&lt;br&gt;
Most AI business tools work like this:&lt;/p&gt;

&lt;p&gt;You upload your documents, customer data, order history&lt;br&gt;
It goes to their cloud servers&lt;br&gt;
Their AI processes it&lt;br&gt;
You get answers&lt;/p&gt;

&lt;p&gt;It works. But ask yourself: where is your data right now?&lt;br&gt;
For most SaaS AI tools, the honest answer is: on someone else's infrastructure, in a jurisdiction you didn't choose, processed by models you don't control, retained for periods you didn't agree to.&lt;br&gt;
For a solo developer or a small startup, this is fine. For a law firm, a hospital, a financial institution, or any business handling customer PII — it's a compliance nightmare waiting to happen.&lt;/p&gt;

&lt;p&gt;What Our Users Actually Told Us&lt;br&gt;
Before building RagLeap, we spoke to businesses across India, the Middle East, and Africa. Three things came up repeatedly:&lt;br&gt;
"We can't send customer data outside our country."&lt;br&gt;
Data residency laws are real and growing. PDPA in Thailand, PDPB in India, GDPR in Europe. A cloud AI tool hosted in US-East doesn't care about your local compliance requirements.&lt;br&gt;
"Our database has 10 years of business history. We're not uploading that anywhere."&lt;br&gt;
This was almost universal among established businesses. Their operational data — sales records, customer interactions, inventory, communications — sits in a PostgreSQL or MySQL database on their own server. They want AI to query it. They don't want to export it.&lt;br&gt;
"We tried [Cloud AI Tool X]. Our customers' WhatsApp messages were being processed in the US."&lt;br&gt;
For businesses in regulated industries, this ended the conversation immediately.&lt;/p&gt;

&lt;p&gt;The Self-Hosted Advantage — Beyond Just Privacy&lt;br&gt;
We expected privacy to be the main argument for self-hosting. It is. But we found three other advantages that surprised us:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cost at Scale
Cloud AI tools charge per message, per document, per user. A business handling 10,000 customer interactions per month on a cloud AI platform can pay $500-2,000/month just for usage fees — before the platform subscription.
On a self-hosted RagLeap instance, you bring your own API key. You pay OpenAI or Gemini directly, at API rates. For high-volume businesses, this is 60-80% cheaper.&lt;/li&gt;
&lt;li&gt;Full Customisation Without Waiting for a Feature Request
When your AI is running on your server, you control everything. Custom voice cloning, custom knowledge graph structure, custom RAG retrieval logic, custom webhook integrations. You don't wait for the SaaS vendor to add a feature you need.&lt;/li&gt;
&lt;li&gt;Your Data Becomes Your Moat
When you connect your 10-year database to a self-hosted AI, that institutional knowledge stays with you. It doesn't train their model. It doesn't improve their product. It doesn't get retained in their servers after you cancel. It's yours — and it makes your AI smarter than any generic cloud tool.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What Self-Hosted Actually Looks Like in Practice&lt;br&gt;
A common misconception is that self-hosted AI requires a dedicated ML team. It doesn't anymore.&lt;br&gt;
RagLeap runs on a standard Ubuntu VPS with 4GB RAM. Installation is a single script. You connect your database, upload your documents, configure your WhatsApp or Telegram channel, and your AI is live — talking to customers in 222+ languages, querying your real data in real-time.&lt;br&gt;
The stack:&lt;/p&gt;

&lt;p&gt;Django for the backend API&lt;br&gt;
Neo4j for the knowledge graph (this is the RAG layer)&lt;br&gt;
PostgreSQL for operational data&lt;br&gt;
Celery for async task processing&lt;br&gt;
Nginx + Gunicorn for serving&lt;/p&gt;

&lt;p&gt;All of it runs on your VPS. Your data never leaves your server unless you explicitly send it to the AI provider API of your choice — and even that can be replaced with a local model if needed.&lt;/p&gt;

&lt;p&gt;When Cloud AI Makes Sense&lt;br&gt;
We're not anti-cloud. Cloud AI tools are excellent for:&lt;/p&gt;

&lt;p&gt;Prototyping and MVPs — get something working fast&lt;br&gt;
Individuals and tiny teams — the compliance overhead of self-hosting isn't worth it&lt;br&gt;
Non-sensitive use cases — public-facing chatbots, general Q&amp;amp;A, content generation&lt;/p&gt;

&lt;p&gt;If you're a solo developer building a personal project, use whatever is fastest. Self-hosting adds operational responsibility.&lt;br&gt;
But if you're building a product for businesses — especially in regulated industries — or if you're a business with sensitive operational data, the question isn't "should we self-host?" It's "why haven't we already?"&lt;/p&gt;

&lt;p&gt;The Practical Checklist&lt;br&gt;
Before choosing between cloud AI and self-hosted, ask:&lt;/p&gt;

&lt;p&gt;Does our data contain customer PII?&lt;br&gt;
 Are we in a regulated industry (finance, health, legal)?&lt;br&gt;
 Do we operate in a country with data residency requirements?&lt;br&gt;
 Is our core business data in an existing database we can't export?&lt;br&gt;
 Do we process more than 5,000 AI interactions per month?&lt;br&gt;
 Do we need customisation beyond what the SaaS tool offers?&lt;/p&gt;

&lt;p&gt;If you checked 2 or more boxes — self-hosted AI is worth serious consideration.&lt;/p&gt;

&lt;p&gt;Where We Landed&lt;br&gt;
RagLeap is our answer to this problem. It's a self-hosted AI platform that works as your AI Engineer, Customer Support agent, Personal Secretary, and Business Manager — all running on your own server.&lt;br&gt;
It connects to your existing database. It handles WhatsApp, Telegram, Discord, Email, and Voice. It speaks 222+ languages. It runs on a $20/month VPS.&lt;br&gt;
And your data stays exactly where it should — with you.&lt;/p&gt;

&lt;p&gt;If you're building AI for businesses that care about data sovereignty, we'd love to hear how you're approaching it. Drop a comment below.&lt;br&gt;
→ ragleap.com — Free self-hosted tier available&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyp35zj4px6e826ym0na.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyp35zj4px6e826ym0na.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>selfhosted</category>
      <category>python</category>
      <category>rpa</category>
    </item>
  </channel>
</rss>
