Files
agent_ops/02.架构设计/01.当前有效设计/02.正式方案/运行时与智能体工具.md
T

23 KiB
Raw Blame History

运行时与智能体工具

版本: 0.1(当前 Runtime 契约)
状态: 已确认
日期: 2026-08-06
关联方案: LineUp App 最终设计方案LineUp Runtime 与 App SDK 架构方案第 04 次迭代:Runtime 工作区与 Pomodoro MiniApp


0. 目的与权威范围

本文定义 Runtime 面向远端 Agent 的工具模型,以及它与本地 MiniApp 界面操作、Host 生命周期事件之间的边界。它是全局 Runtime 设计,Pomodoro 只是当前的具体例子,并不限制本文的适用范围。

本文确认的关键结论是:

Agent Tool 是 Runtime 发布给远端 Agent 的功能调用说明书。它不是用户点击界面的公共入口,也不是 MiniApp 内部函数的别名。

用户通常通过 IM 表达自然语言意图,未来也可以通过 Voice 表达;远端 Agent 负责理解意图、选择可见 Tool 并向 Runtime 发起调用。Runtime 负责校验、路由、执行、持久化和回传结果。用户未来可以在 MiniApp 页面点击按钮,但那属于另一条本地 UI Action 入口,不能伪装成 Agent Tool 调用。

本文细化 LineUp App 最终设计方案 中 Runtime、Tool、状态和边界的结论。后续若修改本文已确认的语义,必须先更新正式方案,再调整迭代定义和技术规范。

1. 术语与对象

