惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Scott Helme
Scott Helme
N
Netflix TechBlog - Medium
AI
AI
Security Latest
Security Latest
GbyAI
GbyAI
P
Proofpoint News Feed
Y
Y Combinator Blog
A
Arctic Wolf
G
Google Developers Blog
U
Unit 42
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Vulnerabilities – Threatpost
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
T
Tor Project blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
C
Check Point Blog
B
Blog RSS Feed
The GitHub Blog
The GitHub Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 【当耐特】
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
Cisco Blogs
云风的 BLOG
云风的 BLOG
NISL@THU
NISL@THU
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
Latest news
Latest news
L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
WordPress大学
WordPress大学
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
The Hacker News
The Hacker News
Simon Willison's Weblog
Simon Willison's Weblog
V
V2EX
Project Zero
Project Zero
博客园_首页

Towards AI

Building AI Agents in Rust — part 4 | Towards AI Building AI Agents in Rust — part 5 | Towards AI The Verified Identity Agent Bridge | Towards AI You Can’t Prompt Your Away Your LLM Problems | Towards AI The Free Agent Trap | Towards AI Your Agentic Loop Will Drift. Here Is the KL Divergence Equation That Measures How Far It Has Wandered From Its Original Instruction. | Towards AI Beyond Chat: Processing Images, PDFs, and Documents with the OpenAI Adapter in Oracle Integration Cloud | Towards AI Building AI Agents in Rust — part 3 | Towards AI Self-Hosting Airflow at Home: Automating Stock Price Data Collection | Towards AI The 76-Hour Frontier: How the Takedown of Claude Fable 5 Birthed the Military-Industrial-AI Complex | Towards AI I Trained a Markdown File to Boost GPT-5.5 by 23 Points — It Shouldn't Work | Towards AI We Replaced ChatGPT With a Local AI Server. Six Months of Honest Data. | Towards AI What Really Makes Cars Pollute? A Data Science Deep Dive into CO₂ Emissions | Towards AI Training GPT-2 From Scratch on a GTX1050 | Towards AI Principal Component Analysis (PCA): Theory, Mathematics, and Applications Build a Zero-Cost Web Automation Pipeline With OpenRouter, OpenClaw, and MediaUse I Gave Qwen3.7-Plus a Screenshot and It Found the Exact Pixel to Click for $0.40 Beyond the Prompt: Why Autonomous AI Agents Are Replacing the Chatbot Moonshot Cracked Claude Code’s Playbook with an MIT Terminal Agent and a $0.60 Model Connections, Roles, and Warehouses: Getting CoCo Desktop Production-Ready from Day One My First $5,000 Month Writing About AI Engineering on Medium Google Shrank Gemma 4 by 72% and Unsloth Fixed the 4-Bit Bug Nobody Else Caught on One 4090, and 4-Bit Shouldn’t Be This Good LangChain Explained: Understanding Models, Prompts, Chains, Memory, Indexes, and Agents TOON: Beyond JSON for LLMs Claude Code Casual, Pro, Elite: The Three Working Personas of Claude Code Mastery MiniMax M3 Decodes 1M Tokens 15x Faster — and It Shouldn’t Be This Cheap Using Amazon SQS for AI Agent Orchestration I Ran a 1.5B-Active Model on My Laptop That Embarrassed a 26B by 46 Points How to Build a Self-Improving Company with AI Part 3 — Implementation/Engine-Level: Choosing the Runtime That Gives You These for Free Part 2 — Serve-Level Speed: System Design That Stabilizes P95/P99 3-Part Series: LLM Latency in Production (Part 1) Claude Code: The AI Coding Partner Changing How Developers Build Software Claude Code Pitfalls: Claude Code Won’t Do What You Told It: A Troubleshooting Catalog Full-Stack Data Scientists for the Agentic Coding World Building Production-Grade AI Skills with Snowflake Cortex AI Function Studio I Tried 10 AI Agent Frameworks in 2026 — Here’s the Honest Guide I Wish I Had Earlier How One Spring Boot Optimization Saved Our Startup $30,000 a Year Inside Palantir AIP: How the World’s Most Controversial AI Platform Actually Works What Is a Reverse Proxy? (And Why Every Backend Developer Should Care) What Claude Opus 4.8 Actually Changes If You’re Building Agents QWEN 3.7 Max Worked For 35 Hrs Straight And The Results Were Mind-blowing When LLMs Meet Knowledge Graphs on the Battlefield Fine-Tuning is Dead: Why Context Orchestration Won in 2026 Google Co-Scientist: Hyper Scaling Research and Discovery Microsoft Just Embarrassed Browser Web Agents — 1,000 Lines Made GPT-5.4 Beat Opus 4.6 on 200 Web Tasks The Modern Data Stack Is Broken — Here’s How to Fix It With AI, Governance, and Real Architecture Building Production MCP Servers: What the Spec Won’t Tell You When Should an Agent Stop? The Anatomy of Termination Harness Engineering: The Layer That Matters More Than the Model AI Engineers Who Can’t Debug Are Getting Fired (Here’s How I Debug with Claude Code) Claude Code Memory: Why You Keep Explaining the Same Thing to Claude (and the Five Layers That Fix It) Claude Code Subagents: The Claude Code Feature You Skip Every Day (And Why It Quietly Wrecks Your Sessions) Agentic AI and the SMB Banking Advantage Claude Code: Spec-Driven Development — Why Your AI Coding Sessions Fall Apart at Hour Three The Real Cost of Agentic AI Nobody Budgets For SVM : 40 must visit Interview Questions (Part 2) Your AI Agent Works Perfectly in the Demo. Here Are the 6 Ways It Dies in Production. Unleashing the Power of ONNX for Speedier SBERT Inference Terraform vs CI/CD for Serverless Deployments Merve Noyan Stopped Writing Training Scripts — Her Agent Just Fine-Tuned 18 Models Solo for $11.40 Why Your Sales Forecast Is Always 20% Wrong (And How To Make It 12% Wrong) Genetic Cubic n{C/A} Ratios For Elementary Robotics Design Top 20 AdaBoost Interview Questions & Answers (Part 2 of 2) Agentic AI Vs AI Agents — What Are the Key Differences? LAI #127: The Infrastructure Layer of AI Is Becoming the Product Anthropic Caught Its Own AI Planning to Blackmail Engineers RNNs Cannot Think What Transformers Think Cheaply. ICLR 2026 Proved the Gap Is Exponential. Time Series Made So Easy My Aunt Got It on the Second Read Claude Cowork 101 | Towards AI Is 3-Bit KV Cache the Holy Grail? A Reality Check on Google’s TurboQuant LangGraph Multi-Agent Architecture: Building a Self-Critiquing AI Debate System AutoML on Autopilot | Towards AI I Ran This Open-Source AI Tool on a Messy Codebase and Got 71x Fewer Tokens — Here Is Exactly What Happened Month in 4 Papers (April 2026) AI Kept Forgetting My Notes. Fixing That Taught Me How It Actually Works. How ChatGPT Makes You Addicted Crack ML Interviews with Confidence: K-Nearest Neighbors (KNN 20 Q&A) The Event-Driven Blueprint: How I Scaled a Spring Boot System to 10 Million Kafka Messages/Day Building Vector Search? Why FAISS Alone Isn’t Enough TAI #202: GPT-5.5 Moves Codex Into Real Work Machine Learning System Design -The Model Serving Triangle, With One Forward Pass Flowing Through Every Trade-off (Part3) AI Orchestration in Action: How MuleSoft and LLMs Fuel the Future of Enterprise AI GPT-4 Has 1.8 Trillion Parameters. It Uses 2% of Them Per Token. Part 20: Data Manipulation in Multi-Dimensional Aggregation A Fundamental Introduction to Genetic Algorithm -Part Two TAI #200: Anthropic’s Mythos Capability Step Change and Gated Release From Notebook to Production: Running ML in the Real World (Part 4) Sqribble’s Template‑Driven Document Automation Anthropic Just Shipped the Layer That’s Already Going to Zero Long-Term vs Short-Term Memory for AI Agents: A Practical Guide Without the Hype The L1 Loss Gradient, Explained From Scratch Your Postcode Is Deciding Your Care. I Built a Pipeline to Prove It. I Directed AI Agents to Build a Tool That Stress-Tests Incentive Designs. Here’s What It Found. Your System Prompt Is the Product — Not the Feature The LLM Wiki Trend Has a Retention Problem Nobody Mentions Top 20 Data Preparation Interview Questions and Answers (Part 2 of 2) LAI #122: Word Embeddings Started in 1948, Not With Word2Vec Top 15 Computer Vision Datasets [2026] 40 Generative AI Interview Questions That Actually Get Asked in 2026 (With Answers)
5 Things Broke When I Shipped a RAG + MCP Agent to Production.
Editorial Team · 2026-05-27 · via Towards AI

