loading image

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层)

本文档详细拆解 OpenClaw Agent 发送给 LLM 的完整 System Prompt 的组成结构版本:v2.1

Posted by Enovace on March 5, 2026

本文档详细拆解 OpenClaw Agent 发送给 LLM 的完整 System Prompt 的组成结构**版本:**v2.1
**更新时间:**2026-03-05

整体架构图

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 1

快速导航(TL;DR)

新手必读:

  1. Layer 7(Workspace Files)- 你能直接编辑的配置文件
  2. Layer 8(Bootstrap Hook)- 你能写脚本动态注入内容
  3. 其他层都是框架自动生成的,了解即可

常见需求:

  • 想定义 Agent 身份?→ 编辑 Layer 7 的 IDENTITY.md
  • 想添加项目文档?→ 使用 Layer 8 的 bootstrap-extra-files Hook
  • 想注入实时上下文?→ 使用 Layer 8 的 before_prompt_build Hook
  • 想控制文件大小?→ 调整 bootstrapMaxChars 配置

Layer 1: OpenClaw Framework Core(框架核心层)

比喻

就像一本操作手册的"使用说明"部分——告诉 LLM 你是谁、能做什么、应该怎么回应

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 2

实际示例

你正在以「创意伙伴」身份运行,这是一个 AI 内容创作专家 Agent。

当前时间:2026-03-05 14:37:00 CST
运行环境:agent=creative | host=黄宗宁的MacBook Air

=== 工具调用规范 ===

  • 使用 XML 风格的工具调用格式
  • 每个工具调用必须包含唯一的 tool_call_id
  • 工具结果通过 <tool_result> 标签返回
  • 执行工具时考虑 AbortSignal 以支持取消操作

=== 安全边界 ===

  • 严禁执行 destructive 操作(rm -rf、格式化等)
  • 处理用户敏感信息时必须加密存储
  • 禁止向未授权的渠道发送消息

设计权衡

为什么这样设计?

  • **权衡:**灵活性 vs 一致性
  • **决策:**框架层统一生成,保证所有 Agent 的基础行为一致
  • **好处:**用户不需要为每个 Agent 重复配置基础规则
    框架升级时所有 Agent 自动获得新能力
    降低配置错误的风险
  • **代价:**用户无法修改这些核心规则
    如果需要特殊行为,只能通过 Layer 7/8 间接实现

Layer 2: Tool Definitions(工具定义层)

比喻

就像一把瑞士军刀的工具清单——告诉 LLM 你有哪些工具、每个工具是干什么用的、怎么用

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 3

工具定义示例

{
"name": "read",
"description": "读取文件内容。支持文本文件和图片(jpg/png/gif/webp)。图片会作为附件发送。文本文件输出限制为2000行或50KB。",
"parameters": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "文件路径(相对或绝对)"
},
"offset": {
"type": "number",
"description": "起始行号(1-indexed)"
},
"limit": {
"type": "number",
"description": "最大读取行数"
}
},
"required": ["path"]
}
}

设计权衡

为什么用 JSON Schema?

  • **权衡:**灵活性 vs 类型安全
  • **决策:**使用严格的 JSON Schema 定义工具参数
  • **好处:**LLM 能更准确地理解工具用法
    框架可以在调用前验证参数
    自动生成文档和类型定义
  • **代价:**添加新工具需要编写完整的 Schema
    无法支持完全动态的参数结构

Layer 3: Skills Registry(技能注册表)

比喻

就像一家餐厅的"特色菜谱"——告诉 LLM 有哪些专业领域的"配方"可以调用

设计权衡

为什么用目录扫描而不是手动注册?

  • **权衡:**灵活性 vs 维护成本
  • **决策:**自动扫描 ~/development/openclaw/skills/ 目录
  • **好处:**添加新 Skill 只需放入目录,无需修改配置
    所有 Agent 自动获得新 Skill
    降低配置错误风险
  • **代价:**无法精确控制每个 Agent 可用的 Skill
    所有 Skill 都会被注入 System Prompt(增加 token 消耗)

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 4

