AI Agent 长任务总跑偏?4 个方法做好上下文工程

14 阅读14分钟

AI Agent 长任务总跑偏?4 个方法做好上下文工程

你让 Agent 修一个线上问题:先读日志,再定位代码、改实现、补测试,最后跑验证。

前几步都很顺。到了后面,它却改了已经确认不能动的接口,重复尝试刚刚失败过的方案,甚至把“先给出诊断,不要直接发布”忘在了几十轮对话之前。

这时我们很容易得出结论:模型还不够聪明,或者上下文窗口还不够大。

但长任务里,真正的问题往往不是 Agent 看过多少信息,而是它在做当前这一步时,能不能拿到正确、最新、可用的信息。模型窗口像一张有限的工作台:重要规则、当前目标、代码片段、工具返回、旧对话都在争位置。把工作台做得更大有帮助,却不会自动把东西摆对。

这就是上下文工程要解决的问题。以 Codex 2026 年 9 月的 0.153.0 和 0.158.0 两次更新为例,可以看到上下文预算、历史记录和压缩流程如何逐步成为运行时要处理的问题。

Codex 的变化,为什么不只是“把对话压短”

先把两个词说清楚:上下文是模型当前这一步实际能看到并利用的信息;compaction(压缩)是在空间紧张时整理出继续工作所需的内容,为后续步骤腾出空间。压缩不是把整段历史无损缩小,更不是删除项目里的文件。

Codex 0.153.0 和 0.158.0 的更新,可以按它们在解决的工程问题来读:

长任务遇到的问题Codex 中的设计线索白话解释与边界
当前窗口空间有限0.153.0 引入实验性的 token budget、history notes 和 new_context预算帮助运行时感知空间;历史笔记帮助任务续接;new_context 提供切换到新上下文的方式。实验能力默认关闭,适用范围也有限,不是所有用户都会自动获得。
每次都把整段旧对话带回来太笨重0.158.0 将本地线程默认切到分页历史不必一开始把所有历史铺进当前工作区;需要时再读取。它不意味着旧历史被删除,也不意味着模型每次都会自动读完全部历史。
读取历史与实验上下文能力被绑在一起0.158.0 允许历史与笔记在不具备实验性上下文能力的模型上使用history / notes 工具不必依赖模型支持整套实验性上下文能力;这不等于所有历史管理都对所有会话开放。
压缩时重复准备旧模型上下文0.158.0 扩大了 unchanged-model compaction shortcut 的适用范围模型没变、兼容条件也没变时,可以跳过部分重复重建和限制检查;这优化的是流程开销,不是摘要质量。

这些机制的共同点不是“压得更狠”,而是开始分别处理空间预算、信息留存、按需读取、上下文切换和重复开销。换句话说,系统不只要回答“窗口还能装多少”,还要回答“哪些信息现在值得占这个位置”。Codex 0.153.0 更新 · Codex 0.158.0 更新 · 分页历史实现

这些代码变化不能证明上下文工程已经是所有 Agent 的唯一瓶颈,也不意味着 Codex 已经替用户解决了长任务记忆。但它们说明,Agent 产品正在把上下文的预算、存取和交接,当成运行时需要认真设计的部分,而不是只靠用户多写几句 Prompt。

上下文不是 Prompt 的另一个名字

Prompt 通常指你交给模型的指令;上下文则是模型做某一次决策时,实际能利用的整个工作集。它可能包括:

  1. 规则:项目约定、安全边界、输出格式。
  2. 目标:当前要交付什么、哪些事情明确不做、如何验收。
  3. 项目材料:相关代码、文档、配置和已确认的决策。
  4. 任务状态:已经完成什么、验证了什么、还卡在哪里、下一步是什么。
  5. 工具与权限:可以调用什么工具、能做什么操作、有哪些限制。
  6. 新证据:刚检索到的文件、命令输出、接口响应和环境观察。

一个文件即使躺在仓库里,如果 Agent 没读到、没检索到,或没有工具可以访问,它就不属于当前这一步可用的上下文。反过来,工具输出进了窗口,也不代表它天然正确:还要确认来源、时间和含义。

AI Agent 长任务总跑偏?4 个方法做好上下文工程

你让 Agent 修一个线上问题:先读日志,再定位代码、改实现、补测试,最后跑验证。

前几步都很顺。到了后面,它却改了已经确认不能动的接口,重复尝试刚刚失败过的方案,甚至把“先给出诊断,不要直接发布”忘在了几十轮对话之前。

