对话背景:围绕 OpenClaw 多 Agent 架构的上下文隔离、Sub-agent 机制、Skill 隔离、并发调度、记忆压缩等核心机制进行系统性问答。
核心需求:理解 OpenClaw 的上下文管理、Sub-agent 创建与隔离、Skill 权限控制、并发与路由机制,并能够配置实现。
一、架构设计理念:从职能划分到上下文隔离
1.1 核心观点
多 Agent 架构不应按"角色"(规划者/执行者/审查者)划分,而应转向上下文隔离 + 工具模块化。
- Anthropic:通过 Harness 实现模型-工具-环境解耦
- OpenAI:通过 Managed Agents 实现元调度
- Google:通过 Session 化重构 实现上下文隔离
1.2 关键收益
- 上下文连续性可控
- Token 消耗可隔离(Sub-agent 做脏活,主流程保持清爽)
- 工具与能力按需加载,而非按角色绑定
二、核心概念速查(按首次出现顺序排列)
| 名词 | 定义 | 类比 |
|---|---|---|
| Context(上下文) | Agent 单次推理时能看到的全部信息总和,包括 System Prompt、历史消息、Skill 文件、记忆文件、工具返回结果 | 学生做试卷时桌上能看到的所有资料 |
| Session(会话) | 用户与 Agent 的一次独立交互实例,拥有独立的聊天历史。格式:agent:<agent-name>:<channel>:<mode>:<user-id> | 病历本(每个病人一本,医生共享) |
| Harness | 维持模型调用循环、拼装 Prompt、路由工具调用到基础设施的控制层。Anthropic 定义其为"模型运行所依赖的指令集与护栏" | 大脑调度中枢 |
| Compaction(压缩) | 当上下文接近窗口上限时,将历史消息切片、摘要、替换,腾出 Token 空间的过程 | 把 50 页笔记折叠成 1 页摘要 |
| Sub-agent(子 Agent) | 由 Main Agent 通过 sessions_spawn 动态创建的独立 Session,在隔离的 Context Window 中异步执行任务 | 外包工人 |
| Skill | 封装特定能力的模块,包含 SKILL.md 描述 + 工具调用逻辑,可被 Agent 加载使用 | 医生的专业技能包 |
| Sandbox(沙箱) | Agent 运行时的文件系统隔离环境,限制 read/write/exec 的访问范围 | 隔离病房 |
| Token | LLM 处理文本的最小单位。中文约 1 Token ≈ 1.5–2 个汉字 | 试卷上的格子 |
| Context Window(上下文窗口) | 模型单次推理能处理的最大 Token 数(如 Claude 200K、GPT-4o 128K) | 试卷总格子数 |
| Lobster | OpenClaw 的原生工作流编排引擎,通过 YAML 定义确定性执行流程 | 流水线控制器 |
| Binding | 将特定频道/账号/群组固定路由到特定 Agent 的配置规则 | 前台分诊台 |
三、上下文(Context)与压缩机制
3.1 Context 的组成
Context 不是"对话框",而是 Agent 单次推理时的完整信息栈:
- System Prompt(
SOUL.md+MEMORY.md+CLAUDE.md) - 历史对话消息(用户输入 + Agent 输出 + 工具调用结果)
- 加载的 Skill 文件(
SKILL.md) - 当前工具返回的实时结果
规格与限制:
- 硬上限:受模型上下文窗口限制(Claude 200K、GPT-4o 128K 等)
- 软上限:Bootstrap(系统提示词)单文件默认 20K 字符,总计约 150K
- 压缩触发线:对话 Token 逼近上限时(默认提前 4000 tokens)触发 Auto-Compaction
3.2 五级上下文压缩(由轻到重依次触发)
| 级别 | 名称 | 通俗解释 | 触发时机 |
|---|---|---|---|
| ① | 工具结果预算限制 | 搜索结果太长,只看前 5000 字 | 每次调用搜索/浏览器等工具时自动截断 |
| ② | Snip(裁剪最旧消息) | 把最早几条聊天记录直接删掉 | 对话历史太长,保留最近 5 轮 |
| ③ | Microcompact(API 级缓存编辑) | 把工具调用结果改成一句话总结 | 针对工具返回的原始数据轻量压缩 |
| ④ | Context Collapse(分阶段折叠) | 把前面 50 页笔记折叠成 1 页摘要 | 历史超过阈值,按块切片摘要 |
| ⑤ | Auto Compact(全量摘要生成) | 整本笔记重写,只保留精华 | 以上四招都不够时全局大扫除 |
触发方式:
- 自动:当前 Token > 窗口大小 - 预留缓冲(如 200K 窗口预留 20K,超过 180K 触发)
- 手动:用户输入
/compact - 强制溢出:LLM 返回"上下文太长"错误时,以
trigger: "overflow"强制执行
3.3 切片(Chunking)的自适应算法
核心参数:
BASE_CHUNK_RATIO = 0.4:默认每块占上下文窗口的 40%MIN_CHUNK_RATIO = 0.15:单条消息平均占窗口 10% 以上时,自动缩小到 15%SAFETY_MARGIN = 1.2:给摘要指令和输出预留 20% 安全缓冲
计算示例(200K 窗口):
场景 A:普通聊天(消息短而多)
- 历史 30 条共 150K,平均每条 5K(占窗口 2.5% < 10%)
- 触发
BASE_CHUNK_RATIO = 0.4 - 每块额定大小 = 200K × 0.4 = 80K
- 实际可装历史 = 80K ÷ 1.2 ≈ 66.7K
- 150K 历史 ÷ 66.7K ≈ 3 块
- 每块装约 13 条消息(按 Token 累积,非固定条数)
场景 B:长文档分析(消息长而少)
- 历史 5 条共 150K,平均每条 30K(占窗口 15% > 10%)
- 触发
MIN_CHUNK_RATIO = 0.15 - 每块额定大小 = 200K × 0.15 = 30K
- 实际可装历史 = 30K ÷ 1.2 = 25K
- 150K 历史 ÷ 25K = 6 块
- 每块装约 1 条长消息
为什么自适应?
- 消息短:大块切,一次多装几条,减少 API 调用次数
- 消息长:小块切,一次少装几条,防止 LLM 超载、摘要遗漏细节
3.4 压缩时的标识符保全
压缩过程中禁止模型改写:
- UUID、API Key、Hash、Hostnames
- 确保"风景可以被遗忘,但执行锚点依旧精准"
3.5 Silent Turn(静默固化)
当 Token 逼近红线(默认提前 4000 tokens),系统抛出用户看不见的静默提示,让模型在"被洗脑前"把重要线索写入当天日志,再输出 NO_REPLY。
四、Session 机制
4.1 Session 的本质
Session 是交互实例,Agent 是处理大脑。一个 Agent 可服务多个 Session,但 Session 之间上下文完全隔离。
Session Key 格式:
agent:<agent-name>:<channel>:<mode>:<user-id>
示例:
agent:main:feishu:direct:ou_123(飞书私聊)agent:main:discord:thread:thread_789(Discord 线程)
4.2 存储位置
每个 Session 的聊天记录独立存储在:
~/.openclaw/agents/<agentId>/sessions/
4.3 并发调度配置
多个 Session 同时向同一个 Agent 发消息时,Gateway 通过两层队列管理:
| 层级 | 作用 | 配置项 |
|---|---|---|
| Session Lane | 同一 Session 的消息串行执行(防止文件竞争) | 自动生效,无需配置 |
| 全局 Main 队列 | 不同 Session 之间的并发数控制 | agents.defaults.maxConcurrent |
配置示例:
{
"agents": {
"defaults": {
"maxConcurrent": 4
}
},
"messages": {
"queue": {
"mode": "collect",
"debounceMs": 1000,
"cap": 20,
"drop": "summarize"
}
}
}
队列模式:
followup:每条消息单独触发 Agent runcollect:快速连续消息先收集,等安静期后合并处理steer-backlog:高级模式,可手动干预队列
溢出策略:
old:丢弃最旧消息new:丢弃最新消息summarize:默认,把被丢弃消息合成摘要注入上下文
五、Harness(调度核心)
5.1 定义
Harness 是维持循环、拼装 Prompt、路由工具调用到对应基础设施的控制层。Anthropic 将 Agent 拆解为四层:
| 组件 | 角色 | 职责 |
|---|---|---|
| Model | 推理引擎 | 理解、规划、生成 |
| Harness | 大脑/调度器 | 维持循环,路由工具调用 |
| Tools | 双手 | 代码执行、文件操作、API 调用 |
| Environment | 身体 | Agent 运行的系统环境 |
5.2 在 OpenClaw 中的实现
- Gateway:维护长连接、消息路由、协议转换、安全验证
- Agent Loop(基于 pi-mono 的 ReAct 循环):调用模型 → 解析工具请求 → 分发执行 → 收集结果 → 继续循环
5.3 工具调用与输出格式
- 组装 System Prompt + 历史消息
- 调用 LLM API
- 模型返回内容(包含
<thinking>和<tool>标签) - Agent Loop 解析输出:
- 普通文本 → 直接返回用户
- 工具调用 → 提取参数 → 路由到 Tool Handler → 执行 → 收集结果 → 格式化为 Observation → 追加到上下文 → 再次调用 LLM(ReAct 循环)
输出格式控制:
- Tool 定义采用 JSON Schema 约束,模型必须按 Schema 输出参数
- 在 Skill 的
SKILL.md中可定义输出模板(Markdown 表格、JSON、YAML)
六、Sub-agent 机制
6.1 核心作用
用隔离的 Context Window 消耗 Token、做搜索/分析,然后把结果压缩成 1000–2000 Token 的摘要合并回主流程。
6.2 创建方式
Sub-agent 是 Main Agent 动态创建的,不是用户在 JSON 中预定义的独立 Agent。
创建流程:
- Main Agent 调用内置工具
sessions_spawn - Gateway 立即返回
childSessionKey和runId,不阻塞 - 后台创建独立 Session(如
agent:main:subagent:<uuid>) - Sub-agent 在独立 Context Window 中异步执行任务
- 完成后通过
announce把结果推回父 Agent 的聊天上下文
调用示例(LLM 自动生成):
{
"tool": "sessions_spawn",
"parameters": {
"agent": "code-reviewer",
"task": "审查 PR #123 的安全性",
"mode": "run"
}
}
模式区别:
mode: "run":一次性跑完返回结果mode: "session":持久化,可后续交互
6.3 独立 Agent vs Sub-agent
| 独立 Agent | Sub-agent | |
|---|---|---|
| 创建方式 | 用户在 ~/.openclaw/agents/ 手动创建目录和配置文件 | Main Agent 运行时通过 sessions_spawn 动态 fork |
| 生命周期 | 持久化 | 随任务创建,完成后归档/销毁 |
| 上下文 | 完全独立,有自己的 MEMORY.md | 继承父 Agent 工作目录,但 Session 隔离 |
| 适用场景 | 高频使用的专业角色 | 一次性、并行的临时任务 |
6.4 配置控制
{
"agents": {
"defaults": {
"subagents": {
"model": "anthropic/claude-haiku-4-5",
"thinking": "low",
"maxConcurrent": 4,
"runTimeoutSeconds": 300,
"archiveAfterMinutes": 30
}
},
"list": [
{
"id": "main",
"subagents": {
"allowAgents": ["code-reviewer", "doc-writer"],
"maxSpawnDepth": 1,
"maxChildrenPerAgent": 5
}
}
]
}
}
配置项解释:
| 配置项 | 含义 | 默认值 |
|---|---|---|
allowAgents | Main Agent 能 spawn 的目标 Agent 白名单 | 空(无限制) |
maxSpawnDepth | Sub-agent 嵌套深度。1 表示 Main 可 spawn Sub,但 Sub 不能再 spawn | 1 |
maxChildrenPerAgent | 一个父 Agent 同时能有多少个活着的 Sub-agent | 视版本而定 |
maxConcurrent | 全局 Sub-agent 队列并发上限 | 8(Sub-agent 队列) |
model | Sub-agent 使用的模型(可用便宜模型) | 继承主 Agent |
runTimeoutSeconds | Sub-agent 运行超时时间 | 120 |
嵌套深度限制:
maxSpawnDepth: 1:Main → Sub(Sub 不能再 spawn)- 优点:防止 Token 成本爆炸、调度混乱、架构扁平化、安全隔离(深度 ≥ 2 时 Sub-agent 默认被剥夺
sessions_spawn)
并行任务启用:
由 Main Agent 的 LLM 自行判断。当用户提出可拆分的复杂任务时,LLM 会连续调用多次 sessions_spawn。真正的并行受限于 maxConcurrent。
6.5 成本对比
- 5 个并行 Haiku Sub-agent 的 Token 成本 ≈ 1 个 Opus 主 Agent 的 Token 成本
- Sub-agent 把 10 万 Token 的调研过程压缩成 1000 Token 摘要传回,父 Agent 只需处理摘要
七、记忆系统
7.1 记忆生成时机
| 触发方式 | 时机 | 写入内容 |
|---|---|---|
| Compaction 触发 | Session 接近上下文上限时自动压缩 | 提取重要事实、结论、偏好,写入 memory.sqlite 或 memory/*.md |
| Silent Turn(静默固化) | Token 逼近红线前(默认提前 4000 tokens) | 关键线索、待办事项、上下文锚点 |
7.2 存储结构
MEMORY.md:长期核心事实memory/YYYY-MM-DD.md:每日日志AGENTS.md:能力反思
7.3 混合检索机制
对 memory/*.md 日志采用 向量搜索(语义匹配)+ BM25(关键词搜索),权重 7:3,互补召回。
时间半衰期:默认 30 天,过时记忆自然衰减淘汰。
7.4 分块写入与检索优化
问题:默认按 400 Token/块 硬切,不识别语义边界,可能切断句子。
补偿策略:
| 策略 | 实现方式 |
|---|---|
| 重叠滑动窗口 | 相邻块保留 10–20% 重叠(需改源码) |
| Markdown 标题分块 | 让 Agent 输出记忆时按 # ## ### 标题组织,标题处优先断开 |
| 后置摘要补偿 | 召回片段让模型二次摘要,补全被切断语义 |
| 按主题分文件 | memory-frontend.md、memory-backend.md,检索时先按文件名过滤 |
Markdown 标题分块示例:
# Session: 2026-04-24
## Summary
用户决定使用 Next.js。
## Key Points
- 用户偏好 Telegram 通知
## Action Items
- [ ] 调研 Next.js 14
分块后:
- Chunk 0:
# Session...到## Key Points之前 - Chunk 1:
- 用户偏好...到结尾
为什么有效:底层算法遇到 Markdown 标题会优先断开,保证每个块内部语义自洽。
八、Skill 管理与隔离
8.1 Skill 加载优先级(从高到低)
1. <workspace>/skills/ ← Agent 私有(最高)
2. <workspace>/.agents/skills/ ← 项目级私有
3. ~/.agents/skills/ ← 个人级共享
4. ~/.openclaw/skills/ ← 机器级共享
5. 内置 skills(随安装包提供) ← 全局
6. skills.load.extraDirs ← 额外配置目录(最低)
8.2 隔离手段
| 手段 | 配置 | 效果 |
|---|---|---|
| Agent 级白名单 | agents[].skills.allow | 精确控制该 Agent 能加载哪些 Skill |
| 目录物理隔离 | ~/.openclaw/agents/<id>/skills/ | 私有 Skill 其他 Agent 看不到 |
| 工具级 Deny | agents[].tools.deny | 禁用底层工具,间接废掉依赖该工具的 Skill |
| Sandbox 隔离 | agents[].sandbox.workspaceAccess | 限制文件系统访问范围 |
8.3 关键配置项
{
"skills": {
"load": {
"extraDirs": ["/company/shared-skills"]
},
"allowBundled": ["filesystem", "exec", "git"]
}
}
extraDirs:额外加载 Skill 的目录路径数组,优先级最低allowBundled:允许使用的内置工具白名单
8.4 两个 Agent 隔离 Skill 的最佳实践
- 敏感 Skill(如
kubectl、db-admin)放在特定 Agent 的私有目录 - 通用 Skill(如
git、search)放在~/.openclaw/skills/共享 - 同名 Skill 冲突时,工作区私有版本优先
九、路由与过滤
9.1 Bindings 频道级路由(最硬)
{
"bindings": [
{ "agentId": "writer", "match": { "channel": "telegram", "accountId": "writing-group" } },
{ "agentId": "coder", "match": { "channel": "telegram", "accountId": "code-group" } }
]
}
- 零 LLM 消耗,按频道/群组固定路由
9.2 SOUL.md / AGENTS.md 路由规则(软引导)
在 Agent 的 AGENTS.md 中写入委派规则,LLM 根据用户输入自行判断 spawn 哪个 Sub-agent:
## Agent 委派规则
- 用户提到"代码"、"PR"、"审查" → 派给 code-reviewer
- 用户提到"文档"、"README" → 派给 doc-writer
- 简单问答 → 自己处理,不要 spawn
9.3 Lobster 工作流编排(确定性流程)
Lobster 是 OpenClaw 原生工作流引擎,通过 YAML 定义确定性执行流程。
启用方式:
- 安装:
pnpm install -g lobster - 在
openclaw.json中启用工具:"tools": { "alsoAllow": ["lobster"] } - 在 workspace 创建
.lobster文件
示例:
name: blog-pipeline
steps:
- id: research
pipeline: openclaw.invoke --tool llm-task --action json ...
- id: write
stdin: $research.json
- id: review
approval: "Review before publishing?"
注意:Lobster 是工作流编排,不是"前置关键词过滤层"。
9.4 前置关键词路由(当前限制)
OpenClaw 原生不支持精确的关键词 → Sub-agent 映射表。如需 100% 确定性关键词路由,需在外部自建 Gateway 插件或前置分类器。
十、文件系统与 Sandbox
10.1 Sandbox 配置
{
"agents": {
"list": [{
"id": "main",
"sandbox": {
"mode": "all",
"workspaceAccess": "rw"
}
}]
}
}
| 模式 | 含义 |
|---|---|
"mode": "off" | 无隔离,可访问任意路径(危险) |
"mode": "non-main" | 仅 Sub-agent 隔离,Main Agent 不隔离 |
"mode": "all" | 全部隔离 |
| workspaceAccess | 效果 |
|---|---|
"none" | 只能访问沙箱临时目录 |
"ro" | 只读挂载 Agent 工作区 |
"rw" | 读写挂载 Agent 工作区 |
10.2 路径限制
tools.fs.workspaceOnly: true时,read/write/edit只能操作工作区目录内文件- 沙箱阻止
../路径逃逸
十一、关键配置参数汇总表
| 参数 | 配置位置 | 默认值 | 作用 |
|---|---|---|---|
BASE_CHUNK_RATIO | 源码/内部 | 0.4 | 默认每块占上下文窗口比例 |
MIN_CHUNK_RATIO | 源码/内部 | 0.15 | 消息很长时的块比例 |
SAFETY_MARGIN | 源码/内部 | 1.2 | 摘要安全缓冲系数 |
maxConcurrent | agents.defaults / agents.list[] | 4(Main)/ 8(Sub-agent) | 全局并发上限 |
maxSpawnDepth | agents.list[].subagents | 1 | Sub-agent 嵌套深度 |
maxChildrenPerAgent | agents.list[].subagents | 视版本 | 父 Agent 同时存活 Sub-agent 数 |
allowAgents | agents.list[].subagents | [](无限制) | Main 可 spawn 的白名单 |
runTimeoutSeconds | agents.defaults.subagents | 120 | Sub-agent 运行超时 |
archiveAfterMinutes | agents.defaults.subagents | 30 | Sub-agent 完成后归档时间 |
debounceMs | messages.queue | 1000 | 消息收集安静期 |
cap | messages.queue | 20 | 队列容量上限 |
workspaceAccess | agents.list[].sandbox | "rw" | 沙箱工作区访问权限 |
workspaceOnly | tools.fs | false | 是否限制文件操作在工作区内 |
十二、最佳实践与避坑指南
- Sub-agent 用便宜模型:
"model": "anthropic/claude-haiku-4-5",降低成本 - 敏感 Skill 不放共享层:放在 Agent 私有目录,防止越权访问
- Sandbox 生产环境必开:
"mode": "all",防止文件系统逃逸 - 记忆按主题分文件:
memory-frontend.md、memory-backend.md,检索时先文件名过滤 - 两个飞书机器人绑定同一 Agent 的风险:共享
MEMORY.md,不同群体(对外客户/对内员工)绝对不要绑定同一 Agent,防止信息泄露 - 不要依赖 LLM 做精确关键词路由:如需 100% 确定性,用 Bindings 频道隔离或外部分类器
- Compaction 前利用 Silent Turn:系统自动把关键线索写入日志,防止压缩丢失上下文锚点
- 验证 Skill 隔离:使用
openclaw skills list --agent <id> --show-source检查实际加载来源
2484

被折叠的 条评论
为什么被折叠?



