尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

RAG Agent 响应策略:文档与分析

RAG Agent 响应策略:文档与分析
📅 发布时间:2026/6/17 19:03:44

=

1. 简介

在构建基于 RAG (Retrieval-Augmented Generation) 的问答系统时,如何准确、可信地向用户展示检索到的源文档(Source Chunks)是一个关键问题。

本文档对比了两种主要的技术方案:Explicit Retrieval (RAG Chain)和Tool Calling Agent,并详细解析了本项目最终采用的方案(方案 2),以及其在代码层面的具体实现。

2. 方案对比

方案 1:显式检索 (Explicit Retrieval / RAG Chain)

流程:

  1. Code: 接收用户 Query。
  2. Code: 调用 Retrieval Service 获取 Top K Chunks。
  3. Code: 将 Query + Chunks 组装成 Prompt。
  4. LLM: 根据 Prompt 生成 Answer。
  5. Code: 将Answer+Chunks拼接返回给用户。
流程图 (Scenario 1)
RetrievalServiceLLMApplication CodeUserRetrievalServiceLLMApplication CodeUserExplicit Retrieval PhaseGeneration Phase提问 ("VisionFive 2 CPU?")Search(Query)Return ChunksPrompt(Query + Chunks)AnswerReturn Answer + Attached Chunks

优缺点:

  • 优点:实现简单,无幻觉(Sources 是代码直接附加的)。
  • 缺点:缺乏灵活性。无论用户问什么(即使是闲聊),都会先去数据库检索,造成资源浪费。无法进行多步推理或根据上下文决定是否检索。

方案 2:工具调用代理 (Tool Calling Agent) -本项目采用

本方案包含三层架构细节:

  • KnowledgeBaseAgent (Wrapper): 应用程序层面的封装,负责后处理和结果组装。
  • Sub-Agent (LangGraph Runtime): 智能体编排引擎,负责状态管理和工具路由。
  • LLM (Model): 负责推理和生成。

流程:

  1. Wrapper: 接收用户 Query,启动 Sub-Agent。
  2. Sub-Agent->LLM: 发送 Query,请求决策。
  3. LLM->Sub-Agent: 返回 Tool Call Request (如 “search”).
  4. Sub-Agent->Tool: 执行RetrievalService。
  5. Tool->Sub-Agent: 返回ToolOutput(Raw Chunks)。
  6. Sub-Agent->LLM: 发送ToolOutput作为上下文。
  7. LLM->Sub-Agent: 返回最终 Answer。
  8. Sub-Agent->Wrapper: 返回完整状态(包含所有历史消息)。
  9. Wrapper: 解析历史消息,提取 Chunks 和 Answer,组装返回给用户。
流程图 (Scenario 2)
RetrievalServiceLLMSub-Agent (LangGraph)KnowledgeBaseAgentUserRetrievalServiceLLMSub-Agent (LangGraph)KnowledgeBaseAgentUserLangGraph Execution LoopPost-Processingask("VisionFive 2 CPU?")Invoke (Query)Predict (Query)Tool Call (name="search")Execute search(...)Return Raw Chunks (ToolMessage)Generate (Query + ToolOutput)Final Answer (AIMessage)Return State (History + Answer)Parse History ->> Extract AnswerParse History ->> Extract ToolOutput (Sources)Return {answer, sources}

优缺点:

  • 优点:
    • 无幻觉:Sources 同样是从工具执行结果中代码提取的,保证真实。
    • 智能决策:Agent 可以根据问题判断是否需要检索,以及如何检索(例如提取 Topic 参数)。
    • 多步推理:Agent 可以根据第一次检索结果决定是否需要再次检索。
  • 缺点:实现较复杂,需要解析 Message History。

3. 最终选择与实现 (方案 2)

本项目选择了方案 2,以确保引用的准确性同时保留 Agent 的智能特性。

3.1 代码结构

核心逻辑位于src/agents/knowledge_base_agent.py类中。

  • create_agent: 构建 LangChain Graph,负责编排 LLM 和 Tool 的交互。
  • ask: 执行 Graph,并负责后处理(提取结果)。

3.2 详细代码解析

Tool 返回的数据 (RetrievalService)

