OpenClaw工具拆解之tts+web_search

一、tts 工具

1.1 工具概述

功能 :文本转语音(Text-to-Speech)
核心特性

  • 支持多种语音提供商
  • 自动交付音频文件
  • 支持渠道特定格式
  • 静默回复支持(避免重复消息)

1.2 Schema 定义

位置:第 113095 行

javascript 复制代码
const TtsToolSchema = Type.Object({
    text: Type.String({ description: "Text to convert to speech." }),
    channel: Type.Optional(Type.String({ description: "Optional channel id to pick output format (e.g. telegram)." }))
});

1.3 完整执行代码

位置:第 113099 行

javascript 复制代码
function createTtsTool(opts) {
    return {
        label: "TTS",
        name: "tts",
        displaySummary: "Convert text to speech and return audio.",
        description: `Convert text to speech. Audio is delivered automatically from the tool result --- reply with ${SILENT_REPLY_TOKEN} after a successful call to avoid duplicate messages.`,
        parameters: TtsToolSchema,
        execute: async (_toolCallId, args) => {
            const params = args;
            
            // 1. 解析文本(必填)
            const text = readStringParam$1(params, "text", { required: true });
            
            // 2. 解析渠道(可选)
            const channel = readStringParam$1(params, "channel");
            
            // 3. 执行文本转语音
            const result = await textToSpeech({
                text,
                cfg: opts?.config ?? loadConfig(),
                channel: channel ?? opts?.agentChannel
            });
            
            // 4. 返回结果
            if (result.success && result.audioPath) {
                return {
                    content: [{
                        type: "text",
                        text: "Generated audio reply."
                    }],
                    details: {
                        audioPath: result.audioPath,
                        provider: result.provider,
                        media: {
                            mediaUrl: result.audioPath,
                            ...result.voiceCompatible ? { audioAsVoice: true } : {}
                        }
                    }
                };
            }
            
            // 5. 失败结果
            return {
                content: [{
                    type: "text",
                    text: result.error ?? "TTS conversion failed"
                }],
                details: { error: result.error }
            };
        }
    };
}

1.4 执行流程图

复制代码
tts 工具调用
    ↓
1. 解析文本(必填)
    ↓
2. 解析渠道(可选)
    ↓
3. 调用 textToSpeech 函数
    ├─ 加载配置
    ├─ 选择提供商
    ├─ 调用 API
    └─ 保存音频文件
    ↓
4. 返回结果
    ├─ 成功 → 返回音频路径
    └─ 失败 → 返回错误信息
    ↓
5. 自动交付音频

1.5 返回结果格式

成功

json 复制代码
{
  "content": [{
    "type": "text",
    "text": "Generated audio reply."
  }],
  "details": {
    "audioPath": "/tmp/tts-abc123.mp3",
    "provider": "elevenlabs",
    "media": {
      "mediaUrl": "/tmp/tts-abc123.mp3",
      "audioAsVoice": true
    }
  }
}

失败

json 复制代码
{
  "content": [{
    "type": "text",
    "text": "TTS conversion failed"
  }],
  "details": {
    "error": "API key not configured"
  }
}

1.6 静默回复

javascript 复制代码
// 成功调用 TTS 后,使用静默回复避免重复消息
// SILENT_REPLY_TOKEN = "NO_REPLY"

// 大模型应该回复:
NO_REPLY

// 这样渠道不会发送重复消息,因为音频已经自动交付

1.7 使用示例

用户用语音回复"你好,我是阿财"

大模型返回

json 复制代码
{
  "tool_call": {
    "name": "tts",
    "arguments": { 
      "text": "你好,我是阿财"
    }
  }
}

执行结果

json 复制代码
{
  "content": [{
    "type": "text",
    "text": "Generated audio reply."
  }],
  "details": {
    "audioPath": "/tmp/tts-abc123.mp3",
    "provider": "elevenlabs",
    "media": {
      "mediaUrl": "/tmp/tts-abc123.mp3",
      "audioAsVoice": true
    }
  }
}

大模型回复

复制代码
NO_REPLY

2.1 工具概述

功能 :网络搜索
核心特性

  • 支持多种搜索提供商(DuckDuckGo/Tavily 等)
  • 支持运行时提供商配置
  • 支持沙盒模式
  • 返回搜索结果(标题/URL/摘要)

2.2 Schema 定义

web_search 的 Schema 是动态解析的,取决于配置的提供商。

2.3 完整执行代码

位置:第 113760 行

javascript 复制代码
function createWebSearchTool(options) {
    // 1. 解析运行时提供商
    const runtimeProviderId = options?.runtimeWebSearch?.selectedProvider ?? 
                              options?.runtimeWebSearch?.providerConfigured;
    
    // 2. 解析搜索定义
    const resolved = resolveWebSearchDefinition({
        ...options,
        preferRuntimeProviders: Boolean(runtimeProviderId) && 
                               !resolveBundledWebSearchPluginId$1(runtimeProviderId)
    });
    
    // 3. 如果没有解析到提供商,返回 null(工具不可用)
    if (!resolved) return null;
    
    // 4. 返回工具定义
    return {
        label: "Web Search",
        name: "web_search",
        description: resolved.definition.description,
        parameters: resolved.definition.parameters,
        execute: async (_toolCallId, args) => 
            jsonResult(await resolved.definition.execute(args))
    };
}

2.4 提供商解析流程

