Cloudflare Agents 迁移指南:从 AI SDK v4 升级到 v5(配合 `@cloudflare/ai-chat`)
发布时间:2026/9/18 3:35:46 作者:尧图编辑部 阅读量:1,286
)
Cloudflare Agents 迁移指南从 AI SDK v4 升级到 v5配合cloudflare/ai-chat【免费下载链接】agentsBuild and deploy AI Agents on Cloudflare项目地址: https://gitcode.com/GitHub_Trending/agents1/agents导读本指南面向使用cloudflare/ai-chat与agents包构建 Cloudflare Agents 应用的开发者完整讲解从 AI SDK v4 升级到 v5 所需的全部代码改动消息格式从content字符串迁移到parts数组、导入路径与类型名的变更、工具定义中parameters到inputSchema的改名、流式事件字段的调整以及旧存储消息的自动迁移机制。读完本文你将掌握 v4 → v5 的完整改造清单并能理解仓库中autoTransformMessages()自动迁移工具的底层实现与边界行为为继续升级到 v6 打下基础。版本前提务必先读当前仓库中的agents与cloudflare/ai-chat包实际支持的是 AI SDK v6 和 v7并非 v5。如果你仍停留在 v4请按本页完成中间的兼容性改动后继续通过 v6 迁移指南 升级到受支持的版本。不要在当前 Cloudflare 包旁边安装 AI SDK v5——这可以从 packages/ai-chat/package.json 的 peerDependencies 得到印证ai: ^6.0.0 || ^7.0.0、ai-sdk/react: ^3.0.0 || ^4.0.0。因此本文介绍的 v5 改动属于中间态改造目的是让代码先对齐 v5 的数据模型再平滑过渡到 v6/v7。一、最大变化消息格式从content迁移到partsv5 最核心的破坏性变更在于消息体的数据结构v4 用单一的content字符串承载用户与助手消息而 v5 改为parts数组将一段消息拆分为多个结构化片段text、reasoning、file、tool 等。// v4 const message { id: 1, role: user, content: Hello }; // v5 const message { id: 1, role: user, parts: [{ type: text, text: Hello }] };这意味着所有直接构造消息、读取message.content、或在 UI 层渲染消息的代码都需要同步调整。好消息是你不需要手动迁移已存储的历史消息。AIChatAgent在加载会话时会通过autoTransformMessages()自动把旧格式消息转换为 v5 格式。这一自动迁移覆盖面很广包括v4 的content字符串v4 的toolInvocations工具调用记录reasoning推理片段file文件数据database64 →urldata URI历史上各种畸形格式例如content被错误地序列化成数组、工具input为null/字符串/数组等二、导入路径与类型名变更v5 中UI 相关的类型与 React Hook 被拆分到了独立的ai-sdk/react包// v4 import type { Message } from ai; import { useChat } from ai/react; // v5 import type { UIMessage } from ai; import { useChat } from ai-sdk/react;逐项替换建议项目v4v5消息类型import type { Message } from aiimport type { UIMessage } from aiReact Hookimport { useChat } from ai/reactimport { useChat } from ai-sdk/react需要注意Message服务端模型消息与UIMessageUI 消息含parts数组在语义上也不再混用后续升级 v6 时CoreMessage还会进一步更名为ModelMessage详见 v6 迁移指南 的Breaking changes部分。三、工具定义parameters改名为inputSchemav5 将工具定义的入参 schema 字段从parameters更名为inputSchema其余结构不变// v4 const tools { weather: { description: Get weather, parameters: z.object({ city: z.string() }), execute: async ({ city }) fetchWeather(city) } }; // v5 const tools { weather: { description: Get weather, inputSchema: z.object({ city: z.string() }), execute: async ({ city }) fetchWeather(city) } };这是一个纯字段改名execute的入参解构方式不受影响。如果代码库中存在通过反射读取parameters键名例如动态注册工具、序列化 schema的逻辑需要一并更新。后续 v6 还推荐把服务端工具用tool()工厂函数包裹以获得完整的 Zod 类型推导并将toolsRequiringConfirmation换成服务端工具的needsApproval详见 v6 迁移指南。四、流式事件变化新增text-start/text-endtextDelta改名为deltav5 在文本增量之外新增了text-start文本片段开始与text-end文本片段结束两个事件同时把文本增量字段textDelta改名为delta// v4 chunk.type text-delta chunk.textDelta; // v5 chunk.type text-delta chunk.delta; // 新增事件text-start 与 text-end如果你在客户端自行处理流式 chunk而非交给useChat需要同时适配这三处识别text-start/text-end用于精确标记文本渲染边界例如流式打字机的开始/结束光标状态并将textDelta读取改为delta。仓库中 packages/agents/src/chat/message-builder.ts 的applyChunkToParts是这一事件模型的底层实现参照——它处理了text-start/text-delta/text-end、reasoning-start/reasoning-delta/reasoning-end、file、tool-input-start/tool-input-delta/tool-input-available/tool-input-error、tool-output-available/tool-output-error、step-start以及自定义data-*等全部 chunk 类型可用于校验你对流式协议的假设。五、迁移检查清单不安装 v5 也能完成官方推荐的做法是不必真的安装 AI SDK v5而是把 v4 代码按 v5 的 API 形状做一次中间态改造然后直接跳到 v6/v7。完整清单如下先按本页清单完成中间态改造不安装 v5随后继续执行 v6 迁移指南 并安装其中列出的受支持主版本ai^6、ai-sdk/react^3、ai-sdk/openai^3等将import type { Message }替换为import type { UIMessage }将ai/react导入替换为ai-sdk/react将工具定义中的parameters重命名为inputSchema运行npm run typecheck修复剩余类型错误agents仓库根目录与各packages/*下均有对应 typecheck 脚本测试你的应用——历史存储消息会被自动迁移无需手工改写数据库中的旧会话数据。六、自动迁移的底层原理源码解读6.1 迁移工具集的导出与状态迁移逻辑集中在 packages/ai-chat/src/ai-chat-v5-migration.ts并从 packages/ai-chat/src/index.ts 以autoTransformMessages的方式被AIChatAgent内部引用。该模块也作为独立子路径cloudflare/ai-chat/ai-chat-v5-migration导出见 packages/ai-chat/package.json 的exports字段。import { autoTransformMessages, // AIChatAgent 内部自动使用 migrateMessagesToUIFormat, // 已弃用 —— 请改用 autoTransformMessages analyzeCorruption // 已弃用 —— 仅用于排查历史脏数据 } from cloudflare/ai-chat/ai-chat-v5-migration;这些工具可用但极少需要手动调用因为迁移已自动化autoTransformMessages会在消息加载、写入缓存、序列化历史等多个入口被调用。仅当你需要诊断历史数据异常时才在开发环境临时调用analyzeCorruption。6.2 识别与转换的核心逻辑迁移器首先用类型守卫判断消息是否已经是 v5UIMessage格式isUIMessage存在parts且为数组若已是新格式则直接原样返回不做任何拷贝——这保证了正常路径零开销。对旧格式消息转换流程按以下顺序构建partsreasoningv4 顶层reasoning字段 →{ type: reasoning, text }toolInvocationsv4 的toolInvocations[]→{ type: \tool-${toolName}, toolCallId, state, input: args, output: result }其中状态按下表映射源码中的STATE_MAP 常量v4 状态v5 状态partial-callinput-streamingcallinput-availableresultoutput-availableerroroutput-errorfile 片段v4 遗留的datamimeType→ v5 的url自动拼装为data:${mimeType};base64,${data}data URI与mediaTypecontent 为数组的畸形格式{ role, content: [{ type: text, text }] }即isCorruptArrayMessage命中的情况→ 逐个元素转为对应 part兜底以上都未命中时字符串content→{ type: text, text }非字符串则JSON.stringify后写入文本 part连content都没有时生成默认空文本 part。此外还会处理role data到system的归一化以及缺失id时用消息下标生成msg-${index}兜底 ID。6.3 关键细节工具输入的自愈normalizeToolInput迁移器对已处于 v5 格式但工具input畸形的消息也会做自愈处理。normalizeToolPartInputs调用packages/agents/src/chat/message-builder.ts中导出的normalizeToolInput其规则为普通对象原样返回changed: false以{开头且可被JSON.parse为普通对象的字符串 → 解析为对象如测试用例中的{prompt:a cat}其余一切null、undefined、、数组、数字、不可解析的 JSON→ 统一收敛为{}。为什么要这么做因为 Anthropic Messages API 会直接拒绝tool_use块中input不是对象的消息。历史会话中若持久化了null、字符串化 JSON 或缺失input键JSON 序列化undefined会直接丢弃该键例如工具调用在tool-input-start阶段被打断后续每一轮对话都会 400 报错且该会话会在重连/重部署/驱逐后一直卡死。在加载时自愈此时没有框架侧的convertToModelMessages可以挂钩即可让这类会话无需逐条手术式修改 Durable Object 存储就能恢复。且该函数只触碰畸形消息健康消息按原引用返回持久化缓存保持零成本。6.4 在 AIChatAgent 中的接入点从 packages/ai-chat/src/index.ts 的源码可见autoTransformMessages被接入在几个关键路径_hydrateMessages()第 2329 行每次唤醒时按hydrationByteBudget预算读取会话历史后统一执行this.messages autoTransformMessages(messages)——这是启动路径上唯一的历史读取点后续变更全部走 Sessions 变更流#messageForCache()第 2378 行将每条写入结果转成内存态时再次过迁移器保证持久层旧数据进入缓存即已是新格式#streamMessagesAsJson()第 2405 行将整个会话记录以分块 JSON 流输出时同样逐条迁移保证暴露给前端的历史也是 v5 格式此外isValidMessageStructure()第 272 行会先校验消息的id非空字符串、roleuser/assistant/system、parts数组三项最小结构非法消息直接跳过并打印[AIChatAgent] Skipping invalid message ...警告避免下游convertToModelMessages或 UI 层崩溃。6.5 测试覆盖迁移逻辑的测试集中在 packages/ai-chat/src/tests/migration.test.ts覆盖了v5 消息原样透传同一引用、畸形工具input空串/null/数组/数字/缺失键/字符串化 JSON的自愈、健康工具消息不动、v4 字符串 content 转 text part、工具调用及四种状态映射、畸形数组 content、reasoning 字段、file partdata → url、data角色映射、fallback id 生成以及混合格式消息数组与空数组的批处理。如果你在升级后遇到历史消息兼容问题可先对照这些用例定位是哪种格式未被覆盖。七、弃用 API 一览已弃用替代方案说明migrateMessagesToUIFormat()autoTransformMessages()直接调用会触发一次性console.warn弃用提示下个大版本将被移除needsMigration()无自动迁移迁移已自动化无需预判analyzeCorruption()仅用于调试历史数据返回total/clean/legacyString/corruptArray/unknown统计及各分类示例消息源码中通过_deprecationWarningsSetstring实现每 key 每会话只警告一次的机制避免刷屏。八、继续升级到 v6下一步做什么完成本页的中间态改造后请继续阅读 v6 迁移指南。要点预告安装命令npm install ai^6 ai-sdk/react^3 ai-sdk/openai^3锁定 v6 兼容主版本避免误装 v7convertToModelMessages()变为 async需补awaitCoreMessage→ModelMessage、convertToCoreMessages()→convertToModelMessages()推荐将静态工具定义移到服务端用tool()包裹用needsApproval取代toolsRequiringConfirmation客户端用useAgentChat的onToolCall回调执行客户端工具相关文档见 Human in the Loop 与 Client Tools Continuation。九、常见问题速查Q升级后历史会话里的老消息会丢吗不会。AIChatAgent在加载、写缓存、流式导出三条路径上都执行autoTransformMessages()旧content字符串、toolInvocations、reasoning、file 数据都会被自动转成 v5parts无需手工迁移数据库。Q迁移器会不会改变未受影响的消息不会。已是合法 v5 格式的消息按原引用返回测试用例断言toBe(msg)持久化缓存保持无操作。Q工具调用状态字段去哪了v4 的toolInvocations[].statepartial-call/call/result/error迁移后进入parts对应 part 的state字段取值映射为input-streaming/input-available/output-available/output-error。Q升级过程中需要装 v5 吗不需要也不建议。当前agents与cloudflare/ai-chat支持的是 v6/v7见 packages/ai-chat/package.json 的 peerDependencies请按本页改造后直接升级到 v6/v7。Q工具input不是对象会导致什么后果Anthropic Messages API 会拒绝tool_use块的非法input会话后续每轮都 400 且持续卡死。迁移器在加载时通过normalizeToolInput将其收敛为{}来解卡。【免费下载链接】agentsBuild and deploy AI Agents on Cloudflare项目地址: https://gitcode.com/GitHub_Trending/agents1/agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考