🌐 持久化与部署
前面章节的 Agent 都在单进程内存里跑。生产 Agent 需要跨进程持久化、远程调用、API 化部署。本章精读 PostgresSaver 生产持久化、RemoteGraph 连接 LangGraph Server、把 Agent 部署成可水平扩展的 API 服务,并对比 OpenCode 的 server 架构。
本章目标
- 理解从单机到分布式的 Agent 部署演进
- 掌握 PostgresSaver / AsyncPostgresSaver 的生产持久化
- 理解 ShallowPostgresSaver 的省存储策略
- 掌握 RemoteGraph 连接远程 LangGraph Server
- 对比 OpenCode 的 server + share + sync 架构
部署演进:从单机到分布式
PostgresSaver:生产持久化
生产环境标配——PostgreSQL 持久化 checkpoint,支持多进程/多实例共享状态:
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) 异步存
# 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 里
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 只存最新状态:
class ShallowPostgresSaver(BasePostgresSaver):
"""浅层持久化:只存最新 checkpoint,不保留完整历史。
优点:省存储(长对话不会无限增长)
代价:失去时间旅行调试能力(没有历史)
适合:不需要回溯、只关心当前状态的场景
"""
# 用法和 PostgresSaver 完全一样,只是行为不同
PostgresSaver(完整):要时间旅行/审计/调试 → 存全历史。ShallowPostgresSaver(浅层):只要记忆、不回溯 → 只存最新。生产中按需求选——大多数对话场景用 Shallow 就够(历史对话用 compaction 压缩,不必存全量快照)。
RemoteGraph:连接远程 Server
最彻底的部署——Agent 跑在专门的 Server 上,客户端通过 RemoteGraph 调用:
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):自动合并分布式追踪头。
"""
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=True 时,RemoteGraph 自动在 HTTP 请求里携带 LangSmith 追踪头(remote.py:1297 _merge_tracing_headers)。这样客户端→Server 的调用在 LangSmith 里显示为连续的 trace,跨服务也能看到完整调用链。这是微服务可观测的标准做法。
部署 Agent 为 API 服务
用 LangGraph Platform / LangGraph Server 把 Agent 部署成 REST API:
# 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 服务架构:
// 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 保护
两者都是"Agent as API",但实现不同:LangGraph Server是专门平台(部署到 LangGraph Cloud 或自建 Docker),深度集成 checkpoint/store。OpenCode server 是应用内嵌的 HTTP 服务(用 Effect HttpApiBuilder),自带 OpenAPI 生成,更轻量自包含。OpenCode 还有share(会话分享 URL)和sync(跨设备事件同步)——这些是编码工具特有的协作需求。
OpenCode 的 share 与 sync
// 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 API | → | server/routes.ts + OpenAPI |
| distributed_tracing 跨服务 | → | OTel span 跨服务 |
| thread_id 会话隔离 | → | sessionID 隔离 |
| (无原生) | → | share 会话分享 + sync 跨设备 |
LangGraph 走"Agent 平台"路线——专门 Server、Cloud 托管、RemoteGraph 客户端,适合大规模企业部署。OpenCode 走"应用内嵌"路线——HTTP 服务直接长在应用里,自包含,适合桌面/本地工具。选择取决于你的产品形态:SaaS 用 LangGraph Server,桌面工具用内嵌。
小结
- 部署四阶段:单机内存 → 单机持久化(Sqlite) → 数据库(Postgres) → 远程服务(RemoteGraph)。
- PostgresSaver 生产标配(多实例共享);ShallowPostgresSaver 省存储(不存历史)。
- RemoteGraph 透明调用远程 Agent Server,接口与本地同构,支持 distributed_tracing。
- LangGraph Server 提供 REST API;OpenCode 用内嵌 server + share + sync。
- 两种哲学:Agent 平台(LangGraph Server)vs 应用内嵌(OpenCode)。
最后一章 AD10 · 评估与测试——进阶阶段的收官。Agent 非确定、多步骤,怎么测它好不好?精读评估体系、标准化测试、LLM-as-judge。