Dify 工作流集成 Tavily 实现 AI 联网搜索

39 阅读12分钟

为什么需要联网搜索?

大模型有一个天然的局限性:知识截止日期。无论是 GPT-4、Claude 还是 DeepSeek,它们的训练数据都有一个时间节点,之后发生的事情它们一无所知。当用户问"今天南昌天气怎么样"、"最近有什么科技新闻"、"某某股票现在多少钱"这类问题时,模型只能无奈地回复"我无法获取实时信息"。

这个问题在企业级应用中尤为突出。想象一下,你搭建了一个智能客服,用户问"你们公司最新的产品发布了吗",AI 却答不上来,这体验有多糟糕。

解决方案就是给 AI 接上"互联网的眼睛"——搜索工具。让 AI 在回答问题之前,先去网上搜一搜,拿到最新的信息,再整合成答案返回给用户。这就是所谓的"联网搜索"或者"实时搜索"能力。

Dify 中的搜索工具选择

Dify 作为一个开源的 LLM 应用开发平台,内置了多种搜索工具供选择:

DuckDuckGo 是最容易上手的,不需要任何 API Key,装上就能用。但问题也很明显:它是基于 IP 限流的,Dify 云服务的所有用户共享同一个 IP 池,别人调用多了你也会被限流。我之前测试的时候,明明只调用了一次就报 202 Rate limit 错误,就是因为这个原因。

Google Search 需要配置 SerpAPI,这是个付费服务,按调用次数收费,适合预算充足的企业用户。

Bing Search 需要 Azure 账号和 API Key,微软的服务稳定性有保障,但配置流程相对繁琐。

SearXNG 是开源自托管方案,没有调用限制,但需要自己部署服务器,适合有运维能力的团队。

Tavily 是本文的主角,它专门为 AI 场景设计,返回的结果格式对大模型非常友好,减少了很多无关信息的干扰。最关键的是,它提供免费额度——每月 1000 次调用,对于个人开发者和小团队来说完全够用。注册即送,不需要绑定信用卡。

综合考虑稳定性、易用性和成本,Tavily 是目前最适合个人开发者的选择。

环境准备

在开始之前,确保你具备以下条件:

  • Dify 环境:可以是 Dify 云服务,也可以是自部署版本,版本建议 0.6.x 及以上
  • Tavily 账号:需要注册并获取 API Key
  • 大模型配置:本文使用 DeepSeek-V3,你也可以换成其他模型

如果你还没有 Dify 环境,可以直接使用官方云服务 cloud.dify.ai,注册后有免费额度可以体验。

安装 Tavily 插件

打开 Dify 控制台,进入「工具」→「插件」页面。这里展示了 Dify 插件市场中所有可用的工具,包括代码解释器、时间工具、网页抓取、数据库查询等各种能力。

在搜索框中输入"Tavily",可以看到由 langgenius 官方维护的 Tavily 插件。插件描述写得很清楚:一个强大的原生 AI 搜索引擎和网页内容提取工具,提供高度相关的搜索结果和网页原始内容提取。

安装 Tavily 插件

点击「安装这个插件」按钮,等待几秒钟安装完成。安装成功后,插件会出现在你的工具列表中,但此时还不能直接使用,因为缺少 API Key 的配置。

Tavily 插件提供了两个核心工具:

  • Tavily Search:执行搜索查询,返回相关网页的摘要信息
  • Tavily Extract:从指定 URL 提取网页的完整内容

对于联网搜索场景,我们主要使用 Tavily Search。

获取 Tavily API Key

访问 Tavily 官网,点击右上角的「Sign Up」注册账号。支持 Google 账号一键登录,非常方便。

注册成功后进入控制台,左侧菜单选择「Overview」可以看到账户概览。页面中间显示了当前的套餐信息:免费版每月 1000 次调用额度(Credits),已使用次数会实时更新。

获取 API Key

往下滚动到「API Keys」区域,这里管理你的所有 API 密钥。默认会有一个名为 default 的开发密钥(dev 类型),点击右侧的复制按钮即可获取完整的 Key。

API Key 的格式类似 tvly-dev-xxxxxxxxxxxxxxxx,以 tvly- 开头。请妥善保管这个密钥,不要泄露到公开的代码仓库中。

