【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,方便用户点击查看原始信息?

相关推荐
草邦设计开发团队_媒体资源平台1 小时前
Linux 稳定常驻启动 PHP 队列,服务器重启自动恢复
linux·服务器·php·队列执行
DS小龙哥1 小时前
基于树莓派PICO2设计的汽车少儿安全预警系统
网络·安全·汽车
solar应急响应1 小时前
【银狐应急复盘】伪装 Telegram 的“白加黑”银狐木马,从深度溯源到彻底清除的闭环响应实录(附自查 IOC)
网络·安全
竣达技术1 小时前
NAS / 服务器断电数据丢失?UPS 配套 USB关机保护板,市电断电池低自动提示服务器/电脑关机
运维·服务器·电脑
国科安芯1 小时前
基于ASM1042S2S的箭载通信网络抗辐射加固方案研究
服务器·网络·嵌入式硬件·fpga开发·架构·信号处理
云栖梦泽在1 小时前
跨境电商账号频繁验证怎么办?从公网 IP、ASN、浏览器环境到登录稳定性排查
网络·网络协议·tcp/ip·网络安全·性能优化
wbs_scy2 小时前
仿 muduo 高并发服务器项目:实现 Any 通用容器并理解 std::any
运维·服务器
爱奥尼欧2 小时前
【LangChain】2.提示词工程
人工智能·microsoft·langchain
海盗12342 小时前
.NET编码规范03-C#命名规范大全
linux·服务器·.net