🌐 持久化与部署

前面章节的 Agent 都在单进程内存里跑。生产 Agent 需要跨进程持久化、远程调用、API 化部署。本章精读 PostgresSaver 生产持久化、RemoteGraph 连接 LangGraph Server、把 Agent 部署成可水平扩展的 API 服务,并对比 OpenCode 的 server 架构。

本章目标

  • 理解从单机到分布式的 Agent 部署演进
  • 掌握 PostgresSaver / AsyncPostgresSaver 的生产持久化
  • 理解 ShallowPostgresSaver 的省存储策略
  • 掌握 RemoteGraph 连接远程 LangGraph Server
  • 对比 OpenCode 的 server + share + sync 架构

部署演进:从单机到分布式

① 单机内存 InMemorySaver 进程内 重启即失 学习/原型 ② 单机持久化 SqliteSaver 本地文件 重启保留 单机生产 ③ 数据库持久化 PostgresSaver 共享DB 多实例可访问 多实例部署 ④ 远程服务 RemoteGraph Agent as API 水平扩展 大规模生产
图 AD9.1 · Agent 部署的四阶段演进

PostgresSaver:生产持久化

生产环境标配——PostgreSQL 持久化 checkpoint,支持多进程/多实例共享状态:

📄 checkpoint-postgres/base.py:297 · BasePostgresSaver python
class BasePostgresSaver(BaseCheckpointSaver[str]):
    """Postgres 持久化基类。含 SQL 迁移列表 MIGRATIONS。"""

# 两个版本:
# PostgresSaver(__init__.py:40)—— 同步
# AsyncPostgresSaver(aio.py:40)—— 异步(生产推荐)
#   - from_conn_string (:65) 从连接串创建
#   - aget_tuple (:181) 异步取 checkpoint
#   - aput (:232) 异步存
📄 ad9_postgres.py · 生产持久化 python
# pip install langgraph langgraph-checkpoint-postgres psycopg[binary]
from langgraph.checkpoint.postgres import PostgresSaver
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
from psycopg import Connection

# 生产:Postgres 连接
DB_URI = "postgresql://user:pass@localhost:5432/langgraph"

# 同步版
with Connection(DB_URI) as conn:
    checkpointer = PostgresSaver(conn)
    checkpointer.setup()   # ★ 自动建表(含迁移)

    agent = create_react_agent(
        ChatOpenAI(model="gpt-4o-mini"),
        tools=[],
        checkpointer=checkpointer,   # ★ 状态存 Postgres
    )

    # 现在多进程/多实例都能访问同一会话状态
    config = {"configurable": {"thread_id": "user-alice"}}
    agent.invoke({"messages": [("user", "你好")]}, config)
    # 进程重启、换机器,只要 thread_id 相同,状态都在 Postgres 里
📄 异步版(生产推荐) python
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
import asyncio

async def main():
    async with await AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
        await checkpointer.setup()
        agent = create_react_agent(model, tools, checkpointer=checkpointer)
        # 异步 IO,高并发下不阻塞——Web 服务必备

asyncio.run(main())

ShallowPostgresSaver:省存储

完整 checkpoint 每步都存,长对话存储爆炸。ShallowPostgresSaver 只存最新状态:

📄 checkpoint-postgres/shallow.py:169 · 浅层持久化 python
class ShallowPostgresSaver(BasePostgresSaver):
    """浅层持久化:只存最新 checkpoint,不保留完整历史。

    优点:省存储(长对话不会无限增长)
    代价:失去时间旅行调试能力(没有历史)
    适合:不需要回溯、只关心当前状态的场景
    """
# 用法和 PostgresSaver 完全一样,只是行为不同
💡 存储策略选择

PostgresSaver(完整):要时间旅行/审计/调试 → 存全历史。ShallowPostgresSaver(浅层):只要记忆、不回溯 → 只存最新。生产中按需求选——大多数对话场景用 Shallow 就够(历史对话用 compaction 压缩,不必存全量快照)。

RemoteGraph:连接远程 Server

最彻底的部署——Agent 跑在专门的 Server 上,客户端通过 RemoteGraph 调用

📄 pregel/remote.py:118 · RemoteGraph python
class RemoteGraph(PregelProtocol):
    """远程图客户端。连接 LangGraph Server。

    __init__ 接收:
    - url (:137):Server 地址
    - api_key / headers (:139)
    - client / sync_client (:140/141):HTTP 客户端
    - distributed_tracing (:163):★ LangSmith 分布式追踪

    提供与本地 Pregel 同构的接口:
    stream (:741) / astream (:912) / ainvoke (:1244) / astream_events (:1080)

    RemoteException (:112):远端异常透传。
    _merge_tracing_headers (:1297):自动合并分布式追踪头。
    """
客户端 RemoteGraph app.invoke() app.stream() HTTP + tracing 头 透传异常 LangGraph Server Agent 图(真实执行) PostgresSaver(共享状态) 可水平扩展(多实例)
图 AD9.2 · RemoteGraph:客户端透明调用远程 Agent Server
📄 ad9_remote.py · 客户端调用远程 Agent python
from langgraph.pregel.remote import RemoteGraph

