langGraph从入门到精通(九)——基于LangGraph构建具备多工具调用与自动化摘要能力的智能 Agent

《基于LangGraph构建具备多工具调用与自动化摘要能力的智能 Agent 》

1 导语

在构建复杂的 AI 代理时,如何让 Agent 不仅能"听懂"需求,还能"协调"多个工具并最终"专业"地汇总结果?本文将基于 LangGraph 实战案例,深度拆解一个具备实时联网搜索、天气查询、数据库入库以及最终结果自动化摘要能力的完整智能体闭环。

本文所有步骤亲测可复现,适配环境:Windows/macOS/Linux,Python >= 3.9。

2 技术栈清单

  • Python == 3.11.x
  • langgraph == 1.0.5
  • langchain-openai == 1.1.7
  • python-dotenv == 1.2.1
  • Model: qwen-plus (DashScope API)

3 项目核心原理

本项目通过 StateGraph 构建了一个闭环工作流:

  1. 决策层 :由大模型判定是否需要调用工具(chat_with_model)。
  2. 执行层 :手动实现工具执行节点(execute_function),处理并行的 tool_calls
  3. 分流逻辑:利用条件边(Conditional Edges)实现"执行工具"与"直接回复"的动态切换。
  4. 汇总层 :所有路径最终汇聚于 natural_response 节点,利用系统 Prompt 对多源信息进行专业化中文总结。

4 实战步骤

4.1 环境准备

前置条件:已配置 .env 文件,包含 DASHSCOPE_API_KEY

bash 复制代码
# 安装必要依赖
pip install langgraph==1.0.5 langchain-openai==1.1.7 pydantic==2.10.0
# 验证环境
python -c "import langgraph; print(langgraph.__version__)"
# 成功标识:输出 1.0.5

4.2 代码实现

4.2.1 状态定义与工具 Schema

使用 Pydantic 定义工具的参数约束,确保 LLM 输出的准确性。

python 复制代码
from typing import TypedDict, Annotated, Optional
import operator
from pydantic import BaseModel, Field
from langchain_core.messages import AnyMessage

# 定义状态:使用 Annotated 和 operator.add 实现消息自动追加
class AgentState(TypedDict):
    messages: Annotated[list[AnyMessage], operator.add]

# 定义工具参数模型
class UserInfo(BaseModel):
    name: str = Field(description="用户姓名")
    age: Optional[int] = Field(description="用户年龄")
    email: str = Field(description="邮箱地址")
    phone: Optional[str] = Field(description="电话号码")
@tool(args_schema = UserInfo)
def insert_db(name, age, email, phone):
    """Insert user information into the database, The required parameters are name, age, email, phone"""
    session = Session()  # 确保为每次操作创建新的会话
    try:
        # 创建用户实例
        user = User(name=name, age=age, email=email, phone=phone)
        # 添加到会话
        session.add(user)
        # 提交事务
        session.commit()
        return {"messages": [f"数据已成功存储至Mysql数据库。"]}
    except Exception as e:
        session.rollback()  # 出错时回滚
        return {"messages": [f"数据存储失败,错误原因:{e}"]}
    finally:
        session.close()  # 关闭会话
4.2.2 核心节点与路由逻辑

手动实现工具执行逻辑,深入理解 ToolMessage 的构造。

python 复制代码
def execute_function(state: AgentState):
    # 获取模型生成的工具调用指令
    tool_calls = state['messages'][-1].tool_calls
    results = []
    # 建立工具映射表
    tools_map = {"insert_db": insert_db, "fetch_real_time_info": fetch_real_time_info, "get_weather": get_weather}
    
    for t in tool_calls:
        # 执行工具并将结果封装为 ToolMessage
        result = tools_map[t['name']].invoke(t['args'])
        results.append(ToolMessage(tool_call_id=t['id'], name=t['name'], content=str(result)))
    return {'messages': results}

def exists_function_calling(state: AgentState):
    # 判定是否存在工具调用请求
    return len(state['messages'][-1].tool_calls) > 0
4.2.3 图编排与编译
python 复制代码
graph = StateGraph(AgentState)
graph.add_node("chat_with_model", chat_with_model)
graph.add_node("execute_function", execute_function)
graph.add_node("natural_response", natural_response)

graph.set_entry_point("chat_with_model")
graph.add_conditional_edges(
    "chat_with_model",
    exists_function_calling,
    {True: "execute_function", False: "final_answer"} # 条件分流
)
graph.add_edge("execute_function", "natural_response")
graph.set_finish_point("natural_response")
app = graph.compile()

4.3 功能测试

测试用户信息的自动入库与专业回复:

  • 启动命令python ./07-tool-05.py
  • 预期输出 :输入用户信息后,控制台应先打印 SQL 执行语句(若配置了 echo=True),最后输出中文专业总结。

5 核心代码深度解析

