学习笔记 · Obsidian

TypeScript 生产化、SDK、测试与迁移

LangChainLangGraphTypeScript

生产应用结构

一个可由 Agent Server 加载的 TypeScript LangGraph 应用通常包含:

my-app/ ├── src/ │ ├── state.ts │ ├── nodes.ts │ ├── tools.ts │ └── agent.ts ├── package.json ├── .env └── langgraph.json

职责建议:

  • state.ts:StateSchema、input/output/context schema;
  • nodes.ts:无框架副作用的 node 逻辑;
  • tools.ts:工具 schema、权限包装与 adapter;
  • agent.ts:组图、compile、导出;
  • langgraph.json:部署加载入口;
  • package.json:锁定运行依赖和 Node engine;
  • .env:仅本地开发,不能提交真实 secret。

langgraph.json 关键字段:

  • dependencies:通常是当前项目;
  • graphs:唯一 graph ID 到导出对象或 factory 的路径;
  • env:本地环境变量文件或映射;
  • node_version:本地生成器可写入目标 Node 版本;
  • dockerfile_lines:需要额外系统库时使用。

graphs 目标可以是已 compiled graph,也可以是构造 graph 的函数。createAgent 返回已编译 LangGraph graph,可直接导出。

生产环境变量由平台 secret 管理注入,不把 API key 直接写进 langgraph.json。

本地 Agent Server

官方 JavaScript 流程:

  1. 安装 dev dependency @langchain/langgraph-cli;
  2. npm create langgraph 创建模板,或对已有项目运行 config 生成器;
  3. 确认 graph 已 export;
  4. 安装依赖并创建 .env;
  5. npx @langchain/langgraph-cli dev;
  6. 用 Studio、SDK 或 REST 测试。

默认地址:

  • API:127.0.0.1:2024;
  • API docs:127.0.0.1:2024/docs;
  • Studio:带 baseUrl 参数的 smith.langchain.com/studio。

dev server 是内存模式,只适合开发测试。它成功不能证明:

  • checkpoint 在重启后恢复;
  • 生产数据库 migration 正确;
  • 并发 thread 隔离;
  • 队列、后台 run 与弹性伸缩;
  • 真实网络、代理和超时;
  • 密钥与租户授权。

Safari 对 Studio 访问 localhost 有限制,可用 --tunnel。隧道扩大网络暴露面,应只在受控环境使用,并配置 allowed origins。

TypeScript SDK 与协议边界

安装 @langchain/langgraph-sdk 后,Client 可以针对 graph ID 发起 threadless 或 thread run。远程 API 的 SDK stream chunk 是网络协议事件,不等同于进程内 graph.streamEvents 对象。

文档不同页面展示了 messages 与 messages-tuple streamMode。原因是进程内 runtime mode、Agent Streaming Protocol 和 SDK 版本演进并不完全同名。项目要按当前 server 与 SDK 的兼容矩阵锁定:

  • server 版本;
  • SDK 版本;
  • stream mode;
  • event/chunk shape;
  • resume/interrupt 行为。

不要依据单页示例硬编码 parser。至少用契约测试覆盖 messages、updates、tools、interrupt、error 和 reconnect。

部署选择

LangSmith Cloud 提供托管的持久化、长任务、扩缩容和 Agent Server;快速路径从 GitHub repository 创建 deployment,再通过 Studio 和 API URL 验证。

LangSmith 还提供 hybrid、standalone server、self-hosted control plane 等方案。JavaScript graph 也可以在 Next.js、SvelteKit、Nuxt、Cloudflare Workers 与 Deno Deploy 等平台上使用 Agent Streaming Protocol。

部署选择要评估:

  • 数据驻留、合规与加密;
  • Node runtime、原生依赖与 edge runtime 限制;
  • 持久化 backend 与 retention;
  • 长连接、SSE、代理缓冲与 serverless 超时;
  • 后台 run、队列和并发隔离;
  • 网络出口和模型 provider 限额;
  • 观测数据是否允许离开环境;
  • 灰度、回滚和 checkpoint 兼容性。

Cloudflare Workers、Deno 和传统 Node 并不是可无差别互换的运行时。文件系统、原生模块、TCP 数据库驱动、process signal 与持续连接能力都要逐平台验证。

