大模型循环调用:从协议级到应用级的循环控制谱系
摘要
大语言模型 Agent 的能力跃迁,本质上来自一个被反复执行的动作:把模型的输出回灌为新输入,再次调用模型。这一动作被称为"循环调用"。它既是 Agent 区别于"一次性问答"的根本机制,也是成本失控、上下文爆炸、任务陷入死循环的根源。本文以"循环控制"为切入口,先提出一个统摄性分析框架------判停权谱系:循环"何时停、由谁判停"存在一条从模型自主到外部强制的连续轴,任何循环控制系统都必须沿此轴回答终止性、预算性、安全性三个核心问题。
沿此谱系,本文依次剖析三种代表性范式。其一是协议级 的 Anthropic Claude------通过 stop_reason 七值协议、tool_use → tool_result 往返、Server Tool 服务端采样循环(默认 10 次迭代触发 pause_turn)、Tool Runner SDK 的 max_iterations、Claude Agent SDK 的 max_turns 与 max_budget_usd,在协议层与 SDK 层提供可组合的终止判据。其二是应用级 的 Cline------作为开环自治 Agent,通过 maxRequestsPerTask(默认 25)的"电路断路器"、Auto-approve 权限网格、上下文窗口管理与人机协同审批,在应用层节制循环。其三是本项目设计的 rule_match 规则化循环 ------既非模型自主判定(Anthropic 路线)也非步数硬阈值(Cline 路线),而是用确定性规则集评估每步结果决定 continue/stop/error,以"规则判定 + default→stop 吸收态"取得形式化可证明的终止性。
三者在学术上同源:ReAct(Yao et al. 2022)、控制论反馈回路(Wiener 1948)、有限状态机终止性(Manna 1974)、神经-符号混合(Garcez & Lamb 2020)与必要多样性定律(Ashby 1956)为"循环何时停、停在哪、由谁判停"提供理论根基;在工程层面则统一为可归因、可预算、可降级的多层守卫框架。循环不是 Agent 的功能,而是 Agent 的边界条件------控制了循环,才控制了 Agent。
关键词:大模型循环调用、stop_reason、tool_use 循环、max_turns、maxRequestsPerTask、电路断路器、规则化循环控制、Agent 终止性
一、问题重定义:循环调用是 Agent 的边界条件
1.1 单次推理的局限与循环的必然性
大语言模型单次推理的本质是"无状态的 token 映射"------给定一段 prompt,输出一段 token。这种单次映射在"问答"场景足够,但在"任务"场景捉襟见肘:任务需要模型读取环境、采取行动、观察结果、调整策略、验证完成------任何一个环节都需要外部世界的状态反馈,而模型本身不持有状态。弥合"无状态推理"与"有状态任务"之间鸿沟的唯一结构手段,是循环:把模型上一次的输出(含工具调用)作为输入的一部分,连同工具执行结果,再次喂给模型,直至任务完成。
这一构造的工程学名是 agent loop(代理循环)。它把"单轮 LLM 调用"扩展为"多轮带工具反馈的 LLM 调用链",使模型从"被动答题者"转变为"主动行动者"。Anthropic 在其 Agent SDK 文档中对此有明确表述:Agent SDK 运行"与 Claude Code 相同的执行循环------Claude 评估 prompt、调用工具采取行动、接收结果、重复,直到任务完成"。
1.2 循环的两面性:能力放大器与成本黑洞
循环是 Agent 能力的放大器,但同时也是成本的黑洞。其放大能力的一面显而易见------循环使模型可以逐步逼近复杂任务目标,每一步在前一步结果基础上精化策略。其吞噬成本的一面则更隐蔽:
- 输入成本随轮次非线性增长 。在扁平历史累积的策略下(如 ReAct),第 N 轮的输入包含前 N−1 轮的全部观察与推理。若首轮上下文为 4K token,每轮观察增长 2K,到第 10 轮输入已达 22K------而且每一轮都要把这部分上下文重新发送,单次任务的输入总成本约为
4 + 6 + 8 + ... + 22 = 130Ktoken。 - 输出成本被乘以 3。主流 API 的输出单价约为输入的 3 倍,每轮若平均输出 1K token,10 轮即 10K 输出 token,按 3 倍单价等价于 30K 输入 token 的成本。
- 失控的循环是数量级的灾难。Cline 用户社区的真实报告显示,一夜无人值守的循环任务可消耗 30--80M token,账单从数十美元至数百美元不等。循环一旦失控,损失按"轮次 × 上下文长度 × 单价"放大。
1.3 循环控制的三个核心问题
任何"循环调用"系统都必须显式回答三个问题:
- 终止性(Termination):循环何时停?由谁判定?是模型自主声明完成,还是外部规则判定,还是达到步数阈值强制中止?
- 预算性(Budget):循环可以花多少?预算以什么单位计量------轮次、token、美元、时间?
- 安全性(Safety):循环中每一步的动作是否被授权?敏感动作(执行命令、修改文件、访问外部)需要人工审批还是自动放行?
这三个问题不是相互独立的维度,而是同一边界条件的不同切面。一个健康的循环控制系统,必须在协议层、SDK 层、应用层分别回答这三问,并形成多层守卫。第二章将把这三问并入一个统一的"判停权谱系"分析框架,第三至五章沿谱系剖析三种范式如何回答它们。
1.4 一个被忽视的诊断信号
判断一个 Agent 系统的循环是否健康,有一个简单的诊断信号:问"你的循环在第 N 步停下的概率分布是什么?"。若回答是"靠模型自己决定何时结束",则系统几乎必然在某些任务上陷入循环失控------因为模型的"完成感"并不与真实任务完成严格对齐。健康的循环系统应当能输出"在 max_turns=10 的预算下,平均 3.2 步完成,最坏 7 步,触发预算熔断的概率 < 1%"这样的可量化描述。本文主张:循环控制必须从"模型自主"升级为"多层守卫",这是 Agent 工程化的核心边界条件。
二、分析框架:判停权谱系与层级轴
在剖析具体实现之前,本章先建立一个统摄全文的分析框架。循环控制的一切差异,都可用两条正交的轴来刻画:判据轴 (谁判停、何时停)与层级轴(控制能力分布在协议、SDK、应用的哪一层)。
2.1 判据轴:判停权谱系------从模型自主到外部强制
循环"何时停"的判据,构成一个从"模型自主"到"外部强制"的谱系。谱系越靠左,判停越灵活但也越不可靠;越靠右,判停越确定但也越不贴合任务语义:
| 判据类型 | 来源 | 范例 | 优势 | 风险 |
|---|---|---|---|---|
| 模型自主终止 | LLM 判断 | Claude end_turn、Cline 任务完成声明 |
灵活、贴合任务语义 | 可能误判,无限循环 |
| 协议信号终止 | API 协议字段 | pause_turn、max_tokens |
协议级可靠 | 仅覆盖部分场景 |
| 规则判定终止 | 确定性规则评估 | rule_match 输出 stop |
零 LLM 成本、可审计 | 规则集需正确设计 |
| 步数阈值终止 | 外部计数 | max_turns、maxRequestsPerTask |
简单可靠 | 不区分请求性质 |
| 预算阈值终止 | 美元/token 累计 | max_budget_usd |
直接对应成本 | 需要准确计费 |
| 人工中断终止 | 人操作 | Cline 用户取消 | 终极兜底 | 需要人值守 |
健康的循环系统应在多个判据上分布守卫------任一判据失效时其他判据仍可兜底。这一谱系正是全文的组织线索:第三至五章剖析的三种范式分别落在谱系的不同位置------Anthropic 依赖"模型自主 + 协议信号 + 预算阈值",Cline 依赖"模型自主 + 步数阈值 + 人工审批",rule_match 则主推"规则判定 + 步数守卫"。
2.2 层级轴:协议---SDK---应用
判据轴回答"由谁判停",层级轴则回答"控制能力分布在哪一层"。循环控制能力可按其所在抽象层级分层:
| 层级 | 关注点 | 代表机制 |
|---|---|---|
| 协议层 | 循环终止信号的语义 | stop_reason 七值、pause_turn、max_tokens |
| SDK 层 | 循环执行抽象与预算 | Tool Runner max_iterations、Agent SDK max_turns/max_budget_usd/hooks |
| 应用层 | 工具授权、步数阈值、上下文管理 | maxRequestsPerTask、Auto-approve 网格、Context Window |
Anthropic 自上而下把控制能力下沉到协议层与 SDK 层;Cline 自下而上在应用层组装策略------前者强依赖自家生态但层级清晰,后者适配任意 API 但失去协议层精细控制。本项目的 rule_match 则以"规则判定"填补谱系中"模型自主"与"步数阈值"之间的空档,既可在任意执行端(CLine/SK/MCP)之上叠加,又可与协议层信号构成"双层循环控制"(详见第五章)。
2.3 评估模板:终止性 / 预算性 / 安全性
把第一章的三个核心问题上升为评估模板:每一类范式都要接受三问拷问------终止性 (判停权落在谱系何处、是否可证明)、预算性 (以何单位计量、如何兜底)、安全性(动作是否被授权、由谁授权)。后续第三至五章对每种范式的剖析,即按此模板展开;第六章再做横向对比,第七章给出学术根基。
三、范式一 · 协议级:Anthropic Claude
Anthropic 把循环控制能力下沉到协议层与 SDK 层,形成"协议---SDK---应用"递进的统一体系。其设计哲学是:模型负责决策,框架负责约束,约束以可组合的方式暴露给开发者。
3.1 stop_reason 七值语义表
Anthropic Messages API 的每个响应都携带 stop_reason 字段,明确告知调用方"模型为何停止生成"。这是循环控制的最底层信号。完整的七值语义如下:
stop_reason 值 |
触发条件 | 调用方应当做什么 |
|---|---|---|
end_turn |
模型自然结束回合,无更多动作 | 接受响应,循环结束 |
max_tokens |
响应达到 max_tokens 上限 |
输出被截断,提高上限或续写 |
stop_sequence |
命中调用方预设的 stop_sequences 之一 |
读取 stop_sequence 字段判断触发哪一个 |
tool_use |
模型请求调用工具,等待结果 | 执行工具,回传 tool_result,继续循环 |
pause_turn |
服务端工具循环达到迭代上限(默认 10) | 把当前 assistant 内容回传以续接 |
refusal |
模型基于安全理由拒绝响应 | 读取 stop_details,转 fallback 模型 |
model_context_window_exceeded |
响应填满模型上下文窗口 | 视为截断,触发上下文压缩 |
这七值的工程价值在于:把"循环是否继续"从隐式判断显式化为可分支的字段值 。一个生产级 Agent 不应盲目把响应当作"完成"------三种 stop_reason(max_tokens、tool_use、pause_turn)实际意味着"任务尚未完成,需要续接"。混淆 end_turn 与 max_tokens 是 Anthropic 文档明确指出的"最常见生产 bug"。
在循环控制语境下,stop_reason 提供了三类判停信号:end_turn 是软终止 (模型自主声明完成),max_tokens 与 model_context_window_exceeded 是硬截断 (生成能力受限),tool_use 与 pause_turn 是延续指令(需要外部回灌才能继续)。
3.2 tool_use → tool_result:客户端工具循环
tool_use 是 Anthropic 客户端工具循环的核心驱动信号。其完整生命周期为:
1. 调用方发送 user 消息 + 工具定义
2. Claude 评估,决定调用工具 → 响应 stop_reason="tool_use",
含一个或多个 tool_use content block(含 name, id, input)
3. 调用方执行工具,构造 user 消息含 tool_result block
(tool_use_id 必须与步骤 2 的 id 匹配)
4. 把 tool_result 回传给 Claude → Claude 继续推理
5. 重复 2--4,直到 Claude 产出无 tool_use 的纯文本响应(end_turn)
这一构造的关键性质是:循环的延续权由模型持有,但循环的终止由模型自然声明 。模型不再调用工具时,响应中无 tool_use block,stop_reason 为 end_turn,循环结束。这是一种"模型自主终止"的范式------终止性由 LLM 的判断决定,外部框架只负责忠实执行工具与回传结果。
这种范式的优势是灵活:模型可以根据任务进展动态决定何时"做完了",不需要外部预设死板的步数阈值。其代价是终止性不可证明------模型可能在错误的"完成感"下提前终止,也可能在反复"让我再试一次"的循环中无限延续。前者影响任务质量,后者引发成本爆炸。
3.3 Server Tool 服务端采样循环与 pause_turn
除了客户端工具,Anthropic 还提供 Server Tool(如 web_search、web_fetch),其执行循环在 Anthropic 服务端运行------服务端自动多轮调用工具并把结果合并到响应中,无需调用方逐步回灌。但服务端循环并非无限:默认上限为 10 次迭代 。当达到此上限时,API 返回 stop_reason="pause_turn",可能伴随未匹配 server_tool_result 的 server_tool_use block。
调用方收到 pause_turn 后,应当把当前 assistant 内容回传以续接循环。这是一种"分段循环"模式------服务端循环达限暂停,由调用方决定是否续接,避免服务端长时间占用资源。这一设计在协议层显式承认了"循环必须有上限"的工程纪律,并把它编码为协议字段而非隐式行为。
3.4 Tool Runner SDK:max_iterations 兜底
Anthropic 各语言 SDK(Python/TypeScript/C#/Go/Java/PHP/Ruby)提供 Tool Runner 抽象,自动处理工具执行、结果回传与对话状态管理。其循环逻辑为:
工具运行器循环直到 Claude 返回不含工具调用的消息,或直到达到
max_iterations(若设置)。
max_iterations 是 SDK 层的循环护栏:当模型陷入"工具调用---回灌---再调用"的死循环时,max_iterations 强制中止。这一参数把"循环上限"从隐式的模型自主性提升为显式的开发者配置------开发者可以声明"这个任务最多允许 K 次工具调用",超过即终止。
Tool Runner 还支持循环内读取与修改 runner 状态,使开发者可以接管消息历史的追加逻辑,实现自定义的循环行为(如注入额外指令、跳过某些工具调用、动态调整工具集)。这把循环从"黑盒执行"提升为"可介入的执行流"。
3.5 Claude Agent SDK:max_turns / max_budget_usd / permission mode
Claude Agent SDK 把 Claude Code 的执行循环以编程库形式开放。其循环抽象为"turn(回合)"------一次完整的"Claude 产出含工具调用 → SDK 执行工具 → 结果回传"的过程。Agent SDK 的循环控制参数如下:
| 选项 | 控制内容 | 默认值 |
|---|---|---|
max_turns / maxTurns |
最大工具调用回合数 | 无上限 |
max_budget_usd / maxBudgetUsd |
最大美元开销阈值 | 无上限 |
permission mode |
工具权限模式(如自动批准哪些工具) | 按工具配置 |
effort level |
模型努力等级 | 默认 |
hooks |
工具执行前的拦截/修改/阻止钩子 | 无 |
max_turns 是步数预算,max_budget_usd 是美元预算------二者形成正交的预算控制维度。Anthropic 官方建议:"对生产 Agent 设置预算是良好默认",因为无上限的循环在开放式任务("改进这个代码库")上可能运行极长时间。Agent SDK 的设计选择是:循环可以无限运行,但开发者必须显式选择"无上限",否则应设置预算。
hooks 提供了循环内的拦截点------开发者在工具执行前可以拦截、修改或阻止工具调用,相当于循环每一步的"安全阀"。permission mode 则控制工具的自动批准范围,与 Cline 的 Auto-approve 网格精神同构(见第四章)。
3.6 小结:协议级循环控制的特征
Anthropic 把循环控制能力分布在协议、SDK、Agent SDK 三个递进层级,形成"可组合的约束体系":
| 层级 | 机制 | 控制维度 | 默认值 |
|---|---|---|---|
| 协议层 | stop_reason 七值 |
终止信号语义 | 模型自主 |
| 协议层 | Server Tool 10 次迭代 | 服务端循环上限 | 10 次 |
| SDK 层 | Tool Runner max_iterations |
工具调用回合上限 | 无(需显式设置) |
| Agent SDK 层 | max_turns |
工具调用回合数 | 无上限 |
| Agent SDK 层 | max_budget_usd |
美元开销 | 无上限 |
| Agent SDK 层 | permission mode + hooks |
工具授权与拦截 | 按配置 |
这一体系的特征是多层级、可组合、默认开放但可收紧 ------开发者可以只使用协议层的 stop_reason 自主驱动循环,也可以在 SDK 层加 max_iterations,还可以在 Agent SDK 层叠加 max_turns + max_budget_usd + hooks 形成多层守卫。终止性以模型自主为主,但被多层预算与拦截点兜底。
四、范式二 · 应用级:Cline
Cline(前身为 Claude Dev)是 VS Code 扩展形态的自治编码 Agent,与 Anthropic 在协议层的精细设计形成鲜明对照。Cline 不控制协议------它消费 Anthropic Messages API 或 OpenAI 兼容 API,循环控制的全部能力都在应用层以"策略+阈值+权限网格"的形式实现。
4.1 开环自治的本质:每步全量上下文重发
Cline 的循环结构是典型的"开环自治 Agent":
1. 用户在 VS Code 输入任务描述
2. Cline 构造 prompt:系统提示 + 历史消息 + 已读文件内容 + 工具结果
3. 调用 LLM API,获得响应(含工具调用请求)
4. Cline 在 VS Code 中执行工具(read_file / write_to_file / execute_command / browser_action)
5. 把工具结果作为新的 user 消息追加到历史
6. 回到步骤 2,直到 Cline 自主声明"任务完成"
这一循环的关键性质是:每一步都把累积的全部上下文重新发送给 LLM。系统提示几千 token、历史消息逐步累积、已读文件内容、已执行命令输出------到第 10 步时,单次请求的输入可能膨胀至 100K--200K token。这是 ReAct 风格的扁平历史累积,在成本上具有"输入随轮次二次方膨胀"的劣根性。
Cline 选择这种结构有其工程权衡:它把"哪些信息进入上下文"的决策权交给模型,简化了 Agent 框架本身的实现复杂度。但代价是失去了提示词分级与前缀缓存优化的机会------每一步的 prompt 都因历史变化而缓存失效,全部按原价计费。这与本项目"提示词分级"文章主张的"L0 固化命中前缀缓存"形成正面对照。
4.2 maxRequestsPerTask:硬性步数阈值的电路断路器
Cline 最核心的循环控制参数是 cline.maxRequestsPerTask,默认值为 25。这一参数的工程语义是:
设置 Cline 在需要您输入之前可以采取的连续自动操作次数。
当连续自动批准的请求数达到 maxRequestsPerTask 时,系统触发 auto_approval_max_req_reached 事件,进入两种降级模式之一:
- 手动批准模式(默认):循环不中止,但后续每一步都需要用户显式批准,把循环控制权交还给人。
- Full-auto 模式:直接中止任务执行,避免无限制自动操作。
这是一种典型的**电路断路器(circuit breaker)**模式------当检测到可能的失控信号(连续自动操作过多),主动切断自动通路,强制降级到更安全的模式。社区建议的合理取值:标准任务 10--20,复杂任务 30--50,配合 Auto-approve 的细粒度权限网格使用。
maxRequestsPerTask 的关键性质是与 LLM 自主性无关------它是纯外部阈值,不依赖模型判断"何时该停"。即使模型陷入"让我再试一次"的循环幻想,外部阈值也会在第 25 次请求时强制打断。这是对"模型自主终止"范式的本质性补充。
4.3 Auto-approve 权限网格:人机协同的循环节制
Cline 的 Auto-approve 不是单一开关,而是对工具类别的细粒度权限网格。其完整权限选项如下:
| 权限类别 | 子选项 | 风险等级 | 默认建议 |
|---|---|---|---|
| 读取项目文件 | 仅工作区 / 含工作区外(系统文件等) | 低 → 中 | 自动批准工作区内 |
| 编辑项目文件 | 仅工作区 / 含工作区外 | 中 → 高 | 手动批准(保留每步审查) |
| 执行终端命令 | 安全命令(模型判定非破坏性)/ 全部命令 | 中 → 极高 | 至少保留全部命令手动 |
| 使用浏览器 | 自动获取网页内容 | 中 | 按需 |
| 使用 MCP 服务器 | 连接和使用 MCP 工具 | 可变 | 按需 |
| 最大请求数 | 连续自动操作次数上限 | --- | 10--20(标准任务)至 30--50(复杂任务) |
这一网格的工程价值在于:循环控制的"安全性"维度被分解为可组合的权限决策。开发者可以让 Cline 自由读取代码(低风险,循环中频繁发生)但保留对编辑与命令执行的人工审批(高风险,每步都该审查)。这是一种"按风险分级的人机协同循环"------不是非黑即白的"全自动 vs 全手动",而是把循环中的动作按风险分类,分别授权。
4.4 上下文窗口管理与自动压缩
Cline 还提供 Context Window 设置(如 Sonnet 4.6 输入 200K,Opus 输入 200K,1M 上下文模型可设 1M)。当上下文接近上限时,Cline 触发上下文压缩------把早期历史摘要化以腾出空间。这是循环控制的一个隐性维度:循环的可持续性依赖上下文管理策略。若不压缩,循环在第 N 步因上下文溢出而强制中止;若压缩过度,关键早期信息丢失导致任务质量退化。
这与 Anthropic Agent SDK 的"automatic compaction"是同源机制------都是承认"无限制累积的循环不可能持续"的工程纪律。差别在于:Anthropic 把压缩作为 Agent SDK 的内置能力,Cline 把它作为可配置的应用层参数。
4.5 失败模式:循环失控的真实案例
Cline 的循环控制并非无懈可击。GitHub issue #7585 记录了一个真实的循环失控案例:在 v3.38.1 版本,多名用户报告 Cline 反复执行工具调用与 git checkpoint,直到 VS Code 崩溃。用户的描述是:
"Cline starts looping anything until the chat is corrupt and you lose all chats. Sometimes there is no chat corruption. Instead it git checkpoints until vscode crashes."
这一案例的关键特征是:maxRequestsPerTask 阈值未生效或被绕过------循环没有在 25 步触发断路器,而是持续到系统资源耗尽。这暴露了应用层循环控制的脆弱性:任何阈值机制都依赖框架的正确实现,一旦框架本身有 bug,阈值形同虚设。回退到 v3.37.1 后问题消失,证明这是框架版本引入的回归 bug。
更隐蔽的失控模式是"软循环"------模型不重复完全相同的工具调用(这会被简单的重复检测捕获),而是在"让我再检查一下" "可能我漏了什么" "试试另一种方式"的语义包装下持续调用不同工具。这种循环不会被基于工具调用哈希的去重逻辑识别,是 maxRequestsPerTask 最需要兜底的场景。
4.6 小结:应用级循环控制的特征
Cline 的循环控制全部位于应用层,其核心机制可总结如下:
| 机制 | 控制维度 | 默认值 | 性质 |
|---|---|---|---|
maxRequestsPerTask |
连续自动操作步数上限 | 25 | 电路断路器 |
| Auto-approve 权限网格 | 工具类别授权 | 全手动 | 风险分级人机协同 |
| Context Window 设置 | 上下文容量上限 | 按模型 | 资源约束 |
| 自动压缩 | 历史摘要化 | 内置 | 可持续性保障 |
| 任务完成判定 | 模型自主声明 | --- | 模型自主终止 |
| 用户取消 | 人工中断 | --- | 兜底人工干预 |
Cline 的特征是应用层策略组合、默认保守、依赖人工审批作为最终安全阀 。其优势是落地简单、对模型协议无要求(任何 OpenAI 兼容 API 均可);其代价是失去了协议层的精细控制能力(无法利用 stop_reason 的细分语义),循环上限的语义粒度较粗(只数请求次数,不区分请求性质)。
五、范式三 · 规则级:rule_match
回到本项目的设计:rule_match 既非 Anthropic 的协议级 stop_reason(不修改 API 协议),也非 Cline 的应用级步数阈值(不依赖粗粒度请求计数)。它是介于二者之间的第三条路径------用确定性规则集评估每步执行结果,输出 continue/stop/error 三态判定,零 LLM 成本。
5.1 规则化循环控制
rule_match 适合在已有工作流引擎之上叠加确定性循环控制,作为对前两者的"判停层增强"。其规则集结构(来自设计文档):
json
{
"rules": [
{ "name": "exit_error",
"condition": { "field": "exec_result.ok", "op": "==", "value": false },
"action": "error", "reason": "CLine 执行失败" },
{ "name": "done_marker",
"condition": { "field": "exec_result.text", "op": "contains_any",
"value": ["完成", "DONE", "任务结束", "已处理"] },
"action": "stop", "reason": "检测到完成标记" },
{ "name": "need_more",
"condition": { "field": "exec_result.text", "op": "contains_any",
"value": ["需要", "下一步", "继续", "待处理"] },
"action": "continue", "next_prompt_hint": "根据上一步结果继续执行" },
{ "name": "max_steps",
"condition": { "field": "step_count", "op": ">=", "value": 10 },
"action": "stop", "reason": "达到最大步数" },
{ "name": "default",
"condition": "true",
"action": "stop", "reason": "默认终止" }
],
"guards": { "max_steps": 10, "timeout_sec": 300 }
}
这一规则集的设计哲学是:循环的"是否继续"由规则评估而非 LLM 判定 ,把"模型自主终止"升级为"规则判定终止 + 模型生成辅助"。default → stop 是关键的吸收态------任何未被规则显式匹配的状态都默认终止,保证有限状态机必有吸收态,循环不可能发散。
5.2 与 stop_reason 的同构与互补
rule_match 的输出 action 与 Anthropic stop_reason 在语义上构成同构对照:
rule_match action |
对应 stop_reason |
语义 |
|---|---|---|
continue |
tool_use |
需要继续执行(提供 hint,类比提供 tool_result) |
stop |
end_turn |
任务自然完成 |
error |
refusal / max_tokens |
异常终止,需降级 |
(内置 max_steps) |
pause_turn |
达上限暂停 |
差别在于:stop_reason 是模型自主产出的协议信号,rule_match action 是规则评估产出的应用信号。二者可以叠加------本项目设计中 cline_execute 内部仍会产生 stop_reason,但外层的 rule_match 做二次判定。这是一种"双层循环控制":协议层 stop_reason 表征模型意图,应用层 rule_match 表征任务实际状态,二者一致时正常流转,不一致时以 rule_match 为准(如模型 end_turn 但 rule_match 判定未完成时仍 continue)。
5.3 与 max_turns 的对照
rule_match 的 max_steps 守卫与 Anthropic Agent SDK 的 max_turns 在工程目的上同构------都是步数阈值兜底。但二者有本质差别:
| 维度 | max_turns |
rule_match max_steps |
|---|---|---|
| 触发单位 | 工具调用回合 | 规则评估次数(与 LLM 调用解耦) |
| 触发前判停 | 仅模型 end_turn |
多条规则首匹配 |
| 触发后行为 | 循环直接结束 | stop 强制结束 |
| 与 LLM 关系 | 每回合消耗 1+ 次 LLM | 评估本身零 LLM |
| 可配置性 | 单一阈值 | 规则集外部化、可演化 |
rule_match 的关键优势是判停的多规则性 ------除了 max_steps 兜底,还有 done_marker(语义完成标记)、need_more(继续信号)、exit_error(执行失败)等多个判停点。这使得循环在多数情况下由语义规则而非步数阈值终止------max_steps 是兜底而非主路径。对照 max_turns 仅在单一阈值上判停,规则化路径的判停多样性更接近 Ashby 的"必要多样性"要求(见 7.5)。
5.4 与 Auto-approve 的精神共鸣
rule_match 与 Cline Auto-approve 在精神上共鸣------都是用确定性配置替代"模型自主决策"。但应用对象不同:
- Auto-approve 针对"动作授权"------循环中每步动作是否被允许执行。
rule_match针对"循环判停"------循环中每步后是否继续。
二者可以叠加:rule_match 判定 continue 后,下一步 cline_execute 仍可走 Auto-approve 网格决定具体动作授权。这是"判停规则化 + 动作授权网格化"的双重确定性控制------循环的两个核心问题(何时停、每步做什么)都被纳入规则化框架。
5.5 三种范式的统一对照表
把三种循环控制范式并列,可得统一对照(注意:本表沿判据轴 对比"范式",与 6.1 沿层级轴对比"协议---SDK---应用"互补不冲突):
| 维度 | Anthropic(协议+SDK) | Cline(应用层) | rule_match(规则化) |
|---|---|---|---|
| 主判停机制 | 模型 end_turn |
模型任务完成声明 | 规则集首匹配 |
| 兜底机制 | max_turns / max_budget_usd |
maxRequestsPerTask |
max_steps + default→stop |
| 决策权归属 | 神经主导 | 神经主导 | 符号主导 |
| LLM 成本(判停本身) | 0(协议字段) | 0(计数器) | 0(规则评估) |
| 判停多样性 | 低(单值 end_turn) |
低(单点完成声明) | 高(多规则首匹配) |
| 可证明终止性 | 否(依赖模型) | 否(依赖模型+阈值) | 是(FSM 有吸收态) |
| 与上下文管理耦合 | 低(协议层解耦) | 高(每步全量重发) | 低(与 LLM 调用解耦) |
| 适配性 | 强依赖 Anthropic API | 适配任意 OpenAI 兼容 API | 适配任意执行端(CLine/SK/MCP) |
三种范式没有绝对的优劣,只有适用场景的差异:Anthropic 适合在自家生态内构建精细 Agent;Cline 适合在 VS Code 内快速搭建可视化编码助手;rule_match 适合在已有工作流引擎之上叠加确定性循环控制,作为对前两者的"判停层增强"。
六、横向对比:层级、预算与安全边界
前三章沿判据轴剖析了三种范式,本章回到层级轴与"预算/安全"两个评估维度做横向对比。
6.1 三层循环控制范式:协议---SDK---应用
把 Anthropic 与 Cline 的实践并列,沿层级轴可提炼出循环控制的三层范式(与 5.5 沿判据轴的范式对照互补):
| 层级 | 关注点 | Anthropic 实现 | Cline 实现 |
|---|---|---|---|
| 协议层 | 循环终止信号语义 | stop_reason 七值、pause_turn |
不控制(依赖 API) |
| SDK 层 | 循环执行抽象与预算 | Tool Runner max_iterations、Agent SDK max_turns/max_budget_usd/hooks |
不分层(应用直接驱动) |
| 应用层 | 工具授权、步数阈值、上下文管理 | (由开发者基于 SDK 构建) | maxRequestsPerTask、Auto-approve 网格、Context Window |
二者代表两种工程取向:Anthropic 自上而下把控制能力下沉到协议与 SDK,Cline 自下而上在应用层组装策略------前者强依赖自家生态但层级清晰,后者适配任意 API 但失去协议层精细控制。rule_match 则可视为在这一层级轴的"应用层之上"再叠加一层规则判定层,独立于执行端实现。
6.2 预算控制的计量单位对照
不同循环控制系统对"预算"的计量单位不同,反映了各自的关注点:
| 系统 | 计量单位 | 优势 | 局限 |
|---|---|---|---|
Anthropic max_turns |
工具调用回合数 | 与任务复杂度直接相关 | 不区分单回合成本差异 |
Anthropic max_budget_usd |
美元 | 直接对应财务成本 | 依赖准确计费、汇率波动 |
Cline maxRequestsPerTask |
API 请求次数 | 简单可计数 | 不区分请求大小(1K vs 100K token 同算一次) |
Anthropic max_tokens(单次) |
单次响应 token | 防止单次输出失控 | 不约束总循环成本 |
rule_match max_steps |
规则评估次数 | 与 LLM 调用解耦 | 需与 LLM 调用次数关联 |
max_budget_usd 是最贴近成本的预算单位,但实现复杂(需要实时计费)。maxRequestsPerTask 最简单,但粒度粗------一次 1K token 的 read_file 与一次 200K token 的全量上下文请求同算一次,对成本控制不够精确。本项目的 rule_match 把预算以"规则评估次数"计量,与 LLM 调用解耦------rule_match 本身零 LLM 成本,预算实际由"循环中每步 LLM 调用次数 = cline_execute 1 次 + provide_prompt 0 或 1 次"决定,可推导为最坏 2 × max_steps 上界。
6.3 安全边界:permission mode vs Auto-approve 网格
循环中的"每步动作是否被授权"是安全性的核心。Anthropic Agent SDK 的 permission mode 与 Cline 的 Auto-approve 网格是两种实现路径:
- Anthropic :通过
hooks在工具执行前拦截,开发者可编程决定批准/修改/阻止。这是"可编程的安全边界"------灵活但需要代码。 - Cline:通过 UI 配置的权限网格,按工具类别(读/写/执行/浏览器/MCP)授权。这是"配置驱动的安全边界"------简单但不可编程。
二者在精神上同源------都是承认"循环中的动作不应无差别放行"。差别在于可编程性:Anthropic 的 hooks 可以基于运行时上下文动态决策(如"工作时间内自动批准,工作时间外需人工"),Cline 的网格是静态配置。本项目的 cline_execute 节点采用 auto_approve=true 传递给 ClineClient,是在简化场景下的工程取舍------生产化时应当叠加类似 Auto-approve 网格的细粒度授权。
七、学术视角:Agent 循环的理论根基
三种范式在学术上同源。本章从 ReAct、控制论、有限状态机、神经-符号混合、必要多样性五个视角,为"循环何时停、停在哪、由谁判停"建立理论根基,并回看三种范式各自落在理论谱系的何处。
7.1 ReAct:Thought-Action-Observation 循环
Yao et al.(2022)提出的 ReAct(Reasoning + Acting)是 Agent 循环的范式性工作。其循环结构为 Thought → Action → Observation 三元组:
- Thought:模型对当前状态的推理,决定下一步动作。
- Action:模型选择并调用工具。
- Observation:工具执行结果回灌为下一轮的输入。
ReAct 的贡献是显式化了"推理"与"行动"的交织------模型不再只输出动作,而是先输出对动作的推理,再执行动作。这一交织结构成为后续所有 Agent 循环(包括 Anthropic tool_use 循环与 Cline 自治循环)的共同范式。
ReAct 的局限也是 Agent 循环的共性问题:每轮携带完整历史导致上下文与成本随轮次膨胀,且终止性依赖模型自主判断。本文剖析的 Anthropic 与 Cline 都在 ReAct 基础上做了工程化改进------Anthropic 用 stop_reason 协议化终止信号,Cline 用 maxRequestsPerTask 兜底步数,rule_match 则用规则集把判停权从模型手中移出。
7.2 控制论:反馈回路与稳态
Wiener(1948)的控制论(Cybernetics)把"反馈回路"作为自适应系统的核心机制:系统输出反馈为输入,使系统趋向稳态。Agent 循环正是反馈回路的实例------工具执行结果作为反馈信号,调整模型下一步的输出。
控制论还提供了"稳态"的概念:一个反馈系统应当趋向某个稳态而非发散。在 Agent 语境下,稳态即"任务完成、循环结束"。但与恒温器等物理反馈系统不同,Agent 的稳态判据由模型自主判断,缺少物理不变式的硬约束。这是 Agent 循环可能发散(无限循环)的根因------缺少强制稳态判据。
控制论的解法是"负反馈+阈值":当系统偏离稳态超过阈值时强制干预。这对应 Cline 的 maxRequestsPerTask(步数阈值)与 Anthropic 的 max_budget_usd(成本阈值)。本项目的 rule_match 则把"稳态判据"从模型自主判断改为规则评估------用确定性条件(如 text contains "完成")作为稳态信号,把控制论的反馈回路形式化为可机器判读的规则集。
7.3 有限状态机与终止性证明
Manna(1974)的《Mathematical Theory of Computation》把程序终止性归约为"是否存在一个良基函数,使每次状态转移都使该函数递减"。这一形式化框架直接适用于 Agent 循环的终止性分析:
- 若循环的每一步都使某个良基函数递减 (如剩余预算、剩余步数),则循环必然终止------这是
max_turns与maxRequestsPerTask的形式化保证。 - 若循环的终止依赖模型判断,则良基函数不存在------循环可能发散,需要外部干预。
rule_match 的设计在终止性上具有特殊性:其规则集是显式的有限状态机,每条规则对应一个状态转移,max_steps 规则提供良基函数(剩余步数递减),default → stop 规则保证有限状态机必有吸收态。这使 rule_match 控制的循环在形式化意义上是可证明终止的------只要规则集正确配置,循环不可能发散。这是规则化循环控制相对于模型自主判定的本质优势:终止性可被形式化证明,而非依赖经验观察。
7.4 决策权分配:神经-符号视角
循环控制的核心张力是"决策权归谁"------模型自主判定(神经)还是规则判定(符号)。Garcez & Lamb(2020)的神经-符号混合(Neurosymbolic AI)主张二者各司其职:
- 符号规则承担确定、可验、零成本的判断(如"任务完成标记是否出现")。
- 神经生成承担灵活、泛化、有成本的判断(如"是否需要语义重规划")。
把这一视角应用于循环控制:
| 决策类型 | 归属 | 范例 |
|---|---|---|
| "是否继续循环"的常规判定 | 符号规则 | rule_match 评估 exec_result |
| "是否需要重规划"的语义判定 | 神经生成 | rule_needs_replan 触发 SK 兜底 |
| "任务是否完成"的标记判定 | 符号规则 | text contains "完成" |
| "任务是否真的达成目标"的语义判定 | 神经生成(可选) | 调用 LLM 验收 |
Anthropic 的 stop_reason 协议是"神经主导+符号兜底"------以模型 end_turn 为主,max_turns/max_budget_usd 为符号兜底。Cline 是"神经主导+符号阈值+人工兜底"------以模型自主为主,maxRequestsPerTask 为符号阈值,用户取消为最终兜底。本项目的 rule_match 是"符号主导+神经兜底"------以规则评估为主,仅在 rule_needs_replan 触发时调 LLM 兜底。三者代表了神经-符号谱系上的不同权衡点。
7.5 自治系统的可控性:必要多样性
更宏观地看,Agent 循环控制是"自治系统可控性"问题的实例。Ashby(1956)的《An Introduction to Cybernetics》提出"必要多样性定律"(Law of Requisite Variety):控制系统的多样性(可采取的状态数)必须不少于被控系统的多样性,才能实现有效控制。
在 Agent 语境下,被控系统是"任务执行的所有可能状态"(成功、失败、循环、偏离、超时...),控制系统是"循环控制机制的所有可能响应"(继续、停止、降级、人工介入...)。若控制系统只有"继续/停止"两态,则无法处理"循环中偏离但未失败"的状态------这是简单 max_turns 阈值的局限。rule_match 的规则集通过多规则首匹配评估,提供了更丰富的响应多样性(continue + next_prompt_hint、stop + reason、error + 降级路径),更接近必要多样性定律的要求。
八、工程落地启示
8.1 多层守卫:协议级 + 规则级 + 应用级
循环控制最稳健的工程实践是多层守卫------任一层失效时其他层兜底。本项目的 agent-loop.json 增强后即体现了这一思想:
协议层(Anthropic) → stop_reason 自然终止(end_turn)
↓ 协议信号不可靠时
规则层(rule_match) → 规则集评估 continue/stop/error
↓ 规则失效(损坏)时
应用层(Cline) → maxRequestsPerTask 兜底
↓ 自动模式失效时
人工层(用户取消) → AgentLoopFunction.CheckCancellation
四层守卫形成纵深防御:协议层处理"模型自主完成"的常态,规则层处理"语义判停"的中频情况,应用层处理"步数兜底"的低频兜底,人工层处理"框架完全失效"的极端情况。每一层都不是必须的,但每一层都为整体鲁棒性提供边际贡献。
8.2 可观测性:循环每步的成本归因
循环控制系统必须有可观测性,否则无法判断"循环是否健康"。本项目的可观测性设计来自"提示词分级"一文的主张,延伸到循环层:
- 每步 LLM 调用次数 :
provide_prompt(0 或 1)+cline_execute(1)+rule_match(0)。 - 每步成本归因:L0 缓存命中(0.1×)、L1 一次性生成(首次 1×+3×)、L2 模板/兜底(0 或 1×+3×)、CLine 执行(1×+3×)。
- 规则命中率 :各
rule_match规则的命中频次分布,揭示任务执行的常态模式。 - 兜底触发率 :
rule_needs_replan触发 SK 兜底的比例,揭示模板覆盖度。
这些指标把"循环是否健康"从主观感受转化为可度量的工程信号。Anthropic Agent SDK 的 ResultMessage 提供了 token usage 与 cost 的最终统计;Cline 在 UI 显示每步与累计成本------这些都是可观测性的工程实现,本项目设计应当复用。
8.3 退化路径:从规则到 LLM 到人工
循环控制系统的退化路径必须显式设计:
rule_match规则集损坏 :使用内置默认规则(default → stop),告警但不崩溃。provide_promptSK 生成失败:重试 1 次(temperature=0),仍失败退纯模板。cline_execute执行失败 :rule_match命中exit_error→error→sk_plan兜底分支。- CLine 模块不可用 :
cline_execute节点on_error → sk_plan,降级到 MCP 路径。 max_steps达上限 :stop强制结束,避免无限循环。
退化路径的关键性质是"规则失效时降级到生成,生成失效时降级到人工"------这与"提示词分级"一文第六节"错误降级链"一致,是统一工程纪律的延续。
8.4 反模式
列举四种循环控制反模式:
- 开环自治无阈值:依赖模型自主判停,无任何步数或预算兜底。Cline 早期版本与未配置的 Anthropic Agent SDK 默认即此模式。后果:循环可能无限发散。
- 隐式终止依赖:循环终止依赖某个未被显式声明的不变式(如"模型总会在合理步数内完成")。后果:当不变式被违反时系统无应对。
- 无预算护栏:只设步数阈值不设成本阈值,模型可在每步消耗巨量 token。后果:步数未达上限但成本已失控。
- 判停单点化 :仅依赖单一判据(如只看
max_turns或只看模型end_turn)。后果:该判据失效时无兜底。判停应当是规则集而非单规则。
识别这些反模式的能力,是循环控制工程成熟度的标志。
九、结语
大模型 Agent 的能力来自循环调用,但 Agent 的工程化边界条件也来自循环控制。本文以"判停权谱系"为框架,剖析了三种代表性范式:Anthropic 在协议层以 stop_reason 七值语义提供细分终止信号,在 SDK 层以 max_turns/max_budget_usd/hooks 提供可组合约束;Cline 在应用层以 maxRequestsPerTask(默认 25)的电路断路器与 Auto-approve 权限网格实现策略级控制;本项目设计的 rule_match 以规则集首匹配评估提供第三条路径------规则化循环控制。
三者在学术上同源:ReAct 范式(Yao et al. 2022)奠定 Agent 循环的 Thought-Action-Observation 结构,控制论(Wiener 1948)提供反馈回路与稳态的视角,有限状态机终止性(Manna 1974)提供形式化证明工具,神经-符号混合(Garcez & Lamb 2020)与必要多样性定律(Ashby 1956)提供决策权分配与可控性的谱系。在工程上,三者互补:协议级提供精细信号,应用级提供落地策略,规则级提供可证明终止性。
循环不是 Agent 的功能,而是 Agent 的边界条件------控制了循环,才控制了 Agent。本文的核心主张可表述为:循环控制必须从"模型自主"升级为"多层守卫",从"单点判停"升级为"规则集评估",从"经验观察"升级为"形式化可证明终止性"。这是从"Agent 能用"到"Agent 可工程化"的结构性前提------没有循环控制,就没有 Agent 系统;正如没有不变式,就没有程序正确性。
关键决策速查表
| 场景 | 推荐策略 | 核心动作 |
|---|---|---|
| 单次工具调用任务 | Anthropic stop_reason 协议级 |
依赖 end_turn,无需复杂守卫 |
| 短链编码任务 | Cline + maxRequestsPerTask=10--20 |
步数断路器 + Auto-approve 网格 |
| 长链复杂任务 | Anthropic Agent SDK + max_turns + max_budget_usd |
双重预算(步数+美元)+ hooks 拦截 |
| 生产级 Agent | 协议+规则+应用多层守卫 | stop_reason + rule_match + maxRequestsPerTask + 人工取消 |
| 循环判停决策 | rule_match 规则集 |
首匹配评估,default→stop 保证吸收态 |
| 步数兜底 | max_steps 守卫(默认 10) |
形式化终止保证,FSM 良基函数递减 |
| 预算控制 | max_budget_usd |
直接对应财务成本,生产 Agent 默认应设 |
| 动作授权 | Auto-approve 权限网格 | 按风险分级,至少保留命令执行人工审批 |
| 上下文管理 | 自动压缩 + Context Window 上限 | 避免循环因上下文溢出强制中止 |
| 循环失控故障 | 降级链:规则→生成→人工 | rule_match 失效用默认规则,SK 失败退模板,CLine 失败转 sk_plan |
| 判停多样性 | 多规则首匹配 | exit_error/done_marker/need_more/max_steps/default 五类信号 |
| 形式化终止性 | 规则集 + default→stop |
有限状态机必有吸收态,循环不可能发散 |
| 反模式识别 | 开环无阈值/隐式终止/无预算/单点判停 | 任一征兆即应增加守卫层 |