ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RAG与GraphRAG实战:从多路召回到Agent编排的落地指南

RAG与GraphRAG实战:从多路召回到Agent编排的落地指南 简介2025大模型RAG图计算实战案例合集.pdf 是一份面向大模型工程落地实践、RAG/GraphRAG 研究和图计算开发的实战资料适合算法工程师、平台架构师与技术决策者阅读汇集了腾讯、京东、小红书、蚂蚁、vivo 等团队在真实业务中的一线经验。整体为单文件 PDF共 168 页压缩包约 12.32MB章节目录清晰便于直接阅读与按需定位。当前已有 385 人学习下载。内容从腾讯基于 RAG 与 Agent 技术的混元大模型业务落地切入覆盖 SFT、RAG、Agent 三种技术路线详解 RAG 2.0 索引与召回机制优化、生成式检索在京东电商搜索和小红书搜索中的实践并扩展到流图计算加速蚂蚁数仓、NebulaGraph 的 GraphRAG 进展、基于 tugraph-analytics 的实时异常归因诊断以及 vivo 超大数据规模分布式消息中间件架构演进。读者可借此了解大模型如何结合知识库、知识图谱与图计算应对复杂推理获取可借鉴的架构设计与优化思路。1. 大模型RAG图计算一份把落地案例讲到这个颗粒度的合集这份PDF我拆了两遍。第一遍当资料翻第二遍是照着里面的路子把自家检索链路重排了一遍——发现腾讯在混元大模型里对RAG优化、GraphRAG角色扮演、Agent工具编排的拆解粒度是「索引怎么建、多路召回怎么融合、Promopt怎么写」这种能直接抄的级别。它不是泛讲概念的白皮书而是十场一线大厂分享的记录腾讯RAG和Agent落地、京东电商生成式检索、小红书生成式检索、蚂蚁流图计算数仓加速、NebulaGraph的GraphRAG实践、vivo超大数据规模分布式消息中间件演进全是有业务背景、有参数、有取舍的实战复盘。适合两类人一是正在搭RAG知识库但召回率上不去的工程师二是想搞清GraphRAG和传统RAG边界、准备上图的团队。168页硬货密度比想象中高我下面把每一块能落地的细节都拆给你看。2. RAG落地链路文档解析、索引构建与多路召回每一步都有优化空间2.1 文档解析和切分Garbage in Garbage out链路源头定生死RAG的效果是全链路叠加的结果而开头第一步——文档解析——往往就决定了后续召回的天花板。腾讯在混元平台里用的是端到端模型对PDF、Office、海报这类异构文档做视觉化编码和特征提取输出高质量的段落、表格和公式结构。这里的关键不只是「把字提出来」而是保结构表格丢了行列关系、公式变成乱码、多栏PDF读串行这些都是后续切分和召回的隐性地雷。切分环节文档里列了四种方式我在自己的项目里分别试过适用场景差异很大切分方式实现思路适合场景主要坑固定长度切分按1024字这类上限硬切通用文本、日志类语义割裂一句话被腰斩中文语义切分模型判断切分点新闻、散文、对话推理耗时高批量处理慢Markdown标题切分按H1/H2/H3层次切文档手册、技术博客同级标题下内容过长仍需二次切递归文本切分按分隔符层级递归降级大部分场景的首选参数组合多需要调我一般会先试递归文本切分默认chunk_size取512、overlap取50再根据你知识库的文档类型微调。如果检索结果里频繁出现「答非所问」或者漏掉关键细节优先检查是不是chunk把完整的知识点切成了两半——比如一个函数说明被从参数表中间切断向量化之后两个片段各自都表达不完整。2.2 索引与召回语义召回和BM25互补多路融合比单一向量库稳召回层文档里讲得很实在向量化支持Transformer/BERT语义召回也支持基于BM25的关键词召回生产环境里则通过多路召回把向量库、ES、外部搜索引擎的结果融合进来再用Reranking模型重排过滤。这个思路和我踩坑后的结论一致——纯向量召回在专业名词、型号编码、产品编号这类精确匹配场景会翻车BM25恰好能兜住反过来BM25对语义近义表达无能为力向量补位。实际搭建时我按这个结构落地索引层from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Milvus from langchain.retrievers import BM25Retriever, EnsembleRetriever # 初始化两个召回源 embedding HuggingFaceEmbeddings(model_nameBAAI/bge-large-zh-v1.5) vector_store Milvus( embedding_functionembedding, collection_namerag_kb, connection_args{host: localhost, port: 19530} ) bm25_retriever BM25Retriever.from_texts(chunk_texts) bm25_retriever.k 5 # 向量召回取 Top 10BM25 取 Top 5融合后重排 vector_retriever vector_store.as_retriever(search_kwargs{k: 10}) ensemble EnsembleRetriever( retrievers[bm25_retriever, vector_retriever], weights[0.3, 0.7] )这段代码的关键在weights参数——我推荐从0.3/0.7起步。BM25权重拉高精确匹配会变强但语义泛化会变弱如果你知识库里产品型号和标准术语占比高可以调到0.4/0.6。融合召回之后的rerank环节不能省我用过bge-reranker-base效果比直接用召回顺序合理得多。没有rerank时Top3里经常混进一两条无关结果加了之后准确率体感提升明显。2.3 生成优化Prompt的角色设定和Few-shot比换大模型更立竿见影召回做得再好生成阶段把Prompt写飘了前面全白干。文档里提到的Prompt工程要点很接地气明确角色设定、定义清晰的输入输出格式、提供示例数据。我在实践中总结了一套结构化Prompt模板核心是给模型划定边界而不是让它自由发挥SYSTEM_PROMPT 你是{domain}领域专家请基于以下检索到的资料回答问题。 规则 1. 只使用给定资料中的信息不得编造 2. 如果资料不足以回答明确说资料中未找到相关信息 3. 回答按「结论 依据出处」的结构组织 4. 对存在矛盾的信息列出不同来源的说法 检索到的资料 {context} 用户问题{question} 请给出你的回答注意{context}在Prompt中的位置——放在系统指令之后、问题之前能让模型更专注于引用给定材料。{domain}替换成你的业务领域比如「3C数码产品售后」「医疗器械法规」之类角色设定的约束力比「你是一个AI助手」强得多。Few-shot示例在格式复杂比如要求输出JSON结构化结果时必须加默认给两个对照例子就够多了反而稀释注意力。SFT微调则是另一条腿。文档里说从业务场景收集样本、结合监督学习微调。我的建议是先跑RAG线积累一批「问题-标准回答」真实日志挑出模型回答不佳但人工修正过的样本做成微调集——这些是RAG补不上的部分比如话术风格、特定术语偏好。RAG管知识、SFT管风格两者分工比一上来就指望微调解决一切靠谱。3. GraphRAG进阶从角色扮演到复杂关系推理图结构补上全局视角3.1 RAG的边界与GraphRAG的索引构建一个问题拆成两步走传统RAG在复杂知识问答里有三个硬伤只看到局部片段、缺乏长文本的上下文关联、幻觉依然存在。文档拿《西游记》举例很形象——问「金箍棒怎么来的」普通RAG只召回「孙悟空从东海借金箍棒」这一句整个「太上老君炼制→大禹治水→留在东海→孙悟空借走」的链条是断的。这就是图结构能补的位置。GraphRAG索引构建分三步我复述一下文档里的完整链路并补上工程细节# 1. 语料切分长文本切成语义完整的 Chunk # 重点切分粒度决定知识抽取的上下文窗口 python split_long_text.py --input story.txt --chunk_size 1200 --overlap 200 # 2. 知识抽取调用 LLM 对每个 Chunk 抽取实体、关系、社区 # 产物entities.csv / relations.csv / communities.json # 3. 图谱入库写入图数据库构建 Embedding 索引 python load_to_nebula.py --entities entities.csv --relations relations.csv知识抽取这一步完全依赖LLMPrompt写得好不好直接决定图谱质量。我参考文档思路写的抽取Prompt核心如下你是知识抽取引擎。从给定文本中抽取 1. 实体Entity人名、物品名、地名、组织名保留完整称谓 2. 关系Relation实体间的动作或属性联系格式为「主语|谓词|宾语」 3. 社区Community对实体与关系的语义聚簇概括为一个短语 规则 - 只抽取文本中明确存在的信息不推断 - 实体名统一规范孙悟空不要出现「齐天大圣」「美猴王」混用 - 关系必须带方向例如「金箍棒|炼制|太上老君」实体名规范化是图查询阶段最容易翻车的地方——不统一命名同一个实体在库里分裂成好几个点查询时召回直接断裂。索引完成后图谱存进Neo4j或NebulaGraph再对实体和社区做Embedding才能支撑后面的向量化检索。3.2 Local与Global双路检索细节和全局视角同时拿文档把GraphRAG的检索分成局部检索和全局检索两种模式这个双路设计是理解GraphRAG的枢纽。Local Query针对单个实体或关系查细节比如「孙悟空有哪些法宝」直接在图上做一跳或多跳遍历Global Query则检索图谱的社区结构与总结内容回答「金箍棒的完整来历」这类需要跨多个实体串联的高层问题。具体查询时我的做法是两条线并行最后在生成阶段合并# Local: 实体检索拿到直接关联的边和点 local_result graph.query( MATCH (e:Entity {name: 孙悟空})-[r]-(n) RETURN e.name, r.name, n.name LIMIT 20 ) # Global: 社区总结检索先找社区嵌入相似度最高的报告再做 Reduce 合并 global_result vector_similarity_search(question, community_reports) # 合并时 Local 给细节、Global 给背景拼进 Prompt 的上下文区 final_context merge_context(local_result, global_result, max_tokens2000)merge_context里我会给Global报告更高的截断优先级因为它篇幅大、信息密度低Local的实体关系信息更精炼。文档提到全局检索通过Reduce机制对Community Report做排序和整合——排序依据是社区与问题的相似度取Top N后再拼。如果不做Reduce直接全塞进Prompt长文本分分钟爆上下文。3.3 角色扮演场景为什么GraphRAG天然适合NPC对话角色扮演场景之所以是GraphRAG的最佳试验场是因为它同时要求「角色设定一致」和「关系网络准确」。文档提到的《长相思》案例里要让人物说出符合自身性格的回答必须理解这个角色完整的背景、与其他角色的恩怨纠葛。纯RAG切出来的碎片片段给不了这种全局理解而图谱天然保存了「谁对谁做过什么」的关系链路。游戏NPC落地时GraphRAG的价值还体现在任务引导上玩家问「下一步该找谁」普通RAG可能只检索到任务说明里的半句话GraphRAG则能从图谱关系推导出「你当前角色的盟友是谁、敌人的盟友是谁、谁可能掌握下一步线索」。这层推理能力是生成式模型直接说不出来的某种程度上图结构承担了「思考脚手架」的职责。不过GraphRAG不是银弹——我在小规模知识库上试过图谱构建的LLM抽取成本不低数据量小于几百个文档时收益未必抵得上复杂度。它适合的是长文本、强关系型知识比如小说IP、产品物料全生命周期、法规条文网络。4. RAG与图计算落地避坑指南五条真实踩坑记录复盘到根因4.1 向量召回结果差排查了一圈发现chunk_size设得离谱现象知识库问答命中率低很多明显存在于文档里的答案召不回来。手动检查向量检索结果Top5里经常出现语义相关但完全不是问题目标的内容。原因chunk_size设置过大2048字一个chunk里包含多个知识点向量被平均化表达检索时「什么都像、什么都不像」。这是最常见的调参失误——总以为chunk越大上下文越全结果向量表征被稀释。解决降到512字起步跑一轮检索看召回样例再决定往大还是往小调。overlap也同步调整512的chunk配50-80的overlap保证跨chunk的语义不丢。祖传经验先拿50条业务真实问题当评测集算召回率别靠感觉调。4.2 多路召回后答案反而变差了rerank环节偷懒的结果现象加了BM25和向量多路召回后准确率不升反降。翻看生成日志发现模型引用了BM25召回的一段完全无关的日志文本把最终回答带偏了。原因多路召回扩大了候选池但融合策略是简单的拼接截断没有做质量过滤。BM25召回了精确匹配但语义不相关的片段向量召回的结果被挤到了截断线之外——等于召回扩了但有效信息没进上下文。解决召回结果必须过rerank。我用bge-reranker-base输入query和所有候选片段按相关性分数重新排序后取Top3-5。分数低于阈值我常用0.3-0.4具体看模型和数据分布的片段直接丢弃不进上下文。从那以后我每次改召回策略都强制把「加rerank」写在改动清单第一条。4.3 GraphRAG图谱越建越乱实体名不规范化导致查询断裂现象图谱里实体数暴增但图查询经常查不到东西。比如搜「金箍棒」有结果搜「如意金箍棒」就空转明明是一个东西。原因知识抽取时没做实体对齐LLM在同一个故事里抽出的同一实体存在多种称谓变体被当成不同节点入图了。图谱的关联查询在节点断裂处直接失效。解决在知识抽取Prompt里强制加一条实体名必须规范化到主称谓别名写入属性。我通常再加一道后处理——用规则或LLM批量合并同义节点把「齐天大圣」「美猴王」归并到「孙悟空」的主节点下。建图阶段的归并工作做得越多查询阶段省的事越多。4.4 Agent链路里工具调用顺序不对原因模型把推理和执行混在一起现象Agent在完成任务时明明第一步工具就报了错比如查询接口返回超时模型却继续往下走最后给用户一个基于残缺上下文生成的错误答案。原因Agent的推理循环里模型对工具执行结果的判断太「顺滑」遇到报错信息没有停下来重新规划而是把报错当成正常上下文继续推理。纯靠LLM判断「工具返回是否有效」非常不可靠。解决把工具返回的有效性判断从模型手里拿出来交给代码硬编码——非200状态码、空结果、超时直接触发重新规划和重试流程不进生成环节。文档里说的「推理和行动分离」在工程实现上就是把每一步tool call的返回校验做成强规则。这也算RAG里Garbage in Garbage out原则在Agent侧的延伸。4.5 分布式消息中间件撑不住实时图计算的写入峰值背压处理缺失现象流图计算作业上线后消息中间件偶尔出现消费延迟数据积压图计算任务的结果时效性从秒级退化到分钟级。原因写入端突发流量高峰比如业务大促消息队列的消费端处理能力跟不上生产速率又没有合理的背压机制积压数据把延迟推高。解决参考vivo那篇分布式消息中间件架构演进的做法——给消费端增加动态限流积压超过阈值时自动降级部分非核心计算任务保证核心图计算作业的时效性。同时把消息体做压缩小消息合并批量发送削峰填谷。流式计算里的「消息中间件」通常不被关注直到延迟上来了它才是第一瓶颈。5. Agent技术实战目标驱动任务里的推理、工具调用与编排闭环5.1 从RAG问答到Agent执行一步之遥但架构复杂度放大一个量级RAG解决「基于知识回答问题」Agent解决「完成一个需要多步骤操作的任务」。文档里用「预算一万块、三天深圳旅游」的例子讲透了这句话——模型要理解预算、日期、天气、交通、住宿多个因素调用天气查询、预算计算器、产品查询、购买等多个工具动态决策每一步行动。这就是从「读」到「做」的跨越。工程上我实现Agent循环时核心结构是while循环加工具注册表class ToolRegistry: def __init__(self): self.tools {} def register(self, name, func, schema): self.tools[name] {func: func, schema: schema} def run_agent(question, registry, max_steps8): context [{role: system, content: 你是任务规划助手...}] context.append({role: user, content: question}) for step in range(max_steps): response llm_chat(context) action parse_action(response) if action[type] final_answer: return action[content] # 工具调用结果作为硬数据注入不修改上下文的自然语言部分 tool_result registry.tools[action[name]][func]( **action[arguments] ) context.append({role: tool, content: str(tool_result)})关键在parse_action这一步——我要求模型输出结构化JSON而非自然语言以便稳健解析{type: tool_call, name: weather_query, arguments: {city: 深圳, date: 2025-06-10}} {type: final_answer, content: 根据天气和预算信息推荐如下行程...}强制结构化输出能省掉大量自然语言解析的坑。注意我给循环设了max_steps8的上限防止模型在复杂任务里无限循环调用工具——这在实际生产环境里是必须的保险丝。5.2 混元平台的Agent编排角色定义、插件扩展、索引召回一体文档里混元平台这块的架构值得细看集成RAG和Agent支持索引与召回能力用户可通过插件扩展自定义功能模块。这个「Agent平台」的思路是把RAG能力作为Agent的一个内置工具暴露把其他外部系统也注册成插件让Agent统一编排。我复刻这个思路时把知识检索做成了一个标准工具注册进Agentregistry.register( namerag_search, funcrag_retrieve_and_generate, schema{ description: 基于知识库检索并回答专业问题, parameters: { query: {type: string, description: 要检索的问题}, top_k: {type: integer, description: 返回片段数量} } } )这样Agent在面对复杂任务时可以自主决定什么时候调知识库、什么时候查天气接口、什么时候计算预算。单一agent能走的步数有限文档里提到的「自定义编排」则可以由用户在界面里拖出多个Agent串联——产品侧的编排能力比单Agent自由度高很多。5.3 多步任务中如何控制幻觉与错误累积让中间结果可校验Agent链路最大的坑是错误在迭代中放大——第一步工具调用返回错误数据模型基于错误数据做第二步推理最后答案离谱到不知所云。我控制这个问题的手段是每步工具调用之间插入检查点def run_agent_with_checkpoints(question, registry, max_steps8): execution_trace [] for step in range(max_steps): response llm_chat_with_trace(question, execution_trace) action parse_action(response) if action[type] final_answer: return action[content] # 执行前校验参数完整性 validate_arguments(action, registry) tool_result registry.tools[action[name]][func](**action[arguments]) execution_trace.append({ step: step, action: action, result: tool_result }) # 执行后校验结果有效性 if not is_valid_result(tool_result): return 抱歉任务执行过程中出现异常已中止。错误环节 action[name]execution_trace就是让模型看到完整执行历史避免它「忘记」自己之前调过什么工具、拿到了什么结果。校验不通过就中止而不是让模型硬着头皮继续——这个决策标准我写在系统Prompt里「遇到数据异常必须告知用户不得强行生成答案」。加上合理的重试策略同一步最多重试2次后多步任务的成功率比裸跑高出一大截。6. 实战验证与迁移路径京东、小红书、蚂蚁、vivo四家案例如何变成你自己的方案文档后半部分四个案例分别是不同技术侧面的延伸京东电商搜索讲生成式检索替代传统相关性匹配、小红书探索生成式检索的社区内容适配、蚂蚁用流图计算加速数仓场景、vivo消息中间件保障超大规模数据底座。我拆解这些案例时发现它们的共性方法论是「先诊断瓶颈再选技术」——京东的问题是搜索相关性瓶颈选择了生成式排序蚂蚁的问题是数仓ETL对时效性的瓶颈选择流图计算加速vivo的问题是数据规模增长压垮消息链路选择架构分层演进。这套思路迁移到自建系统时的落地路径我总结为四步建立评测集选50-100条真实业务问题标注标准答案作为RAG/Agent效果的基线。定位瓶颈环节跑一轮基线看是召回漏了、排序不对、还是生成表述差。用文档里的链路法逐环节排查别眉毛胡子一把抓。按瓶颈选型召回率低走文档里的多路召回Rerank路线复杂关系问答上GraphRAG需要工具执行上Agent编排。记录改动前后的评测分数只有量化对比才能判断优化方向是否正确否则就变成凭感觉调参。验证的另一个关键是「对照组设计」。我在评估GraphRAG时会保留传统RAG作为对照组同一批问题两边都跑对比回答的准确性和完整度。文档里角色扮演案例强调了溯源能力——能从图谱指回原文位置这个特性在合规审查场景尤其重要用「是否有来源可查、来源是否真实覆盖了答案要点」作为评分维度比只看答案文字相似度更能反映真实效果。最后一条经验是这类PDF的阅读顺序先读腾讯的RAG链路部分建立整体框架再精读GraphRAG章节理解图的查缺补位逻辑然后带着自己的业务问题去看京东、蚂蚁、vivo案例只提取与你场景匹配的那一块。从那以后我每拆完一份这样的实战合集都会强制走一遍「选三处能立刻试的点→各设一个评测指标→记录前后变化」的流程。就是靠这个笨办法我把文档里那些「大厂方案」一个个变成了自己系统里可量化的改进。希望帮到你。本文还有配套的精品资源点击获取
返回列表