Langgraph学习3:AI搜索工具的比较

AI搜索工具的比较:Tavily VS DuckDuckGo

在构建AI应用程序时,获取准确、实时的外部信息是非常重要的一环。LangChain提供了多种搜索工具来帮助AI系统获取网络上的信息。本文将详细比较两种常用的搜索工具:Tavily和DuckDuckGo,分析它们的使用方法、特点以及性能差异。

搜索工具概述

Tavily

Tavily是一款专为AI应用优化的搜索引擎,提供了结构化的搜索结果。它需要API密钥才能使用,但能提供高质量的AI友好型搜索结果。

特点:

  • 需要API密钥
  • 结果格式统一,便于AI处理
  • 专为AI应用优化
  • 返回结构化数据
  • 每月1000次免费请求

需要先到官网进行注册,和创建APIKEY: https://app.tavily.com/home

DuckDuckGo

DuckDuckGo是一个注重隐私的搜索引擎,在LangChain中可以免费使用,无需API密钥。它提供了一种无需额外凭证即可获取网络信息的方式。

特点:

  • 无需API密钥
  • 注重隐私保护
  • 免费使用
  • 覆盖范围广泛

完整代码

以下是完整的比较代码,可以直接运行来测试这两种搜索工具:

"""
搜索工具比较示例:Tavily vs DuckDuckGo

该示例比较了LangChain中两个常用的搜索工具:
1. Tavily - 需要API密钥的AI优化搜索引擎
2. DuckDuckGo - 注重隐私的免费搜索引擎,无需API密钥

通过相同的查询,观察两种搜索工具返回结果的差异。
"""

import os
import time
import json
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_community.tools.ddg_search.tool import DuckDuckGoSearchResults

# 设置Tavily API密钥(如果存在)
tavily_api_key = os.getenv('TAVILY_API_KEY', '')
if tavily_api_key:
    os.environ['TAVILY_API_KEY'] = tavily_api_key


def format_results(results, tool_name):
    """
    格式化搜索结果为易读的格式
    
    Args:
        results (list or str): 搜索结果列表或字符串
        tool_name (str): 搜索工具名称
        
    Returns:
        str: 格式化后的搜索结果字符串
    """
    formatted_output = f"{tool_name} 搜索结果:\n"
    
    # 如果结果是字符串,尝试解析JSON
    if isinstance(results, str) and tool_name == "DuckDuckGo":
        try:
            parsed_results = json.loads(results)
            results = parsed_results
        except:
            return formatted_output + results
    
    # 根据不同的工具格式化结果
    if tool_name == "Tavily":
        for i, result in enumerate(results, 1):
            formatted_output += f"{i}. 标题: {result.get('title', 'N/A')}\n"
            formatted_output += f"   链接: {result.get('url', 'N/A')}\n"
            formatted_output += f"   内容: {result.get('content', 'N/A')[:150]}...\n\n"
    else:  # DuckDuckGo
        if isinstance(results, list):
            for i, result in enumerate(results, 1):
                formatted_output += f"{i}. 标题: {result.get('title', 'N/A')}\n"
                formatted_output += f"   链接: {result.get('link', 'N/A')}\n" 
                formatted_output += f"   摘要: {result.get('snippet', 'N/A')}\n\n"
        else:
            formatted_output += "无法解析搜索结果格式\n"
            
    return formatted_output


