docs(i18n): proofread README translations 161-180
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
本包为 `WorkflowService` 提供实现,每次运行使用一个 Node worker thread。worker 执行编排脚本;子 agent(智能体)留在宿主上,通过带类型的宿主/worker 协议访问 `ctx.subagents`。
|
||||
本包(package)为 `WorkflowService` 提供实现,每次运行使用一个 Node worker thread。worker 执行编排脚本;子 agent(智能体)留在宿主上,脚本通过带类型的宿主/worker 协议经由 `ctx.subagents` 访问它们。
|
||||
|
||||
包根目录默认导出引擎插件及其 `Config`;worker 协议、运行时和会话模块均为实现私有。操作入口 `./worker` 仍是引擎的派生目标。
|
||||
包根目录默认导出引擎插件及其 `Config`;worker 协议、运行时和会话模块均为实现私有。操作入口 `./worker` 仍是引擎的 spawn 目标。
|
||||
|
||||
这种拆分只有一个主要目的:同步脚本循环不能阻塞 harness 事件循环,忽略取消的脚本可以连同其 worker 一起终止。它不是安全沙箱。
|
||||
|
||||
@@ -16,14 +16,14 @@ worker 仍提供实用的隔离:
|
||||
|
||||
- 脚本 CPU 工作和同步自旋不会占用宿主事件循环;
|
||||
- `worker.terminate()` 为 dispose(资源释放)提供真实的最终停止手段;
|
||||
- 除未构建 loader 的管道变量外,worker 以空环境启动,因此环境凭据不会通过 `process.env` 跨越边界;
|
||||
- 除未构建 loader 所需的衔接配置外,worker 以空环境启动,因此环境凭据不会通过 `process.env` 跨越边界;
|
||||
- 宿主/worker 消息使用结构化克隆数据,并在脚本边界执行普通 JSON 校验。
|
||||
|
||||
真正的不可信脚本沙箱需要在同一 workflow seam 后采用不同引擎。
|
||||
真正的不可信脚本沙箱需要在同一工作流 seam(扩展点)背后采用不同引擎。
|
||||
|
||||
## 脚本契约
|
||||
|
||||
工作流的 `meta` 是宿主提供的数据,而不是待求值的脚本文本。引擎会校验必需的 `name` 和 `description`、拒绝未知字段,并在返回运行前检查函数体能否解析。
|
||||
工作流的 `meta` 是宿主提供的数据,而不是待求值的脚本文本。引擎会校验必需的 `name` 和 `description`、拒绝未知字段,并在返回运行前检查脚本正文能否解析。
|
||||
|
||||
在 worker 内,脚本会收到 `args` 以及以下钩子:
|
||||
|
||||
@@ -32,16 +32,16 @@ worker 仍提供实用的隔离:
|
||||
- `pipeline(items, ...stages)` 在没有跨阶段屏障的情况下传递 `(previous, item, index)`;
|
||||
- `phase(title)` 和 `log(message)` 发出观察器叙述。
|
||||
|
||||
未知选项、格式错误的参数、不支持的 schema、触发的上限、提供方启动失败和基础设施结果失败都属于致命工作流错误。有意不注入 timer、文件系统 API 或 Node 全局变量,但上述信任注意事项仍然适用。
|
||||
未知选项、格式错误的参数、不支持的 schema、超出上限、提供方启动失败和基础设施结果失败都属于致命工作流错误。有意不注入 timer、文件系统 API 或 Node 全局变量,但上述信任注意事项仍然适用。
|
||||
|
||||
## 运行顺序
|
||||
|
||||
`start()` 会校验 meta、解析函数体、解析一个已注册且规范化的提供方路由,并解析每次运行的子 agent 总数上限,然后才创建 worker 或发布 `workflow/start`。请求的 `maxTotalAgents` 必须是正安全整数,且不能超过引擎配置的部署上限。源代码模式通过 data URL bootstrap 安装 TypeScript 转换;构建模式把同级 `lib/worker.cjs` 作为文件系统路径传入,因为 pkg 的 VFS 钩子要求 CommonJS。两者都能在普通 Node 下运行。ready/go 握手可以避免启动信号取消与 worker 启动发生竞态,导致脚本最初的同步片段被执行。
|
||||
`start()` 会校验 meta、解析脚本正文、解析一个已注册且规范化的提供方路由,并解析每次运行的子 agent 总数上限,然后才创建 worker 或发布 `workflow/start`。请求的 `maxTotalAgents` 必须是正安全整数,且不能超过引擎配置的部署上限。源代码模式通过 data URL bootstrap 安装 TypeScript 转换;构建模式把同级 `lib/worker.cjs` 作为文件系统路径传入,因为 pkg 的虚拟文件系统(VFS)钩子要求 CommonJS。两者都能在普通 Node 下运行。ready/go 握手可以避免启动信号取消与 worker 启动发生竞态,导致脚本最初的同步片段被执行。
|
||||
|
||||
对于每次 `agent()` 调用:
|
||||
|
||||
1. worker 发送 `child-start`,其中包含普通数据提示词和选项。
|
||||
2. 宿主通过异步 `SubagentService.start` 调用启动请求中的提供方覆盖值,否则调用已配置提供方;调用会传入工作流父级和每次运行唯一的规范中止信号。提供方选择应用于该次运行的每个子 agent,对脚本不可见。
|
||||
2. 宿主通过异步 `SubagentService.start` 调用启动请求中指定的提供方,否则调用已配置的提供方;调用会传入工作流父级和该次运行共用的唯一中止信号。提供方选择应用于该次运行的每个子 agent,对脚本不可见。
|
||||
3. 如果启动被拒绝,宿主会发送 `child-start-error`;提供方启动已经完全停稳,不会发出子 agent 生命周期事件。
|
||||
4. 如果启动兑现时工作流仍接纳工作,宿主会记录该运行、观察 `result`,然后发送 `child-started`。即使结果已经结算,也只会随后转发,以保持先启动、后结果的顺序。
|
||||
5. worker 发出成对的 `workflow/agent-start` 和 `workflow/agent-end` 叙述,并在收集后请求 dispose 子 agent。
|
||||
@@ -56,9 +56,9 @@ worker 仍提供实用的隔离:
|
||||
|
||||
## 取消与 dispose
|
||||
|
||||
`WorkflowRun.cancel()` 会记录第一个原因、通知 worker 取消、中止每个待处理及已发布子 agent 共享的唯一信号,并启动 `disposeGraceMs` timer。worker 钩子会在下次 await 时抛出 `CANCELLED`。如果运行到期限仍未结算,宿主会将其以已取消状态兑现、为悬空的子 agent 生命周期事件配对,并终止 worker。
|
||||
`WorkflowRun.cancel()` 会记录第一个原因、通知 worker 取消、中止每个待处理及已发布子 agent 共享的唯一信号,并启动 `disposeGraceMs` 定时器。worker 钩子会在下次 await 时抛出 `CANCELLED`。如果运行到期限仍未结算,宿主会将其以已取消状态兑现、为悬空的子 agent 生命周期事件配对,并终止 worker。
|
||||
|
||||
subagent seam 只有一个取消通道:请求信号。不存在单独的子 agent 取消 RPC。已发布子 agent 使用 `run.dispose()` 清理;待处理提供方启动在其 promise 拒绝或兑现前仍由提供方拥有。
|
||||
subagent seam 只有一个取消通道:请求信号。不存在单独的子 agent 取消 RPC。已发布子 agent 使用 `run.dispose()` 清理;待处理的提供方启动在其 promise 拒绝或兑现前仍由提供方负责。
|
||||
|
||||
正常结算也会中止待处理启动,并在结果对外结算前开始 dispose 所有已发布但无需等待的子 agent。宿主的完全停稳条件同时包括待处理启动和已发布子 agent 的 dispose,因此清理不会遗漏异步启动事务。
|
||||
|
||||
@@ -66,9 +66,9 @@ subagent seam 只有一个取消通道:请求信号。不存在单独的子 ag
|
||||
|
||||
## 结果与事件保证
|
||||
|
||||
在宿主主张点,终态结果遵循先到者胜。已接受的外部取消会覆盖后到的非取消 worker 结果;先完成主张的结果或 worker 死亡不能被可重入清理回调改写。
|
||||
在宿主的结果确认点,终态结果遵循先到者胜。已接受的外部取消会覆盖后到的非取消 worker 结果;先完成确认的结果或 worker 死亡不能被可重入清理回调改写。
|
||||
|
||||
worker 错误、消息失败或提前退出会在清理前关闭消息接纳,然后以 `error` 兑现;如果取消已经拥有该运行,则不覆盖取消。后到的排队消息无法在该逻辑边界后创建子 agent 或发出叙述。
|
||||
worker 错误、消息失败或提前退出会在清理前关闭消息接纳,然后以 `error` 兑现;如果取消已经接管该运行,则不覆盖取消。后到的排队消息无法在该逻辑边界后创建子 agent 或发出叙述。
|
||||
|
||||
宿主会维护已转发子 agent 启动的台账。优雅退出的 worker 会提供对应的结束事件;死亡或强制终止会把缺失的结束事件合成为已取消。因此,每个已转发的 `workflow/agent-start` 都会且只会配对一次,不过已经到达的工作流结果之后的清理可能稍后才完成。
|
||||
|
||||
@@ -83,7 +83,7 @@ worker 错误、消息失败或提前退出会在清理前关闭消息接纳,
|
||||
| `syncTimeoutMs` | `5000` | 脚本最初同步片段的 VM 超时时间。 |
|
||||
| `disposeGraceMs` | `5000` | 强制结算/终止之前的期限,也是公开 dispose 的期限。 |
|
||||
|
||||
所属消费方可以为一次运行设置 `WorkflowStartRequest.subagentProvider` 和 `WorkflowStartRequest.maxTotalAgents`。它们属于引擎级政策,不是脚本钩子或面向模型的选项;普通 `workflow` 工具不会设置两者。每次运行的子 agent 总数上限可以降低、但绝不能提高已配置的 `maxTotalAgents` 上限。
|
||||
负责该引擎的消费方可以为一次运行设置 `WorkflowStartRequest.subagentProvider` 和 `WorkflowStartRequest.maxTotalAgents`。它们属于引擎级策略,不是脚本钩子或面向模型的选项;普通 `workflow` 工具不会设置两者。每次运行的子 agent 总数上限可以降低、但绝不能提高已配置的 `maxTotalAgents` 上限。
|
||||
|
||||
## 模型体验
|
||||
|
||||
@@ -91,7 +91,7 @@ worker 错误、消息失败或提前退出会在清理前关闭消息接纳,
|
||||
|
||||
#### 模型看到的内容
|
||||
|
||||
脚本每次调用 `agent()`,都会把提示词逐字发送给 subagent 提供方,并附带可选模型或结构化输出 schema。每个子 agent 看到该提供方自己的上下文;phase 和 log 叙述只留在观察器事件中。
|
||||
脚本每次调用 `agent()`,都会把提示词原样发送给 subagent 提供方,并附带可选模型或结构化输出 schema。每个子 agent 看到该提供方自己的上下文;phase 和 log 叙述只留在观察器事件中。
|
||||
|
||||
#### Token 影响
|
||||
|
||||
@@ -109,16 +109,16 @@ worker 错误、消息失败或提前退出会在清理前关闭消息接纳,
|
||||
|
||||
#### Token 影响
|
||||
|
||||
本引擎不会直接向父级添加 token。最终结果大小由工具消费方限制,并保留到上下文压缩(compaction)为止。
|
||||
本引擎不会直接向父级添加 token。最终结果大小由工具消费方限制,并保留到 compaction(上下文压缩)为止。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
|
||||
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
|
||||
|
||||
## 已知限制与延期工作
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **worker/vm 不是安全边界**:模型编写的代码可以逃逸 `node:vm` 并取得 worker 的进程权限;不可信代码部署需要独立进程或容器引擎。
|
||||
- **每次运行都要支付一个 worker thread 的成本**:没有池、预热运行时或跨运行脚本缓存。
|
||||
- **不注入环境 timer、文件系统或网络,但逃逸代码仍可访问 Node**:缺失的全局变量用于保证 API 可移植性,而非隔离。
|
||||
- **终止只能报告宿主观察到的启动**:`agentsStarted` 不包括仍在 worker 侧排队等待并发、且在强制终止后无法得知的调用。
|
||||
- **不注入默认可用的定时器、文件系统或网络,但逃逸代码仍可访问 Node**:这些缺失的全局变量属于可移植性 API 设计,而非隔离措施。
|
||||
- **终止只能报告宿主观察到的启动**:`agentsStarted` 不包括因并发限制仍在 worker 侧排队、且在强制终止后无法得知的调用。
|
||||
- **跨 realm 错误在脚本内无法通过 `instanceof Error`**:工作流作者必须根据 `name` 和 `code` 等稳定字段分支。
|
||||
|
||||
Reference in New Issue
Block a user