世界上有一种Agent,它手里握着100个工具,却不知道哪个能拧螺丝。就像凌晨4点17分,你站在工具箱前,突然发现——你根本不知道哪个是螺丝刀。
—— 妙趣AI · 工具发现哲学
Agent Tool Discovery(工具发现)是指AI Agent在运行时自动发现、识别和理解可用工具(Tools/Skills)的能力。包括:工具列表获取、功能理解、适用场景匹配、参数格式解析。
在OpenClaw中,Tool Discovery主要通过SKILL.md扫描实现:Agent启动时扫描skills/目录,读取每个技能的元数据,构建可用工具索引。
工具需要以标准格式注册,OpenClaw使用SKILL.md:
--- name: web-search description: 搜索网页内容,当用户需要查找最新信息、新闻、技术文档时使用。 --- # 使用方式 当用户说"搜索XX"时,调用本工具... # 参数 - query: 搜索关键词 - maxResults: 最多返回结果数
Agent根据用户意图,匹配最合适的工具:
| 用户意图 | 匹配工具 | 匹配依据 |
|---|---|---|
| "搜索最新AI新闻" | web-search | description包含"搜索"、"最新信息" |
| "生成术语页面" | content-generator | description包含"生成"、"术语" |
| "发送到Discord" | discord | description包含"Discord"、"发送" |
OpenClaw的优势:工具可以热加载,无需重启Agent:
妙趣AI启动时的Tool Discovery:
# 1. 扫描技能目录
skills_dir = ~/.openclaw/agents/miaoquai/skills/
skills = scan_directory(skills_dir)
# 2. 读取每个技能的SKILL.md
for skill in skills:
metadata = parse_skill_md(skill.path + "/SKILL.md")
# 提取: name, description, location
# 3. 构建工具索引
tool_index = {
"web-search": { desc: "...", location: "..." },
"discord": { desc: "...", location: "..." },
...
}
# 4. 用户请求到达时,匹配工具
matched = match_tool(user_request, tool_index)
通过MCP(Model Context Protocol)接入外部工具时的发现:
# MCP Server 提供工具列表
# Agent通过MCP协议查询可用工具
mcp_tools = await mcp_client.list_tools()
# 返回格式
[
{
"name": "github_create_issue",
"description": "Create a GitHub issue",
"inputSchema": { ... }
},
{
"name": "feishu_send_message",
"description": "Send message to Feishu chat",
"inputSchema": { ... }
}
]
# Agent将这些工具加入自己的工具索引
当多个工具都匹配时,Agent需要决策:
# 用户:"帮我搜索并生成报告" # 匹配到:web-search, content-generator, report-writer # 决策逻辑: 1. 分析任务复杂度 → 需要多个工具 2. 构建工具链 → [web-search, content-generator, report-writer] 3. 按顺序执行,前一个工具的输出作为后一个的输入
// OpenClaw 工具发现实现(简化版)
class SkillDiscovery {
constructor(skillsDir) {
this.skillsDir = skillsDir;
this.tools = new Map();
}
async discover() {
const skillDirs = await fs.readdir(this.skillsDir);
for (const dir of skillDirs) {
const skillPath = path.join(this.skillsDir, dir);
const skillMdPath = path.join(skillPath, 'SKILL.md');
if (await fileExists(skillMdPath)) {
const content = await fs.readFile(skillMdPath, 'utf8');
const metadata = this.parseSkillMD(content);
this.tools.set(metadata.name, {
name: metadata.name,
description: metadata.description,
location: skillPath,
content: content
});
}
}
return this.tools;
}
parseSkillMD(content) {
// 解析 YAML front matter
const match = content.match(/^---\n([\s\S]*?)\n---/);
if (match) {
return yaml.parse(match[1]);
}
return { name: 'unknown', description: '' };
}
findTool(userQuery) {
// 简化匹配:检查description是否包含查询关键词
const matches = [];
for (const [name, tool] of this.tools) {
if (tool.description.includes(userQuery) ||
this.semanticMatch(userQuery, tool.description)) {
matches.push(tool);
}
}
return matches;
}
semanticMatch(query, description) {
// 实际应使用embedding相似度
return false;
}
}
// MCP Client 工具发现
class MCPToolDiscovery {
constructor(serverUrl) {
this.serverUrl = serverUrl;
}
async discoverTools() {
// MCP协议:发送 tools/list 请求
const response = await fetch(`${this.serverUrl}/tools/list`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ method: 'tools/list' })
});
const { tools } = await response.json();
// 转换为OpenClaw格式
return tools.map(tool => ({
name: tool.name,
description: tool.description,
parameters: tool.inputSchema,
source: 'mcp',
server: this.serverUrl
}));
}
}
// 工具匹配评分算法
function scoreToolMatch(userQuery, tool) {
let score = 0;
// 1. description精确匹配
if (tool.description.includes(userQuery)) {
score += 10;
}
// 2. 关键词重叠
const queryWords = userQuery.split(' ');
const descWords = tool.description.split(' ');
const overlap = queryWords.filter(w => descWords.includes(w));
score += overlap.length * 2;
// 3. 工具使用历史(如果之前用过这个工具,加分)
if (tool.lastUsed && Date.now() - tool.lastUsed < 3600000) {
score += 5; // 1小时内用过
}
return score;
}
// 选择得分最高的工具
function selectBestTool(userQuery, tools) {
const scored = tools.map(t => ({
tool: t,
score: scoreToolMatch(userQuery, t)
}));
scored.sort((a, b) => b.score - a.score);
return scored[0]?.tool;
}
✅ DO(推荐做法)
⚠️ DON'T(常见坑)
| 机制 | 优点 | 缺点 | OpenClaw方式 |
|---|---|---|---|
| 静态注册 | 简单、确定 | 不灵活、需重启 | ❌ 不用 |
| SKILL.md扫描 | 热加载、文件即配置 | 依赖文件系统 | ✅ 主要方式 |
| MCP协议 | 标准化、跨平台 | 需要MCP Server | ✅ 支持 |
| 语义搜索 | 智能匹配 | 需要embedding模型 | 🔄 规划中 |
就像《唐伯虎点秋香》里的"含笑半步癫"——不是所有工具都叫螺丝刀,但每个工具都有自己的用处。好的Tool Discovery就像给Agent配了个"工具百科全书",需要什么拿什么,不用满世界瞎找。记住:工具不在多,能找到才行!