def search_with_tool(query, tool_type, max_results):
    """
    使用指定的搜索工具进行网络搜索
    
    Args:
        query (str): 搜索查询
        tool_type (str): 搜索工具类型 ("tavily" 或 "duckduckgo")
        max_results (int, optional): 最大结果数. 默认为5.
        
    Returns:
        dict: 搜索结果和状态信息
    """
    try:
        # 根据工具类型创建搜索工具
        if tool_type.lower() == "tavily":
            if not tavily_api_key:
                return {
                    "success": False,
                    "message": "未设置Tavily API密钥,无法使用Tavily搜索",
                    "results": []
                }
            search_tool = TavilySearchResults(max_results=max_results)
            tool_name = "Tavily"
        elif tool_type.lower() == "duckduckgo":
            search_tool = DuckDuckGoSearchResults(num_results=max_results, output_format="list")
            tool_name = "DuckDuckGo"
        else:
            return {
                "success": False,
                "message": f"不支持的搜索工具类型: {tool_type}",
                "results": []
            }
        
        # 计时开始
        start_time = time.time()
        
        # 调用搜索工具
        results = search_tool.invoke({"query": query})
        
        # 计时结束
        end_time = time.time()
        search_time = end_time - start_time
        
        # 检查结果
        if not results:
            return {
                "success": False,
                "message": f"{tool_name}搜索未返回任何结果",
                "results": [],
                "tool_name": tool_name,
                "search_time": search_time
            }
            
        # 格式化结果
        formatted_results = format_results(results, tool_name)
        
        return {
            "success": True,
            "message": f"{tool_name}搜索成功完成",
            "results": results,
            "formatted_results": formatted_results,
            "tool_name": tool_name,
            "search_time": search_time
        }
        
    except Exception as e:
        return {
            "success": False,
            "message": f"搜索过程中出现错误: {str(e)}",
            "results": [],
            "tool_name": tool_type
        }


def compare_search_tools(query, max_results=3):
    """
    比较不同搜索工具的结果
    
    Args:
        query (str): 搜索查询
        max_results (int, optional): 每个工具返回的最大结果数. 默认为3.
    """
    print("=" * 60)
    print(f"搜索查询: '{query}'")
    print("=" * 60)
    
    # 使用DuckDuckGo搜索
    print("\n[1] 使用DuckDuckGo搜索...")
    ddg_result = search_with_tool(query, "duckduckgo", max_results)
    
    # 使用Tavily搜索 (如果有API密钥)
    print("\n[2] 使用Tavily搜索...")
    tavily_result = search_with_tool(query, "tavily", max_results)
    
    # 打印结果比较
    print("\n" + "=" * 60)
    print("搜索结果比较")
    print("=" * 60)
    
    # DuckDuckGo结果
    if ddg_result["success"]:
        print(f"\nDuckDuckGo 搜索时间: {ddg_result.get('search_time', 'N/A'):.2f} 秒")
        print(ddg_result["formatted_results"])
    else:
        print(f"\nDuckDuckGo 搜索失败: {ddg_result['message']}")
    
    # Tavily结果
    if tavily_result["success"]:
        print(f"\nTavily 搜索时间: {tavily_result.get('search_time', 'N/A'):.2f} 秒")
        print(tavily_result["formatted_results"])
    else:
        print(f"\nTavily 搜索失败: {tavily_result['message']}")
    
    # 添加差异分析
    if ddg_result["success"] and tavily_result["success"]:
        print("\n" + "-" * 60)
        print("结果差异分析:")
        print("-" * 60)
        
        # 比较结果数量
        ddg_results = ddg_result["results"]
        tavily_results = tavily_result["results"]
        
        # 处理DuckDuckGo的结果数量
        if isinstance(ddg_results, str):
            try:
                import json
                ddg_results = json.loads(ddg_results)
            except:
                ddg_results = []
                
        ddg_count = len(ddg_results) if isinstance(ddg_results, list) else 0
        tavily_count = len(tavily_results)
        
        print(f"DuckDuckGo 返回结果数量: {ddg_count}")
        print(f"Tavily 返回结果数量: {tavily_count}")
        
        # 比较响应时间
        if "search_time" in ddg_result and "search_time" in tavily_result:
            ddg_time = ddg_result["search_time"]
            tavily_time = tavily_result["search_time"]
            faster = "DuckDuckGo" if ddg_time < tavily_time else "Tavily"
            time_diff = abs(ddg_time - tavily_time)
            print(f"响应时间差异: {faster} 更快 {time_diff:.2f} 秒")


def main():
    """主函数,运行搜索工具比较示例"""
    # 示例搜索查询
    queries = [
        "2024年人工智能的主要发展趋势",
        "LangChain和LlamaIndex的比较",
        "Python和JavaScript的区别"
    ]
    
    for query in queries:
        compare_search_tools(query)
        print("\n\n" + "=" * 70 + "\n")
        
        # 暂停一下,避免搜索频率过高
        time.sleep(2)