Author(s): Sudip P.

Originally published on Towards AI.

5 Things Broke When I Shipped a RAG + MCP Agent to Production.
Diagram-1: RAG vs MCP agent architecture: a small LLM router classifies each user query as either a Knowledge request (hybrid search → cross-encoder rerank) or an Action request (validate input → tool call). Both paths converge at a single frontier model for synthesis, then pass through eval and logging before returning a response.

Read this article for free: link

TL;DR (because you’re busy)

  • Demos lie. Production finds your dumb mistakes.
  • Vector‑only search is a trap. Hybrid + rerank or go home.
  • MCP tools will return null and ruin your night. Validate. Timeout. Return structured errors.
  • Keyword routers die on real users. Use a small LLM as router. Cache stuff.
  • Build the eval harness on day zero. No evals, no clue.

6:14 a.m. and I want to quit

6:14 a.m. Slack explodes. On-call guy asks our shiny new agent why a pipeline job stalled.

Agent replies, all calm and confident like a junior consultant who just read a blog: “This job is covered under the Tier-2 SLA with a 4-hour response window.”

The real SLA is 30 minutes. The job had been dead for 90.

I open the trace. Someone already filed a PagerDuty ticket. Title: “agent gave wrong SLA again”. The “again” part is what really stung.

Quick context (if you missed my last post): RAG gets knowledge from a static index. MCP lets the model call live tools. On my laptop, with two test queries, it felt like magic. In prod, with 80 users pasting real Slack threads, it felt like a liability.