Studio 与 Agent Chat UI

Studio

Studio 是连接 Agent Server 的开发和调试界面,可以查看:

  • graph node 与中间 State;
  • 模型 prompt、tool call 和结果;
  • exception 与周围状态;
  • token、延迟与 trace;
  • thread、assistant 与历史 checkpoint;
  • 从历史步骤重跑;
  • hot reload 后快速迭代。

Studio 适合诊断,不替代自动化测试。若不允许把本地数据作为 trace 发送到 LangSmith,显式 LANGSMITH_TRACING=false。Studio 连接本地 server 与 trace 上传是两个独立问题。

Agent Chat UI

Agent Chat UI 是开源 Next.js 客户端,提供聊天、tool visualization、interrupt thread、time travel 与 State fork。它可以连接本地或部署后的 Agent Server。

连接参数包括:

  • graph ID,即 langgraph.json 的 graphs key;
  • Agent Server URL;
  • 远程服务所需认证。

hosted UI 适合验证协议。生产产品要自建用户认证、租户隔离、CORS、内容安全、审计与密钥代理;LangSmith API key 不能作为公共浏览器长期 secret。

观测

LangSmith trace 由一系列 run 组成,可用于调试、评价和监控。常见配置:

  • LANGSMITH_TRACING;
  • LANGSMITH_API_KEY;
  • LANGSMITH_PROJECT;
  • per-invocation callbacks;
  • tags 与 metadata。

metadata 应放稳定但非敏感的排障维度,例如:

  • environment;
  • applicationVersion;
  • featureFlag;
  • tenant 的不可逆/受控标识;
  • business workflow type。

不要把 access token、密码、完整身份证号、银行卡、模型密钥或未授权正文写入 tag/metadata。

官方展示了使用 langsmith anonymizer 在上传 trace 前对 SSN 格式做替换。实际生产还需要覆盖:

  • email、phone、address、payment data;
  • message content 和 tool args/results;
  • custom stream 与 error stack;
  • 结构化字段而非只靠正则;
  • 脱敏失败时 fail-closed 或禁用上传的策略。

测试策略

官方 TypeScript 示例使用 Vitest。推荐测试金字塔:

node 单元测试

compiledGraph.nodes[name].invoke 可以直接调用单 node,但会绕过 compile 时的 checkpointer。它适合验证纯 State update、schema、router 和错误分支,不证明 checkpoint/retry/interrupt。

graph 测试

每个 test 创建新 builder、新 MemorySaver 和唯一 thread_id,避免测试互相污染。覆盖:

  • happy path;
  • conditional edge;
  • parallel reducer;
  • tool call/ToolMessage 配对;
  • timeout/retry/handler;
  • interrupt/resume;
  • replay 与 checkpoint history。

partial execution

可以用 updateState 预置 checkpoint,并指定 asNode,让执行从某个 successor 开始;再用 interruptAfter 在目标节点后暂停。这适合验证一段大图而不重构 topology。

官方 partial-execution 片段存在 API 形态漂移:正文描述 options.asNode,代码又展示位置参数;还残留 Python None 表述。应以当前 TypeScript 类型为准并让 Vitest 编译。

集成与故障测试

必须补充:

  • 真实数据库 checkpointer migration;
  • 进程 kill/restart 后恢复;
  • 同一 thread 并发写与多个 thread 隔离;
  • SSE 断线、重连、代理缓冲;
  • provider 429/5xx/timeout;
  • SIGTERM drain;
  • 旧 checkpoint 在新 graph 上恢复;
  • 浏览器端 node 卡片、interrupt 和 custom channel。

checkpoint 是生产兼容 API

LangGraph 不把 in-flight run 固定到启动时的代码版本。部署新 graph 后,旧 thread 恢复时立即运行最新代码。因此 graph code 与已持久化 State 之间存在长期 API 合同。

技术兼容

高风险改动:

  • 删除或重命名仍可能作为恢复点的 node;
  • 删除或重命名旧 checkpoint 中的 State key;
  • 把 optional 字段改 required;
  • 缩窄字段类型;
  • 新增没有 default 的 required 字段。

edge topology 本身通常不持久化。只要节点名仍存在,新增、删除或重路由 edge 通常可作用于恢复后的最新路径;真正会让 interrupted thread 无法找到入口的是 node rename/removal。