if __name__ == "__main__":
    print("\n" + "*" * 70)
    print("* LangChain搜索工具比较: Tavily vs DuckDuckGo *".center(70))
    print("*" * 70 + "\n")
    
    if not tavily_api_key:
        print("警告: 未设置TAVILY_API_KEY环境变量,Tavily搜索将不可用\n")
    
    main()

实际运行结果

下面是使用上述代码运行三个不同查询的实际对比结果,可以直观地看出两种搜索工具在不同方面的表现差异:

**********************************************************************
              * LangChain搜索工具比较: Tavily vs DuckDuckGo *
**********************************************************************

============================================================
搜索查询: '2024年人工智能的主要发展趋势'
============================================================

[1] 使用DuckDuckGo搜索...

[2] 使用Tavily搜索...

============================================================
搜索结果比较
============================================================

DuckDuckGo 搜索时间: 6.33 秒
DuckDuckGo 搜索结果:
1. 标题: 李飞飞团队发布《2024年人工智能指数报告》:10大趋势,揭示AI大模型喜与忧_澎湃号·湃客_澎湃新闻-The Paper
   链接: https://www.thepaper.cn/newsDetail_forward_27045165
   摘要: 刚刚,由李飞飞联合领导的斯坦福大学以人为本人工智能研究所(Stanford HAI)发布了《2024 年人工智能指数报告》(Artificial Intelligence Index Report 2024)。 这份长达 300 多页的报告是 Stanford HAI 发布的第 7 份 AI Index 研究,追踪了 2023 年全球人工智能的发展趋势。

2. 标题: 《2024年人工智能指数报告》
   链接: https://cingai.nankai.edu.cn/2024/0914/c10233a550905/page.htm
   摘要: 2024年4月,斯坦福大学以人为本人工智能研究所(Stanford HAI)发布了《2024 年人工智能指数报告》(Artificial Intelligence Index Report 2024)。 据Stanford HAI 官方介绍道:"这是我们迄今为止最全面的报告,而且是在人工智能对社会的影响从未如此明显的重要时刻发布的。

3. 标题: 中国信息通信研究院发布《人工智能发展报告(2024年)》
   链接: https://d.wanfangdata.com.cn/periodical/Ch9QZXJpb2RpY2FsQ0hJTmV3UzIwMjUwMTE2MTYzNjE0Eg1tamd5MjAyNTAxMDEwGghkNGwzYXFocg==
   摘要: 2024年12月10日,中国信息通信研究院发布《人工智能发展报告(2024年)》.《人工智能发展报告(2024年)》立足产业新发展、新变化、新需求,聚
焦新形势下全球人工智能发展重点,总结梳理人工智能技术创新方向、产业升级重点、行业落地趋势和安全治理进展,展望人工智能发展机遇,以期与业界分享,共同推动 ...



Tavily 搜索时间: 7.20 秒
Tavily 搜索结果:
1. 标题: 瞭望| 前瞻2024人工智能四大趋势 - 新华网
   链接: http://www.news.cn/tech/20240103/06334b17b41c44518168c2dea7bb844d/c.html
   内容: 瞭望 | 前瞻2024人工智能四大趋势
2024-01-03 16:01:40 来源:新华社
据消息人士称,OpenAI正在训练下一代的人工智能,暂名“Q*”(读作Q-star)。新的一年,OpenAI下一代产品可能发布
数据瓶颈指的是可用于训练AI的高质量数据的有限性,合成数据有望打破这一瓶颈。除...

2. 标题: 2024年人工智能产业十大发展趋势
   链接: https://zhuanlan.zhihu.com/p/683509691
   内容: 2024年人工智能产业十大发展趋势技术变革1. 多模态预训练大模型将是人工智能产业的标配2. 高质量数据愈发稀缺将倒逼数据智能飞跃3. 智能 算力无处不在...

3. 标题: 2024 年最重要的AI 趋势 - IBM
   链接: https://www.ibm.com/cn-zh/think/insights/artificial-intelligence-trends
   内容: 人工智能主要趋势 | IBM
