长时间运行智能体的有效管控框架
长时间运行智能体的有效管控框架
发布日期: 2025年11月26日
作者: Justin Young
来源: Anthropic 工程博客
智能体在跨多个上下文窗口工作时仍面临诸多挑战。我们从人类工程师的工作方式中汲取灵感,打造了一套更有效的长时间运行智能体管控框架。
随着 AI 智能体能力不断增强,开发者越来越多地要求它们承担需要数小时甚至数天才能完成的复杂任务。然而,如何让智能体在多个上下文窗口之间持续稳定地推进工作,仍然是一个尚未解决的难题。
长时间运行智能体的核心挑战在于:它们必须在离散的会话中工作,而每个新会话开始时对之前发生的一切一无所知。想象一个软件项目由轮班工程师负责,每位新上岗的工程师对上一班的工作毫无记忆。由于上下文窗口有限,而大多数复杂项目无法在单个窗口内完成,智能体需要一种方式来弥合编码会话之间的断层。
我们开发了一套双管齐下的解决方案,使 Claude Agent SDK 能够在多个上下文窗口间有效工作:一个初始化智能体负责在首次运行时搭建环境,一个编码智能体负责在每次会话中推进增量进展,同时为下一次会话留下清晰的工作记录。你可以在配套的快速入门指南中找到代码示例。
长时间运行智能体的问题
Claude Agent SDK 是一个强大的通用智能体管控框架,擅长编码以及其他需要模型使用工具来收集上下文、规划和执行的任务。它具备上下文管理能力,例如上下文压缩(compaction),使智能体可以在不耗尽上下文窗口的情况下持续工作。理论上,有了这套机制,智能体应该能够在任意长的时间内持续产出有效工作。
但仅有上下文压缩是不够的。开箱即用的情况下,即使是 Opus 4.5 这样的前沿编码模型在 Claude Agent SDK 上跨多个上下文窗口循环运行,仅凭一条高层级的提示(比如"构建一个 claude.ai 的克隆版"),也无法构建出一个生产级别的 Web 应用。
Claude 的失败表现为两种模式。
**第一种,智能体倾向于一次性做太多事情——本质上是试图一步到位完成整个应用。**这往往导致模型在实现过程中耗尽上下文,留下一个功能只完成了一半且没有文档记录的状态。下一个会话的智能体不得不猜测之前发生了什么,并花费大量时间试图让基础应用重新运行起来。即使使用了上下文压缩,这种情况依然会发生,因为压缩后传递给下一个智能体的指令并不总是足够清晰。
**第二种失败模式通常出现在项目后期。**当一些功能已经构建完成后,后续的智能体实例会环顾四周,看到已有一些进展,便宣布任务完成。
这将问题分解为两个部分。
首先,我们需要搭建一个初始环境,为给定提示所要求的所有功能奠定基础,引导智能体逐步、逐个功能地推进工作。
其次,我们应该提示每个智能体朝着目标做出增量进展,同时在会话结束时将环境保持在一个干净的状态。所谓"干净状态",指的是可以合并到主分支的代码质量:没有重大 bug,代码井然有序且有良好的文档说明,总体而言,开发者可以轻松开始一个新功能的开发,而无需先清理无关的烂摊子。
在内部实验中,我们用一套两阶段方案解决了这些问题:
初始化智能体: 第一个智能体会话使用专门的提示,要求模型搭建初始环境:一个
init.sh脚本、一个claude-progress.txt文件用于记录智能体的工作日志,以及一个初始 git 提交来展示新增了哪些文件。编码智能体: 后续每个会话都要求模型推进增量进展,然后留下结构化的更新记录。
这里的关键洞察是找到一种方式,让智能体在以全新上下文窗口启动时能快速了解工作状态——这通过 claude-progress.txt 文件配合 git 历史记录来实现。这些实践的灵感来自于对高效软件工程师日常工作方式的观察。^1
环境管理
在更新版的 Claude 4 提示指南中,我们分享了一些多上下文窗口工作流的最佳实践,包括一种管控框架结构,其中"第一个上下文窗口使用不同的提示"。这个"不同的提示"要求初始化智能体搭建好环境,提供未来编码智能体高效工作所需的全部上下文。以下我们将深入探讨这种环境的几个关键组成部分。
功能清单
为了解决智能体一步到位构建应用或过早宣布项目完成的问题,我们提示初始化智能体编写一份全面的功能需求文件,对用户的初始提示进行扩展。以 claude.ai 克隆为例,这意味着超过 200 个功能点,例如"用户可以打开新对话,输入问题,按回车,看到 AI 回复"。这些功能最初全部标记为"未通过",这样后续的编码智能体就能清楚地知道完整功能应该是什么样的。
{
"category": "functional",
"description": "New chat button creates a fresh conversation",
"steps": [
"Navigate to main interface",
"Click the 'New Chat' button",
"Verify a new conversation is created",
"Check that chat area shows welcome state",
"Verify conversation appears in sidebar"
],
"passes": false
}
我们提示编码智能体只能通过更改 passes 字段的状态来编辑这个文件,并使用措辞强硬的指令,例如"删除或编辑测试用例是不可接受的行为,因为这可能导致功能缺失或出现 bug"。经过多次实验,我们最终选择了 JSON 格式,因为模型不太可能不当地修改或覆盖 JSON 文件,相比 Markdown 文件更安全。
增量推进
有了初始环境的脚手架后,下一轮编码智能体被要求一次只处理一个功能。这种增量推进的方式对于解决智能体一次做太多事情的倾向至关重要。
在增量工作的基础上,模型在完成代码变更后将环境保持在干净状态同样至关重要。在实验中,我们发现引导这种行为的最佳方式是:要求模型将进展提交到 git 并附上描述性的提交信息,同时在进度文件中写入工作总结。这使得模型可以利用 git 回退糟糕的代码变更,恢复到代码库的可用状态。
这些方法也提高了效率,因为它们消除了智能体猜测之前发生了什么、花时间让基础应用重新运行起来的需要。
测试
我们观察到的最后一个主要失败模式是 Claude 倾向于在没有充分测试的情况下将功能标记为完成。在没有明确提示的情况下,Claude 往往会做代码变更,甚至用单元测试或对开发服务器执行 curl 命令来测试,但无法识别功能在端到端层面并不正常工作。
在构建 Web 应用的场景中,一旦被明确提示使用浏览器自动化工具、像人类用户一样进行所有测试,Claude 在端到端功能验证方面表现就好了很多。
Claude 通过 Puppeteer MCP 服务器截取的屏幕截图,展示了它测试 claude.ai 克隆的过程。
为 Claude 提供这类测试工具极大地提升了表现,因为智能体能够识别并修复仅从代码层面看不出来的 bug。
仍然存在一些问题,比如 Claude 的视觉能力和浏览器自动化工具的局限性,使得识别每一种 bug 都很困难。例如,Claude 无法通过 Puppeteer MCP 看到浏览器原生的 alert 弹窗,依赖这些弹窗的功能往往 bug 更多。
快速进入状态
以上所有机制就位后,每个编码智能体都会被提示执行一系列步骤来了解当前状况——其中一些相当基础,但仍然很有帮助:
- 运行
pwd查看当前工作目录。你只能编辑该目录下的文件。 - 阅读 git 日志和进度文件,了解近期的工作内容。
- 阅读功能清单文件,选择优先级最高且尚未完成的功能开始工作。
这种方式为 Claude 在每次会话中节省了一些 token,因为它不必自行摸索如何测试代码。同样有帮助的是,让初始化智能体编写一个 init.sh 脚本来启动开发服务器,然后在实现新功能之前先执行一个基本的端到端测试。
以 claude.ai 克隆为例,这意味着智能体每次都会先启动本地开发服务器,并使用 Puppeteer MCP 发起一次新对话、发送一条消息并接收回复。这确保了 Claude 能够快速发现应用是否处于损坏状态,并立即修复已有的 bug。如果智能体直接开始实现新功能,很可能会让问题更加严重。
基于以上设计,一个典型会话的开头看起来如下:
[助手] 我先来了解一下当前状况和项目的进展。
[工具调用] <bash - pwd>
[工具调用] <read - claude-progress.txt>
[工具调用] <read - feature_list.json>
[助手] 让我查看一下 git 日志,了解最近的工作。
[工具调用] <bash - git log --oneline -20>
[助手] 现在让我检查是否有 init.sh 脚本来重启服务。
<启动开发服务器>
[助手] 很好!现在让我访问应用,验证一些基础功能是否仍然正常运行。
<测试基础功能>
[助手] 根据验证测试的结果,基础功能运行良好。核心聊天功能、主题切换、对话加载和错误处理都工作正常。现在让我更全面地查看 tests.json 文件,了解接下来需要实现哪些功能。
<开始处理新功能>
智能体失败模式与解决方案
| 问题 | 初始化智能体的行为 | 编码智能体的行为 |
|---|---|---|
| Claude 过早宣布整个项目完成 | 搭建功能清单文件:根据输入规范,创建一个结构化的 JSON 文件,列出端到端的功能描述。 | 在会话开始时阅读功能清单文件,选择一个功能开始工作。 |
| Claude 留下有 bug 或进展未记录的环境状态 | 创建初始 git 仓库和进度记录文件。 | 在会话开始时阅读进度记录文件和 git 提交日志,对开发服务器运行基本测试以发现未记录的 bug。在会话结束时编写 git 提交和进度更新。 |
| Claude 过早将功能标记为完成 | 搭建功能清单文件。 | 自行验证所有功能。只有在仔细测试后才将功能标记为"通过"。 |
| Claude 需要花时间摸索如何运行应用 | 编写一个 init.sh 脚本来启动开发服务器。 |
在会话开始时阅读 init.sh。 |
总结长时间运行 AI 智能体的四种常见失败模式及解决方案。
未来工作
本研究展示了一套长时间运行智能体管控框架中的可行解决方案,使模型能够在多个上下文窗口间实现增量推进。然而,仍有一些开放性问题。
最值得关注的是,目前尚不清楚单一的通用编码智能体在跨上下文场景中是否表现最优,还是说通过多智能体架构可以获得更好的性能。专门化的智能体——例如测试智能体、质量保障智能体或代码整理智能体——似乎有可能在软件开发生命周期的各个子任务中做得更好。
此外,本次演示针对全栈 Web 应用开发进行了优化。未来的一个方向是将这些发现推广到其他领域。这些经验教训很可能部分或全部适用于其他需要长时间运行的智能体任务,例如科学研究或金融建模。
致谢
撰文:Justin Young。特别感谢 David Hershey、Prithvi Rajasakeran、Jeremy Hadfield、Naia Bouscal、Michael Tingley、Jesse Mu、Jake Eaton、Marius Buleandara、Maggie Vo、Pedram Navid、Nadine Yasser 和 Alex Notov 的贡献。
这项工作凝聚了 Anthropic 多个团队的集体努力,他们使 Claude 能够安全地执行长周期的自主软件工程任务——尤其是代码强化学习团队和 Claude Code 团队。
If you read this far — thank you.
Come tell me what you thought on X.