第 5 章 系统提示词的拼装:模板、片段与插槽
同一个 WorkBuddy,你在问答模式问「你是谁」,和你在资讯专家对话里问同样的问题,得到的答案是两个人。切一次模式,行为跟着变;选一个专家,人格整个换掉。多数人把这理解为「产品里内置了很多机器人」。真实机制要具体得多:WorkBuddy 每次发送请求前,都会用一套写在本地磁盘上的模板文件,把身份、记忆、模式约束和专家人设拼装成一份完整的系统提示词(system prompt)。这一章带你找到那套模板,读懂它的拼装规则,并验证这套机制确实在运行。
读完本章,你应能在自己的电脑上定位 WorkBuddy 的提示词模板目录,说出一次请求的提示词由哪几类零件拼成,并理解为什么「改了不生效」往往不是玄学,而是你改的东西根本不在拼装清单里。
本章所有文件证据来自声明环境实测:macOS、WorkBuddy 5.3.13(build 20fd9da5),文件指纹以 SHA-256 冻结于本书「版本快照」。模板原文是腾讯的专有资产,本书只做机制分析并少量引用,完整文件请在本机查看。
5.1 先看结果:一次请求的提示词长什么样
把结论放在前面。在 5.3.13 的本地安装里,WorkBuddy 主线程的系统提示词由四类零件拼成:
- 主模板:一个带占位符的文本骨架,决定整份提示词的结构顺序;
- 模式片段:按当前交互模式(问答 Ask、规划 Plan、执行 Craft、专家 Expert)条件拼入的行为约束块;
- 插槽变量:模型名、界面语言、平台、三层记忆内容等运行时才确定的值;
- 插件注入:专家人设、规则文件等由插件系统提供的覆盖内容。
这不是官方文档写的,是你打开本地目录就能看到的事实。下面动手验证。