2024 年最重要的 AI 趋势
标签
Artificial Intelligence
2024 年 2 月 9 日
阅读时长:12 分钟
复制链接
2022 年是生成式人工智能 (AI) 迅速进入公众意识的一年,而 2023 年则是它开始在商业世界扎根生长的一年。因此...



------------------------------------------------------------
结果差异分析:
------------------------------------------------------------
DuckDuckGo 返回结果数量: 3
Tavily 返回结果数量: 3
响应时间差异: DuckDuckGo 更快 0.87 秒


======================================================================

============================================================
搜索查询: 'LangChain和LlamaIndex的比较'
============================================================

[1] 使用DuckDuckGo搜索...

[2] 使用Tavily搜索...

============================================================
搜索结果比较
============================================================

DuckDuckGo 搜索时间: 6.44 秒
DuckDuckGo 搜索结果:
1. 标题: LangChain vs LlamaIndex:为您的AI应用选择最佳框架
   链接: https://myscale.com/blog/zh/llamaindex-vs-langchain-detailed-comparison/
   摘要: 总之,LlamaIndex和LangChain在技术领域的不同用例中提供了独特的优势。它们通过其专业化的功能满足了各种应用需求。它们提高了可用性, 并扩展了AI开发的视野。 # 根据需求做出正确选择. 在考虑选择LlamaIndex和LangChain之间的选择时,仔细评估您的项目需求至关 ...

2. 标题: Langchain与LlamaIndex应该选哪个 - 53AI-AI知识库|大模型知识库|大模型训练|智能体开发
   链接: https://www.53ai.com/news/langchain/2025040387046.html
   摘要: 在选择LangChain和LlamaIndex时,需要考虑以下因素: 项目需求: 如果应用主要关注搜索和检索,LlamaIndex可能更适合。对于更多样化的NLP任务和自定义工作流程,LangChain提供更大的灵活性。 使用简易性: LlamaIndex提供更简化和适合初学者的界面,而LangChain需要更深入 ...

3. 标题: LangChain vs LlamaIndex: A Detailed Comparison - DataCamp
   链接: https://www.datacamp.com/blog/langchain-vs-llamaindex
   摘要: Langchain vs LlamaIndex: A Comparative Analysis. LlamaIndex is primarily designed for search and retrieval tasks. It excels at indexing large datasets and retrieving relevant information quickly and accurately. LangChain, on the other hand, provides a modular and adaptable framework for building a variety of NLP applications, including chatbots ...



Tavily 搜索时间: 7.36 秒
Tavily 搜索结果:
1. 标题: LangChain 与LlamaIndex:详细比较原创 - CSDN博客
   链接: https://blog.csdn.net/RamendeusStudio/article/details/140046035
   内容: LangChain 专注于构建复杂的工作流和交互式应用程序,而LlamaIndex 则强调无缝数据集成和动态数据管理。 本文对这两个框架进行了全面比较,探讨了它们独特...

2. 标题: LangChain vs LlamaIndex:为您的AI应用选择最佳框架 - MyScale
   链接: https://myscale.com/blog/zh/llamaindex-vs-langchain-detailed-comparison/
   内容: 让我们讨论一下LlamaIndex和LangChain的一些核心功能和功能。

# 数据索引

在数据索引的背景下比较LlamaIndex和LangChain时,不同的方法浮出水面。LlamaIndex在快速组织和分类大量信息方面表现出色,将信息高效地转化为数值表示(嵌入式)。它专注于高效索引,以确...

3. 标题: LlamaIndex 和Langchain 有啥区别? - 杰力皓博
   链接: https://www.aqwu.net/wp/?p=2902
   内容: 两者之间的主要区别在于它们的使用场景和灵活性。LlamaIndex特别适合于搜索和检索任务,使其成为深度数据探索的有力工具。相比之下,LangChain提供了更广泛的能力和工具集成,...



------------------------------------------------------------
结果差异分析:
------------------------------------------------------------
DuckDuckGo 返回结果数量: 3
Tavily 返回结果数量: 3
响应时间差异: DuckDuckGo 更快 0.92 秒


