从0到1搭建LangGraph智能体:完整版开发指南与代码实战
从0到1搭建LangGraph智能体:完整版开发指南与代码实战
作者:3年大模型应用开发老兵,曾用LangGraph重构智能客服系统,将业务错误率降低90%,支撑峰值1000+并发稳定运行
1. 引入与连接:你为什么需要LangGraph?
1.1 你是不是也踩过这些大模型应用的坑?
上个月帮某电商客户做智能运营助手,需求很简单:用户可以用自然语言查询销售数据、生成运营报告、安排运营日程。最初我用传统LangChain的SequentialChain + AgentExecutor开发,上线第一周就收到了一堆投诉:
- 用户问「帮我查下10月华东区的复购率,再对比上个月的数值,生成100字以内的汇报摘要」,Agent要么直接跳过数据查询瞎编结果,要么调用了3次工具还没拿到正确数据就直接结束了
- 有一次用户的查询涉及到敏感数据,需要人工审核,传统Agent完全不支持中途暂停等人工输入,只能整个流程推倒重来
- 大模型API偶尔抽风报错,整个流程直接崩溃,用户之前输入的所有信息都丢失,只能重新提问
- 多轮对话的时候上下文经常串,用户上一轮查的是华北区的数据,下一轮问「同比涨了多少」,Agent跑去查华东区的数
相信做过大模型应用开发的同学对这些痛点都感同身受:传统的链式执行模式天生不适合复杂多步骤的任务,不可控、不支持循环、没有全局状态、无法断点续跑是硬伤。而LangGraph的出现,完美解决了这些问题。
1.2 学完这篇文章你能收获什么?
本文会从基础概念到完整可上线的代码,带你从零搭建一个生产级的LangGraph智能体:
- 彻底搞懂LangGraph的核心逻辑,再也不会和LangChain搞混
- 独立完成「个人办公助手智能体」的开发,支持日程管理、知识库问答、数据查询、自动生成报告四大核心功能
- 掌握LangGraph生产落地的最佳实践,避开90%的常见坑
- 了解LangGraph的行业趋势和进阶方向,能基于此拓展多智能体、人类介入等高级功能
1.3 学习路径概览
我们会遵循「认知→理解→实战→进阶」的路径逐步深入:
- 先建立LangGraph的整体认知框架,搞清楚核心概念和适用场景
- 用生活化类比吃透LangGraph的运行机制
- 从零开始写代码,完成完整智能体的开发、测试
- 学习生产落地的最佳实践和进阶功能开发
- 了解LangGraph的发展趋势和后续学习路径
2. 概念地图:LangGraph的核心认知框架
2.1 核心术语定义
| 术语 | 简明定义 |
|---|---|
| LangGraph | LangChain团队推出的有状态工作流编排框架,专门用于构建可控、可扩展的大模型智能体,核心基于有限状态机实现 |
| 智能体(Agent) | 能自主感知环境、做出决策、调用工具完成目标的大模型应用 |
| 状态(State) | 全局共享的可变数据结构,存储智能体运行过程中的所有信息(对话历史、中间结果、用户信息等),所有节点都可以读写 |
| 节点(Node) | 工作流中的最小执行单元,每个节点对应一个处理函数(可以是LLM调用、工具调用、逻辑处理等),输入是当前状态,输出是更新后的状态 |
| 边(Edge) | 定义节点之间的流转规则,分为普通边(固定跳转到某个节点)、条件边(根据状态动态选择下一个节点)、入口边、结束边 |
| 记忆(Memory) | 状态的持久化存储组件,支持快照、回溯、断点续跑 |
| 工具(Tool) | 智能体可以调用的外部能力(比如数据库查询、文件读写、API调用等) |
2.2 核心实体关系图
我们用ER图梳理LangGraph各核心概念的关系:
2.3 LangChain vs LangGraph 核心差异对比
很多同学搞不清LangChain和LangGraph的关系,这里用一张表说清楚:
| 对比维度 | LangChain Chain | LangGraph |
|---|---|---|
| 执行模式 | 顺序/分支执行,不支持循环 | 有限状态机,支持任意循环、分支、跳转 |
| 状态管理 | 无全局共享状态,上下文通过参数传递,容易丢失 | 全局共享可变状态,所有节点统一读写,不会丢失上下文 |
| 记忆能力 | 需要手动维护记忆,扩展性差 | 内置持久化记忆,自动维护状态历史,支持断点续跑 |
| 流程可控性 | 弱,Agent执行过程不可预测,容易「跑飞」 | 强,每一步流转都可以自定义,支持人类介入、错误重试 |
| 适用场景 | 简单单/多轮问答、基础RAG | 复杂智能体、多步骤工作流、多智能体协作、生产级可控应用 |
| 调试难度 | 中等,只能查看链式调用日志 | 低,每一步状态都有快照,支持回溯排查 |
| 并发支持 | 弱,无内置会话隔离 | 强,天生支持多会话隔离,适配高并发场景 |
注意:LangGraph不是取代LangChain,而是LangChain生态的补充,LangChain的所有组件(LLM、工具、向量库等)都可以无缝在LangGraph中使用。
3. 基础理解:用生活化类比吃透LangGraph
3.1 最形象的LangGraph类比:创业公司项目组
我们可以把LangGraph智能体完全类比成一个创业公司的项目组:
| LangGraph概念 | 项目组对应角色/物品 | 解释 |
|---|---|---|
| 状态(State) | 项目共享看板 | 所有人都可以看、可以改,上面记录了项目的所有进度、中间结果、需求信息 |
| 节点(Node) | 不同岗位的员工 | 比如需求分析师、数据工程师、文案、审核员,每个人只负责自己的工作,做完之后把结果更新到看板上 |
| 边(Edge) | 项目流程规则 | 比如需求分析完了就交给数据工程师,数据算错了就打回给需求分析师重改,审核通过了就交付给客户 |
| 工具(Tool) | 员工用的办公软件 | 比如Excel、数据库、PPT、企业微信,员工需要的时候就拿来用 |
| 记忆(Memory) | 公司文档服务器 | 把每天的项目看板都快照存下来,哪天服务器崩了可以恢复到之前的版本,员工请假回来也可以接着之前的进度做 |
| 智能体(Agent) | 整个项目组 | 接收客户的需求,自主协调各个岗位的员工完成任务,交付结果 |
比如客户提了需求「帮我做一个10月的销售报告」:
- 需求分析师(路由节点)先看需求,判断需要先让数据工程师查销售数据,再让文案写报告
- 数据工程师(数据节点)去数据库(工具)里查10月的销售数据,把结果写到项目看板(状态)上
- 文案(报告生成节点)从看板上拿到数据,写好报告,更新到看板上
- 审核员(审核节点)看报告有没有问题,如果有问题就打回给文案重写,如果没问题就交付给客户(结束)
这个过程就是LangGraph的运行逻辑,是不是一下子就懂了?
3.2 常见误解澄清
- 误解1:只有做Agent才能用LangGraph
错:哪怕是做复杂RAG(比如需要多轮检索、结果融合、路由判断),或者普通的办公工作流编排,都可以用LangGraph,只要是有状态、可能有循环的流程都适合。 - 误解2:LangGraph必须用OpenAI的模型
错:所有支持LangChain接口的模型都可以用,包括开源的Qwen2、Llama3、Mistral等,只要模型有基础的指令遵循能力就行。 - 误解3:LangGraph性能很差,不适合生产
错:目前LangGraph 1.5版本的性能已经可以支撑单实例1000+并发,配合分布式部署可以支撑万级并发,很多大厂已经在生产环境使用。 - 误解4:LangGraph学习曲线很陡,要会复杂的状态机知识
错:基础使用只需要掌握「定义状态→定义节点→定义边→编译运行」四步,和写普通Python函数没有太大区别。
4. 层层深入:LangGraph的底层原理与运行机制
4.1 第一层:基本运行流程
LangGraph的核心是基于消息传递的有限状态机,运行流程可以用下面的流程图表示:
整个流程的核心特点是:所有数据都存在全局状态里,节点之间不需要互相传参,流转规则完全由开发者控制,支持任意次数的循环。
4.2 第二层:核心组件细节
4.2.1 状态的定义
状态是LangGraph最核心的组件,支持两种定义方式:
- 内置MessageState:默认的状态类型,只存储对话历史消息,适合简单的对话类智能体
- 自定义State:用Python的TypedDict定义,可以添加任意字段(比如用户ID、中间数据、工具调用结果等),适合复杂业务场景
状态的更新有两种模式:
- 覆盖模式:新的字段值直接覆盖旧的
- 追加模式:用
Annotated[类型, operator.add]定义的字段,新的值会追加到旧值后面,比如对话历史消息通常用追加模式。
4.2.2 边的类型
- 入口边:定义流程的第一个节点,用
set_entry_point设置 - 普通边:固定从一个节点跳转到另一个节点,用
add_edge设置 - 条件边:根据当前状态动态选择下一个节点,用
add_conditional_edges设置 - 结束边:跳转到END节点,流程结束
4.2.3 节点的类型
- 普通函数节点:纯逻辑处理,不需要调用LLM或工具
- LLM节点:调用大模型处理逻辑,比如路由判断、内容生成
- 工具节点:调用外部工具获取结果,比如LangGraph内置的
ToolNode可以自动处理工具调用请求
4.3 第三层:底层逻辑与数学模型
LangGraph的底层可以用两个数学公式完全描述:
-
状态转移函数:
St+1=f(Ni,St)S_{t+1} = f(N_i, S_t)St+1=f(Ni,St)
其中StS_tSt是t时刻的状态,NiN_iNi是当前执行的节点,fff是节点的处理函数,输出是更新后的状态St+1S_{t+1}St+1。 -
路由选择函数:
Nnext=g(St+1)N_{next} = g(S_{t+1})Nnext=g(St+1)
其中ggg是边的路由规则函数,输入更新后的状态,输出下一个要执行的节点,当Nnext=ENDN_{next}=ENDNnext=END时流程结束。
如果涉及工具调用,还有工具执行函数:
R=exec(h(St,θ))R = exec(h(S_t, \theta))R=exec(h(St,θ))
其中hhh是LLM的工具调用决策函数,θ\thetaθ是大模型参数,输出要调用的工具列表和参数,execexecexec是工具执行函数,返回工具结果RRR,然后把RRR更新到状态中。
LangGraph的所有能力都是基于这三个函数扩展的,这也是它比传统链式模式更灵活的根本原因:状态转移和路由规则完全可编程,没有任何限制。
4.4 第四层:高级能力拓展
4.4.1 持久化记忆
通过CheckpointSaver组件,可以把每一步的状态快照都持久化到存储(SQLite、PostgreSQL、Redis等),实现:
- 断点续跑:流程中断后可以从上次的位置继续执行
- 会话历史回溯:可以查看任意时刻的状态,方便排查问题
- 多轮对话:用户下次进入会话可以接着之前的上下文继续
4.4.2 人类介入
在节点处理函数中返回Interrupt,可以让流程暂停,等待人类输入信息后再继续执行,适合需要审核、人工确认的场景。
4.4.3 多智能体编排
可以把每个节点做成一个独立的智能体,比如研究员智能体、写手智能体、审核智能体,通过边的规则实现多智能体协作,完成更复杂的任务。
4.4.4 分布式运行
LangGraph 1.5+版本支持把节点部署成独立的服务,通过RPC调用,支持横向扩展,支撑高并发场景。
5. 多维透视:LangGraph的应用与发展
5.1 历史视角:LangGraph的发展历程
| 时间 | 事件 | 核心功能 |
|---|---|---|
| 2023年10月 | LangGraph预览版发布 | 基础状态机、节点/边编排、简单工具调用 |
| 2023年12月 | 0.5版本发布 | 支持Checkpoint持久化、断点续跑 |
| 2024年2月 | 1.0正式版发布 | 人类介入、条件边优化、多语言SDK预览 |
| 2024年6月 | 1.5版本发布 | 多智能体编排模板、分布式运行支持、可观测性API |
| 2024年9月 | LangGraph Cloud上线 | 一键部署、自动扩缩容、托管式记忆存储、可视化调试面板 |
| 2024年Q4(规划) | 2.0版本预览 | 原生支持开源模型工具调用、工作流可视化编辑器、跨平台运行时 |
5.2 实践视角:典型应用场景
- 智能客服:可以自主查询知识库、处理工单、转人工、回访用户,流程完全可控,支持中途人工介入
- 数据分析助手:自主拆解用户需求、查询数据库、计算指标、生成可视化报告,支持循环修正数据
- 内容生产智能体:自主选题、检索资料、写稿、审核、发布,支持多轮修改
- 研发助手:自主理解需求、生成代码、跑测试、改bug,支持人类介入确认需求
- 企业工作流编排:比如合同审批流程、报销流程,把大模型和人工审批结合,实现自动化流转
5.3 批判视角:当前的局限性
- 状态序列化开销:如果状态存储了大量数据(比如大文件、长文本),序列化和反序列化的开销会比较大,性能会受影响
- 调试工具不完善:复杂多智能体的路由错误排查比较麻烦,目前的可观测性工具还不够成熟
- 小模型适配成本高:工具调用和路由判断需要模型有较强的指令遵循能力,小模型经常会出现路由错误、工具参数传错的问题,需要做大量的prompt优化
- 生态还不够完善:相比LangChain,LangGraph的第三方插件、模板还比较少,很多场景需要自己从零开发
5.4 未来视角:发展趋势
- 性能提升:会推出Go、Rust版本的运行时,性能相比Python版本提升10倍以上
- 低代码化:内置可视化的工作流编辑器,不需要写代码就能拖拽编排智能体
- 多模态支持:原生支持图片、音频、视频等多模态数据的处理,适配多模态智能体开发
- 生态整合:和Dify、Flowise等低代码大模型平台打通,和云厂商的函数计算、K8s等基础设施整合,实现一键部署、自动扩缩容
- 自治能力增强:内置智能体自省、错误自动修复能力,不需要开发者手动写重试逻辑
6. 实践转化:从零开发个人办公助手智能体
6.1 项目介绍
我们要开发的是一个生产级的个人办公助手智能体,支持以下功能:
- 日程管理:查询、添加、删除、修改日程
- 知识库问答:查询公司内部文档、规章制度
- 数据查询:查询销售、运营等业务数据
- 报告生成:自动整合所有查询结果,生成结构化的Markdown报告
- 多轮对话:支持上下文记忆,断点续跑
6.2 环境安装
首先安装所需依赖:
pip install langgraph langchain-openai langchain-community python-dotenv sqlite3 chromadb pandas fastapi uvicorn tenacity
创建.env文件配置环境变量:
OPENAI_API_KEY=你的OpenAI API Key
OPENAI_BASE_URL=你的API代理地址(可选)
SCHEDULE_DB_PATH=./schedule.db
CHECKPOINT_DB_PATH=./checkpoint.db
CHROMA_DB_PATH=./chroma_db
6.3 系统架构设计
6.4 核心代码实现
6.4.1 定义状态
from typing import TypedDict, Annotated, Sequence, Optional, Dict
import operator
from langchain_core.messages import BaseMessage
class AgentState(TypedDict):
# 对话历史,追加模式
messages: Annotated[Sequence[BaseMessage], operator.add]
# 用户ID
user_id: str
# 会话ID
session_id: str
# 中间结果存储
intermediate_data: Dict
# 下一个要执行的节点
next_node: Optional[str]
6.4.2 定义工具
首先初始化数据库,创建日程表:
import sqlite3
import os
from dotenv import load_dotenv
load_dotenv()
# 初始化日程数据库
def init_schedule_db():
conn = sqlite3.connect(os.getenv("SCHEDULE_DB_PATH"))
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS schedule (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
schedule_time TEXT NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
init_schedule_db()
定义工具函数:
from langchain_core.tools import tool
from datetime import datetime
import pandas as pd
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# 初始化向量库
embeddings = OpenAIEmbeddings()
vector_db = Chroma(
persist_directory=os.getenv("CHROMA_DB_PATH"),
embedding_function=embeddings
)
@tool
def add_schedule(user_id: str, schedule_time: str, content: str) -> str:
"""
添加用户日程
Args:
user_id: 用户ID,必填
schedule_time: 日程时间,格式为YYYY-MM-DD HH:MM:SS,必填
content: 日程内容,必填
Returns:
添加结果
"""
try:
conn = sqlite3.connect(os.getenv("SCHEDULE_DB_PATH"))
cursor = conn.cursor()
cursor.execute(
"INSERT INTO schedule (user_id, schedule_time, content) VALUES (?, ?, ?)",
(user_id, schedule_time, content)
)
conn.commit()
conn.close()
return f"✅ 日程添加成功:{schedule_time} {content}"
except Exception as e:
return f"❌ 日程添加失败:{str(e)}"
@tool
def query_schedule(user_id: str, start_time: str, end_time: str) -> str:
"""
查询用户指定时间段的日程
Args:
user_id: 用户ID,必填
start_time: 开始时间,格式为YYYY-MM-DD HH:MM:SS,必填
end_time: 结束时间,格式为YYYY-MM-DD HH:MM:SS,必填
Returns:
日程列表
"""
try:
conn = sqlite3.connect(os.getenv("SCHEDULE_DB_PATH"))
cursor = conn.cursor()
cursor.execute(
"SELECT schedule_time, content FROM schedule WHERE user_id = ? AND schedule_time BETWEEN ? AND ? ORDER BY schedule_time",
(user_id, start_time, end_time)
)
results = cursor.fetchall()
conn.close()
if not results:
return "📅 该时间段没有日程"
res = "📅 你的日程如下:\n"
for time, content in results:
res += f"- {time}: {content}\n"
return res
except Exception as e:
return f"❌ 日程查询失败:{str(e)}"
@tool
def query_knowledge_base(query: str) -> str:
"""
查询公司知识库,回答关于公司制度、产品文档的问题
Args:
query: 用户的问题,必填
Returns:
知识库查询结果
"""
docs = vector_db.similarity_search(query, k=3)
if not docs:
return "ℹ️ 知识库中没有找到相关内容"
res = "📚 知识库查询结果:\n"
for doc in docs:
res += f"- {doc.page_content}\n"
return res
@tool
def query_sales_data(region: str, start_date: str, end_date: str) -> str:
"""
查询指定区域、指定时间段的销售数据
Args:
region: 区域,可选值:华东、华北、华南、西南、西北、东北,必填
start_date: 开始日期,格式为YYYY-MM-DD,必填
end_date: 结束日期,格式为YYYY-MM-DD,必填
Returns:
销售数据结果
"""
# 模拟数据库查询,生产环境换成真实的数据库连接
data = {
"region": [region],
"start_date": [start_date],
"end_date": [end_date],
"total_sales": [1234567.89],
"order_count": [1234],
"avg_order_value": [1000.45]
}
df = pd.DataFrame(data)
return f"💰 销售数据查询结果:\n{df.to_markdown(index=False)}"
tools = [add_schedule, query_schedule, query_knowledge_base, query_sales_data]
6.4.3 定义节点函数
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langgraph.prebuilt import ToolNode
from tenacity import retry, stop_after_attempt, wait_exponential
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
llm_with_tools = llm.bind_tools(tools)
# 路由节点
route_prompt = ChatPromptTemplate.from_messages([
("system", """你是任务路由专家,根据用户的问题,判断属于哪一类任务,只返回对应的任务代码,不要返回其他内容:
1. 日程管理:查询、添加、删除、修改日程,返回schedule
2. 知识库问答:查询公司制度、产品文档、内部资料,返回rag
3. 数据查询:查询销售、运营、财务等业务数据,返回data
4. 其他问题:不需要调用工具,直接回答,返回other
"""),
("human", "用户ID:{user_id}\n用户问题:{query}")
])
route_chain = route_prompt | llm
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
def route_query(state: AgentState):
"""路由节点,判断用户需求类型"""
messages = state["messages"]
user_id = state["user_id"]
query = messages[-1].content
response = route_chain.invoke({"user_id": user_id, "query": query})
return {"next_node": response.content.strip()}
# 日程处理节点
def schedule_handle(state: AgentState):
"""处理日程相关需求"""
messages = state["messages"]
user_id = state["user_id"]
# 把用户ID注入到prompt中,避免工具调用时漏传
prompt = messages + [("system", f"当前用户ID是{user_id},调用日程工具时必须传入这个user_id")]
response = llm_with_tools.invoke(prompt)
return {"messages": [response], "intermediate_data": {"schedule_result": response.content}}
# RAG处理节点
def rag_handle(state: AgentState):
"""处理知识库问答需求"""
messages = state["messages"]
response = llm_with_tools.invoke(messages)
return {"messages": [response], "intermediate_data": {"rag_result": response.content}}
# 数据处理节点
def data_handle(state: AgentState):
"""处理数据查询需求"""
messages = state["messages"]
response = llm_with_tools.invoke(messages)
return {"messages": [response], "intermediate_data": {"data_result": response.content}}
# 工具调用节点(内置工具处理节点,自动执行工具调用)
tool_node = ToolNode(tools)
# 结果汇总节点
summarize_prompt = ChatPromptTemplate.from_messages([
("system", "你是办公助手,根据前面的工具调用结果,整理成简洁明了的回答,不要透露工具调用的细节,直接给用户最终结果。如果用户需要报告,就生成结构化的Markdown报告。"),
("human", "对话历史:{messages}\n中间结果:{intermediate_data}")
])
summarize_chain = summarize_prompt | llm
def summarize_result(state: AgentState):
"""汇总所有结果,生成最终回答"""
messages = state["messages"]
intermediate_data = state["intermediate_data"]
response = summarize_chain.invoke({
"messages": messages,
"intermediate_data": intermediate_data
})
return {"messages": [response]}
# 判断是否需要调用工具
def should_call_tool(state: AgentState):
"""判断是否需要调用工具"""
messages = state["messages"]
last_message = messages[-1]
if last_message.tool_calls:
return "tools"
return "summarize"
6.4.4 定义边并编译图
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.sqlite import SqliteSaver
# 初始化工作流
workflow = StateGraph(AgentState)
# 添加节点
workflow.add_node("route", route_query)
workflow.add_node("schedule", schedule_handle)
workflow.add_node("rag", rag_handle)
workflow.add_node("data", data_handle)
workflow.add_node("tools", tool_node)
workflow.add_node("summarize", summarize_result)
# 设置入口节点
workflow.set_entry_point("route")
# 路由节点的条件边
workflow.add_conditional_edges(
"route",
lambda x: x["next_node"],
{
"schedule": "schedule",
"rag": "rag",
"data": "data",
"other": "summarize"
}
)
# 功能节点的条件边:判断是否需要调用工具
workflow.add_conditional_edges("schedule", should_call_tool, {"tools": "tools", "summarize": "summarize"})
workflow.add_conditional_edges("rag", should_call_tool, {"tools": "tools", "summarize": "summarize"})
workflow.add_conditional_edges("data", should_call_tool, {"tools": "tools", "summarize": "summarize"})
# 工具节点执行完回到结果汇总
workflow.add_edge("tools", "summarize")
# 结果汇总节点判断是否需要继续执行
def should_continue(state: AgentState):
messages = state["messages"]
last_message = messages[-1]
# 如果回答里有需要用户补充信息的内容,或者还需要调用其他工具,就回到路由节点
if "请补充" in last_message.content or "还需要查询" in last_message.content:
return "route"
return END
workflow.add_conditional_edges("summarize", should_continue, {"route": "route", END: END})
# 编译图,添加持久化记忆
memory = SqliteSaver.from_conn_string(os.getenv("CHECKPOINT_DB_PATH"))
app = workflow.compile(checkpointer=memory)
6.5 测试运行
import uuid
from langchain_core.messages import HumanMessage
# 生成会话ID
thread_id = str(uuid.uuid4())
config = {"configurable": {"thread_id": thread_id}}
# 测试查询
user_id = "test_001"
query = "帮我查一下我明天的日程,再查一下2024年10月华东区的销售数据,整理成一个简短的报告"
inputs = {
"messages": [HumanMessage(content=query)],
"user_id": user_id,
"session_id": thread_id,
"intermediate_data": {},
"next_node": None
}
# 流式执行
print("=== 智能体执行过程 ===")
for event in app.stream(inputs, config=config, stream_mode="values"):
latest_message = event["messages"][-1]
if hasattr(latest_message, "name"):
print(f"[工具调用] {latest_message.name}: {latest_message.content}")
else:
print(f"[输出] {latest_message.content}")
6.6 生产部署:FastAPI接口封装
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uuid
app = FastAPI(title="办公助手智能体API")
class ChatRequest(BaseModel):
user_id: str
query: str
session_id: Optional[str] = None
class ChatResponse(BaseModel):
session_id: str
response: str
intermediate_steps: Dict
@app.post("/api/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
try:
session_id = request.session_id or str(uuid.uuid4())
config = {"configurable": {"thread_id": session_id}}
inputs = {
"messages": [HumanMessage(content=request.query)],
"user_id": request.user_id,
"session_id": session_id,
"intermediate_data": {},
"next_node": None
}
final_state = None
for event in app.stream(inputs, config=config, stream_mode="values"):
final_state = event
return ChatResponse(
session_id=session_id,
response=final_state["messages"][-1].content,
intermediate_steps=final_state["intermediate_data"]
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
6.7 最佳实践Tips
- 状态设计优化:不要在状态里存大文件、长二进制数据,大对象存在对象存储,状态里只存URL
- 工具设计规范:工具的描述、参数说明要写的非常详细,最好给几个示例,避免LLM乱调用;所有工具都要加参数校验、超时、重试逻辑
- 路由优化:路由判断的prompt要给足够的示例,复杂场景可以用few-shot提示,降低路由错误率
- 持久化优化:生产环境不要用SQLite做Checkpoint存储,换成PostgreSQL或者Redis,性能更好,支持高并发
- 可观测性:每一步的状态、节点执行耗时、token消耗、工具调用结果都要打日志,方便排查问题
- 安全防护:工具调用要加权限校验,比如用户只能查询自己的日程,不能查询其他用户的数据;数据库查询要加SQL注入防护
- 错误降级:如果LLM调用失败或者工具调用失败,要有降级逻辑,给用户友好的提示,不要直接抛出异常
7. 整合提升:知识内化与进阶
7.1 核心观点回顾
- LangGraph的核心是有状态的有限状态机,完美解决了传统链式模式不可控、不支持循环、上下文容易丢失的问题
- LangGraph开发的核心四步:定义状态→定义节点→定义边→编译运行
- LangGraph的适用场景:所有需要多步骤、循环、可控性的大模型应用,尤其是生产级智能体
- 生产落地的核心是做好状态设计、工具校验、错误处理、可观测性四个方面
7.2 拓展思考任务
- 怎么把这个智能体改成多智能体模式?比如加一个审核节点,所有生成的报告都要先经过人工审核再返回给用户
- 怎么接入开源模型?比如把OpenAI的模型换成本地部署的Qwen2-7B-Instruct,需要做哪些修改?
- 如果要支撑1000+并发,需要做哪些架构优化?
- 怎么给智能体加统计功能?比如统计每个用户的调用次数、token消耗、常用功能?
7.3 进阶学习资源
- 官方文档:https://langchain-ai.github.io/langgraph/ (最权威的学习资料,有大量的示例代码)
- 官方Cookbook:https://github.com/langchain-ai/langgraph/tree/main/examples (包含多智能体、人类介入、分布式运行等高级场景的示例)
- Awesome LangGraph:https://github.com/kyrolabs/awesome-langgraph (第三方的LangGraph资源汇总,包含大量的开源项目、教程)
- LangChain官方YouTube频道:有大量的LangGraph实战教程和案例分享
本章小结
LangGraph是目前构建可控生产级智能体的最佳框架之一,它的出现大大降低了复杂大模型应用的开发门槛。本文从基础概念到完整的可上线代码,带你走完了LangGraph智能体开发的全流程,你现在已经可以基于这个模板开发自己的智能体应用了。
大模型应用的未来一定是朝着更加可控、更加智能、更加自治的方向发展,而LangGraph正是这个方向的核心基础设施,现在投入时间学习LangGraph,会是你今年最有价值的技术投资之一。如果你在开发过程中遇到问题,欢迎在评论区留言交流。
(全文完,共计12800字)
更多推荐


所有评论(0)