模块定位
packages/core/system-prompt 负责每个 step 的系统提示组装。它不是简单字符串拼接器,而是一个 registry:插件注册 section、runtime context、tool schema provider 和变量,loop 每次请求前按当前 agent scope 组装。
源码入口:
packages/core/system-prompt/src/index.tspackages/core/tools/src/index.tspackages/context/*docs/subsystems/system-prompt.md
组装输入
一次 prompt assembly 包含:
- 静态 harness identity。
- deployment persona。
- 插件注册的 prompt sections。
- runtime contexts。
- tool schemas。
- prompt variables。
system-prompt/assemblewaterfall 的最终变换。
1 | flowchart LR |
Section 机制
插件通过:
1 | ctx.systemPrompt.section({ |
注册 section。Section 按 order 升序拼接。常见 order band:
-100:harness identity。0:deployment persona。100–199:tool guidance。
同一 scope 下 section name 不能重复。Agent scope 可以 shadow global section。
complete: true 是特殊机制:有效 complete section 会成为完整 system prompt,压过普通 sections。这个能力适合兼容某些部署,但也危险,因为它需要保证 Code Mode、工具协议、runtime context 等仍然一致。
Prompt Variables
变量形如:
1 | {{model}} |
插件通过 ctx.systemPrompt.variable(name, provider) 注册变量。渲染时严格检查:
- 未知变量报错。
- 已注册但无值报错。
- malformed braces 报错。
这是 fail loud 设计。它宁可让一次 turn 失败,也不把坏 prompt 发给模型。
Tool Schemas 是 Prompt 的一部分
虽然 provider wire 协议里 tool schemas 往往和 system prompt 分开发送,但在 Harness 里它们同属一次 PromptAssembly。原因很直接:模型被告知“能做什么”必须和 system prompt 一致。
ToolRuntime 会自动注册 tool schema provider。工具 restriction、agent-scoped shadow、Code Mode presentation 都会影响当前 agent 看到的工具 schema。
toolOrder
toolOrder 是配置级工具排序。它要求列表中有一个 '<unlisted-tools>' rest entry。
为什么要这个配置?因为 tool schema 顺序会影响 prompt 和 KV cache。靠插件加载顺序不稳定,显式排序更可控。
错误配置会 fail loud:
- 没有 rest entry。
- rest entry 多于一个。
- 重复工具名。
- 配置中列出的工具不存在。
Runtime Context
ctx.systemPrompt.context() 注册动态上下文。它每次 assembly 都会被调用,产生带 source 的 runtime context snapshot。includeRuntimeContext: false 或 scoped suppressor 可以禁用 runtime context,但不会禁用底层服务和策略。
典型 runtime context:
- workspace instructions。
- 当前时间。
- tmux context。
- session reference。
system-prompt/assemble
这是一个 waterfall。Listener 可以修改或替换 assembly。它是非常强的扩展点,也因此要谨慎:如果替换 tools 或 sections,要保证工具协议仍然可用。例如 Code Mode 需要 run_code schema 和 SDK section 一致。
常见坑
第一,prompt section 和 tool guidance 是不同东西。限制工具不会自动删除某个独立 prompt section。
第二,变量没有 escape 语法。需要输出字面 {{...}} 时要小心。
第三,section order 相同会按注册顺序 tie-break,这不是稳定设计来源。
第四,完整覆盖 system prompt 后,要自己维护工具协议。
继续读源码
packages/core/system-prompt/README.mddocs/subsystems/system-prompt.mdpackages/context/agent-instructions/README.mdpackages/core/tools/README.md#code-mode