Agent 显示成功,任务为何没完成
一个自动写作流水线重复生成已发布文章,入库被唯一约束拒绝后仍将运行标记为成功。案例揭示 Agent 的运行状态与业务结果可能脱节,已有历史记录也未必能阻止重复执行。
AI 深度解读
AI Agent 能把文章写完,却不代表它把任务办成了。作者的一条自动写作流水线生成了约 1100 词的文章,提交时因内容重复被 API 拒绝,最后竟然还报告成功。直到几小时后,作者发现没有新稿,才知道出了问题。
这次故障暴露的缺口,不是模型忘了某句话,而是系统没有一份可靠的工作记录:做过什么、还有什么待办、各自处于什么状态。作者给出的办法,是把这些信息组织起来,让 Agent 每次开工前主动读取。思路值得借鉴,但它并不能包治自动化故障。
为什么有记忆,任务还是会丢
作者的流水线每周运行两次,使用本地模型,草稿进入仪表盘之前没有人工介入。出问题的那个周二,它选题、写作、质量检查都走完了,却在保存草稿时撞上重复 slug:同一篇文章五天前就已发布。
最终挡住重复内容的,是作者几个月前出于其他原因设置的数据库列唯一约束。
流水线并非完全没有历史记录。代码里有一份人工维护的已覆盖主题清单,只是过期了。每发一篇文章,作者都得记着更新它。委托已经交给机器,维护状态的责任却还留在人脑里。
作者因此区分了三个问题:
- 记忆回答「以前作过什么决定」,例如为什么选某个数据库。
- 工作记录回答「项目里有哪些工作,它们在哪里,处于什么状态」。
- 实时会话感知回答「此刻有哪些 Agent 正在做事」,用于减少多个会话之间的冲突。
三者有关联,却不能互相替代。检索再聪明,也无法查到从未记录过的发布结果;知道哪个 Agent 正在运行,也不等于知道它昨天有没有把草稿保存成功。
任务完成的证据,需要由工作流程留下。
用四层结构,让待办有地方可查
作者提出的结构从外到内分四层:project、space、item、task。
project 划定项目边界,可以对应一个产品、一个仓库或一项范围明确的工作。Agent 在每台机器上通过 memory_link_project 绑定当前目录,再用 memory_current_project 确认归属,避免查询时混入其他项目的信息。
space 是项目里的主题目录,例如 API、Frontend、Infra、Decisions。作者建议保持宽泛,不要每个功能都建一个。目录过细,维护和检索都会重新变得困难。
item 保存事实与决策。例如「因为访问模式是关系型的,所以选 Postgres 而非 DynamoDB」。这些记录带标签、可搜索,并关联它们描述的文件。作者强调,价值首先来自写下了什么,而非检索算法有多聪明。
task 则描述尚未完成的工作,包含负责人、优先级、截止日期,以及从 pending 到 in progress 再到 resolved 的状态。它补上的,是记忆系统通常缺少的未来部分。
下面这组接口展示了任务从创建到结束的操作路径,原文中的箭头说明是接口示意,并非可直接执行的脚本:
tasks_create → with title, priority, due date
tasks_list → pending, sorted by due date
tasks_what_next → "what should I pick up?"
tasks_start / tasks_resolve
重点看最后一行:有了 tasks_create,还得有人调用 tasks_start 和 tasks_resolve。只创建、不更新,留下的仍是一份会过期的清单。
让 Agent 开工前读取,比多一个看板更关键
作者认为,结构是否有用,取决于 Agent 会不会主动查。
他的 CLAUDE.md 要求每次会话开始时并行完成五件事:查询项目记忆、读取最近几次提交、列出进行中的任务、按截止日期列出待办,以及检查其他会话是否已在这个项目中工作。完成后先汇报发现,再回答用户的问题,逾期事项优先提醒。
据作者描述,这一步约需两秒,让他不再需要每天先解释「我们做到哪了」。这是个人使用反馈,原文没有给出跨团队测试或效率对照。
作者通过 MCP 把这些能力交给 Agent,配置命令如下:
claude mcp add contextforge -s user \
-e CONTEXTFORGE_API_KEY=your-api-key-here \
-- npx -y contextforge-mcp
注意第二行的 CONTEXTFORGE_API_KEY,需要替换为实际密钥。之后执行 npx contextforge-mcp init,将会话启动规则写入 CLAUDE.md。添加工具与要求 Agent 使用工具,是两个步骤。
这里真正有价值的设计,是把查询变成固定工作动作。作者据此主张结构必须放在 MCP 后面,但这个判断有些绝对:项目管理工具如果也能被 Agent 读取,并纳入启动流程,同样可能达到目的。原文没有提供两种方案的对照。
我的判断
我认可作者把记忆、任务状态和实时会话分开处理。它能帮助团队判断,问题究竟是信息没写下来、状态没更新,还是多个 Agent 同时动了同一份工作。
不过,这次事故至少还暴露了另一处独立缺陷:API 已经拒绝保存,流水线却仍然报告成功。补充任务记录可以帮助提前避开重复选题,但不能替代对提交结果的检查。
能查到待办,不等于能证明任务已经成功。
原文也没有展示改造后的流水线如何自动登记文章、如何在写作前检查历史记录,以及是否验证过同类故障不再发生。因此,「四层结构能够避免这次事故」仍有前提,不能当成已经完成验证的结论。
作者承认的局限也很实在:Agent 经常少写记录;任务会过期;系统虽能在相关代码变化时标记记忆,却不会监控任务清单的新鲜度。没有及时更新的条目,无法可靠区分「尚未开始」和「已经做完但忘了关闭」。这套结构也不会替人理解没有读过的代码。
对于只有少量待办的项目,现有 issue 列表加上一段启动查询规则,可能已经够用。是否需要额外引入 ContextForge,应看维护成本和现有工具的可接入程度。原文提供的是作者的实践经验,没有证明它比其他工具更有效。
能拿来做什么
- 选一个最近最容易失去进度感的项目,先建立三到四个宽泛主题目录,再录入四到五件真正等待推进的任务,并填写截止日期。先把活跃工作记清楚,不急着搬完整个 backlog。
- 为日常 AI 编程会话增加固定的启动步骤:读取项目决策、最近提交、进行中任务和按截止日期排序的待办,先汇报再动手。使用多会话时,再加入其他会话的工作检查。
- 如果你也用 Node 或其他脚本运行内容流水线,把成功标准落实到最终提交结果:API 拒绝保存时,应反馈失败;提交成功后,再更新可供自动检查读取的记录。
- 用原文的验收问题检查效果:不补充背景,Agent 能否回答「项目还有什么待办,相关决定是什么」。答不出来时,先检查信息有没有被写入、状态有没有更新,再考虑优化检索。