Files
deepseek-harness/packages/subagent/subagent-dsh-sdk/README.zh.md

98 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# @deepseek-ai/dsh-subagent-dsh-sdk
[English](README.md) | 中文
SDK provider 把每个子代理作为一个完整的 DeepSeek Harness 运行时跑在全新子进程里,经由 [TypeScript SDK 客户端](../../sdk/sdk-client/README.md)走 stdio JSON-RPC 驱动。它是 [`subagent-acp`](../subagent-acp/README.md) 之外的第二个进程外后端差异在线协议与子进程契约ACP 后端能驱动任何 Agent Client Protocol 代理;本后端专门驱动 harness SDK 运行时(`dsh-jsonrpc-agent` bin 或打包可执行文件),因此子进程是一个完整的对等 harness——自有 `cordis.yml` 决定的组成、会话持久化、模型路由与工具。
## 启动与所有权
`start(request)` 先解析子进程工作目录,经 `DeepSeekHarness` 生成运行时,并在履行前完成 `initialize` 握手(携带配置的 `provider`/`model` 路由)。因此履行意味着子运行时已就绪、所有权已移交调用方。生成、握手或发布前取消的失败只在子进程被收割之后拒绝;工作目录解析失败在生成任何东西之前拒绝。
工作目录的解析与 ACP 后端完全一致,经由接缝共享的进程外助手([`dsh-subagent`](../subagent/README.md)):设置了 `cwd` 覆盖则用之(加载时校验一次),否则用发起委托的父会话 cwd——绝不用服务器进程自己的 cwd。解析出的路径同时成为子进程 cwd 与其 SDK 会话的工作区 cwd。
返回的 run id 铸造于父命名空间;子运行时的会话 id 只存在于子进程内部。发布之后provider 跑一个 SDK 回合,并从子会话事件中读取答案:最后一条完整 `assistant/message`,或回合被截断时已累积的 `text-delta` 流——部分答案在取消与错误路径上都得以保留。
`dispose()` 幂等:先把结果就地定格为 `aborted`(线上没有 prompt 取消方法),再关闭运行时——一次有界的协议 `shutdown` 请求,随后是共享的 stdin-EOF → SIGTERM → SIGKILL 阶梯直到真正退出。
## 停止原因映射
子进程在 `session.finished` 上以结构化 `TurnEndReason` 报告回合结局provider 把它映射进接缝词汇表。`completed``completed``max-tokens``max-tokens``aborted``aborted`;其余一切——`error``interrupted``disposed`、未来变体、或根本没跑回合——映射为 `error`,不洁终止绝不报告为成功。发布后的传输层失败经 `onError` 诊断汇(接到 `ctx.logger.warn`)压平为 `stopReason: 'error'`;接缝契约禁止 `result` 拒绝。
## 能力与上下文
Provider 不宣告任何启动期能力(`outputSchema`/`depthLimit`/`toolFilter`/`persona` 全为 false`inheritsParentContext: false`:子进程是另一进程里的全新运行时,唯一来自父方的输入是工作区 cwd。基于本 provider 的 `dsh-tool-subagent` 部署应设置 `maxDepth: 'provider-managed'`——子 harness 拥有自己的递归预算。
## 配置
| 键 | 默认 | 含义 |
|---|---|---|
| `providerName` | `dsh-sdk` | `ctx.subagents` 上的注册名。 |
| `command` | 必填 | 每次 run 生成的可执行文件(子运行时 bin 或打包 exe。 |
| `args` | `[]` | 命令参数(通常是子进程的 `cordis.yml` 路径)。 |
| `cwd` | 父会话 cwd | 工作目录覆盖;校验规则与 [`subagent-acp`](../subagent-acp/README.md) 相同。 |
| `provider` | `deepseek` | 写入子进程 `initialize` 的 provider 路由。 |
| `model` | `deepseek-v4-flash` | 写入子进程 `initialize` 的模型。 |
| `env` | `{}` | 在凭据擦除后的父环境之上叠加的显式子环境(例如子进程自己的 `DEEPSEEK_API_KEY`,或 `DSH_CORDIS_CONFIG`)。 |
| `shutdownTimeoutMs` | `1000` | 处置期间协议 `shutdown` 交换的时限。 |
| `disposeEofGraceMs` | `6000` | stdin EOF 之后、平台终止之前的宽限。 |
| `disposeGraceMs` | `3000` | 终止后的退出确认窗口POSIX 在 SIGTERM 之后、SIGKILL 之前也等待同样时长。 |
```yaml
- id: subagent-dsh-sdk
name: '@deepseek-ai/dsh-subagent-dsh-sdk'
config:
providerName: dsh-sdk
command: node
args: ['./packages/examples/jsonrpc-demo/lib/bin.js', './examples/jsonrpc-agent/cordis.yml']
env:
DEEPSEEK_API_KEY: !!js process.env.DEEPSEEK_API_KEY
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
config: { provider: dsh-sdk, toolName: subagent, maxDepth: 'provider-managed' }
```
## 进程边界
子环境以 [`dsh-subprocess`](../../subprocess/README.md) 接缝的 `scrubbedParentEnv()` 为基底——移除形似凭据与 `DSH_*` 的环境变量——再在擦除之后合并显式 `config.env` 值。子进程由 SDK 客户端生成而非经 `ctx.subprocess`subprocess README 记载的 SDK 托管传输例外因此本后端自行应用该擦除。JSON-RPC 线就是真实的序列化边界。
本包没有默认导出。否则 Cordis loader 解包会隐藏具名 `inject` 元数据;见[事后分析 0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md)。
免密钥测试通过真实 stdio 驱动 SDK 客户端包的脚本化伪运行时,还包括一个 Loader 组合 e2e子进程是真实的第二个 harness 运行时,端到端证明父会话 cwd 继承(`tests/loader-composition.e2e.ts`)。
## Model Experience
### Child-agent request
#### What the model sees
子运行时的模型收到独立任务作为其用户消息,加上该运行时自己配置的系统提示、工具与全新会话。它收不到任何父对话。本 provider 不宣告可选启动期能力,因此本地服务会拒绝需要 persona、工具过滤、深度强制或结构化输出的请求而不是静默省略。
#### Token effect
子进程支付一份独立的完整上下文与自己的多步历史。这些 token 绝不进入父上下文。
#### KV Cache effect
独立于父请求缓存。每个 SDK 子进程只能复用在其自身 provider、模型、组成与历史下完全相同的前缀子步骤在此之外只增不改。
### Parent tool result, indirectly
#### What the model sees
经由 `dsh-tool-subagent`,父方只收到子进程的最终助手文本(或累积的部分文本),或该消费者精确的停止原因错误——收不到中间消息与工具流量。
#### Token effect
父输入只增长最终结果或错误,其大小依数据而定,保留至压缩。本 provider 自身不给父方增加任何 schema。
#### KV Cache effect
只追加;新可见内容跟在可复用请求前缀之后,不使既有 KV 缓存条目失效。
## Known Limitations and Deferred Work
- **每次 run 一个全新运行时进程** —— 无池化harness 运行时要启动完整插件树,单次生成成本高于 ACP 后端的典型子进程。
- **无可选启动期能力** —— 父方无法在子进程内强制 `outputSchema`、深度、工具过滤或 persona请改为配置子进程自己的 `cordis.yml`
- **子进程的转录留在其自己的会话根** —— 父日志只记录委托工具调用/结果(接缝的子隔离规则);流式 `session.event` 通道只用于提取输出,不桥接进父日志。
- **仅限本地子进程** —— 解析出的 cwd 是本地路径;远程运行时需要自己的后端。