OpenClaw 更准确的定位是:

  • 一个自托管的 Agent 控制平面(Gateway)
  • 一套按会话串行执行的单回合运行时
  • 一组以文件为事实源、以插件为扩展边界的工程系统

它不是“每个聊天窗口里养着一个持续思考的机器人”,而是“由 Gateway 统一接管入口、状态、权限与执行”的系统。

用户或外部系统

渠道适配层

入站归一: MsgContext

路由: sessionKey

队列: 去重 去抖 串行化

单回合 Agent Run

上下文组装

模型推理

工具 技能 插件 Hook

持久化

transcript: JSONL

memory: Markdown

索引: FTS Vector QMD

出站渲染与抑制

1. 先说本质:它到底解决什么问题

如果把 OpenClaw 抽象到最小,它解决的是四件事:

  1. 把不同聊天平台的消息入口统一起来,让上层 Agent 不必理解 Telegram、Slack、WhatsApp、iMessage 的协议差异。
  2. 把一次次离散消息组织成稳定会话,避免多设备、多渠道、多轮工具调用把状态搅乱。
  3. 把模型“当前看到的上下文”与“真正持久化的事实”区分开,避免把上下文窗口误当成记忆系统。
  4. 把高能力工具放进可控边界内执行,而不是把“会调工具”直接等同于“可以安全自动化”。

所以它的重点不是 UI,也不是某个单独模型,而是:

  • 入口统一
  • 状态归一
  • 执行串行
  • 事实落盘
  • 能力受控

2. 最重要的架构判断:Gateway 才是权威主体

OpenClaw 的核心不是聊天客户端,也不是某个 agent 实例,而是 Gateway

  • 会话归 Gateway 所有:session 列表、token 统计、会话 transcript、配置解释,都以 Gateway 看到的状态为准。
  • 客户端只是表面:macOS App、Web 控制台、TUI、聊天平台,都不是权威状态源;它们只是 Gateway 的不同观察窗。
  • 多表面不保证完全回灌:多个设备或渠道可以映射到同一 session,但历史并不会完整同步回每个客户端;真正完整的记录仍以 Gateway transcript 为准。
  • 远程模式尤其如此:如果 Gateway 跑在远端,那么“本机看到的文件”并不代表真实运行状态;真实状态在 Gateway 主机上。

这点很关键,因为它决定了 OpenClaw 不是“端上智能体”,而是“控制平面 + 多表面接入”。

3. 执行模型:不是常驻思考,而是单回合重建

OpenClaw 的运行单位不是“一个永远活着的 agent 线程”,而是 一次 run

每次入站消息触发的大致流程是:

  1. 渠道接收消息并归一成内部上下文。
  2. Gateway 根据 sessionKey 找到或创建对应会话。
  3. 运行时重建本回合上下文。
  4. 模型推理,按需调用工具。
  5. 结果流式输出到目标渠道。
  6. 将本回合增量追加写入 transcript。
  7. 本回合结束,Gateway 继续等待下一次事件。

这里最容易误解的一点是:

  • Gateway 是常驻的
  • Agent run 是短生命周期的

也就是说,它不是严格意义上的 Serverless,但它确实采用了“每回合重建工作集”的思路。

这样做的直接收益是:

  • 同一会话天然可以串行化,减少工具竞态与 transcript 写冲突。
  • 运行边界清晰,失败恢复、超时控制、重试与压缩更容易做。
  • 系统不会因为“维持很多常驻 agent 线程”而把复杂度提前透支。

代价也很明确:

  • 每次都要重新组装上下文,延迟与 token 成本更高。
  • 如果上下文治理做不好,系统会越来越依赖压缩、摘要与检索。

4. 一致性单元:不是 channel,而是 session

OpenClaw 最核心的工程约束不是“消息来了就处理”,而是“同一 session 只能按顺序处理”。

