news 2026/9/25 2:54:24

IronClaw Reborn 轻量 Agent Loop 契约:父循环的决策权与执行权是如何分离的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
IronClaw Reborn 轻量 Agent Loop 契约:父循环的决策权与执行权是如何分离的
  • 人工智能
  • AI 应用
  • 交互助手
  • AI Agent

【免费下载链接】ironclaw

IronClaw is an Agent OS focused on privacy, security and extensibility

项目地址:https://gitcode.com/gh_mirrors/iro/ironclaw
点击查看免费下载

本文围绕 IronClaw Reborn 的轻量 Agent Loop 参考契约(lightweight-agent-loop.md)展开,讲清这个默认随项目交付的父循环(parent loop)在 IronClaw 宿主契约内如何运行:它只负责“何时问模型、何时请求可见能力”,而能力能否执行、如何执行完全由宿主侧的 CapabilityHost、审批与授权体系裁决。读完本文,你将掌握该循环的完整状态机、Reply | CapabilityCalls父协议、批量执行与挂起/恢复机制、可见能力面(visible capability surface)的门控策略,并能对照仓库源码定位每一环节的真实契约类型与测试用例。

1. 定位:默认交付的轻量 Agent Loop,而非内核行为

契约文档开篇即给出定位:定义 Reborn 默认交付的轻量 Agent Loop,作为参考循环实现(reference loop implementation),而不是内核行为。它借鉴了badlogic/pi-mono/packages/agent的循环机制:

stream assistant -> execute tool/capability calls -> append tool results -> repeat until reply, blocked, failed, or interrupted

但有两个明确的边界约束:

  • 它不是对pi-mono的依赖,也不导入pi-mono的授权(authority)语义,而是一个运行在 IronClaw 宿主契约之内的 Reborn 原生循环;
  • 它可以打包为内置的agent_loop扩展,也可以实现为随附的参考循环 crate。无论哪种形态,它只能获得一个窄化的、经内核中介的宿主门面(host facade),永远拿不到原始服务管理器,也永远无法绕过CapabilityHost/策略检查。

该契约声明依赖同目录下的多个兄弟契约(仓库中均已存在):agent-loop-protocol.md、runtime-workflows.md、capabilities.md、run-state.md、approvals.md、events.md、runtime-selection.md、runtime-profiles.md。

2. 核心不变量:循环决定“何时问”,宿主决定“如何执行”

契约的核心不变量只有两句话:

The lightweight loop decides when to ask the model and when to request visible capabilities. The host decides whether and how those capabilities execute.

循环不得绕过以下内核管理器:

CapabilityHost RunStateManager ConversationManager ApprovalManager AuthFlowManager RuntimeDispatcher EventStreamManager ResourceGovernor

契约进一步强调:这个循环是父循环机制(parent-loop mechanic),而不是授权/运行时层。它由项目官方交付这一事实,可能会通过宿主策略影响其信任上限(trust ceiling),但交付身份本身不授予任何授权。

3. 父协议:顶层只有Reply | CapabilityCalls两个分支

面向宿主的父协议保持极简:

Reply | CapabilityCalls

Provider 原生的 tool calling 可以编码CapabilityCalls,但循环必须在执行前把 provider 的 tool call归一化为 IronClaw capability call。

以下内容不是顶层父协议分支:

CodeAct QuickJS script shell job subagent experiment

它们是显式的能力(capability),例如:

action_script.run(...) script.run(...) experiment.exec(...) spawn_subagent(...) create_job(...)

从源码结构看,这一“两个顶层分支”的约定在契约 crate 中有对应的枚举定义:ironclaw_loop_contracts/src/host/model.rs 中的ParentLoopOutput只有两个变体——AssistantReply与CapabilityCalls(Vec<CapabilityCallCandidate>),其中每个CapabilityCallCandidate携带activity_id、surface_version、capability_id、input_ref等字段(model.rs),与契约要求的“调用前分配稳定活动身份”相吻合。