首先,src/services/retrieval_service.py负责生成 Tool 的输出字符串。这个字符串包含了 Chunk 的元数据和内容。

# src/services/retrieval_service.py# 格式化 Header,包含 Score 和 Metadataheader=f"[Source{i+1}]{page_info}(Score:{distance:.4f}){status_tag}"# 拼接 Header 和 Contentcontext_parts.append(f"{header}:\n{chunk.content}")
Agent 执行与解析 (KnowledgeBaseAgent)

在src/agents/knowledge_base_agent.py的ask方法中:

asyncdefask(self,query:str,topic:Optional[str]=None)->Dict[str,Any]:# ... (构建输入) ...# 1. 执行 Agent Graph# result["messages"] 包含了完整的对话历史,包括:# HumanMessage -> AIMessage (ToolCall) -> ToolMessage (Output) -> AIMessage (Final Answer)result=awaitself.agent_graph.ainvoke(inputs)messages=result["messages"]# 2. 提取 LLM 的回答 (Answer)# 通常是列表中的最后一条消息last_message=messages[-1]answer_text=str(last_message.content)# 3. 提取 Tool 的输出 (Sources)sources=[]formsginmessages:# 遍历历史消息,寻找 ToolMessageifisinstance(msg,ToolMessage)andmsg.name=="search_knowledge_base":tool_output=str(msg.content)# 4. 解析 Tool Output 字符串# 我们的 RetrievalService 返回格式是:# [Source 1] ... :# Content ...current_source=Nonecurrent_content=[]lines=tool_output.split('\n')forlineinlines:stripped_line=line.strip()ifstripped_line.startswith("[Source"):# 保存上一个 Sourceifcurrent_source:full_content=' '.join(current_content)# 保存完整内容sources.append(f"{current_source}\nContent:{full_content}")# 开始新 Sourcecurrent_source=stripped_line.rstrip(':')current_content=[]elifcurrent_sourceisnotNone:ifstripped_line:current_content.append(stripped_line)# 保存最后一个 Sourceifcurrent_source:full_content=' '.join(current_content)sources.append(f"{current_source}\nContent:{full_content}")# 5. 组装最终结果return{"answer":answer_text,"sources":sources}

3.3 关键点总结

  1. 为什么 ToolMessage 绝对可靠?

    • 框架保证:ToolMessage的生成和格式不是由 LLM 决定的,而是由 LangChain/LangGraph 框架代码控制的。
    • 流程:
      1. LLM 输出结构化的Tool Call Request(如search(query="..."))。
      2. 框架捕获请求,执行 Python 函数 (RetrievalService.search_knowledge_base)。
      3. 框架将 Python 函数的返回值(字符串)强制封装为ToolMessage对象。
      4. 框架将此对象追加到消息历史。
    • 结论:因为这是确定性的程序逻辑,不存在 LLM 的“幻觉”或“格式错误”问题。只要工具执行了,ToolMessage就一定存在且内容准确。
  2. 手动解析:我们编写了 Python 代码来解析ToolMessage.content。这让我们能够完全控制如何向用户展示来源(例如,我们选择了截断内容以保持界面整洁,但 LLM 看到的是全文)。

  3. 可靠性:即使用户问了一个无关问题,导致 LLM 拒绝回答,ToolMessage依然存在(只要搜索被执行了)。这让我们能够展示“虽然没回答,但我确实搜到了这些东西”。

相关新闻

  • 新手教程:理解USB3.0传输速度的协议基础
  • Terraform基础设施即代码:在云端快速创建CosyVoice3运行环境
  • 版权问题提醒:未经授权不得克隆他人声音商用

最新新闻

  • 2026年香薰棒深度测评:如何为品牌生产匹配最佳供应方案? - 热点速览
  • 2026年6月回转风机厂家推荐指南 - 多才菠萝
  • 免费搭建微信公众号RSS订阅:终极私有化部署完整指南
  • 2026年青岛留学中介综合测评,个性化方案与模板化服务区别 - 资讯速览
  • Cherry Markdown:企业级文档自动化工作流的技术架构与实践
  • 地址智能识别Pro实战指南:5步实现精准地址解析

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号