5.1 原始代码展示

python 复制代码
# 行号 139-148
graph.add_conditional_edges(
    "chat_with_model",
    exists_function_calling,
    {True: "execute_function", False: "final_answer"}
)

graph.add_edge("execute_function", "natural_response")
graph.add_edge("final_answer", "natural_response")
graph.set_finish_point("natural_response")

5.2 关联知识点讲解

  • 知识点 1:ToolMessage 的手动构造
    execute_function 中,我们没有使用预构建的 ToolNode语法/知识点名称ToolMessage(tool_call_id=...)核心作用 :它必须携带 tool_call_id 才能让模型知道这条结果对应的是哪个请求,否则在多工具并行场景下会逻辑混乱。
  • 知识点 2:Annotated 状态归并
    语法/知识点名称Annotated[list, operator.add]新手易错 :如果漏写了 operator.add,后续节点返回的 {"messages": [...]} 会直接覆盖之前的消息,导致 Agent 丢失上下文记忆。

5.3 代码逻辑解析

  1. exists_function_calling :作为"分流器",它通过检查 AIMessage 中的 tool_calls 列表长度。如果模型觉得需要查外部信息(如天气),则返回 True 强制流向执行节点。
  2. natural_response :这是系统的"润色员"。它不直接返回工具执行的原始字符串(通常很乱),而是通过一个 SYSTEM_PROMPT 指令:"基于现有信息,生成专业中文回复"。这种设计保证了最终用户看到的输出具有统一的语气和格式。

6 效果验证

6.1 案例1

python 复制代码
query="你好,请你介绍一下你自己"
input_message = {"messages": [HumanMessage(content=query)]}

result = graph.invoke(input_message)
result

6.2 案例2

python 复制代码
query="小米汽车"
input_message = {"messages": [HumanMessage(content=query)]}

result = graph.invoke(input_message)
result

6.3 案例3

python 复制代码
query="北京的天气怎么样?"
input_message = {"messages": [HumanMessage(content=query)]}

result = graph.invoke(input_message)
result

7 踩坑记录

7.1 Pydantic 模型描述缺失

  • 错误现象:模型总是乱填参数,或者不调用工具。
  • 根因分析UserInfoFielddescription 写得太简略,模型不理解什么时候该采集电话。
  • 解决方案 :在 Field 中明确标注"如果用户没有提供则不填"等引导语。

7.2 异步调用下的状态冲突

  • 错误现象:数据库插入成功但回复里说失败。
  • 根因分析 :由于 operator.add 的原子性,在并发执行工具时,如果节点逻辑编写不当可能导致消息顺序错乱。
  • 解决方案 :在 execute_function 中使用列表收集所有 ToolMessage 后一次性返回。

7.3 环境配置导致的导入错误

  • 错误现象ModuleNotFoundError: No module named 'langgraph'
  • 根因分析:在虚拟环境外执行或未正确安装。
  • 解决方案 :执行 pip install langgraph==1.0.5 并确认 which python 指向正确环境。

8 总结与扩展

本文通过手动实现 ToolNode 的逻辑,带大家深入理解了 LangGraph 内部的消息交换机制。复现关键点在于:

  1. Schema 描述:给 LLM 的"说明书"必须精准。
  2. 状态追加 :必须使用 operator.add 保证记忆连续。
  3. 结果润色:最后加入一个汇总节点,极大提升用户体验。

欢迎评论区留言讨论核心主题相关的问题,若复现失败可留言你的系统版本+报错日志,我会及时回复~

相关推荐
辰阳星宇2 小时前
【工具调用】BFCL榜单数据分析
人工智能·数据挖掘·数据分析
一晌小贪欢2 小时前
Python 对象的“Excel 之旅”:使用 openpyxl 高效读写与封装实战
开发语言·python·excel·表格·openpyxl·python办公·读取表格
【赫兹威客】浩哥2 小时前
【赫兹威客】Python解释器部署教程
python
Das12 小时前
【机器学习】07_降维与度量学习
人工智能·学习·机器学习
代码or搬砖2 小时前
Prompt(提示词工程)
人工智能·python·prompt
老纪的技术唠嗑局2 小时前
不止于替换 HBase:宝付支付借力 OceanBase,构建面向未来的“TP+AP+KV+AI”统一数据基座
人工智能·hbase·oceanbase
喵手2 小时前
Python爬虫零基础入门【第二章:网页基础·第3节】接口数据基础:JSON 是什么?分页是什么?
爬虫·python·python爬虫实战·python爬虫工程化实战·python爬虫零基础入门·接口数据基础·爬虫json
2501_944526422 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 关于页面实现
android·java·开发语言·javascript·python·flutter·游戏
DO_Community2 小时前
海外云 AWS、GCP、Azure 与 DigitalOcean 的核心区别有哪些?
人工智能·云计算·azure·aws·谷歌云·digitalocean