LangGraph SDK 全量技术手册:分布式 Agent 集群的远程调用与编排引擎

LangGraph SDK 全量技术手册:分布式 Agent 集群的远程调用与编排引擎

1. 技术概论

LangGraph SDK 是与 LangGraph Server / LangGraph Cloud 进行交互的官方客户端库(提供 Python 与 JavaScript 版本)。其核心价值在于实现 Agent 逻辑的前后端分离与分布式部署。通过该 SDK,开发者无需在业务服务中直接运行沉重的图计算逻辑,而是通过统一的 REST/WebSocket API 远程管理助手(Assistants)、线程(Threads)、运行实例(Runs)以及跨会话存储(Store),是构建高并发、可扩展企业级 AI 智能体服务的标准调用协议。


2. 全量 API 指南与组件字典(强类型版)

本节覆盖 langgraph_sdk 中的核心模块及全量 API 操作,主要基于异步客户端 AsyncLangGraphClient(同步客户端方法签名一致)。

2.1 客户端初始化与全局配置

API 原型 参数说明 输入/输出 功能简述
get_client(url: str, *, headers: dict = None) -> AsyncLangGraphClient url: Server 地址 headers: 认证头(如 API Key) : 异步客户端实例 初始化异步客户端,与 LangGraph 部署环境建立连接。
get_sync_client(url: str, *, headers: dict = None) -> LangGraphClient 同上 : 同步客户端实例 初始化同步客户端,适用于传统的阻塞式后台任务。

2.2 助手管理 API (client.assistants)

助手(Assistant)是基于特定图逻辑(Graph)和配置初始化的代理实例。

API 原型 主要参数说明 输入/输出 功能简述
create graph_id: 部署的图名称, config: 模型/提示词等配置 : 助手实例 (Assistant) 实例化助手。基于一个通用的逻辑图,创建一个带有特定"个性"或"参数"的独立助手。
get assistant_id: 助手唯一 ID : 助手详情 (Assistant) 获取详情。查询特定助手的基本信息、关联图 ID 及其默认配置参数。
search graph_id: 按图过滤, metadata: 按标签搜索 : 助手列表 (List[Assistant]) 资产盘点。在系统中分页查找符合条件的助手实例。
update config: 新的模型配置, metadata: 新标签 : 更新后的实例 配置变更。在不改变图逻辑的前提下,动态调整助手的底层模型、参数或元数据。
delete assistant_id: 助手唯一 ID : 无 (None) 实例销毁。下线并删除指定的助手配置实例。
get_graph assistant_id: 助手唯一 ID : 序列化图拓扑 (dict) 结构可视化 。获取图的节点和连线数据,常用于前端生成流程图或 Mermaid 代码
get_schemas assistant_id: 助手唯一 ID : JSON Schema 字典 协议定义。获取该助手运行所需的输入/输出数据结构,方便前端进行表单校验。

2.3 线程与记忆管理 API (client.threads)

线程(Thread)是维护多轮对话和 Agent 长时记忆的独立上下文容器。

API 原型 主要参数说明 输入/输出 功能简述
create metadata: 业务标签, thread_id: 可选 ID : 线程实例 (Thread) 创建隔离上下文。为新的用户对话或任务建立独立的"记忆沙箱"。
get thread_id: 唯一标识 : 线程实例 (Thread) 查询元数据。获取线程的创建时间、配置和业务标签信息。
search status: "idle"/"busy", limit: 数量限制 : 线程列表 (List[Thread]) 批量检索。根据运行状态或自定义元数据筛选系统中的线程。
update metadata: 要覆盖或新增的标签 : 更新后的实例 属性维护。修改线程的外部描述信息,不干预内部业务逻辑。
delete thread_id: 线程标识 : 无 (None) 彻底销毁。删除线程及其所有的状态快照、运行记录和物理存储。
get_state thread_id: 线程标识 : 状态快照 (StateSnapshot) 获取实时快照。查看当前程序运行到了哪个节点,以及当前的全局变量值。
update_state values: 注入的数据, as_node: 触发节点名 : 更新响应 (dict) 外部干预。手动修改线程状态,常用于**人工审核(Human-in-the-loop)**场景。
get_history before: 起始快照, limit: 历史深度 : 快照列表 (List[Snapshot]) 回溯历史 。获取状态演进的时间轴,是实现"版本回滚 "或"时间旅行"的基础。

