1. 为什么说上下文是 Agent 的“第二大脑”
做 AI Agent 开发这大半年,我踩过最深的坑不在模型选型,不在推理框架,而在一个看起来特别“软”的环节——上下文工程。你给 GPT-4o、Claude 这类模型直接丢一个问题,它回答得往往不错;可一旦把它包装成 Agent,让它自己规划步骤、调用工具、读取文档、处理中间结果,问题就全冒出来了:答非所问、重复调用同一个工具、把上一次对话的结论当成当前问题的答案、甚至完全忘记用户最开始要的是什么。
这些问题根子上都指向同一个原因:上下文没管好。
所谓上下文工程,简单说就是管理“进入大模型窗口的所有内容”的一整套方法——系统提示词、用户输入、工具返回结果、历史对话、检索到的外部知识、中间推理过程,全都算。它直接决定了模型在一个具体任务里能“看到”什么,进而决定了它能不能做出正确的决策。模型本身不会记忆,你给它看什么,它就只能基于什么来思考;你给错了、给多了、给乱了,它就会在错误的信息上自信地胡说八道。
传统RAG(检索增强生成)解决的是“如何把知识库内容塞进上下文”,但面向 Agent,上下文工程的范畴要大得多。Agent 会多轮调用工具,每轮工具返回都可能携带大量噪音;Agent 要自主决策,就必须把“目标、约束、进度、已知条件、待办事项”这些状态信息完整地呈现给模型;Agent 还要具备记忆,短期记忆管当前任务,长期记忆管跨会话的经验。每一层处理不当,都会直接反映在最终效果上。
一句话概括我的体会:模型能力决定 Agents 的上限,上下文工程决定 Agents 的下限。你把上下文管好了,一个普通的模型也能稳定干活;管不好,再强的模型也会变成一个“看起来聪明、用起来崩溃”的玩具。
这篇文章我不会堆概念,而是从实战角度拆开讲:Agent 的上下文到底由哪些部分组成、每一部分该怎么设计、主流框架(LangGraph、Spring AI Agent 这类)是怎么管理的,以及我最常遇到的项目级上下文污染问题和对应的排查手段。内容偏工程向,适合已经跑过简单 Agent Demo、正在做真实项目的开发者参考。
2. 我踩过的第一个坑:Agent 忘了“用户最开始要什么”
先讲一段真实经历。
刚上手 LangGraph 做 Agent 那会儿,我搭了一个所谓的“数据分析助手”:用户输入问题,Agent 自己决定要不要调用 Python 代码解释器、要不要查数据库、要不要搜索文档,最后汇总结果。第一次测的时候还算顺利,但第二轮我就发现了一个诡异的现象——用户先问“帮我统计上季度各区域销售额”,Agent 正确调用了 SQL 工具拿到了数据,接着用户追问“东北区哪个月降幅最大”,Agent 居然又跑了一遍 SQL 查了全量数据,然后开始回答“上季度各区域的销售额分布是……”,直接把第一个问题的结论重复了一遍。
我调试了很久,最后打开 LangGraph 的 Trace 日志才看明白问题:在第二轮对话里,Agent 的上下文只有“当前用户消息 + 最近几轮消息摘要”,而摘要把第一轮的关键约束——“统计对象是各区域销售额,重点是区域间对比”——给压缩掉了。模型看到的只是零散的“用户要统计”“工具返回了表格”,它判断不出自己当前究竟处在任务的哪个阶段、已经完成了什么、下一步该做什么。于是它选择“重新做一遍”,而不是“基于已有结论继续回答”。
这个案例特别典型。它说明了一个被很多人忽略的事实:Agent 的上下文不仅是“信息容器”,更是“状态载体”。模型每次推理都需要回答三个问题:我现在在哪一步、我手里有什么、我接下来要干什么。这三个问题如果答案不清晰,任何复杂任务都会翻车。传统单轮 Prompt 不需要考虑这一点,因为问题、背景、约束都在同一条用户消息里;但 Agent 是跨多轮、跨工具的,信息会被一步步拆分、传递、加工,你必须在每一轮都把“任务状态”完整、准确地交付给模型。
后来我总结了一套自己的上下文状态管理规则,核心就三条:
- 每一轮消息都必须带上完整的任务目标描述,哪怕会重复,也不能省。不要指望模型从历史对话里“领悟”目标。
- 工具调用结果必须附带结构化摘要,尤其是查询类工具,返回原始表格前先算好“这个结果说明了什么”,把这句结论给模型。
- 上下文中的每条消息都明确标注角色——哪些是用户的要求,哪些是系统的约束,哪些是工具返回的事实。角色混在一起时,模型很容易把工具输出误当成自己的判断,产生幻觉。
这三条听起来简单,但真正做到位,需要你对 Agent 的每一条消息流都有清晰的掌控。接下来的章节我会逐一展开细说。
3. Agent上下文的四大组成:不止是“提示词”那么回事
很多人一提上下文,就以为“只要把 Prompt 写长一点、把资料贴进去”就行。真做 Agent 就会发现,这是一种极其危险的简化。以一个典型的 LangGraph Agent 为例,我每一轮向模型发送的上下文,实际上由四类内容叠在一起,每一类都有独立的工程策略。
3.1 系统提示词:Agent的“岗位说明书”和“操作手册”
这是上下文里最稳定、也最常被轻视的部分。系统提示词不只是一个“角色设定”,它更是一个完整的“岗位说明书 + 操作手册”。我现在的推荐写法是分区块组织,每个区块解决一类问题:
- 角色与目标:用一两句话说清楚这个 Agent 是干什么的、服务谁、追求什么效果。
- 能力边界:明确它能调用哪些工具、不能做什么。这个相当重要——不给模型划边界,它就会自己“发明”工具调用,或者在没有依据的情况下强行回答。
- 工作流程:如果有标准流程(先分析、后规划、再执行、最后复盘),写清楚。
- 工具使用规则:每个工具什么时候用、怎么填参数、返回结果后要做什么。这里可以引用工具函数命名,让模型把工具名和它的具体动作绑定起来。
- 输出格式规范:要求模型最终回答时采用什么结构,方便下游解析。
- 禁忌清单:明确哪些事绝对不能做,比如不编造数据、不越权操作、不重复调用同一工具。
写系统提示词有一条心得:不要让它过长。模型对上下文的注意力不是均匀分配的,越靠后的内容权重往往越高,系统提示词如果写了几千字的“规章制度”,真正关键的约束反而会被淹没。我现在给自己的上限是 1500 字左右,确保每条指令都是“必要指令”,而不是“可能有用”的废话。实测下来,精简过的系统提示词,指令遵循率明显高于长篇大论版本。
3.2 用户消息层:把“目标”和“约束”结构化
很多 Agent 项目犯的错误,是直接把用户的一句话丢进模型,就期望它能干复杂活儿。实际上,用户表达往往模糊、缺省、口语化,模型要理解“帮我看看最近的异常订单,分析下原因”这句话背后到底藏着多少隐含需求,是很吃上下文的。
我的做法是在 Agent 入口做一个“目标解析 + 约束补全”的前置环节,把用户的原始消息加工成结构化的任务描述,再放进上下文。加工之后的消息大概是这个形态:
用户核心目标:分析最近7天异常订单(退款率>5%)的主要原因 任务背景:异常订单集中在华东区,涉及3个商品线 约束条件: 1. 只基于数据库实表数据,不猜测 2. 结论需附数据支撑 3. 若数据不足,明确告知用户,不要编造 待办事项: - [ ] 查询异常订单明细 - [ ] 分析原因分布 - [ ] 给出改进建议这段内容放在用户消息层的最前面,模型一眼就能看到“目标+约束+待办”,后面无论发生多少轮工具调用,它都不容易跑偏。这个做法本质上是把“用户意图”显式化为“任务状态”,是上下文工程里性价比最高的一个动作。
3.3 工具定义与返回结果:Agent的“双手”和“眼睛”
工具调用是 Agent 最核心的能力,也是上下文最容易“灌水”的地方。每调用一次工具,函数定义、参数、返回结果都会进入上下文。如果工具返回一大段 JSON 日志、一大堆无关字段,模型既浪费 token,又容易从噪音里提取错误信息。
我对工具层做了两个关键改造:
一是工具描述必须精简且包含“什么时候用”。同样一个查询订单的函数,写“查询订单信息”和写“当用户询问订单详情/物流/金额时使用,入参order_id必填”,模型调用准确率完全两个级别。工具描述本质上是给模型看的“路由说明”,越是清晰的路由说明,模型的工具选择越准确。
二是工具返回结果必须做“后处理压缩”。我习惯在工具返回之后加一个轻量级的加工层:把原始 JSON 转写为“结构化摘要 + 关键字段”。比如查询订单返回了一个包含 40 个字段的订单对象,我会让加工层只提取模型真正需要用到的字段(订单号、金额、状态、用户备注),并增加一行“数据分析结论:该订单金额异常偏高,可能是拆单未遂或误操作”。模型拿到这行结论,后续推理的正确率会高很多。记住一个原则:让 Agent 的“眼睛”看结论,而不是让它自己去原始数据里大海捞针。
3.4 历史对话与记忆:短期、长期、工作记忆三层分离
Agent 的记忆不是“聊天记录的堆积”,而是分层的。我目前在生产环境用的是三层结构:
- 短期记忆:当前任务最近几轮的完整消息。保留完整原始消息,不压缩,用于保证局部上下文精确。
- 工作记忆:当前任务的关键状态,例如“已调用的工具列表”“已获取到的结论”“待验证的假设”。每次工具调用之后,我会在工作记忆里追加一条结构化记录。
- 长期记忆:跨会话的、值得沉淀的经验,例如“用户偏好用表格看数据”“上次排查发现数据源A有时间延迟问题,优先用数据源B”。长期记忆通过向量检索,只取最相关的 3-5 条注入上下文。
把历史对话不加区分地全量塞进上下文的做法,我劝你趁早放弃。它最直接的两个恶果:token 成本暴涨;模型注意力被旧内容稀释,导致对近期的关键信息“视而不见”。记忆分层之后,信息才能各归其位。
下面用一张表汇总这四类组成的职责和关键策略,方便对照自查:
| 上下文组成部分 | 核心职责 | 推荐策略 | 常见问题 |
|---|---|---|---|
| 系统提示词 | 角色、能力边界、工作流程、输出规范 | 分区结构化,控制在1500字内 | 过长导致关键约束被稀释 |
| 用户消息层 | 目标、背景、约束、待办 | 入口解析并结构化 | 原始消息模糊,模型自行发挥 |
| 工具定义与返回 | 工具选择、结果理解 | 精简描述+结果摘要化 | 原始JSON灌入,token暴涨且噪音大 |
| 历史对话与记忆 | 状态延续、经验复用 | 三层分离(短期/工作/长期) | 全量堆叠,注意力被稀释 |
4. 主流 Agent 框架里的上下文管理方式:LangGraph 与 Spring AI Agent 的对照
市面上 Agent 框架很多,不同框架对上下文的处理思路也完全不同。我实际用得最多的是LangGraph,也调研过Spring AI Agent(Java 生态),还简单看过 Rust 生态的做法。这一节主要说说 LangGraph 和 Spring AI Agent 的差异,以及它们各自逼你养成的上下文管理习惯。
4.1 LangGraph:状态图思维下的上下文流
LangGraph 的核心抽象是状态图。你把 Agent 的推理过程定义为一个个节点(node),节点之间通过状态(state)传递信息。这意味着上下文不再是“一条消息长河”,而是一个可编程、可迁移的状态对象。
我在 LangGraph 里最常用的一种做法,是自定义 state 结构,把上下文的四类组成显式建模出来:
class AgentState(TypedDict): messages: Annotated[list, operator.add] task: dict # 结构化任务目标 memory: dict # 工作记忆 tool_results: dict # 工具结果缓存每轮节点执行时,我可以精确控制要往模型消息里塞什么、不塞什么。比如在“规划”节点,我只把 task、memory 和最近几条 messages 拼给模型;在“执行工具”节点,我把 tool_results 的最新结果注入。这种精细控制带来的好处很明显——上下文的最小化:模型每次看到的永远只是“完成这一步推理所必需的内容”,不必背负全局历史。
LangGraph 的高阶玩法是把“路由逻辑”也写进上下文。比如根据工具结果判断“是否需要追问用户”“是否需要切换工具”,这些决策尽量不给模型自由发挥,而是用明确的规则写进下游节点的 prompt。这样既省 token,也减少模型“自作主张”带来的不确定性。
4.2 Spring AI Agent:Java 生态的结构化讲究
Spring AI Agent 我接触得不算深,但它的设计思路和 LangGraph 有显著区别。它更强调声明式配置和与 Spring Boot 生态的整合,其上下文管理非常适合企业级、规范化场景。
在 Spring AI Agent 里,提示词模板、工具描述、历史消息都以配置类和注解的形式管理,天然要求开发者对上下文“显式声明”。例如用@Tool注解定义工具时,工具的功能描述是强制项,这就是在逼你把“模型路由信息”写清楚。它的消息结构(SystemMessage、UserMessage、ToolMessage)也很规范,强制你在代码层面就区分上下文的角色,避免了 LangGraph 里常见的“消息角色混乱”问题。
如果你所在团队以 Java 为主,整体工程规范要求高,Spring AI Agent 会是一个更稳的选择。它牺牲了一些灵活性,但换来了清晰的结构和更低的出错率。
4.3 框架无关的一条原则:谁负责管理上下文,谁就拥有 Agent 的质量
不管是 LangGraph 的状态对象、Spring AI 的声明式配置,还是基于 Rust 的高性能实现,背后其实是一个共同的理念:上下文管理必须显式化、工程化,而不能依赖模型的“临场发挥”。模型偶尔能靠推理能力“救场”,但一个可靠的 Agent 架构,必须把上下文作为一个一等公民来设计——有结构、有规范、有流转逻辑。
我在换框架时对这一点体会特别深。最初用纯函数调用的方式写 Agent,上下文全凭手拼字符串,一遇到多轮任务就崩;后来迁移到 LangGraph,虽然上手成本高了一些,但所有上下文流转都有了明确的“状态依托”,Bug 率肉眼可见地下降了一截。框架之于上下文工程,就像轨道之于火车:轨道本身不产生动力,但没有轨道,火车跑不了长途。
5. Token 预算:上下文工程的底层物理约束
聊上下文就不能不谈 token。模型窗口是有限的,上下文工程的一切策略,最终都要落到“在这有限的窗口里,放什么、放多少、怎么放”这个终极问题上。很多人开发 Agent 到中期会发现:“唉,我的上下文为什么塞不下了?”这其实就是没做好 token 预算管理。
我在项目里建立了一套 token 预算分配表,每次构建上下文之前先按预算“计划分配”,再动手拼装。一份典型的长任务预算大致如下(以 128k 上下文窗口为例):
| 上下文区块 | 预算占比 | 预算量估算 | 说明 |
|---|---|---|---|
| 系统提示词 | 1% | 约1-2k | 保持精简,必要时拆成“常驻+按需加载”两段 |
| 用户任务描述 | 1% | 约1-2k | 结构化,目标+约束+待办 |
| 工具定义 | 5% | 约5-8k | 工具多了建议分组建装,不是全量加载 |
| 工作记忆与任务状态 | 4% | 约4-6k | 必须精简为结论型记录 |
| 工具返回结果摘要 | 15% | 约15-20k | 原始数据绝不直接进入模型 |
| 检索到的参考资料 | 20% | 约20-30k | 按相关性排序,只取 Top-N |
| 历史消息 | 20% | 约20-30k | 短中长记忆分层裁剪 |
| 预留余量 | 34% | 约40k | 应对模型思维链输出和突发信息 |
这张表的核心思想是:长期对话中必须给“未来”留出余量。很多出问题的 Agent 都是把上下文塞到 95% 满才开始回复,模型写到一半窗口就爆了,或者被迫遗忘一部分早期关键约束——这就是典型的“预算管理失败”。
Token 预算还涉及一个底层原理:注意力机制是资源池。大模型的注意力不是无限的,相关内容越多,每条内容分到的注意力权重就越低,越往后、越长的上下文,遗忘和忽略现象就越严重。这意味着“塞得越满”往往效果越差,反而“精准而克制”的上下文能获得更好的模型响应质量。上下文工程本质上是一门管理稀缺注意力的艺术。
关于 token 计算,我再补充一个实操细节:不同模型的 token 成本不一样,中文场景尤其要注意。Claude、GPT 这类模型对中文的 token 切分差异很大,同样 1000 个汉字,在不同模型里 token 数可能从 800 到 2000 不等。所以做 token 预算时,不要用“字数”估,要用“token 计数器”实测你的内容类型,然后校准预算。
6. 项目级上下文污染的四种常见形态与排查方法
前面讲的都是构建侧的优化,实际开发中,上下文“被污染”才是导致 Agent 行为异常的头号原因。我把自己这一年在真实项目里遇到的上下文污染形态整理了一下,分享四种最常见的,每一种都附了排查思路和修复方案。
6.1 故障形态一:工具结果“篡改”了用户目标
这是最危险的一种污染。
情景还原:用户说“帮我推荐一款适合送给爸爸的500元以内的手表”,Agent 第一次调用商品搜索工具时,返回结果里混入了大量“1000元以上智能手表”,因为工具端按“综合排序”返回了混合数据。模型看到丰富的数据,居然开始围绕“1000元智能手表”做推荐,完全无视了“500元以内”这个约束。
根因:工具返回的现实数据“喧宾夺主”,压过了用户目标在上下文中的权重。模型天然容易被具体的、近期的、细节丰富的信息吸引,而抽象的、放在前文的约束目标反而权重偏低。
排查方法:看 Trace 日志里的最终一轮模型输入,确认工具返回结果和用户消息在上下文中的相对位置。如果工具结果出现在最后、且篇幅很长,基本可以判断是它抢占了模型注意力。
修复方案:一是把用户任务约束在每次工具调用之后“重新强化”,比如在工具返回后的下一轮 prompt 开头重申“用户目标:500元以内手表,偏差是违反需求的”;二是对工具返回结果做硬过滤,在工具层直接把不符合约束的数据滤掉,而不是留给模型判断。记住:能靠程序解决的问题,不要丢给模型。
6.2 故障形态二:长会话中早期关键信息被“挤出”窗口
情景还原:用户在会话一开始设置了偏好:“所有回复用表格形式,数字保留一位小数”,Agent 前几轮一直遵守得很好,但聊到第 10 轮的时候,模型开始输出大段文字,数字也不管小数位了。
根因:滑动窗口式的历史消息管理,把最早的用户偏好信息当成“过期消息”截掉了。上下文保留的是“最近 N 条消息”,而不是“最重要的消息”。
排查方法:看历史消息保留策略的源码或配置。很多框架默认保留最近 N 轮,不会区分消息的重要性。
修复方案:在做历史消息裁剪前,先识别出哪些消息是“持久化约束”类信息(用户偏好、任务边界、数据口径),把它们单独抽出放进系统提示词层或工作记忆层,再对剩余历史消息做窗口裁剪。这是我在项目里改过之后效果非常明显的一处优化——裁剪前先做“重要消息提取”,再把提取结果注入到一个固定位置,即便窗口不断滚动,关键约束也始终在场。
6.3 故障形态三:检索知识喧宾夺主,压制模型自身推理
情景还原:Agent 带 RAG 功能,用户问“明天上海会不会下雨”,RAG 检索到一堆关于“上海历史气候”的文档,模型开始长篇大论介绍上海亚热带季风气候特征,就是不直接回答明天天气。
根因:检索结果在上下文里占据大篇幅,模型把它当成“主导信息”,而把用户的直接问题当成“次要信息”处理。尤其是在系统提示词没说明“检索资料仅作参考”的情况下,模型很容易跟着资料走。
排查方法:检查系统提示词里有没有“知识库信息优先级”声明。我建议明确写一句:“知识库信息仅供参考,请优先基于用户问题直接回答;知识库内容与用户问题冲突时,以用户问题和已验证数据为准。”
修复方案:给检索模块加一个“相关性判定 + 摘要压缩”的中间层。检索到资料后,不要直接把原始段落丢进上下文,而是先让一个轻量级模型或规则判断资料与用户问题的相关度,只把“高分相关”的部分压缩成要点句再注入。这一步对完整性、准确性和 token 成本都是巨大优化。
6.4 故障形态四:多 Agent 协作时的“上下文串味”
情景还原:我做一个“客服主管 Agent + 技术专员 Agent”的协作系统,用户先咨询了退款政策,又追问“为什么我的 App 一直闪退”,结果技术专员 Agent 的回复里居然引用了退款政策的条款,说“根据退款政策,闪退问题可以申请退款处理”,完全答非所问。
根因:多 Agent 共享了一个全局消息列表,技术专员 Agent 构建上下文时把客服 Agent 的历史回复也拿了进来,导致信息串味。
排查方法:检查消息的路由与隔离机制。如果所有 Agent 都从同一个“全局会话”取消息,就极容易出现这种互相污染。
修复方案:给多 Agent 系统设计“按 Agent 隔离的消息视图”。每个 Agent 只能看到自己的计划、思考、工具结果和用户需求;涉及跨 Agent 传递的信息,必须以“显式交接”的方式写入对方的工作记忆,而不是直接让对方读全局聊天记录。我用 LangGraph 时,会为每个子 Agent 单独维护一个 state,主 Agent 需要传递信息时,通过一个明确的“交接消息”来完成。
这张表汇总了四种污染形态的“症状—根因—解法”:
| 污染形态 | 核心症状 | 根因 | 推荐解法 |
|---|---|---|---|
| 工具结果压过用户目标 | 模型遗忘用户约束 | 工具数据量大且靠近末尾 | 工具层硬过滤+每轮重申目标 |
| 早期关键信息被挤出 | 中途开始违反偏好 | 滑动窗口不分主次 | 持久化约束提取到固定层 |
| RAG资料压过推理 | 长篇跑题不回答问题 | 检索内容权重失衡 | 相关度判定+摘要压缩 |
| 多Agent互相串味 | 答非所问引用他人结论 | 共享全局消息列表 | 消息视图隔离+显式交接 |
7. 三个让上下文质量明显提升的工程技巧
这一节分享三个我实测过、立竿见影的优化技巧。它们不属于某个框架的标配能力,但都能显著改善 Agent 的行为质量。
7.1 技巧一:结论先行,逐层展开
模型对上下文里的信息处理不是线性的、平等的。我观察到:把“结论/要点”放在“详细数据”之前,模型的正确率显著更高。这和人类的阅读习惯一样:先知道结论,再看数据,大脑更容易建立结构。
所以在构建工具返回结果摘要、RAG 检索片段时,我都会要求处理层输出“先一句结论,再列出支撑数据”。例如查询订单异常情况,优先给模型的是:“异常订单集中在华东区,主要原因是配送超时(占比62%)。” 然后才是具体的订单列表。模型拿到结论后再看数据,它就会围绕结论做判断,而不是在数据里漫无目的地寻找模式。
7.2 技巧二:给每个上下文区块打标签显式分隔
当上下文包含多类信息时(系统约束、用户目标、工具结果、检索知识、任务状态),我会在提示词里用显式的分隔标签把它们区隔开,例如:
<system_role>你是一个数据分析助手,专注于订单分析。</system_role> <user_task>用户核心目标:分析最近7天异常订单原因,约束:仅基于事实数据。</user_task> <tool_result>工具返回:异常订单原因分布为配送超时62%、商品质量21%、其他17%。</tool_result> <knowledge_ref>知识库:华东区域配送网络近期压单严重,平均延迟2.1天。</knowledge_ref> <task_state>已完成:查询异常分布;待办:给出改进建议。</task_state>分隔标签的真正价值不是“格式化好看”,而是给模型一个信息结构导航。模型在自我注意力计算时,能够更清楚地识别“哪一段对应哪种用途”,减少信息在语义空间里的混淆。实测下来,打了标签之后,Agent 工具路由准确率有接近 5 个百分点的提升,对复杂任务尤其明显。
7.3 技巧三:上下文监控与日志回溯
这是我最想强调、也最容易被忽视的技巧:上下文必须可观测。我在所有 Agent 项目里都加入了一个中间件,把每一轮发给模型的完整上下文 JSON 打到日志里,并计算每轮 token 消耗和注意力分布。真正遇到诡异行为时,这个日志就是唯一的、最有效的排查入口。
具体做法很简单:写一个 logging 拦截器,在模型调用前后,把 messages 数组、模型输出、token 统计全部序列化存储。出现问题时,你先看“模型当时到底看到了什么”,再追溯“这些内容从哪来、为什么进来”。很多网络上的调试教程会直接告诉你“加这句话进提示词”,但如果你不会看上下文日志,下次遇到新问题你依然会抓瞎。先学会看上下文,再谈调提示词。
8. 我的上下文工程设计落地清单
文章的最后,我把整个上下文工程的落地路径浓缩成一份可直接对照的自查清单。这份清单来自我的项目实践,你拿去对着你的 Agent 代码逐条检查,通常能一次性发现两到三个潜在问题。
设计阶段:
- 上下文四类组成是否有明确的模块边界(系统提示词、用户任务、工具结果、历史记忆)?
- 系统提示词是否控制在 1500 字以内且分区块组织?
- 用户输入是否经过“目标解析 + 约束补全”的结构化前置处理?
- 工具描述是否写清楚了“什么时候用、怎么用、返回后做什么”?
- 工具返回结果是否有“摘要化 + 结论化”的后处理层?
运行阶段:
- 历史消息是否按短期/工作/长期三层管理,而不是全量堆叠?
- 多轮对话中,持久化约束(用户偏好、任务边界)是否存在于固定位置,而不是随窗口滚动?
- 每次工具调用后,是否重新强化了用户目标?
- 检索知识入库前,是否有相关度判定和摘要压缩?
- 多 Agent 协作时,每个 Agent 的消息视图是否隔离?
- 是否预留了 30% 以上的 token 余量,避免上下文爆满?
监控阶段:
- 是否记录了每一轮完整上下文日志?
- 是否监控了 token 消耗和关键约束在上下文中的存活情况?
- 是否有基于日志回溯的异常排查 SOP?
这套清单看起来琐碎,但每一条背后都是一个真实的线上事故。把上下文工程当成 Agent 架构的一等公民来对待,前期多花一点时间设计和埋点,后期就能少熬好几个晚上的 Debug。上下文工程没有银弹,有的只是一件一件做对的小事。