这时我们很容易得出结论:模型还不够聪明,或者上下文窗口还不够大。

但长任务里,真正的问题往往不是 Agent 看过多少信息,而是它在做当前这一步时,能不能拿到正确、最新、可用的信息。模型窗口像一张有限的工作台:重要规则、当前目标、代码片段、工具返回、旧对话都在争位置。把工作台做得更大有帮助,却不会自动把东西摆对。

这就是上下文工程要解决的问题。以 Codex 2026 年 9 月的 0.153.0 和 0.158.0 两次更新为例,可以看到上下文预算、历史记录和压缩流程如何逐步成为运行时要处理的问题。

Codex 的变化,为什么不只是“把对话压短”

先把两个词说清楚:上下文是模型当前这一步实际能看到并利用的信息;compaction(压缩)是在空间紧张时整理出继续工作所需的内容,为后续步骤腾出空间。压缩不是把整段历史无损缩小,更不是删除项目里的文件。

Codex 0.153.0 和 0.158.0 的更新,可以按它们在解决的工程问题来读:

长任务遇到的问题Codex 中的设计线索白话解释与边界
当前窗口空间有限0.153.0 引入实验性的 token budget、history notes 和 new_context预算帮助运行时感知空间;历史笔记帮助任务续接;new_context 提供切换到新上下文的方式。实验能力默认关闭,适用范围也有限,不是所有用户都会自动获得。
每次都把整段旧对话带回来太笨重0.158.0 将本地线程默认切到分页历史不必一开始把所有历史铺进当前工作区;需要时再读取。它不意味着旧历史被删除,也不意味着模型每次都会自动读完全部历史。
读取历史与实验上下文能力被绑在一起0.158.0 允许历史与笔记在不具备实验性上下文能力的模型上使用history / notes 工具不必依赖模型支持整套实验性上下文能力;这不等于所有历史管理都对所有会话开放。
压缩时重复准备旧模型上下文0.158.0 扩大了 unchanged-model compaction shortcut 的适用范围模型没变、兼容条件也没变时,可以跳过部分重复重建和限制检查;这优化的是流程开销,不是摘要质量。

这些机制的共同点不是“压得更狠”,而是开始分别处理空间预算、信息留存、按需读取、上下文切换和重复开销。换句话说,系统不只要回答“窗口还能装多少”,还要回答“哪些信息现在值得占这个位置”。Codex 0.153.0 更新 · Codex 0.158.0 更新 · 分页历史实现

这里要克制一点:这些代码变化不能证明上下文工程已经是所有 Agent 的唯一瓶颈,也不意味着 Codex 已经替用户解决了长任务记忆。但它们说明,Agent 产品正在把上下文的预算、存取和交接,当成运行时需要认真设计的部分,而不是只靠用户多写几句 Prompt。

上下文不是 Prompt 的另一个名字

Prompt 通常指你交给模型的指令;上下文则是模型做某一次决策时,实际能利用的整个工作集。它可能包括:

  1. 规则:项目约定、安全边界、输出格式。
  2. 目标:当前要交付什么、哪些事情明确不做、如何验收。
  3. 项目材料:相关代码、文档、配置和已确认的决策。
  4. 任务状态:已经完成什么、验证了什么、还卡在哪里、下一步是什么。
  5. 工具与权限:可以调用什么工具、能做什么操作、有哪些限制。
  6. 新证据:刚检索到的文件、命令输出、接口响应和环境观察。

一个文件即使躺在仓库里,如果 Agent 没读到、没检索到,或没有工具可以访问,它就不属于当前这一步可用的上下文。反过来,工具输出进了窗口,也不代表它天然正确:还要确认来源、时间和含义。

上下文组成.png

上下文是围绕当前决策组装的工作集,不是越多越好。

所以,上下文工程不是“写一份更长的系统提示词”,也不是“把所有资料塞进超长窗口”。它是在任务的不同阶段,持续决定:什么信息应该进入、什么信息应该留在外部、什么时候更新,以及旧信息如何被纠正或淘汰。

长任务为什么特别容易跑偏?

把 Agent 想成接力队员。每一步都要把棒交给下一步:诊断交给修改,修改交给测试,测试结果再决定是否完成。接力棒没交好,单个队员再快也跑不完全程。

长任务里的“交接失败”通常有三种:

1. 关键约束被噪声淹没