4. 循环机制:从开始运行到停止的完整状态机

契约第 4 节给出了完整的机制描述(原文流程):

begin run load durable thread snapshot build instruction bundle load visible capability surface while run is active: process queued steering/follow-up messages stream one assistant response persist assistant milestone when finalized if response is Reply: complete run stop if response has CapabilityCalls: execute call batch sequentially or in parallel according to policy append capability-result messages continue if a call requires approval/auth/resource wait: checkpoint loop block run stop until resumed if interrupted/cancelled/failed: transition run state stop

这里有一个关键的双通道设计:能力结果在转录记录中携带严格的LoopSafeSummary,用于可移植的元数据、日志、检查点和回退重放;而当宿主拥有更丰富的面向模型的恢复信息时,它可以向 tool-result 引用附加一个有界的ModelVisibleToolObservation侧信道。该观察值是模型可见的不可信工具输出,不是LoopSafeSummary的替代品,且在回放到模型前必须经过校验/脱敏。

仓库源码印证了这两个类型都是真实存在的一等契约类型:

  • LoopSafeSummary定义在 ironclaw_loop_contracts/src/host/refs.rs;
  • ModelVisibleToolObservation定义在 ironclaw_loop_contracts/src/model_observation.rs,带schema_version、status、summary、detail、artifacts、recovery、trust字段,并有硬性边界:摘要最多 512 字节、artifacts/repairs/input issues 各最多 16 条(model_observation.rs),validate()方法在跨边界时强制校验 schema 版本与长度。

契约还给出了等价伪代码:

loop { let pending = host.take_pending_messages(run).await?; context.append(pending); let bundle = host.build_instruction_bundle(run).await?; let surface = host.visible_capabilities(run).await?; let assistant = loop_impl.stream_assistant(context, bundle, surface).await?; host.append_milestone(assistant.clone()).await?; match assistant.output { Reply(reply) => { host.complete_run(reply).await?; break; } CapabilityCalls(calls) => { let results = loop_impl.execute_batch(run, calls).await?; context.append(results.messages); host.checkpoint(run, context.summary()).await?; } } }

循环的运行时实现落在 ironclaw_agent_loop crate 中,其executor模块下按职责拆分为capabilities.rs、checkpoint.rs、model.rs、prompt.rs、mapping.rs等文件,并配套了成体系的 executor 测试。

5. 宿主门面:AgentLoopHost与端口化落地

循环接收的是AgentLoopHost门面,而不是原始管理器。契约中给出的 trait 形态:

pub trait AgentLoopHost { async fn load_thread_snapshot(&self, run: RunHandle) -> Result<ThreadSnapshot>; async fn build_instruction_bundle(&self, run: RunHandle) -> Result<InstructionBundle>; async fn visible_capabilities(&self, run: RunHandle) -> Result<VisibleCapabilitySurface>; async fn stream_model(&self, request: ModelStreamRequest) -> Result<ModelStream>; async fn invoke_capability(&self, request: LoopRequest) -> Result<CapabilityOutcome>; async fn append_milestone(&self, milestone: TranscriptMilestone) -> Result<()>; async fn publish_event(&self, event: RuntimeEvent) -> Result<()>; async fn checkpoint(&self, checkpoint: LoopCheckpoint) -> Result<()>; async fn block_run(&self, blocked: BlockedRun) -> Result<()>; async fn complete_run(&self, output: LoopOutput) -> Result<()>; async fn fail_run(&self, error: LoopError) -> Result<()>; }

契约强调:该门面“组合”了更底层的各类服务,但不把所有权移入循环。

从源码结构看,当前仓库把这个门面进一步细化为一组按契约簇划分的端口(port),统一在 ironclaw_loop_contracts/src/host/mod.rs 中重导出,例如:

  • LoopCapabilityPort/LoopRequest/LoopRequestBatch/VisibleCapabilitySurface(host/capability.rs);
  • LoopModelPort/LoopModelRequest/LoopModelResponse/ParentLoopOutput(host/model.rs);
  • LoopCheckpointPort/LoopCheckpointKind(host/checkpoint.rs);
  • LoopTranscriptPort/BeginAssistantDraft/FinalizeAssistantMessage(host/transcript.rs);
  • LoopInputPort/LoopProgressPort/AgentLoopDriverHost(host/input.rs、host/progress.rs)。

