【8】补充与拓展:Langchain的联网搜索Agent,使用Tavily工具

Langchain的联网搜索Agent,使用Tavily工具

在 LangChain 中,Tavily 是一款专为大型语言模型(LLMs)和检索增强生成(RAG)优化的搜索引擎 API。它能够提供结构化、带溯源的搜索结果,非常适合用来赋予 Agent 实时联网搜索的能力。

下面我将为你演示如何在 LangChain 中配置并使用 Tavily 工具来构建一个搜索 Agent。

第一步:安装依赖与配置 API Key

首先,你需要安装 LangChain 的 Tavily 集成包,并获取 Tavily 的 API Key(可以在 Tavily 官网注册获取)。

bash 复制代码
pip install -U langchain-tavily langchain-openai

在代码或环境变量中配置你的密钥:

python 复制代码
import os
os.environ["TAVILY_API_KEY"] = "你的Tavily-API-Key"
os.environ["OPENAI_API_KEY"] = "你的OpenAI-API-Key"

第二步:基础工具绑定与调用

LangChain 提供了 TavilySearch 工具类。你可以将其直接绑定到支持工具调用的 LLM(如 GPT-4o)上:

python 复制代码
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langchain_tavily import TavilySearch

# 1. 定义模型与工具
model = ChatOpenAI(model="gpt-4o-mini")
tool = TavilySearch(max_results=4)

# 2. 将工具绑定到模型
model_with_tools = model.bind_tools([tool])

# 3. 发起对话,触发模型调用工具
messages = [HumanMessage("北京今天的天气怎么样?")]
ai_message = model_with_tools.invoke(messages)
messages.append(ai_message)

# 4. 手动执行工具并将结果反馈给模型
for tool_call in ai_message.tool_calls:
    tool_message = tool.invoke(tool_call)
    messages.append(tool_message)

# 5. 模型根据搜索结果生成最终回答
final_response = model.invoke(messages)
print(final_response.content)

第三步:构建自动化的搜索 Agent

在实际应用中,我们通常不希望手动去循环执行工具,而是使用 LangChain 的 Agent 框架让它自主决策。你可以使用 create_tool_calling_agent 配合 AgentExecutor 来实现:

python 复制代码
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.agents import create_tool_calling_agent, AgentExecutor

# 1. 定义提示词模板(必须包含 agent_scratchpad 用于记录工具调用过程)
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个乐于助人的AI助手。当遇到不确定的实时信息时,请使用搜索工具获取答案。"),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

# 2. 创建 Agent 并传入工具
agent = create_tool_calling_agent(
    llm=model,
    tools=[tool],
    prompt=prompt
)

# 3. 使用 AgentExecutor 包装并运行
agent_executor = AgentExecutor(agent=agent, tools=[tool], verbose=True)
result = agent_executor.invoke({"input": "最近一周有什么重大的AI科技新闻?"})

print(result["output"])

核心机制解析

  • Function Call 模式 :Tavily 在 LangChain 中主要通过 Function Call(结构化函数调用)模式工作。LLM 会生成 JSON 格式的调用参数(如 {"query": "北京天气"}),LangChain 拦截后自动调用 Tavily API,并将返回的 URL、摘要等结构化数据作为 ToolMessage 传回给 LLM。
  • 丰富的返回数据 :通过 tool_msg.artifact,你不仅能获取到网页的标题和摘要(Snippets),还能获取到原始搜索结果列表、图片链接甚至后续追问建议(Follow-up questions),这对于构建高质量的 RAG 系统非常有帮助。

要不要我把这个联网搜索 Agent 整合到之前搭建的 LangGraph 多智能体客服系统中?比如当用户问实时新闻或天气时,自动触发搜索节点。

LangGraph的联网搜索 Agent ,使用Tavily工具

将联网搜索 Agent 整合到 LangGraph 多智能体系统中,最优雅的方式是构建一个**"混合检索路由(Agentic Hybrid RAG)"**架构。在这个架构中,系统会先对用户的问题进行意图分类,然后动态决定是查询本地知识库(向量搜索),还是调用 Tavily 进行实时网络搜索。

下面为你提供完整的实战代码,演示如何将 Tavily 搜索工具无缝集成到之前的客服系统中:

核心代码实现

python 复制代码
import os
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import create_react_agent
from langchain_core.messages import HumanMessage, AIMessage
from langchain_tavily import TavilySearch
from langchain_openai import ChatOpenAI

# ================= 1. 初始化模型与工具 =================
llm = ChatOpenAI(model="gpt-4o-mini")

# 初始化 Tavily 搜索工具
search_tool = TavilySearch(max_results=3, tavily_api_key=os.getenv("TAVILY_API_KEY"))
tools = [search_tool]

# ================= 2. 定义共享状态 =================
class AgentState(TypedDict):
    messages: Annotated[list, add_messages]
    intent: str  # 记录路由意图

