Agent Engineering
Loop Engineering:搭一个会给你定罪的循环
Prompt engineering 解决的是「该说什么」,Loop engineering 解决的是「系统怎么把事做完」——而在它状态最好的那些日子里,它还会给你.
简版速览
过去两年,我们都在学怎么把 prompt 写得更好。可 prompt 只是一个方向盘,它不是一辆车。
真正的活儿需要方向盘之外的一切:一个可以核实的目标、一个能记事的地方、刹车、温度计、修理工、一个签字放行的成年人,还有一本笔记本,好让明天比今天更聪明地开始。这就是一个循环(loop),而搭建它,就是工程。
没人写过的那部分,恰恰是最好的部分:一个搭建得当的循环,终究会告诉你,你错了。我自己的循环在一周之内做到了这一点,四次。这四个故事就是本文的证据,它们的成本,远比那张架构图本身要高。
树屋
你爸说:搭一个安全的树屋。
你不能闭上眼睛,念一句咒语,然后一睁眼树屋就造好了。你得跑一个循环:「安全」到底是什么意思?我手头有什么木料?木板装上去合不合适?梯子晃不晃?哪里出了问题?我弟弟能不能爬上去?
现在把名词换一下。树屋变成软件,木板变成代码,螺丝变成 API 调用,安全检查变成测试,爸爸变成人工审查,笔记本变成记忆,错误变成反馈。
一个 agent 强大,不是因为它答对了一次,而是因为它能不断尝试、观察、判断、修正、再尝试。
一一对应表
| 心智模型 | 技术名称 | 为什么重要 |
|---|---|---|
| 「造一个安全的树屋」 | Goal Contract(目标契约) | agent 需要一个明确的目标,以及「完成」的定义。 |
| 先画草图 | Plan(计划) | 行动之前先提出一条路径。 |
| 工作台上的工具 | Tool Access(工具权限) | 能力,但要刻意划定边界。 |
| 量一量木料 | Observation(观察) | 真实的反馈,而不是想当然。 |
| 检查梯子晃不晃 | Evaluation(评估) | 这真的够好了吗? |
| 拧紧松掉的螺丝 | Recovery(恢复) | 解决你真正遇到的那个失败 |
| 老爸检查完,孩子才能爬上去 | 人类闸门 | 高影响力的操作需要一个签字 |
| 把失败的原因写下来 | 记忆 | 下一次运行会比这一次更聪明 |
| 在安全的时候停下来 | 停止条件 | 知道什么时候该收工 |
| 不独自使用电锯 | 策略闸门 | 危险操作需要确定性的管控 |
这张表就是整个架构。下面的内容只是细节。
为什么一句提示词不够用
一句提示词可以说把这个 bug 修了。但一个编程 agent 得去读 issue、检查仓库、找到文件、提出假设、改代码、跑测试、读懂报错信息、再次打补丁、重新运行、总结证据、开一个 pull request,然后等待评审。
这不是一句提示词能干的事。这是一整个操作系统,只是方向盘长在了外面。
脊梁骨
User intent → Goal Contract → State Ledger → Planner → Tool Router
→ Policy Gate → Executor → Observer → Evaluator → Recovery
→ Human Gate → Memory → next loop or delivery
目标契约——那张点单
餐厅的点单会写:7号桌,鸡肉,不加花生,中辣,二十分钟。没有这张单子,厨房只能靠猜。
差的写法:把结账那个问题修一下。 好:
{
"objective": "Fix timeout during checkout payment confirmation",
"success_criteria": [
"Payment confirmation completes under 3 seconds",
"Existing payment tests pass",
"No duplicate charges are created",
"Pull request includes test evidence"
],
"constraints": {
"max_iterations": 8,
"max_cost_usd": 10,
"forbidden_actions": ["deploy_to_production"],
"requires_human_approval": ["database_migration", "payment_logic_change"]
}
}
大多数智能体系统失败,不是因为模型笨,而是因为目标模糊。目标一模糊,计划就模糊,工具跟着乱用,混乱由此变得昂贵。
状态账本——白板
修自行车时,你会把试过的方法记下来。模型是大脑;账本是白板。别指望大脑同时兼任白板——上下文会退化,工具输出带噪声,旧的推理也会过期。
每次工具调用都要记录:状态、迭代次数、当前假设、已完成步骤、待解决问题、上一次的报错。
策略闸门——刹车
十几岁的孩子可以用厨房刀,但不该独自用电锯。策略闸门就是站在电锯旁边的那个大人,而这个大人必须由代码来当——code:
def policy_gate(tool, args, state):
if tool == "process_refund":
if not state.get("verified_customer_id"):
return {"allowed": False, "next_action": "lookup_verified_customer"}
if args["amount"] > 500:
return {"allowed": False, "next_action": "escalate_to_human"}
if tool == "deploy_to_production":
return {"allowed": False, "next_action": "request_approval"}
return {"allowed": True}
提示词指令是概率性的,闸门是确定性的。如果这个动作涉及资金、生产环境、隐私、安全或法律风险,靠概率是不够的。
评估器——温度计
你不会靠猜来判断鸡肉熟没熟。优先用确定性检查——测试是否通过、schema 是否校验、类型是否检查、数字是否对得上——只在真正需要判断力的地方,才动用模型来评判。
别问这样好吗? 要问哪些标准通过了,哪些没通过,又有什么证据支撑这个结论? 一个给不出下一步行动的评估,不过是一句感想。
恢复——机修工
链条掉了,你不会去买辆新自行车。先分类,再行动:临时性失败退避重试,校验性失败修改输入,权限性失败申请权限,业务规则性失败停下或上报——同一个失败出现三次,就该换策略了。
重试不是一种策略,它只是一个工具。好的智能体不会更努力地硬撑,而是换一种方式去尝试——不同的方法.
停止——是控制,不是失败
你停工,是因为框架已经稳固、梯子已经安全、爸爸点了头——不是因为你累了。在运行任何东西之前,先定义好五种停止条件:成功、失败、上报、预算、安全。一个停不下来的循环,谈不上自主,只是失控。
人类闸门——那个负责任的大人
上报不是智能体的失败,而是审慎的系统用来保持安全的方式。但"need human help"(中译:需要人类帮忙) 是一次没用的升级请求。好的升级请求要带上需要做的决定、建议方案、证据、风险,以及备选方案——人类应该能在两分钟内做出决定。
记忆——经过筛选,绝不自动写入
糟糕的记忆会让错误滚雪球,好的记忆会让智慧滚雪球。所以记忆要先由智能体提出,再由人类或闸门批准。只保存那些具体、有证据支撑、可复用、并且挂钩着未来某个行动的经验。
循环四次定了我的罪
接下来这部分,是我一年前写不出来的。这些事都发生在我搭建自己那一队智能体的某一周里,每一次都是我造的机器告诉我:我错了。这就是循环工程的回报——不是速度,是纠错.
1. 闸门定的第一个罪,是它的作者
我给一个验证器加了条新的阻断规则,上线之后,构建直接变红。不是因为规则本身有错——是因为我把规则加进了代码,却没加进代码所依据检查的那份规格说明里,一个一致性测试抓到了这个偏差。我这个新闸门第一个定罪的,就是我自己。
法则:一个从没对自己作者动过手的验证器,大概什么都没在检查。
2. 那个悄悄漏掉每一个词根的路由器
我造了一个确定性路由器,用来判断一篇新文章或新仓库该归到我哪个仓库下。它看起来没问题,测试也全过了。可我拿四个真实来源一跑,它只路由对了一个。
原因出在我自己:它读取的注册表把触发词标注为子串匹配,其中好几个本来就是故意设计成词根的——self-improv, portfolio rebalanc。而我实现的却是整词匹配,于是一篇讲“自我进化流水线”的文章,什么都没匹配上。测试之所以全过,是因为我写测试时对齐的是我的实现,而不是数据本身。
法则:先拿真实输入跑一遍,再相信自己那一片绿色。
3. 评分器拒绝了我的成绩单
我系统里每一次交付都会生成一张成绩单,由一个独立的评分器打分。我提交了一份,结果打回来0.00——被封顶,理由是"significance unstated"(中译:重要性未说明)。我描述了我做了什么,却从没说明这为什么重要、它撬动了哪个数字。
后来同一个评分器给一个小改动1.00打了高分,却又标记了它(sandbagged?)——告诉我,我给自己设的标准太低了。两次判定都对,但都不好听。
法则:如果你的评估器给不出差评,它就只是个摆设。
4. 说不清自己目标的计划
我为一个 360 天的营收计划搭建了一个关键路径路由器。它算出这个计划轻轻松松就能完成——四十天就能搞定一个九十天的里程碑——可实际营收是零。
算术没问题,问题出在图本身:图里没有一个节点声明自己会产生营收。这其实是一张仓库依赖图,只是披了张计划的皮。现在这已经成了一条阻断规则:如果目标是可衡量的,却没有任何东西对它有贡献,那就一条路由都不放行。
法则:一个说不清自己目标的计划,只是一张画了甘特图的愿望。
十二条法则
- 目标不清,智能体就不可靠。模糊的目标只会催生一个瞎转悠的循环。
- 状态存在于模型之外。模型负责思考;系统负责记住。
- 工具需要契约。用途、输入、输出、边界、失败模式,一样都不能少。
- 关键规则需要闸门。提示词层面的引导,算不上真正的控制。
- 评估必须产出证据。没有证据,就没有信任。
- 只重试可重试的失败。 更努力尝试不等于更聪明地恢复。
- 停止条件是架构的一部分。 一个无法停止的循环,就是一个 bug。
- 记忆必须经过筛选。 糟糕的记忆会让错误复利增长。
- 人类应该守在高杠杆的闸门前。 那是责任,不是软弱。
- 可观测性创造信任。 如果你无法检视它,你就无法操作它。
- 更多智能体不等于更多智能。 协调才是难点。
- 循环应当产生复利。 每一次运行,都该让下一次更好。
还有第十三条法则,是上面四个故事换来的:build the loop so it can convict you.(中译:把循环建得能给你定罪。) 一个只会验证自己作者的系统,不过是一面镜子。
三十天:目标,不是成绩单
本节中的一切都是一个瞄准的目标,而不是我在汇报的结果。我没有做过对照实验;这些只是我给自己定下的建造标准。
第一周——最小可用循环。 目标合约、状态模式、工具结果模式、控制器、一个规划器、两个工具、一个评估器、一个迭代上限。目标:不用你插手,它就能完成简单任务。
第二周——可靠性。 错误分类,一个is_retryable 标志、一套恢复策略、重复错误检测。目标:能区分瞬时性错误、校验错误、权限错误与业务规则错误。
第三周——刹车。 风险分级、写进代码的策略闸门、一份审批包、一份审计日志。目标:测试套件里每一次受限调用都被拦下。
第四周——复利。 候选记忆、任何内容成为永久记忆前的人工复核、失败模式追踪。目标:同一个错误不再重复发生。
本文没有主张什么
- 没有基准测试。 我没有拿这套架构去和其他方案做对比测量。那四个故事是事故,不是研究。
- 上面那些数字是目标。 这篇文章最初的草稿把它们写得像是已测得的结果,那是个错误——我在这里把它改了过来,而不是悄悄删掉了事。
- 一支团队,一个负责人。 我所学到的一切,都来自我自己的仓库和我自己的智能体。你的失败模式会不一样。
参考来源
我自己定的规矩是:没有来源,就不能下结论。这篇文章的早期草稿就违反过这条规矩——它用一个未标注来源的说法去引用 Tree-of-Thoughts 论文,而这恰恰就是这条规矩本该防止的那种失败。所以:
- Tree of Thoughts: Deliberate Problem Solving with Large Language Models,Yao 等,2023 年——arXiv:2305.10601。该论文报告称,在搜索与规划类任务上,其表现相较思维链(chain-of-thought)有显著优势。我在这里刻意没有照搬具体数字,因为发布时我没有重新核实过它们。
- 这四起事故都出自我自己仓库的提交历史,时间在 2026-08-05 至 2026-08-11 之间。
结语:允许被推翻的系统
提示工程让 AI 变得有用。循环工程让它变得可靠。
提示词能给出一个答案;循环能交付一份工作。提示词可以听起来很聪明;循环可以被检验。提示词能让人印象深刻;循环能产生复利。
构建目标、状态、工具、闸门、评估器、修复机制、人类、记忆。然后构建大多数人都会跳过的那一件事:允许它告诉你「你错了」的那一部分。