其中LoopModelRequest(model.rs)携带messages、surface_version、iteration(发起该 provider 调用的循环迭代序号)与可选的tool_choice约束——这正是契约第 4 节“每次模型调用前请求带版本能力面”的工程化体现。该契约还有专门的调用方级测试:ironclaw_turns/tests/agent_loop_host_contract.rs 通过宿主门面驱动整个循环。

6. 能力工具封装与capability_info合成工具

可见能力会变成当前运行专用的、紧凑的模型可见工具 schema:

CapabilityDescriptor -> model-visible name -> description -> input schema -> concurrency policy -> result shaping hints

对应源码类型CapabilityDescriptorView携带capability_id、provider、runtime、safe_name、safe_description、description_trust与parameters_schema(host/capability.rs),并由此派生出面向 provider 的ProviderToolDefinition。

循环还暴露一个合成的只读 provider 工具capability_info:用于渐进式披露(progressive disclosure)——当模型需要当前可见能力的名称、必填字段、副作用说明或完整输入 schema 时调用它。它不经过HostRuntime分发,也无法检视当前可见面之外的能力。仓库中该功能有独立实现与测试:ironclaw_loop_host/src/capability_info.rs、synthetic_capability.rs 以及 capability_info_tests.rs。

工具执行是对CapabilityHost的封装,完整调用链为:

model tool call -> normalize to LoopRequest -> CapabilityHost.invoke_json(...) -> CapabilityAccessManager action-time authorization -> Approval/Auth/Resource gates if needed -> RuntimeDispatcher.dispatch_json(...) -> capability result -> toolResult/capability-result message

契约划出一条硬边界:循环不得直接调用RuntimeDispatcher,RuntimeDispatcher只接收已经授权完成的调用。

7. 批量执行:默认并行,独占资源强制串行

同一模型响应中发出的多个调用默认并行调度。顺序执行的策略措辞仍保留在内部执行与可观测性词汇中,但规范执行器不再为新的模型发出批次选择它。宿主端口仍可为具体调用集中的运营风险要求有序批次入口——有序入口会设置stop_on_first_suspension,外层装饰器必须保持调用者顺序分发,不得把批次重新扇出。

契约给出的规则:

  • 宿主能力策略可强制某个调用或整个批次串行执行;
  • 每个调用独立授权;
  • 并行批次执行不是批量授权;
  • 多个调用需要审批时,审批提示应保持来源顺序;
  • 文件系统写入、shell/进程调用及其他独占资源,可由描述符/配置档策略指定串行;
  • 结果消息应按 assistant 来源顺序追加,除非后续契约明确选择完成顺序。

推荐的批次选择逻辑:

if any call requires exclusive/sequential execution: execute whole batch sequentially else: preflight/authorize each call and execute approved calls concurrently

这一机制在源码中有对应测试:executor/tests/parallel_batch.rs 专门验证并行批次行为,capability_results.rs 验证结果消息的追加语义。

8. 挂起与恢复:审批/认证/资源等待不是普通工具错误

随附的参考循环必须支持结构化挂起(structured suspension)。能力结果(outcome)类型:

pub enum CapabilityOutcome { Completed(CapabilityResult), ApprovalRequired(ApprovalGate), AuthRequired(AuthGate), ResourceBlocked(ResourceGate), Failed(CapabilityError), }

遇到ApprovalRequired:

checkpoint loop state -> ApprovalManager.open_pending_gate -> RunStateManager.blocked(approval) -> EventStreamManager.publish(approval_needed) -> stop loop until resume

遇到AuthRequired:

checkpoint loop state -> AuthFlowManager.begin -> RunStateManager.blocked(auth) -> TransportAdapter presents auth flow -> stop loop until secret lease/auth completion

恢复(resume)流程:

RunStateManager.resume -> reload checkpoint and durable transcript snapshot -> rebuild instruction/capability surface -> continue or replay the pending invocation using idempotent invocation fingerprinting

恢复依赖幂等调用指纹(invocation fingerprinting)来决定是继续还是重放待处理调用。契约还给出务实的降级说明:MVP 纯本地实现可以在短审批期间阻塞一个 promise,但托管(hosted)与持久(durable)会话要求显式挂起。源码侧,executor/tests/gates.rs 与 auth_resume.rs 分别覆盖审批/资源门控与认证恢复路径,CapabilityOutcome类型的实际使用可在 ironclaw_host_runtime 的能力响应处理器及其契约测试中查证。

9. 工作上下文 vs 持久转录:谁是事实源

循环可以维护一个内存中的工作上下文(类似AgentMessage[]),但它不是事实源。事实源划分如下:

working context = turn-local projection ConversationManager = durable transcript source of truth RunStateManager = run lifecycle source of truth EventStreamManager = realtime delivery source ProjectionReducer = derived read models

契约给出持久化行为指引表(逐行继承原文):

Loop eventDurable behavior
assistant stream start/updatelive event only, optional ephemeral partial
assistant finalizedtranscript milestone
capability batch startrun/event milestone
capability call start/update/endcapability audit + live progress
capability result messagetranscript milestone
turn boundarycheckpoint/milestone
blocked approval/auth/resourcerun-state transition + event
final replytranscript milestone + run complete

并有一条硬约束:实时流丢失不得损坏持久转录状态(Realtime stream loss must not corrupt durable transcript state)。这意味着流式增量只是“活的投影”,而转录里程碑(milestone)写入才是可恢复的持久事实。

10. 引导(Steering)与后续(Follow-up)双队列

循环可支持两个宿主拥有的输入队列:

  • steering messages(引导消息):在循环活跃期间、下一次 assistant 响应之前注入;
  • follow-up messages(后续消息):在循环本应停止后被消费,从而触发另一个 assistant 轮次。
active run receives steering -> append as pending message before next model call agent would stop, follow-up exists -> append follow-up and continue

两个队列必须保留作用域(scope)与顺序,且不得绕过运行状态规则。远程/托管部署还必须遵守每线程单活跃运行(one-active-run-per-thread)与传输层授权约束。

11. 动态能力面:版本化、门控与“仅示能”选择

可见能力面在扩展激活、认证完成、授权变更或配置档变化之后都可能改变。循环应在每次模型调用前请求带版本的能力面:

visible_capabilities(run) -> { version, capabilities }

若版本变化,循环重新生成模型可见工具 schema。循环本身不直接发现扩展。即便能力已可见,操作时授权(action-time authorization)仍然必需。源码中VisibleCapabilitySurface结构正携带version(CapabilitySurfaceVersion)与descriptors,并额外区分了callable_capability_ids:在渐进式工具披露下,“广告集”(token 经济考虑收窄过的子集)与“可调用集”可以不同,调用时授权必须针对更宽的“可调用”集合校验(host/capability.rs)——这是对契约“可见面是推理辅助而非授权捷径”的直接落实。

11.1 可见面的过滤管线与“仅示能”原则

循环应避免隐藏的策略启发式,例如:

if estimated tool calls >= 5, force ActionScript if task mentions tests, force shell

取而代之的做法是:宿主在每次模型调用前塑造模型可见面,模型从清晰的语义示能(affordance)中选择,宿主再通过正常能力策略执行或阻断这些请求:

visible surface = CapabilityCatalog filtered by DeploymentMode filtered by RuntimeProfile filtered by tenant/org/user/project grants filtered by auth/installation state filtered by run/thread policy rendered as LlmToolViews

契约给出“该隐藏还是该暴露”的判断表(逐行继承原文):