2.4 执行引擎 API (client.runs)

运行(Run)是在特定线程上触发助手执行的单次动作。

API 原型 主要参数说明 输入/输出 功能简述
stream stream_mode: "values"(状态), "messages"(消息), "events"(事件) : 异步事件流生成器 (AsyncIterator) 触发图执行,并建立长连接实时接收图状态变更或 LLM Token 流。
wait thread_id, assistant_id, input : 最终状态字典 (dict) 阻塞式触发执行,直至图运行结束(达到 END 或被中断)并返回最终结果。
create input: 初始数据, webhook: 回调 URL : 运行实例 (Run) 异步提交后台任务,立即返回任务句柄,可通过 Webhook 接收完成通知。
batch thread_ids: 线程列表, inputs: 输入列表 : 运行实例列表 (List[Run]) 并发向多个线程提交批量执行任务,适用于大规模离线数据处理。
join thread_id: 线程 ID, run_id: 任务 ID : 最终状态字典 (dict) 阻塞等待 之前由 create 提交的后台任务,直到其执行完毕并获取结果。
cancel run_id: 执行任务标识, wait: 是否同步等待 : 无 (None) 强制终止正在执行的任务,用于手动干预或释放计算资源。
list limit: 分页大小, offset: 偏移量 : 任务历史列表 (List[Run]) 查询并获取指定线程下所有运行过的任务记录及其状态。

2.5 跨会话存储与定时任务 (Store & Crons)

API 原型 参数说明 输入/输出 功能简述
client.store.put_item(namespace: Tuple[str], key: str, value: dict) -> None namespace: 层级命名空间 key: 键名 value: 存储载荷 : None 在全局 Store 中持久化与特定用户或组织相关联的记忆数据,跨 Thread 共享。
client.store.search_items(namespace_prefix: Tuple[str], limit: int) -> List[Item] namespace_prefix: 命名空间前缀 : 存储项列表 依据命名空间前缀搜索全局记忆/配置数据。
client.crons.create(thread_id: str, assistant_id: str, schedule: str, input: dict) -> Cron schedule: Cron 表达式 (如 0 8 * * *) : Cron 实例 创建一个定时任务,按照设定的频率自动在指定线程中触发 Agent 执行。

3. 应用场景与典型案例

3.1 场景一:构建实时流式对话后端 (Streaming)

前端需要打字机效果,后端通过 SDK 桥接 LangGraph Server 并通过 Server-Sent Events (SSE) 转发。

python 复制代码
from langgraph_sdk import get_client

async def chat_stream(thread_id: str, user_message: str):
    client = get_client("http://localhost:8123")
    input_data = {"messages": [{"role": "user", "content": user_message}]}
    
    # 监听 messages 流模式,仅获取大模型的生成 token
    async for chunk in client.runs.stream(
        thread_id, 
        assistant_id="my_assistant", 
        input=input_data, 
        stream_mode="messages"
    ):
        if chunk.event == "messages/partial":
            yield chunk.data[0]["content"]

3.2 场景二:人在回路的人工干预注入 (Human-in-the-loop)

当获取到线程状态为"挂起"时,管理员调用 SDK 更新状态并唤醒图继续执行。

python 复制代码
async def approve_action(thread_id: str, is_approved: bool):
    client = get_client("http://localhost:8123")
    
    # 将人工决策注入系统状态中
    await client.threads.update_state(
        thread_id,
        values={"approval_status": "approved" if is_approved else "rejected"},
        as_node="human_reviewer" # 伪装成挂起的审查节点产生的数据
    )
    
    # 恢复执行:传入 None 作为 input
    await client.runs.wait(thread_id, assistant_id="my_assistant", input=None)

3.3 场景三:后台自动化与 Webhook 回调

触发长时间分析任务,避免阻塞主线程,依靠 Server 进行 Webhook 通知。

python 复制代码
async def trigger_report_generation(thread_id: str, data_url: str):
    client = get_client("http://localhost:8123")
    run = await client.runs.create(
        thread_id,
        assistant_id="data_analyst",
        input={"data_url": data_url},
        webhook="https://my-backend.com/api/webhooks/langgraph"
    )
    return run.run_id

