OpenClaw 这个项目,最近在 AI 自动化玩家圈子里出镜率很高。说白了,它就是让大模型直接接管你的电脑——模拟鼠标键盘、读写文件、执行命令,配合脚本帮你把重复操作串成自动化流程。不过,真拿它干实际活儿的时候,你会很快撞上一个固定的短板:模型的知识停留在训练那一刻,你让它查今天某股的价格、某个开源项目的最新 Release 版本、或者最近一周技术圈发生了什么事,它要么一本正经地编一个答案,要么老实告诉你"我的知识截止到某年某月"。这种情况放在自动化任务里几乎绕不开,搜索能力缺了,很多工作流根本没法闭环。所以,给 OpenClaw 外挂一个实时搜索能力,基本是它从"能跑"变成"好用"的分水岭。这篇就完整记录我折腾"给 OpenClaw 配置 Tavily Search"的过程,从为什么选 Tavily、怎么申请 API Key,到写技能、调参数、排查问题,全部摊开讲。
1. OpenClaw 为什么需要外挂搜索能力
1.1 大模型的静态知识瓶颈
先别急着写代码,想清楚"为什么需要搜索"才是关键。大模型的训练方式决定了它的知识是一份"快照",训练截止之后发生的事它完全不知道。这本身不算缺陷,但放在自动化任务里就变成硬伤:你给它一个"整理今天科技圈三条大新闻"的任务,它大概率会从训练数据里翻出几个月前甚至几年前的旧闻,然后当作今天的新闻输出。
更麻烦的是幻觉问题。模型在不知道答案的时候,不会总是说"不知道",很多时候它会基于上下文编造一个看起来合理的内容。我最初用 OpenClaw 跑一个市场周报的自动化任务,让它总结上周某类产品的行情变化,它写得有模有样,数据、趋势、结论全都有,但我对比真实记录一看,几乎每一条都是错的。这个经历让我意识到:在信息密集型场景里,不接搜索的 AI 助手,本质上是个"自信的瞎猜机器"。
1.2 OpenClaw 实际干活时的搜索需求场景
OpenClaw 这类工具的定位是"帮你操作电脑",它本身不产生知识,只是个执行者。真正跑起来之后,它需要外部信息的场景非常密集,我粗列一下就有这么几类:
- 信息汇总类任务:比如"查一下最近热门大模型榜单并整理成表格",这类任务时效性极强,没有搜索就只能编。
- 技术调研类任务:让 OpenClaw 帮你查某个库的最新版本、接口变更、社区讨论,它的知识库永远追不上仓库的更新速度。
- 价格与资讯监控:比如每天定时抓取某类商品价格或行业新闻,纯靠模型知识根本做不到。
- 工作流里的判断节点:自动化流程中经常有"根据最新数据决定下一步走哪个分支",这时候搜索结果就是决策输入。
这些场景有一个共同点:都需要实时的外部数据。OpenClaw 本身没有内置的联网搜索能力,所以要靠外部服务来补。这就是 Tavily Search 进入视野的原因。
1.3 为什么我在一堆搜索服务里选了 Tavily
市面上搜了一圈之后,我其实把可选方案都过了一遍:直接用爬虫抓取太脆弱,目标网站改个结构就废了;传统搜索 API 返回的是网页链接和摘要,要再加工一遍才能喂给模型;通用搜索框架往往需要自己处理 JS 渲染、反爬、页面清洗,维护成本堪比一个小项目。Tavily 从一开始就是按"给大模型用"这个思路设计的,这是我选它的核心原因。
给它做个横向对比就清楚了:
| 方案 | 返回内容 | 对 LLM 友好度 | 上手成本 | 时效性 |
|---|---|---|---|---|
| Tavily | 结构化 JSON,带摘要、答案、关键内容 | 很高,直接能读 | 极低,一个 API Key 即可 | 好 |
| 通用搜索 API | 搜索结果列表(标题、链接、片段) | 一般,需要二次清洗和拼接 | 中等,配额和参数复杂 | 好 |
| 自建爬虫 | 原始 HTML | 很差,要写大量解析代码 | 很高,还要维护反爬逻辑 | 取决于实现 |
| 普通搜索接口 | 以链接和排名为主 | 一般,很难直接引用 | 中等,注册步骤繁琐 | 好 |
Tavily 这边有几个很实用的点:它能直接返回一个"answer"字段,相当于官方帮你把搜索结果先总结了一遍,模型拿过来稍微整合就能用;支持"新闻"这个专门的搜索主题,做资讯类任务很顺手;还有一个"advanced"深度模式,可以翻更深的页面。加上它对每次请求的配额设计得比较宽松,个人开发者免费额度足够日常折腾。综合下来,它就是目前给 OpenClaw 这类工具接搜索的省心方案。
2. 配置前的准备:理解技能机制与密钥申请
2.1 OpenClaw 的技能加载机制
在动手之前,先花两分钟搞懂 OpenClaw 是怎么"学会一个新能力"的,这能省掉后面很多弯路。OpenClaw 的能力扩展走的是技能(Skill)体系:在它的配置目录下,每个技能是一个独立文件夹,里面放一个SKILL.md描述文件和一个script.js(有的版本支持其他脚本语言)逻辑文件。SKILL.md里的 frontmatter 会给这个技能起名、写描述,OpenClaw 启动时会扫描这些目录,把技能清单连同描述一起暴露给大模型。当用户在对话里下达相关指令时,模型会根据描述判断该调用哪个技能,然后执行对应的script.js。
这个机制很像给工具箱里加了一把新工具,关键是要确保"工具描述"足够清楚,模型才知道什么时候用这把工具。另外,密钥之类的敏感信息不要写死在脚本里,OpenClaw 支持通过环境变量读取,这也是官方推荐的做法。
2.2 申请 Tavily API Key 的完整流程
Tavily 的注册流程很简单,基本不需要科普,但我还是把步骤列出来,方便第一次接触的人:
- 打开 Tavily 的官方网站,用邮箱注册账号。
- 登录后进入控制台,API Keys 页面会显示一个默认生成的密钥,也可以自己新建一个。
- 复制密钥,它是一串以
tvly-开头的字符串。这个格式很有辨识度,后面排查问题的时候,看一眼就能知道是不是拿错了变量。
关于额度:免费档每个月会送一定量的搜索次数(具体数字以官网实时显示为准),个人自动化项目日常查询完全够用。如果你跑的是高频任务,再去考虑付费档。我的建议是先拿免费额度跑通整个链路,确认搜索确实是刚需,再决定要不要升级。
2.3 密钥管理里容易踩的坑
API Key 说到底是你的"钱包钥匙",Tavily 是按用量计费的,密钥要是泄露出去,被别人薅走额度,那就不只是麻烦的问题了。这里有几个必须养成的好习惯:
- 密钥只放在 OpenClaw 的环境变量文件里,绝不硬编码进技能脚本。
- 如果你用 git 管理配置,记得把
.env文件加进.gitignore,不然哪天提交到公开仓库,密钥就裸奔了。 - 一旦发现密钥有泄露风险,马上去控制台把这个 Key 删掉,重新生成一个。
注意:环境变量文件属于敏感配置文件。粘贴或复制密钥时,留意是否被同步到剪贴板历史记录或云同步工具里,这类细节不像代码报错那么显眼,但出了问题非常麻烦。
3. 核心实操:给 OpenClaw 配置 Tavily 搜索
3.1 确认运行环境与目录结构
我这里基于 2025 年主流的 OpenClaw 版本演示,不同小版本之间目录可能略有差异,但大的结构是稳定的。你先确认环境是否就绪:
# 检查 Bun 运行时(OpenClaw 依赖 Bun) bun --version # 检查 OpenClaw 命令是否可用 openclaw --versionOpenClaw 的配置文件默认放在用户级目录下,通常是~/.openclaw/。里面有一个.env文件负责存环境变量,还有一个skills/目录存放所有技能。如果这些目录还不存在,说明可能是第一次启动没跑完初始化,先正常启动一次 OpenClaw,让它自动生成目录结构再继续。
3.2 把 API Key 写进环境变量
打开(或新建)~/.openclaw/.env,加上这一行:
TAVILY_API_KEY=tvly-你的密钥然后重启 OpenClaw 的进程或服务,让环境变量生效。这个变量的名字不是随便起的——后面写的技能脚本里,就用process.env.TAVILY_API_KEY读取它,保持命名一致就能省掉很多麻烦。
如果你懒得重启,也可以在当前 shell 里临时导出,但那只对当前终端生效,OpenClaw 的后台进程未必能读到。所以最稳妥的做法还是改完.env后,把 OpenClaw 整个退掉再重新启动。
3.3 编写 Tavily 搜索技能文件
接下来是核心步骤:创建技能目录和文件。
mkdir -p ~/.openclaw/skills/tavily-search cd ~/.openclaw/skills/tavily-search先创建SKILL.md,这是技能的"说明书",写给模型看的:
--- name: tavily_search title: 网络实时搜索 description: 使用 Tavily Search API 搜索实时网络信息,适用于查询新闻、最新技术动态、产品价格、行业资讯等时效性内容。当用户需要了解最近发生的事件、最新的版本信息或实时数据时,应该优先使用这个技能。 --- # Tavily 网络搜索 调用 Tavily Search API 执行实时搜索,并返回结构化的搜索结果。这个文件里最关键的是 frontmatter 的name和description。name是模型调用技能时的方法名,description决定了模型在什么情况下会想起用这个技能。描述写得越具体,模型越容易在需要搜索的时候正确调用它。
然后创建script.js,这是实际执行搜索逻辑的脚本:
const TAVILY_API_KEY = process.env.TAVILY_API_KEY; async function tavilySearch(query, options = {}) { if (!TAVILY_API_KEY) { throw new Error("缺少 TAVILY_API_KEY 环境变量,请检查 ~/.openclaw/.env 配置"); } const response = await fetch("https://api.tavily.com/search", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${TAVILY_API_KEY}` }, body: JSON.stringify({ query: query, search_depth: options.search_depth || "basic", max_results: options.max_results || 5, topic: options.topic || "general", include_answer: options.include_answer !== false }) }); if (!response.ok) { const errText = await response.text(); throw new Error(`Tavily 请求失败: ${response.status} ${errText}`); } return await response.json(); } // OpenClaw 技能约定的默认入口 export default async function (params) { const { query } = params; if (!query) { throw new Error("搜索查询词不能为空"); } return await tavilySearch(query, params); }这个脚本的核心就一件事:把 OpenClaw 传过来的查询词包装成 Tavily 的 API 请求发出去,再把结构化的 JSON 结果原样返回给模型。fetch是 Bun 运行时内置的,不需要额外安装任何依赖。
关于search_depth、topic、max_results这三个参数,我先给了基础配置,后面专门有一节讲怎么调优。这里先记住它们是怎么透传到 API 的就行。
3.4 加载技能并进行自然语言验证
技能文件保存好之后,重启 OpenClaw 让它重新扫描技能目录。然后直接用人话测试:
请用 tavily_search 搜索一下:最近一周开源 AI Agent 框架有什么新动态如果一切正常,OpenClaw 会调用tavily_search技能,把查询词传进去,然后基于返回结果给你一个汇总回答。你可以在回复里看到它引用了哪些搜索结果,或者要求它直接列出相关链接。
在验证这一步,我还习惯做一件事:先用命令行直接调一下 Tavily API,确认 Key 和环境本身没问题,再回到 OpenClaw 里测试,这样出了问题能快速定位到底是在 API 层还是技能层。
curl -X POST "https://api.tavily.com/search" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer tvly-你的密钥" \ -d '{"query":"OpenClaw 最新版本","max_results":3,"include_answer":true}'curl 返回的 JSON 里如果能看到answer字段和results数组,就说明 API 链路是通的,接下来专心在 OpenClaw 侧做调试就行。
4. 搜索参数调优与实战效果验证
4.1 Tavily 核心参数到底是什么
很多人在配置搜索服务时,习惯性忽略参数调优,其实 Tavily 返回答复的质量,很大程度上取决于参数怎么组合。逐一说下这几个最常用的:
query:搜索查询词,不用解释。但有一点值得注意:给模型的提示词里最好让它把搜索查询写得更"像搜索框里会输入的内容",而不是自然语言长句。比如"世界人工智能大会是什么时候开"可能不如"世界人工智能大会 2025 时间地点"效果好。search_depth:分为basic和advanced两个档位。basic速度快、成本低,适合日常资讯和常规查询;advanced会深度遍历更多网页,返回内容更丰富,适合技术调研或稀缺信息查找,但耗时和配额消耗都会增加。topic:默认是general,还有一个news选项。做新闻类任务时强烈建议切到news,因为 Tavily 的新闻搜索会走专门的新闻源聚合,时效性和内容相关度都好很多。max_results:返回的最大结果数。默认 5 就够大多数场景用,不是越多越好,结果太多模型反而容易被无关内容干扰。include_answer:是否让 Tavily 用大模型生成一个摘要答案。这个默认开就好,返回的answer字段可以直接作为模型回答的骨架,省一次推理。days:一个不太起眼但很好用的参数,限定只搜索最近 N 天的内容,做时效性任务很实用。
4.2 不同任务场景的参数推荐
我把常见的使用场景和推荐参数组合整理成了表格,照着抄就行:
| 任务场景 | search_depth | topic | max_results | include_answer | 备注 |
|---|---|---|---|---|---|
| 日常问答、常识核实 | basic | general | 5 | true | 默认配置基本够用 |
| 技术调研、查文档 | advanced | general | 10 | false | 内容更细,答案自己总结更好 |
| 新闻资讯追踪 | basic | news | 8 | true | 配合 days 限定时间窗口 |
| 竞品/价格监控 | advanced | general | 10 | true | 建议加具体产品词限制范围 |
| 学术资料查找 | advanced | general | 15 | false | 结果多,让模型自行筛选 |
这组参数不是死规则,核心思路是:任务越偏"广泛信息"用 basic + 少结果,越偏"深度资料"用 advanced + 多结果。你可以在技能脚本里把这些参数做成可选项,让 OpenClaw 根据查询意图动态传入,比写死更灵活。
4.3 让搜索和 OpenClaw 的指令习惯衔接起来
参数调好了,还有一个影响体验的细节:怎么提示 OpenClaw,让它把搜索用得自然。
我的经验是,在给模型的任务指令里,尽量明确"搜索"这一步。比如你让它做一份行业日报,可以这样描述:"先搜索最近 24 小时内的相关新闻,再结合搜索结果生成日报摘要。" 这比单纯说"帮我做一份日报"可靠得多,因为模型能直接从指令里识别出搜索的必要条件和时间范围。
另外一个小技巧:OpenClaw 能操作电脑,所以搜索完的网络链接,完全可以让它再打开浏览器逐条核对一遍。搜索给的是线索,浏览器验证给的是"眼见为实",这两步配合起来,自动化任务的可靠性会提升一大截。实测下来,这种"搜索 + 浏览器二次确认"的组合用法,比单靠搜索自动汇总要靠谱得多。
5. 常见问题排查与经验杂谈
5.1 API Key 相关的报错
配置过程中最多的报错就是鉴权问题,典型的提示是 HTTP 401。遇到这个别慌,按顺序排查:
- 确认
.env里写的 Key 是不是完整的,开头是不是tvly-。复制的时候容易少复制末尾字符。 - 确认 OpenClaw 重启过了,旧进程很可能还占着没有新环境变量的那块内存。
- 去 Tavily 控制台看一眼这个 Key 是不是被删了或者被禁用了,有时候你可能一顺手在后台重建了一个 Key,旧的自然就失效了。
我在查这类问题时的土办法是,在script.js里临时把环境变量读取值打印到日志里,确认进程实际拿到的是什么。注意测试完要删掉这行调试代码,免得密钥出现在日志里。
5.2 限流、超时与配额耗尽
用了一段时间之后,最常见的错误变成了 HTTP 429(请求过于频繁)和超时。429 基本就是额度快用完了或者短时间请求太多,可以去控制台看用量,也可以检查是不是有自动化任务在循环里高频调用搜索。
超时问题要分两种看:一种是网络环境本身不稳定,这属于底层基础设施的问题,建议在技能脚本里给搜索请求设置一个合理的超时时间,默认的fetch可能等待过久;另一种是search_depth设成了 advanced,深度模式本身就慢,如果任务对时效性要求高,可以退回 basic。还有一种容易被忽略的情况:搜索词设计得太宽泛,Tavily 内部为了给你凑结果多爬了很多页面,自然就慢了。
5.3 技能文件存在但模型就是不调用
这是比较隐蔽的一类问题:技能文件写好了,目录结构也对,日志里也没报错,但模型就是不用它。排查方向通常是SKILL.md里的description写得太模糊。
模型是靠描述来判断"什么时候该用哪个技能"的,如果你的描述只写"网络搜索工具"几个字,模型在遇到复杂任务时可能根本联想不到它。把描述写具体一点,比如"用于查询最近发生的事件、最新版本信息、实时数据与新闻,当用户明确需要获取最新的外部信息时优先调用",模型就很容易在合适的场景里选中它。
另外确认一下技能目录是否在 OpenClaw 的扫描路径下,有些版本需要把技能放在skills/下的src/子目录,路径不对会直接被静默跳过。
5.4 返回内容质量差,搜索结果不像预期的
搜索功能跑通后,另一个常见抱怨是"搜出来的东西不对"。大部分时候不是搜索坏了,而是查询词没写好。模型生成查询词时,往往会把用户的问题原封不动搬过来,但搜索引擎吃的是关键词,不是完整问句。一个有效的做法是,在SKILL.md的说明里额外提醒模型:调用搜索技能时,请将查询词拆成简洁的关键词组,并尽可能附加限定词(比如时间、地点、领域)。
还有topic没切对也会导致内容偏,比如查"某公司最近发布了什么新品",用general主题可能出来一堆分析文章,切到news后返回的就是即时新闻稿了。这类问题排查起来很快,只要把参数调整思路理清楚,搜索质量会明显上一个台阶。
5.5 成本控制与隐私的几个提醒
最后分享几条跟搜索服务长期相处的心得:
- 给高频自动化任务设置合理的
max_results,结果数量直接决定花费的算力,不是返回越多越好。 - 对隐私敏感的信息,不要让模型把这些内容直接拼进搜索词。查询词会记录在当地服务端日志里,涉及内部数据的任务,过滤后再发出去更稳妥。
- 定期检查控制台用量,设置月度提醒。免费额度够归够,但自动化任务一旦跑上量,消耗速度还是容易超出直觉。
我个人的体感是,给 OpenClaw 配完 Tavily 之后,它的能力边界一下子宽了很多。以前跑不了的实时信息类任务,现在基本都能交出去了。如果你也在折腾类似的方向,建议从最小配置开始,先跑通一条任务链路,再慢慢往里加参数调整和边界处理。搜索这件事,配置本身不复杂,真正花时间的是让它贴合你的实际使用节奏。