当 AI 智能体需要连续工作数小时甚至数天,如何在一次次“失忆”的会话之间保持进展?Anthropic 从人类工程师的轮班协作中找到了答案。
随着 AI 智能体能力提升,开发者越来越多地要求它们承担跨越数小时乃至数天的复杂任务。但一个根本性难题始终存在:智能体必须在离散的会话中工作,而每个新会话开始时,对之前发生的事情没有任何记忆。
Anthropic 在 2025 年 11 月 26 日发布的一篇工程博客中,分享了他们为长时间运行智能体构建高效运行框架的实践。核心思路借鉴自人类工程师的日常工作方式——通过初始化智能体搭建环境,编码智能体在每个会话中取得增量进展,并为下一个会话留下清晰产物。
Claude Agent SDK 是一个强大、通用的智能体运行框架,擅长编码以及需要模型使用工具来收集上下文、规划和执行的其他任务。它具备上下文管理能力,例如压缩(compaction),使智能体在处理任务时不至于耗尽上下文窗口。理论上,在这种设置下,智能体应该能够持续进行有用的工作任意长的时间。
然而,压缩并不足够。开箱即用的情况下,即使是像 Opus 4.5 这样的前沿编码模型,在 Claude Agent SDK 上跨多个上下文窗口循环运行,如果只给定一个高层级的提示词——例如“构建一个 claude.ai 的克隆”——也无法构建出生产质量的 Web 应用。
Anthropic 观察到 Claude 的失败表现为两种模式:
第一种失败模式:一次做太多事情。 智能体倾向于试图一次性完成整个应用。这通常导致模型在实现过程中耗尽上下文,使下一个会话开始时某个功能只实现了一半且没有文档记录。智能体随后不得不猜测发生了什么,并花费大量时间试图让基本应用重新运行起来。即使有压缩也会发生这种情况,因为压缩并不总能将完全清晰的指令传递给下一个智能体。
第二种失败模式:过早宣布任务完成。 这种模式通常在项目后期出现。在已经构建了一些功能之后,后续的智能体实例会环顾四周,看到已经取得了进展,然后宣布任务完成。
Anthropic 将问题分解为两个部分:首先,搭建一个初始环境,为给定提示词所需的所有功能奠定基础,使智能体能够逐步、逐个功能地工作;其次,提示每个智能体朝着目标取得增量进展,同时在会话结束时将环境保持在干净的状态。
所谓“干净的状态”,指的是适合合并到主分支的代码:没有重大 bug,代码有序且文档完善,开发者可以轻松地开始新功能的开发,而无需先清理不相关的混乱。
在内部实验中,他们使用了一个由两部分组成的解决方案:
init.sh 脚本、一个记录智能体已完成工作的 claude-progress.txt 文件,以及一个显示添加了哪些文件的初始 git 提交。这里的关键洞察是找到一种方法,让智能体在从全新的上下文窗口开始时能够快速理解工作状态,这通过 claude-progress.txt 文件配合 git 历史来实现。这些实践的灵感来源于了解高效软件工程师每天的工作方式。
为了解决智能体一次性完成整个应用或过早认为项目完成的问题,Anthropic 提示初始化智能体编写一份全面的功能需求文件,扩展用户的初始提示词。在 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。”经过一些实验,Anthropic 最终选择使用 JSON 来实现这一点,因为与 Markdown 文件相比,模型不太可能不适当地更改或覆盖 JSON 文件。
有了初始环境脚手架,编码智能体的下一次迭代被要求一次只处理一个功能。这种增量方法对于解决智能体倾向于一次做太多事情的问题至关重要。
在增量工作之后,模型在做出代码更改后保持环境处于干净状态仍然至关重要。在实验中,Anthropic 发现引发这种行为的最佳方式是要求模型用描述性的提交信息将其进展提交到 git,并在进展文件中写入进展摘要。这允许模型使用 git 来还原错误的代码更改并恢复代码库的工作状态。
这些方法还提高了效率,因为它们消除了智能体需要猜测发生了什么并花费时间试图让基本应用重新运行的需要。
Anthropic 观察到的最后一个主要失败模式是 Claude 倾向于在没有适当测试的情况下将功能标记为完成。在没有明确提示的情况下,Claude 倾向于进行代码更改,甚至使用单元测试或针对开发服务器的 curl 命令进行测试,但无法识别该功能并未端到端正常工作。
在构建 Web 应用的情况下,一旦明确提示使用浏览器自动化工具并像人类用户一样进行所有测试,Claude 在端到端验证功能方面大多表现良好。
配图建议:可插入一张展示智能体通过浏览器自动化工具进行端到端测试的示意图或流程图。
为 Claude 提供这类测试工具显著提升了性能,因为智能体能够识别并修复仅从代码中不明显的错误。
不过,一些问题仍然存在。例如,Claude 的视觉能力和浏览器自动化工具的限制使得难以识别每一种错误。Anthropic 举例说,Claude 无法通过 Puppeteer MCP 看到浏览器原生的警告模态框,依赖这些模态框的功能因此往往更容易出现错误。
有了上述所有设置,每个编码智能体都会被提示执行一系列步骤来了解情况,其中一些相当基础但仍然有帮助:
pwd 查看你正在工作的目录。你只能编辑此目录中的文件。这种方法在每个会话中为 Claude 节省了一些 token,因为它不必弄清楚如何测试代码。它还有助于要求初始化智能体编写一个 init.sh 脚本,该脚本可以运行开发服务器,然后在实现新功能之前运行基本的端到端测试。
在 claude.ai 克隆的情况下,这意味着智能体总是启动本地开发服务器,并使用 Puppeteer MCP 启动新聊天、发送消息并接收响应。这确保了 Claude 能够快速识别应用是否处于损坏状态,并立即修复任何现有错误。如果智能体转而开始实现新功能,很可能会使问题变得更糟。
一个典型的会话以以下助手消息开始:
[Assistant] I'll start by getting my bearings and understanding the current state of the project.
[Tool Use] <bash - pwd>
[Tool Use] <read - claude-progress.txt>
[Tool Use] <read - feature_list.json>
[Assistant] Let me check the git log to see recent work.
[Tool Use] <bash - git log --oneline -20>
[Assistant] Now let me check if there's an init.sh script to restart the servers.
<Starts the development server>
[Assistant] Excellent! Now let me navigate to the application and verify that some fundamental features are still working.
<Tests basic functionality>
[Assistant] Based on my verification testing, I can see that the fundamental functionality is working well. The core chat features, theme switching, conversation loading, and error handling are all functioning correctly. Now let me review the tests.json file more comprehensively to understand what needs to be implemented next.
<Starts work on a new feature>
| 问题 | 初始化智能体行为 | 编码智能体行为 |
|---|---|---|
| Claude 过早宣布整个项目胜利。 | 设置功能列表文件:根据输入规范,设置一个结构化的 JSON 文件,包含端到端功能描述列表。 | 在会话开始时阅读功能列表文件。选择单个功能开始处理。 |
| Claude 使环境处于存在错误或未记录进度的状态。 | 写入初始 git 仓库和进度笔记文件。 | 通过阅读进度笔记文件和 git 提交日志开始会话,并在开发服务器上运行基本测试以捕获任何未记录的错误。通过写入 git 提交和进度更新结束会话。 |
| Claude 过早将功能标记为完成。 | 设置功能列表文件。 | 自我验证所有功能。只有在仔细测试后才将功能标记为“通过”。 |
| Claude 必须花时间弄清楚如何运行应用。 | 编写一个可以运行开发服务器的 init.sh 脚本。 |
通过阅读 init.sh 开始会话。 |
这项研究展示了一组长时运行智能体框架中可能的解决方案,使模型能够在多个上下文窗口中逐步推进。然而,仍有一些开放性问题。
最值得注意的是,目前尚不清楚是单个通用编码智能体在不同场景下表现最佳,还是通过多智能体架构可以获得更好的性能。像测试智能体、质量保证智能体或代码清理智能体这样的专用智能体,似乎有可能在软件开发生命周期的各个子任务中表现得更好。
此外,这个演示是针对全栈 Web 应用开发优化的。未来的一个方向是将这些发现推广到其他领域。这些经验中的部分或全部很可能可以应用于其他类型的长时运行智能体任务,例如科学研究或金融建模。
Anthropic 的这套框架揭示了一个朴素但重要的洞察:让智能体长时间工作的关键,不在于让单次会话变得更强,而在于让会话之间的“交接”变得可靠。通过初始化智能体搭建环境、功能列表明确目标、增量进展控制节奏、git 与进度文件保留状态、端到端测试确保质量,智能体得以在一次次“失忆”中依然保持方向感。
这套方法目前针对全栈 Web 应用开发优化,但其核心思路——用结构化产物弥合上下文鸿沟——很可能适用于更广泛的长时运行智能体场景。对于正在构建智能体应用的开发者而言,这提供了一份可借鉴的工程实践参考。
本文基于 Anthropic 工程博客《Effective harnesses for long-running agents》编译整理,原文发布于 2025 年 11 月 26 日。作者:Justin Young。
生成标记:本文由 ITPUB 文章生成平台基于已选素材整理生成。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69965512/viewspace-3182721/ ,如需转载,请注明出处,否则将追究法律责任。