你想让 AI Agent 帮你从零开始构建一个完整的Web应用,你把需求告诉它:“帮我做一个聊天应用,能取代Facebook的那种”。
Agent开始工作了,它阅读需求、编写代码、创建文件,一切看起来很顺利。几个小时后,你打开项目一看,情况可能不太妙——到处都是半成品,部分代码逻辑甚至互相冲突。
这说明你遇到了一个根本性问题:Agent会失忆。
失忆的Agent
要理解这个问题,首先得弄清楚Agent的工作机制。
每个AI Agent都有一个“上下文窗口”,你可以把它想象成一块白板。Agent在这块白板上阅读需求、编写代码、进行推理。但这块白板的面积是有限的,一旦写满,Agent就必须擦掉一些内容才能继续。
更严重的是,当一次会话结束、下一次会话开始时,Agent面对的是一块全新的空白白板。它完全不记得之前写了什么代码、做了哪些决策或遇到了什么问题。
这就像一个实行轮班制的研发团队,但每一班新来的工程师完全不知道上一班做了什么。新成员只能到处翻看代码,努力猜测前一班的意图,然后凭感觉继续开发。
除了失忆,Agent通常还有两种典型的失败模式:
- 贪多求全。Agent一开始就想写完整套应用,比如“一口吃下Facebook”。结果功能还没完成,上下文窗口就用尽了。下一个接手的Agent看到的是一堆半成品——界面写了一半,后端接了一半,到处是TODO注释。它无从分辨哪些已完成、哪些待完善,只能硬着头皮猜测,花费大量时间去修补“烂摊子”。
- 过早宣布胜利。项目进行到后期,Agent浏览了一下现有代码,发现已经有不少功能模块,于是自信地宣布:“项目完成了!”但实际上,还有一大堆核心功能压根没做。
你会发现,问题不在于Agent能力不足,而在于其工作方式本身存在缺陷。
给白板拍张照
既然Agent每次会话都从空白开始,那么有没有办法在擦掉白板之前,先把关键信息保存下来?
Agent运行的环境里,有一个东西是持久化的:文件系统。代码文件、配置文件乃至Git历史记录都储存在那里。Agent的白板会被擦除,但这些文件不会。
一个有效的办法是:让Agent在每次会话结束前,将已完成的工作、当前进度以及下一步计划,记录到一个专门的进度文件中。
# progress.txt
## 已完成
- 搭建了项目脚手架(React + Express)
- 完成了用户登录功能
- 完成了聊天界面的基础布局
## 当前状态
- 正在开发消息发送功能,已完成前端部分,后端API待实现
## 已知问题
- 登录页面在移动端有样式错位
## 下一步
- 完成消息发送的后端API
- 对接WebSocket实现实时推送
同时,引导Agent将每次代码改动提交到Git,并编写清晰的提交信息。
这样,新来的Agent接手时,就不再是盲目摸索,而是遵循一套明确的流程:
- 打开
progress.txt,了解上一轮的工作进展。
- 查看
git log,掌握近期的代码变更历史。
- 在明确当前状况后,从断点处继续开发。
这相当于在轮班制中引入了交接记录本,每个人下班前必须做好记录,接班人上班后先阅读记录再开始工作。
经过测试,这种方法效果显著。Agent不再需要花费大量时间猜测项目历史,它能快速了解当前状态,并从上次停止的地方无缝衔接。
Agent失忆导致效率低下的问题,初步得到了解决。
然而,新的问题又浮现出来。
渐进式完成任务
进度文件解决了“失忆”问题,但没有根治“贪多”的毛病。
仔细想想,问题的根源是什么?Agent不知道“完成”的具体标准是什么。你给它一个模糊的宏大目标——“做一个聊天应用”,它只能自行脑补需要哪些功能,以及做到何种程度才算完成。
因此,我们需要一份明确的、细粒度的功能清单,将大目标拆解为一个个可独立验证的小功能点:
{
“description“: “用户点击新建聊天按钮,创建一个空白对话“,
“steps“: [
“打开应用主界面“,
“点击新建聊天按钮“,
“验证新对话被创建“,
“验证聊天区域显示欢迎页面“,
“验证侧边栏出现新对话“
],
“passes“: false
}
对于一个完整的聊天应用,这样的功能点可能有数百个。每个功能点都包含明确的验收步骤和状态标记(passes: false 表示未完成)。
有了这份清单,给Agent的指令也变得非常具体:“从功能清单里找到优先级最高且未完成的功能,只实现这一个。”
Agent每次只专注完成一个功能。完成后,提交代码、更新进度文件,并将功能清单中对应条目的状态标记为 passes: true,然后结束本轮会话。
下一轮Agent启动时,它会先查看进度文件和功能清单,找到下一个待办项,继续开发。
此前Agent贪多求全、过早宣布胜利的问题,通过这种方法也得到了有效解决——只要清单里还有一堆 passes: false,项目就谈不上真正完成。
必须自测
你可能会遇到这种情况:Agent完成一个功能后,自信地将清单状态改为了 passes: true,但你实际测试时却发现根本不能用。按钮点击没反应,消息发送后页面空白。Agent只是“写完”了代码,却从未真正运行验证过。
这就像一个程序员声称代码写完了,但从未编译运行过一样。
问题出在哪里?Agent可能运行了单元测试,或者用curl命令调用了API,但它从未像真实用户那样在浏览器中进行端到端的完整操作。
解决方案是,为Agent配备浏览器自动化工具,让它能够模拟真实用户的操作:打开浏览器、访问应用、点击按钮、输入文字、检查页面渲染是否正确。
并且要设定一条铁律:每次开始新功能开发前,必须先运行一遍已有基础功能的端到端测试。坚持“先测试,后开发”的原则,发现问题优先修复,确保地基稳固后再向上建设。
一轮标准的、高效的Agent工作流程应该如下:
1. 打开进度文件,了解项目当前状态
2. 查看git记录,了解最近的改动
3. 启动开发服务器
4. 用浏览器跑一遍基础功能测试
如果有bug,先修bug
如果一切正常,继续
5. 从功能清单中选择下一个待完成的功能
6. 实现这个功能
7. 用浏览器端到端验证
8. 提交代码,更新进度文件
这套用于引导和约束AI Agent工作的外围系统,正是所谓的 Agent Harness。它通过进度跟踪、任务分解和自动化测试,将原本容易中断、出错的Agent任务,转变为稳定、连续的工程化流程。
如果你想了解更多关于自动化工程实践或AI开发的深入讨论,欢迎在云栈社区与更多开发者交流心得。