Here’s what broke. Here’s what I did. Some of it worked.

The whole mess (how it should work)

Diagram 2 — A production agent pipeline drawn as a single-board layout. User queries enter through edge connector J1, get classified by the U1 router, and check the U2 cache. On a miss, two parallel rails fire: the RAG pipeline (normalize, hybrid search, rerank) builds context, while the MCP tools (validate, timeout/retry, structured result) handle side-effecting calls. Both feed into U9, the frontier model, which synthesizes the answer. From there, copper traces loop the output through observability and the eval harness before delivering it to J2. Every stage is independent, measurable, and replaceable, just like real PCB components.

A small LLM router decides whether the user query needs knowledge (RAG) or a live action (MCP). The RAG pipeline uses hybrid search (BM25 + vector) plus a cross‑encoder reranker to find relevant chunks. MCP tools validate inputs, enforce timeouts and retries, and return structured {ok, error, detail} responses. Both paths feed into a frontier model for synthesis, then through an eval and logging layer before the final response. Every box here exists because something broke without it.

If you want the calm, demo-version of this same architecture before any of it broke, the original write-up walks through it end-to-end.

Breakage #1: Retrieval gave me the wrong SLA

What failed: The model didn’t hallucinate. The retriever just handed it the wrong chunk. “Tier-1 SLA for streaming” and “Tier-2 SLA for batch” are really close in vector space. To a human at 3 a.m., they are completely different.

Why: Vector similarity is not relevance. Embeddings smooth over the exact words you actually care about.

Fix: Two things, both required.

First, hybrid search: BM25 (keyword) plus vector, combined with reciprocal rank fusion. BM25 catches literal terms like “Tier-1” and “streaming” that embeddings blur together.

Second, rerank the top 20 candidates with a cross-encoder. Cross-encoders look at the query and chunk together. They catch the “semantically close but factually wrong” cases.

Here’s the code I wish I’d started with. Not perfect, but you get the idea.

# Not real code, but you get the idea
def retrieve(query, k=5):
candidates = hybrid_search(query, k=20) # BM25 + vector
reranked = rerank_model.rerank(query, candidates, top_n=k)
return reranked

