LangGraph实战:用条件边和循环流程,手把手教你打造一个能联网搜索的AI助手

张开发
2026/4/13 7:04:31 15 分钟阅读

分享文章

LangGraph实战:用条件边和循环流程,手把手教你打造一个能联网搜索的AI助手
LangGraph实战构建具备联网搜索能力的AI助手全流程解析当开发者需要构建一个能处理实时信息的AI助手时如何让系统智能地判断何时调用外部工具、何时结束对话成为关键挑战。LangGraph通过条件边和循环流程的灵活组合为这类需求提供了优雅的解决方案。本文将深入探讨如何从零构建一个能自动联网搜索的智能体涵盖工程实现中的核心考量。1. 理解LangGraph的核心机制在开始构建之前我们需要明确几个关键概念。LangGraph中的边决定了节点间的流转逻辑而条件边conditional edge则是实现智能决策的关键。与普通边不同条件边通过函数动态决定下一步执行的节点这为复杂逻辑提供了可能。循环流程的实现则更为直观——只需通过add_edge将节点首尾相连即可。但这里有个重要细节必须设置合理的退出条件否则系统会陷入无限循环。实践中我们通常会在循环中插入条件边作为安全阀。典型的工具调用场景会涉及三种节点决策节点判断是否需要调用工具工具执行节点实际调用外部API结果处理节点整理工具返回的数据2. 构建基础架构让我们从一个具体的用户需求出发查询实时信息。以下是完整的实现步骤from typing import TypedDict, Annotated, Literal from langchain_community.tools import GoogleSerperRun from langchain_core.messages import ToolMessage from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph, END # 定义状态结构 class AgentState(TypedDict): messages: Annotated[list, add_messages] # 初始化工具和模型 search_tool GoogleSerperRun( nameweb_search, description用于查询实时信息的谷歌搜索API ) llm ChatOpenAI(modelgpt-4) llm_with_tools llm.bind_tools([search_tool])2.1 实现核心节点决策节点负责分析对话上下文判断是否需要调用工具def should_use_tool(state: AgentState) - Literal[search, end]: last_msg state[messages][-1] if hasattr(last_msg, tool_calls): return search return end工具执行节点处理具体的API调用def search_executor(state: AgentState): tool_calls state[messages][-1].tool_calls results [] for call in tool_calls: if call[name] web_search: result search_tool.invoke(call[args]) results.append(ToolMessage( tool_call_idcall[id], contentstr(result), nameweb_search )) return {messages: results}2.2 组装工作流将各个节点连接成完整的工作流# 初始化图结构 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(generate, lambda state: {messages: [llm_with_tools.invoke(state[messages])]}) workflow.add_node(search, search_executor) # 设置边关系 workflow.add_edge(search, generate) workflow.add_conditional_edges( generate, should_use_tool, {search: search, end: END} ) # 设置入口点 workflow.set_entry_point(generate) agent workflow.compile()3. 工程实践中的关键考量3.1 状态管理策略在循环流程中状态管理尤为重要。我们建议明确状态结构使用TypedDict定义清晰的数据结构避免状态污染每个节点应只修改自己负责的数据部分添加版本控制复杂场景可考虑加入状态版本标记3.2 错误处理机制工具调用可能因各种原因失败健壮的系统需要处理API限流实现指数退避重试逻辑网络异常设置合理的超时时间结果解析验证返回数据的完整性改进后的工具执行节点示例def robust_search_executor(state: AgentState): tool_calls state[messages][-1].tool_calls results [] for call in tool_calls: try: if call[name] web_search: result search_tool.with_retry().invoke(call[args]) if not validate_result(result): raise ValueError(Invalid search result) results.append(ToolMessage( tool_call_idcall[id], contentstr(result), nameweb_search )) except Exception as e: results.append(ToolMessage( tool_call_idcall[id], contentfError: {str(e)}, nameweb_search_error )) return {messages: results}3.3 性能优化技巧对于高频调用的工具可以考虑优化策略实现方式适用场景结果缓存使用LRU缓存工具结果查询重复度高时批量调用合并多个工具请求并行工具调用场景预处理在工具调用前过滤无效请求输入质量不可控时4. 进阶应用多工具协作当系统需要同时处理多种工具时路由逻辑会变得更加复杂。以下是扩展方案tools [search_tool, calculator_tool, weather_tool] def advanced_router(state: AgentState) - str: last_msg state[messages][-1] if not hasattr(last_msg, tool_calls): return end called_tools {call[name] for call in last_msg.tool_calls} if web_search in called_tools: return search elif calculator in called_tools: return calculate else: return other_tools对应的图结构配置workflow.add_node(calculate, calculator_executor) workflow.add_node(other, other_tools_executor) workflow.add_conditional_edges( generate, advanced_router, { search: search, calculate: calculate, other: other, end: END } )5. 调试与监控在实际部署前建议添加以下保障措施日志记录关键节点的状态变化性能指标各节点执行时间统计输入输出检查数据格式验证调试时可使用LangGraph的可视化工具from langgraph.graph import GraphDrawer drawer GraphDrawer(workflow) drawer.render(workflow.png) # 生成流程图在开发过程中我发现在处理复杂对话时添加对话轮次计数器能有效防止无限循环。当轮次超过阈值时可以强制跳转到结束节点避免资源浪费。

更多文章