4. 常见问题与解决方案

  • 异常现象: 运行 client.runs.wait() 时长时间阻塞直至触发 TimeoutError
    • 核心原因: 远端 Agent 内部发生死循环(如由于 ReAct 路由逻辑缺陷导致的无限次工具调用),或者图代码执行极其耗时的操作。
    • 修正建议: 在调用时指定超时控制配置:client.runs.wait(..., config={"configurable": {"timeout_seconds": 60}})
  • 异常现象: update_state 后再次触发图运行,发现系统似乎忽略了更新的状态,又从头开始运行或报错。
    • 核心原因: as_node 参数错误或未提供。若图在节点 A 前挂起,此时手动更新状态应表现为节点 A 执行完毕,因此需要明确指定 as_node="A"
    • 修正建议: 先通过 get_state 获取挂起的 next 节点,然后在 update_state 中将其设为 as_node
  • 异常现象: 使用同步客户端 get_sync_client 在 FastAPI 或 Asyncio 循环中报错:RuntimeError: This event loop is already running
    • 核心原因: httpx 同步客户端和异步环境冲突。
    • 修正建议: 在任何基于 asyncio 的框架(FastAPI, Sanic)中,严禁使用 get_sync_client,必须全局使用 get_clientawait 调用。

5. 零门槛全闭环实战项目:异步流式 Agent 中台网关

项目背景

构建一个企业级的中间层网关(基于 FastAPI)。该网关不对内承载任何 LLM 算力,而是使用 LangGraph SDK 连接独立的 LangGraph Server 集群。网关负责创建会话线程、触发分析任务,并将远端 Server 传回的状态流(State Values)转换为 SSE(Server-Sent Events)推送给前端应用。

环境搭建 (Conda)

bash 复制代码
# 创建网关环境
conda create -n graph_gateway python=3.11 -y
conda activate graph_gateway

# 安装 FastAPI, Uvicorn, LangGraph SDK 及 SSE 支持
pip install fastapi uvicorn langgraph-sdk sse-starlette

前置说明:假设 LangGraph Server 已经运行在 http://localhost:8123 且注册了名为 agent 的 assistant。

架构可视化

HTTP POST
SDK: create_thread
SDK: stream_runs
Chunked State Events
SSE Streaming
Web/Mobile Client
FastAPI Gateway
LangGraph Server
LLM / Tools Execution

全量源码

复制代码
gateway_app.py
python 复制代码
import json
from typing import AsyncGenerator
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sse_starlette.sse import EventSourceResponse
from langgraph_sdk import get_client, AsyncLangGraphClient

# 1. 声明数据模型
class ChatRequest(BaseModel):
    message: str

class ThreadResponse(BaseModel):
    thread_id: str

# 2. 初始化应用与 SDK 客户端
app = FastAPI(title="LangGraph Agent Gateway")
LANGGRAPH_URL = "http://localhost:8123"
ASSISTANT_ID = "agent" # 需在 Server 中预先配置的图标识

def get_lg_client() -> AsyncLangGraphClient:
    """获取 LangGraph SDK 异步客户端"""
    return get_client(url=LANGGRAPH_URL)

# 3. 会话管理接口:创建新线程
@app.post("/api/threads", response_model=ThreadResponse)
async def create_new_thread():
    client = get_lg_client()
    try:
        thread = await client.threads.create()
        return ThreadResponse(thread_id=thread["thread_id"])
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"无法连接到计算节点: {str(e)}")