Layer 4: Model Aliases(模型别名层)

比喻

就像"快捷键"——给复杂的模型路径起个简短的别名,方便调用

设计权衡

为什么需要模型别名?

  • **权衡:**灵活性 vs 可读性
  • **决策:**允许用户为常用模型定义简短别名
  • **好处:**简化模型调用(glm-5 代替 zhipu/glm-5)
    支持多 Provider 切换(同一别名可映射不同 Provider)
    便于 A/B 测试和模型迁移
  • **代价:**需要维护别名配置文件
    可能造成混淆(不同 Agent 的同一别名可能指向不同模型)

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 5

实际示例

在 System Prompt 中,模型别名会被展示为:

Model Aliases

  • GLM-5: zhipu/glm-5
  • Opus 4.6: xiaowang886/claude-opus-4-6-thinking
  • Sonnet 4.5: xiaowang886/claude-sonnet-4-5

LLM 可以使用别名来切换模型:/model glm-5

Layer 5: Protocol Specifications(协议规范层)

比喻

就像"交通规则"——定义 Agent 与系统交互的标准协议

设计权衡

为什么需要协议规范?

  • **权衡:**自由度 vs 一致性
  • **决策:**定义标准化的交互协议(Silent Replies、Heartbeats、Reply Tags 等)
  • **好处:**保证所有 Agent 行为一致
    支持自动化监控和健康检查
    简化多 Agent 协作
  • **代价:**限制了 Agent 的自由表达
    需要 LLM 严格遵守协议(可能被忽略)

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 6

实际示例

Silent Replies 示例:

用户:收到
Agent:NO_REPLY

Heartbeats 示例:

System:[Heartbeat Poll]
Agent:HEARTBEAT_OK

Reply Tags 示例:

Agent:[[reply_to_current]] 已完成任务 ✓

Layer 6: Runtime Info(运行时信息层)

比喻

就像"仪表盘"——告诉 LLM 当前运行环境的实时状态

设计权衡

为什么每次都注入运行时信息?

  • **权衡:**Token 消耗 vs 上下文准确性
  • **决策:**每次请求都注入最新的运行时状态
  • **好处:**LLM 知道当前时间(避免时间错乱)
    LLM 知道当前模型(避免能力误判)
    LLM 知道当前环境(避免路径错误)
  • **代价:**每次请求消耗 ~2KB token
    信息可能包含冗余

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 7

实际示例

Runtime

Runtime: agent=thinktank | host=黄宗宁的MacBook Air |
repo=/Users/huangzongning/.openclaw/workspace-thinktank |
os=Darwin 25.2.0 (arm64) | node=v25.5.0 |
model=xiaowang886/claude-opus-4-6-thinking |
default_model=xiaowang886/claude-opus-4-6-thinking |
shell=zsh | channel=discord | capabilities=none | thinking=off

Layer 7: Workspace Files(工作区文件层)★ 用户可控

比喻

就像"你的工作笔记"——这是你可以直接编辑的静态配置文件

设计权衡

为什么只有这一层是静态可编辑的?

  • **权衡:**框架稳定性 vs 用户自由度
  • **决策:**把"变"和"不变"分离,框架层保证一致性,用户层允许个性化
  • **好处:**用户可以定义 Agent 身份、工作规范、记忆
    框架升级不会破坏用户配置
    配置文件可以版本管理、备份、共享
  • **代价:**用户无法修改框架核心行为
    需要学习 TELOS 框架和文件结构

核心文件

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 8

Layer 8: Bootstrap Hook System(动态注入层)★ 用户可控

比喻

就像"可编程的注射器"——你可以写脚本在运行时动态注入内容到 System Prompt

设计权衡