ContextHide or expose?Reason
hosted multi-tenant sessionhideLocalHostshell/file capabilitiesprovider host access is never valid
local safe profile before write approvalexpose write capability with ask policyuser may approve writes
no GitHub extension installedhide GitHub provider capabilities or expose install/auth capability onlyavoid pointless API retries
GitHub installed but token expiredexpose GitHub capability as auth-blockable if auth flow can resumemodel can request semantic action; host opens auth gate
ActionScript disabled by tenant policyhideaction_script.runno amount of retrying can make it valid
Experiment sandbox unavailable due quotaexpose only if resource-blocked resume is supported; otherwise hide or ask useravoid loop churn

也就是说,对于调用方/配置档绝对不可能或类别性禁止的能力,通常应当直接不出现在可见面,而不是暴露后在调用时反复拒绝。可见面是 UX 与推理辅助,不是授权捷径。每个可见能力仍然会接受操作时授权,原因是:

  • 授权/租约可能在提示词与调用之间过期;
  • 参数影响风险与审批要求;
  • 资源配额可能变化;
  • 认证可能缺失或已撤销;
  • 并发运行可能消耗共享限额;
  • 配置档或租户策略可能在执行前改变。

模型可以在action_script.run、shell.run、experiment.*可见时选择它们,但不选择运行时后端——后端选择始终是宿主/配置档的职责。结构化拒绝(structured denial)只用于“可见但因参数特定或时变条件被拒绝”的选择;不要依赖拒绝/重试循环来解决静态配置档约束。

12. 与 QuickJS/ActionScript 及运行时配置档的关系

12.1 QuickJS 是能力,不是父循环

lightweight loop -> action_script.run(code, allowed_capabilities) -> QuickJS executes real JS with no ambient fs/net/env/process -> QuickJS ic.call(...) -> CapabilityHost for every internal call

适用action_script.run的场景:循环(loops)、扇出/扇入(fan-out/fan-in)、分页、过滤/排序/分组、结构化 JSON 转换、基于先前结果的动态调用。简单/静态的工具调用应使用直接能力调用;shell/包管理/构建/测试类工作应使用experiment.*或script.run。

12.2 同一个循环跑在所有配置档下

LocalDev profile: filesystem.read/write -> HostWorkspace shell.run -> LocalHost HostedMultiTenant profile: filesystem.read/write -> tenant workspace shell.run -> tenant-scoped sandbox EnterpriseDedicated profile: filesystem.read/write -> org-dedicated workspace shell.run -> org-dedicated runner/container/VM

循环只看到带脱敏描述符、访问状态与选定资源估计的可见能力;由配置档解析器与运行时后端决定它们在哪里、如何执行。

13. 扩展姿态、最小实现目标与后续契约测试

13.1 参考循环的扩展姿态

该循环可以随附第一方包元数据交付,但元数据不等于授权:

extension role: agent_loop trust ceiling: assigned by host policy host surface: AgentLoopHost facade only

生成的扩展不能创建新的父循环授权面;它们可以提供该循环可调用的能力(受正常的能力注册、授权、审批与运行时分发约束)。ironclaw_extension_registry可以注册内置包元数据,但不得执行循环——循环执行属于持有AgentLoopHost门面的已配置循环 runner/服务,并继续受内核中介策略约束。

13.2 最小实现应包含与不应包含

第一个实现应包含:

  • provider 无关的Reply | CapabilityCalls归一化;
  • 流式 assistant 消息事件;
  • 从可见能力生成能力封装器;
  • 串行/并行批次执行;
  • 结构化的审批/认证/资源挂起;
  • 在 assistant-finalized、batch-start、result-appended 与 blocked 状态的检查点;
  • steering 与 follow-up 队列钩子;
  • 到EventStreamManager的事件映射;
  • 通过ConversationManager的持久里程碑写入;
  • 运行时配置档无关的行为。

