LangChain LangGraph
Module 1 Module 2 Module 3
Module 1 · 基础能力
1 1.1a 基础模型
2 1.1b Prompting
3 1.2a Tools
4 1.2b Web Search
5 1.3 Memory
6 1.4 Multimodal
7 1.5 Personal Chef
SUM Module Summary
HomeLangChainModule 1 · 基础能力1.2b Web Search
📓 Notebook 📖 Explained
LANGCHAIN MODULE 1 · LESSON 1.2b

Web 搜索工具
Tavily · 实时联网 · 信息检索 Agent

LLM 的知识有截止日期。通过 Tavily 搜索工具,Agent 能实时检索网页内容,让模型基于最新信息回答问题——"谁是 XX 的校长?""今天的股价是多少?"

1 为什么需要 Web 搜索?LLM 知识截止的根本局限

所有 LLM 都有一个根本局限:训练数据有截止日期(Knowledge Cutoff)。GPT-4、DeepSeek、Claude——它们只知道训练集里的知识,无法知道训练后发生的新事件、新数据。

对于这类问题,单纯依赖 LLM 会得到可能过时或错误的答案。Web 搜索工具解决了这个问题——它让 Agent 能在推理时"出去查一下",把最新信息带回来。

检索增强生成(RAG)的实时版

Web 搜索工具本质上是实时 RAG(Retrieval-Augmented Generation)的一种形式:先检索(Retrieve)相关内容,再让模型基于检索结果生成(Generate)答案。区别在于:RAG 通常从私有知识库检索,Web 搜索从公开互联网检索。

2 Tavily:专为 AI Agent 设计的搜索 API

Tavily 是一个为 LLM/Agent 场景优化的搜索服务,相比直接爬网页,它有几个关键优势:

特性Tavily自己爬网页
返回格式 干净的 JSON,包含 URL、标题、内容摘要 原始 HTML,需要解析和清洗
内容质量 智能筛选,过滤广告和无关内容 包含大量噪声
搜索深度 支持 basicadvanced 两档 需要自己实现深度搜索
集成难度 一行代码,直接返回 LLM 可用的内容 需要处理 robots.txt、限流、编码等问题
获取 Tavily API Key

tavily.com 注册即可获取免费 API Key(有月度配额),将其设置为环境变量 TAVILY_API_KEY,TavilyClient 会自动读取。

3 定义 web_search 工具:@tool + TavilyClient

from langchain.tools import tool
from typing import Dict, Any
from tavily import TavilyClient

tavily_client = TavilyClient()  # 自动读取 TAVILY_API_KEY 环境变量

@tool("web_search", description="Search web")
def web_search(query: str) -> Dict[str, any]:
    return tavily_client.search(query, search_depth="basic")

这个工具的关键参数:

description 要足够描述性

上面代码里 description="Search web" 非常简短。在实际项目中,建议写得更详细,例如:"Search the web for real-time information. Use when you need current data, recent events, or facts that may have changed after your training cutoff." 这样模型能更准确地判断何时调用。

4 没有搜索工具时:LLM 的局限性演示

先建一个没有工具的普通 Agent,看它如何回答实时性问题:

agent_no_tools = create_agent(model=deepseek_model())

question = {
    "role": "user",
    "content": "Who is the principal of Birralee Primary School?"
}

response = agent_no_tools.invoke({"messages": question})
无工具 Agent 的回答(不可靠)
I don't have specific information about the current principal of Birralee Primary School. School leadership can change over time, and I may not have up-to-date information. I recommend checking the school's official website or contacting the school directly for accurate information.

模型诚实地承认不知道——这是最好的情况。更糟糕的情况是模型自信地给出一个错误答案(幻觉)。

5 绑定搜索工具后:实时回答真实问题

场景一:查找学校校长

# 给 Agent 绑定 web_search 工具
agent = create_agent(
    deepseek_model(),
    tools=[web_search]
)

question = {
    "role": "user",
    "content": "Who is the principal of Birralee Primary School?"
}

response = agent.invoke({"messages": question})
print(response['messages'][-1].content)
有工具 Agent 的回答(来自真实网页)
The principal of Birralee Primary School is **Ashley Ryan**.

模型这次调用了 web_search("Birralee Primary School principal"),从真实网页里找到了答案,而不是凭空编造。

场景二:查找市长信息

agent = create_agent(
    model=deepseek_model(),
    tools=[web_search]
)

question = HumanMessage(content="Who is the current mayor of San Francisco?")
response = agent.invoke({"messages": [question]})
print(response['messages'][-1].content)
执行输出(来自实时 Web)
Based on the search results, the current mayor of San Francisco is **Daniel Lurie**, who took office in January 2025...

6 解析搜索结果:ToolMessage 里的 JSON 数据

Tavily 返回的是 JSON 字符串,被封装为 ToolMessage.content。如果需要从搜索结果中提取具体信息,可以解析这个 JSON:

import json

# messages[2] 是 ToolMessage(工具执行结果)
content = response['messages'][2].content
data = json.loads(content)   # 字符串 → dict

from pprint import pprint
pprint(data)
Tavily 返回的 JSON 结构
{
  "query": "Who is the current mayor of San Francisco?",
  "results": [
    {
      "url": "https://sfmayor.org/...",
      "title": "Mayor Daniel Lurie - City and County of San Francisco",
      "content": "Daniel Lurie is the 46th Mayor of San Francisco...",
      "score": 0.9521
    },
    { ... }, // 更多结果
  ],
  "response_time": 0.87
}

Tavily 搜索结果的关键字段

字段含义
query 实际执行的搜索查询词
results 搜索结果列表,每项包含 url、title、content、score
results[i].content 网页摘要内容(已清洗,适合 LLM 阅读)
results[i].score 相关性评分(0-1),越高越相关
answer Tavily 自动生成的直接答案(并非总是有)
response_time 搜索耗时(秒)

7 搜索工具的进阶用法与注意事项

先独立测试工具,再绑定 Agent

# 先独立测试 web_search,确认可以正常工作
web_results = web_search.invoke("Who is the current mayor of San Francisco?")
print(web_results['results'][0]['content'])  # 第一条结果的内容

完整的工具列表示例

# 可以同时绑定多个工具
agent = create_agent(
    model=deepseek_model(),
    tools=[web_search, square_root, another_tool],
    system_prompt="You have access to web search and math tools. Use them when needed."
)
搜索工具的潜在问题

使用 Web 搜索工具时要注意:
成本:Tavily 有 API 调用费用,高频调用需监控用量
延迟:网络搜索增加响应时间(通常 1-3 秒)
信息质量:搜索结果可能包含错误或偏颇的网页内容,模型需要判断可信度
无限循环风险:如果 system prompt 设计不当,模型可能无限搜索。LangGraph Agent 内置有最大步骤限制

Lesson 1.2b 核心要点
Tavily 搜索工具
  • TavilyClient() 自动读取 API Key
  • • 返回干净 JSON,包含 results 列表
  • search_depth="basic" 快速适用
实时信息能力
  • • 打破 LLM 知识截止日期限制
  • • Agent 自动决定何时搜索
  • • ToolMessage 保存搜索结果