这里要区分三个概念:

  • sessionKey:逻辑会话键,用于路由与隔离。
  • sessionId:物理 transcript id,用于落盘文件名,可轮换。
  • <sessionId>.jsonl:实际 transcript,记录对话、工具结果、压缩摘要等事件。

本质上:

  • sessionKey 解决“这条消息属于哪个连续上下文”
  • sessionId 解决“当前这段上下文写到哪份物理文件”

这也是它比很多聊天机器人实现更稳的地方。很多系统把“用户 id”或者“channel id”直接当上下文边界,结果会在群聊、分线程、跨设备、重置、每日切片这类场景里迅速变乱。OpenClaw 显式把“路由键”和“物理文件”拆开了。

5. 真正的状态分层:不要把 transcript、memory、context 混为一谈

这是当前文档原本提到但还不够本质的一块。OpenClaw 至少有四层不同性质的状态:

第一层:配置与路由元数据

  • 例如 openclaw.json、认证资料、sessions.json
  • 作用是告诉系统“怎么连外部世界”“当前会话映射到哪里”“会话启用了哪些开关”。
  • 这是控制平面的管理状态。

第二层:transcript

  • <sessionId>.jsonl
  • 它是会话回放日志,不是长期知识库。
  • 它的职责是让下一轮能够重建上下文,并为压缩、回放、调试和导出提供统一事实记录。
  • 它记录的不只是用户与助手消息,还包括工具调用、工具结果、压缩摘要等事件,因此它更像“会话事件流”而不是纯聊天记录。
  • compaction 会把旧历史压成持久摘要写回 transcript,后续回放看到的是“压缩摘要 + 最近保留的后缀”。
  • pruning 更像运行时减载,主要减少当轮回放负担,不改写这份长期回放记录。
  • 所以 transcript 的核心职责不是“永久存所有原文”,而是“在有限窗口里尽量保住会话连续性”。

第三层:可人工编辑的长期事实

  • 即工作区里的 MEMORY.mdmemory/YYYY-MM-DD.md
  • 它们才是持久事实源。
  • 用户和模型都可以读写,且内容具备可审计性与可迁移性。

第四层:检索加速层

  • 例如 SQLite FTS、向量索引,或可选的 QMD 后端。
  • 它们只是为了更快召回 Markdown / 会话切片,不是事实源本身。
  • 索引坏了可以重建,Markdown 才不能丢。

所以最重要的判断是:

  • Context 是运行时工作集
  • Transcript 是回放日志
  • Markdown 是长期事实
  • 索引是加速器

这四者分清了,很多设计就不会跑偏。

6. 上下文装配:OpenClaw 自带系统提示词,再叠加用户工作区与会话状态

OpenClaw 有一个很重要、但很多类似系统没讲清楚的点:每次 run 的输入不是“用户写了什么就发什么”,而是 Gateway 现组的一份工作集。

每次 run 发给模型的内容至少包括:

  • OpenClaw 构建的系统提示词
  • 会话历史
  • 工具调用与工具结果
  • 附件或转录内容
  • 工具 schema