不应包含:

  • 直接的 filesystem/shell/HTTP 调用;
  • 扩展发现;
  • 密钥解析(secret resolution);
  • 运行时分发绕过;
  • 指令/工具选择之外的产品特定编码 agent 行为;
  • 把 QuickJS 嵌入为父协议分支。

13.3 待补充的契约测试清单

契约要求实现完成后补充通过宿主门面驱动循环的调用方级测试(原文逐条继承):

  • 最终回复完成运行且无副作用;
  • provider 原生 tool call 归一化为能力调用;
  • 可见能力仍接受操作时授权;
  • 串行能力强制整个批次串行执行;
  • 并行只读调用并发执行,但结果按来源顺序追加;
  • 需审批的调用挂起运行,且不追加伪造的错误 tool result;
  • 需认证的调用独立于审批挂起运行;
  • 从审批检查点恢复后,以调用指纹继续或重放;
  • steering 消息在下一次模型调用前注入;
  • follow-up 消息在自然停止后重启循环;
  • 能力面版本变化在下次模型调用前重建工具 schema;
  • 配置档禁止的能力在模型调用前就不出现在可见面中;
  • 可见但因参数被拒的能力返回结构化拒绝,且不改选后端;
  • 本地与托管配置档运行同一循环,但解析出不同后端。

14. 延伸阅读:仓库内的关键坐标

围绕本契约,仓库中值得继续深入的坐标:

  • 契约 crate:ironclaw_loop_contracts——宿主边界 DTO 与端口的单一定义点,LoopSafeSummary、VisibleCapabilitySurface、ParentLoopOutput均在此 crate;
  • 模型可见观察值:model_observation.rs——ModelVisibleToolObservation的边界常量与validate()校验;
  • 循环实现:ironclaw_agent_loop——executor 及其按主题划分的测试(并行批次、门控、认证恢复、检查点、预算、取消);
  • 宿主侧端口:ironclaw_loop_host——能力端口、capability_info合成工具与能力面快照;
  • 调用方级契约测试:agent_loop_host_contract.rs;
  • 兄弟契约文档:agent-loop-protocol.md、capabilities.md、run-state.md、approvals.md、runtime-profiles.md。

需要说明的适用前提:本文描述的是该契约文档(日期 2026-04-26,状态为“Decision guide / reference loop contract”)所定义的参考循环契约。文档中的AgentLoopHost单 trait 形态是契约层的设计描述;当前源码已将其细化为一组LoopXxxPort端口——两者语义一致(循环只经门面与宿主交互),但具体类型命名以ironclaw_loop_contracts为准。

  • 人工智能
  • AI 应用
  • 交互助手
  • AI Agent

【免费下载链接】ironclaw

IronClaw is an Agent OS focused on privacy, security and extensibility

项目地址:https://gitcode.com/gh_mirrors/iro/ironclaw
点击查看免费下载

相关推荐

上一篇:Rust Rosetta Code内存安全:所有权和借用检查器的实战解析
下一篇:Sol2单头文件生成教程:快速集成到任何项目

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 2:52:33

HHO-LSBoost多输入回归预测:哈里斯鹰优化与Matlab实现

做预测建模这些年&#xff0c;我最深刻的体会就是&#xff1a;调参的功夫往往比跑模型本身还多。尤其是用集成学习做回归预测时&#xff0c;弱学习器的数量、学习率、树深这些超参数&#xff0c;直接决定了模型的上限&#xff0c;可手动一个个试又费时又费力。所以当我尝试把哈…

作者头像 李华
网站建设 2026/9/25 2:46:16

灰色模型GM(1,1)电力负荷预测实战指南

简介&#xff1a;本资源是一份面向电力系统分析初学者与能源领域算法实践者的灰色模型&#xff08;GM&#xff09;负荷预测代码实现&#xff0c;聚焦小样本、非线性电力负荷序列的建模与预测问题。包内共8个文件&#xff0c;含4个MATLAB核心脚本&#xff08;gmfun.m、ols_run.m…

作者头像 李华