开发指南:实现可生产的 Agent Loop Runtime
七天实战
本篇对应你在 Loop Engineering 子站 「从实验到系统」的工程部分;实现时请同步对照 Hermes 开发指南 的工具链与 DSH 开发指南 的 Session/插件边界。
导读
快速开始解决了「能跑的 ReAct」。开发指南解决五件事:
- 六类循环的 实现契约(接口、状态、停止)。
- 失败模式库(可检索、可告警)。
- 与 Harness 的 清晰分层(谁熔断、谁审批)。
- 并发、重试、checkpoint 的工程选择。
- 如何把 Loop 做成可测、可灰度的模块。
一、Loop Runtime 的推荐模块边界
| 模块 | 输入 | 输出 | 单测重点 |
|---|---|---|---|
TopologySelector | 任务卡元数据 | 拓扑枚举 | 规则表 |
StepEngine | 状态 + 事件 | 新状态 | 迁移完备 |
BudgetAccountant | usage 事件 | 是否耗尽 | 边界值 |
StopJudge | 状态快照 | reason | 优先级 |
ObservationPipeline | 原始 tool_result | 压缩文本 + 指纹 | 截断不丢关键错误 |
WriteBackGate | 候选记忆 | 允许/拒绝 | 过滤策略 |
Tracer | 事件 | 持久化记录 | 字段必填 |
原则:Prompt 可以脏,状态机必须干净。 把「下一状态」从「模型说了啥」里剥离出来。
二、ReAct / Tool Loop 深化
2.1 消息协议冻结
选定一种并全局唯一:
| 协议 | 适用 | 解析风险 |
|---|---|---|
OpenAI tool_calls | 多数云 API | 低 |
Hermes <tool_call> | 本地对齐模型 | 中(需修复 JSON) |
| Claude tool_use | Anthropic | 低 |
Loop 层只吃 规范化后的 Action{name,args};解析失败算 fatal 或「要求模型重发」专用步(计入预算)。
2.2 并行工具调用
当模型一次返回多个 tool_calls:
| 策略 | 行为 | 风险 |
|---|---|---|
| 串行 | 按数组顺序 | 慢但简单 |
| 受限并行 | 只读工具并行,写工具串行 | 推荐默认 |
| 全并行 | 同时打 | 写冲突、竞态 |
2.3 重试策略(工具层 vs 循环层)
- 工具瞬时失败(429、超时):Harness 内短重试(1–2 次),指数退避。
- 逻辑失败(404、断言失败):不要盲重试;交给 Loop 改参或 Replan。
- 禁止:对同一指纹无限「再试一次」。
三、Plan–Execute 实现要点
3.1 计划对象
{
"plan_id": "p3",
"version": 2,
"steps": [
{"id": "s1", "goal": "定位失败测试", "tools_allow": ["read_file", "run_pytest"], "done_when": "pytest_output_contains_FAILED"},
{"id": "s2", "goal": "最小补丁", "tools_allow": ["read_file", "edit_file"], "done_when": "diff_non_empty"}
]
}
状态字段:current_step_id、plan_version、replan_count、step_attempt。
3.2 Replan 触发器
| 触发 | 条件 | 动作 |
|---|---|---|
| 签名停滞 | 同 error_signature ≥ N | 升 plan_version |
| 步骤超时 | 单步 steps 超限 | 标记 blocked → replan |
| 用户改目标 | 外部事件 | 强制 replan |
| 工具权限拒绝 | Harness 403 | 可能直接 fatal |
振荡检测:若 plan_version 在 A↔B 间来回,直接失败并请求人审。
四、Reflection 与 Evaluator–Optimizer
4.1 Reflection 契约
反思模型输出必须 schema 化:
{
"verdict": "revise",
"issues": [{"severity": "factual", "detail": "API 名称未在原文出现", "fix": "删除或补引用"}],
"must_fix": true
}
verdict=pass 才允许成功停止;revise 则把 issues 注入下一轮。max_reflect_rounds 默认 1–2。
4.2 Evaluator–Optimizer 双进程思维
即使跑在同一机器,也要 逻辑隔离:
| 角色 | 权限 | 输入 | 输出 |
|---|---|---|---|
| Optimizer | 可写产物 | 上轮分数+评语 | 新候选 |
| Evaluator | 只读产物 + 只读测试 | 候选 | score + rationale |
刷分检测:score 上升但关键业务指标不变 → 标记 metric_gaming 失败。
4.3 何时用规则评测 vs LLM Judge
| 目标类型 | 推荐传感器 |
|---|---|
| 编译/测试/格式 | 确定性脚本 |
| 文风、温和毒性 | LLM Judge + 抽样人工 |
| 安全性 | 规则 + 专用分类器,慎用被优化器可见的弱 Judge |
五、多 Agent 编排环
5.1 编排器职责
编排器(Orchestrator)不是「另一个爱聊天的 Agent」,而是 带策略的调度器:
- 维护全局目标与预算池(给子 Agent 配额)。
- 定义 handoff schema。
- 检测传球环(A→B→A)。
- 决定并行还是流水线。
5.2 Handoff 载荷
{
"from": "researcher",
"to": "writer",
"artifact_refs": ["notes.md"],
"claims": ["框架X用显式 max_iterations"],
"budget_left": {"steps": 6, "tokens": 20},
"do_not": ["重新全网搜索已完成主题"]
}
缺少 artifact_refs 的 handoff 应拒绝——防止「口头交接」。
5.3 拓扑选择
| 模式 | 结构 | 适用 |
|---|---|---|
| 主管–工人 | 星型 | 任务分解清晰 |
| 流水线 | 链式 | 调研→写→审 |
| 黑板 | 共享存储 | 多专家填同一工件 |
| 自由讨论 | 全连接 | 默认禁止上生产 |
六、Memory Write-back 工程
6.1 写回管道
过滤规则示例:拒绝无来源事实;拒绝密钥/PII;拒绝与当前用户指令冲突的「偏好」。
6.2 读入策略
- 标注
memory_id