How to detect
Log the chunk IDs for every answer. When users complain, you need to see instantly if retrieval failed or synthesis failed. Add a “retrieval precision” metric to your eval set. For each golden query, did the right chunk show up in top 5?

Breakage #2: MCP tool returned null and the model said “all good”

What failed: The MCP tool called the job status API. The API timed out and returned null. The model saw null, interpreted it as "no issues", and cheerfully told the user everything was fine. The job was actually dead for 90 minutes.

Why: No validation on the tool output. No distinction between null (no data) and {"status": "ok"}. The model treated both as success.

Fix: Wrap every tool call in a structured result. Validate inputs. Enforce timeouts. Return an explicit ok flag. Never let a raw null reach the model.

def get_job_status(job_id):
try:
validate(job_id)
data = call_api(job_id, timeout=5.0)
return {"ok": True, "data": data}
except TimeoutError:
return {"ok": False, "error": "upstream_timeout"}
except Exception as e:
return {"ok": False, "error": "upstream_failure", "detail": str(e)}

When the tool returns {"ok": false, "error": "upstream_timeout"}, the model can say "I couldn't reach the job system – please retry." That is the answer you want at 3 a.m.

How to detect: Emit a metric per tool call. Label it with tool name, ok/error, and error category. Alert on error rate. The first tool to drift is never the one you expect.

What actually happens when a tool fails (vs what you think happens)

Diagram 3 — The silent API timeout that turns null into "success" – why your agent needs explicit null checks and timeout handling, not just error handling. That second path ruined my week.

Breakage #3: Keyword router didn’t survive first contact with users

What failed.
My demo router was 12 lines of if statements.
if "job" in query: do this. elif "sla" in query: do that.

I knew it was bad. I shipped it anyway.

Real users don’t type “what is the SLA for job 1234”. They type “hey is the prod thing borked again lol” and paste a 600‑word Slack thread. Keyword routers die on that.

Why.
Intent classification is genuinely hard. You cannot write enough rules to cover paraphrase, sarcasm, multi‑intent, and copy‑pasted garbage.

Fix.
Three levels:

  • Keyword router → fast and free, but brittle.
  • LLM‑as‑router (small model returning a JSON route) → handles ambiguity, adds one cheap hop.
  • Full tool use with frontier model → most accurate, most expensive.

From my deployment (rough numbers)

Diagram 4 — Latency and cost scale significantly with model size. The small LLM router offers a strong middle ground — 90% accuracy at 20× lower cost and 3.6× lower latency than a frontier model — making it the default choice for most routing decisions in a tiered pipeline.

We settled on small LLM for the first hop, frontier only for synthesis. The 5‑point accuracy gap was not worth 20× the cost for most queries.

How to detect.
Log routing decisions. Overlay with user satisfaction (thumbs down, follow‑ups, escalations). Clusters of follow‑ups usually mean the router fired wrong.

Breakage #4: I didn’t check the bill for two weeks

What failed:
Two weeks after launch I checked cloud costs. Daily spend was 300–300–400. Trending up. 80 daily active users.

Then I opened the latency dashboard. P50 was 6 seconds. P95 was 14 seconds. User satisfaction chart was basically an inverse of the latency curve. That chart ruins your afternoon.

Why:
A single query was doing 5+ model calls and 2+ tool calls, each with retries. No caching. No parallelism. Everything ran through the frontier model because that’s what the demo did.

Fix:
Four levers, in order of impact.

  1. Embedding cache → hash the input query, store the vector. “Is the pipeline down” comes in fifty flavors. Normalize it and hit the cache.
  2. Tool‑result cache with TTLs → job statuses don’t change every second. Short TTL on status, long TTL on SLA lookups. Cut tool calls a lot.
  3. Smaller models for boring hops → routing, query reformulation, intent extraction. All on a cheap model. Frontier only for final synthesis.
  4. Async tool execution → if two tools don’t depend on each other, run them in parallel. asyncio.gather. Boring, but shaved a full second off P50.

How to detect.
Tag every span with token counts and estimated dollar cost. Build a dashboard with tokens.in, tokens.out, latency.p50, latency.p95, and cost.per_query. Look at it every morning with your coffee.

