OpenClaw 精髓与要点参考

0 评论 315 浏览 1 收藏 18 分钟

本文汇总 OpenClaw 项目的整体精髓、提示词、Skills、记忆(含长记忆)、Agent 工作原理与代码精髓,便于快速把握设计与实现要点。

1. 项目精髓

一句话

在一个你自己掌控的「控制面」(Gateway)上,跑一个统一的个人 AI 助手,在你已有的聊天渠道(WhatsApp、Telegram、Slack、Discord 等)里和你对话,并支持语音、画布、多端节点,数据与逻辑都在你自己手里。

三个核心点

架构精髓

单一 WebSocket 控制面

Gateway 在ws://127.0.0.1:18789(可配)提供唯一控制平面;CLI、Web UI、macOS 菜单栏、iOS/Android 节点、Pi agent 都通过它协作。

会话与路由

谁在哪个渠道、进哪个会话、用哪个 agent/workspace,都由 Gateway 统一做路由和会话管理。

可扩展

新渠道通过extensions/*以插件形式加入;技能、Cron、webhook、浏览器/画布等工具都挂在这套控制面上。

整体架构示意

2. 提示词精髓

一句话

系统提示词是 OpenClaw 自己组装的、分块固定的「单次运行说明书」:先给身份与安全底线,再给工具/技能/文档/工作区等能力说明,最后把工作区里的AGENTS.md、SOUL.md等 bootstrap 文件整块注入;子 agent 用精简版,渠道/群组可追加额外说明。

五个要点

1)OpenClaw 全权拥有提示词由 OpenClaw 组装并注入,不使用 pi-coding-agent 的默认 prompt。

2)固定分块、刻意紧凑身份 → Tooling → Safety → Skills(只列清单+路径,按需 readSKILL.md)→ Documentation → Workspace → Sandbox → Current Date & Time → Reply Tags → Heartbeats → Runtime → Reasoning;安全护栏是建议性的,硬约束靠工具策略、审批、沙箱、allowlist。

3)工作区 Bootstrap = 身份与上下文注入AGENTS.md、SOUL.md、TOOLS.md、IDENTITY.md、USER.md、HEARTBEAT.md、BOOTSTRAP.md、MEMORY.md(及memory.md若存在)整块注入;受bootstrapMaxChars/bootstrapTotalMaxChars限制;子 agent 只注入AGENTS.md+TOOLS.md。

4)三种 Prompt 模式

  • full:主 agent,所有块。
  • minimal:子 agent;去掉 Skills 详述、Memory Recall、Self-Update、Reply Tags、Messaging、Heartbeats 等。
  • none:仅身份行。

5)会话重置与渠道/群组/new或/reset时给模型一条固定指引(用 persona 打招呼、1–3 句);渠道/群组可在 system 里追加systemPrompt或「Group Chat Context」。

设计精髓小结

系统提示组装结构

3. Skills 调用/使用关键要点

一句话

Skill 的「调用」分两种:模型按系统提示里的<available_skills>清单「选一个 → 用 read 读SKILL.md→ 照做」;用户用/skill <name> [input]直接指定技能。两者都依赖「加载时门控 + 会话快照 + 按需读文件」,环境变量在每次 agent 运行前注入、结束后恢复。

模型侧:如何使用 Skill

  • 系统提示里只有Skills (mandatory)说明 +<available_skills>下的技能列表(name / description / location),不注入SKILL.md全文。
  • 指令要点:回复前扫<description>;恰好一个明显适用 → 用read读该技能在<location>的SKILL.md再执行;多个适用选最贴切一个;都不适用则不读任何SKILL.md;先选再读、每次最多读一个

用户侧:/skill 与「仅用户可调」

  • /skill <name> [input]: 用户直接触发名为<name>的技能。
  • user-invocable:true(默认)暴露为斜杠命令;false仅模型按清单选用。
  • disable-model-invocation:true则不加入<available_skills>,仅可通过/skill由用户调用。
  • command-dispatch:tool+command-tool:用户执行该技能时不经模型,直接调用指定工具。

加载与门控

三个来源与优先级

  • workspace > managed(~/.openclaw/skills)> bundled;同名时 workspace 覆盖。
  • 门控(metadata.openclaw):requires.bins/requires.anyBins、requires.env、requires.config、os;always: true跳过检查。
  • 配置(skills.entries.<key>):enabled: false禁用;env/apiKey在该次 agent run 前注入到process.env,run 结束恢复

会话快照与性能

  • 会话开始时对符合条件的技能列表做快照(buildWorkspaceSkillSnapshot),本会话后续轮次复用;改 skills 或 config 要新开会话才生效。
  • 若开启skills.load.watch,SKILL.md变更会触发快照刷新,下一轮 agent 回合用新列表。

Skills 调用流程示意

小结

4. 记忆(长记忆)处理关键要点

一句话

长记忆 = 写在磁盘的 Markdown(MEMORY.md+ memory/.md),不靠上下文窗口;MEMORY.md会整份注入每轮上下文并受 bootstrap 上限截断,日誌 memory/.md 不注入、只通过 memory_search + memory_get 按需拉取;接近 compaction 前会做一次「记忆冲刷」把重要内容写盘,并用向量/混合检索控制长记忆的召回。

两层记忆文件

  • MEMORY.md 受bootstrapMaxChars/bootstrapTotalMaxChars限制,超了会被截断。
  • memory/*.md 不注入;模型需要时先memory_search,再用memory_get(path, from, lines)只拉命中片段。

记忆层与 context 关系

长记忆不撑爆 context 的用法

  • MEMORY.md: 写精炼的长期事实、决定、偏好;保持简短,或用 memory_search + memory_get 只拉需要的行。
  • memory/YYYY-MM-DD.md:不注入;先memory_search再memory_get只读命中片段。系统提示里「Memory Recall」要求:在回答「过往工作、决定、日期、人、偏好、待办」前先对MEMORY.md+ memory/*.md 做 memory_search,再用 memory_get 拉所需行。

自动记忆冲刷(pre-compaction memory flush)

  • 目的:在自动 compaction 前把还在对话上下文里、但还没写盘的「重要内容」写进记忆文件。
  • 时机:会话 token 估计达到contextWindow – reserveTokensFloor – softThresholdTokens时,触发一次静默 agent 轮
  • 配置:agents.defaults.compaction.memoryFlush(enabled、softThresholdTokens、systemPrompt、prompt);每轮 compaction 周期只做一次。

向量/混合检索(长记忆召回)

对MEMORY.md+ memory/*.md 分块建向量索引;memory_search返回片段、路径、行号、分数。

  • Hybrid:BM25 + 向量,既语义又精确词匹配。
  • Temporal decay:对按日期文件(如 memory/YYYY-MM-DD.md)按时间衰减分数;MEMORY.md等常青文件不衰减
  • MMR:结果多样性重排,减少重复片段。

小结

5. Agent 工作原理

一句话

Agent = 在 Gateway 里跑的「单次 agent 循环」:按 session 排队 → 组会话/系统提示/工具 → 调嵌入式 pi-agent-core 做「推理 → 工具 → 再推理」直到结束 → 流式输出并写回 session transcript;会话、工作区、技能、记忆都由 OpenClaw 管,模型和工具循环由 pi-mono 提供。

整体定位

  • 运行时:基于pi-mono的嵌入式 agent(runEmbeddedPiAgent)。
  • 谁管什么:会话、发现、工具接线、系统提示、bootstrap、技能归 OpenClaw;模型调用、工具定义、推理循环用 pi-agent-core。
  • 工作区:一个 agent 一个 workspace(agents.defaults.workspace),作为文件类工具的 cwd。

从「收到消息」到「一次 Agent 跑完」

  1. 入口:Gateway WS 请求agent(或agent.wait)、CLIopenclaw agent、渠道 inbound 经 auto-reply 触发。
  2. 入队与串行:sessionKey入队(同一 session 同时只跑一个 run),再进全局 lane,总并发受agents.defaults.maxConcurrent限制。
  3. Session + Workspace 准备:解析 workspace、加载或复用 skills snapshot、解析 bootstrap、拿 session 写锁、打开 SessionManager。
  4. Prompt 组装:系统提示 + bootstrap 注入 + 该 session 历史 transcript + 当前用户消息;考虑 compaction reserve 等限制。
  5. 跑嵌入式循环:(runEmbeddedPiAgent):模型推理 → tool_calls → 执行工具 → 结果 append 进 messages → 再推理,直到结束或超时/取消;事件桥接为assistant/tool/lifecycle流。
  6. 写回与收尾:把本轮的 assistant 消息 + tool calls + tool results 追加到该 session 的 JSONL transcript;必要时 memory flush、compaction、重试;释放锁,更新 store。

Session 与并发

  • SessionKey:标识「哪条对话」;SessionId:当前 transcript 文件;/new//reset或每日/空闲策略会换新 sessionId。
  • 串行:同一 sessionKey 一次只跑一个runEmbeddedPiAgent。
  • 队列模式:collect/followup/steer/steer-backlog等,决定新消息是立刻插队、等当前 run 结束,还是合并成一条再跑。

Agent Run 流程示意

6. 代码精髓

一句话

TypeScript ESM 严格类型 + 依赖注入(Deps/Context)+ 单一参数包贯穿管线 + Gateway 的「方法 → 处理器」注册与鉴权 + Config/Session 为单一事实源 + 内外双钩子扩展 + 同文件/同目录测试;不搞 prototype 魔改、不复制 V2 文件,控制单文件体量。

语言与风格

  • TypeScript ESM,严格类型,避免any;禁止 prototype 魔改,用显式继承/组合。
  • 单文件体量:目标约~700 LOC,超了拆 helper 或模块,不开*-v2.ts。
  • 格式化/检查:Oxlint + Oxfmt,pnpm check。

依赖注入(Deps / Context)

  • CLI:CliDeps(各渠道sendMessage*)由createDefaultDeps()提供,命令层传入;测试可注入 mock。
  • Gateway:GatewayRequestContext集中放 cron、execApprovalManager、broadcast、nodeRegistry、session/store、wizard 等;每个 WS 请求的 handler 收到统一context。
  • Outbound:createOutboundSendDeps(deps)把 CLI 的sendMessage*转成OutboundSendDeps。

单一参数包(Params Bag)

  • Agent/命令管线:HandleCommandsParams一个对象带齐 ctx、cfg、command、sessionEntry、sessionKey、workspaceDir、provider/model、各种 resolved*Level、skillCommands 等;command handler 签名为(params, allowTextCommands) => Promise<CommandHandlerResult | null>。
  • Gateway 请求:GatewayRequestHandlerOptions含 req、params、client、respond、context;各server-methods/*.ts的 handler 只认这一种入参。

Gateway:方法注册 + 鉴权后派发

  • Handlers 注册:server-methods.ts把各域 handler 聚成coreGatewayHandlers,按method 字符串索引。
  • 请求处理:handleGatewayRequest(opts)先authorizeGatewayMethod(req.method, client)(按 role/scopes 判 READ/WRITE/ADMIN 等),再coreGatewayHandlers[req.method](…)。
  • 扩展:可传extraHandlers覆盖或增加方法。

Gateway 请求处理与代码数据流

Config / Session 为事实源

  • Config:loadConfig、validateConfigObject(Zod);行为由配置决定。
  • Session:sessions.json+ transcript*.jsonl;resolveSessionKey、loadSessionEntry、updateSessionStore等统一走 config/sessions 模块。

双轨 Hooks(内建 + 插件)

  • 内建:如agent:bootstrap、命令类(/new、/reset等)。
  • 插件:before_model_resolve、before_prompt_build、before_tool_call、after_tool_call、tool_result_persist、message_received/message_sent、session_start/session_end、gateway_start/gateway_stop等;入参/出参有类型。

渠道与路由

  • 每个渠道实现自己的send+inbound 处理;CLI 的createDefaultDeps按渠道注入对应sendMessage*。
  • Inbound 消息经路由得到sessionKey,再进 auto-reply 队列,最终进同一套HandleCommandsParams+ agent 管线。

测试

  • 位置:与源码同目录,*.test.ts、*.e2e.test.ts;Vitest。
  • 风格:优先 per-instance stub,少用SomeClass.prototype.method = …。

小结

7. 文档与代码入口速查

希望这篇文章能帮你快速了解和学习 OpenClaw 的精髓,也欢迎在评论区聊聊你更想深挖的部分。

本文由 @Lucky培丽 原创发布于人人都是产品经理。未经作者许可,禁止转载

题图来自Openclaw官网截图

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 目前还没评论,等你发挥!