术语 定义 不是
远端 Agent 运行在 LineUp 设备外、通过 AppServer / IM Transport 与 Runtime 通信的智能体。它理解用户自然语言,并在可见能力范围内选择 Tool。 不是 Runtime 内的计时器、存储或 UI 控制器。
Agent Tool MiniApp 在 Manifest 声明、Runtime 校验并发布给远端 Agent 的远程调用契约。它包含名称、说明、输入输出 schema、调用模型、可见性和策略。 不是用户按钮,也不是 App 任意 JavaScript 函数。
Agent Inventory Runtime 根据 App、Host、权限、策略、会话和 Agent 范围计算出的 Agent Tool 清单及其 revision。 不是安装包内全部函数的列表。
Tool Call Agent 对 Inventory 内某个 Agent Tool 发起的一次远端调用,带有 call_id、参数和 inventory revision。它可先收到协议回执和进度,最后才收到业务结果。 不等于业务 operation,也不等于 App instance。
Tool 协议回执 / 进度 Runtime 对一条已接受调用的可重放协议事实,例如 acceptedstartingactivation_readystarted;用于告诉 Agent 调用是否已接收、MiniApp 是否已就绪、业务是否真正开始。 不是 Tool 的业务 result,不受业务 output schema 约束,也不等于一次完成记录。
Tool 业务结果 Tool 的最终业务结论;必须符合该 Tool Manifest 的 output schema,并且对同一 call_id 只持久化、回传一次。 不是“请求已收到”或“正在启动”的临时状态。
Runtime 内部业务动作 Runtime 为实现业务请求执行的受控命令,例如创建 deadline operation、改变焦点、写 outbox、关闭实例。多个入口可以复用同一个动作。 不是自动公开给 Agent 的 Tool。
UI Action 用户在本地 MiniApp 页面点击、输入或拖动后,经 SDK / Bridge 发送给 Runtime 的本地请求。 不发布给 Agent,也不带 Agent 身份。
Host 生命周期意图 Host 或工作区产生的前后台切换、返回、关闭、恢复、锁屏等本地事实或请求。 不是 Agent Tool,也不应伪造成用户的 IM 指令。
MiniApp instance 一个 MiniApp 的运行实例;Runtime 管理其生命周期、作用域和启动状态。 不必然对应一次业务 operation。
App 子会话 Interact 中围绕一个 MiniApp instance 保存的、面向人与 Agent 的交互记录。 不等于一次专注、计时或其他业务 operation。
MiniApp activation Runtime 管理的一次 MiniApp 启动过程:`starting → ready failed
MiniApp session data Runtime 为当前 app_scope + app_session_id 持久化的通用 JSON 数据字典;内容和可变性由 MiniApp 自己定义。 不是 Runtime 可理解的 App 业务 schema,也不是 IM 记录或 operation Store。
operation Runtime 管理的实际业务执行单元,例如一次有 deadline 的专注。它有独立的状态机和终态。 不等于 Tool Call、App 子会话或界面实例。

2. Agent 的角色、能力范围与边界

2.1 Agent 的职责

远端 Agent 是意图理解者和工具调用者,不是本地 Runtime 的替身。它的职责是:

  1. 从用户 IM、Voice 或其他交互内容理解意图;
  2. 根据 Runtime 已发布的 Agent Inventory 选择合适的 Tool
  3. 按 Tool schema 构造参数,并携带当前 inventory revision 发起调用;
  4. 接收 Runtime 回传的受控结果,在用户会话中解释、追问或发起下一步调用。

当用户说“现在开始 20 分钟的冥想,帮我计时”时,正确链路如下:

用户的 IM 消息
  → 远端 Agent 理解为启动专注
  → Agent 调用 pomodoro.start
  → Runtime 请求 Pomodoro 进入前台
  → Host 确认前台激活后,Runtime 才创建并管理专注 operation
  → Pomodoro MiniApp 用自身 session data 显示界面

Agent 不需要、也不能自己一秒一秒倒数。时间事实由 Runtime 持久化的 deadline 和本地时间裁决;MiniApp 仅根据 Runtime 投影显示剩余时间。

2.2 Agent 可做的事

  • 调用当前 Agent Inventory 中、对当前 Agent 和 conversation 可见的 Agent Tool
  • 接收 Runtime 回传的 Tool 结果、进度和受控交互结果;
  • 在会话范围内发送内容、交互或后续 Tool 请求;
  • 在 Runtime 允许的范围内请求启动 Tool 所需的 MiniApp instance。

2.3 Agent 明确不能做的事

  • 不能调用未在当前 Inventory 中声明的 Tool,或绕过 inventory revision、参数 schema、会话和策略校验;
  • 不能直接读写 Runtime Store、MiniApp instance state、Conversation Store、operation Store、outbox 或审计记录;
  • 不能直接调用 Tauri、文件、通知、麦克风、窗口或其他 Host 特权能力;
  • 不能直接执行 MiniApp 的任意函数、修改其 DOM 或访问 Surface Bridge
  • 不能指定、伪造或跨会话操控任意 instance_id、operation_id、app_scope
  • 不能通过 Tool Call 绕过 App 安装、启用、权限确认、风险策略或 Host 能力限制。

Runtime 对 Agent 输入实行不信任原则:即使调用来自已认证 Agent,也必须重新验证可见性、作用域、幂等、生命周期和输出。

3. 三条独立入口

Runtime 可以接收不同来源的请求,但来源决定身份、校验、审计和可用能力。三者不是同一入口。

入口 发起者 Runtime 接收的内容 是否进入 Agent Inventory 主要校验 典型示例
Agent Tool 远端 Agent 有 Agent 身份、call_id 和 inventory revision 的远端 Tool 调用 Agent、Inventory、Tool schema、conversation、策略、幂等 Agent 调用 pomodoro.start。
MiniApp UI Action 用户在本地 MiniApp 页面操作 SDK / Bridge 发送的本地 Action 当前 instance、App 权限、UI schema、业务前置状态、用户确认 用户未来点击开始计时。
Host 生命周期意图 Runtime Shell、Host 或系统 前后台、返回、关闭、恢复、系统状态等本地事件 instance 生命周期、焦点栈、系统策略、operation 收口规则 用户离开 Pomodoro 工作区。

三条入口的流程如下:

一、远端 Agent Tool
用户 IM / Voice
  → 远端 Agent 理解意图
  → Agent Tool Call
  → Runtime 校验、路由和持久化
  → Runtime 内部业务动作
  → MiniApp 状态投影 / Agent 结果 outbox

二、本地 UI Action(未来可选)
用户点击 MiniApp 页面
  → SDK / Surface Bridge 的本地 Action
  → Runtime 校验和持久化
  → Runtime 内部业务动作
  → MiniApp 状态投影;必要时由 Runtime 产生 Agent 可见结果

三、Host 生命周期意图
返回 / 切换工作区 / 关闭 / 恢复 / 系统事件
  → Host Lifecycle Intent
  → Runtime 生命周期与焦点裁决
  → Runtime 内部业务动作 / operation 收口
  → MiniApp 状态投影 / 必要的 Agent 结果 outbox

后两条入口可以在 Runtime 内部复用与 Agent Tool 相同的业务服务。例如未来 UI 的开始按钮与 Agent Tool 的开始调用都可以请求同一个“创建专注 operation”动作。但复用内部动作不改变入口身份:UI Action 不会因此成为 Agent Tool,Host 生命周期也不会因此伪造成 Tool Call。

4. Agent Tool 的发布与调用

4.1 MiniApp 声明,Runtime 发布,Agent 调用

Agent Tool 的权威链条必须保持为:

MiniApp 源码中的 SDK Tool 声明
  → 构建生成 Manifest 的不可执行 Tool 描述
  → Runtime 验证 Manifest、App 与 Host 条件
  → Runtime 计算并发布动态 Agent Inventory
  → 远端 Agent 看到 Inventory 后选择 Tool
  → Agent 发起 Tool Call
  → Runtime 验证、路由、执行并回传

MiniApp 只声明自己支持的候选能力,不能自行向 Agent 宣传、发送或执行 Tool Call。Runtime 是唯一的 Inventory 发布者、远端调用接收者和结果回传者。

Tool 声明的开发者入口是 MiniApp SDK,而不是第二份手写 ManifestMiniApp 用 defineAgentTools(...) 同时声明 公开 method、schema、activation requirement 和 miniapp_sdk Tool 的本地 handler。SDK 源码声明是唯一真相;构建阶段 自动生成随 Bundle 安装的 Manifest Tool 描述。该描述供 Runtime 验证、Registry 和 Inventory 使用,但不包含 handler、 私有函数名或其他可执行内容。Bundle 内 SDK 保留 method → handler 映射,收到 Runtime 的统一 Tool 调用后在 MiniApp 内部分发。安装包仍可有 App 身份、版本、签名与 Host 能力等基础元数据,但开发者不再维护一份独立的 Tool 清单来重复 描述源码已经定义的能力。runtime Tool 只能引用 Runtime 内置的受控执行类型。这样既有类似 MCP Tool 描述文件的稳定 能力契约,也不让 Runtime 知道 MiniApp 的内部实现。

一个 Agent Tool Descriptor 至少应定义:

  • 稳定的 app_scope、method、contract_version
  • 面向 Agent 的业务说明、输入 schema 和输出 schema
  • 调用模型,例如 query、command、interactive 或 operation
  • 幂等键、超时或终态规则;
  • 启动就绪条件:app_ready(目标 MiniApp session 已 active、可接收方法调用)、foreground_required (在 app_ready 的基础上还必须已在前台),或 activation_not_required(只操作已有 Runtime 事实,不能因此 启动或唤醒 MiniApp);
  • 所需权限、风险级别和对前台 / Host 的要求。

Runtime 实际发布给特定 Agent 的清单是动态交集:

已验证的 Manifest Tool
  ∩ App 已安装并启用
  ∩ Host 当前支持
  ∩ 用户 / 组织策略允许
  ∩ 当前 Agent 与 conversation 可见
  ∩ 所需前置权限满足

4.2 Runtime 收到 Tool Call 后的职责

Runtime 收到远端 Agent Tool Call 后,按以下顺序处理:

  1. 验证远端 Envelope、Agent 身份、conversation 关联和 Inventory revision
  2. 验证目标 Agent Tool 当前可见,且参数符合已发布 schema;
  3. 用 call_id 执行幂等去重,持久化调用记录和审计;
  4. 解析 Tool 所允许的作用域,不接受 Agent 任意指定跨会话目标;
  5. 创建或复用 MiniApp activation,并在 Tool 所需的 app_readyforeground_required 条件满足后,选择内部 执行路径:直接处理、将 method 与已验证参数投递 App SDK、创建 operation 或拒绝;Runtime 不解释参数的 MiniApp 业务含义,也不直接写 MiniApp 的 session data
  6. 原子持久化业务状态、operation 终态与需要回传的 outbox
  7. 仅向相关 MiniApp 投递经过裁剪的状态或调用投影;
  8. 将协议回执 / 进度与最终业务结果分别持久化并经 outbox 回传:前者不使用业务 output schema;后者必须通过该 schema 校验。

Tool Call 的成功接收不等于业务已经完成。对于长期 operation,Runtime 可以先确认接受调用,业务真正开始时再报告 进度,之后只在进入唯一终态时回传最终结果。相同 call_id 重放时,Runtime 返回已持久化的最新协议回执或最终 业务结果,不重新执行业务,也不追加新的 outbox 消息。

4.3 activation 就绪通知与提前到达的后续调用

当 Agent 的一个 Tool 调用使 MiniApp 进入 startingRuntime 必须把 activation 的受控状态作为与该 call_id 关联的协议进度通知给发起 Agent:

accepted / starting
  = Runtime 已接受调用,MiniApp 正在准备

activation_ready
  = MiniApp 已 active / ready;后续要求 app_ready 的 Tool 现在可以接收

activation_failed / activation_cancelled
  = 本次启动不能继续;依赖它的等待中调用将得到受控失败结果

这些通知是 Runtime 持久化 activation 后,经 Runtime outbox 发出的事实;MiniApp、Surface 和 Host 只能向 Runtime 报告自己的就绪或失败,不能直接向 Agent 发送通知。公开通知只携带 call_idapp_scope、状态和受控 reason,不能 把 instance_idapp_session_id 变成 Agent 可指定或跨会话操控的目标。

Agent 收到 activation_ready 后再发送有依赖关系的后续 Tool,是推荐的编排方式;但它不是 Runtime 接收调用的硬前提。 若一条合法、同 conversation / app scope 的 app_readyforeground_required Tool 在目标 activation 仍为 starting 时提前到达,Runtime 必须持久化该调用并把它挂到同一 activation 的等待队列,在 ready 后按已持久化的到达 顺序投递。activation 失败或取消时,Runtime 不执行这些 handler,而为各调用回传稳定的 app_activation_failedapp_activation_cancelledactivation_not_required Tool 不进入等待队列,仍立即处理;因此 Pomodoro 在启动中收到 pomodoro.interrupt 时可以立即取消启动。

某些 Tool 的业务进度比通用 activation 状态更强时,不应重复发两条没有新增信息的通知。第 04 次的 pomodoro.start 在 Host 确认前台的同一提交中同时得到 activation = ready、创建 operation 并开始计时,因此只向 Agent 发 started;它语义上已包含“Pomodoro ready”,且额外保证“前台已确认、计时已真实开始”。

5. 状态、身份与生命周期不得混同

本节是 Runtime 状态模型的一部分。下列对象可以互相关联,却不能共享语义或被一个 ID 替代。

Conversation(人与主 Agent 的协作范围)
  ├── App 子会话(MiniApp 启动后可在 Interact 中保存的交互记录)
  ├── MiniApp instance(实际运行的界面 / SDK 上下文)
  │     ├── activationstarting / ready / failed / cancelled
  │     └── session data(该 App 子会话的通用、MiniApp 自解释 JSON 数据)
  ├── Agent Tool Call(远端调用与其幂等、审计和回执)
  └── operation(实际业务执行;可无,也可独立于界面按规则收口)
对象 最小职责 应有的状态 / 身份 不能承担的事实
Conversation 用户与主 Agent 的协作边界 conversation_id 不能表示某次业务执行。
App 子会话 保存围绕 MiniApp 的可见交互与历史 app_session_id 或等价记录 不能替代 MiniApp instance 或 operation。
MiniApp instance 管理运行、焦点、挂起、关闭和 SDK scope instance_id、生命周期状态 不自动代表一次业务 operation。
MiniApp activation 将 App 准备为 active / ready 的过程;某些 Tool 还要求成为前台 instance_id、app_session_id、starting / ready / failed / cancelled 不是业务 operation,不能自行产生 deadline 或终态。
MiniApp session data MiniApp 自己的业务 / 展示数据 app_scope 加 app_session_id 加 revision Runtime 不理解内容;不能裁决 deadline、Tool 终态或 outbox。
Agent Tool Call 一次远端请求、幂等与审计 call_id、Tool key、inventory revision 不能替代长期 operation。
operation 实际业务过程、deadline、进度和唯一终态 operation_id、业务状态机 不等于一次 MiniApp 启动或 App 子会话。

因此,一个 MiniApp 会话或 instance 启动时未必启动业务 operation;一个 operation 也不应靠 UI 是否存在来判断是否完成。Tool 可以声明其业务开始是否需要前台:例如 pomodoro.start 只有在用户确实进入前台专注界面后才创建 operation;未来 todo.add 则可以在后台数据上下文就绪后完成。具体 Tool 的就绪条件不能上升为 Runtime 的统一前台要求。

Runtime 可以在一个原子事务中同时更新 operation、activation、session data 和 outbox,但它们仍保留各自的事实来源和恢复规则。

6. 各层能力边界

主体 负责什么 可以请求什么 明确禁止
用户 通过 IM / Voice 表达意图;未来可直接操作 MiniApp UI。 Agent 对话;本地 UI Action。 不直接调用 Agent Tool 协议或 Runtime 内部 Store。
远端 Agent 意图理解、Tool 选择、调用参数和会话回复。 当前 Inventory 中的 Agent Tool。 直接访问 Host、Store、MiniApp DOM 或任意 App 函数。
Runtime Agent 通信、Tool Registry、校验、路由、状态、operation、生命周期、持久化、outbox、审计。 通过 Host Provider 使用受控系统能力;向 App 投递受限 SDK 投影。 将 Transport、密钥或跨 App 数据直接暴露给 Agent / MiniApp。
MiniApp 自己的界面、已声明业务处理和当前 App 子会话的 session data。 SDK 提供的投影、声明性 Action、Capability request。 自行连接 Agent / AppServer、直接写 Runtime Store、直接使用 Tauri / Host。
Surface / UI 渲染和收集本地用户事件。 受限 Surface Bridge。 假冒 Agent、构造 Agent Tool Call、直接操作 Host DOM 或特权 API。
Host 提供窗口、通知、文件、音频等运行环境和系统事实。 向 Runtime 报告生命周期意图。 直接改变 MiniApp 业务状态、直接向 Agent 发布工具或交付特权能力。

特别地,Host 只报告本地事实或意图,最终如何改变业务状态由 Runtime 的业务规则裁决。例如“用户离开专注工作区”可触发 Runtime 中断当前专注,但 Host 不是在调用 pomodoro.interrupt,也不能假装成 Agent。

7. Pomodoro:第 04 次迭代的具体应用

第 04 次迭代用 Pomodoro 验证的是第一条入口,即 Agent Tool 到 Runtime 再到 MiniApp 投影。其冻结模型为:

用户在 IM 中说:现在开始 20 分钟的冥想,帮我计时
  → 远端 Agent 调用 pomodoro.start
  → Runtime 创建 Pomodoro instance、App 子会话和 activation(starting)
  → Host 确认 Pomodoro 已成为当前前台 App
  → Runtime 创建 deadline operationPomodoro 进入 focusing 并被动显示

用户在 IM 中说:停止或结束这次专注
  → 远端 Agent 调用 pomodoro.interrupt
  → 若仍在 startingRuntime 取消启动;若已 focusingRuntime 原子收口当前 operation
  → Pomodoro 只接收通用 lifecycle 关闭通知

本迭代的 pomodoro.start 把“Pomodoro 已成为用户当前前台界面”作为开始专注的前提:Runtime 接受调用并创建 starting activation 后,先向 Agent 回传 accepted / starting 协议回执;这只能表示“正在进入专注模式”,不能说 “已经开始计时”。Host 前台确认与 operation 创建成功后,Runtime 再回传 started 进度,此时 Agent 才能说“已开始 为你计时”。确认之前不存在 operation、倒计时或专注 IM 记录;最终无法前台激活时,Runtime 回传符合 start output schema 的 not_started 业务结果并恢复 Interact。pomodoro.interrupt 由 Agent 调用,而不是 Runtime 私下调用 Pomodoro: 它可取消当前启动尝试,或收口当前 focusing operation。Runtime 根据调用所在 conversation 定位目标,不接受 Agent 指定 或伪造 instance_id、operation_id 等目标。

当前 Pomodoro Surface 不实现开始、暂停、继续、停止等业务按钮。未来如果引入“用户先让 Agent 设定时长、随后自己点击开始”之类的 UI,按钮的 onClick 应产生独立的本地 UI ActionRuntime 可以让它复用创建 operation 的内部动作,但不得改变当前 Agent Tool 的含义,也不要求为第 04 次迭代提前加入两阶段 Tool 模型。

用户切回 Interact、切至其他 MiniApp 或关闭 Pomodoro 属于 Host 生命周期意图。Runtime 按 Pomodoro 的业务规则将其收口为 interrupted,但不伪造一条 Agent Tool Call;自动暗屏、锁屏和 Surface 重载则不等于离开专注。

8. 对协议与实现的约束

  1. Agent Inventory 只能包含 Agent Tool Descriptor;不得包含 UI Action、Host 生命周期事件或 MiniApp 任意内部方法。
  2. Runtime 必须分别记录 Agent Tool Call、UI Action 和 Host 生命周期意图的来源、身份、关联 ID 与审计类型;不得用一种来源伪造另一种。
  3. UI Action 的本地 Bridge 协议可在后续版本独立设计,但其入口、权限和审计不得依赖远端 Agent 身份或 inventory revision。
  4. Runtime 内部业务服务可由多个入口复用,但每个入口都必须先完成自己的授权、作用域和幂等校验。
  5. MiniApp session data 只能保存当前 App 子会话的 MiniApp 自定义 JSON 数据;不能借此完成 Tool、operation、outbox、焦点或 Host Capability 的特权动作。
  6. Agent Tool 的调用结果必须由 Runtime 校验 schema、持久化并经 outbox 回传;MiniApp 不得直接向 Agent 或 Transport 发送结果。
  7. 在没有明确产品决议前,不得为了未来 UI 的可能性改变已发布 Agent Tool 的语义,或向当前 Inventory 额外加入预设、打开、准备等 Tool。
  8. 对 operation、activation、session data、Tool receipt、outbox 和工作区目标的同一次业务变更,Runtime 必须先原子持久化事实, 再让 Lifecycle、Host 和 Surface 对账;持久化失败不得改变任何层,提交后的 UI / Host 失败不得回滚已提交事实。

9. 非目标

本文不定义:

  • Voice 的具体协议或语音识别实现;它未来只需复用“用户表达意图,再由 Agent 调用 Tool”的语义;
  • UI Action 的具体事件名称、Bridge 线协议或按钮设计;
  • 允许用户绕过 Agent 调用远端 Agent Tool
  • 允许 MiniApp 直接与 Agent、AppServer、Tauri 或任意系统能力通信;
  • 将所有 MiniApp 都强制设计为有 operation 的应用;
  • 因未来 UI 交互扩展而修改第 04 次 Pomodoro 已冻结的直接开始模型。