为什么需要 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)
像一把瑞士军刀的工具清单。内置工具包括 read、write、edit、exec,OpenClaw 扩展工具包括 message、browser、canvas、cron、memory_search,还有渠道特定工具如 discord_*、telegram、slack_*。工具定义采用 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:bootstrapHook:完全控制 bootstrapFiles 数组bootstrap-extra-filesHook:追加额外文件before_prompt_buildHook:修改最终 promptbootstrapMaxChars配置:控制字符预算
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:
- 加载框架核心:读取核心框架代码,生成 Context Header,注入 Tool Call Style,添加 Safety Rules
- 扫描并加载 Tools:扫描
src/tools/目录,读取 TypeScript 定义,生成 JSON Schema,按类别分组 - 扫描并加载 Skills:扫描 skills 目录,提取元信息,生成 Available Skills 表格
- 加载 Model Aliases:读取
models.json,解析映射关系 - 注入协议规范:Silent Replies、Heartbeats、Chunked Write Protocol、Reply Tags
- 注入运行时信息:时间、Agent、主机、模型、渠道信息
- 加载 Workspace Files:读取用户编辑的 7 个核心 Markdown 文件
- 执行 Bootstrap Hook System:依次触发各个 Hook,应用字符预算控制
- 注入 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 架构。