为什么需要 Hook 系统?

  • **权衡:**静态配置的简单性 vs 动态注入的灵活性
  • **决策:**在静态 Workspace Files 之外,提供动态 Hook 机制
  • **好处:**可以根据上下文(channel、sender、时间)动态调整注入内容
    可以执行 shell 命令并注入输出(如当前天气、Git 状态)
    可以读取外部文件并注入(如项目文档、API 文档)
    支持条件判断(if/else)
  • **代价:**需要学习 Hook 系统的语法和触发机制
    Hook 脚本错误可能导致 System Prompt 异常
    增加了系统复杂度

四种 Hook 机制

  1. agent:bootstrap Hook(内部 Hook 系统)

**触发位置:**bootstrap-hooks.ts 的 applyBootstrapHookOverrides()

能力:

  • 完全控制 bootstrapFiles 数组
  • 可以增删改文件
  • 可以重排序
  • 可以修改文件内容

谁可以注册:

  • OpenClaw 插件
  • Workspace Hooks(~/.openclaw/workspace-*/hooks/ 目录)
  • 内部模块

代码示例:

registerInternalHook("agent:bootstrap", (event) => {
const context = event.context as AgentBootstrapHookContext;
// 完全控制 bootstrapFiles 数组
context.bootstrapFiles = [
{ path: "CUSTOM.md", content: "自定义内容" }
];
});

  1. bootstrap-extra-files Hook(Bundled Hook)

**触发位置:**hooks/bundled/bootstrap-extra-files/handler.ts

能力:

  • 只追加文件,不修改现有文件
  • 通过配置文件指定额外文件

配置示例:

{
"hooks": {
"bootstrap-extra-files": {
"enabled": true,
"paths": ["extra/*.md", "docs/CONTEXT.md"]
}
}
}

适用场景:

  • 需要注入项目特定的上下文文件
  • 不想修改默认的 8 个 Bootstrap 文件
  • 需要动态加载额外文档
  1. before_prompt_build Hook(Plugin Hook)

**触发位置:**attempt.ts 的 runBeforePromptBuild()

能力:

  • 修改最终 prompt(在系统提示词构建后、发送给 LLM 前)
  • 可以 prepend context(在 prompt 前添加内容)
  • 可以覆盖 systemPrompt

事件数据:

{
prompt: string; // 用户输入
messages: unknown[]; // Session 消息历史
}

返回值:

{
prependContext?: string; // 在 prompt 前添加的内容
systemPrompt?: string; // 覆盖系统提示词
}

适用场景:

  • 需要根据 session 历史动态调整 prompt
  • 需要注入实时上下文(如当前时间、天气)
  • 需要完全替换系统提示词
  1. bootstrapMaxChars / bootstrapTotalMaxChars(配置项)

**类型:**配置项(不是 hook)

能力:

  • 控制字符预算
  • 单文件默认 20K
  • 总计默认 150K
  • 超出部分按头 70% + 尾 20% 截断

配置位置:

{
"agents": {
"defaults": {
"bootstrapMaxChars": 20000,
"bootstrapTotalMaxChars": 150000
}
}
}

实战建议

场景 1:我想添加项目文档

推荐方案:bootstrap-extra-files

{
"hooks": {
"bootstrap-extra-files": {
"enabled": true,
"paths": ["docs/API.md", "docs/ARCHITECTURE.md"]
}
}
}

场景 2:我想根据任务类型动态加载文件

推荐方案:自定义 agent:bootstrap Hook

registerInternalHook("agent:bootstrap", (event) => {
const context = event.context as AgentBootstrapHookContext;
const sessionKey = context.sessionKey;

// 根据 session 类型加载不同文件
if (sessionKey.includes("coding")) {
context.bootstrapFiles.push({
path: "CODING_GUIDELINES.md",
content: fs.readFileSync("...").toString()
});
}
});

场景 3:我想注入实时上下文(如当前时间)

推荐方案:before_prompt_build Hook

on("before_prompt_build", (event, ctx) => {
return {
prependContext: 当前时间:${new Date().toISOString()}
};
});

Layer 9: Inbound Context(入站上下文层)

比喻

就像"实时路况信息"——每次请求都会动态注入当前对话的上下文信息

设计权衡

