一 LangGraph 概述
是什么
LangGraph 是基于 LangChain 构建、用于开发 AI 智能体的图结构编排框架,通过状态图管理多节点、多步骤的复杂交互。
核心特点
- 图形化工作流:用有向图组织流程,支持循环、条件分支
- 内置状态持久化:自动保存执行状态与进度
- 支持循环调用:可让智能体反复调用工具、自我修正
- 可接入人工干预:支持人工审核、介入决策
- 统一状态管理:全局共享 State,实现节点间无缝通信
LangGraph 与 LangChain 的区别
- LangChain:基础组件库,适合简单线性流程,内存、持久化需手动实现
- LangGraph:高级编排层,自带状态管理、循环工作流、人工监督等复杂能力
关键组件(白话版)
- 节点(Nodes):执行具体任务的单元(工具、LLM、函数等)
- 边(Edges):定义节点执行顺序与跳转逻辑
- 状态(State):全局共享数据,负责节点之间的信息传递
二 LangGraph CLI 核心信息提取
LangGraph CLI 是一个多平台命令行工具,用于在本地构建和运行 LangGraph API 服务器。生成的服务器包含图的所有运行、线程、助手等的 API 端点,以及运行代理所需的其他服务(包括检查点相关服务)。
2.1 核心命令与功能
| 命令 | 描述 |
|---|---|
langgraph build | 构建一个可直接部署的 LangGraph API 服务器的 Docker 镜像。 |
langgraph dev | 启动一个轻量级开发服务器,无需 Docker 安装。适合快速开发和测试,该功能在 0.1.55 及更高版本中可用。 |
langgraph dockerfile | 生成一个 Dockerfile,可用于为 LangGraph API 服务器构建镜像并部署实例。适合需要进一步定制 Dockerfile 或自定义部署的场景。 |
langgraph up | 在本地 Docker 容器中启动一个 LangGraph API 服务器实例,要求本地 Docker 服务器正常运行。本地开发需要 LangSmith API 密钥,生产使用需要许可证密钥。 |
补充说明
langgraph dev是无 Docker 依赖的开发模式,适合本地快速迭代;langgraph up是基于 Docker 的完整环境,更贴近生产部署。langgraph dockerfile用于自定义构建,满足个性化部署需求。- 生产环境部署需许可证密钥,本地开发需 LangSmith API 密钥。
2.2 创建 Python虚拟环境
- 安装好 python 解释器:
Python >= 3.11 is required. - 安装虚拟环境库,在 cmd 中输入:
pipinstallvirtualenv - 创建虚拟环境,在 cmd 中切换到需要创建虚拟环境的目录下,执行:
(示例:virtualenv env_nameD:\python-3.9\Scripts\virtualenv fastapi_env) - 激活虚拟环境,在 cmd 中进入到第三步创建的
env_name/Scripts目录下,执行:
执行成功后,在 cmd 中,当前输入行前面会有activate(env_name)的前缀,在当前状态下,使用pip就是在虚拟环境中安装第三方库了 - 退出虚拟环境,cmd 中输入:
deactivate
2.3、安装 LangGraph CLI
要求:
Python >= 3.11 is required.
pipinstall--upgrade"langgraph-cli[inmem]"2.4、创建 LangGraph 应用
从new-langgraph-project-python模板或new-langgraph-project-js模板创建一个新应用。此模板演示了一个单节点应用,您可以根据自己的逻辑进行扩展。
注意:如果您使用langgraph new命令时未指定模板,将显示一个交互式菜单,允许您从可用模板列表中进行选择。
langgraph new path/to/your/app--templatenew-langgraph-project-python2.5、安装项目依赖
在您的新 LangGraph 应用的根目录下,以编辑模式安装依赖项,以便服务器使用您的本地更改。
在 LangGraph 中,pyproject.toml代传统的setup.py和requirements.txt,可包含以下扩展配置:
- 依赖分组:如
[project.optional-dependencies]定义dev(开发工具)和test(测试框架)依赖。 - 动态版本控制:通过
requires-python = ">=3.9"指定 Python 版本兼容性。 - CI/CD 集成:通过
[tool.*]配置与 GitHub Actions 或 GitLab CI 的交互
安装命令
cdpath/to/your/app pipinstall-e.2.6、修改graph.py的代码
示例代码(本地私有部署大模型)
# 本地私有化部署的大模型llm=ChatOpenAI(model='qwen3-8b',temperature=0.8,api_key='xx',base_url="http://localhost:6006/v1",extra_body={'chat_template_kwargs':{'enable_thinking':False}},)defget_weather(city:str)->str:"""Get weather for a given city."""returnf"It's always sunny in{city}!"graph=create_react_agent(llm,tools=[get_weather],prompt="You are a helpful assistant")2.7、启动 LangGraph 服务器
langgraph dev命令以内存模式启动 LangGraph 服务器。此模式适用于开发和测试目的。对于生产用途,请部署 LangGraph 服务器并使其能够访问持久存储后端。
启动命令
langgraph dev完整参数选项表
| 选项 | 默认值 | 描述 |
|---|---|---|
-c, --config 文件 | langgraph.json | 声明依赖项、图和环境变量 |
--host TEXT | 127.0.0.1 | 服务器绑定的主机 |
--port 整数 | 2024 | 服务器绑定的端口 |
--no-reload | - | 禁用自动重载 |
--n-jobs-per-worker 整数 | - | 每个工作进程的作业数 |
--debug-port 整数 | - | 调试器监听的端口 |
--wait-for-client | FALSE | 等待调试器客户端连接 |
--no-browser | - | 服务器启动时跳过自动打开浏览器 |
示例输出
> Ready! > - API: http://localhost:2024 > - Docs: http://localhost:2024/docs > - LangGraph Studio Web UI: https://smith.langchain.com/studio/?baseUrl=http://...三 Tool工具的定义
工具核心属性表
| 属性 | 类型 | 描述 |
|---|---|---|
| 名称 | str | 在提供给 LLM 或代理的一组工具中必须是唯一的。 |
| 描述 | str | 描述工具的作用,被 LLM 或代理用作上下文。 |
args_schema | pydantic.BaseModel | 可选但推荐,如果使用回调处理程序则为必需。它可用于为预期参数提供更多信息(例如,少量示例)或验证。 |
return_direct | boolean | 仅与代理相关。当为True时,在调用给定工具后,代理将停止并将结果直接返回给用户。 |
如果工具具有精心选择的名称、描述和args_schema,模型将表现得更好。
LangChain 支持的工具创建方式
- 函数
- LangChain Runnables
- 通过从
BaseTool子类化– 这是最灵活的方法,它提供了最大的控制程度,但代价是需要付出更多的努力和编写更多的代码。
3.1、从函数创建工具
这个@tool装饰器是定义自定义工具的最简单方法。默认情况下,装饰器使用函数名作为工具名称,但可以通过将字符串作为第一个参数传递来覆盖。此外,装饰器将使用函数的文档字符串作为工具的描述 - 因此必须提供文档字符串。请注意,@tool支持解析注释、嵌套模式和其他特性。
3.11@tool装饰器
classCalculateArgs(BaseModel):a:float=Field(description="第一个需要输入的数字。")b:float=Field(description="第二个需要输入的数字。")operation:str=Field(description="运算类型,只能是add、subtract、multiply和divide中的任意一个。")@tool('calculate',args_schema=CalculateArgs)defcalculate(a:float,b:float,operation:str)->float:"""工具函数:计算两个数字的运算结果"""print(f"调用 calculate 工具,第一个数字:{a},第二个数字:{b},运算类型:{operation}")result=0.0matchoperation:case"add":result=a+bcase"subtract":result=a-bcase"multiply":result=a*bcase"divide":ifb!=0:result=a/belse:raiseValueError("除数不能为零")returnresult@tool('calculate')defcalculate(a:Annotated[float,'第一个需要输入的数字。'],b:Annotated[float,'第二个需要输入的数字。'],operation:Annotated[str,'运算类型,只能是add、subtract、multiply和divide中的任意一个。'])->float:"""工具函数:计算两个数字的运算结果"""print(f"调用 calculate 工具,第一个数字:{a},第二个数字:{b},运算类型:{operation}")result=0.0matchoperation:case"add":result=a+bcase"subtract":result=a-bcase"multiply":result=a*bcase"divide":ifb!=0:result=a/belse:raiseValueError("除数不能为零")returnresultprint(calculate.name)print(calculate.description)print(calculate.args)print(calculate.args_schema.schema_json())fromlangchain_core.toolsimporttool@tool('calculate')defcalculate4(a:float,b:float,operation:str)->float:""" 工具函数:计算两个数字的运算结果 Args: a: 第一个需要输入的数字。 b: 第二个需要输入的数字。 operation: 运算类型,只能是add、subtract、multiply和divide中的任意一个。 Returns: 返回两个输入数字的运算结果。 """print(f"调用 calculate 工具,第一个数字:{a},第二个数字:{b},运算类型:{operation}")result=0.0ifoperation=="add":result=a+belifoperation=="subtract":result=a-belifoperation=="multiply":result=a*belifoperation=="divide":ifb==0:raiseValueError("除数不能为零")result=a/breturnresult3.12@tool装饰器StructuredTool.from_function创建agent
fromlangchain_core.toolsimportStructuredTool# 假设 calculate5 是同步计算函数,calculate6 是异步计算函数calculater=StructuredTool.from_function(func=calculate5,name="calculater",description="工具函数:计算两个数字的运算结果",return_direct=False,coroutine=calculate6)| 参数 | 作用 |
|---|---|
func=calculate5 | 绑定同步版本的计算函数,用于同步调用场景 |
name="calculater" | 工具的唯一名称,供 LLM 识别和调用 |
description="工具函数:计算两个数字的运算结果" | 工具功能描述,作为 LLM 调用工具的上下文依据 |
return_direct=False | 工具执行结果是否直接返回给用户(False表示结果会再交给 LLM 处理) |
coroutine=calculate6 | 绑定异步版本的计算函数,用于异步调用场景,实现同步/异步双支持 |
补充说明
StructuredTool.from_function()是 LangChain 中手动创建结构化工具的经典方式,相比@tool装饰器,支持更灵活的配置(如同步/异步双实现、自定义参数校验等)- 该写法可以同时兼容同步和异步调用,适配不同的运行环境(如 FastAPI 异步接口、同步脚本)
- 完整使用需要先定义
calculate5(同步)和calculate6(异步)两个函数,示例如下:
# 同步函数defcalculate5(a:float,b:float,operation:str)->float:"""计算两个数字的运算结果(同步版)"""# 运算逻辑...# 异步函数asyncdefcalculate6(a:float,b:float,operation:str)->float:"""计算两个数字的运算结果(异步版)"""# 运算逻辑...