为什么需要 9 层?一层真不够

如果只用一个文件定义 Agent,实际开发中会撞上一堆问题:

  • 框架升级了,所有 Agent 都要手动改配置
  • 工具定义散落各处,LLM 搞不清自己能干什么
  • 每个 Agent 都要重复写"你是谁、能做什么"
  • 运行时信息(当前时间、模型、环境)没法动态注入,容易过时

OpenClaw 的核心设计哲学是把"变"和"不变"分离

  • 框架层(Layer 1-6):所有 Agent 共享,框架自动生成,保证一致性
  • 用户层(Layer 7-8):每个 Agent 独立配置,支持个性化
  • 运行时层(Layer 9):每次请求动态注入,保证上下文准确

这样框架升级不会破坏用户配置,用户配置也不会影响框架稳定性。

Layer 1-6:框架自动生成的"底座"

这 6 层是 OpenClaw 的"操作系统",所有 Agent 共享,用户无法修改。

Layer 1:框架核心层(约 8KB)

相当于操作手册的"使用说明"。包含上下文头(告诉 LLM 当前时间、Agent 身份、运行环境)、工具调用格式(XML 风格)、安全规则(禁止 rm -rf、格式化等危险操作)。所有 Agent 的基础行为由这一层统一保证,框架升级时自动获得新能力。

Layer 2:工具定义层(约 12KB)

像一把瑞士军刀的工具清单。内置工具包括 readwriteeditexec,OpenClaw 扩展工具包括 messagebrowsercanvascronmemory_search,还有渠道特定工具如 discord_*telegramslack_*。工具定义采用 JSON Schema 格式,好处是 LLM 能更准确理解工具用法,框架可以在调用前验证参数,还能自动生成文档和类型定义。

Layer 3:技能注册表(约 5KB)

自动扫描 ~/development/openclaw/skills/ 目录,提取每个 Skill 的 name、description、location。添加新 Skill 只需放入目录,无需修改配置,所有 Agent 自动获得新技能。这个设计很实用,省去了大量手动维护的工作。

Layer 4:模型别名层(约 2KB)

给复杂的模型路径起简短别名,比如 glm-5 → zhipu/glm-5。简化模型调用、支持多 Provider 切换、便于 A/B 测试和模型迁移。

Layer 5:协议规范层(约 3KB)

定义了几个关键协议:Silent Replies(无需回复时返回 NO_REPLY)、Heartbeats(定期健康检查)、Reply Tags(原生引用回复)、Chunked Write Protocol(大文件分块写入)。这些协议保证所有 Agent 行为一致,也为多 Agent 协作打下基础。

Layer 6:运行时信息层(约 2KB)

每次请求都注入当前时间戳、时区、Agent ID、当前模型、主机名、操作系统、Node 版本、Shell 类型、渠道信息等。LLM 知道当前时间就不会时间错乱,知道当前模型就不会能力误判,知道当前环境就不会路径出错。

Layer 7-8:用户可控的"个性化层"

这两层决定了每个 Agent 的"个性",是独立开发者最需要关注的部分。

Layer 7:工作区文件层(约 10-15KB)— 静态可控

这一层通过一组 Markdown 文件定义 Agent 的身份和行为:

  • IDENTITY.md:基于 TELOS 框架的身份定义
  • SOUL.md:性格内核和行为准则
  • USER.md:用户信息和偏好
  • AGENTS.md:协作规范和 @ 规则
  • HEARTBEAT.md:定期检查任务清单
  • TOOLS.md:环境特定工具清单
  • MEMORY.md:MemOS 导出的记忆

这些配置文件可以版本管理、备份、在不同 Agent 之间共享。

Layer 8:Bootstrap Hook 系统(约 2KB)— 动态可控

提供四种 Hook 机制:

  • agent:bootstrap Hook:完全控制 bootstrapFiles 数组
  • bootstrap-extra-files Hook:追加额外文件
  • before_prompt_build Hook:修改最终 prompt
  • bootstrapMaxChars 配置:控制字符预算

Hook 系统支持根据上下文动态调整注入内容、执行 shell 命令、读取外部文件、条件判断。实际使用中的建议:添加项目文档用 bootstrap-extra-files,动态加载文件用 agent:bootstrap Hook,注入实时上下文用 before_prompt_build Hook。

Layer 9:入站上下文层(约 3KB)

每次请求都会注入消息元信息(message_id、sender_id、was_mentioned)、发送者信息、最近 N 条消息的摘要、引用上下文、线程上下文。LLM 因此知道当前是谁在说话、对话历史是什么、是否被 @ 提及。

完整组装流程

当你 @ 一个 Agent 时,OpenClaw 按以下 9 步组装 System Prompt:

  1. 加载框架核心:读取核心框架代码,生成 Context Header,注入 Tool Call Style,添加 Safety Rules
  2. 扫描并加载 Tools:扫描 src/tools/ 目录,读取 TypeScript 定义,生成 JSON Schema,按类别分组
  3. 扫描并加载 Skills:扫描 skills 目录,提取元信息,生成 Available Skills 表格
  4. 加载 Model Aliases:读取 models.json,解析映射关系
  5. 注入协议规范:Silent Replies、Heartbeats、Chunked Write Protocol、Reply Tags
  6. 注入运行时信息:时间、Agent、主机、模型、渠道信息
  7. 加载 Workspace Files:读取用户编辑的 7 个核心 Markdown 文件
  8. 执行 Bootstrap Hook System:依次触发各个 Hook,应用字符预算控制
  9. 注入 Inbound Context:解析消息元数据、发送者、聊天历史

最终组装完成的 System Prompt 总大小约 43KB,其中用户可控部分约 14-17KB(Layer 7 + 8),框架生成部分约 26-29KB(Layer 1-6、9)。

优化建议:让 Agent 更"轻盈"

如果 System Prompt 超过 50KB,可以从用户可控部分入手优化:

Layer 7 静态文件优化:

  • 保留核心 TELOS 框架,删除冗余描述
  • 用 checklist 代替长段落
  • 依赖 MemOS 自动导出,不要手动堆内容
  • 不要重复描述框架已经知道的事情
  • 不要把 Skills 的详细说明复制到 Workspace Files

Layer 8 Hook 系统优化:

  • 简单场景优先用 bootstrap-extra-files
  • 需要条件判断时用 agent:bootstrap
  • 需要实时上下文时用 before_prompt_build
  • 不要在 Hook 中执行耗时操作
  • 不要在 Hook 中注入过多内容

这套架构的启发

OpenClaw 这 9 层架构解决的核心矛盾其实很普遍:框架稳定性 vs 用户自由度、一致性 vs 个性化、静态配置 vs 动态注入、Token 消耗 vs 上下文准确性。

对独立开发者来说,即使不用 OpenClaw,这套分层思路也值得借鉴——当你在搭建自己的 AI Agent 时,把系统级的"不变量"和用户级的"可变量"清晰分离,再加上运行时动态注入,就能在不牺牲灵活性的前提下保持系统的可维护性。如果你正在构建自己的 Agent 系统,不妨从这个分层模型开始思考你的 System Prompt 架构。