08. API 迁移与版本兼容#
参考教程使用 Python,且部分文章早于当前 JavaScript 文档。迁移时不要逐字替换函数名,先确认运行时语义。本文集中整理最容易出错的差异。
1. 命名差异#
| Python/旧文章 | 当前 TypeScript 方向 |
|---|---|
create_deep_agent | createDeepAgent |
system_prompt | systemPrompt |
interrupt_on | interruptOn |
response_format | responseFormat |
| snake_case 配置 | JavaScript 驼峰配置 |
| docstring 推导参数 | tool() + Zod schema |
这不是简单的格式问题。JS 的工具 schema 是运行时对象,必须真正传给 tool();TypeScript 接口不会自动约束模型生成的 JSON。
2. 规划能力的版本变化#
旧教程可能把 write_todos 当成默认能力。当前从 v0.7 起,任务规划需要显式加入:
import { todoListMiddleware } from "langchain";
const agent = createDeepAgent({
model,
middleware: [todoListMiddleware()],
});迁移检查:工具清单中是否出现 write_todos;模型是否真的使用;state 中的计划字段是否符合当前版本;UI 是否能区分无计划、空计划和完成计划。
3. Backend 实例化变化#
当前文档推荐直接传 backend 实例:
const agent = createDeepAgent({
model,
backend: new FilesystemBackend({
rootDir: "/absolute/path/to/project",
virtualMode: true,
}),
});旧版 factory 写法可能仍存在兼容路径,但升级时应以当前类型和官方 Backends 文档为准。检查 rootDir 是否绝对路径、是否意外暴露整个 home,以及 virtualMode 是否符合应用边界。
4. 文件和消息#
Python 示例中的文件工具语义可以迁移,但不能把 StateBackend 当成本地 fs。默认 StateBackend 的文件属于 thread state;要读取项目目录,显式使用 FilesystemBackend;要跨 thread 共享,使用 StoreBackend 或持久文件系统。
消息最终内容也不要盲目断言为字符串:
const content = result.messages.at(-1)?.content;
const text = typeof content === "string" ? content : JSON.stringify(content);5. Human-in-the-loop 迁移#
当前 HITL 需要 checkpointer。中断后用 Command({ resume: { decisions } }),并复用同一 thread_id:
const config = { configurable: { thread_id: "thread-123" } };
const result = await agent.invoke(input, config);
await agent.invoke(new Command({
resume: { decisions: [{ type: "approve" }] },
}), config);不要把“用户在 UI 点了批准”当成恢复完成。服务端还要验证审批归属、参数、权限、过期时间和幂等键。
6. Skills 和 Memory#
Skills 使用带 frontmatter 的 SKILL.md,通过 backend root 下的 POSIX 路径加载;AGENTS.md 适合始终相关规则。自定义子 Agent 不会自动继承主 Agent 的 Skills,默认 general-purpose 的继承行为要以当前文档为准。
迁移时检查:frontmatter 是否有 name 和 description;路径是否相对 backend root;supporting files 是否用相对路径引用;StateBackend 是否真的提供了初始文件。
7. Interpreter、动态子 Agent 与 MCP#
这些能力有更强的版本敏感性:
- QuickJS 需要
@langchain/quickjs和createCodeInterpreterMiddleware(); - 动态子 Agent 仍应当作 beta,不能把“请运行 workflow”当成确定性协议;
- MCP adapter 的 transport 配置以当前 LangChain MCP 文档为准;
- Interpreter 没有 shell、网络和宿主机文件能力;
- Sandbox、LocalShell 和 MCP 写入工具要分别配置权限。
升级前为每个能力准备最小回归:单个解释器计算、一个静态子 Agent、一次动态 fan-out、一次 MCP 只读查询、一次审批拒绝。
8. 版本锁定与升级流程#
把以下信息写进运行摘要:
type CompatibilityStamp = {
deepagents: string;
langchain: string;
langgraph: string;
model: string;
promptVersion: string;
rubricVersion: string;
};升级流程:
- 读取官方 changelog、overview 和相关专题文档;
- 锁定依赖并更新类型;
- 运行工具单测和静态检查;
- 跑 happy path、空结果、工具失败、越权和 interrupt 恢复;
- 比较工具轨迹、文件状态、成本和最终质量;
- 确认旧 thread 是否可恢复,再逐步放量。
9. 迁移排错清单#
| 问题 | 优先检查 |
|---|---|
| 工具不存在 | 是否忘记 middleware,或导入了旧包路径 |
| Skill 不触发 | description、frontmatter、backend root 和路径 |
| 文件为空 | StateBackend 是否传入 FileData,是否误以为有本地磁盘 |
| 中断无法恢复 | checkpointer、同一 thread_id、decision 顺序 |
| 子 Agent 看不到规则 | 自定义子 Agent 是否显式配置 Skills 和 systemPrompt |
| 动态任务不执行 | beta 约束、interpreter middleware、模型能力和任务形状 |
| MCP 工具失效 | adapter transport、server 版本、工具清单和超时 |
最终检查
迁移完成的标准不是“TypeScript 能编译”,而是:当前文档中的 API 能被正确调用;工具、文件、计划和审批的语义没有被旧教程的假设改变;升级后可以用 trace 和评估集解释质量差异。