概述
OpenClaw 的扩展(Extension)系统允许开发者为 AI 代理添加自定义能力。扩展可以注册新工具、注入系统提示词片段、处理特定事件,甚至修改工具流水线的行为。本文将带你从零开始,了解如何开发、测试和部署一个 OpenClaw 扩展。
扩展加载方式
OpenClaw 支持两种扩展加载方式:
编程式加载
通过代码直接注册扩展,适合与 OpenClaw 深度集成的场景:
const { OpenClaw } = require('openclaw');
const app = new OpenClaw();
app.registerExtension({
name: 'my-extension',
version: '1.0.0',
description: '我的自定义扩展',
setup: async (context) => {
// 扩展初始化逻辑
}
});
磁盘路径加载
将扩展放置在指定目录下,OpenClaw 启动时自动发现和加载:
extensions:
path: /data/openclaw/extensions
autoLoad: true
allowedExtensions:
- my-extension
- another-extension
扩展目录结构:
/data/openclaw/extensions/
my-extension/
index.js
package.json
manifest.yaml
扩展结构
manifest.yaml
每个扩展必须包含一个清单文件,声明扩展的元信息和能力:
name: my-extension
version: 1.0.0
description: 这是一个示例扩展
author: 开发者名称
minOpenClawVersion: 2.0.0
capabilities:
tools: true
prompts: true
events: true
permissions:
network: false
filesystem:
read: ["/data/openclaw/workspace"]
write: ["/tmp/openclaw/my-extension"]
config:
apiEndpoint:
type: string
required: true
description: API 端点地址
maxRetries:
type: number
default: 3
description: 最大重试次数
入口文件
扩展的入口文件导出一个 setup 函数,该函数接收扩展上下文对象:
module.exports = {
setup: async (ctx) => {
// 注册工具
ctx.registerTool({
name: 'my_custom_tool',
description: '自定义工具的功能描述',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: '查询内容' }
},
required: ['query']
},
execute: async (params, toolCtx) => {
const result = await doSomething(params.query);
return { content: result };
}
});
// 注入提示词
ctx.registerPrompt({
position: 'tools',
content: '当用户需要某某功能时,请使用 my_custom_tool 工具。'
});
// 监听事件
ctx.on('session:start', async (session) => {
console.log(`新会话开始: ${session.id}`);
});
}
};
工具注册详解
工具定义
注册工具时需要提供符合 JSON Schema 规范的参数定义。这些定义会在七阶段工具流水线的 Schema 验证阶段被检查,不合格的定义会被拒绝。
执行函数
工具的执行函数接收两个参数:
- params:用户传入的工具参数,已经过 Schema 验证
- toolCtx:工具上下文,包含以下内容:
session:当前会话对象channel:当前频道信息user:当前用户信息abortSignal:中止信号(来自流水线第七阶段)config:扩展配置
返回格式
工具执行函数应返回一个对象,常见格式:
// 文本结果
return { content: '操作成功完成' };
// 结构化数据
return { content: JSON.stringify(data), metadata: { type: 'json' } };
// 错误结果
return { error: '操作失败:具体原因' };
// 带有附件的结果
return {
content: '图片已生成',
attachments: [{ path: '/tmp/output.png', type: 'image/png' }]
};
提示词注入
扩展可以在系统提示词的不同位置注入内容:
ctx.registerPrompt({
position: 'system', // 系统级提示词
content: '你具备某某能力...',
priority: 10 // 优先级,数字越大越靠前
});
ctx.registerPrompt({
position: 'tools', // 工具使用指导
content: '使用 xxx 工具时应注意...'
});
这些提示词片段会被 buildAgentSystemPrompt() 收集并整合到最终的系统提示词中。
事件系统
OpenClaw 的事件系统让扩展能够响应各种系统事件:
session:start— 新会话开始session:end— 会话结束message:receive— 收到新消息message:send— 发送消息tool:before— 工具执行前tool:after— 工具执行后tool:error— 工具执行出错
ctx.on('tool:before', async (event) => {
console.log(`即将执行工具: ${event.toolName}`);
// 可以修改参数或取消执行
});
扩展间通信
多个扩展之间可以通过共享上下文进行通信:
// 扩展 A 发布数据
ctx.shared.set('weather:current', weatherData);
// 扩展 B 读取数据
const weather = ctx.shared.get('weather:current');
测试
单元测试
OpenClaw 提供了测试工具包,用于在隔离环境中测试扩展:
const { createTestContext } = require('openclaw/testing');
describe('my-extension', () => {
it('should execute tool correctly', async () => {
const ctx = createTestContext();
await extension.setup(ctx);
const result = await ctx.executeTool('my_custom_tool', {
query: 'test'
});
expect(result.content).toBeDefined();
});
});
集成测试
使用 OpenClaw 的开发模式启动服务,实际加载扩展并通过对话测试其功能。
会话持久化
扩展产生的数据可以利用 OpenClaw 的会话持久化机制(JSONL 格式)进行存储。当会话数据执行压缩(compaction)时,扩展可以通过 session:compact 事件参与压缩过程,决定哪些数据需要保留。
发布与分享
完成开发的扩展可以打包发布到 OpenClaw 技能市场(Skill Marketplace),供其他用户安装使用。发布前需要通过基本的安全审查和功能验证。
最佳实践
- 最小权限:只声明扩展实际需要的权限
- 优雅处理错误:所有异步操作都应有错误处理
- 响应中止信号:长时间运行的操作应定期检查
abortSignal - 文档齐全:为工具编写清晰的描述和参数说明
- 版本兼容:在 manifest 中声明最低 OpenClaw 版本要求
总结
OpenClaw 的扩展系统提供了强大而灵活的定制能力。无论是添加新工具、修改行为还是集成外部服务,扩展都能以模块化的方式实现。掌握扩展开发,就掌握了让 OpenClaw 适应任何场景的钥匙。