📅 更新于 2026-05-29 | OpenClawTool DiscoveryMCP

🔍 Agent Tool Discovery 详解

世界上有一种Agent,它手里握着100个工具,却不知道哪个能拧螺丝。就像凌晨4点17分,你站在工具箱前,突然发现——你根本不知道哪个是螺丝刀。

—— 妙趣AI · 工具发现哲学

📖 什么是 Agent Tool Discovery?

Agent Tool Discovery(工具发现)是指AI Agent在运行时自动发现、识别和理解可用工具(Tools/Skills)的能力。包括:工具列表获取、功能理解、适用场景匹配、参数格式解析。

在OpenClaw中,Tool Discovery主要通过SKILL.md扫描实现:Agent启动时扫描skills/目录,读取每个技能的元数据,构建可用工具索引。

🧠 核心原理

1. 工具注册(Tool Registration)

工具需要以标准格式注册,OpenClaw使用SKILL.md:

---
name: web-search
description: 搜索网页内容,当用户需要查找最新信息、新闻、技术文档时使用。
---

# 使用方式
当用户说"搜索XX"时,调用本工具...
# 参数
- query: 搜索关键词
- maxResults: 最多返回结果数

2. 语义匹配(Semantic Matching)

Agent根据用户意图,匹配最合适的工具:

用户意图匹配工具匹配依据
"搜索最新AI新闻"web-searchdescription包含"搜索"、"最新信息"
"生成术语页面"content-generatordescription包含"生成"、"术语"
"发送到Discord"discorddescription包含"Discord"、"发送"

3. 动态加载(Dynamic Loading)

OpenClaw的优势:工具可以热加载,无需重启Agent:

🛠️ OpenClaw 实战应用

场景一:妙趣AI技能发现流程

妙趣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工具发现

通过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. 按顺序执行,前一个工具的输出作为后一个的输入

💻 代码示例

示例1:SKILL.md驱动的Tool Discovery

// 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;
  }
}

示例2:MCP工具发现协议

// 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
    }));
  }
}

示例3:工具匹配评分

// 工具匹配评分算法
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配了个"工具百科全书",需要什么拿什么,不用满世界瞎找。记住:工具不在多,能找到才行!

🔗 相关链接

🔗 相关推荐

🔧 工具教程
OpenClaw MCP 工具集成教程 - AI Agent 模型上下文协议
🔧 工具教程
OpenClaw MCP 工具编排实战 - 让 AI Agent 调用外部工具
🔧 工具教程
OpenClaw 工具编排模式 | Agent Tool Orchestration 实战

📚 相关术语

📄 文章
OpenClaw Skill
📖 术语
MCP Server
📄 文章
OpenClaw
📄 文章
openclaw
📄 文章
AI Agent
📖 术语
Agent