任务跑久了,日志、代码、工具返回和尝试记录不断增加。重要要求——比如“兼容旧接口”“不能触碰生产配置”——可能还在早期对话里,却不在模型当下能有效注意到的位置。

2. 任务状态没有随事实更新

Agent 记得计划,却没带上刚发生的结果;或者新证据推翻了旧判断,旧判断却仍留在上下文里。于是它会重复做已失败的尝试,沿着过期前提继续推理。

3. “信息存在”被误当成“信息可用”

仓库里有规范、历史会话里有结论、工具有权限,但如果当前步骤没有取到正确片段,Agent 仍然像不知道一样。反过来,机械地塞入所有内容,只会让当前工作集更拥挤。

因此,可靠性不只取决于模型能力和窗口大小,也取决于上下文的相关性、新鲜度、可追溯性和可行动性。压缩只是其中一环;如果压缩前没有区分事实、决定和猜测,再好的压缩也可能把关键东西压没。

把上下文当作动态工作集:一套能直接用的方法

下次让 Agent 执行跨多步任务时,可以按下面四步来组织,而不是先把提示词越写越长。

第一步:先写清本次任务卡

把临时目标和长期规则分开。任务卡只写这次工作需要的内容:

目标:修复订单查询超时,不改动对外 API。
范围:检查查询链路、修改实现、补测试;不发布生产环境。
约束:保留旧参数兼容;不得修改数据库结构。
验收:相关测试通过;说明修改文件、验证结果和未解决风险。

目标、范围、约束、验收四项写清,Agent 才知道什么叫“做完”,也知道哪些看似合理的动作不能做。

第二步:按信息寿命放到合适的位置

不要让一个越来越长的 AGENTS.md 同时充当规则手册、百科、任务计划和历史日志。

信息更适合放在哪里
长期有效的项目规则与安全边界项目规则文件
当前任务目标、范围、验收本次任务 Spec / 任务卡
项目知识、历史决策、已验证经验可检索的文档或知识库
可重复的多步操作Skill 或脚本
外部系统操作与权限控制有校验、预览、确认和读回能力的工具

归位的判断标准很简单:这条信息未来会不会长期有效?如果只对这一次任务有效,就不要把它永久塞进常驻规则里。

第三步:先取摘要,再按需展开

先找入口、摘要和最相关的文件;需要接口细节、历史决定或具体代码时,再读取原文或精确片段。命令输出优先保留必要字段,避免整份日志、整个目录都挤进上下文。

每次准备加载一段材料,都问一句:它会影响我眼前这个决策吗? 如果不会,就先留在外部,等需要时再取。

第四步:用状态卡接力,并用验证兜底

长任务每完成一个阶段,都更新一份精简状态:

已确认:超时发生在订单聚合查询;API 参数兼容约束来自接口定义。
已完成:定位调用链;补充查询超时复现测试。
当前判断:瓶颈在重复读取明细,不是连接池配置。
未解决:大订单下的性能边界尚未压测。
下一步:实现批量读取,运行单测与基准测试;不执行发布。
依据:src/order/query.ts;测试输出 2026-10-08 14:20。

只保留下一个阶段会用到的事实、决定、状态和风险。新证据推翻旧判断时,明确替换它;不要让两个互相矛盾的结论并排等待 Agent 猜。

最后,别让上下文代替工程护栏。代码变更要跑测试;外部写操作要有参数校验、最小权限、dry-run、人工确认和读回验证。上下文帮助 Agent 做判断,工具边界负责拦住不该发生的动作。

结语:不要要求 Agent 记住一切

Agent 的长任务像一条持续交接的流水线。窗口再大,也不等于信息自动变得相关;历史再完整,也不等于当前步骤拿到了正确证据。Codex 的相关变化值得关注,是因为它们把预算、历史读取、任务续接和压缩成本拆成了更明确的运行时问题。

所以,Agent 的“胜负手”未必是某个更长的上下文窗口,而是系统能否持续给它一份足够小、足够新、能支撑下一步决策的工作集。

下次遇到长任务,先别急着把 Prompt 加长。先写清目标与边界,按需取资料,再维护一张可信的任务状态卡——让下一步接到的是棒,而不是整段聊天记录。

延伸阅读

所以,上下文工程不是“写一份更长的系统提示词”,也不是“把所有资料塞进超长窗口”。它是在任务的不同阶段,持续决定:什么信息应该进入、什么信息应该留在外部、什么时候更新,以及旧信息如何被纠正或淘汰。