javascript 复制代码
// 1. 检查运行时配置
const runtimeProviderId = options?.runtimeWebSearch?.selectedProvider ?? 
                          options?.runtimeWebSearch?.providerConfigured;

// 2. 解析搜索定义
const resolved = resolveWebSearchDefinition({
    ...options,
    preferRuntimeProviders: Boolean(runtimeProviderId) && 
                           !resolveBundledWebSearchPluginId$1(runtimeProviderId)
});

// 3. resolveWebSearchDefinition 函数会:
//    - 检查配置的提供商
//    - 加载提供商定义(description/parameters/execute)
//    - 验证 API 密钥
//    - 返回完整的工具定义

2.5 支持的提供商

提供商 说明 API Key
DuckDuckGo 无需 API key 不需要
Tavily AI 优化搜索 需要
Firecrawl 网页抓取 + 搜索 需要
Brave Brave Search API 需要
Google Custom Search API 需要

2.6 执行流程图

复制代码
web_search 工具调用
    ↓
1. 解析运行时提供商
    ↓
2. 解析搜索定义
    ├─ 检查配置的提供商
    ├─ 加载提供商定义
    ├─ 验证 API 密钥
    └─ 返回工具定义
    ↓
3. 执行搜索
    ├─ 调用提供商 API
    ├─ 解析结果
    └─ 返回搜索结果
    ↓
4. 返回结果

2.7 返回结果格式

DuckDuckGo 成功

json 复制代码
{
  "results": [
    {
      "title": "网页标题",
      "url": "https://example.com",
      "snippet": "摘要内容..."
    },
    ...
  ]
}

Tavily 成功

json 复制代码
{
  "results": [
    {
      "title": "网页标题",
      "url": "https://example.com",
      "content": "详细内容...",
      "score": 0.95
    },
    ...
  ],
  "query": "搜索关键词",
  "total": 10
}

失败

json 复制代码
{
  "error": "API key not configured for provider: tavily"
}

2.8 使用示例

用户搜索 OpenClaw 文档

大模型返回

json 复制代码
{
  "tool_call": {
    "name": "web_search",
    "arguments": { 
      "query": "OpenClaw documentation"
    }
  }
}

执行结果

json 复制代码
{
  "results": [
    {
      "title": "OpenClaw Documentation",
      "url": "https://docs.openclaw.ai",
      "snippet": "Official documentation for OpenClaw..."
    },
    {
      "title": "OpenClaw GitHub",
      "url": "https://github.com/openclaw/openclaw",
      "snippet": "OpenClaw source code and examples..."
    }
  ]
}

三、关键机制对比

3.1 功能定位

特性 tts web_search
用途 文本转语音 网络搜索
输出 音频文件 搜索结果
提供商 ElevenLabs 等 DuckDuckGo/Tavily 等

3.2 配置要求

特性 tts web_search
API Key 需要 取决于提供商
渠道配置 可选 不需要
运行时配置 不支持 支持

3.3 返回结果

特性 tts web_search
媒体交付 自动 不支持
静默回复 推荐 不需要
结果数量 1 个音频 N 个搜索结果

四、相关工具

4.1 web_fetch

位置:第 113588 行

javascript 复制代码
function createWebFetchTool(options) {
    // 抓取网页内容
    // 支持 Firecrawl 集成
    // 返回 Markdown 或纯文本
}

4.2 工具组合使用

javascript 复制代码
// 1. 搜索信息
const searchResults = await web_search({ query: "..." });

// 2. 抓取网页内容
const content = await web_fetch({ url: searchResults.results[0].url });

// 3. 转换为语音
await tts({ text: content });

五、配置示例

5.1 TTS 配置

yaml 复制代码
# openclaw.yaml
tts:
  provider: elevenlabs
  apiKey: "${ELEVENLABS_API_KEY}"
  voice: "Rachel"
  model: "eleven_monolingual_v1"
yaml 复制代码
# openclaw.yaml
tools:
  web:
    search:
      provider: duckduckgo  # 或 tavily/brave/google
      # tavily:
      #   apiKey: "${TAVILY_API_KEY}"
      # brave:
      #   apiKey: "${BRAVE_API_KEY}"
相关推荐
阿杰学AI1 小时前
AI核心知识137—大语言模型之 CLI与MCP(简洁且通俗易懂版)
人工智能·ai·语言模型·自然语言处理·cli·mcp·模型上下文协议
qq_342295821 小时前
如何让 Bootstrap 图标在 Vue 3 中持续旋转动画
jvm·数据库·python
Sirius.z1 小时前
第J2周:ResNet-50V2算法实战与解析
python
knight_9___2 小时前
RAG面试篇6
人工智能·python·机器学习·agent·rag
阿杰学AI2 小时前
AI核心知识138—大语言模型之 数据墙危机(简洁且通俗易懂版)
人工智能·机器学习·ai·语言模型·合成数据·数据墙危机·data wall
weixin_568996062 小时前
如何用 IndexedDB 存储从 API 获取的超大列表并实现二级索引
jvm·数据库·python
2301_775148152 小时前
如何授权AWR报告生成_GRANT SELECT ANY DICTIONARY诊断权限
jvm·数据库·python
whinc2 小时前
Node.js技术周刊 2026年第17周
前端·javascript
nbsaas-boot2 小时前
100万门店级分货系统架构设计
前端·javascript·vue.js