推荐迁移:

  1. 新字段先 optional/default;
  2. rename 使用 add -> dual-read/dual-write -> drain -> remove;
  3. deprecated node 保留一个完整 drain 周期;
  4. staging 用真实旧 checkpoint getState/time travel 验证;
  5. 观察 busy/interrupted/error thread 和 node trace;
  6. 没有活跃旧 thread 后再删除。

LangGraph 本身不维护任意部署环境下的 thread State 搜索索引。在 LangSmith Deployment 可用 thread search;其他环境需依靠自己的索引与 trace。

业务兼容

技术能加载不代表业务语义应该改变。若新流程只应应用于新 thread,在 thread 启动时写入 flowVersion,后续 conditional edge 按版本分支。旧 checkpoint 缺字段时显式落入旧版本默认。

flowVersion 必须在可能分支之前写入。所有旧 thread 完成后再移除兼容路径。

Functional API 的确定性兼容

Functional entrypoint 恢复时从开头 replay,并按调用位置复用 task 与 interrupt 结果。对 in-flight run,以下改动危险:

  • 在 resume point 之前插入、删除或重排 task;
  • 插入、删除或重排 interrupt;
  • 把时间、随机数、网络调用放在 task 外;
  • 修改会改变此前控制流的非确定性条件。

安全策略:等待旧 run drain;把新逻辑封装为新 task;或在 langgraph.json 注册新 graph ID,让新 thread 使用新入口。

TypeScript 文档部分段落仍使用 Python @task、@entrypoint 表述。实际兼容单位是 task/entrypoint 函数工厂调用位置,而非 TypeScript 装饰器。

版本演进要点

/oss/javascript/langgraph/changelog-js 会 307 跳转到全 JavaScript/TypeScript changelog。与 LangGraph 直接相关的节点:

  • 2025-10:LangGraph v1.0 发布,并提供 v1 migration guide;
  • 2026-01:v1.1 引入 StateSchema、Standard Schema、ReducedValue、UntrackedValue、MessagesValue 与类型 helper;旧 Annotation/Zod API 保持兼容;
  • 之后的 fault tolerance 与 frontend/event streaming 能力还有各自最低小版本要求,不能只看 “v1”。

升级流程:

  1. 锁定所有 @langchain/* 包,而不是只升一个;
  2. 阅读 changelog 和 migration guide;
  3. 跑 TypeScript、Vitest、SDK contract test;
  4. 用旧 checkpoint 做 replay;
  5. 灰度观察 error、latency、token 与 interrupted thread;
  6. 保留可回滚 artifact 和兼容 schema。

案例页应该如何使用

官方案例页是从公开资料汇总的使用者索引,不是统一方法论或经过同一标准审计的基准。列出的场景覆盖:

  • browser automation:AirTop;
  • research/search:Athena、Exa、Harmonic、Morningstar;
  • customer support:Cisco、Minimal、Prosper;
  • coding/developer productivity:GitLab、Qodo、Replit、Uber、Vodafone;
  • finance/legal/healthcare copilot:BlackRock、J.P. Morgan、Definely、Komodo、Vizient 等;
  • data extraction:Captide、WebToon;
  • logistics/enterprise automation:C.H. Robinson 等。

可提炼的共性是“有状态、多步骤、可观测、需要人工或工具边界”,而不是某公司名称自动证明某种架构适合自己的合规、成本和规模。

上线门禁

  • 锁定 Node 与所有 LangChain/LangGraph/SDK 版本。
  • langgraph.json 的 graph ID、导出路径和环境变量可在干净环境加载。
  • 生产 secret 不进代码、config 或浏览器。
  • 真实 checkpointer 完成 migration、备份、恢复和 retention 测试。
  • SDK/server stream contract 与 reconnect 通过。
  • node、graph、partial、HITL、fault 和旧 checkpoint 测试通过。
  • trace 做最小化与脱敏,敏感数据策略经过安全审查。
  • node/State rename 走兼容窗口和 in-flight thread 审计。
  • serverless/edge 目标验证连接、原生模块、长任务与信号差异。
  • Studio/hosted UI 验证不被当成生产认证和性能结论。