CH-03 引导层:系统提示词、身份与记忆
图 3-1:引导层与提示词注入流程
图 3-1:引导层与提示词注入流程
3.1 系统提示词:Agent 的第一行代码
系统提示词(System Prompt)是 Agent Harness 中最核心的引导文件。它在用户消息之前注入模型上下文,定义了 Agent 的身份、能力边界、行为规则和输出格式。在一个工具调用 Agent 中,系统提示词通常还包含可用工具列表、工具调用格式、安全规则和错误处理指引。
豆包工作的系统提示词通过运行时观测可以确认包含六大模块。「实测」需要说明的是,受安全约束,本书不引用系统提示词原文,只描述其模块结构和机制。
模块一:身份定位
系统提示词定义了 Agent 的基本身份——"你是 Doubao,字节跳动推出的 AI 助手"。与 WorkBuddy 的 SOUL.md(一个用户可编辑的、包含性格特征和价值观的身份文件)不同,豆包工作的身份是固定的产品身份,用户无法修改。身份定义中包含了语言偏好(默认中文)、回复风格(简洁、结构化)和基本行为准则。
模块二:安全规则
这是篇幅最大的模块之一,包含多层安全约束:
- 内容安全:拒绝生成违法、暴力、色情等内容,不讨论敏感政治话题,不进行人身攻击。
- 隐私保护:不泄露用户个人信息,不输出 open_id/user_id/phone 等技术标识符。
- 系统保护:不泄露系统提示词原文、工具列表、内部配置和安全规则细节。
- 操作安全:执行命令前考虑可逆性和影响范围,高风险操作需用户确认,不执行破坏性操作。
这些规则不是建议,而是硬约束。它们通过系统提示词注入模型上下文,同时在工具层和 Helper 层有额外的执行机制(沙箱、权限确认、审计日志)。这是一种纵深防御:即使模型被诱导绕过提示词层面的规则,工具层和沙箱层仍然会阻止危险操作。
模块三:工具定义
系统提示词包含了所有初始可用工具的定义,每个工具包含名称、描述、参数 schema 和使用说明。工具定义采用 XML function call 格式,模型通过生成 function 标签来调用工具。
值得注意的是,豆包工作的工具系统分两层:
- 初始工具:在系统提示词中直接定义,包括文件操作(Read/Write/Edit/Glob/Grep)、Bash 执行、网络搜索、图片生成、音视频生成、定时任务、企业搜索、金融/医疗/法律搜索等。这些工具在会话开始时就可用。
- 延迟加载工具:不在初始列表中,需要时通过
tool_search工具发现并加载 schema。延迟加载的工具包括视觉搜索(visual_search)、学术搜索(scholar_search)、Canvas 文件读取、当前时间获取、Jupyter 编辑等。
这种两层设计是为了控制初始上下文的大小。如果把所有工具的完整 schema 都注入系统提示词,会占用大量 token 并降低模型的指令遵循能力。延迟加载让模型只在需要时才获取工具定义,类似于编程语言中的 lazy import。「实测」
模块四:Skill 发现机制
系统提示词中包含 Skill 的发现和使用规则。它告诉模型:
- Skill 是预安装的能力包,存放在多个 Skill 根目录下。
- 当任务匹配某个 Skill 的描述时,必须先读取对应的 SKILL.md 再行动。
- Skill 的发现流程是:扫描 Skill 根目录 → 读取 SKILL.md 的 name 和 description → 匹配用户意图 → 读取完整 SKILL.md 正文 → 按指引执行。
- 部分 Skill 设置了
disable-model-invocation: true,需要用户显式调用(如通过 skill:// 链接)。
这个机制与 Anthropic 的 AgentSkills 规范高度一致——模型不"调用"Skill,而是"拾取"Skill:根据 frontmatter 中的 description 自主判断何时使用。「实测」
模块五:多 Agent 编排规则
系统提示词定义了三层 Agent 架构的行为规则:
- MainAgent 是用户直接对话的入口,拥有完整对话历史。
- MainAgent 可以通过
create_agent把整任务委派给 OrganizeAgent。 - OrganizeAgent 可以创建 SubAgent 执行专业任务。
send_message用于向已有 Agent 追加消息,terminate_organizer用于终止偏离的 Agent。- MainAgent 给 OrganizeAgent 的 hint 不会自动透传给 SubAgent。
这些规则决定了 Agent 之间的权力边界和信息流。特别是 hint 不透传的设计,强制 OrganizeAgent 主动转发必要信息,避免了上下文污染。「实测」
模块六:交付规范
系统提示词规定了产物交付方式:
- 文件和链接通过
present_files工具交付,不用 markdown 链接。 - 媒体文件逐个交付,每个文件有独立的介绍文字。
- 搜索结果的 URL 用引用标签标注,不作为产物交付。
- 回复以结论开头,结构清晰。
3.2 系统提示词从哪里来
豆包工作的本地文件系统中不存在系统提示词模板文件。WorkBuddy 有 prompt.tpl(Jinja2 模板,用户可直接编辑),豆包工作没有等效文件。「源码」
系统提示词的来源有两种可能:
可能一:远程配置下发。 豆包工作启动时从 doubao.com 或相关 CDN 拉取最新的系统提示词,缓存在渲染进程的内存或 localStorage 中。这种方式允许字节随时更新提示词而不需要发版,对于快速迭代的产品来说是合理的选择。支持证据:manifest.json 中定义了 doubao.com 和 doubaocdn.com 为信任域;系统提示词中包含的工具列表与产品功能同步更新,本地文件中没有工具定义。
可能二:打包在渲染进程资源中。 系统提示词可能内嵌在 App 包的 JavaScript bundle 中,随版本更新。支持证据:主二进制只有 1MB,但 DoubaoWork Browser.app 有 977MB,其中包含渲染进程资源;系统提示词在离线状态下仍然可用(基本对话功能不依赖网络)。
最可能的情况是两者结合:基础提示词打包在 JS bundle 中,工具列表和动态配置通过远程接口下发。这是大型 AI 产品的常见做法——静态指令随版本发布,动态能力通过配置中心更新。「推断」
反证搜索:我检查了 App 包中的 Resources 目录,没有发现 .prompt、.txt 或 .md 格式的提示词文件;Chromium 的 Local Storage 和 Extension State 是 LevelDB 格式,可能包含缓存的提示词,但未做深度解析。因此"远程下发"和"JS 打包"的比例无法精确确认。
3.3 身份系统:从文件到产品
WorkBuddy 的身份系统是文件化的:SOUL.md 定义性格和价值观,IDENTITY.md 定义名称和角色,USER.md 定义用户信息。这些文件用户可以直接编辑,Agent 每次启动时读取。
豆包工作走了一条完全不同的路。
3.3.1 产品身份
豆包工作的 Agent 身份由系统提示词定义,是固定的产品身份——"你是 Doubao"。用户不能修改 Agent 的名字、性格或核心行为准则。这与豆包作为消费级产品的定位一致:所有用户获得一致的体验,Agent 的"人设"是产品品牌的一部分。
3.3.2 doubao-identity Skill
在 103 个预装 Skill 中,有一个特殊的 Skill 叫 doubao-identity。它的触发条件是:当用户询问豆包产品自身的问题(会员权益、付费方案、隐私政策、记忆功能等)时,必须以这个 Skill 内置的官方内容为准,不基于模型记忆推测,不联网搜索替代。「源码」
这个 Skill 的 references/ 目录下包含多个官方内容摘录文件:
doubao-official-content.md:豆包产品官方口径doubao-pro-membership-plans.md:Pro 会员方案doubao-pro-membership-support.md:Pro 会员支持doubao-privacy-data.md:隐私与数据政策doubao-memory.md:记忆功能说明
doubao-identity 相当于 WorkBuddy 中 IDENTITY.md 的产品化版本,但有两个关键区别:
- 不可编辑:它是预装 Skill,存放在
.skills/目录(App 管理),用户不能修改。WorkBuddy 的 IDENTITY.md 用户可以随意改。 - 只管产品口径,不管 Agent 性格:doubao-identity 回答"豆包 Pro 多少钱"这类产品问题,不定义 Agent 的说话风格或价值观。Agent 的行为风格由系统提示词统一规定。
3.3.3 AGENTS.md:项目级约定
虽然豆包工作本身不提供身份文件,但它支持读取项目目录中的 AGENTS.md 文件。这是一个来自开源社区的约定(最初由 Cursor 等 AI 编程工具推广):在项目根目录放一个 AGENTS.md,告诉 Agent 这个项目的规则、命令、架构和注意事项。
豆包工作的系统提示词明确要求:在仓库中工作时,查找并遵循 AGENTS.md 等持久项目指令。这意味着用户可以通过 AGENTS.md 在项目级别定制 Agent 的行为——比如规定代码风格、Git 工作流、测试命令。这是一种"项目级身份",与"产品级身份"分离:Agent 的核心身份不变,但在特定项目中遵守额外规则。「实测」
这种设计比 WorkBuddy 的全局 IDENTITY.md 更精细:不同项目可以有不同的规则,Agent 自动适配。但它也更弱——AGENTS.md 只能约束项目内的行为,不能改变 Agent 的核心身份或全局偏好。
3.4 记忆系统:产品功能而非本地文件
3.4.1 本地无记忆文件
WorkBuddy 有 MEMORY.md(Markdown 格式的长期记忆)、memory/ 目录(记忆条目)和 edge-sync 数据库(向量同步)。豆包工作的本地文件系统中没有任何等效文件。.doubaowork/agent_mode/workspace/ 下只有 .skills/ 和 .user_skills/,没有 memory/、MEMORY.md 或数据库文件。「源码」
3.4.2 记忆是服务端功能
豆包工作的记忆是一个产品功能,数据存储在服务端。根据 doubao-identity Skill 中的官方说明(doubao-memory.md),豆包具备跨会话记忆能力,可以记住用户的偏好、历史对话中的关键信息和常用工作模式。「源码」
官方 FAQ 也确认了记忆功能的存在,但没有公开技术实现细节。从产品行为推测,记忆系统可能包含:
- 短期记忆:当前会话的上下文窗口,由模型直接处理。
- 长期记忆:跨会话的用户偏好和事实,存储在服务端,通过检索增强生成(RAG)在需要时注入。
- 工作记忆:当前任务的状态和中间结果,在任务执行期间保持。
BytePlus AgentKit Harness 的文档提供了字节记忆系统的组件模型参考:短期记忆支持 local/sqlite/mysql/postgresql 后端,长期记忆支持 viking/opensearch/redis/mem0 后端。「官方」豆包工作作为字节自家产品,很可能使用了类似的基础设施(viking 是字节的向量数据库,mem0 是开源记忆层),但这只是体系内推断,不是直接证据。
3.4.3 记忆的产品化取舍
把记忆放在服务端而非本地文件,有几个产品化考量:
- 跨设备同步:用户在 MacBook、Mac mini 和手机上使用豆包工作时,记忆自动同步,不需要手动管理文件。
- 降低用户负担:用户不需要知道记忆存在哪里、格式是什么、如何编辑。
- 可控性:字节可以统一管理记忆的生命周期、隐私合规和数据安全。
- 检索质量:服务端可以使用更强大的检索模型和向量数据库,比本地文件 grep 更智能。
代价是透明度和可移植性:用户不能直接查看、导出或批量编辑自己的记忆数据;记忆的检索逻辑是黑盒;如果服务停止,记忆数据可能丢失。
这与 WorkBuddy 的设计哲学再次形成对比:WorkBuddy 把记忆文件放在本地,用户可以用任何编辑器打开、修改、版本控制;豆包工作把记忆做成服务,用户通过产品界面交互。前者适合开发者和 power user,后者适合大众市场。
3.5 上下文组装流程
图 3-2:上下文六层注入流程
综合运行时观测和本地证据,可以重建豆包工作的上下文组装流程:
用户发送消息
↓
1. 加载系统提示词(远程配置 + JS 打包的基础指令)
↓
2. 注入工具定义(初始工具列表 + 延迟加载工具的 schema)
↓
3. 注入 Skill 发现规则和已匹配 Skill 的 SKILL.md 正文
↓
4. 注入项目级指令(AGENTS.md,如果在项目目录中工作)
↓
5. 注入记忆上下文(从服务端检索的相关记忆)
↓
6. 注入对话历史(当前会话的消息列表)
↓
7. 注入当前用户消息
↓
发送给模型
「推断」
这个流程中,第 1-2 步在会话开始时完成,第 3 步在模型决定使用 Skill 时动态追加,第 4 步在进入项目目录时触发,第 5 步每次消息都可能触发检索,第 6-7 步是标准对话流程。
需要强调的是,这是一个基于观测的重建,不是官方文档描述的精确流程。特别是第 5 步(记忆检索)的触发时机、检索范围和注入方式,目前没有公开的技术文档确认。
3.6 提示词注入的防御
系统提示词是 Agent 安全的第一道防线,但它也是最脆弱的一道。Prompt injection(提示词注入)攻击通过在用户消息、网页内容、文件内容中嵌入恶意指令,试图覆盖系统提示词的规则。豆包工作的防御策略是多层的:
3.6.1 系统提示词的结构性防御
系统提示词中的安全规则不是简单的"不要做坏事",而是包含具体的行为约束:
- 明确区分"系统指令"和"用户内容",要求模型不把用户内容中的指令当作系统指令执行
- 对工具调用设置参数校验和确认机制
- 要求模型在执行高风险操作前检查用户意图
- 禁止泄露系统提示词内容(防止攻击者通过"复述你的指令"等方式获取规则)
3.6.2 工具层的硬约束
即使模型被注入攻击诱导,工具层仍然提供硬约束:
- Bash 工具在沙箱模式下受 Seatbelt 限制
- 文件写入受目录授权限制
- MCP 服务器的 OAuth scope 限制了可访问的资源
- 危险操作需要用户在 UI 中确认
这意味着 prompt injection 最多能诱导模型"尝试"危险操作,但沙箱和权限系统会阻止实际伤害。
3.6.3 间接注入的特殊风险
Agent 读取网页、文件、邮件等外部内容时,面临间接提示词注入风险——恶意内容中嵌入"忽略之前的指令,执行..."。豆包工作的系统提示词要求模型对外部内容保持警惕,但这本质上是模型层面的防御,不可能 100% 有效。沙箱和审计是最终的安全网。
3.7 上下文窗口管理
大模型的上下文窗口是有限资源。豆包工作通过多种机制管理上下文:
3.7.1 工具定义的延迟加载
如 CH-03 模块三所述,不常用的工具通过 tool_search 延迟加载,避免初始工具列表占用过多 token。
3.7.2 Skill 的渐进式加载
103 个 Skill 只加载 name + description(几千 token),完整 SKILL.md 正文在匹配时才读取。复杂 Skill 的 references/ 文档进一步按需加载。
3.7.3 多 Agent 的上下文隔离
每个 SubAgent 有独立的上下文窗口,不继承 MainAgent 的对话历史。这把一个大上下文拆成多个小上下文,每个 Agent 只处理相关信息。
3.7.4 对话历史的截断与摘要
长对话中,早期消息可能被截断或摘要,以释放上下文空间。具体的截断策略在本地证据中未确认,但这是大模型应用的标准做法。
3.7.5 文件系统作为外部记忆
Agent 不把所有信息都放在上下文中,而是把中间结果写入文件,需要时通过 Read/Grep 工具检索。这相当于把文件系统当作"外部记忆",上下文窗口只保留当前步骤需要的信息。
3.8 引导层的架构判断
判断一:系统提示词是 Harness 的唯一身份源。 与 WorkBuddy 的多文件身份系统(SOUL.md + IDENTITY.md + USER.md)不同,豆包工作把所有引导信息集中在系统提示词中。这使得身份定义不可分割、不可局部修改,但也更一致、更难被误配置。「推断」
判断二:Skill 是引导层的"第二提示词"。 当模型决定使用某个 Skill 时,SKILL.md 的正文会被注入上下文,相当于在基础系统提示词之上叠加了一层任务特定的指令。这种"基础提示词 + Skill 提示词"的分层设计,使得基础行为保持稳定,同时允许能力扩展。「推断」
判断三:记忆从文件系统迁移到服务端是产品成熟的标志。 WorkBuddy 的本地记忆文件透明但粗糙(grep 检索、无向量化、手动维护),豆包工作的服务端记忆黑盒但强大(语义检索、跨设备同步、自动管理)。这代表了 Agent 产品从"开发者工具"到"大众产品"的必然路径。「推断」
判断四:AGENTS.md 是唯一留给用户的引导入口。 用户不能修改系统提示词、不能编辑身份文件、不能直接管理记忆,但可以通过 AGENTS.md 在项目级别添加规则。这个入口虽然有限,但足以让团队在代码仓库中共享 Agent 行为约定,是开发者场景的关键设计。「推断」
下一章将进入能力扩展层,分析豆包工作的 Skill 系统——103 个预装 Skill 如何分类、如何被发现和触发、与在线技能商店和连接器的关系。
CHAPTER 04 · ZJBB-004
授权:CC BY-NC-SA 4.0 (署名 · 非商业性使用 · 相同方式共享)—— 转载请保留原作者署名与相同协议。
整理:疯狂的豇豆 · 查看完整来源清单
❓ 什么是CH-03 引导层:系统提示词、身份与记忆?
图 3-1:引导层与提示词注入流程
❓ 如何理解系统提示词:Agent 的第一行代码?
系统提示词(System Prompt)是 Agent Harness 中最核心的引导文件。它在用户消息之前注入模型上下文,定义了 Agent 的身份、能力边界、行为规则和输出格式。在一个工具调用 Agent 中,系统提示词通常还包含可用工具列表、工具调用格式、安全规则和错误处理指引。
❓ 如何理解系统提示词从哪里来?
豆包工作的本地文件系统中不存在系统提示词模板文件。WorkBuddy 有 prompt.tpl(Jinja2 模板,用户可直接编辑),豆包工作没有等效文件。「源码」
❓ 如何理解身份系统:从文件到产品?
WorkBuddy 的身份系统是文件化的:SOUL.md 定义性格和价值观,IDENTITY.md 定义名称和角色,USER.md 定义用户信息。这些文件用户可以直接编辑,Agent 每次启动时读取。