拿到 Key 后,回到 Dify 的 Tavily 插件配置页面,在「API Key」输入框中粘贴刚才复制的密钥,点击保存。配置完成后,插件状态会变成可用。

工作流设计思路

在动手配置之前,先理清整个联网搜索的工作流程:

用户提问 → 判断是否需要联网 → 调用搜索工具 → LLM 整合结果 → 返回答案

最简单的实现是跳过"判断是否需要联网"这一步,直接对所有问题都执行搜索。这样做的好处是逻辑简单,坏处是浪费搜索额度——用户问"1+1等于几"也会触发一次搜索。

更优雅的做法是先用一个 LLM 节点做意图分类,判断用户的问题是否需要实时信息,只有需要的时候才调用搜索。但这会增加一次模型调用的延迟和成本。

本文采用简化方案:假设进入这个工作流的问题都是需要联网搜索的。在实际项目中,你可以在上游通过意图分类把不同类型的问题路由到不同的处理分支。

Tavily 搜索节点配置

在 Dify 工作流编辑器中,从左侧工具栏拖入一个「Tavily Search」节点。点击节点打开配置面板。

Tavily 搜索配置

核心参数说明:

查询(Query) :这是最重要的参数,决定了搜索什么内容。直接引用开始节点的用户输入变量,比如 {{#start.query#}}。Tavily 会根据这个查询去互联网上搜索相关信息。

搜索深度(Search Depth) :有「基本」和「高级」两个选项。基本模式速度快、消耗额度少,适合大多数场景;高级模式会进行更深入的搜索,返回更多结果,但消耗的额度也更多。建议默认使用基本模式。

主题(Topic) :可选「一般」或「新闻」。如果用户的问题明显是关于新闻时事的,选择「新闻」会得到更相关的结果;否则选择「一般」即可。

天数(Days) :限制搜索结果的时间范围,比如只搜索最近 7 天的内容。对于天气、新闻这类时效性强的查询很有用。不设置则搜索所有时间的内容。

时间范围(Time Range) :另一种时间过滤方式,可以选择「不指定」、「过去一天」、「过去一周」等预设选项。

国家(Country) :设置搜索结果的地域偏好。选择「中国」后,搜索结果会更偏向中文内容和国内网站,对于中文用户来说体验更好。

包含域 / 排除域:高级过滤选项。如果你只想从特定网站获取信息(比如只搜索知乎、CSDN),可以在「包含域」中指定;如果想排除某些网站的结果,在「排除域」中指定。

对于"南昌今天天气怎么样"这个测试问题,使用默认配置就能得到很好的结果。

LLM 总结节点配置

Tavily 返回的是原始的搜索结果,包含多个网页的标题、摘要、URL 等信息。这些信息是结构化的,但对用户来说阅读体验不好。我们需要一个 LLM 节点把这些原始结果整合成自然流畅的回答。

在工作流中添加一个 LLM 节点,连接在 Tavily Search 节点之后。

联网搜索 LLM 配置

System Prompt 配置

你是一个智能助手,负责根据搜索结果回答用户问题。
​
## 回答原则
1. 基于搜索结果中的事实信息回答,不要编造
2. 如果搜索结果信息不足,诚实告知用户
3. 语言简洁清晰,直接回答问题
4. 如果涉及时效性信息(天气、新闻等),注明信息来源时间
5. 对于数字、日期等关键信息要准确
​
## 回答格式
- 先直接回答用户问题
- 必要时补充相关细节
- 不要罗列原始搜索结果,要整合成自然的回答

这个 System Prompt 的设计有几个要点:

第一,强调"基于搜索结果回答,不要编造"。大模型有时候会"自信地胡说八道",明明搜索结果里没有的信息,它也能编出来。通过 prompt 约束可以减少这种情况。

第二,要求"信息不足时诚实告知"。如果搜索结果确实没有用户想要的信息,让模型坦诚地说"没有找到相关信息",比瞎编一个答案要好得多。

第三,强调"注明信息来源时间"。对于天气、股价这类时效性信息,告诉用户"这是截至今天上午的数据"很重要,避免用户误以为是实时数据。

User Prompt 配置

用户问题:{{#start.query#}}
​
搜索结果:
{{#tavily_search.text#}}
​
请根据以上搜索结果,回答用户的问题。

User Prompt 很简单,就是把用户的原始问题和 Tavily 返回的搜索结果拼接在一起,让模型去理解和整合。

注意变量引用的写法:{{#tavily_search.text#}} 中的 tavily_search 是你给 Tavily Search 节点起的名字,text 是该节点的输出字段。如果你的节点名字不同,需要相应修改。

效果验证

配置完成后,点击工作流编辑器右上角的「运行」按钮进行测试。在输入框中填入测试问题:"南昌今天天气怎么样"。

搜索结果

从运行结果可以看到,AI 成功返回了实时的天气信息:

根据联网搜索结果,南昌今天的天气情况如下:

  • 天气状况:阴转晴,温度 3~12°C,西北风 1 级,湿度 63%,紫外线无,气压 1023hPa。日出时间为 7:01,日落时间为 17:21。
  • 今日逐小时预报:从 08:00 到次日 06:00,风力主要为西北风或东北风,级别为...

结果面板还显示了一些元数据:

  • 状态:SUCCESS,表示执行成功
  • 运行时间:4.669 秒,这个时间包括了 Tavily 搜索和 LLM 推理两部分
  • Token 数:767 Tokens,这是 LLM 节点消耗的 token 数量

4.6 秒的响应时间对于联网搜索场景来说是可以接受的。如果觉得慢,可以考虑:

  • 使用更快的模型(比如 GPT-3.5-turbo 比 GPT-4 快很多)
  • 减少搜索结果的数量(Tavily 有参数可以控制)
  • 使用流式输出,让用户先看到部分结果

处理"今天"的时间问题

细心的你可能注意到一个问题:用户说"今天",但 LLM 怎么知道今天是哪一天?

大模型本身是没有时间概念的,它不知道"现在"是什么时候。如果用户问"今天天气",模型生成的搜索词可能就是"今天天气",而不是"2024年12月21日天气"。

好在 Tavily 足够智能,它会自动处理这类时间相关的查询,返回当前日期的结果。但如果你想更精确地控制,可以在工作流中加一个代码节点,获取当前日期并注入到 prompt 中:

import datetime
​
def main() -> dict:
    now = datetime.datetime.now()
    return {
        "current_date": now.strftime("%Y年%m月%d日"),
        "weekday": ["周一","周二","周三","周四","周五","周六","周日"][now.weekday()]
    }

然后在 LLM 的 System Prompt 中加上:

当前时间:{{#get_time.current_date#}} {{#get_time.weekday#}}

这样模型就能准确知道"今天"是哪一天了。

常见问题

Q:搜索结果不准确怎么办?

A:可以尝试调整 Tavily 的参数,比如设置「国家」为中国、调整「主题」类型、使用「包含域」限制搜索范围。另外,用户的查询本身也很重要,模糊的问题很难得到精确的答案。

Q:免费额度用完了怎么办?

A:Tavily 的付费套餐价格不贵,可以根据需求升级。或者考虑自部署 SearXNG 作为备选方案,没有调用限制。

Q:如何在意图分类后才调用搜索?

A:在 Tavily 节点之前加一个 LLM 意图分类节点,判断用户问题是否需要实时信息。如果需要,走搜索分支;如果不需要,直接让模型回答。这样可以节省搜索额度。

Q:搜索结果太长导致超出 token 限制怎么办?

A:可以在 Tavily 配置中限制返回结果的数量,或者在 LLM 节点之前加一个代码节点对搜索结果进行截断处理。

总结

Tavily 相比 DuckDuckGo 的核心优势在于稳定性和结果质量。它不会因为其他用户的调用而影响你的使用,返回的结果格式也对 AI 更友好,减少了无关信息的干扰。每月 1000 次的免费额度对于个人项目和测试完全够用,即使需要更多调用,付费套餐的价格也很合理。整个配置过程只需要安装插件、获取 API Key、搭建两个节点的工作流,十分钟内就能让你的 Dify 应用具备联网搜索能力。如果你正在构建需要回答实时性问题的 AI 应用,Tavily 是目前性价比最高的选择。