转载--Karpathy 怎么看 AI Agent(三):怎么给 Agent 搭一个真正能用的上下文
原文https://mp.weixin.qq.com/s/qZRp0KI69PThh_YknMfVRw一、从框架到操作之间的鸿沟理解了上下文是 Agent 的内存之后很多人面临的下一个问题是好我知道上下文很重要。那我具体应该怎么做这个问题没有标准答案——不同的任务、不同的 Agent 架构、不同的模型上下文设计的最优解是不同的。但 Karpathy 的工程经验以及 2024-2026 年大量生产级 Agent 系统的实践给出了一套可以作为起点的设计原则。这篇文章不讲理论讲操作。从一个 Agent 上下文的四个组成部分开始到怎么验证它有没有设计好到怎么用失败来迭代它。二、上下文的四个组成部分一个运行中的 Agent它的上下文窗口通常包含四类信息。理解这四类信息各自的作用和设计要点是搭建有效上下文的第一步。第一类系统提示System Prompt这是上下文的宪法——定义 Agent 是谁、能做什么、不能做什么、遇到各种情况应该怎么反应。大多数人的系统提示写得像一段自我介绍你是一个专业的客服助手负责回答用户关于产品的问题语气友好回答简洁。这样的系统提示能用但不够用。在 Agent 场景里系统提示更重要的部分是决策边界当用户要求你做系统提示没有明确授权的事情时你怎么办当你不确定某个操作是否应该执行时你是执行还是暂停等待确认当你遇到工具调用失败时你是重试、跳过还是报告给用户当任务目标和某个中间步骤的结果产生矛盾时你优先遵循哪个这些边界不写清楚Agent 就会在这些情况下自行判断——有时候判断对有时候判断错而且不可预测。设计要点系统提示不是越长越好。把角色定义控制在 100 字以内把决策边界写清楚把最常见的异常情况的处理方式明确说明。长而模糊的系统提示比短而精确的系统提示更差。第二类任务上下文Task Context这是 Agent 执行当前任务需要知道的所有背景信息——不是永久性的角色定义是这一次具体任务相关的信息。包括任务目标、相关数据、约束条件、历史记录、用户偏好、领域特定的术语和规则。这一类是最容易出现信息缺口的地方。你知道这些信息Agent 不知道而且它不会主动来问你——它会用听起来合理的假设来填补。设计要点在开始任务之前问自己一个问题如果我把这个任务交给一个聪明但对我们公司完全陌生的新员工他最可能在哪里卡住或者做出错误假设把那些地方的信息主动放进任务上下文。不要期待 Agent 会问你——它通常不会它会继续往前走。第三类工具结果Tool ResultsAgent 调用工具——搜索、数据库查询、代码执行、API 调用——工具返回的结果会进入上下文成为 Agent 下一步判断的依据。这一类是最容易被忽视的上下文设计问题。大多数人在设计 Agent 系统时把工具的输出直接传给 LLM不做任何处理。但工具的原始输出通常是为机器设计的不是为 LLM 设计的数据库返回的 JSON可能包含大量 Agent 不需要的字段搜索结果可能包含大量不相关的内容代码执行结果可能包含冗长的 stack trace而 Agent 真正需要的只是错误类型和关键行号API 返回可能包含分页信息、元数据、状态码——Agent 只需要实际内容把这些原始输出直接塞进上下文是在用宝贵的 Token 容量装噪音。设计要点为每个工具设计一个输出格式化层——在工具结果进入上下文之前把它压缩成 Agent 真正需要的格式。一个好的工具输出格式化的标准如果你把这个格式化后的输出给一个人看他能在 10 秒内理解关键信息。如果不能继续精简。第四类执行历史Execution History在多步骤任务里Agent 之前做了什么、得到了什么结果需要在上下文里有某种形式的记录——否则 Agent 在后续步骤里会忘记前面发生了什么。这是上下文窗口管理最复杂的部分因为历史记录会随着任务推进不断增长而上下文窗口是有限的。处理这个问题有三种主要策略策略 A保留原始历史把所有历史原封不动地保留在上下文里。简单但随着任务推进上下文会越来越长最终超出窗口限制或者因为过长而导致注意力稀释。适合步骤少、每步输出短的简单任务。策略 B滚动窗口只保留最近 N 步的历史丢弃更早的。处理了长度问题但 Agent 会忘记早期的重要决策。适合每一步都相对独立、不太依赖早期历史的任务。策略 C摘要压缩定期把历史压缩成摘要——用 LLM 把最近 10 步的历史总结成 3-5 句关键信息然后用摘要替换原始历史。在保留关键信息的同时控制长度。适合长任务但摘要质量会影响 Agent 后续判断。设计要点大多数生产级 Agent 系统最终采用的是策略 B 和策略 C 的组合——对近期历史用策略 B 保留原文对远期历史用策略 C 压缩成摘要。这个边界在哪里需要根据具体任务调整。三、一个可以直接用的上下文设计检查清单在把 Agent 交给真实任务之前过一遍这个清单【系统提示检查】□ 角色定义是否精确有没有模糊的专业、智能之类的形容词□ 决策边界是否写清楚——不确定时怎么办遇到错误时怎么办□ 最常见的异常情况至少 3 种是否有明确的处理指引□ 系统提示是否有内部矛盾——两条规则在某种情况下会相互冲突【任务上下文检查】□ 如果把这个任务交给完全不了解我方情况的新员工他最可能在哪里卡住□ 那些我觉得不用说大家都知道的信息是否已经放进了上下文□ 任务的成功标准是否明确说明了Agent 怎么知道它完成了□ 有哪些约束条件不能做什么、必须避免什么是否明确说明【工具结果检查】□ 每个工具的原始输出是否经过了格式化处理再进入上下文□ 格式化后的输出是否去除了 Agent 不需要的字段和信息□ 错误信息是否包含足够的信息让 Agent 判断下一步——只有错误码是不够的【执行历史检查】□ 选择了哪种历史管理策略原始/滚动/摘要这个选择适合这个任务吗□ 有没有设计强制保留机制——某些早期决策无论如何都不能被压缩掉□ 上下文长度有没有监控——在接近窗口限制之前有没有触发压缩的机制这个清单不是一次性的。每次 Agent 出现意外行为回来对照清单找到是哪一项没有处理好。四、怎么知道你的上下文设计是否有效上下文设计好不好最终要看 Agent 的表现。但Agent 表现不好是一个太模糊的观察——你需要把它翻译成更具体的诊断。诊断方法一让 Agent 复述任务理解在 Agent 开始执行之前先让它用自己的话复述一遍它对任务的理解包括它认为的任务目标、它知道的约束条件、它打算怎么推进。如果它的复述和你的预期有偏差现在修正比任务跑完之后修正代价小得多。这一步听起来多余但在真实工程实践里它能在任务开始阶段拦截大约一半的方向性偏差。诊断方法二在关键步骤检查 Agent 的推理不是看最终输出是看 Agent 在关键决策节点的推理过程。大多数 Agent 框架支持让 Agent 输出它的思考过程Chain of Thought。在关键步骤上开启这个功能看 Agent 的推理链它用了哪些信息做判断有没有你知道是错误的前提出现在推理链里有没有它本来应该知道但显然不知道的信息缺口推理链诊断比结果诊断更有效——因为它让你看到问题在哪里产生而不是只看到问题的结果。诊断方法三故意制造边缘情况在你把 Agent 部署到真实任务之前用你能想到的边缘情况来测试它输入信息不完整时它怎么处理工具调用失败时它怎么处理任务目标和中间结果产生矛盾时它怎么处理它接收到了相互矛盾的信息时它怎么处理如果这些边缘情况在测试阶段没有被发现它们会在生产环境里以更高的代价出现。五、怎么用失败来迭代上下文上下文设计不是一次性完成的是在失败里迭代出来的。Karpathy 有一个他自己实践的习惯把 Agent 的每次失败分类而不只是修复单次失败。分类的框架很简单这次失败属于哪种类型├── 信息缺口Agent 需要某个信息但上下文里没有├── 信息过载上下文里信息太多太杂Agent 忽略了关键部分├── 指令矛盾系统提示或任务描述里有相互冲突的规则├── 工具输出噪音工具返回的结果格式化不够干扰了 Agent 判断├── 历史压缩损失执行历史被压缩时丢失了关键信息└── 边界模糊Agent 在决策边界上做了不符合预期的自主判断知道了类型修复方向就清楚了信息缺口 → 在对应位置补充任务上下文信息过载 → 精简上下文去掉不相关的信息指令矛盾 → 回到系统提示找到矛盾的地方明确优先级工具输出噪音 → 改进工具的输出格式化层历史压缩损失 → 调整历史管理策略把关键决策标记为强制保留边界模糊 → 在系统提示里补充对应边界情况的明确规则每修复一类失败同类任务的成功率就系统性地提升一点。这个迭代过程没有终点但它有一个明显的规律前十次失败能覆盖大约 80% 的常见问题类型。认真分析并修复这十次失败Agent 的可靠性会有质的提升。