OpenHuman RLM 工作流 Phase 2:为 TinyAgents 补齐宿主嵌入能力(外部取消、实时事件与异步文档化)
发布时间:2026/9/10 14:07:20 作者:尧图编辑部 阅读量:1,286
)
OpenHuman RLM 工作流 Phase 2为 TinyAgents 补齐宿主嵌入能力外部取消、实时事件与异步文档化【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman导读rlm-workflows是 OpenHuman 把 TinyAgents 的 Rhai 脚本引擎.ragsh/ RLM / CodeAct 表面由replcargo feature 门控投影为编排者orchestrator可调用的“一级rlm工具”的落地计划让模型能以脚本语言自行编写扇出、批量调用、循环与条件等临时控制流。本篇聚焦该计划中的Phase 2 —— TinyAgents 侧的宿主嵌入改造为一颗独立运行的脚本 cell 补上“外部可取消”“过程可观测”“宿主侧正确驱动”三块缺失并以独立 PR 的方式先行合入上游tinyhumansai/tinyagents。读完本文你将理解外部取消标志ReplCancelFlag的双点执行设计、基于EventSink的实时能力调用事件契约、阻塞式eval_cell的异步宿主驱动约定以及配套测试与验收口径。本仓库当前为计划阶段正文会同时给出计划文件与仓库既有源码的相互印证。一、背景为什么需要 Phase 2整套计划把工作拆分到两个仓库vendor/tinyagentsgit submodule指向tinyhumansai/tinyagents当前钉在提交357bcc8负责宿主嵌入所需的缺口补齐即本文件描述的 Phase 2openhuman负责新增src/openhuman/rlm/领域、rlm工具、prompt/文档与测试Phase 3–6对应feat/rlm-language-workflows分支最终 bump 一次 submodule 指针。总体脉络见 docs/plans/rlm-workflows/README.md各阶段交付见下表Phase文件交付物1phase-1-research.md调研tinyagentsrepl提供了什么、openhuman 提供什么、缺口在哪2本文phase-2-tinyagents.mdTinyAgents 侧改动外部取消、实时事件独立 PR3phase-3-rlm-domain.mdsrc/openhuman/rlm/领域会话、能力桥、策略映射4–6phase-4~6rlm工具、加固、测试7phase-7-delivery.mdPR 策略tinyagents PR openhuman 巨型 PRPhase 1 的结论是TinyAgents 的脚本会话ReplSession本身已具备沙箱化、策略受限fail-closed 的ReplPolicy的eval_cell(script) - ReplResult执行入口超时在引擎on_progress钩子与bridge_block_on计时线程竞速丢弃在途能力 future两个点强制执行。但宿主openhuman仍无法做到三件事且这三件事无法在宿主侧单纯用包装解决必须下沉到 tinyagents crate 本身见 phase-1-research.md 的 “Gaps a host must fill”没有外部取消进行中的 cell 只能被墙钟超时终止缺少让宿主按需 abort 的句柄没有实时进度stdout/calls/emit只能在 cell 返回后读取长时间扇出在 UI 上“看起来卡死”eval_cell是同步的且内部block_on异步宿主若在 async worker 上直接调用会死锁 current-thread runtime而这一约束目前只能靠读builtins/mod.rs才能发现。因此 Phase 2 的范围被刻意保持最小只做 Phase 1 识别出的、宿主侧无法绕过的宿主嵌入缺口作为独立 PR 先行合入上游openhuman 的 PR 随后仅做 submodule 指针 bump。二、2.1 外部取消ReplCancelFlag2.1.1 问题一个正在运行的 cell 此前只能靠它的 wall-clock 超时被停止。而 OpenHuman 需要在这些场景下主动中止在途 RLM cell用户取消一次 run计划中对应宿主侧workflows::run_log::cancel_run的取消路径agent turn 因故中断宿主 abort。2.1.2 设计改动在会话上新增一个共享取消标志随会话复制、可被宿主随时置位repl/session/types.rs新增pub struct ReplCancelFlag(ArcAtomicBool)提供new() / cancel(self) / is_cancelled(self)且是廉价的Clone内部只是Arc多份句柄共享同一布尔位线程安全ReplSession::with_cancel_flag(flag)负责保存该标志会话内部的CellBuffers在携带deadline墙钟截止的同时也携带该标志新增错误变体TinyAgentsError::Cancelled(String)定义在 crate 的src/error.rs使“被取消”成为一种一等错误而非笼统的 timeout/limit 异常。2.1.3 与既有超时的“双点执行”对齐fail-closedPhase 1 记录过超时在两个点被强制执行phase-1-research.md引擎on_progress钩子针对纯脚本循环与bridge_block_on计时线程竞速丢弃在途的能力 future。取消标志的强制点镜像同样的两点结构并且一律 fail-closed引擎on_progress钩子钩子每拍检查ReplCancelFlag::is_cancelled()一旦置位即以一个CANCELLED_TOKEN哨兵终止脚本eval_cell把该哨兵映射为新的TinyAgentsError::Cancelled返回给宿主bridge_block_on路径当取消标志被武装armed时在该函数的计时器竞速中轮询标志——即以短间隔定时器参与 select——这样即使底层模型/工具/agent 调用处于阻塞中例如挂起的 HTTP future也能在取消时被及时丢弃而不是干等墙钟超时。设计意图取消不是“礼貌请求”而是与超时并列的第二道硬闸。宿主侧 ops 层负责把“用户取消 →ReplCancelFlag::cancel()”串起来对应 Phase 3ops.rs中把取消注册到会话条目上见 phase-3-rlm-domain.md。仓库现有编排代码里已经有同构的取消惯例可作参照例如src/openhuman/agent/orchestration/workflow_runs/engine_part_01.rs中的register_cancel_signal(run_id) - WorkflowCancelSignal与register_cancel_flag(run_id) - ArcAtomicBool以及src/openhuman/agent/orchestration/下多处通过tinyagents_harness::CancellationToken做协作式取消。ReplCancelFlag正是把这种ArcAtomicBool惯例下沉进 tinyagents 会话内部让引擎自身在on_progress与阻塞桥两个层面执行它。三、2.2 实时能力调用事件写往EventSink3.1 问题ReplResult.calls只有在 cell 完整执行结束后才可用。当脚本做长时间扇出例如agent_query_batched/tool_call_batched批量并发调用时宿主 UI 在这段时间内看不到任何中间状态表现为“冻结”。3.2 设计改动在builtins/各能力内建函数的调用起始与完成两个时点向HostContext.events发出类型化事件——HostContext.events正是与 run context 共享的既有EventSink无需新增独立通道记录采用AgentEvent::Custom风格携带结构化字段{ session_id, kind: model|tool|agent|emit, name, elapsed? }elapsed在完成事件中给出该次调用的耗时如果现有AgentEvent枚举缺少合适变体则在replfeature 之后追加AgentEvent::ReplCall { record: ReplCallRecord, phase: Started|Completed }不加新公共类型能复用事件枚举就复用宿主侧不必感知新的 tinyagents 类型。3.3 宿主侧消费方式openhuman 作为宿主在会话的EventSink上订阅一个EventListener把 REPL 调用事件转发到自己的进度通道。仓库侧可以承接这一事件流的现成结构是AgentProgress枚举见src/openhuman/agent/progress.rs及其ToolCallStarted/ToolCallCompleted变体——例如src/openhuman/agent/harness/session/tool_progress.rs已在用AgentProgress::ToolCallStarted向 UI/run log 推送工具执行进度。Phase 3 的ops.rs进一步把订阅到的 REPL 调用事件映射为ToolCallStarted/Completed形状的AgentProgress消息并在全局DomainEvent总线发布 coarse 粒度的开始/结束事件phase-3-rlm-domain.md。由此形成完整链路脚本内 model_query / tool_call / agent_query ... └─ builtins 内建函数在开始/完成时 emit AgentEvent::ReplCall或 Custom 记录 └─ 宿主 EventListener订阅 EventSink └─ openhuman AgentProgressToolCallStarted/Completed └─ UI 时间线 / run logs长扇出不再“冻结”四、2.3 异步嵌入文档化4.1 问题的根因TinyAgents 的脚本引擎是同步的能力调用经由一个阻塞桥内部使用futures::executor::block_on完成。这意味着eval_cell会阻塞当前线程。Phase 1 调研明确警告过phase-1-research.md在 current-thread runtime 的 async worker 上直接调用eval_cell会导致死锁宿主必须把它投递到tokio::task::spawn_blocking或专用线程。4.2 文档改动由于这一约束“目前只能靠读builtins/mod.rs才能发现”Phase 2 要求在eval_cell的 API 表面上直接写明双重位置rustdoc 注释模块级 README。明确说明eval_cell内部会阻塞经futures::executor::block_on异步宿主必须通过spawn_blocking/专用线程驱动它。这与 Phase 3 的宿主编排完全对应ops.rs中每个 cell 的执行正是tokio::task::spawn_blocking(move || session.eval_cell(script))外层再包一层 policy timeout 5 s 宽限的tokio::time::timeout作为兜底phase-3-rlm-domain.md。文档化的意义在于让未来任何宿主都无需再靠读实现来推断这一约束。五、2.4 TinyAgents 侧测试与改动同行TinyAgents 自身约定每个行为变更必须伴随测试该 crate 不会推迟测试。因此在 tinyagents 内与改动一起落地四类用例测试场景触发方式断言取消先行置位eval_cell之前先ReplCancelFlag::cancel()返回Cancelled脚本根本不会启动脚本循环中途取消脚本运行中置位取消标志及时终止走on_progress路径挂起的能力 future 中取消在挂起的 capability future 等待期间置位及时丢弃走bridge_block_on路径事件流可观测用ScriptedModel/FakeTool驱动model_query/tool_call在EventSink上观察到 start completion 事件前两条覆盖取消标志的执行路径哨兵终止与未启动短路第三条覆盖阻塞桥竞速路径——确保取消在模型/工具/agent 调用真正“卡住”时也能尽快返回第四条用脚本化模型与假工具ScriptedModel/FakeTool验证事件不依赖真实网络/模型确定性可重复。六、验收口径AcceptancePhase 2 的合入门槛写得很明确——在vendor/tinyagents目录内跑通以下三连cargo fmt --check cargo clippy --all-targets -- -D warnings cargo test --features repl三条命令全绿后对tinyhumansai/tinyagents开出 PR并在 PR 描述中附上变更摘要与所运行命令。这也是后续 openhuman 巨型 PR 的前提Phase 7 的合并顺序是tinyagents PR 先合 → openhuman 侧 bump submodule 指针并让 CI 全量重跑见 phase-7-delivery.md。在 tinyagents PR 落地前openhuman 的开发可基于本地 submodule checkout 推进互不阻塞若 PR 未及时合入openhuman PR 则先钉住该分支头并注明依赖关系。七、落地形态与后续衔接改动隔离Phase 2 内容全部处于 tinyagents 侧repl/session/types.rs、src/error.rs、builtins/、EventSink枚举分支为feat/repl-host-embedding。openhuman 侧不接触这些实现只消费replfeature 暴露的ReplCancelFlag、EventListener与文档化后的eval_cell契约。宿主侧对应物ReplCancelFlag由会话条目持有并链接到 turn 的取消上下文EventSink上的调用事件由EventListener转发为AgentProgress仓库现有src/openhuman/agent/progress.rs的ToolCallStarted/Completed形状——这部分具体在 phase-3-rlm-domain.md 展开。回滚与开关整个 RLM 表面默认暗置可通过OPENHUMAN_RLM0开关关闭且 readonly 自治层级根本不注册rlm工具因此 Phase 2 合入后对既有行为无影响。明确不进 v1 的后续项phase-7-delivery.md脚本内graph_run真正执行已编译图依赖 tinyagents 实现超步执行RPC/CLI 暴露 RLM 会话与专用 UI 时间线卡片会话跨核心重启的持久化cell 运行中的部分 stdout 流式输出。从更广的计划视图看Phase 2 解决的三个缺口正好对应 RLM 落地的三个不可绕过的宿主需求——取消安全边界、进度可观测边界、驱动约定线程/运行时边界。三者补齐后TinyAgents 的 Rhai 会话才真正具备被 OpenHuman 编排循环当作“每个rlm工具调用即一个 cell”的可托管嵌入形态。【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考