
RAG 在 Agent 中的使用从强制检索到按需检索你搭了一个 RAG 系统不管用户问什么都先去向量数据库搜一遍。用户问什么是 HTTP 协议——搜了一遍返回的全是公司内部文档里提到 HTTP 的段落没一条有用的。模型忽略了这些噪声靠自己的知识回答了但你白白多花了 50ms 延迟和一次 Embedding 调用的钱。这篇文章讲一件事RAG 不应该是一条硬编码的流水线而应该是 Agent 工具箱里的一把工具——什么时候用、查什么关键词、查几条全由 LLM 自己判断。一、传统 RAG 的尴尬不管该不该查每次都查第四章讲的 RAG 是一种Pipeline 模式用户提问 → Embedding → 向量检索 → 拼接 Prompt → LLM → 回答每次请求不管问题类型强制走一遍检索。这在知识库问答这个垂直场景里没问题——用户进来就是问公司政策的。但如果你想建一个通用助手问题就来了用户什么是余弦相似度 Pipeline RAG 的处理 ① Embedding(什么是余弦相似度) → 查询向量 ② 向量数据库检索 Top-3 → 返回公司内部文档中提到相似度的段落 ③ 把这些不相关的文档片段塞进 Prompt ④ LLM 要么被误导要么忽略噪声自己回答 问题 - 浪费了一次 Embedding 计算~20ms - 浪费了一次向量检索~30ms - 更危险的是如果内部文档恰好有余弦相似度相关段落 但内容不够准确LLM 可能基于错误文档回答 用户帮我查一下 Q2 的 KPI 达成率 Pipeline RAG 的处理 ① → ② → ③ → ④ 同上 ✓ 这次检索是有价值的因为这是私有数据一个是通用知识一个是私有数据——Pipeline RAG 无法区分一律检索。问题的核心是谁来决定要不要查在 Pipeline 模式下没有人决定——流水线是硬编码的。二、Agentic RAG让 LLM 自己决定要不要查答案是把决策权交给 LLM。具体做法把 RAG 的检索能力注册为一个工具让 LLM 根据问题类型自主判断是否调用。这就是Agentic RAG——RAG 不再是一条管道而是 Agent 工具箱里的一个工具。Pipeline RAG传统 用户提问 → [强制] 向量检索 → 增强 Prompt → LLM → 回答 Agentic RAGAgent 模式 用户提问 → LLM 推断 ├─ 这是公司内部数据 → 调用 search_knowledge_base 工具 → 拿到文档 → 生成回答 └─ 这是通用知识 → 直接回答不检索两个模式的本质区别Pipeline RAGAgentic RAG检索决策者硬编码永远检索LLM按需检索查询词控制用户原始问题LLM 可改写查询词检索次数固定 1 次LLM 可多次追问适用范围单一知识库问答多工具通用助手三、完整流程一个 Agent 处理两类问题先看两个真实交互过程理解 LLM 是如何做出查 / 不查决策的场景 1通用知识 → 直接回答用户什么是余弦相似度 Agent 内部过程 ① LLM 收到问题 工具列表 ② LLM 推断余弦相似度是数学概念训练数据里有不需要查公司知识库 ③ LLM 选择 stop_reasonend_turn直接输出文本回答 ④ 结束 API 调用次数1 次 向量检索次数0 次场景 2私有数据 → 先检索再回答用户我们 2025 年 Q2 的 KPI 达成率是多少 Agent 内部过程 ① LLM 收到问题 工具列表 ② LLM 推断Q2 KPI 是公司内部数据我不知道需要查知识库 ③ LLM 选择 stop_reasontool_use调用工具 search_knowledge_base(query2025年Q2 KPI达成率) ④ 工具执行向量检索返回 2025年Q2核心经营数据整体KPI达成率94%销售KPI达成118%研发KPI达成89%... ⑤ 把工具返回结果喂回 LLM ⑥ LLM 基于检索结果生成最终回答 API 调用次数2 次一次判断 一次生成 向量检索次数1 次关键观察LLM 做了一个条件分支——Pipeline RAG 做不到的事。并且在场景 2 中LLM 自己改写了查询词——用户原文是我们 Q2 的 KPILLM 传给工具的是2025年Q2 KPI达成率补充了年份并去掉了口语化的我们这能提升向量检索的召回率。四、消息循环Agent 是怎么跑起来的Agentic RAG 的运行机制和第七章讲的 Agent 循环完全一致——while True循环根据stop_reason决定下一步┌──────────────┐ │ 用户提问 │ └──────┬───────┘ │ ▼ ┌───────────────────────┐ ┌────│ LLM 推断带工具列表 │ │ └───────────┬───────────┘ │ │ │ stop_reason 是什么 │ │ │ │ tool_use end_turn │ │ │ │ ▼ ▼ │ ┌──────────────┐ ┌──────────┐ │ │ 执行 RAG 检索 │ │ 返回回答 │ │ └──────┬───────┘ └──────────┘ │ │ │ ▼ │ ┌──────────────┐ └───┤ 工具结果喂回 │ │ LLM 继续推断 │ └──────────────┘对应到消息列表messages整个过程的数据流是这样的── 第一轮 ── messages [ {role: user, content: Q2 KPI 达成率} ] → LLM 返回 stop_reasontool_use → content 里包含tool_use(namesearch_knowledge_base, input{query: ...}) ── 第二轮 ── messages [ {role: user, content: Q2 KPI 达成率}, {role: assistant, content: [tool_use块]}, ← LLM 的调用意图 {role: user, content: [tool_result块]}, ← 工具执行结果 ] → LLM 返回 stop_reasonend_turn → 输出最终回答 ── 结束 ──核心设计assistant 的工具调用意图和 user 的工具执行结果必须成对出现。这是 Anthropic Tool Use API 的协议约束——LLM 说我要查知识库你必须告诉它查到了什么它才能继续。五、工具描述决定 LLM 判断准确率的关键LLM 靠什么判断要不要调用 RAG靠工具的description。这个 description 写得好不好直接决定了 LLM 的路由准确率# ❌ 模糊的 description → LLM 判断不准{name:search_knowledge_base,description:搜索知识库}# LLM 遇到什么是 HTTP时也可能调用因为知识库太宽泛# ✓ 精确的 description → LLM 判断准确{name:search_knowledge_base,description:(搜索公司内部知识库。当问题涉及公司政策、产品文档、经营数据、技术架构等私有信息时调用。对于通用知识编程概念、科学原理、常识性问题不需要调用此工具。)}# 明确告诉 LLM什么时候该调、什么时候不该调工程结论工具 description 不只是给人看的文档——它是 LLM 的决策依据。写 description 时要回答两个问题什么时候该调这个工具以及什么时候不该调。否定条件和肯定条件一样重要。六、完整代码可运行的 Agentic RAG下面这段代码实现了一个完整的 Agentic RAG Agent。它由四个部分组成模拟的公司内部文档、基于 ChromaDB 的知识库负责离线索引和在线检索、Agent 循环LLM 自主决策是否调用 RAG、以及测试用例。Agent 的核心是一个while True循环——当 LLM 返回tool_use时执行检索并把结果喂回去当返回end_turn时直接输出答案。这个设计让 RAG 成为一个可选工具而不是强制步骤。 Agentic RAG 完整示例 传统 RAG用户提问 → 强制检索 → 增强 Prompt → LLM Agentic RAG用户提问 → LLM 推断 → [需要] 调用 RAG 工具 → LLM 生成回答 → [不需要] 直接回答 依赖pip install anthropic chromadb importosimportchromadbfromchromadb.utils.embedding_functionsimportDefaultEmbeddingFunctionimportanthropic# ─────────────────────────────────────────────────────────# 1. 模拟公司内部文档知识库原料# ─────────────────────────────────────────────────────────COMPANY_DOCS[{id:hr-leave,source:HR手册-休假政策,content:(年假政策正式员工入职满1年享有10天带薪年假满3年15天满5年20天。年假申请需提前5个工作日提交超过5天须部门总监审批。当年未使用的年假可结转至次年3月底逾期作废。),},{id:hr-bonus,source:HR手册-薪酬福利,content:(年终奖在次年2月随工资发放按全年绩效评分计算S级月薪×4A级月薪×3B级月薪×2C级及以下不发年终奖。绩效评定结果每年12月由直属上级与HR共同确认。),},{id:prod-platform,source:产品文档v2.3-支持平台,content:(智能客服系统支持Web端、iOS App、Android App、微信小程序四个平台。API协议支持RESTful和WebSocketSLA承诺99.9%可用性P99延迟500ms。数据存储符合ISO 27001和SOC 2 Type II认证要求。),},{id:prod-pricing,source:产品文档v2.3-定价方案,content:(定价方案基础版1999元/月5坐席专业版4999元/月20坐席企业版9999元/月无限坐席专属客户成功经理私有化部署选项。年付享9折三年付享8折。),},{id:kpi-q2-2025,source:2025年Q2季报,content:(2025年Q2核心经营数据营收同比增长37%DAU突破280万环比12%NPS满意度评分72分付费转化率从8.3%提升至11.2%整体KPI达成率94%其中销售KPI达成118%研发KPI达成89%。),},{id:tech-arch,source:技术架构文档v3.0,content:(系统采用微服务架构核心服务用户服务、会话服务、模型调度服务、向量检索服务。向量数据库使用Qdrant生产Embedding模型text-embedding-3-small1536维LLM使用Claude Sonnet 4.6部署在K8s集群跨可用区高可用。),},]# ─────────────────────────────────────────────────────────# 2. 知识库离线索引 在线检索# ─────────────────────────────────────────────────────────classKnowledgeBase:封装 ChromaDB负责文档向量化索引和相似度检索def__init__(self,collection_name:strcompany_docs):self.clientchromadb.Client()# all-MiniLM-L6-v2首次运行自动下载约 80MBself.efDefaultEmbeddingFunction()self.collectionself.client.create_collection(namecollection_name,embedding_functionself.ef,# 使用余弦相似度作为距离度量metadata{hnsw:space:cosine},)self._build_index()def_build_index(self):离线阶段文档 → Embedding → 存入向量数据库print([ 离线阶段 ] 正在建立向量索引...)self.collection.add(ids[d[id]fordinCOMPANY_DOCS],documents[d[content]fordinCOMPANY_DOCS],metadatas[{source:d[source]}fordinCOMPANY_DOCS],)print(f[ 离线阶段 ] 完成共索引{len(COMPANY_DOCS)}个文档片段\n)defsearch(self,query:str,top_k:int3)-str:在线检索问题向量化 → 余弦相似度搜索 → 返回 Top-K 片段resultsself.collection.query(query_texts[query],n_resultstop_k)chunks[]fordoc,meta,distinzip(results[documents][0],results[metadatas][0],results[distances][0],):# ChromaDB 返回的 cosine distance 1 - similaritysimilarity1-dist chunks.append(f[来源:{meta[source]}| 相似度:{similarity:.2f}]\n{doc})return\n\n.join(chunks)# ─────────────────────────────────────────────────────────# 3. AgentLLM 自主决定是否调用 RAG# ─────────────────────────────────────────────────────────# 工具定义description 是 LLM 判断要不要调用的唯一依据# 必须写清楚两件事什么时候该调、什么时候不该调TOOLS[{name:search_knowledge_base,description:(搜索公司内部知识库。当问题涉及公司政策、产品文档、经营数据、技术架构等私有信息时调用。对于通用知识编程概念、科学原理、常识性问题不需要调用此工具。),input_schema:{type:object,properties:{query:{type:string,description:检索查询词用自然语言描述要查找的信息,},top_k:{type:integer,description:返回最相关的文档片段数量默认3,default:3,},},required:[query],},}]SYSTEM_PROMPT你是公司内部智能助手可以回答公司私有信息和通用知识问题。 规则 - 问题涉及公司内部信息政策、产品、数据等→ 先调用 search_knowledge_base 检索基于检索结果回答 - 问题是通用知识 → 直接回答不需要检索 - 回答要简洁注明关键数据的来源不要捏造数据classAgenticRAG: Agentic RAG Agent 核心循环 用户问题 → LLM 推断 ├─ stop_reason tool_use → 执行工具 → 把结果喂回 LLM → 继续循环 └─ stop_reason end_turn → 返回最终答案 def__init__(self,knowledge_base:KnowledgeBase):self.kbknowledge_base self.clientanthropic.Anthropic()def_execute_tool(self,name:str,inputs:dict)-str:工具路由根据工具名分发到具体执行逻辑ifnamesearch_knowledge_base:queryinputs[query]top_kinputs.get(top_k,3)print(f → 调用 search_knowledge_base(query{query}, top_k{top_k}))resultself.kb.search(query,top_ktop_k)print(f → 检索完成返回{top_k}个片段)returnresultraiseValueError(f未知工具:{name})defchat(self,question:str)-str:Agent 主循环LLM 推断 → 按需调工具 → 生成回答print(f\n{─*60})print(f用户{question})print(f{─*60})messages[{role:user,content:question}]whileTrue:# 把完整消息历史含工具调用记录传给 LLMresponseself.client.messages.create(modelclaude-sonnet-4-6,max_tokens1024,systemSYSTEM_PROMPT,toolsTOOLS,messagesmessages,)# 情况 ALLM 认为不需要工具直接回答ifresponse.stop_reasonend_turn:answernext(b.textforbinresponse.contentifhasattr(b,text))print(f\n[ LLM 判断直接回答未调用工具 ])print(fAgent{answer})returnanswer# 情况 BLLM 决定调用工具ifresponse.stop_reasontool_use:print(f\n[ LLM 判断需要检索知识库 ])# 记录 LLM 本轮输出包含工具调用意图# 这一步必须做——API 要求 assistant 的 tool_use 和 user 的 tool_result 成对出现messages.append({role:assistant,content:response.content})# 执行所有工具调用收集结果tool_results[]forblockinresponse.content:ifblock.typetool_use:resultself._execute_tool(block.name,block.input)tool_results.append({type:tool_result,tool_use_id:block.id,content:result,})# 把工具结果还给 LLM进入下一轮循环messages.append({role:user,content:tool_results})# 继续循环 → LLM 拿到文档后生成最终答案# ─────────────────────────────────────────────────────────# 4. 测试观察 Agent 何时调用 RAG、何时直接回答# ─────────────────────────────────────────────────────────DEMO_QUESTIONS[# ── 通用知识预期 LLM 直接回答不触发工具调用 ──什么是余弦相似度用一句话解释。,# ── 公司私有信息预期 LLM 先检索知识库再基于文档回答 ──年假需要提前几天申请超过 5 天有什么额外要求,我们 2025 年 Q2 的 KPI 达成率是多少销售和研发分别怎么样,企业版产品多少钱包含哪些功能,]defmain():kbKnowledgeBase()agentAgenticRAG(kb)forquestioninDEMO_QUESTIONS:agent.chat(question)print()if__name____main__:main()运行前确保设置了 API KeyexportANTHROPIC_API_KEY你的密钥pipinstallanthropic chromadb python agentic_rag.py预期输出中会看到两种路径的区别── 问题 1什么是余弦相似度 ── [ LLM 判断直接回答未调用工具 ] ← stop_reason end_turn Agent余弦相似度是衡量两个向量方向接近程度的指标... ── 问题 2年假需要提前几天申请 ── [ LLM 判断需要检索知识库 ] ← stop_reason tool_use → 调用 search_knowledge_base(query年假申请 提前天数, top_k3) → 检索完成返回 3 个片段 Agent根据公司HR手册年假需提前5个工作日申请。超过5天须部门总监审批...七、扩展RAG 只是工具箱里的一把回到第七章讲的 Agent 架构——Agent 的核心是LLM 工具集合 循环决策。RAG 只是工具集合中的一个。同一个 Agent 可以同时拥有多个工具LLM 根据问题类型选择调用哪个TOOLS[{name:search_knowledge_base,description:搜索公司内部知识库。涉及公司政策、产品文档、经营数据时调用。,input_schema:{...}},{name:query_database,description:执行 SQL 查询。涉及实时业务数据订单、用户量、交易记录时调用。,input_schema:{...}},{name:call_weather_api,description:查询天气预报。涉及天气、温度、空气质量时调用。,input_schema:{...}},{name:calculator,description:执行数学计算。涉及四则运算、统计计算时调用。,input_schema:{...}},]LLM 面对不同问题时的路由决策用户年假提前几天申请 → search_knowledge_base() 用户今天上海多少度 → call_weather_api() 用户昨天新增了多少订单 → query_database() 用户1999 × 12 × 0.9 等于多少 → calculator() 用户什么是 TCP 三次握手 → 不调任何工具直接回答甚至一个问题可能触发多次工具调用用户企业版年付多少钱帮我算一下三年总费用。 Agent 执行过程 第 1 轮 → search_knowledge_base(query企业版定价 年付折扣) → 检索到企业版 9999 元/月年付9折三年付8折 第 2 轮 → calculator(expression9999 * 12 * 0.8 * 3) → 计算结果287,971.2 第 3 轮 → 最终回答企业版三年付总费用约 28.8 万元月费 9999 元 × 12 个月 × 8 折 × 3 年这就是 Agent 的核心价值把工具的选择权还给模型而不是硬编码在代码里。八、Pipeline RAG vs Agentic RAG怎么选不是所有场景都需要 Agentic RAG。选择标准很简单场景推荐方案原因纯知识库问答客服、HR BotPipeline RAG每个问题都需要检索Agent 判断是多余的开销通用助手知识库 通用问题混合Agentic RAG需要 LLM 判断要不要检索多工具场景RAG SQL APIAgentic RAG工具选择必须由 LLM 动态决策检索后需追问第一次没查到换查询词重试Agentic RAGPipeline 只查一次Agent 可以多轮检索一句话工程结论如果你的系统只有 RAG 一个能力且每次都需要检索用 Pipeline 更简单可靠。一旦工具超过一种、或者有些问题不需要检索就应该切换到 Agentic RAG——让 LLM 来做路由决策而不是硬编码。九、总结Pipeline RAG 不管三七二十一先查再说 Agentic RAG LLM 先想一想该查才查不该查就直接答 核心变化把 RAG 从固定管道变成可选工具 实现方式Tool Use API Agent 循环while True stop_reason 判断 关键细节工具 description 写得好不好直接决定 LLM 的路由准确率这个模式的意义超出了 RAG 本身——它展示了 AI 工程的一个趋势所有能力最终都会变成工具由 Agent 统一调度。RAG 是工具SQL 查询是工具API 调用是工具代码执行也是工具。Agent 的 LLM 循环是统一的调度层每个具体能力都是可插拔的插件。这也是为什么第五章Function Call、第六章MCP、第七章Agent这条线是连贯的——Function Call 让 LLM 能调工具MCP 标准化了工具协议Agent 把工具调度变成了自主循环。RAG 在这个体系里找到了它正确的位置不是一条独立的管道而是 Agent 工具箱里的一把可靠的工具。