为什么每次都注入上下文?

  • **权衡:**Token 消耗 vs 对话连贯性
  • **决策:**每次请求都注入最新的消息元信息、发送者信息、对话历史
  • **好处:**LLM 知道当前是谁在说话(避免混淆发送者)
    LLM 知道对话历史(保持上下文连贯)
    LLM 知道是否被 @(决定是否响应)
  • **代价:**每次请求消耗 ~3KB token
    对话历史可能包含噪音信息

组成内容

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 9

完整 System Prompt 组装流程

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 10

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 11

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 12

用户可控层总结

OpenClaw 提供了 3 种用户可控机制

  1. Layer 7(Workspace Files)- 静态配置文件适用场景:定义 Agent 身份、工作规范、记忆
    优点:简单直观,易于版本管理
    缺点:无法动态调整
  2. Layer 8(Bootstrap Hook System)- 动态注入脚本适用场景:根据上下文动态注入内容、执行命令、读取外部文件
    优点:灵活强大,支持条件判断和命令执行
    缺点:需要学习 Hook 系统,脚本错误可能导致异常
  3. 间接控制 Layer 9(Inbound Context)- 通过发送消息影响上下文适用场景:通过对话历史、引用消息影响 LLM 行为
    优点:无需配置,自然交互
    缺点:无法精确控制

大小对比表

⚠️ 注意:以下数据为估算值,实际大小会因配置和运行时上下文而变化。框架层(Layer 1-6 + 9)理论上应该相同,但实际可能因工具定义、Skills 加载、运行时信息等差异而略有不同。

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 13

说明:

  • Layer 7 和 Layer 8 是用户可控层,大小因 Agent 配置而异
  • 其他层由框架自动生成,理论上所有 Agent 应该相同
  • 实际测量时可能因工具可用性、Skills 加载、运行时上下文等因素产生差异

优化建议

  1. 用户可控部分优化(Layer 7 + 8)

由于 Layer 7 和 8 是用户可以控制的,以下是优化策略:

Layer 7(静态文件)优化:

✅ 推荐的精简策略:

  • IDENTITY.md:保留核心 TELOS 框架,删除冗余描述,使用表格代替段落
  • AGENTS.md:使用 checklist 代替长段落,用代码块展示命令,删除重复的规则说明
  • MEMORY.md:依赖 MemOS 自动导出,不要手动添加内容,让系统自动维护

❌ 避免的做法:

  • 不要重复描述 OpenClaw 框架已经知道的事情
  • 不要把 Skills 的详细说明复制到 Workspace Files
  • 不要使用过多的修辞和装饰性语言

Layer 8(Hook 系统)优化:

✅ 推荐的使用策略:

  • 优先使用 bootstrap-extra-files(简单场景)
  • 需要条件判断时使用 agent:bootstrap(复杂场景)
  • 需要实时上下文时使用 before_prompt_build(动态场景)

❌ 避免的做法:

  • 不要在 Hook 中执行耗时操作(会阻塞 System Prompt 生成)
  • 不要在 Hook 中注入过多内容(会超出 token 限制)
  • 不要在 Hook 中使用不稳定的外部依赖(会导致启动失败)
  1. 提示词裁剪策略

如果 System Prompt 过大,可以考虑:

呕心沥血肝出来的,奉献给你们的龙虾了:OpenClaw Agent System Prompt 架构详解(9层) 配图 14

总结

OpenClaw 的 System Prompt 不是一个单一的文件,而是 9 层架构的精心编排:

  • Layer 1-6:框架自动生成,保证一致性和稳定性
  • Layer 7:用户可编辑的静态配置文件(IDENTITY.md、AGENTS.md 等)
  • Layer 8:用户可编程的动态注入脚本(Bootstrap Hook System)
  • Layer 9:框架自动注入的实时上下文(Inbound Context)

用户可控的层有 2 个(Layer 7 + 8),而不是之前错误说的"只有 Layer 7"。

理解这些层的区别和联系,才能真正掌握 OpenClaw 的配置能力。