Loop Engineering(运行循环工程)

Loop Engineering 是专门设计和调优 Agent 那个”想一步→做一步→看结果→再想”的循环的工程实践。它不新造一个概念,而是把 agent.md 里提到的”运行循环(Loop)“当成一个要认真设计的一等公民来对待。

一句话类比:如果 Agent 是一辆自动驾驶的车,模型是”大脑”,工具是”手脚”,那 Loop 就是这辆车的”驾驶节奏”——什么时候踩油门(继续调用工具)、什么时候刹车(停止并回答)、迷路了怎么办(纠错重试)。Loop Engineering 就是把这个节奏调好。

定位:Loop Engineering 关注循环本身的逻辑(要不要再来一轮、这一轮喂什么);承载这个循环运行的”外壳/运行时”叫 Agent Harness,见 agent_harness.md。两者是”循环的规则” vs “跑循环的机器”的关系。

1. 一个最朴素的循环长什么样

ReAct 循环(见 agent.md)用伪代码写出来,本质就是一个 while

state = init_state(user_input)          # 初始状态:用户问题 + 空的历史
while True:
    action = model.decide(state)        # 想:模型看当前状态,决定下一步
    if action.is_final_answer:          # 判停:够了就跳出
        return action.answer
    observation = run_tool(action)      # 做 + 看:执行工具,拿到结果
    state = state.append(action, observation)  # 更新状态,进入下一轮

Loop Engineering 要回答的,就是这段代码里每一处看起来简单、实则要命的决策:

循环中的环节朴素做法真正要工程化的问题
判停(何时结束)模型说”我答完了”就停模型不肯停 / 提前乱停怎么办?要不要设最大轮数?
更新状态把所有历史全塞回去上下文越滚越长、越贵,怎么裁剪?(见 Context Engineering)
执行工具直接调用工具报错、超时、返回一坨垃圾怎么办?
下一轮决策全交给模型要不要强制某些步骤、要不要人来确认?

2. 循环设计的核心决策点

2.1 判停条件(Termination)

最容易被忽视、也最容易翻车的地方。常见几种停法,通常组合使用:

  • 模型主动收尾:模型这一轮不再请求工具,直接给出最终答案 → 自然结束。
  • 最大轮数 / 步数上限(max iterations):兜底,防止无限循环烧钱。必须有
  • 预算上限:达到 token 或时间预算就停。
  • 达成显式目标:某个校验条件满足(如测试通过、文件已生成)就停。

常见坑:只靠”模型自己说停”。模型可能陷入”反复调同一个工具→拿到同样结果→再调”的死循环,或者相反——过早收尾,工具还没跑完就急着回答。所以硬性的 max iterations 是底线。

2.2 一轮里做几件事:串行 vs 并行

  • 串行:一次只决定一个动作,看到结果再决定下一个。逻辑清晰,但慢。
  • 并行:一轮里同时发起多个独立工具调用(如同时查北京和上海天气,见 agent.md 的例子),再一起聚合。快,但要求这些调用互不依赖

判断标准:后一个动作是否依赖前一个的结果。不依赖就并行,依赖就串行。

2.3 错误处理与重试(这是 Loop 和 Harness 的交界)

工具失败不该直接让整个 Agent 崩掉。常见策略:

  • 把错误信息当成 observation 喂回给模型,让它自己换个方式重试(很有效)。
  • 有限次重试 + 退避(backoff):网络类错误重试,逻辑类错误就别硬试。
  • 降级:某工具挂了,换个工具或直接告诉用户”这部分做不了”。

把报错原文喂回模型,往往比你写一堆 if-else 更聪明——模型能读懂”参数写错了”并自己改。这是 agentic 循环相比传统 workflow 的一大优势。

2.4 状态在循环里怎么滚

每轮都要更新 state(历史、工具结果、中间产物)。核心矛盾:信息要够全(不然模型失忆)vs 不能太长(贵、慢、稀释注意力)。

  • 早期简单做法:全量拼接(把所有历史塞回去)——短任务够用。
  • 工程化做法:摘要压缩旧历史、只保留关键结果外置记忆(写到文件/DB,需要时再读回)。
  • 这部分正是 Context Engineering 的地盘,Day 2 会专门学(计划见 context_engineering.md)。

⚠️ 边界澄清(易混):状态更新的”策略”归 Loop Engineering,“执行”归 Harness。 也就是说”保留多少、怎么压缩、何时外置”是这里要设计的规则;真正把 state 存下来、每轮追加、读写记忆,是 agent_harness.md 模块⑥那台机器干的。一句话记:Loop 定策略,Harness 管执行。

3. 循环的两种形态:固定 vs 自主

维度Workflow(固定流程)Agentic Loop(自主循环)
下一步谁决定代码写死的路径模型每轮动态决策
可预测性高(见 AI 可预测性)低,但更灵活
适用步骤固定、可枚举步骤不定、需随机应变
调试容易,路径确定难,每次路径可能不同

呼应 agent.md 的判断原则:流程路径固定就用 workflow,不固定才用 agent。真实系统常是”大流程写死(workflow)+ 某几个节点内部放一个小 agentic loop”的混合体。这正是”流程编排”(Day 3,计划见 orchestration.md)要处理的。

4. 常见坑(复习重点)

  • 没有 max iterations 兜底 → 死循环烧 token。任何生产循环都要有硬上限。
  • 状态无脑全量拼接 → 上下文爆炸,越到后面越慢越贵越蠢。
  • 工具报错直接抛出 → Agent 一遇错就整个挂掉,而不是让模型尝试自愈。
  • 该并行的串行做 → 明明互不依赖的调用一个个排队,白白变慢。
  • 只看”最终答案”不看”循环轨迹” → 出了问题无从排查。循环一定要可观测(记录每轮的 thought/action/observation),这是 Harness 要提供的能力。

5. 明天实操钩子 🔧

不用任何框架,纯 Python 手写一个最小 ReAct 循环,亲手体会上面这些决策点:

  1. 定义 1~2 个假工具(如 get_weather(city) 返回写死的数据)。
  2. 写一个 while 循环:调用模型 → 解析它想调哪个工具 → 执行 → 把结果拼回去 → 再问模型。
  3. 故意制造三种情况,观察循环行为:①模型不肯停(加 max_iterations 兜底)②工具报错(把错误喂回去看它会不会改)③需要两个独立查询(试试并行)。
  4. 做完对照 agent.md 里 LangChain 的 AgentExecutor——你会发现它帮你封装的正是这个循环。这就自然过渡到 agent_harness.md

关联概念