======================================================================

============================================================
搜索查询: 'Python和JavaScript的区别'
============================================================

[1] 使用DuckDuckGo搜索...

[2] 使用Tavily搜索...

============================================================
搜索结果比较
============================================================

DuckDuckGo 搜索时间: 6.39 秒
DuckDuckGo 搜索结果:
1. 标题: JavaScript与Python编程语言对比:性能、应用场景及学习建议 - 云原生实践
   链接: https://www.oryoy.com/news/javascript-yu-python-bian-cheng-yu-yan-dui-bi-xing-neng-ying-yong-chang-jing-ji-xue-xi-jian-yi.html  
   摘要: JavaScript与Python编程语言对比:性能、应用场景及学习建议 在当今的编程世界中,JavaScript和Python无疑是两种最受欢迎且广泛应用的编 程语言。它们各自拥有庞大的开发者社区和丰富的库资源,但同时也存在明显的差异。本文将从性能、应用场景以及学习建议三个方面,对JavaScript和Python进行深入对比 ...

2. 标题: JavaScript 与 Python:您应该先学习哪一个? - Web前端之家
   链接: https://www.jiangweishan.com/article/PythonandavaScript.html
   摘要: 句法 虽然我们已经讨论了这两种语言的语法,但我们将更深入地研究这两种语言的细微差别。我们将研究最标准的编程指令以及 Python 和 JavaScript 的区别。 印刷 任何编程语言中一个基本概念就是打印。在任何优秀的初学者编程教程中,您编写的第一个程序都应该打印短语 Hello, World!。  使用 Python ...

3. 标题: Python vs Java脚本:它们之间的主要区别 - Guru99
   链接: https://www.guru99.com/zh-CN/python-vs-javascript.html
   摘要: 之间的区别 Python vs Java脚本 Python 是一种高级面向对象编程语言,具有内置数据结构以及动态绑定和类型,非常适合快速应用程序开发。 JavaScript 是一种脚本语言,可以帮助您创建交互式网页。 Python 具有可变和不可变的数据类型,但是 Java脚本没有可变和不可变的概念。 Python 源 代码默认为 ASCII ...



Tavily 搜索时间: 7.98 秒
Tavily 搜索结果:
1. 标题: Python和JavaScript在使用上有什么区别? - 葡萄城技术团队 - 博客园
   链接: https://www.cnblogs.com/powertoolsteam/p/14450549.html
   内容: 两种方法之间的主要区别在于,在Python中,将提示用户在控制台中输入值,而在JavaScript中,浏览器中将显示一个小提示,并要求用户输入值。...

2. 标题: python 和javascript 有什么区别? - 知乎
   链接: https://www.zhihu.com/question/583932715
   内容: 1、语法差异:Python 的语法比较简单,强调代码可读性,比如它使用缩进来表示代码块的范围。 JavaScript 的语法比较复杂,结构更加灵活,比如它没有明显的缩进...

3. 标题: Python与JavaScript有什么区别? - 稀土掘金
   链接: https://juejin.cn/post/7112346448229990414
   内容: 一方面,Python是强类型的,因此类型之间没有隐式转换。另一方面,JavaScript是弱类型的,意味着不相关的类型之间的转换是隐式的。...   



------------------------------------------------------------
结果差异分析:
------------------------------------------------------------
DuckDuckGo 返回结果数量: 3
Tavily 返回结果数量: 3
响应时间差异: DuckDuckGo 更快 1.59 秒


======================================================================

1.环境设置

先需要导入必要的库并设置环境变量

2. 结果格式化函数

搜索工具返回的原始数据格式各不相同,需要统一格式化以便比较。

format_results这个函数接收搜索结果和工具名称,根据不同工具返回的数据结构进行格式化,生成一个易于阅读的字符串输出。对于Tavily,它处理标题、URL和内容摘要;对于DuckDuckGo,它处理标题、链接和snippet摘要。

3. 搜索工具调用函数

search_with_tool核心功能是通过不同的搜索工具执行查询:

