Add OpenClaw architecture and skill system notes
Notes on overall architecture, skill invocation mechanism, and skill management design based on OpenClaw 2026.6.2 source.
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
# OpenClaw 整体架构设计
|
||||
|
||||
> 本文是对 OpenClaw 代码库的架构梳理笔记(基于 2026.6.2 版本源码与 `docs/concepts/architecture.md`、根 `AGENTS.md`),
|
||||
> 从三个视角描述系统:运行时拓扑、代码分层、消息流转。
|
||||
|
||||
## 1. 运行时拓扑:单 Gateway 控制平面
|
||||
|
||||
整个系统的核心是一个**单实例、长驻的 Gateway 守护进程**(每台主机一个,默认绑定 `127.0.0.1:18789`,
|
||||
由 launchd/systemd 托管)。它是唯一的控制平面:所有消息渠道连接、所有控制面客户端、所有设备节点都汇聚到这里。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph Channels["消息渠道(用户在这里说话)"]
|
||||
WA[WhatsApp<br/>Baileys]
|
||||
TG[Telegram<br/>grammY]
|
||||
DC[Discord / Slack /<br/>Signal / iMessage / 微信...]
|
||||
WC[WebChat]
|
||||
end
|
||||
|
||||
subgraph GW["Gateway 守护进程(单实例,launchd/systemd 托管)"]
|
||||
WS[WebSocket 服务<br/>typed req/res + event,JSON Schema 校验]
|
||||
RT[路由层<br/>渠道/账号/对端 → agent]
|
||||
AG[Agent 运行时<br/>会话、队列、工具调用循环]
|
||||
CRON[Cron / Webhook<br/>自动化触发]
|
||||
CANVAS["Canvas Host<br/>/__openclaw__/canvas + a2ui"]
|
||||
DB[(SQLite 状态库<br/>state/openclaw.sqlite<br/>+ 每 agent 独立库)]
|
||||
end
|
||||
|
||||
subgraph Clients["控制面客户端(role: client)"]
|
||||
CLI[openclaw CLI]
|
||||
MAC[macOS 菜单栏 App]
|
||||
WIN[Windows Hub]
|
||||
ADMIN[Web 管理 UI]
|
||||
end
|
||||
|
||||
subgraph Nodes["设备节点(role: node,设备配对)"]
|
||||
IOS[iOS 节点<br/>语音唤醒/Canvas]
|
||||
AND[Android 节点<br/>相机/录屏/语音]
|
||||
end
|
||||
|
||||
subgraph LLM["模型提供商"]
|
||||
P1[Anthropic / OpenAI /<br/>Gemini / 本地模型...]
|
||||
end
|
||||
|
||||
Channels <--> RT
|
||||
RT --> AG
|
||||
AG <--> P1
|
||||
AG --> DB
|
||||
Clients <-->|WebSocket| WS
|
||||
Nodes <-->|WebSocket| WS
|
||||
WS --> AG
|
||||
CRON --> AG
|
||||
AG --> CANVAS
|
||||
```
|
||||
|
||||
### 协议关键不变量
|
||||
|
||||
- 每台主机只有一个 Gateway,它是唯一打开 WhatsApp(Baileys)会话的进程。
|
||||
- WebSocket 握手第一帧必须是 `connect`,否则硬关闭连接。
|
||||
- 所有客户端(操作端 + 节点)在 `connect` 时携带设备身份,新设备需配对审批
|
||||
(签名 challenge nonce + 签发设备 token);本机回环连接可自动批准,非本地连接必须显式审批。
|
||||
- 副作用方法(`send`、`agent`)要求幂等键,服务端维护短期去重缓存。
|
||||
- 事件不重放;客户端检测到序号断档后需主动刷新快照。
|
||||
|
||||
## 2. 代码分层:核心与插件的边界
|
||||
|
||||
这是根 `AGENTS.md` 中最强调的设计约束:**core 保持 plugin-agnostic**,
|
||||
插件只能通过 `openclaw/plugin-sdk/*` 公开门面进入核心,禁止反向或越界 import。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Repo["pnpm workspace 单仓"]
|
||||
subgraph Core["核心 src/(发布进 dist)"]
|
||||
GWY[gateway/<br/>WS 服务与协议方法]
|
||||
CHN[channels/<br/>渠道传输实现]
|
||||
AGS[agents/<br/>agent 循环/工具/会话]
|
||||
SKL[skills/ cron/ memory/<br/>media/ tts/ ...]
|
||||
CFG[config/ state/<br/>canonical 配置 + SQLite]
|
||||
SDK[plugin-sdk/<br/>唯一对外门面 barrel]
|
||||
end
|
||||
|
||||
subgraph Ext["extensions/(插件,对外叫 plugins)"]
|
||||
E1[telegram / discord /<br/>slack / whatsapp ...]
|
||||
E2[codex / copilot /<br/>bedrock / vertex ...<br/>模型提供商]
|
||||
E3[memory-lancedb /<br/>voice-call / ...]
|
||||
end
|
||||
|
||||
PKG[packages/*<br/>gateway-protocol, llm-core,<br/>agent-core, sdk ...]
|
||||
UI[ui/ — Control UI]
|
||||
APPS[apps/ — macOS/iOS/Android]
|
||||
DOCS[docs/ → docs.openclaw.ai]
|
||||
end
|
||||
|
||||
Ext -->|"仅允许 import<br/>openclaw/plugin-sdk/*"| SDK
|
||||
SDK --> Core
|
||||
Core --> PKG
|
||||
Core -.->|"禁止 import 插件内部<br/>(只走 manifest/registry)"| Ext
|
||||
APPS -->|"Swift 模型由<br/>JSON Schema 生成"| PKG
|
||||
```
|
||||
|
||||
### 边界规则(核心设计哲学)
|
||||
|
||||
- **插件 → 核心**:只能走 `openclaw/plugin-sdk/*`、manifest 元数据、注入的 runtime helper、
|
||||
文档化的 barrel(`api.ts`、`runtime-api.ts`);禁止 import 核心 `src/**` 或其他插件内部。
|
||||
- **核心 → 插件**:核心代码中不允许出现任何具体插件的 id/默认值/策略,
|
||||
只通过 manifest/registry/capability 这类通用契约发现插件。
|
||||
- **渠道是纯传输层**:只负责渲染可移植的 presentation/action、执行传输限制、映射原生回调封套;
|
||||
产品命令树、provider 策略、功能菜单归核心/owner 插件所有。
|
||||
- **提供商插件**拥有自己的 auth/catalog/runtime hooks;核心只拥有通用 agent 循环。
|
||||
- **状态只进 SQLite**(Kysely 访问,禁止裸 SQL 字符串,DDL/迁移除外):
|
||||
全局状态在 `state/openclaw.sqlite`,agent 级状态在 `agents/<agentId>/agent/openclaw-agent.sqlite`。
|
||||
旧文件格式只在 `openclaw doctor --fix` 迁移代码中处理,运行时无兼容分支、无 fallback 读取。
|
||||
- **配置只有 canonical 形态**:运行时只读当前配置形态;旧配置由 doctor 迁移,不做静默兼容。
|
||||
- **协议链**:TypeBox schema → 生成 JSON Schema → 生成 Swift 模型;
|
||||
协议变更必须先做加法兼容,不兼容变更需要版本化 + 文档 + 客户端跟进。
|
||||
|
||||
## 3. 一条消息的生命周期
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户(Telegram 等)
|
||||
participant CH as 渠道插件<br/>(transport-only)
|
||||
participant GW as Gateway
|
||||
participant RT as 路由
|
||||
participant A as Agent 会话
|
||||
participant LLM as 模型提供商
|
||||
|
||||
U->>CH: 发消息
|
||||
CH->>GW: 标准化入站 envelope
|
||||
GW->>RT: 渠道/账号/对端匹配
|
||||
Note over RT: DM 配对检查:陌生人<br/>收到 pairing code,消息不处理
|
||||
RT->>A: 投递到目标 agent 会话(队列)
|
||||
A->>A: 组装 prompt:系统提示 + skills<br/>快照 + 记忆 + 会话历史
|
||||
loop Agent 循环
|
||||
A->>LLM: completion 请求
|
||||
LLM-->>A: 文本 / 工具调用
|
||||
A->>A: 执行工具(浏览器/bash/canvas...<br/>非 main 会话可进沙箱)
|
||||
end
|
||||
A->>GW: 回复 payload(分块/媒体处理)
|
||||
GW->>CH: 映射为渠道原生格式
|
||||
CH->>U: 回复送达
|
||||
GW-->>GW: 会话/状态写入 SQLite,<br/>事件推送给 WS 订阅者
|
||||
```
|
||||
|
||||
### 安全模型要点
|
||||
|
||||
- 入站 DM 默认视为**不可信输入**:主流渠道默认 `dmPolicy="pairing"`,
|
||||
陌生发送者只收到配对码,消息不进 agent;公开 DM 需要显式 `dmPolicy="open"` + 通配 allowlist。
|
||||
- `main` 会话默认在宿主机直接执行工具(单用户场景);群组/多人场景可配
|
||||
`agents.defaults.sandbox.mode: "non-main"`,非 main 会话进 Docker/SSH/OpenShell 沙箱,
|
||||
并按工具族 allow/deny。
|
||||
- 第三方 skill 视为不可信代码:安装走 ClawHub 信任信封 + 安全扫描,
|
||||
可配 `security.installPolicy` 本地策略命令,失败即拒绝(fail-closed)。
|
||||
|
||||
## 一句话总结
|
||||
|
||||
OpenClaw = **"一个本地 Gateway 进程 + 插件化的渠道/提供商生态 + 通用 agent 循环"**。
|
||||
所有外部世界(聊天软件、设备、模型 API)都被插件适配成统一契约,
|
||||
核心只做路由、会话、工具循环和状态管理;
|
||||
客户端和设备节点统一走带配对认证的 WebSocket 协议接入。
|
||||
|
||||
完整官方文档:<https://docs.openclaw.ai/concepts/architecture>
|
||||
@@ -0,0 +1,102 @@
|
||||
# OpenClaw Skill 触发机制:agent 如何判断是否使用、使用哪个 skill
|
||||
|
||||
> 本文是对 OpenClaw skill 调用决策机制的源码分析笔记(基于 2026.6.2 版本),
|
||||
> 关键源码:`src/skills/loading/skill-contract.ts`(`formatSkillsForPrompt`)、
|
||||
> `src/skills/loading/workspace.ts`(`formatSkillsCompact` / `applySkillsPromptLimits`)。
|
||||
> 配套文档:[skills-management-design.md](./skills-management-design.md)。
|
||||
|
||||
## 核心结论
|
||||
|
||||
**OpenClaw 不做任何代码层面的"技能匹配/检索"——没有 embedding、没有关键词索引、没有路由算法。
|
||||
选择哪个 skill 完全交给模型自己语义判断**,采用渐进式披露(progressive disclosure)设计:
|
||||
prompt 里只放每个技能的元数据目录,正文由模型按需用 `read` 工具加载。
|
||||
|
||||
## 两层决策
|
||||
|
||||
### 第一层:代码决定"哪些可用"
|
||||
|
||||
加载管线(见 skill 管理设计笔记)先把不合格的技能筛掉:
|
||||
|
||||
- 门控不满足(缺二进制 `requires.bins`、缺环境变量 `requires.env`、缺配置 `requires.config`、平台不符 `os`)
|
||||
- agent allowlist 之外(`agents.list[].skills`)
|
||||
- `enabled: false` 或 `disable-model-invocation: true`
|
||||
|
||||
活下来的技能只把**元数据**序列化进系统提示——不含正文:
|
||||
|
||||
```xml
|
||||
The following skills provide specialized instructions for specific tasks.
|
||||
Use the read tool to load a skill's file when the task matches its description.
|
||||
If a skill's <version> differs from a previous turn, re-read its SKILL.md before using it.
|
||||
|
||||
<available_skills>
|
||||
<skill>
|
||||
<name>github</name>
|
||||
<description>Interact with GitHub via gh CLI...</description>
|
||||
<location>/path/to/skills/github/SKILL.md</location>
|
||||
<version>3</version>
|
||||
</skill>
|
||||
...
|
||||
</available_skills>
|
||||
```
|
||||
|
||||
### 第二层:模型决定"用不用、用哪个"
|
||||
|
||||
prompt 里那句指令就是全部机制——
|
||||
*"当任务与某个 skill 的 description 匹配时,用 read 工具加载它的文件"*。即:
|
||||
|
||||
1. 模型拿用户任务和目录里的 `description` 做语义比对(纯 LLM 推理);
|
||||
2. 认为匹配 → 调 `read` 工具读取 `<location>` 指向的 `SKILL.md` 全文;
|
||||
3. 按读到的指令行事(正文里通常写"遇到 X 情况用 Y 工具/命令")。
|
||||
|
||||
**推论:`description` 写得好不好直接决定技能会不会被触发** ——
|
||||
它是 skill 作者手里最重要的"路由表项"。
|
||||
|
||||
## 决策流程图
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
T[用户任务到达] --> M{模型读 available_skills 目录<br/>任务 ≈ 某条 description?}
|
||||
M -->|匹配| R[read 工具读取 SKILL.md 正文]
|
||||
R --> V{version 与上轮一致?}
|
||||
V -->|否| R
|
||||
V -->|是| E[按正文指令执行工具调用]
|
||||
M -->|不匹配| N[正常回答,不用 skill]
|
||||
U[用户敲 /skill-name] -->|user-invocable| R
|
||||
U -->|command-dispatch: tool| D[绕过模型<br/>直接分发到注册工具]
|
||||
```
|
||||
|
||||
## 三个细节设计
|
||||
|
||||
### 1. 预算降级(`applySkillsPromptLimits`)
|
||||
|
||||
技能太多时按梯度退化,尽量保住"模型知道技能存在"这件事:
|
||||
|
||||
| 梯度 | 行为 | 代价 |
|
||||
| --- | --- | --- |
|
||||
| 正常 | name + description + location + version | 无 |
|
||||
| 超出 `maxSkillsInPrompt` | 截断技能数量 | 后面的技能不可见 |
|
||||
| 超字符预算 | 降级 compact 格式:只有 name + location | 丢 description,模型只能按名字匹配 |
|
||||
| 仍超 | 截断 + 注入警告 | `⚠️ Skills truncated... Run openclaw skills check` |
|
||||
|
||||
### 2. 版本失效信号
|
||||
|
||||
目录里带 `<version>`,prompt 指令要求
|
||||
"若 version 与上一轮不同,使用前必须重读 SKILL.md"。
|
||||
这是会话内技能内容更新的缓存失效机制——
|
||||
技能集快照(SkillSnapshot)本身在会话内固定,但正文变更可以通过版本号传导。
|
||||
|
||||
### 3. 绕过模型的路径
|
||||
|
||||
| frontmatter 配置 | 效果 |
|
||||
| --- | --- |
|
||||
| `disable-model-invocation: true` | 不进 `<available_skills>`,模型永远不会自主使用;仅用户可通过 `/skill-name` 触发 |
|
||||
| `command-dispatch: tool` | 斜杠命令连模型都不经过,确定性分发到注册工具(`SkillCommandDispatchSpec`,`argMode: raw` 原样转发参数) |
|
||||
| `metadata.openclaw.always: true` | 反向操作:跳过 requirements 门控,无条件进目录 |
|
||||
|
||||
## 设计渊源
|
||||
|
||||
这与 Anthropic 官方 Agent Skills 的设计同构:
|
||||
目录条目只占几十 token/技能,正文按需加载;
|
||||
**"路由智能"留给模型,"可用性控制"留给代码**。
|
||||
好处是零检索基础设施、技能数量可扩展(token 成本近似常数),
|
||||
代价是触发可靠性依赖模型能力与 description 质量。
|
||||
@@ -0,0 +1,188 @@
|
||||
# OpenClaw Skill 管理整体设计
|
||||
|
||||
> 本文是对 OpenClaw skill(技能)系统的设计梳理笔记(基于 2026.6.2 版本源码 `src/skills/`、
|
||||
> `docs/tools/skills.md` 与根 `AGENTS.md`)。
|
||||
> Skill 是教 agent "如何及何时使用工具"的 markdown 指令单元,遵循 [AgentSkills](https://agentskills.io) 规范。
|
||||
|
||||
## 0. 基本单元:SKILL.md
|
||||
|
||||
每个 skill 是一个目录,核心是带 YAML frontmatter 的 `SKILL.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: image-lab
|
||||
description: Generate or edit images via a provider-backed image workflow
|
||||
metadata: {"openclaw": {"requires": {"bins": ["ffmpeg"]}, "emoji": "🎨"}}
|
||||
user-invocable: true
|
||||
---
|
||||
|
||||
When the user asks to generate an image, use the `image_generate` tool...
|
||||
```
|
||||
|
||||
关键契约(见 `src/skills/types.ts`):
|
||||
|
||||
- `name` / `description` 必填;name 决定技能名、斜杠命令名、allowlist 键(缺省取目录名)。
|
||||
- `metadata.openclaw.requires`:门控声明 —— `bins` / `anyBins`(命令行二进制)、`env`(环境变量)、
|
||||
`config`(配置项)、`os`(平台),不满足则该 skill 不进 prompt。
|
||||
- `metadata.openclaw.install`:声明式安装规格(`brew | node | go | uv | download`),
|
||||
缺二进制时引导安装。
|
||||
- 调用策略:`user-invocable`(暴露为斜杠命令)、`disable-model-invocation`(不进模型 prompt)、
|
||||
`command-dispatch: tool`(斜杠命令绕过模型直接分发到注册工具)。
|
||||
- frontmatter 解析器只支持**单行键**,`metadata` 必须是单行 JSON;正文可用 `{baseDir}` 引用技能目录。
|
||||
|
||||
## 1. 模块地图(src/skills/)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph SK["src/skills/"]
|
||||
LOAD[loading/<br/>多源扫描、frontmatter 解析、<br/>优先级合并、序列化进 prompt]
|
||||
DISC[discovery/<br/>门控过滤、skill 索引、<br/>斜杠命令生成、agent 过滤]
|
||||
LIFE[lifecycle/<br/>安装/更新:ClawHub、Git、<br/>本地目录、zip 上传]
|
||||
RUN[runtime/<br/>会话/cron 快照、env 注入、<br/>tool 直接分发、远程节点 eligibility]
|
||||
SEC[security/<br/>安装扫描器、ClawHub 信任裁决、<br/>workspace 审计]
|
||||
WORK[workshop/<br/>agent 提案队列:<br/>store / policy / service]
|
||||
RES[research/<br/>autocapture:从会话中<br/>捕捉可复用工作流信号]
|
||||
CFG[config/<br/>skills.* 配置变更]
|
||||
end
|
||||
|
||||
LOAD --> DISC --> RUN
|
||||
LIFE --> LOAD
|
||||
SEC -.->|安装前置闸门| LIFE
|
||||
RES --> WORK -->|apply 写回| LOAD
|
||||
CFG --> LOAD
|
||||
|
||||
CLI[openclaw skills CLI<br/>+ Gateway skills.* 方法] --> LIFE
|
||||
CLI --> WORK
|
||||
HUB[(ClawHub<br/>clawhub.ai 注册表)] <--> LIFE
|
||||
```
|
||||
|
||||
## 2. 加载管线:从磁盘到 agent prompt
|
||||
|
||||
技能从六类来源加载,**同名时高优先级覆盖低优先级**;
|
||||
任何根目录下出现 `SKILL.md` 即被发现(子目录层级仅作组织用)。
|
||||
|
||||
| 优先级 | 来源 | 路径 | 可见范围 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1(最高) | Workspace skills | `<workspace>/skills` | 仅该 agent |
|
||||
| 2 | 项目 agent skills | `<workspace>/.agents/skills` | 仅该工作区 agent |
|
||||
| 3 | 个人 agent skills | `~/.agents/skills` | 本机所有 agent |
|
||||
| 4 | 托管/本地 skills | `~/.openclaw/skills` | 本机所有 agent |
|
||||
| 5 | 内置 skills | 随安装包发布(仓库 `skills/`,约 50 个) | 本机所有 agent |
|
||||
| 6(最低) | 额外目录 + 插件 skills | `skills.load.extraDirs`、插件 manifest 的 `skills` 字段 | 本机所有 agent |
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph Sources["技能来源(优先级从高到低)"]
|
||||
S1[workspace/skills]
|
||||
S2[workspace/.agents/skills]
|
||||
S3[~/.agents/skills]
|
||||
S4[~/.openclaw/skills]
|
||||
S5[内置 bundled]
|
||||
S6[extraDirs + 插件 skills]
|
||||
end
|
||||
|
||||
SCAN[扫描 + frontmatter 解析<br/>loading/]
|
||||
PATH{路径收敛检查<br/>realpath 必须在根内<br/>除非 allowSymlinkTargets}
|
||||
GATE{门控过滤 discovery/filter<br/>requires.bins / env / config / os}
|
||||
MERGE[同名合并:高优先级覆盖]
|
||||
ALLOW{agent allowlist<br/>agents.list#91;#93;.skills}
|
||||
|
||||
Sources --> SCAN --> PATH --> GATE --> MERGE --> ALLOW
|
||||
|
||||
subgraph Outputs["产出(同一份有效集,四处一致)"]
|
||||
SNAP["SkillSnapshot<br/>(prompt 片段 + env 需求 + 版本号)<br/>会话级固定,cron 另有快照"]
|
||||
CMD["斜杠命令注册<br/>/skill-name(渠道可见)"]
|
||||
SBX[沙箱同步<br/>非 main 会话的技能文件]
|
||||
REG[运行时注册表<br/>tool 直接分发]
|
||||
end
|
||||
|
||||
ALLOW --> SNAP & CMD & SBX & REG
|
||||
```
|
||||
|
||||
设计要点:
|
||||
|
||||
- **位置与可见性分离**:目录优先级只决定"谁覆盖谁";agent 能看到什么由 allowlist 决定
|
||||
(`agents.defaults.skills` 为共享基线,`agents.list[].skills` 非空时**整体替换**而非合并,
|
||||
`[]` 表示零技能,省略则不限制)。
|
||||
- **快照(snapshot)语义**:会话开始时固化一份 `SkillSnapshot`(prompt 文本 + 所需 env + 版本号),
|
||||
会话中途技能变更不影响进行中的会话;cron 任务有独立的快照路径(`runtime/cron-snapshot.ts`)。
|
||||
这与 AGENTS.md "hot path 不做 freshness 轮询" 的原则一致 —— 技能集是进程稳定元数据,
|
||||
变更走显式 refresh(`runtime/refresh.ts`)。
|
||||
- **远程节点 eligibility**(`runtime/remote.ts`):门控检查可以基于远程执行环境的平台/二进制集合,
|
||||
而不是 Gateway 宿主机本身。
|
||||
|
||||
## 3. 安装生命周期:ClawHub 与多源安装
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant CLI as openclaw skills CLI
|
||||
participant POL as security.installPolicy<br/>(可选本地策略命令)
|
||||
participant HUB as ClawHub 注册表
|
||||
participant FS as 技能目录
|
||||
|
||||
U->>CLI: skills install <slug> [--global] [--as name]
|
||||
alt ClawHub 来源
|
||||
CLI->>HUB: 解析 slug,下载归档
|
||||
HUB-->>CLI: 包 + 安全扫描状态<br/>(VirusTotal / ClawScan / 静态分析)
|
||||
else Git / 本地 / 上传
|
||||
CLI->>CLI: git:owner/repo@ref 克隆 /<br/>本地目录 / zip 分块上传<br/>(上传需显式 allowUploadedArchives)
|
||||
end
|
||||
CLI->>POL: 元数据 + 暂存路径
|
||||
Note over POL: fail-closed:策略命令<br/>无法给出有效决定即拒绝
|
||||
POL-->>CLI: allow / deny
|
||||
CLI->>FS: 写入 workspace/skills<br/>(--global → ~/.openclaw/skills)
|
||||
CLI->>FS: 记录 .clawhub/origin.json<br/>(版本 + 注册表来源)
|
||||
|
||||
U->>CLI: skills update --all
|
||||
CLI->>HUB: 按 origin.json 对比版本(仅 ClawHub 安装可追踪)
|
||||
U->>CLI: skills verify <slug>
|
||||
CLI->>HUB: 请求 clawhub.skill.verify.v1 信任信封
|
||||
HUB-->>U: 校验结果(失败则非零退出)
|
||||
```
|
||||
|
||||
安全模型(skill 被明确视为**不可信代码**):
|
||||
|
||||
- **信任信封**:`openclaw skills verify` 对照 `.clawhub/origin.json` 记录的版本与注册表做校验;
|
||||
ClawHub 页面在安装前即暴露最新扫描状态。
|
||||
- **操作员安装策略**:`security.installPolicy` 配一个本地策略命令,
|
||||
覆盖 ClawHub/上传/Git/本地/更新/依赖安装全部路径,fail-closed。
|
||||
- **路径收敛**:workspace/项目/extraDirs 的 skill 根必须 realpath 收敛在配置根内
|
||||
(防符号链接逃逸),例外需 `skills.load.allowSymlinkTargets` 显式信任。
|
||||
- **密钥注入范围**:`skills.entries.*.env` / `.apiKey` 只注入**宿主进程的当轮 agent 调用**,
|
||||
不进沙箱、不进 prompt。
|
||||
|
||||
## 4. Skill Workshop:agent 自我演化的审批闸门
|
||||
|
||||
agent 在工作中发现可复用的流程时,**不直接写 SKILL.md**,而是产出提案进队列,人工审批后才落盘:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Agent 会话] -->|research/autocapture<br/>捕捉可复用信号| P[提案草稿]
|
||||
P --> Q[(workshop/store<br/>提案队列)]
|
||||
Q -->|workshop list / inspect| H{用户审批}
|
||||
H -->|apply| W[写入活动技能文件<br/>workspace-skill-write]
|
||||
H -->|拒绝/忽略| X[丢弃]
|
||||
W -.->|符号链接目标写入需<br/>allowSymlinkTargetWrites| W
|
||||
```
|
||||
|
||||
这是整个系统"agent 可以建议、人类拥有最终所有权"原则的具体化:
|
||||
`workshop/policy.ts` 定义什么可以被提案,`service.ts` 管理生命周期,
|
||||
CLI 入口为 `openclaw skills workshop list / inspect <id> / apply <id>`。
|
||||
|
||||
## 5. 与插件系统的关系
|
||||
|
||||
- 插件通过 `openclaw.plugin.json` 的 `skills` 字段携带技能目录,随插件启用而加载,
|
||||
合并在最低优先级层(与 `extraDirs` 同级)—— 任何同名的内置/托管/agent/workspace 技能都能覆盖它。
|
||||
- 插件技能可用 `metadata.openclaw.requires.config` 绑定到插件自己的配置项做门控。
|
||||
- 核心通过 `plugin-sdk/skills-runtime` barrel 向插件暴露技能运行时能力,
|
||||
符合"插件只走 SDK 门面"的总边界。
|
||||
|
||||
## 一句话总结
|
||||
|
||||
Skill 系统 = **"markdown 即能力 + 多源覆盖加载 + 声明式门控 + 快照固化 + 不可信供应链治理 + 人审进化"**:
|
||||
能力以纯文本契约描述,从六层来源按优先级合并,按环境声明过滤,
|
||||
会话内固化为快照保证确定性;安装链路全程有信任校验与策略闸门,
|
||||
而 agent 对技能库的修改永远经过 Workshop 人工审批。
|
||||
|
||||
完整官方文档:<https://docs.openclaw.ai/tools/skills>
|
||||
Reference in New Issue
Block a user