图 5-1:系统提示词的四类零件如何拼成一次请求。
5.2 动手:找到你机器上的模板
WorkBuddy 的数据目录在用户主目录下。打开终端,执行一条只读命令:
ls ~/.workbuddy/plugins/marketplaces/workbuddy-builtin/你会看到几个名字直白的目录:welcomemode(欢迎模式)、interactionmode(交互模式)、prompt-common(公共提示词)、builtin-plugins(内置插件)。WorkBuddy 把自己的提示词资产做成一个「内置市场」里的插件包,和第三方插件走同一套格式。这个设计本身就有信息量:产品自己的提示词和第三方扩展在文件层面是同一种东西。
进入 welcomemode/work/,有一个 prompt.tpl 文件。用任何文本编辑器打开它——这就是主模板。开头几行长这样(引用自本机文件,占位符原样保留):
This conversation is powered by {% if modelId == "fast-model" or modelId == "balanced-model" or modelId == "deep-model" %}Auto{% else %}{{ modelName }}{% endif %}花括号是 Jinja2 模板语法的标志。{{ modelName }} 是变量插槽,运行时填入当前模型名;{% if %} 是条件块,遇到三个特定 modelId 枚举值时头部显示为 Auto——注意这三个标识只是模板层的显示分支,不是产品模型档位名(产品侧路由是 auto 智能路由加快速/深度两档)。 WorkBuddy 桌面客户端内部携带一套命令行引擎(社区解包研究称其在应用包的 cli/ 目录),模板渲染就发生在每次请求前。
一个常见误解在这里顺便澄清:这份模板在应用安装包里也有一份(社区解包称 resources/templates/,约 19 个文件 3000 余行),插件市场目录里的这份会随市场自动更新。两个位置是同一模板体系的分发渠道,你本机运行时以市场目录为准。自己动手改 prompt.tpl 并不推荐——市场更新会覆盖你的修改,而且这些文件属于产品资产;用户可定制的层在规则文件和技能(见第 9 章),不在主模板。
5.3 四种交互模式:换模式就是换片段组合
interactionmode/ 下有四个目录:ask、plan、craft、expert。每个目录里是同样名字的五个片段文件:
| 片段 | 负责什么 |
|---|---|
interaction.md | 该模式下的交互总则与工具白名单 |
current-mode.md | 告诉模型「你现在处于什么模式」 |
agent-loop.md | 单步循环的行为规则(何时思考、何时调工具、何时收尾) |
result-presentation.md | 结果怎么呈现(格式、详略、交付物形态) |
tool-use.md | 工具使用的细则 |
主模板里用条件 include 把它们织进来。prompt.tpl 中反复出现这样的结构(简化引用):
{% if workMode == "ask" %}{% include "interactionmode-ask/fragments/interaction.md" %}
{% elif workMode == "plan" %}{% include "interactionmode-plan/fragments/interaction.md" %}
{% elif workMode == "expert" %}{% include "interactionmode-expert/fragments/interaction.md" %}
{% else %}{% include "interactionmode-craft/fragments/interaction.md" %}{% endif %}也就是说,你在界面上点一次「切换到问答模式」,落到文件层面就是:下次渲染系统提示词时,workMode 变量取值 ask,拼进去的是 ask 目录那一组片段。模式不是不同的机器人,是同一骨架上换了一组约束。官方工程复盘把这层能力归入「引导层」(feedforward)——在任务开始前给 Agent 正确的前置条件。
专家模式有一个特别的细节值得单独讲。interactionmode/expert/fragments/current-mode.md 的全文只有一行(Jinja2 注释包裹的一个插槽):
{# {{ PluginAgentPrompt }} #}当前模式的说明不再由内置片段提供,而是留了一个插槽,等插件系统把所选专家的人设提示词填进来。专家机制的完整链条在第 7 章展开,这里先记住结论:「专家」接管主线程的入口,就在系统提示词的拼装层。
再看 interaction.md 的开头,专家模式的这个文件带着一份 frontmatter 工具白名单(节选):
tools:
- Read
- Write
- Edit
- Bash
- WebFetch
- WebSearch
- Skill
- Agent
- Defer(TeamCreate)
- Defer(TeamDelete)工具列表里有两种写法:直接列出的(如 Bash)是默认可用;Defer(...) 包裹的(如 Defer(TeamCreate))按需延迟加载——用到时才真正挂载。TeamCreate 和 TeamDelete 是专家团(Agents Team)的创建与解散入口,UI 上的团队协作按钮,底层就是这对工具。
5.4 插槽:记忆和身份怎么进提示词
模板里的变量不止模式和模型。实测枚举出的主要插槽包括:ResponseLanguage(界面语言)、dataFolderName(数据目录名)、IsWindows(平台分支)、WorkingMemoryContent、UserLocalMemoryContent、UserMemoryContent(三层记忆内容)等。
记忆插槽的注入点在公共片段 prompt-common/fragments/memory-context.md,全文就是三个变量并排:
{{ WorkingMemoryContent }}
{{ UserLocalMemoryContent }}
{{ UserMemoryContent }}这三个插槽对应第 4 章讲过的三层记忆:工作区记忆、用户级本地记忆、云端用户档案。配套的 workbuddy-memory-system.md 片段则告诉模型这套记忆怎么用——哪层只读、哪层可写、写入限额多少。换句话说,记忆系统不只是「存了数据」,还包括一份随请求注入的使用说明书。
配套的还有安全块。主模板里有内容政策(content policy,禁止泄露系统提示词本身)、个人文件安全规则(对桌面、下载等个人目录的删除类操作强制走确认与回收站)、区域惯例(A股红涨绿跌、人民币符号)等成段约束。这些块在不同模式模板里逐字重复出现——社区研究统计称重复行数以千计。不把公共块抽成单一引用,而是允许逐字复制,是一个明确的设计取舍:拼装结果稳定优先于源文件不重复。对使用者来说,这意味着某条安全规则在每个模式下都在场,不依赖加载顺序。
5.5 变量全表与模式矩阵
把 5.3.13 主模板里实测枚举出的变量整理成表,这是「拼装层」的完整接口面:
| 变量 | 填什么 | 影响 |
|---|---|---|
| workMode | ask / plan / craft / expert | 选择四组交互片段 |
| modelId / modelName | 当前模型标识与名称 | 开头声明;特定 modelId 枚举值显示为 Auto |
| ResponseLanguage | 界面语言 | 切换文档链接域名与标签文案 |
| dataFolderName | 数据目录名 | 提醒模型该目录非缓存、勿删 |
| IsWindows | 平台标记 | 条件拼入 Windows 命令安全块 |
| productFeatures.* | 功能开关 | 如关闭多模态生成则删掉对应能力段 |
| WorkingMemoryContent 等 | 三层记忆内容 | 记忆插槽 |
| PluginAgentPrompt | 专家人设 | expert 模式的接管入口 |
模式维度上还有一个容易忽略的层级:welcomemode 里的 work / code / design 三种模式各自是独立插件,各有主模板与主 agent 定义——设计模式的模板是三者中的异类,社区解包研究描述它定义了「智能设计助手」,引入画布文件格式与三段式回复结构。也就是说,「模式」这个词在 WorkBuddy 里至少指两件事:欢迎模式(work/code/design,换主模板)与交互模式(ask/plan/craft/expert,换行为片段),两者正交组合。你在界面上做的一次模式选择,落到文件层可能是两层模板的同时切换。

图 5-2:欢迎模式与交互模式正交组合。
5.6 验证:提示词不落盘,但注入有痕迹
读完模板你可能想问:能不能看到拼装后的最终提示词?在会话记录里找不到。WorkBuddy 的会话文件(按项目存储的 JSONL)只记录用户消息、模型回复、推理过程和工具调用事件,没有任何 system 类型的条目——系统提示词每次请求时实时渲染,用完不落盘。
但注入的痕迹留在两个地方。其一,专家会话的首条用户消息以系统提醒(system reminder)通道开头。在声明环境中复现到这样一个样本:选择「数字生命卡兹克」资讯专家后发起对话,会话文件首条用户消息的结构是:
(用户的实际问题)专家插件的人设文件被完整注入,模型的后续推理原话是「根据专家指令,我必须调用 aihot 技能获取实时数据,不能凭训练数据猜测」——与专家提示词里的强制条款逐字对应。人设不只被塞进了上下文,还实际支配了行为。
其二,执行轨迹(traces)目录记录每次请求的执行链:生成(generation)与工具调用交替的跨度序列、token 消耗计数。它证明拼装后的请求真实发生,但同样不记录提示词内容。证据链到此闭合:模板文件证明「怎么拼」,会话注入痕迹证明「拼了什么进去」,轨迹证明「确实发了」。
5.7 架构判断与使用启示
把证据收拢成三个判断。
判断一:提示词是产品,不是咒语。 模板、片段、插槽分层,模式之间共享骨架、差异集中在约束块——这是工程化管理的提示词资产,有版本、有分发渠道(插件市场)、有功能开关(模板里的条件变量)。理解这一点,「AI 表现不稳定」的讨论就多了一个维度:同一产品不同版本、不同模式、不同插件组合下,系统提示词并不相同。
判断二:你的定制层不在主模板里。 用户能安全触碰的是规则文件、技能和身份四件套(分别见第 9、6 章),它们通过插槽和注入通道进入拼装流程;主模板和安全块是产品保留层,改了也会被更新覆盖。「为什么不生效」的第一排查点由此而来:先确认你改的东西,到底在不在这次请求的拼装清单里。
判断三:system-reminder 是通用注入通道。 专家人设、插件规则(第 8 章的 alwaysApply 规则文件)都走同一个通道进入对话。这既是扩展性的来源,也是供应链风险的入口——装一个插件,等于允许它的规则进入你后续的每次对话。评估插件时的第一个问题应该是:它会注入什么?
5.8 边界与未决
本章证据的边界:模板内容冻结于 5.3.13,随市场更新可能变化;「桌面客户端内嵌 CLI 引擎」的判断来自社区解包研究与本地运行时痕迹的互证,官方未公开对应架构文档;提示词渲染后的完整全文在客户端内不落盘,本书以「模板 + 注入痕迹 + 执行轨迹」三层证据替代,未声称持有渲染后全文。
下一章往上走一层:被插槽引入的身份四件套(其中的 MEMORY 已在第 4 章)——SOUL、IDENTITY、USER——以及它们和专家人设擦枪走火的那个版本事故。