这个函数根据指定的工具类型(”tavily”或”duckduckgo”)创建相应的搜索工具实例,然后执行查询,记录搜索时间,并返回格式化的结果。

关键API使用:

  • TavilySearchResults(max_results=max_results) - 创建Tavily搜索工具
  • DuckDuckGoSearchResults(num_results=max_results, output_format="list") - 创建DuckDuckGo搜索工具,注意DuckDuckGoSearchResults要使用num_results
  • search_tool.invoke({"query": query}) - 执行搜索查询

4. 搜索工具比较函数

compare_search_tools比较函数协调多个搜索工具的使用并分析差异:

这个函数执行以下步骤:

  1. 使用DuckDuckGo执行搜索
  2. 使用Tavily执行相同的搜索
  3. 打印两种工具的搜索时间
  4. 显示格式化的搜索结果
  5. 分析结果之间的差异,包括结果数量和响应时间

5. 主函数

在主函数中,定义了三个示例查询,并对每个查询依次运行比较函数。为了避免请求频率过高,每次比较之间添加了短暂的延迟。

工具性能与结果差异分析

通过代码的运行,我们可以观察到两种搜索工具的几个关键差异:

  1. 结果格式:Tavily返回结构化的JSON数据,包含标题、URL和内容;DuckDuckGo返回的结果包含标题、链接和摘要。

  2. 响应时间:代码会测量并比较两种工具的响应时间,帮助我们了解它们在性能方面的差异。

  3. 结果质量:通过运行多个查询,可以主观评估两种工具返回结果的相关性和质量。

  4. 可用性:DuckDuckGo无需API密钥,随时可用;Tavily需要有效的API密钥。

应用场景

不同的搜索工具适合不同的应用场景:

  • Tavily:适合需要高质量、结构化结果的专业AI应用,特别是那些有预算支持API调用的项目。

  • DuckDuckGo:适合开发阶段的项目、教育目的或不需要特别优化的应用,尤其是当预算有限或注重隐私时。

综合比较分析(以下是Claude-3.7-sonnet根据完整log进行的分析结果)

通过对三种不同查询的测试比较,我们可以总结出以下几点关于Tavily和DuckDuckGo搜索工具的对比:

响应速度

在所有测试查询中,DuckDuckGo的响应速度都比Tavily快,平均快约1秒左右:

  • 查询1:DuckDuckGo快0.87秒
  • 查询2:DuckDuckGo快0.92秒
  • 查询3:DuckDuckGo快1.59秒

这可能是因为DuckDuckGo不需要额外的API认证步骤,且其服务器可能针对简单查询做了更好的优化。

结果质量与相关性

两种工具在结果质量上各有特点:

  • DuckDuckGo:返回的结果更全面,包含了更多来源的信息。例如在”2024年人工智能的主要发展趋势”的查询中,DuckDuckGo返回了包括斯坦福研究所和中国信息通信研究院的报告,覆盖面较广。

  • Tavily:虽然结果数量较少,但针对AI应用场景做了优化,返回的内容格式更统一,且内容摘要往往直接切入主题。例如在”Python和JavaScript的区别”查询中,Tavily的结果更直接地列出了语法差异等关键点。

结果格式

两种工具返回的结果格式有明显差异:

  • DuckDuckGo:返回的字段包括title、link和snippet,更适合传统的搜索结果展示。
  • Tavily:返回的字段包括title、url和content,格式更为结构化,便于AI系统进一步处理。

总结

通过实际的搜索测试比较,我们可以看到:

  1. 性能方面:DuckDuckGo在响应速度上略胜一筹。
  2. 可用性方面:DuckDuckGo无需API密钥,更容易上手使用。
  3. 结果质量方面:Tavily的结果更适合AI应用处理,而DuckDuckGo提供了更广泛的信息覆盖。

这些结果验证了理论分析中的预期,并提供了直观的证据帮助开发者根据自己的应用需求选择合适的搜索工具。对于注重速度和无需API密钥的应用,DuckDuckGo是更好的选择;而对于需要高质量、结构化结果的AI专业应用,Tavily则能提供更好的支持。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!