all posts
AI技术 · ZH

如何让 AI 智能体持续工作数小时而不掉链子

May 8, 2026·10 min read·by PandaTalk

如何让 AI 智能体持续工作数小时而不掉链子

原文:Effective Harnesses for Long-Running Agents,Anthropic 工程博客,2025年11月


想象一个场景:你让 AI 智能体帮你从零搭建一个完整的 Web 应用。它兴冲冲地干了起来,写了一堆代码,然后上下文窗口用完了。新的会话开始,智能体一脸茫然——它完全不记得之前做了什么。面对一堆半成品代码,它只能连蒙带猜,花大量时间试图理解现状,甚至把已经能跑的功能搞坏了。

这就是长时间运行的 AI 智能体面临的核心难题。

Anthropic 团队在实践中找到了一套方法来解决这个问题。他们的灵感来源很朴素:看看优秀的人类工程师每天是怎么交接工作的。

智能体为什么会"掉链子"

AI 智能体的上下文窗口是有限的。虽然有"压缩"(compaction)技术可以让智能体在单次会话中处理更多内容,但对于需要数小时甚至数天才能完成的复杂项目,智能体不得不在多个会话之间切换工作——而每次新会话都是一张白纸。

这就像一个软件团队采用轮班制,但每个新来的工程师对前一班次发生的事情毫无记忆。

Anthropic 团队用 Claude 尝试构建一个 claude.ai 的克隆应用时,观察到了两种典型的失败模式:

失败模式一:贪多嚼不烂。 智能体试图一口气完成所有功能,结果上下文耗尽时只完成了一半,代码既不完整也没有文档。下一个会话的智能体接手后,只能靠猜来理解半成品,然后花大量时间救火。

失败模式二:过早宣布胜利。 当项目已经有了一些功能后,新会话的智能体环顾四周,觉得看起来做得差不多了,于是直接宣布任务完成——尽管还有大量功能没实现。

解决方案:两阶段智能体架构

Anthropic 的方案借鉴了工程团队的交接实践,把长期运行拆分为两个角色:

1. 初始化智能体(Initializer Agent)

仅在项目启动的第一次会话运行,负责搭建环境脚手架:

  • 创建 init.sh 启动脚本——后续智能体可以一键启动开发服务器
  • 创建 claude-progress.txt 进度文件——充当"交接班日志",记录每个会话完成了什么
  • 初始化 Git 仓库——提交初始代码,建立版本控制基线
  • 生成功能需求清单——这是最关键的一步,下面详细讲

2. 编码智能体(Coding Agent)

后续每个会话都使用这个角色,遵循严格的工作流:

  1. 先搞清楚现状(读进度文件、git 日志)
  2. 每次只做一个功能
  3. 做完就提交代码、更新进度
  4. 确保代码库始终处于可合并状态

这两个角色其实用的是同一个模型、同一套工具,唯一的区别只是初始提示词不同。^1

关键设计细节

功能需求清单:防止智能体"跑偏"

初始化智能体会根据用户的高层需求,展开为一份详细的功能清单(在 claude.ai 克隆项目中,这份清单包含超过 200 个功能点)。每个功能用 JSON 格式描述,初始状态全部标记为"未通过":

{
    "category": "functional",
    "description": "点击新建对话按钮可以创建一个新的聊天",
    "steps": [
      "导航到主界面",
      "点击'新建对话'按钮",
      "验证新对话已创建",
      "检查聊天区域显示欢迎状态",
      "验证对话出现在侧边栏"
    ],
    "passes": false
}

为什么用 JSON 而不是 Markdown?因为实验发现,智能体更不容易随意修改或覆盖 JSON 文件。编码智能体被要求只能修改 passes 字段,提示词中还加了强硬的约束:"删除或编辑测试用例是不可接受的,因为这会导致功能缺失或出 bug。"

这份清单就像一个不容篡改的项目看板,让智能体始终清楚"全貌是什么,我做到哪了"。

增量推进:一次只做一件事

有了功能清单后,编码智能体被要求每次只处理一个功能。这种增量式的工作方式是解决"贪多嚼不烂"问题的关键。

每完成一个功能,智能体必须:

  • 用描述性的 commit message 提交代码到 Git
  • 在进度文件中写入本次会话的摘要

这不仅让下一个会话能快速了解现状,还让智能体可以用 git revert 回退有问题的代码变更,恢复到正常状态。

端到端测试:别让智能体自己骗自己

另一个常见问题是智能体"自我欺骗"——它改了代码,跑了个单元测试或者 curl 了一下接口,就认为功能完成了。但实际上,从用户视角来看,功能可能根本不能用。

解决方法是明确要求智能体使用浏览器自动化工具(如 Puppeteer MCP)进行端到端测试,像真实用户一样操作页面验证功能。

这种测试方式大幅提升了质量——智能体能发现很多光看代码发现不了的 bug。当然也有局限,比如 Claude 无法通过 Puppeteer 看到浏览器原生的 alert 弹窗,依赖这类弹窗的功能就容易出问题。

一个典型会话长什么样

每个编码智能体启动后,会按照以下流程热身:

[智能体] 我先了解一下项目现状。
[工具调用] <bash - pwd>
[工具调用] <读取 - claude-progress.txt>
[工具调用] <读取 - feature_list.json>

[智能体] 让我看看最近的 git 日志。
[工具调用] <bash - git log --oneline -20>

[智能体] 启动开发服务器。
<运行 init.sh>

[智能体] 先验证一下基础功能是否正常。
<用 Puppeteer 打开页面,发送一条消息,确认收到回复>

[智能体] 基础功能正常。现在看看下一个要实现的功能是什么。
<开始实现新功能>

注意这里的顺序:先确认已有功能没坏,再开始做新的。如果跳过这一步直接写新代码,很可能在一个已经坏掉的基础上越堆越乱。

四种失败模式和对策

问题 初始化智能体的应对 编码智能体的应对
过早宣布项目完成 生成完整的 JSON 功能需求清单 每次开始先读功能清单,选一个未完成的功能来做
遗留 bug 或未记录的进度 初始化 Git 仓库和进度日志文件 开始时读日志和 git 记录,先跑一遍基础测试;结束时提交代码并更新日志
未充分测试就标记功能完成 生成功能清单(含测试步骤) 只有经过端到端测试验证后,才能把功能标为"通过"
花大量时间搞清楚如何启动项目 编写 init.sh 启动脚本 开始时直接读取并运行 init.sh

仍待探索的方向

这套方案验证了一种可行的思路,但还有一些开放性问题:

单智能体 vs 多智能体架构。 目前的方案用的是同一个通用智能体。如果引入专门的测试智能体、代码审查智能体、清理智能体,各司其职,效果会不会更好?

从 Web 开发推广到其他领域。 目前的实验集中在全栈 Web 应用开发上。但这些"增量推进、记录进度、端到端验证"的原则,很可能同样适用于科学研究、金融建模等其他需要长时间运行的智能体场景。

核心启示

这篇文章的底层洞察其实很简单:让 AI 智能体像优秀的人类工程师一样工作

优秀的工程师不会在交接班时把半成品代码丢给下一个人,他们会提交干净的代码、写好文档、更新任务状态。同样的道理,长时间运行的 AI 智能体也需要这套"交接班纪律":

  • 明确的任务清单(知道全貌)
  • 增量式工作(一次一个功能)
  • 版本控制和进度记录(让下一个会话能接上)
  • 端到端测试(确认功能真的能用)

这些都不是什么黑科技,却是让 AI 智能体从"演示级别"走向"生产级别"的关键。


━━━ fin ━━━

If you read this far — thank you.
Come tell me what you thought on X.