08. API 迁移与版本兼容
6 min read

08. API 迁移与版本兼容

整理 Python/旧教程迁移到当前 deepagentsjs 的命名、middleware、Backend 和运行时语义差异,形成升级排错清单。

08. API 迁移与版本兼容#

参考教程使用 Python,且部分文章早于当前 JavaScript 文档。迁移时不要逐字替换函数名,先确认运行时语义。本文集中整理最容易出错的差异。

1. 命名差异#

Python/旧文章当前 TypeScript 方向
create_deep_agentcreateDeepAgent
system_promptsystemPrompt
interrupt_oninterruptOn
response_formatresponseFormat
snake_case 配置JavaScript 驼峰配置
docstring 推导参数tool() + Zod schema

这不是简单的格式问题。JS 的工具 schema 是运行时对象,必须真正传给 tool();TypeScript 接口不会自动约束模型生成的 JSON。

2. 规划能力的版本变化#

旧教程可能把 write_todos 当成默认能力。当前从 v0.7 起,任务规划需要显式加入:

typescript
import { todoListMiddleware } from "langchain";

const agent = createDeepAgent({
  model,
  middleware: [todoListMiddleware()],
});

迁移检查:工具清单中是否出现 write_todos;模型是否真的使用;state 中的计划字段是否符合当前版本;UI 是否能区分无计划、空计划和完成计划。

3. Backend 实例化变化#

当前文档推荐直接传 backend 实例:

typescript
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 或持久文件系统。

消息最终内容也不要盲目断言为字符串:

typescript
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

typescript
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 是否有 namedescription;路径是否相对 backend root;supporting files 是否用相对路径引用;StateBackend 是否真的提供了初始文件。

7. Interpreter、动态子 Agent 与 MCP#

这些能力有更强的版本敏感性:

  • QuickJS 需要 @langchain/quickjscreateCodeInterpreterMiddleware()
  • 动态子 Agent 仍应当作 beta,不能把“请运行 workflow”当成确定性协议;
  • MCP adapter 的 transport 配置以当前 LangChain MCP 文档为准;
  • Interpreter 没有 shell、网络和宿主机文件能力;
  • Sandbox、LocalShell 和 MCP 写入工具要分别配置权限。

升级前为每个能力准备最小回归:单个解释器计算、一个静态子 Agent、一次动态 fan-out、一次 MCP 只读查询、一次审批拒绝。

8. 版本锁定与升级流程#

把以下信息写进运行摘要:

typescript
type CompatibilityStamp = {
  deepagents: string;
  langchain: string;
  langgraph: string;
  model: string;
  promptVersion: string;
  rubricVersion: string;
};

升级流程:

  1. 读取官方 changelog、overview 和相关专题文档;
  2. 锁定依赖并更新类型;
  3. 运行工具单测和静态检查;
  4. 跑 happy path、空结果、工具失败、越权和 interrupt 恢复;
  5. 比较工具轨迹、文件状态、成本和最终质量;
  6. 确认旧 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 和评估集解释质量差异。

相关文章