# ================= 3. 定义专职节点 =================
# 意图识别节点:判断是否需要联网搜索
def router_node(state: AgentState):
    last_msg = state["messages"][-1].content.lower()
    # 简单的关键词判断,实际生产中可替换为 LLM 意图分类
    if any(keyword in last_msg for keyword in ["天气", "新闻", "最新", "今天"]):
        return {"intent": "SEARCH"}
    return {"intent": "LOCAL"}

# 本地客服节点(模拟)
def local_agent_node(state: AgentState):
    return {"messages": [AIMessage(content="【本地客服】:已为您查询本地知识库...")]}

# 联网搜索节点:使用预构建的 ReAct Agent 处理复杂搜索
def search_agent_node(state: AgentState):
    # 利用 LangGraph 预构建的 ReAct Agent 自动调用 Tavily
    search_agent = create_react_agent(
        model=llm, 
        tools=tools, 
        prompt="你是一个搜索助手,请根据用户问题调用 Tavily 搜索工具,并总结搜索结果。"
    )
    result = search_agent.invoke({"messages": state["messages"]})
    return {"messages": result["messages"]}

# ================= 4. 构建工作流图 =================
workflow = StateGraph(AgentState)

workflow.add_node("router", router_node)
workflow.add_node("local_agent", local_agent_node)
workflow.add_node("search_agent", search_agent_node)

# 设置入口
workflow.add_edge(START, "router")

# 条件路由
def route_by_intent(state: AgentState):
    return "search" if state["intent"] == "SEARCH" else "local"

workflow.add_conditional_edges(
    "router",
    route_by_intent,
    {"search": "search_agent", "local": "local_agent"}
)

# 所有分支最终汇聚到结束节点
workflow.add_edge("local_agent", END)
workflow.add_edge("search_agent", END)

app = workflow.compile()

# ================= 5. 运行测试 =================
test_queries = [
    "帮我查一下我的订单到哪了",
    "北京今天天气怎么样?",
    "最近一周有什么重大的AI科技新闻?"
]

for query in test_queries:
    print(f"👤 用户: {query}")
    result = app.invoke({"messages": [HumanMessage(content=query)]})
    print(f"🤖 AI: {result['messages'][-1].content}\n")

架构亮点解析

  1. 动态路由决策 :系统不再盲目地执行固定流水线。通过 router_node,系统能够根据用户的问题特征,动态决定是将任务交给本地知识库,还是交给联网搜索 Agent。
  2. ReAct 框架的无缝集成 :在 search_agent_node 中,我们使用了 LangGraph 预构建的 create_react_agent。它遵循"推理-行动-观察"(Reason-Act-Observe)框架,能够自主决定何时调用 Tavily,并处理返回的复杂结构化数据,无需我们手动编写循环逻辑。
  3. 状态隔离与共享AgentState 作为全局状态,既包含了对话历史 messages,也包含了路由决策依据 intent。搜索节点在获取到实时信息后,会将结果追加到 messages 中,保证上下文的连贯性。

通过这套架构,你的多智能体系统不仅具备了"记忆"和"多专家协作"的能力,还长出了"感知外部实时世界"的眼睛,真正达到了生产级智能客服的标准!


要不要我把 Tavily 的返回结果结构化处理一下,让 AI 在总结时能直接引用来源 URL,方便用户点击查看原始信息?

相关推荐
平行宇宙喜欢吃橙15 分钟前
Agent Harness 实战指南:构建生产级 AI Agent 的“马具“框架
网络·人工智能
公众号:fuwuqiBMC19 分钟前
(转自“服务器BMC”)服务器BMC芯片——AST1840
运维·服务器·fpga开发
测试专家24 分钟前
PCI-1553B板卡在 Windows Server 2016 服务器安装流程详解
服务器·windows·单片机
忘路之远近i32 分钟前
受够阿里云自带终端后,我用 Cursor + grill-me 做了个运维面板
服务器·开发语言·人工智能·python·阿里云·云计算
laboratory agent开发41 分钟前
工具调用失败后怎么办?重试分层与降级回路的三种路线
服务器·前端·网络
邪修king1 小时前
Re:Linux系统篇(四):权限Chapter--用户身份、权限位与目录权限三大核心问题
linux·运维·服务器
肥胖小羊2 小时前
企业微信自建应用多环境联调与路由代理方案
服务器·前端·网络
Alan_6912 小时前
第三方API对接的通用封装模式
服务器·开发语言·php
buhuizhiyuci2 小时前
【Linux 篇】数字世界的通信管道 —— 匿名管道与进程池深度实战解析
linux·运维·服务器
无锡耐特森2 小时前
ModbusTCP转Profinet:打通潜油电泵工业互联新路径
linux·运维·服务器