其中,系统提示词内部通常还包含:

  • 工具列表与简述
  • 技能列表元信息
  • 时间与运行时元数据
  • 注入的工作区 bootstrap files(如 AGENTS.mdSOUL.mdTOOLS.mdUSER.md

这里最关键的事实是:OpenClaw 本身有一套编码在运行时里的系统提示词骨架,SOUL.md 只能影响其中一部分,不能覆盖全部。

更准确地说:

  • SOUL.md 不是和系统提示词平级的输入。
  • SOUL.md 是被注入到系统提示词里的 Project Context 文件之一。
  • 系统还会在更高优先级的位置注入一批用户通常不会直接从 SOUL.md 感知到的框架级提示,例如工具调用风格、执行偏向、安全提醒、静默回复约定、运行时信息、消息表面规则等。

这意味着用户即使精心编写了 SOUL.md,也只能塑造:

  • 语气、人格、风格边界
  • 某些稳定身份设定
  • 一部分工作区规则

但用户无法仅通过 SOUL.md 感知或替换:

  • OpenClaw 自带的系统提示词骨架
  • provider / runtime 注入的额外提示
  • 工具 schema 本身携带的调用约束
  • 某些运行时特定段落,例如静默回复、审批提示、运行时元数据

所以从结构上看,更像是:

OpenClaw-owned system prompt
  + provider/runtime 注入
  + Project Context(含 SOUL.md / AGENTS.md / TOOLS.md ...)
  + 会话历史
  + 工具调用与结果
  + 附件
  + 工具 schema

如果继续追问“OpenClaw 自己到底注入了什么”,可以把它理解成几类固定 section:

  • Tooling / Tool Call Style / Execution Bias:告诉模型当前有哪些工具、怎么调用、何时少说话直接做、何时该继续执行直到完成。
  • Safety:给出最上层的行为约束,例如不要追求权限扩张、不要绕过监督、不要擅自改 system prompt 或安全规则。
  • Skills / Memory / Docs / CLI Quick Reference:告诉模型“去哪里找能力说明”和“遇到 OpenClaw 自身问题时先查什么”。
  • Workspace / Sandbox / User Identity / Time / Runtime:把这次 run 所处的具体运行环境显式告诉模型,避免它凭空假设路径、权限、时间和宿主能力。
  • Messaging / Voice / Silent Replies / Reactions / Assistant Output Directives:约束它在具体交付表面上的行为,例如不要乱发流式草稿、何时可以静默、何时该靠原生审批按钮而不是手写 /approve
  • Project Context / Dynamic Project Context / Group Chat Context / Subagent Context:把真正与当前工作区或当前会话相关的动态材料挂进来。

这些 section 之所以需要由 OpenClaw 自己硬编码,而不是全交给 SOUL.md,是因为它们承担的是控制平面责任

  • SOUL.md 适合表达“我是谁、怎么说话、什么风格”。
  • 框架 section 负责表达“你此刻拥有什么能力、受什么约束、运行在什么环境、应该如何交付”。

如果把这两类东西混在一起,会出现两个问题:

  • 用户 persona 文件会膨胀成运行时规范,既难维护,也难确保每次都正确注入。
  • 安全、审批、沙箱、消息表面这些和运行环境强绑定的规则,不能依赖用户文件自觉维护。

从设计上看,OpenClaw 用的是“框架骨架 + 用户文件填充 + provider/runtime 局部覆写”:

  • 框架骨架负责稳定的控制平面语义。
  • 用户文件负责人格、工作区规则、局部项目语境。
  • provider/runtime 只在少数 section 做覆写或增补,而不是整体替换。

这样设计的好处是:

  • 大部分运行约束始终存在,不会因为用户没写 SOUL.md 就消失。
  • 用户仍然能通过工作区文件显著影响 agent 的表现。
  • 不同模型族可以在不推翻整套 prompt 的前提下做局部调优。

再往里看,这份系统提示词也不是一整块平铺文本,而是分层组织的:

  • 稳定骨架:工具、执行、安全、技能、工作区、运行时等框架段落。
  • Project Context:工作区 bootstrap files,被截断后注入。
  • 动态附加段:例如群聊上下文、subagent 上下文、provider 动态后缀。
  • 缓存边界:系统会尽量把稳定段和频繁变动段分开,减少每次完全失效。

如果要更严格,应该把“上下文装配”拆成两层:

  • 第一层:system prompt 内部有哪些层次
  • 第二层:最终请求对象里,system prompt、messages、tools 是什么关系

先看第一层,也就是 buildAgentSystemPrompt() 产出的 system prompt 内部结构

身份基线

框架骨架: Tooling Execution Safety CLI

环境段: Workspace Docs Sandbox Time Runtime

交付段: Messaging Voice Silent Replies Reactions

Project Context stable

Cache Boundary

Dynamic Project Context

Group Chat 或 Subagent Context

provider dynamic suffix

最终 system prompt 文本

再看第二层,也就是 最终请求对象

system prompt

messages

tools: tool schemas

最终模型请求

其中 messages 内部更接近下面这个顺序:

compaction 摘要或保留历史前缀

较新的 user assistant toolResult 回放

当前轮最新 user message

该 user message 挂载的附件或转录块

messages 数组尾部

这里有两个容易混淆的点:

  • SOUL.mdAGENTS.mdTOOLS.md 不是和历史平级的主输入;它们先被注入到 system prompt 的 Project Context 里。
  • 当前轮用户回答不在 system prompt 里,而是在 messages 的尾部,通常是最新一条 user message。
  • 附件或转录内容通常不是独立悬浮的一段全局文本,而是挂在某条 user message 上的内容块。
  • tool schema 也不是普通 prompt 文本段落;它更像“与 system prompt / messages 并列发送的结构化能力描述”,但同样占上下文预算。

这正是为什么 OpenClaw 的“人格”和“行为”看起来像混合物:

  • 一部分来自 SOUL.md
  • 一部分来自 AGENTS.md / TOOLS.md
  • 一部分来自框架硬编码提示
  • 一部分来自工具可用性和渠道约束

用户不是完全无法感知这些东西,只是默认不会从 SOUL.md 这条入口完整感知。只有查看上下文报告或系统提示词细节时,才能看到更完整的装配结果。

这意味着几个很现实的结论:

  • 记忆不是“写在磁盘上就天然进入模型脑中”。
  • bootstrap 文件不是越多越好,它们直接挤占上下文窗口。
  • 工具能力越多,schema 开销越大。
  • transcript 越长,越需要压缩与剪枝。

所以 OpenClaw 的上下文系统,本质上是在做 受 token 预算约束的工作集构建,而不是简单的 prompt 拼接。

7. compaction 与 pruning:如何在有限窗口里保住连续性

如果只说“历史长了就做摘要”,会低估 OpenClaw 的压缩机制。它实际解决的是一个更难的问题:

  • 旧历史太长,模型窗口放不下。
  • 但如果随便摘要,又会把当前回合继续所需的局部细节压没。
  • 特别是工具调用场景里,摘要边界切错一次,就可能让后续回放失去上下文配对关系。

所以 OpenClaw 的 compaction 不是“定期简单总结”,而是“在有限 token 内保留会话可继续执行的最小连续结构”。

它大致有几层机制:

先直接回答一个容易误会的问题:

  • compaction 不是只保存一个索引
  • 它会在 transcript 里持久化写入一条 compaction 摘要条目,并记录从哪里开始保留未压缩后缀,例如 firstKeptEntryId
  • 之后的历史回放会把这条摘要当作“旧历史的代表”,只继续拼接它之后保留的消息。
  • 也就是说,它改变的是未来如何回放这份 transcript
  • 从当前实现与文档语义看,它更接近“逻辑上裁掉旧历史,物理上保留原始事件”,而不是立刻把旧 JSONL 行从文件里硬删除。

所以更准确的说法是:

  • 对未来上下文来说,旧历史被实际移出了回放主路径。
  • 对磁盘 transcript 来说,旧事件通常仍作为历史痕迹存在,只是不再是默认 replay 输入。

如果按实际执行过程展开,可以近似理解为下面这条链:

  1. 先估 token,不直接相信原始长度

    • 系统会先估算消息 token。
    • 在 compaction 估算里,还会先剥掉 toolResult.details 这类不该再喂给摘要模型的冗长明细。
    • 同时会带安全余量,避免估算偏小导致摘要时再次超窗。
  2. 决定要不要分块,以及块有多大

    • 如果消息还不够多,或者总 token 还在单块可处理范围内,就直接摘要。
    • 如果历史过长,就先按 token share 切成多个 chunk。
    • chunk 比例不是写死的;平均消息越大,块会切得越小,防止摘要阶段自己先爆掉。
  3. 切块时保护执行结构

    • 系统会跟踪 assistant 发出的 tool call id。
    • 如果某个切分点正好落在 tool call 与 tool result 之间,会把边界回退到更安全的位置。
    • 这样做是为了避免摘要后一半记着“调用了什么”,另一半丢了“结果是什么”。
  4. 分块摘要,再合并摘要

    • 每个 chunk 先单独摘要。
    • 如果有多个 partial summary,再把这些 partial summary 当成新的输入继续合并成一份总摘要。
    • 合并时不是随便归纳,而是明确要求保留:当前任务进度、最近用户请求、决策与理由、未完成事项、约束、承诺等。
  5. 如果摘要失败,走降级路径

    • 先尝试完整摘要。
    • 失败后,会把过大的单条消息标记出来,只摘要其余较小消息。
    • 再失败,就退化成“当前上下文过大,摘要不可用”的说明,而不是让整次 compaction 直接失真崩掉。
  6. 把摘要和保留后缀重新拼成新的 replay 入口

    • 最终落盘的不是“一个裸摘要”。
    • 系统还会尽量附上近期保留回合、拆分回合提示、工具失败摘要、文件操作摘要、工作区上下文等后缀。
    • 所以后续看到的实际回放入口,更像“摘要头 + 结构化尾巴”,而不是一句空泛总结。

把这个过程压成图,大致是这样:

原始 transcript 历史

估 token 并剥离不该摘要的冗余明细

按 token 切块

保护 tool call 与 tool result 配对

逐块摘要

合并 partial summaries

补回保留后缀: recent turns tool failures file ops

写入 compaction 条目

未来回放: compaction 摘要加 firstKeptEntryId 之后的消息

第一层:触发时机

  • 一种是在真正溢出后触发,也就是模型已经明确报上下文过长。
  • 另一种是在接近阈值时提前触发,也就是运行时发现 contextTokens 已逼近 contextWindow - reserveTokens

后者很重要,因为系统不是只为“这一次能塞进去”服务,还要给下一次输出、工具结果和 housekeeping 留余量。

第二层:压缩后的保留结构

  • 老历史不会原样保留,而是变成持久化的 compaction 摘要条目。
  • 最近的后缀消息不会全部吞掉,而是继续以未压缩形式保留。
  • 后续回放看到的,不是“全量历史”,而是“压缩摘要 + 最近保留段”。

也就是说,compaction 的目标不是保真归档,而是构造一个更短、但还能继续工作的 replay 入口。

第三层:切块边界不是随便切

  • 如果切分点刚好落在 assistant 的 tool call 和对应 tool result 之间,系统会调整边界,尽量不把这对关系拆开。
  • 如果尾部还挂着一个尚需保留的工具结果块,系统会倾向于把这段留在未压缩后缀里,而不是强行塞进摘要。
  • 失败或中止的工具块不会无限阻止压缩,否则系统会被少量异常数据拖死。

这说明 OpenClaw 的压缩不是只看 token 数,而是同时保护“执行结构”。

第四层:摘要并非只有一段自然语言

  • 默认路径会走内建的摘要流水线,而不是简单拼一段摘要文本。
  • 在 safeguard 路径里,系统还会尽量保留最近回合、拆分回合提示、部分工具失败信息、文件操作摘要等后缀信息。
  • 如果配置了 compaction provider,插件也可以替换摘要后端;失败时再回退到内建 LLM 摘要路径。

所以 compaction 既是“语义压缩”,也是“执行连续性修复”。

这里顺带能回答“为什么要这么复杂”:

  • 因为 OpenClaw 不是纯聊天系统,而是工具执行系统。
  • 纯聊天摘要丢一点过程,通常只是回答变笨。
  • 工具系统摘要丢掉一次关键配对或当前任务状态,下一轮就可能直接执行错上下文。

所以它的 compaction 设计重点不是“把过去讲短”,而是“让下一轮还能接着做事”。

第五层:压缩前还会先做一次 memory flush

  • 当上下文接近自动压缩阈值时,系统可以先触发一次静默回合。
  • 这次回合的目的不是回复用户,而是提醒模型先把值得长期保留的事实写入 Markdown。
  • 这样即使后面 transcript 被压缩,真正该长期保留的内容也已经从“会话回放层”迁移到了“长期事实层”。

这一步说明 OpenClaw 已经明确承认一个现实:transcript 不适合承担全部长期记忆职责。

和它相对的 pruning,则更像“本轮为了塞进窗口而做的减载”:

  • 它主要减少回放时的体积,尤其是过大的旧工具结果。
  • 它不重写 transcript,不改变那份长期回放事实。
  • 它解决的是“这一轮怎么塞得下”,而不是“之后如何持续回放”。

所以可以把两者简单理解成:

  • compaction:改写长期回放形态,换取后续多轮可持续运行。
  • pruning:减轻当轮回放负担,换取本次上下文装配成功。

8. 记忆系统的关键,不是“能搜到”,而是“先落盘,再召回”

OpenClaw 的记忆设计里,真正重要的不是向量库,而是这条顺序:

  1. 先把值得保留的信息写成 Markdown
  2. 再把 Markdown 建索引
  3. 最后通过 memory_search / memory_get 召回

这和很多 SaaS Agent 把“记忆”藏在内部数据库里不同。它的优点是:

  • 可审计
  • 可手工纠错
  • 可迁移
  • 可与普通工程文档共存

但代价也很明确:

  • 模型不会自动拥有永久记忆,必须触发写入。
  • 检索新鲜度依赖 watch、debounce、按需同步或定期更新,不是无条件实时。
  • 混合检索虽然提升召回,但会引入更多参数与调优面。

项目中比较成熟的一点,是它没有把“向量检索”神化,而是采用更务实的混合路子:

  • 关键词检索:补足精确 token、ID、符号名查询。
  • 向量检索:补足语义相近但措辞不同的召回。
  • 时间衰减:让近因信息更容易浮上来。
  • MMR 重排:降低重复片段挤占结果。

这不是为了追求“学术上最优”,而是为了让真实工作区里的 Markdown 更能用。

9. 渠道抽象的本质:统一入站,不强求统一能力

OpenClaw 并不是把所有渠道“做成一样”,而是:

  • 把入站事件统一成可路由的上下文
  • 把出站渲染按各渠道约束单独处理

这是更现实的做法。因为不同渠道本来就不对称:

  • Telegram / Slack / Discord 更像开放 Bot API。
  • WhatsApp 依赖 Web 协议模拟。
  • iMessage 这类能力则需要本机桥接;新接入更推荐 BlueBubbles,imsg 属于遗留路径。
  • 还有一部分渠道根本不在 core,而是通过单独插件安装。

因此,OpenClaw 的渠道层目标不是“抹平平台差异”,而是把差异压缩到适配层,不让上层运行时和工具系统被协议细节淹没。

10. 插件边界的本质:核心只做控制,能力尽量外插

OpenClaw 的扩展面比较清晰:

  • Channel 插件:扩展入口与出站能力。
  • Provider 插件:扩展模型提供方。
  • Tool / Skill / Hook 插件:扩展执行能力与生命周期干预点。
  • Memory / Context Engine slot:替换部分核心子系统。

这说明它的核心思路不是“把所有东西都内建”,而是:

  • 核心负责控制平面与稳定边界。
  • 变化快、供应商相关、协议相关的部分尽量插件化。

这比“一个超大核心里堆满各种渠道和工具特殊逻辑”更容易长期演进。

当然,插件化不是零成本:

  • 调试路径更长。
  • 插件装载、启用、优先级与配置校验更复杂。
  • hook 过多时,问题定位会从“哪段代码错了”变成“哪条生命周期被谁改写了”。

11. 安全模型的本质:不是禁止能力,而是把能力放进边界

OpenClaw 的安全设计,不是靠一句“请小心操作”完成的,而是分层做约束:

  • 入口约束:DM allowlist、pairing、群聊 mention / 激活规则。
  • 执行约束:危险工具审批、策略限制、只读工作区、沙箱工作区。
  • 输出约束:对工具结果做截断与净化,避免把外部不可信输出原样塞回后续上下文。
  • 可见性约束NO_REPLY、静默 flush、消息发送抑制,避免系统内部 housekeeping 泄漏到用户表面。

其中比较容易被忽略但很关键的一点是:

  • OpenClaw 不只控制“能不能调工具”,还控制“结果是否应该被用户看到”

例如:

  • 接近 compaction 时会触发一次静默 memory flush,提醒模型把耐久信息写入 Markdown。
  • 精确的 NO_REPLY 会被出站层识别并抑制。
  • 当消息工具已经对外发出内容时,系统还会做重复确认抑制,避免模型再回一遍“我已经发出了消息”。

这类机制看似细碎,实际上决定了系统会不会显得“啰嗦、穿帮、把内部流程暴露给用户”。

12. 队列与回压:系统活性来自调度,不来自模型自觉

OpenClaw 没把“并发控制”交给模型,而是放在 Gateway 调度层。

几个关键点:

  • 按 session lane 串行:同一会话一次只跑一个 run。
  • 按 global lane 限流:全局并发也受上限控制。
  • 入站去重:处理渠道重复投递。
  • 入站去抖:把短时间连续文本合并成一次 turn。
  • 队列模式:支持 collectfollowupsteerinterrupt 等策略。

这套机制背后的本质是:

  • 一致性优先于极限实时性
  • 系统活性依赖显式调度,而不是寄希望于模型“自己别乱来”

代价是:

  • 高峰时会产生排队等待。
  • 若配置不当,用户会感知到“怎么消息发了但要过一会儿才处理”。

但这个代价比“多轮 run 抢写同一 session”要小得多。

13. 一个更准确的数据流心智模型

可以把它理解成下面这条链路:

外部消息
-> 渠道适配
-> 归一上下文
-> session 路由
-> 队列与串行化
-> 单回合 agent loop
-> 工具/技能/插件
-> transcript 与 memory 落盘
-> 渠道渲染与发送

注意这里有两个关键回路:

  • 执行回路:消息进入 -> run 执行 -> 结果发出
  • 知识回路:有价值信息 -> 写入 Markdown -> 建索引 -> 后续再召回

很多系统只把第一条做出来,于是“当轮能答”;OpenClaw 试图把第二条也做稳,所以它更像控制平面而不是聊天壳子。

14. 如果要复刻这种系统,真正该抄的不是界面,而是这些约束

  • 不要做“每个会话一个永久 while true 智能体”。
  • 做“每次事件触发一个短生命周期 run,并由控制平面重建工作集”。
  • 不要把 transcript 当长期记忆。
  • 把长期事实写入可审计文件,并允许人工修正。
  • 不要把渠道差异直接扩散到运行时核心。
  • 在适配层完成协议归一,在出站层处理平台限制。
  • 不要把安全寄托在 prompt 里。
  • 在入口、执行、输出三层都放硬约束。
  • 不要假设上下文无限大。
  • 把上下文构建、压缩、剪枝、静默 housekeeping 当一等公民。

15. OpenClaw 最有价值的地方

它最值得学的不是“支持很多渠道”,也不是“工具很多”,而是它把 Agent 系统里几件最容易混淆的东西拆清楚了:

  • 控制平面一次 run
  • 会话日志长期事实
  • 记忆事实源检索加速层
  • 入口适配能力执行
  • 可调用可安全交付

这使得它可以用相对朴素的工程材料去搭复杂系统:

  • sessions.json
  • *.jsonl
  • Markdown
  • SQLite
  • CLI / Cron / Hooks
  • 插件与 slot

朴素不代表简单,而是指这些部件的边界比较清楚,可审计、可替换、可恢复。


Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