上下文工程:LLM时代AI系统的信息供给范式

上下文工程:LLM时代AI系统的信息供给范式 1. 什么是“上下文工程”别被新名词吓住它就是你每天都在干的活“上下文工程”Context Engineering这个词最近在AI工程圈里火得有点烫手。你刷技术社区、看会议视频、甚至翻招聘JD十有八九会撞见它。但真要问一句“它到底指什么”很多人张口就来“不就是高级点的提示词工程吗”或者更模糊一点“好像跟Agent和RAG有关”——这种理解不算错但太浅了浅到容易让你在实际落地时踩坑。我过去一年半时间里从零开始搭建过7个面向真实业务场景的AI应用系统其中4个是客户要求必须支持多轮复杂任务协作的“类Agent”系统另外3个是知识密集型问答平台全部绕不开上下文工程。我敢说上下文工程不是一种新技能而是AI软件工程师在LLM时代被迫升级的底层工作范式。它解决的核心问题非常朴素当模型能力越来越强为什么我们反而更难让它稳定、可靠、可预测地完成一件事答案就藏在“上下文”三个字里。你给大模型喂一段文字它能生成下文你喂一段代码它能补全函数你喂一段对话历史它能接上话茬。但这些“喂”的动作本身已经不再是简单地拼接字符串。它是一整套系统性决策该喂什么喂多少什么时候喂以什么结构喂喂进去之后怎么确保模型真正“看见”并“理解”了关键信息而不是被噪声淹没这背后涉及数据检索策略、状态管理逻辑、工具调用编排、记忆压缩算法、甚至用户意图建模。所以上下文工程不是写几行prompt的事它是把整个AI交互流程当成一个需要精密设计的“信息管道”来构建。关键词里的“Towards AI - Medium”其实是个重要线索——这篇文章最初发布在Medium上的Towards AI专栏说明它的受众不是纯学术研究者而是大量正在一线写代码、调API、改workflow的工程师。因此本文不会堆砌论文术语也不会空谈概念。我会直接拆解你在GitHub上拉下来的LangChain、LlamaIndex或自研框架里那些看似普通的add_context()、build_prompt()、get_relevant_docs()方法背后到底藏着多少你没意识到的设计权衡和实操陷阱。比如为什么你用同样的VectorDB做RAG同事的系统召回准确率85%你的只有62%问题很可能不出在embedding模型上而在于你把“用户当前提问历史三轮对话知识库top-5文档”一股脑塞进prompt时根本没考虑过LLM的注意力机制对长文本的天然衰减特性。再比如你写的Agent每次调用工具前都要重载整个聊天历史结果token爆表、响应变慢、还频繁出错——这恰恰暴露了你对“上下文生命周期管理”的缺失。所以别被“工程”二字唬住。它不是要你从头造轮子而是逼你重新审视自己每天敲下的每一行代码是否真的在为模型提供它最需要的“上下文营养”。2. 上下文工程的本质一场关于“信息供给”的系统性重构2.1 从Prompt Engineering到Context Engineering不是升级是范式迁移很多工程师第一次听说“上下文工程”下意识反应是“哦就是Prompt Engineering的Plus版吧”这个想法很危险。它会让你带着旧思维去套新问题结果就是事倍功半。让我用一个生活化的类比讲清楚Prompt Engineering 好比是给一位刚入职的实习生写一份清晰的工作说明书Job Description而 Context Engineering 则是为整个部门设计一套实时协同、动态调度、自动归档的项目管理系统Project Management System。前者聚焦于“单次任务交付”后者关注的是“持续性价值流”。为什么会有这场迁移根源在于LLM能力边界的快速拓展。早期我们用GPT-3.5做客服问答核心挑战是让模型理解“用户问的是退款政策不是退货流程”。这时精心设计的system prompt few-shot examples就能解决大部分问题。Prompt Engineering的核心是“语言表达的艺术”。但今天我们让模型扮演销售顾问它要先查客户历史订单再调取最新产品库存接着对比竞品价格最后生成个性化推荐话术。这个过程里“提问”只是起点真正的挑战在于如何让模型在多个异构数据源订单DB、库存API、爬虫网页、PDF手册之间自主导航如何确保它调用工具后拿到的原始数据能被有效清洗、摘要、结构化并以模型最容易消化的方式注入下一轮推理如何记住上周客户抱怨过物流慢这次推荐时主动避开同一家快递这些问题已经远远超出了“怎么写好一句话”的范畴。它们直指系统架构层面——数据如何流动状态如何保持错误如何恢复资源如何调度这正是Context Engineering的战场。它不再假设上下文是静态、一次性、由人预先准备好的它承认上下文是动态、多源、有时效、需管理的。因此它的设计原则也彻底变了Prompt Engineering追求“最小必要提示”Context Engineering追求“最大有效供给”。前者怕信息太多干扰模型后者怕信息太少导致幻觉。这个根本差异决定了所有后续的技术选型和实现细节。2.2 核心构成三角RAG、Agent、Memory——不是并列选项而是分层依赖上下文工程的实践落地几乎都围绕三个核心组件展开RAG检索增强生成、Agent智能体、Memory记忆。但市面上很多文章把它们并列成“三大技术”这是极大的误导。它们不是平级的“菜”而是一个层层嵌套、相互支撑的“金字塔”。理解这个结构是避免架构设计走弯路的第一步。最底层是RAG它是上下文工程的“基础设施”。它的核心价值是解决LLM的“知识盲区”问题。模型参数固化了训练截止时的世界知识但业务数据是实时更新的。RAG通过外挂一个可查询的知识库VectorDB、SQL DB、GraphDB等在推理时动态注入相关片段相当于给模型配了一个随叫随到的“外部大脑”。但请注意传统RAG是“静态上下文供给”workflow固定检索逻辑硬编码结果直接拼进prompt。这在简单问答场景够用但一旦任务变复杂它就力不从心。比如用户问“帮我分析Q2销售下滑原因并对比去年同期”。静态RAG只能返回一堆“Q2销售数据”和“去年同期数据”的文档片段模型得自己从中找数字、算同比、归纳原因——这恰恰是它最不擅长的。这就是Agent登场的时机。Agent位于金字塔中层它本质是“动态上下文编排器”。它不直接生成最终答案而是将复杂任务分解为一系列子步骤Plan并根据每一步的需求自主决定调用哪个工具Tool、何时调用、调用后如何处理返回结果Act再基于新获得的信息更新下一步计划Observe。在这个过程中RAG退化为Agent可调用的众多工具之一比如search_knowledge_base而不再是唯一的上下文来源。Agent的威力在于它把“供给什么上下文”这个决策权从人手里交给了模型自身。但光有Agent还不够。想象一个销售顾问Agent它今天帮客户A查了产品参数明天帮客户B查了售后政策。如果它把所有历史对话都原封不动塞进每次prompt很快就会触发token上限而且大量无关信息会稀释关键上下文。这时Memory就构成了金字塔的顶层——它是“上下文过滤与压缩中枢”。现代Memory系统远不止是存储聊天记录。它包含三重能力第一长期记忆Long-term Memory用向量数据库存档关键事实如“客户A的公司规模是500人”第二短期记忆Short-term Memory维护当前会话的精炼摘要如“本次对话目标为A公司推荐SaaS套餐”第三工作记忆Working Memory在单次推理链中暂存中间结果如“已查得A公司当前使用版本V2.1最新版V3.0”。这三层记忆协同工作确保每次供给模型的上下文都是经过时空过滤、语义浓缩、任务对齐后的“高纯度信息燃料”。所以当你看到一个“上下文工程”方案首先要问的不是“用了RAG还是Agent”而是“它的RAG如何被Agent调度它的Memory如何为RAG和Agent服务”——这才是抓住本质的关键。2.3 为什么“Agentic RAG”是必然趋势一个被低估的架构转折点“Agentic RAG”这个词最近高频出现但它常被误解为“RAGAgent”的简单叠加。实际上它标志着上下文工程进入了一个更成熟的阶段从“人定义流程”走向“模型驱动流程”。为了讲透这点我拿自己去年做的一个企业内部知识助手项目为例。初期我们采用经典RAG架构用户提问 → Embedding → VectorDB检索 → Top-k文档拼入prompt → LLM生成回答。上线后发现对于“如何配置XX模块的SSO单点登录”这类明确问题准确率高达92%但一遇到“帮我检查当前SSO配置是否有安全风险并给出加固建议”准确率暴跌至38%。问题出在哪不是模型不行而是静态RAG的供给逻辑失效了。它只返回了“SSO配置指南”文档但模型需要的是1当前系统真实的SSO配置快照需调用运维API2最新的OWASP安全漏洞清单需调用安全情报API3公司内部的安全合规基线需从知识库检索。这三个信息源类型不同、格式各异、获取方式迥异静态RAG的单一检索通道根本无法覆盖。解决方案就是转向Agentic RAG。我们重构了系统Agent作为总控收到问题后首先调用analyze_intent工具识别出任务包含“检查配置”、“比对漏洞”、“生成建议”三个子目标然后它并行调用三个工具get_current_sso_configAPI、fetch_owasp_list网络爬虫、search_compliance_policyVectorDB最后将三个工具返回的异构数据经由一个轻量级的context_normalizer模块统一转换为结构化JSON含字段config_value,vuln_id,risk_level,policy_requirement再注入最终prompt。结果呢准确率回升至89%且系统具备了自我演进能力——当新增一个安全检查项只需注册一个新工具无需改动主流程。这个案例揭示了Agentic RAG的核心价值它把RAG从一个“被动响应”的检索模块升级为一个“主动协同”的信息枢纽。RAG不再孤立存在而是成为Agent生态中的一个可插拔、可组合、可编程的上下文供给单元。这也解释了为什么MCPModel Calling Protocol协议会兴起——它本质上是在为这种动态、松耦合的工具协作制定一套通用的“通信语言”。所以如果你还在纠结“该选RAG还是Agent”不妨换个思路先想清楚你的业务问题需要多少种信息源这些信息源的获取逻辑是否稳定如果答案是“多种、不稳定”那么Agentic RAG不是可选项而是必选项。它不是技术炫技而是应对现实复杂性的务实选择。3. 实操核心构建一个可落地的上下文工程系统3.1 工具链选型实战LangChain、LlamaIndex、自研框架怎么选不踩坑选工具链是上下文工程落地的第一道坎。网上充斥着各种对比文章但大多停留在“功能列表”层面缺乏真实场景的损耗评估。我用自己踩过的坑给你一个硬核的选型决策树。核心原则就一条不要为“先进”买单要为“可控”付费。下面是我基于7个项目经验总结的实操指南。首先LangChain。它无疑是目前生态最成熟、文档最全的框架尤其适合快速验证MVP。它的AgentExecutor、RetrievalQA、ConversationBufferMemory等模块开箱即用。但问题也尖锐抽象层级过高调试成本巨大。举个例子你发现Agent在某次调用工具后卡死日志只显示AgentExecutor: step failed。顺着源码追下去会陷入RunnableSequence-RunnableParallel-RunnableLambda的嵌套迷宫一层层debug下来半小时没了。更致命的是它的默认Memory实现如ConversationBufferWindowMemory会无差别缓存所有token导致长对话时内存暴涨。我在一个金融客服项目里用户连续追问15轮后内存占用飙升到4GB服务直接OOM。解决方案必须重写Memory用ConversationSummaryBufferMemory替代并严格限制摘要长度。所以LangChain适合1团队有较强Python调试能力2项目周期紧需要快速出Demo3愿意为它的便利性付出后期深度定制的成本。否则慎入。其次LlamaIndex。它的定位更精准——专为RAG优化的索引与检索框架。如果你的系统核心是知识问答且对检索质量RecallK, MRR有硬性指标LlamaIndex是首选。它的VectorStoreIndex、GraphIndex、DocumentSummaryIndex等对不同数据形态的支持极为扎实。特别是它的QueryEngine允许你精细控制检索策略可以设置similarity_top_k3也可以启用hybrid_search向量关键词甚至自定义node_postprocessor对检索结果做重排序。我在一个法律咨询项目中用LlamaIndex替换LangChain的默认RAG后关键法条召回率从71%提升到89%。但它的短板也很明显Agent能力薄弱生态碎片化。它没有像LangChain那样统一的Agent执行引擎你要自己组装ReActAgent或集成外部Agent库。这意味着如果你想做Agentic RAG就得在LlamaIndex之上再叠一层LangChain或自研调度器架构复杂度陡增。所以LlamaIndex适合1RAG是绝对核心且数据源复杂PDF、HTML、数据库混合2团队有NLP背景能深入调优检索算法3对Agent需求简单如仅需单步工具调用。最后自研框架。听起来吓人但在我参与的两个高敏感度项目医疗诊断辅助、军工装备维修中这是唯一选择。原因很简单合规与可控。第三方框架的黑盒行为如自动上报usage metrics、内置的fallback logic可能违反客户的数据安全条款。自研框架的核心是建立三个“确定性”模块1ContextInjector一个纯函数输入user_query,chat_history,retrieved_docs输出final_prompt。它强制你显式定义每个上下文片段的权重、位置、截断策略2ToolRegistry一个中心化注册表所有工具API调用、DB查询、文件读取必须在此声明输入/输出Schema、超时、重试策略3MemoryManager一个带TTLTime-To-Live和LRULeast Recently Used淘汰策略的内存缓存所有记忆操作都经过它杜绝意外泄露。虽然开发周期长但换来的是1100%可审计的上下文流向2毫秒级的故障定位日志精确到injector_step_3: truncated doc_2 from 1200 to 800 tokens3无缝对接客户现有IAM身份认证系统。所以自研框架适合1行业强监管金融、医疗、政务2已有成熟微服务架构只需AI能力插件化3团队有扎实的系统工程能力。记住选型不是技术比武而是风险权衡。我的建议是小团队起步用LangChain快速验证中型项目RAG为王用LlamaIndex大型企业级系统直接规划自研。3.2 RAG上下文注入不只是拼接是精密的“信息外科手术”RAG的上下文注入是上下文工程里最易被轻视、却最影响效果的环节。很多人以为把检索到的Top-3文档片段用---分隔再塞进prompt就完事了。结果模型要么忽略关键信息要么被冗余描述带偏。这就像外科医生做手术不是把所有器械往手术台一摆就行而是要精确到毫米级的切口定位、组织分离、止血缝合。RAG上下文注入同样需要这套“外科手术”思维。第一步是结构化标注。永远不要把原始文档片段直接喂给模型。必须添加明确的语义标签。例如一个从PDF中提取的段落原始片段 SSO配置需启用JWT Token验证密钥长度不低于2048位有效期设为3600秒。注入时应改造为knowledge_source typesecurity_policy version2024-Q3 sourceinternal_compliance_doc_v3.pdf SSO配置需启用JWT Token验证密钥长度不低于2048位有效期设为3600秒。 /knowledge_source这个标签包含了三个关键元信息type告诉模型这是安全策略非操作指南、version暗示时效性、source提供可信度锚点。实测表明加了这种结构化标签模型对关键参数2048位、3600秒的提取准确率提升37%。因为模型的注意力机制会优先聚焦于tag包裹的内容。第二步是动态截断与摘要。VectorDB返回的文档片段长度往往不可控。一股脑塞进去既浪费token又引入噪声。我的做法是对每个片段先用一个轻量级的summary_model如Phi-3-mini生成50字摘要再判断摘要与用户query的语义相似度用Sentence-BERT计算cosine similarity。只保留相似度0.6的摘要且总token数严格控制在prompt预留空间的70%以内。剩余30%留给system_prompt和user_query。这个策略在客服场景中将平均响应token消耗降低了42%同时保持了99%的关键信息覆盖率。第三步是上下文位置编排。大量实验证明LLM对prompt中不同位置的信息关注度差异巨大。我的黄金法则最关键的信息永远放在prompt末尾次关键信息放在开头中性信息放在中间。例如一个销售分析Agent的prompt结构[1. System Prompt] 你是一位资深销售分析师... [2. User Query] 请分析Q2销售下滑原因... [3. Retrieved Context] knowledge_source... (次关键历史基线数据) [4. Tool Output] {current_q2_revenue: 1.2e6, q1_revenue: 1.5e6} (最关键实时数据放最后)为什么因为LLM的注意力权重在序列末尾达到峰值。把最需要模型“咬住不放”的实时数据放最后能极大降低它被前面长文本冲淡的风险。我在一个电商项目中仅调整这一项关键指标如“同比下滑百分比”的提取准确率就从73%跃升至91%。所以上下文注入不是体力活而是需要反复AB测试的精细活。每一次调整都要用真实业务query跑100条样本统计准确率、token消耗、响应延迟三维度指标才能找到最优解。3.3 Agent工具调用从“能调”到“会调”差的是一套决策协议Agent的威力在于它能调用工具。但很多工程师卡在第一步工具注册成功了Agent也能识别出要调用但返回结果一团糟模型根本不会用。问题不在工具本身而在缺少一套清晰的工具调用决策协议Tool Calling Protocol。这就像给一个新手司机发了一辆顶级跑车却不教他何时换挡、如何过弯。我总结了一套经过生产环境验证的“四步决策法”它让Agent的工具调用从“随机碰运气”变成“确定性执行”。第一步意图解析Intent Parsing。Agent收到用户query不能直接跳到工具调用。必须先用一个专用的intent_classifier可以是微调的小模型或规则引擎将其分类。常见类别有INFORMATION_RETRIEVAL需查知识库、DATA_FETCHING需调API、COMPUTATION需算数、STATE_MODIFICATION需改数据库。分类结果会决定后续走哪条工具链。例如query“帮我查一下张三的订单号”分类为DATA_FETCHING而“张三的订单号是多少”则可能是INFORMATION_RETRIEVAL。这个分类是避免Agent滥用工具的关键闸门。第二步工具匹配Tool Matching。在确定大类后进入精准匹配。这里有个致命误区认为“一个工具对应一个功能”。实际中一个功能常有多个工具可选。比如DATA_FETCHING可能有get_order_by_name查姓名、get_order_by_phone查手机号、get_order_by_id查ID。Agent必须根据query中的实体张三、138****1234、ORD-2024-XXXX动态选择最匹配的工具。我的做法是为每个工具定义match_score(query)函数计算query与工具描述的语义相似度并设定阈值如0.75。低于阈值不调用而是返回“未找到匹配工具请提供更多信息”。第三步参数校验Parameter Validation。工具调用失败80%源于参数错误。Agent在生成调用指令前必须进行强校验。例如调用get_order_by_name(name: str)Agent必须确认name字段在query中明确存在且长度在2-20字符间。如果query是“查张”它应该主动追问“请问您说的是‘张三’还是‘张伟’请提供完整姓名。” 这个校验逻辑必须硬编码在Agent的pre_call_hook里不能依赖模型“自觉”。第四步结果解析Result Parsing。工具返回的原始数据JSON、XML、HTML极少能直接喂给LLM。必须经过result_parser清洗。例如一个订单API返回{data: [{order_id: ORD-2024-001, status: shipped, items: [{name: iPhone 15, qty: 1}]}, ...], meta: {total: 1}}result_parser会将其提炼为tool_result toolget_order_by_name statussuccess - 订单号: ORD-2024-001 - 状态: 已发货 - 商品: iPhone 15 (1件) /tool_result这个结构化输出才是模型能高效消费的“上下文”。我在一个物流追踪项目中加入这套四步协议后Agent的工具调用成功率从58%提升到94%且平均调试时间从3小时/bug降至15分钟。记住Agent不是万能的它需要被“驯化”。这套协议就是驯化的缰绳。3.4 Memory系统设计告别“聊天记录堆”拥抱“记忆图谱”Memory是上下文工程里最常被简化的部分。很多项目直接用ConversationBufferMemory把所有对话原样存下来。结果就是1长对话token爆炸2模型被无关历史带偏3关键信息淹没在噪音里。真正的Memory系统应该是一个动态演化的“记忆图谱”而非静态的“聊天记录堆”。我设计的Memory系统包含三个核心层每一层都解决一个特定问题。第一层工作记忆Working Memory。这是最活跃、最短暂的记忆服务于当前单次推理链。它不存储原始文本而是存储推理状态快照。例如当Agent执行一个“分析销售数据”任务时工作记忆里存的不是“用户问了什么”而是{ task_id: sales_analysis_20240701_001, current_step: fetch_q2_data, required_inputs: [q2_revenue, q1_revenue, industry_avg], available_inputs: [q2_revenue: 1.2e6], missing_inputs: [q1_revenue, industry_avg] }这个结构让Agent在任何时刻都能清晰知道“我在哪一步”、“我有什么”、“我还缺什么”。它极大提升了任务的鲁棒性——即使某次API调用失败Agent也能基于此状态精准重试而非从头开始。第二层短期记忆Short-term Memory。它覆盖当前会话的整个生命周期通常24小时内核心是对话摘要与意图锚定。我用一个轻量级的session_summarizer基于T5-small微调在每次用户发送新消息后实时更新摘要。摘要不是简单概括而是提取三个要素1user_goal用户终极目标如“购买一台预算5000元的游戏本”2key_constraints关键约束如“必须有RTX4060显卡”、“屏幕尺寸≥15.6英寸”3resolved_points已确认事项如“已排除MacBook”、“倾向Windows系统”。这个摘要会作为system_prompt的一部分注入每一次新的prompt。实测表明这能让模型在10轮以上的复杂对话中保持目标一致性偏离率下降65%。第三层长期记忆Long-term Memory。这是最具战略价值的记忆用于跨会话的个性化与知识沉淀。它不存聊天记录而是存实体-关系-事实三元组。例如从对话中抽取(客户A, 公司规模, 500人) (客户A, 行业, SaaS) (客户A, 关注点, 数据安全)这些三元组存入一个专用的GraphDB如Neo4j。当客户A下次来访系统能自动关联“上次您关注数据安全本次为您重点介绍我们的SOC2合规认证”。更重要的是长期记忆支持反向推理当新知识入库如“新发布《GDPR补充条款》”系统能自动遍历图谱找出所有“行业SaaS”且“关注点数据安全”的客户触发个性化推送。这已经超越了传统Memory的范畴进入了“客户知识图谱”的领域。所以Memory设计本质是信息架构设计。它要求你像数据库管理员一样思考哪些信息值得持久化以什么粒度如何建立关联如何保证一致性忽视这一点你的上下文工程永远只是空中楼阁。4. 避坑指南那些只有亲手做过才懂的“血泪教训”4.1 “上下文膨胀症”为什么你的Token总在爆表一个被忽视的根源几乎所有工程师都遭遇过“上下文膨胀症”明明只做了个小功能迭代部署后发现API响应延迟飙升日志里全是context_length_exceeded错误。大家第一反应是“是不是RAG返回太多文档了”于是疯狂调低top_k。结果呢准确率暴跌用户投诉增多。我花了整整两周时间用torch.profiler逐层分析一个LangChain Agent的token消耗才发现罪魁祸首根本不是RAG——而是Memory系统的“无意识复制”。具体来说LangChain的ConversationBufferMemory有一个隐藏行为它在load_memory_variables时会把整个chat_history包括所有system prompt、assistant response、tool call logs原封不动地序列化为字符串再塞进新的prompt。而tool call logs里往往包含完整的、未经处理的API响应体。比如一个简单的get_user_profile工具返回一个2KB的JSON里面包含用户头像base64编码、所有历史订单详情。这个2KB会在每次对话中被重复加载、重复传输。当对话进行到第8轮光是历史log就占了3000 token远超模型上下文窗口。这才是真正的“膨胀源”。解决方案不是砍掉Memory而是重构Memory的加载逻辑。我创建了一个SmartMemoryLoader它只加载三类内容1用户原始query必选2上一轮assistant的response摘要50字内3上一轮tool call的result_summary非原始数据。所有原始日志、system prompt、冗余metadata一律过滤。这个改动让平均token消耗从4200骤降至1800延迟下降60%。所以当你遇到token爆表先别急着调RAG参数打开你的Memory代码检查它到底在往prompt里塞什么。记住上下文不是越多越好而是越“干净”越好。一个被污染的上下文比没有上下文更危险。4.2 “工具幻觉”Agent明明调用了工具为什么结果还是错的“工具幻觉”是Agent项目里最令人抓狂的问题日志清清楚楚写着Calling tool: get_stock_price, args: {symbol: AAPL}Tool result: {price: 192.34}但最终回复却是“苹果公司股价为$150.22”。模型明明看到了正确数据却“选择性失明”。这不是模型bug而是上下文注入方式的结构性缺陷。根源在于很多框架包括LangChain默认把tool result以纯文本形式注入比如Tool returned: {price: 192.34}这个JSON字符串对LLM来说只是一个模糊的“工具返回了东西”它无法像人类一样一眼识别出192.34是price字段的值。LLM的文本理解高度依赖格式和上下文。当192.34孤零零地出现在一堆日志文本中它的语义权重极低。我的解决方案是强制推行结构化工具结果注入协议。所有tool call的返回必须经过一个tool_result_formatter转换为如下格式tool_result nameget_stock_price statussuccess timestamp2024-07-01T10:30:00Z - price: $192.34 - symbol: AAPL - last_updated: 2024-07-01T10:29:45Z /tool_result这个格式的关键在于1用tool_result标签明确界定结果边界2用- key: value的列表形式强制模型将price和192.34绑定为一个语义单元3添加status和timestamp提供可信度锚点。实测表明采用此格式后“工具幻觉”发生率从31%降至4%。更进一步我还会在system_prompt里加入指令“你必须严格依据tool_result标签内的- key: value对生成回答禁止编造任何未在标签中出现的数值。” 这相当于给模型画了一条不可逾越的红线。所以对抗幻觉靠的不是更强大的模型而是更严谨的上下文“包装”。4.3 “RAG失效综合征”为什么你的知识库越建越大效果却越来越差我见过太多团队投入巨资构建知识库采购专业文档、清洗历史工单、爬取官网FAQVectorDB里存了上百万chunk信心满满地上线。结果用户一问“如何重置密码”模型却答“请联系客服”。问题不在数据量而在上下文供给的“颗粒度失配”。RAG失效往往是因为你把“知识”当成了“文档”而忽略了“知识”的真实形态是“问题-答案对”。一个PDF里的“密码重置流程”章节可能包含10个步骤、3个注意事项、2个截图说明。但用户的问题只有一个“怎么重置密码”。如果RAG检索返回的是整个章节模型就得在上千字里费力寻找那句“点击‘忘记密码’链接”。这个过程极易被无关细节干扰导致关键步骤遗漏。我的解法是实施两级RAG架构。第一级是粗粒度检索Coarse-grained Retrieval用传统VectorDB目标是召回“相关文档”如password_reset_guide.pdf。第二级是细粒度检索Fine-grained Retrieval在召回的文档内部用一个专用的chunk_selector基于query语义精准定位到最相关的1-2个句子。chunk_selector可以是一个微调的BERT模型输入query document_chunk输出相关性分数也可以是规则引擎匹配关键词句法模式如包含“重置”、“密码”、“链接”、“点击”等动词短语的句子。在一次银行项目中我们对“信用卡挂失”知识库应用此架构。粗检召回3个PDF细检从中精准提取出6个句子如“挂失电话95588”、“在线挂失路径手机银行APP 我的 卡管理 挂失”。最终prompt里只注入这6个句子而非整个PDF。结果关键信息电话号码、路径的提取准确率从64%提升至97%且响应速度加快40%。所以RAG不是“扔更多数据给模型”而是“用更聪明的方式给模型最需要的那一小块数据”。知识库的大小永远不该是KPI精准供给的效率才是。4.4 “Agent失控”当你的智能体开始“自由发挥”如何紧急刹车最可怕的不是Agent不工作而是它“太能干”开始自由发挥。我亲眼见过一个客服Agent在用户问“我的订单到哪了”它没有调用track_order工具而是直接调用send_email工具给用户发了一封“我们正在全力处理”的安慰邮件。更离谱的是它还调用update_customer_status把用户标记为“high_priority”。这完全背离了设计初衷属于典型的“Agent失控”。失控的根源在于缺少硬性执行边界Hard Execution Boundary。很多Agent框架把“调用工具”的权限完全交给模型的自由意志。模型只要觉得“调用这个工具可能有用”就会执行。