# 4. 核心流式接口:触发 Agent 并转发状态流
@app.post("/api/threads/{thread_id}/chat_stream")
async def chat_with_agent_stream(thread_id: str, request: ChatRequest):
    client = get_lg_client()
    
    # 验证线程是否存在
    try:
        await client.threads.get(thread_id)
    except Exception:
        raise HTTPException(status_code=404, detail="会话不存在")

    # 构建输入载荷 (符合 LangGraph State 定义)
    payload = {"messages": [{"role": "user", "content": request.message}]}

    async def sse_generator() -> AsyncGenerator[dict, None]:
        try:
            # 调用 SDK 建立流式连接 (使用 values 模式监听全量状态变更)
            async for chunk in client.runs.stream(
                thread_id=thread_id,
                assistant_id=ASSISTANT_ID,
                input=payload,
                stream_mode="values"
            ):
                # chunk.data 包含当前图的完整状态字典
                # 将状态打包为 SSE 格式向前端推送
                yield {
                    "event": chunk.event,
                    "data": json.dumps(chunk.data, ensure_ascii=False)
                }
            
            # 运行结束标志
            yield {"event": "done", "data": "[DONE]"}
            
        except Exception as e:
            yield {"event": "error", "data": str(e)}

    return EventSourceResponse(sse_generator())

# 5. 状态透视接口:获取会话当前记忆与挂起状态
@app.get("/api/threads/{thread_id}/state")
async def get_thread_state(thread_id: str):
    client = get_lg_client()
    try:
        state_snapshot = await client.threads.get_state(thread_id)
        return {
            "values": state_snapshot["values"],
            "next_nodes": state_snapshot["next"],
            "created_at": state_snapshot["created_at"]
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 6. 项目启动入口
if __name__ == "__main__":
    import uvicorn
    # 运行网关服务器
    uvicorn.run(app, host="0.0.0.0", port=8000)

预期输出

模拟前端调用网关(需保持 LangGraph Server 开启):

  1. 创建会话:
bash 复制代码
curl -X POST http://localhost:8000/api/threads
# 输出: {"thread_id":"11223344-5566-7788-9900-aabbccddeeff"}
  1. 发起流式聊天:
bash 复制代码
curl -N -X POST http://localhost:8000/api/threads/11223344-5566-7788-9900-aabbccddeeff/chat_stream \
-H "Content-Type: application/json" \
-d '{"message": "你好,请查询今天的天气"}'

流式输出截取:

复制代码
event: metadata
data: {"run_id": "...", "thread_id": "..."}

event: values
data: {"messages": [{"content": "你好,请查询今天的天气", "role": "user"}]}

event: values
data: {"messages": [{"content": "你好,请查询今天的天气", "role": "user"}, {"content": "", "tool_calls": [...], "role": "assistant"}]}

event: done
data: [DONE]

6. 核心总结

LangGraph SDK 将复杂的图计算状态机逻辑封装在 REST/WebSocket 通信层之下。其核心范式为:创建 Thread(沙箱) -> 使用 Assistant(逻辑模版) -> 触发 Run(计算实例) -> 监听 Stream / Wait(状态获取)。通过将图的执行部署在远端 Server 并通过 SDK 交互,开发团队可以轻松实现 AI 算力与业务网关的解耦,为高并发、高可用性的 Multi-Agent 系统奠定了工程基础。

相关推荐
迷藏4942 小时前
**基于Python与OpenCV的光场显示图像处理技术实践**在现代显示技术发展中,**光场显示(Light
java·图像处理·python·opencv
枫叶林FYL2 小时前
【Python高级工程与架构实战】项目六:RAG知识库问答系统(企业文档智能)
python·深度学习·机器学习
itzixiao2 小时前
L1-041 寻找250(10分)
开发语言
njsgcs2 小时前
获得solidworks 3d零件的包围框 长宽高 boundingbox c#
开发语言·c#·solidworks
网域小星球2 小时前
C 语言从 0 入门(十九)|共用体与枚举:自定义类型进阶
c语言·开发语言·算法·枚举·自定义类型·共用体
witAI2 小时前
gpt写小说工具2025推荐,助力高效创作小说
人工智能·python·gpt
Roselind_Yi2 小时前
【开源仓库系列学习分享】MemPalace 仓库(超级记忆管家)全流程部署!(专业版)
人工智能·经验分享·笔记·python·数据挖掘·github·知识图谱
Evand J2 小时前
【滤波代码介绍|MATLAB】粒子滤波(PF)与自适应粒子滤波(APF)在三维动态系统状态估计中的对比,使用Sage Husa自适应的思想
开发语言·matlab·pf·粒子滤波·apf·自适应滤波
Flying pigs~~2 小时前
检索增强生成RAG项目tools_04:flask➕fastapi➕高并发
数据库·python·flask·大模型·fastapi·异步