Where your latency and money actually go (spoiler: not where you think)

Diagram 5 — Where your latency and money actually go (spoiler: not where you think)

That pie chart made me redo my caching strategy.

Breakage #5: I had no evals. Then I upgraded an embedding model and broke everything.

What failed:
For the first month my eval suite was “I tried it and it seemed fine.” Then I upgraded the embedding model. Retrieval got quietly worse. I noticed three days later, because a user complained.

Why:
Without an eval harness, every change is a coin flip. You cannot tell if you improved one thing or broke another.

Fix:
Build a golden dataset. 100 real queries from your logs. Each annotated with the expected tool calls and the specific facts the answer must contain. Not “the answer should mention the SLA” but “the answer must contain the string ’30 minutes’”. Deterministic checks catch deterministic regressions.

Then layer LLM‑as‑judge on top for the squishy stuff: tone, completeness, whether it answered the actual question. Use a different model than your agent. Do not let the chef grade their own cooking.

Run the suite on every PR. Block merges on deterministic regressions. Treat judge scores as a trend line, not a gate.

How to detect.
This is the detector. The whole point is that the harness tells you when something broke before your users do.

What I got wrong before production (a short, sad list)

  • “The retrieval looks pretty good” is not a measurement. It’s a feeling. Feelings ship bugs.
  • I assumed MCP tools were reliable because they worked in the demo. Demos run on healthy networks against warm caches.
  • I underestimated how creative real users would be with input. The keyword router survived me and three teammates. It did not survive the whole engineering org.
  • I thought I would add evals “once the system stabilized”. Systems don’t stabilize without evals. That’s how you know if they are stable.
  • I optimized latency where it didn’t matter (one LLM call) and ignored it where it did (sequential tool calls that could have run in parallel).
  • I named tools generically (get_data, lookup). The model hallucinated arguments. Specific names with descriptive schemas reduced tool‑argument hallucinations more than any prompt change I tried.

The checklist I use now (no shipping without these)

  • Hybrid search (BM25 + vector) with reranking over top‑20.
  • Pydantic validation on every tool input.
  • Per‑tool timeouts and bounded retries with exponential backoff.
  • Structured {ok, error, detail} responses from every tool. No silent nulls. Ever.
  • Routing on a small model with logged decisions. Fallback to frontier for ambiguous queries.
  • Embedding cache keyed on normalized query string.
  • Tool‑result cache with explicit per‑tool TTLs.
  • Async tool execution for independent calls.
  • Tokens, latency, and dollar estimate emitted on every span.
  • Golden eval set in version control. Deterministic + judge checks. Run on every PR.
  • Daily dashboard with cost.per_query, latency.p95, tool.error_rate by tool name.
  • Rollback story for model version, prompt version, index version. When things go sideways, you need to go back fast.

Closing (go to sleep)

If I started over tomorrow, I would build the eval harness on day one and the agent on day two. Almost everything I learned the hard way comes back to not being able to measure regressions.

The second-hardest lesson: tool boundaries are where trust leaks fastest. Structured error returns matter more than any clever prompt.

My pipeline agent is now branchier than that first diagram. It fetches a job status. Decides if the runbook applies. Maybe calls a second tool based on what the runbook says. Loops back if data went stale mid-answer. That’s not a straight line anymore. That’s a graph.

New here? Part 1 covers the RAG vs MCP split this piece builds on, start there if any of this felt thin.

Next piece: orchestrating multi-step RAG + MCP workflows with LangGraph. Including the parts that broke when I tried to put a real loop into production.

Liked this? Clap, comment, or rage‑tweet at me. I’ve earned it.

If you’re preparing for a GenAI interview

I failed my first AI engineer interview. Here’s the complete playbook I built to never fail again.

The 10 Questions That Decide Whether You’re an AI Engineer or Just an AI User

If you are trying to test the best chunking strategies, read this:

Chunking Strategies in RAG Systems: Insights from 80+ GenAI Interviews — A story from the other side of the table.

If you want to understand why you should build your own MCP host, read this:

Why You Should Build Your Own MCP Host: A Python Deep‑Dive Into the Agentic Loop — M models, N tools, M×N headaches.

Published via Towards AI