本示例演示了如何使用 @cloudflare/codemode ↗ 库和 Agents SDK ↗ 构建一个 agent,该 agent 的 LLM 通过编写代码来编排工具调用,而不是一次调用一个。这种称为 Code Mode ↗ 的方法可减少高达 80% 的 token 消耗,返回更好的结果,并避免上下文窗口膨胀。
本示例向您展示如何:
- 将工具定义为带有 Zod schema 的普通函数
- 使用
createCodeTool将您的工具作为一个单独的“编写代码 (write code)”工具暴露给 LLM - 使用
DynamicWorkerExecutor安全地运行 LLM 生成的代码 - 使用
AIChatAgent将它们组装起来,通过 WebSocket 处理聊天
该 agent 使用 @cloudflare/codemode ↗ 库和 Agents SDK ↗ 中的三个组件:
AIChatAgent(@cloudflare/ai-chat),您的 agent 的基类。处理 WebSocket 聊天,持久化消息并调用 LLM。createCodeTool(@cloudflare/codemode/ai),将您的工具包装成一个接受{ code: string }的单一codemode工具。DynamicWorkerExecutor(@cloudflare/codemode),在隔离的 Dynamic Worker 中运行 LLM 生成的代码。
流程:
- 用户通过 WebSocket 发送消息。
AIChatAgent将其传递给 LLM,只有单一的工具可用:codemode。- LLM 编写 JavaScript 代码(例如
const projects = await codemode.listProjects()),而不是进行单独的工具调用。 DynamicWorkerExecutor启动一个隔离的 Worker 并运行代码。在沙箱内部,codemode.listProjects()会通过 Workers RPC 调用您真正的listProjects实现。- 结果、任何控制台输出以及错误将一并返回给 LLM。
- LLM 使用结果响应用户,或者如果需要的话编写更多代码。
DynamicWorkerExecutor 是 @cloudflare/codemode 库的一部分。当 LLM 编写了编排您工具的代码时,这些代码需要在一个安全的地方运行。DynamicWorkerExecutor 使用 Worker Loader 绑定,为每次执行启动一个隔离的 Dynamic Worker。在沙箱内部:
- 一个
codemode代理对象将诸如codemode.createTask(...)的调用通过 Workers RPC 路由回您真实的工具实现 - 将
globalOutbound设置为null以阻止fetch(),以便代码只能通过您的工具连接外部世界 console.log的输出会被捕获并与结果一起返回- 每次执行都有其自己的具有 30 秒超时的 Worker 实例
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
const executor = new DynamicWorkerExecutor({
loader: env.LOADER, // WorkerLoader binding from wrangler.jsonc
timeout: 30000, // default: 30s
globalOutbound: null, // null = fetch blocked
});import { DynamicWorkerExecutor } from "@cloudflare/codemode";
const executor = new DynamicWorkerExecutor({
loader: env.LOADER, // WorkerLoader binding from wrangler.jsonc
timeout: 30000, // default: 30s
globalOutbound: null, // null = fetch blocked
});createCodeTool 是 @cloudflare/codemode 的一部分。它接受您的工具和一个 executor,并返回一个单一的 AI SDK tool()。它负责:
- 从您工具的 Zod schema 生成 TypeScript 类型声明,以便 LLM 知道哪些内容可用以及参数形状是怎样的。
- 将这些类型放在该工具的描述中,因此 LLM 看到的是一个参数为
{ code: string }的单一工具,并且描述包含了完整的类型化 API 表面。 - 在执行时,规范化 LLM 的代码(剥离 markdown 栅栏,将裸露的语句包装在异步函数中,自动返回最后一个表达式),然后将其传递给 executor。
import { createCodeTool } from "@cloudflare/codemode/ai";
const codemode = createCodeTool({
tools: myTools, // Record<string, tool()> with Zod schemas
executor, // DynamicWorkerExecutor
});
// The LLM sees: one tool called "codemode" with input { code: string }
// The description includes TypeScript types for all your toolsimport { createCodeTool } from "@cloudflare/codemode/ai";
const codemode = createCodeTool({
tools: myTools, // Record<string, tool()> with Zod schemas
executor, // DynamicWorkerExecutor
});
// The LLM sees: one tool called "codemode" with input { code: string }
// The description includes TypeScript types for all your toolsLLM 会编写一个异步箭头函数。createCodeTool 会对其进行规范化并传递给 executor。executor 构建一个带有 codemode 代理的 Worker 模块,运行代码,并返回 { code, result, logs }。