# 连接到部署好的 LangGraph Server
remote_app = RemoteGraph(
    "my-agent",                           # 图名
    url="https://my-langgraph-server.com",
    api_key="lsa_...",
    distributed_tracing=True,             # ★ 跨服务追踪(自动合并 tracing 头)
)

# ★ 调用方式和本地完全一样!客户端无感知
result = remote_app.invoke(
    {"messages": [("user", "你好")]},
    config={"configurable": {"thread_id": "u1"}},
)

# 流式也一样
for chunk in remote_app.stream({"messages": [...]}):
    print(chunk)

# 异常透传:Server 端的错误会原样抛给客户端(RemoteException)
🧭 distributed_tracing:跨服务追踪

distributed_tracing=True 时,RemoteGraph 自动在 HTTP 请求里携带 LangSmith 追踪头(remote.py:1297 _merge_tracing_headers)。这样客户端→Server 的调用在 LangSmith 里显示为连续的 trace,跨服务也能看到完整调用链。这是微服务可观测的标准做法。

部署 Agent 为 API 服务

用 LangGraph Platform / LangGraph Server 把 Agent 部署成 REST API:

📄 部署流程(概念) bash
# 1. 定义 Agent(langgraph_app.py)
def make_graph():
    return create_react_agent(model, tools, checkpointer=PostgresSaver(...))

# 2. 用 langgraph CLI 部署
# langgraph up  →  本地 Docker 起 Server
# langgraph deploy  →  部署到 LangGraph Cloud

# 3. Server 提供 REST API:
# POST /threads  → 创建会话(thread)
# POST /threads/{id}/runs  → 触发执行
# GET /threads/{id}/runs/{id}/stream  → 流式获取结果
# 客户端用 RemoteGraph 或直接 HTTP 调用

OpenCode 的 server 架构

OpenCode 自己实现了完整的 HTTP 服务架构:

📄 server/routes.ts:39 · HTTP 服务装配 typescript
// createRoutes(password?) 装配 HTTP 服务
function createRoutes(password?: string) {
  return Layer.effect(function* () {
    return HttpApiBuilder.layer(Api, { openapiPath: "/openapi.json" })
    // ★ 自动生成 OpenAPI 文档!
    // webHandler() 转成标准 web handler
  })
}

// handlers/ 下按资源分:session.ts / message.ts / event.ts / model.ts ...
// 每个资源有对应的 HTTP 端点处理器

// 鉴权:auth.ts + middleware/authorization.ts(Basic Auth)
// routes.ts:42 支持 password 保护
💡 OpenCode vs LangGraph Server

两者都是"Agent as API",但实现不同:LangGraph Server是专门平台(部署到 LangGraph Cloud 或自建 Docker),深度集成 checkpoint/store。OpenCode server 是应用内嵌的 HTTP 服务(用 Effect HttpApiBuilder),自带 OpenAPI 生成,更轻量自包含。OpenCode 还有share(会话分享 URL)和sync(跨设备事件同步)——这些是编码工具特有的协作需求。

OpenCode 的 share 与 sync

📄 share/share-next.ts:81 + sync/README.md typescript
// ShareNext 服务(:81):会话分享
// - sync(sessionID, data[]):同步会话数据到分享后端
// - create:生成可分享 URL(别人能看你的 Agent 对话)
// - get/remove/flush:管理分享

// sync 系统(sync/README.md):事件溯源同步
// "one writer, multiple syncers" 模型:
// - 单写入者产生 SyncEvent
// - 多设备 replay 同步事件流
// SyncEvent.run / subscribeAll

// 路由:server/routes/.../sync.ts(HTTP 同步端点)
// 这是 OpenCode 跨设备协作的基建

与生产实践对照

LangGraph 部署OpenCode 对应
PostgresSaver 持久化Drizzle/SQLite 持久化
AsyncPostgresSaver 高并发Effect 异步 IO
RemoteGraph 远程调用内嵌 HTTP server(不需远程)
LangGraph Server APIserver/routes.ts + OpenAPI
distributed_tracing 跨服务OTel span 跨服务
thread_id 会话隔离sessionID 隔离
(无原生)share 会话分享 + sync 跨设备
🧭 两种部署哲学

LangGraph 走"Agent 平台"路线——专门 Server、Cloud 托管、RemoteGraph 客户端,适合大规模企业部署。OpenCode 走"应用内嵌"路线——HTTP 服务直接长在应用里,自包含,适合桌面/本地工具。选择取决于你的产品形态:SaaS 用 LangGraph Server,桌面工具用内嵌。

小结

下一章 · 进阶收官

最后一章 AD10 · 评估与测试——进阶阶段的收官。Agent 非确定、多步骤,怎么测它好不好?精读评估体系、标准化测试、LLM-as-judge。