
1. 从“幻觉”到“事实”为什么Agent需要Context Engineering最近在折腾各种AI Agent项目时一个老问题又浮出水面模型在规划或执行任务时经常“记错”或“误解”当前步骤所需的关键信息。比如你让一个Agent帮你分析一份财报它可能在计算某个关键比率时错误地引用了前几步已经修正过的旧数据或者干脆“脑补”了一个不存在的数字。这种现象我们通常称之为模型的“幻觉”或上下文混淆。但仔细想想这真的只是模型能力不足吗很多时候问题出在我们如何为模型“准备”和“呈现”信息上。这就是“Context Engineering”要解决的核心痛点确保Agent在当前决策的“这一刻”看到的是正确、完整且相关的事实。传统的Prompt Engineering提示工程教会我们如何“问问题”比如通过思维链Chain-of-Thought引导模型推理。但Context Engineering更进一步它关注的是“给信息”——如何动态地、精准地为模型构建每一步推理所需的上下文环境。你可以把它理解为Agent的“工作记忆管理”或“实时信息导航系统”。一个没有经过良好上下文工程的Agent就像一个在杂乱书房里找资料的研究员虽然书房向量数据库里什么书都有但他可能因为光线信息检索方式不好或书架信息组织太乱在需要查证一个关键公式时拿错了上一本笔记。为什么这如此重要因为现代Agent的工作流往往是多步骤、长序列的。从理解用户意图、拆解任务、调用工具、整合结果到最终输出每一步都严重依赖前序步骤的准确输出和外部知识。如果上下文管理不当错误会像滚雪球一样累积导致最终结果完全偏离轨道。Context Engineering的目标就是通过一系列设计原则和技术手段为Agent的每一步“擦亮眼镜”确保它基于最清晰、最相关的事实进行判断和行动。2. Context Engineering的核心组件构建Agent的“事实看板”要让Agent看到正确的事实我们不能只靠模型自身的注意力机制而需要主动设计一套信息供给系统。这套系统通常由几个核心组件构成它们共同作用像一个精密的仪表盘为Agent的当前操作提供实时数据支持。2.1 动态上下文窗口管理大语言模型LLM的上下文长度有限即使是128K或更长的窗口也无法无脑塞入所有历史信息。动态管理的关键在于“选择性记忆”和“重要性排序”。策略一滑动窗口与关键信息锚点最基础的策略是维护一个固定大小的最近对话历史滑动窗口。但这不够智能。我们需要设立“关键信息锚点”。例如在一个数据分析任务中用户最初提供的“分析2023年Q4财报”这个指令以及从数据库中提取出的“2023年Q4营收为1.2亿”这个核心事实应该被标记为锚点并始终以高优先级保留在上下文窗口中无论中间经历了多少步数据清洗和计算。而中间某一步尝试但失败的SQL查询语句其细节可能很快被移出窗口只保留“查询失败”这个结果摘要。策略二递归式摘要与精炼对于长程任务可以采用递归摘要。当上下文即将填满时不是粗暴地丢弃最早的信息而是调用模型本身将较早的、非锚点的大量交互历史如多轮调试对话总结成一段精炼的要点。例如“用户曾要求调整图表颜色为蓝色系并修正了X轴标签的格式。最终图表样式已确定。” 这样既保留了关键决策脉络又释放了空间。实操技巧设定上下文“保鲜期”为不同类型的信息设定逻辑上的“保鲜期”。工具调用的原始响应如200行的JSON数据可能只在紧随其后的1-2步内需要完整呈现之后就应该用提取出的关键字段如{“status”: “success”, “total_count”: 150}来替代。这需要我们在Agent框架中设计信息压缩和降噪的环节。2.2 精准的事实检索与验证Agent所需的事实常常来自外部知识源如数据库、API或文档。简单的向量检索RAG可能会引入不相关或过时的信息。Context Engineering要求检索是“目标导向”和“可验证的”。目标导向检索在Agent准备执行一个步骤例如“计算毛利率”前检索系统不应只是基于“毛利率”这个关键词进行语义搜索。更有效的方式是结合完整的当前任务状态“正在分析公司A的2023年财报”和步骤意图“需要营收和成本数据”来构建检索查询。查询可能是“公司A 2023年度 营业收入 营业成本 财务报表”。这比单一关键词的召回精确度要高得多。事实的交叉验证与溯源对于关键事实尤其是数值型数据应设计验证环节。例如从一份PDF中提取的营收数字最好能通过调用另一个工具如数据库查询API进行二次确认。在上下文中可以这样呈现事实【已验证事实】公司A 2023年Q4营收 - 来源1财报PDF解析120,000,000 元 - 来源2数据库查询120,500,000 元 - 采纳值120,000,000 元以官方财报PDF为准这种呈现方式让Agent和后续的审计者清晰地看到数据的来源和决策依据极大增强了结果的可靠性。工具调用结果的标准化封装工具函数调用的返回结果往往是杂乱的。一个良好的Context Engineering实践是设计一个结果包装器强制将工具返回的数据转换为结构化的、带有元数据的格式。例如{ “fact”: “120000000”, “unit”: “CNY”, “source”: “database_query_v1”, “confidence”: 0.95, “timestamp”: “2024-05-27T10:30:00Z”, “relevant_to_step”: [“calculate_gross_profit_margin”] }这样下游的LLM可以轻松、无歧义地理解和引用这个事实。2.3 状态跟踪与事实图谱复杂的Agent任务涉及多个实体及其关系变化。维护一个轻量级的“事实图谱”或“状态字典”至关重要。实体中心的状态跟踪以电商客服Agent为例交互中会涉及“用户”、“订单”、“商品”、“物流”等实体。我们需要一个中央状态跟踪器记录每个实体的核心属性及其最新、最确定的值。状态快照 (Step 5): - 用户: {id: “U123”, 问题: “订单未送达”} - 订单: {id: “O202405271234”, 状态: “已发货”, 物流单号: “SF123456789”, 最新轨迹: “2024-05-26 18:00 到达上海中转站”} - 当前待办: 根据物流单号查询最新详细轨迹。在每个推理步骤开始前将这个状态快照的最新版本注入上下文。这确保了Agent在任何时候讨论“订单状态”时指的都是同一个、最新的、共识的事实。事实的声明与撤销当新证据出现时旧事实可能被推翻。系统需要支持事实的更新和撤销。例如之前根据用户描述记录“商品破损”但后续收到用户上传的图片经视觉模型分析为“商品完好仅外盒皱褶”那么“商品破损”这个事实就应该被明确标记为“已撤销”或“更正为...”。在上下文中可以保留旧事实的痕迹但加上删除线并清晰呈现新事实这有助于模型理解决策的演变过程。3. 在主流Agent框架中实施Context Engineering理论需要落地。我们来看看如何在像LangChain、LlamaIndex或自定义框架中实践上述原则。3.1 设计上下文组装管道Context Assembly Pipeline不要简单地将所有历史消息和检索结果拼接起来扔给LLM。应该建立一个可配置的管道输入当前用户输入 完整对话历史 外部知识检索结果 内部状态快照。过滤与排序模块根据当前步骤的类型是规划、工具调用还是总结应用不同的规则过滤历史消息。例如在工具调用步骤优先保留最近的工具使用规范和结果在规划步骤则保留高层任务描述和之前的计划。压缩与摘要模块对过滤后仍较长的历史应用摘要或提取关键操作指令。格式化模块将状态快照、检索到的事实按照易读的模板如Markdown表格、项目符号列表进行格式化。明确区分“系统指令”、“历史对话”、“当前状态”、“可用事实”等部分。输出组装好的、结构清晰的上下文字符串送入LLM。示例一个数据分析Agent的上下文片段## 系统指令 你是一个数据分析助手。请基于以下事实和状态执行下一步操作。 ## 当前任务状态 - 总体目标分析公司ABC 2023年财务表现。 - 当前阶段已完成营收数据提取正在计算盈利能力指标。 - 下一步建议计算毛利率、净利率。 ## 已验证核心事实 | 指标 | 数值 | 单位 | 数据源 | 置信度 | | :--- | :--- | :--- | :--- | :--- | | 2023年总营收 | 1.2 | 亿元 | 财报PDF解析 | 高 | | 2023年总成本 | 0.78 | 亿元 | 数据库查询API | 高 | ## 最近相关操作 - 已调用工具 fetch_revenue成功获取营收数据。 - 已调用工具 fetch_cost成功获取成本数据。 ## 可用工具 - calculate_ratio(a, b, ratio_name): 计算比率并返回解释。这样的上下文让模型一目了然“我在哪”、“我有什么”、“我该干什么”。3.2 利用智能体Agent框架的Memory与State管理大多数现代Agent框架都提供了Memory记忆抽象。我们需要定制化地使用它们。ConversationBufferWindowMemory可以用于保存最近几轮对话但最好配合自定义的k值并为重要消息打上“钉住”pin的标签防止其被滑动出去。ConversationSummaryMemory / EntityMemory这些是更高级的记忆体。ConversationSummaryMemory可以自动生成历史摘要非常适合长对话。EntityMemory则能自动提取和跟踪对话中提到的实体信息这正好服务于我们“事实图谱”的需求。我们可以定期将EntityMemory的内容格式化后注入上下文。自定义State状态对象在LangChain的AgentExecutor或自定义循环中维护一个全局的、结构化的Python字典或Pydantic模型作为状态容器。这个容器存储那些需要跨步骤传递的、确定的事实和任务元数据。在每个迭代开始将这个状态对象渲染成文本插入到提示词中。避坑指南记忆体的序列化与成本频繁地将大量历史消息或向量存储的记忆体塞进上下文会迅速消耗令牌数并增加API成本。一个重要的实践是区分“存储记忆”和“激活记忆”。所有历史可以安全地存储在向量数据库或普通数据库中存储记忆但在每一步只有经过管道筛选和压缩的、最相关的部分才被“激活”并放入LLM的上下文窗口。这需要在框架中精细地设计记忆的读取策略。3.3 提示词Prompt模板的精细化设计最终的上下文是通过提示词模板组装的。模板的设计直接决定了事实的呈现清晰度。采用分节、标记清晰的模板如上文示例所示使用清晰的Markdown标题#####或分隔符---来划分上下文的不同部分。LLM对这类结构化的信息理解得更好。为事实添加元数据标签在模板中不仅呈现事实内容还呈现其来源和置信度。例如[来自数据库-高置信度] 用户会员等级黄金VIP。这相当于给事实加上了“引用”和“评注”引导模型更审慎地使用它们。指令明确化在模板的系统指令部分明确告诉模型如何处理这些上下文。例如“你必须在‘已验证核心事实’部分寻找计算所需的数据。如果数据缺失或冲突请优先使用置信度高的来源并可以请求调用工具进行核实。请基于‘当前任务状态’来决定下一步行动。”4. 实战案例构建一个“零幻觉”的财报分析Agent让我们通过一个具体案例串联起上述所有概念。目标是构建一个Agent用户上传一份财报PDF它能够自动提取关键数据进行计算分析并生成报告且过程中确保数据引用的绝对准确。4.1 系统架构与工作流设计任务接收与解析用户输入“分析这份财报”。Agent调用文本提取工具解析PDF原始文本存入“文档存储”。关键信息提取事实获取Agent调用信息抽取工具或LLM函数调用从原始文本中结构化提取“营业收入”、“营业成本”、“净利润”等关键字段。每个提取结果都被封装为带有来源原文片段、置信度提取模型得分的“事实对象”存入“已验证事实池”。状态初始化创建任务状态{stage: “data_extraction”, extracted_facts: […], target_ratios: [“gross_profit_margin”, “net_profit_margin”]}。循环执行分析步骤 a.上下文组装根据当前stage从“已验证事实池”中检索相关事实如计算毛利率时检索“营业收入”和“营业成本”从“文档存储”中检索相关的解释性段落连同当前state一起送入“上下文组装管道”。 b.LLM推理与规划LLM收到富含事实的上下文输出下一步动作如“调用计算工具calculate_ratio(1.2, 0.78, ‘gross_profit_margin’)”。 c.工具执行与验证计算工具返回结果如0.35。系统将此结果作为一个新的事实“毛利率为35%”其来源是“基于已验证事实[营收成本]的计算”置信度为“高”并更新状态stage: “ratio_calculation”。 d.事实池与状态更新新事实存入事实池。状态更新准备下一步如计算净利率。报告生成所有比率计算完毕后stage变为“reporting”。上下文组装管道会收集所有核心事实和计算过程供LLM生成最终分析报告。报告中的每一个数据点都能追溯到事实池中的某个源头。4.2 确保“正确事实”的关键设计点事实的唯一标识与冲突解决每个事实有一个唯一ID如fact_rev_2023_q4。当提取工具从PDF不同位置提取出两个不同的“营业收入”值时系统会触发冲突解决流程要么请求人工复核要么根据预设规则如“取最新日期章节的值”、“取数值更大的值作为保守估计”自动裁决并记录裁决日志。最终事实池中只有一个“权威”值被标记为is_activeTrue。上下文的版本化每一步的完整上下文包括输入给LLM的提示词和LLM的响应都可以被记录下来。当最终报告出现疑问时可以回溯查看在计算某一步时Agent到底“看到”了哪些信息实现了完全的审计追踪。容错与事实补充请求如果LLM发现上下文缺少必要事实例如要计算净利率但缺少“税费”数据它不应猜测而应输出一个标准化的“事实请求”动作。系统会捕获这个请求并触发新一轮的信息提取或向用户提问。这形成了一个“感知-缺口-补充”的闭环。4.3 可能遇到的挑战与应对性能开销每一步都进行检索、状态管理、上下文组装会增加延迟。应对策略包括对事实池建立索引实现快速检索异步执行非关键路径的组件缓存那些不变的基础事实。复杂性系统变得比简单提示复杂得多。这需要通过封装良好的框架和库来降低实现门槛。利用像LangChain这样的框架提供的RunnableLambda、RunnableBranch等组件可以将上下文管理逻辑模块化。评估困难如何评估Context Engineering的效果除了最终任务的准确性可以设立中间指标如“事实引用准确率”报告中的数据点是否能正确追溯到源头、“幻觉步骤比例”在多少推理步骤中模型使用了未提供或错误的事实。5. 超越基础Context Engineering的进阶模式当基础的事实管理驾轻就熟后我们可以探索更高级的模式让Agent的认知能力再上一个台阶。5.1 多模态上下文融合对于能处理图像、音频的AgentContext Engineering需要管理异构信息。例如一个维修指导Agent同时看到了设备说明书文本PDF和用户拍摄的故障部位照片。上下文需要融合这两者【文本事实】手册第5页正常状态下指示灯A应为绿色常亮。 【视觉事实】用户上传图片分析结果图中指示灯A为红色闪烁。 【冲突/补充】视觉事实与文本事实描述的状态不符。推断设备可能处于故障模式B。系统需要将多模态模型对图片的描述转化为结构化的文本事实并和文本事实进行关联、比对形成统一的认知上下文。5.2 基于元提示Meta-Prompting的上下文优化我们可以让Agent具备一定的“上下文自省”能力。即在主要任务提示之外提供一个“元提示”让模型对当前上下文的质量进行评估和优化建议。例如【元指令】请评估以下“当前任务状态”部分是否清晰、无歧义地描述了下一步该做什么如果不够清晰请提出修改建议。LLM可能会反馈“‘计算盈利能力指标’不够具体建议明确为‘计算毛利率和净利率’。” 然后系统可以自动采纳这个建议来更新状态描述。这实现了一种动态的上下文质量校准。5.3 预测性上下文预加载对于可预测的任务流Agent可以提前加载下一步可能需要的上下文。例如在客服场景中当用户说“我的订单没收到”Agent在回复的同时就可以在后台异步触发物流查询API。这样当用户下一句问“现在到哪了”时最新的物流信息已经作为“已验证事实”准备好了可以瞬间被纳入上下文实现零等待的流畅体验。这要求Agent具备一定的任务预测和预执行能力。Context Engineering不是一项孤立的技术而是贯穿Agent设计、开发、评估全过程的一种工程哲学。它要求我们从“模型中心”的思维转向“系统中心”的思维精心设计信息流动的每一个环节。其终极目标是让AI Agent不仅强大而且可靠、可信、可审计。这或许是当前让AI真正走向实用化、迈向“靠谱”的智能体的最关键一步。