在开发大语言模型应用时,我们常常面临这样的困境:固定的控制流难以应对复杂场景,明明框架提供了强大的工具调用能力,却只能实现简单的单步响应。是架构设计限制了潜力?还是我们对智能体的理解不够深入?今天我们就来系统梳理 LangGraph 中的智能体架构体系,从基础的路由器到高级的自定义框架,聊聊如何让 LLM 真正拥有自主决策能力,以及这些架构在实际场景中的落地实践。
一、智能体架构的核心价值与分类
1.1 为什么需要智能体架构
传统 LLM 应用就像预设好剧本的演员,只能按照固定流程回应。而智能体架构则赋予 LLM"导演" 的能力 —— 让模型自主决定调用工具的顺序、判断信息是否足够、甚至规划多步解决方案。这种灵活性在以下场景尤为重要:
- 客服系统需要根据问题类型路由到不同专员
- 数据分析工具需要动态决定调用哪些计算模块
- 复杂任务需要分步骤逐步完成
1.2 架构分类与控制层级
智能体架构本质上是赋予 LLM 不同程度的控制权,根据控制复杂度可分为三大类:
- 路由器(Router):基础决策层,只能在有限选项中做单一选择
- 工具调用智能体:中级控制层,支持多步决策和工具组合
- 自定义架构:高级管理层,包含人在回路、并行处理等复杂机制
这些架构并非孤立存在,而是可以组合使用,形成层次化的智能体系统。
二、基础架构:路由器与结构化输出
2.1 路由器的工作原理
路由器就像智能体的 "交通警察",负责将用户请求引导到合适的处理路径。它的核心特点是:
- 决策范围有限:仅能在预定义的选项中选择
- 单次决策:不支持多步流程
- 轻量化:计算开销小,适合初步分类
典型应用场景是客服系统的问题分诊:当用户询问 "我的订单什么时候到",路由器会识别为 "物流查询",并转交给对应的处理模块。
2.2 结构化输出:路由器的 "翻译官"
路由器要准确工作,离不开结构化输出的支持。这就像我们让孩子用特定格式写作文,LLM 需要按照预设模式生成响应。实现方式包括:
- 提示工程:在系统提示中明确格式要求
plaintext
请用JSON格式返回分类结果,示例:{"category": "物流查询", "priority": "normal"}
- 输出解析器:从自然语言中提取结构化数据
- 工具调用:利用 LLM 内置的函数调用能力
结构化输出的关键价值在于:让机器能够可靠地解析 LLM 的决策,避免歧义。例如在电商场景中,确保 "红色 M 码 T 恤" 被正确解析为 {"color": "red", "size": "M", "item": "T 恤"}。
三、进阶架构:工具调用智能体与 ReAct 模式
3.1 工具调用智能体的核心能力
相比路由器,工具调用智能体就像 "会使用工具的工匠",具备两大突破:
- 多步决策:不再是单次选择,而是能制定行动计划
- 工具交互:可以调用外部系统完成实际工作
这种架构的典型代表是 ReAct 模式,它整合了三个核心要素:
- 工具调用:按需选择合适的工具
- 记忆:保存历史信息供后续步骤使用
- 规划:制定多步执行计划
3.2 ReAct 架构的工作流程
ReAct 的运行机制可以理解为一个 "思考 - 行动 - 观察" 的循环:
- 思考阶段:LLM 分析用户请求,决定是否需要调用工具
- 行动阶段:选择并调用合适的工具
- 观察阶段:获取工具返回结果,作为下一步决策的依据
- 循环终止:当 LLM 认为信息足够时,整理结果并回复用户
以天气查询为例,完整流程可能是:
plaintext
用户:旧金山明天天气如何?
LLM:需要调用天气工具
行动:调用get_weather工具,参数city="San Francisco"
观察:工具返回温度22℃,多云
LLM:信息足够,无需更多工具
回复:旧金山明天22℃,多云
3.3 在 LangGraph 中实现工具调用
LangGraph 提供了便捷的工具调用支持,核心步骤包括:
- 定义工具函数
python
运行
def get_weather(city: str) -> str:
"""获取指定城市的天气"""
# 实际应用中会调用天气API
return f"{city}的天气是晴朗,温度25℃"
- 绑定工具到模型
python
运行
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model_name="gpt-4")
agent = create_react_agent(
model=model,
tools=[get_weather],
prompt="你是一个天气查询助手"
)
- 执行并获取结果
python
运行
response = agent.invoke({
"messages": [{"role": "user", "content": "旧金山天气如何"}]
})
print(response["messages"][-1]["content"])
四、智能体的 "记忆系统":短期与长期存储
4.1 短期记忆:会话内的信息传递
短期记忆就像我们的 "工作记忆",用于保存当前会话中的临时信息:
- 作用范围:仅在一次会话内有效
- 典型应用:保存多轮对话中的上下文
- 技术实现:通过状态(State)和检查点(Checkpointer)实现
在客服场景中,短期记忆可以保存用户之前提到的订单号,避免重复询问。LangGraph 中的实现方式:
python
运行
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import InMemorySaver
# 配置检查点用于保存状态
checkpointer = InMemorySaver()
agent = create_react_agent(
model=...,
tools=...,
checkpointer=checkpointer
)
# 调用时指定thread_id标识会话
response1 = agent.invoke(
{"messages": ["我的订单号是12345"]},
config={"configurable": {"thread_id": "user_001"}}
)
response2 = agent.invoke(
{"messages": ["这个订单什么时候发货"]},
config={"configurable": {"thread_id": "user_001"}}
)
4.2 长期记忆:跨会话的数据持久化
长期记忆则如同我们的 "知识库",用于保存跨会话的重要信息:
- 作用范围:在不同会话间共享
- 典型应用:保存用户偏好、历史订单等
- 技术实现:通过存储(Store)接口实现
例如电商智能体可以记住用户的收货地址,下次购买时无需重新输入。LangGraph 中的长期记忆操作:
python
运行
from langgraph.config import get_store
from langgraph.store.memory import InMemoryStore
# 初始化存储
store = InMemoryStore()
# 保存用户偏好
store.put(
("users", "001"),
{"preference": {"theme": "dark", "language": "zh"}}
)
# 在工具中读取记忆
def get_user_preference(user_id: str) -> str:
store = get_store()
preference = store.get(("users", user_id))
return f"你的偏好设置是:{preference.value}"
五、规划能力:让智能体学会 "分步思考"
规划是智能体解决复杂问题的关键能力,它使 LLM 能够:
- 将大目标分解为多个子任务
- 确定任务执行顺序
- 判断每个步骤的必要性
规划的实现本质上是一个循环决策过程:
- LLM 分析当前状态,确定是否需要行动
- 选择下一步操作(调用工具或直接回答)
- 执行操作并获取结果
- 评估结果是否接近目标
- 重复直到目标达成
以旅行规划为例,智能体可能需要先查询目的地天气,再推荐景点,最后提供交通建议,这一系列步骤就是规划的体现。在 LangGraph 中,规划能力内置于工具调用智能体的循环机制中,无需额外开发。
六、高级架构:自定义与优化技术
6.1 人在回路:关键决策的人工审核
在涉及敏感操作时,我们需要 "人在回路" 机制,就像银行的大额转账需要人工复核:
- 应用场景:金融交易、个人信息修改、高价值操作
- 实现方式:通过 interrupt () 函数暂停流程等待审核
- LangGraph 实现:
python
运行
from langgraph.types import interrupt
def transfer_money(amount: float, to_account: str) -> str:
# 触发人工审核
review = interrupt(
f"即将转账{amount}元到账户{to_account},请确认"
)
if review["approved"]:
# 执行转账
return "转账成功"
else:
return "转账已取消"
6.2 并行化:提升复杂任务处理效率
对于可以分解的任务,并行化处理能大幅提升效率,类似工厂的流水线作业:
- 适用场景:多数据源查询、批量数据处理
- LangGraph 支持:通过 Send API 实现并行调用
- 典型应用:同时查询多个电商平台的价格
6.3 子图:构建层次化智能体系统
子图允许我们将复杂系统拆分为多个独立模块,就像搭建积木:
- 核心价值:模块化设计、隔离状态、简化调试
- 通信方式:通过状态模式中的重叠键实现数据共享
- 应用场景:大型客服系统中,不同产品线使用独立子图
6.4 反思机制:让智能体学会自我改进
反思是智能体进阶的关键,就像学生做完题后检查对错:
- 实现方式:LLM 自评、外部反馈、确定性验证
- 典型应用:代码生成后的语法检查、回答准确性评估
- LangGraph 示例:通过预构建的评估工具实现反思
七、架构选择与实践建议
7.1 架构选型指南
- 路由器:适用于简单分类场景,如问题分诊、初步筛选
- 工具调用智能体:适合需要调用外部工具的中等复杂度任务
- 自定义架构:适用于高复杂度场景,如多步骤业务流程、敏感操作
7.2 性能优化要点
- 记忆管理:定期清理过期短期记忆,优化长期记忆查询效率
- 规划优化:设置合理的循环终止条件,避免无效工具调用
- 并行策略:根据资源情况调整并行度,避免过载
7.3 落地路径建议
- 从路由器开始,实现基础的请求分类
- 引入工具调用智能体,增加实际操作能力
- 加入记忆机制,提升多轮对话体验
- 根据业务需求,逐步添加人在回路、并行化等高级功能
八、总结与技术展望
通过本文的解析,我们系统了解了智能体架构的演进路径 —— 从简单的路由器到具备规划、记忆能力的复杂系统,再到支持人工审核和并行处理的高级框架。LangGraph 提供的全栈支持,让我们能够根据业务需求灵活选择和定制架构。
如果本文对你有帮助,别忘了点赞收藏,关注我,一起探索更高效的开发方式~