LangGraph Node节点:让AI"动起来"
LangGraph Node节点:让AI”动起来”
想象一下,你走进一家热闹的餐厅。厨房里,厨师正在翻炒锅中的食材;吧台前,调酒师熟练地摇晃着雪克杯;收银台后,收银员微笑着为客人结账。每个人都有自己的职责,每个人都在特定的时刻执行特定的任务,而最终,一道道美味佳肴被端上餐桌。
这就是**节点(Node)**的魅力——将复杂的流程拆解成一个个独立、可复用的单元。
在LangGraph的世界里,Node就是构建AI工作流的基本砖块。如果说LangGraph是一座宏伟的建筑,那么Node就是构成这座建筑的每一块砖石。理解Node,你就掌握了让AI真正”动起来”的钥匙。
一、什么是Node?——餐厅里的分工艺术
1.1 从餐厅说起
让我们继续用餐厅来比喻。一家餐厅要正常运营,需要哪些角色?
- 服务员:接待客人,记录点单,将需求传递给厨房
- 厨师:根据订单烹饪食物,把控口味和品质
- 收银员:计算账单,处理付款,开具发票
- 保洁员:打扫餐桌,保持环境整洁
每个角色都是一个独立的”节点”,他们各自有明确的职责,通过特定的流程(服务员下单→厨师做菜→服务员上菜→收银员结账)协同工作,最终为客人提供完整的用餐体验。
1.2 AI世界的Node
在LangGraph中,Node的作用与餐厅中的角色异曲同工。每个Node都是一个执行特定任务的函数或方法,它们接收输入、处理数据、产生输出,并通过状态(State)与其他Node交换信息。
举个例子,一个最简单的AI对话系统可能包含:
- 理解节点:分析用户的输入,提取关键信息
- 思考节点:根据提取的信息进行推理和决策
- 回复节点:生成自然语言的回应
这三个Node串联起来,就构成了一个完整的对话流程。
1.3 为什么需要Node?
你可能会问:为什么不把所有逻辑写在一个大函数里呢?
好问题!想象一下,如果餐厅只有一个员工,他既要接待客人,又要炒菜,还要收银和打扫——效率会极其低下,而且一旦他请假,整个餐厅就得关门。
使用Node的好处:
- 职责单一:每个Node只做一件事,代码更易理解和维护
- 灵活组合:像搭积木一样,不同的Node可以组合出不同的工作流
- 易于调试:当出现问题时,可以快速定位到具体的Node
- 便于复用:写好的Node可以在多个项目中重复使用
- 可视化:LangGraph可以将Node和它们之间的连接绘制成图,一目了然
二、LangGraph中的三种Node类型
LangGraph主要支持三种类型的Node,它们各有特色,适用于不同的场景。
2.1 函数节点(Function Node)——万能的基础砖块
函数节点是最基础、最灵活的Node类型。它本质上就是一个Python函数,你可以在里面写任何逻辑。
适用场景:
- 数据预处理(清洗、格式化)
- 条件判断(根据某些条件决定下一步做什么)
- 状态更新(修改共享状态中的数据)
- 调用外部API
- 任何自定义逻辑
代码示例:
1 | from langgraph.graph import StateGraph |
这个例子展示了最基础的函数节点用法。我们定义了两个节点:接收订单和验证订单,它们通过状态传递信息。
2.2 LLM节点(LLM Node)——AI的大脑
LLM节点是LangGraph的核心亮点之一。它将大语言模型(如GPT-4、Claude、文心一言等)封装成一个Node,让AI能够在工作流中”思考”和”决策”。
适用场景:
- 理解自然语言输入
- 生成文本回复
- 进行推理和决策
- 提取结构化信息
- 多轮对话管理
代码示例:
1 | from langgraph.graph import StateGraph |
在这个例子中,ai_respond节点封装了对GPT模型的调用。当状态传递到这个节点时,它会将用户的message发送给LLM,并将回复存入response字段。
2.3 工具节点(Tool Node)——连接外部世界的桥梁
工具节点是LangGraph的”超能力”来源。它允许AI调用外部工具,比如查询天气、搜索网络、操作数据库、发送邮件等。这让AI从”只会聊天”变成了”能够行动”。
适用场景:
- 获取实时信息(天气、股价、新闻)
- 执行计算或数据分析
- 操作外部系统(数据库、API)
- 搜索互联网
- 调用专业软件或服务
代码示例:
1 | from langgraph.graph import StateGraph |
工具节点的强大之处在于,它让AI不再局限于自己的”知识库”,而是能够动态地获取信息、执行操作。这是构建真正有用AI应用的关键。
三、Node间的数据传递——State的秘密
现在你已经了解了三种Node类型,但可能还有一个疑问:Node之间是如何传递信息的?
答案是:State(状态)。
3.1 什么是State?
State是一个共享的数据容器,所有的Node都可以读取和修改它。你可以把它想象成餐厅里的订单小票——服务员写下客人的需求,厨师按照小票做菜,收银员根据小票结账,每个人都看得到同一张小票上的信息。
在LangGraph中,State通常用TypedDict来定义,这样既能明确字段类型,又能享受类型提示的好处。
1 | from typing import TypedDict, List |
3.2 从State读取数据
每个Node的函数签名都接收state作为参数,你可以直接访问其中的字段:
1 | def read_example(state: ConversationState) -> ConversationState: |
3.3 向State写入数据
Node可以修改State,这些修改会自动传递给下一个Node:
1 | def write_example(state: ConversationState) -> ConversationState: |
3.4 重要注意事项
State是 mutable(可变的):虽然你可以直接修改state,但建议始终返回修改后的state,这是一个好的编程习惯。
字段默认值:如果某个字段可能不存在,使用get方法提供默认值,避免KeyError。
1 | # 好的做法 |
四、实战:天气查询助手
理论讲得再多,不如动手实践。下面我们来构建一个完整的天气查询助手,它结合了LLM节点和工具节点,能够:
- 理解用户的自然语言查询
- 提取城市名称
- 调用天气API获取实时天气
- 生成友好的回复
4.1 完整代码
1 | #!/usr/bin/env python3 |
4.2 代码逐行讲解
第1-10行:导入和配置
- 导入必要的库,包括LangGraph的核心组件和OpenAI的客户端
- 设置环境变量用于存储API密钥(安全考虑,不要硬编码)
第12-63行:定义工具
- 使用
@tool装饰器定义两个工具:get_weather和get_weather_advice - 每个工具都有清晰的文档字符串,说明参数和返回值
- 工具的本质就是函数,可以是任何Python逻辑
第65-72行:定义State
- 使用
TypedDict定义状态结构 Annotated用于添加类型元数据,让代码更易读- State包含:消息列表、城市名、天气信息、最终回复
第74-82行:初始化LLM
- 创建ChatOpenAI实例,指定模型和温度参数
- 使用
bind_tools将工具”绑定”到LLM,让LLM知道可以调用哪些工具
第84-203行:定义节点函数
这是整个程序的核心,定义了6个节点:
extract_city_node:从用户输入中提取城市名agent_node:AI决策节点,决定调用工具还是直接回复tool_executor_node:执行AI调用的工具generate_response_node:生成最终友好回复ask_for_city_node:当没有识别到城市时询问用户check_city_node和should_continue:条件判断函数,决定流程走向
第205-245行:构建图
- 创建
StateGraph实例 - 使用
add_node添加所有节点 - 使用
set_entry_point设置入口 - 使用
add_edge和add_conditional_edges连接节点 - 最后用
compile编译成可执行的图
第247-290行:运行和测试
chat_with_weather_assistant函数封装了完整的对话流程- 主程序中运行预设测试用例
4.3 运行结果示例
1 | 🌤️ LangGraph 天气查询助手 🌤️ |
五、Node设计最佳实践
通过上面的实战,相信你对Node有了更深的理解。下面分享一些设计Node的最佳实践,帮助你写出更好的代码。
5.1 单一职责原则
每个Node只做一件事。不要把太多逻辑塞到一个Node里。
❌ 不好的做法:
1 | def messy_node(state): |
✅ 好的做法:
1 | def parse_input(state): pass |
5.2 完善的错误处理
Node可能遇到各种错误,要做好防护:
1 | def robust_node(state: MyState) -> MyState: |
5.3 添加日志记录
日志是调试的利器,特别是在复杂的图流程中:
1 | import logging |
5.4 使用类型提示
类型提示不仅能让代码更易读,还能在IDE中享受自动补全:
1 | from typing import TypedDict, Literal |
5.5 保持State的扁平化
尽量避免过深的嵌套结构,让State保持扁平:
❌ 避免:
1 | {"user": {"profile": {"name": "", "age": 0}}} |
✅ 推荐:
1 | {"user_name": "", "user_age": 0} |
5.6 命名要清晰
Node和State字段的命名要见名知意:
❌ 避免:
1 | builder.add_node("n1", f1) |
✅ 推荐:
1 | builder.add_node("extract_keywords", extract_keywords) |
六、总结与下篇预告
6.1 本文回顾
通过这篇文章,我们学习了:
- 什么是Node:LangGraph的基本构建单元,就像餐厅里的不同角色
- 三种Node类型:
- 函数节点:灵活的基础砖块
- LLM节点:AI的大脑
- 工具节点:连接外部世界的桥梁
- 数据传递:通过State在Node间共享数据
- 实战项目:完整的天气查询助手,展示了如何组合不同类型的Node
- 最佳实践:单一职责、错误处理、日志记录等
6.2 核心要点
- Node是LangGraph的核心概念,掌握Node就掌握了构建复杂AI应用的基础
- 选择合适的Node类型:简单逻辑用函数节点,需要AI决策用LLM节点,需要外部能力用工具节点
- State是Node间的”通信协议”,设计好State结构很重要
- 实际项目中,Node的设计要遵循单一职责原则,做好错误处理
6.3 下篇预告
在下一篇文章中,我们将深入探讨Tool Calling——
如果说Node是餐厅里的员工,那么Edge就是员工之间传递信息的通道和规则。我们会学习:
- 什么是条件边(Conditional Edge)
- 如何实现循环和分支逻辑
- 如何构建多轮对话
- 实战:构建一个更复杂的多Agent协作系统
参考资源:
希望这篇文章能帮助你入门LangGraph!如果有任何问题,欢迎在评论区留言交流。
📚 LangGraph 入门系列
本系列共10篇文章,带你从零掌握 LangGraph:
| 篇目 | 标题 | 链接 |
|---|---|---|
| 01 | LangGraph 是什么? | 阅读 |
| 02 | State 状态管理 | 阅读 |
| 03 | Node 节点 | 阅读 |
| 04 | Tool Calling | 阅读 |
| 05 | Memory 记忆系统 | 阅读 |
| 06 | HITL 人机协作 | 阅读 |
| 07 | Multi-Agent | 阅读 |
| 08 | Streaming 流式输出 | 阅读 |
| 09 | Conditional Edges | 阅读 |
| 10 | Production 生产部署 | 阅读 |
当前位置: 第3篇 / 共10篇
- 上一篇:State 状态管理
- 下一篇:Tool Calling









