跳转到内容
搜索文档

AI SDK 集成

最后更新 查看 MarkdownAgent 设置

@cloudflare/codemode/ai 入口将 AI SDK 工具转换为一个 Code Mode 工具。模型编写调用工具的 JavaScript,执行器在隔离沙箱中运行该代码。

在两种集成模式间选择:

模式 用例 审批行为
createCodeTool() 一个或多个工具提供商的简单无状态执行 排除使用 needsApproval 的工具
ToolSetConnectortoolSetConnector() 通过 Code Mode 运行时的持久执行 needsApproval 映射到持久运行时审批

创建无状态 Code Mode tool

createCodeTool() 接受 AI SDK ToolSet 或工具提供商数组。还需要执行器。返回标准 AI SDK 工具,供 streamText()generateText() 使用。

  1. 安装 Code Mode、AI SDK 与 Zod:

    npm i @cloudflare/codemode agents ai zod
  2. DynamicWorkerExecutor 添加 Worker Loader 绑定:

    {
      "$schema": "./node_modules/wrangler/config-schema.json",
      // Set this to today's date
      "compatibility_date": "2026-08-17",
      "compatibility_flags": [
        "nodejs_compat"
      ],
      "worker_loaders": [
        {
          "binding": "LOADER"
        }
      ]
    }
    # Set this to today's date
    compatibility_date = "2026-08-17"
    compatibility_flags = ["nodejs_compat"]
    
    [[worker_loaders]]
    binding = "LOADER"
  3. 定义可执行的 AI SDK tool。Code Mode 使用其 schema 生成类型并在调用 execute 前验证参数。

    src/tools.jsjs
    import { tool } from "ai";
    import { z } from "zod";
    
    export const weatherTools = {
    	getWeather: tool({
    		description: "Get the weather for a city",
    		inputSchema: z.object({
    			city: z.string().describe("City name"),
    		}),
    		outputSchema: z.object({
    			city: z.string(),
    			conditions: z.string(),
    		}),
    		execute: async ({ city }) => ({
    			city,
    			conditions: "sunny",
    		}),
    	}),
    };
    src/tools.tsts
    import { tool } from "ai";
    import { z } from "zod";
    
    export const weatherTools = {
      getWeather: tool({
        description: "Get the weather for a city",
        inputSchema: z.object({
          city: z.string().describe("City name")
        }),
        outputSchema: z.object({
          city: z.string(),
          conditions: z.string()
        }),
        execute: async ({ city }) => ({
          city,
          conditions: "sunny"
        })
      })
    };

    每个沙箱可调用 tool 需要 execute 函数。Client-side 或 provider 执行的 tool 无法通过此 server-side executor 运行。

  4. 创建 Code Mode tool 并传给 AI SDK model 调用:

    src/index.jsjs
    import { DynamicWorkerExecutor } from "@cloudflare/codemode";
    import { createCodeTool } from "@cloudflare/codemode/ai";
    import { generateText, stepCountIs } from "ai";
    import { model } from "./model";
    import { weatherTools } from "./tools";
    
    export default {
    	async fetch(request, env) {
    		const executor = new DynamicWorkerExecutor({ loader: env.LOADER });
    		const codemode = createCodeTool({ tools: weatherTools, executor });
    
    		const response = await generateText({
    			model,
    			prompt: await request.text(),
    			tools: { codemode },
    			stopWhen: stepCountIs(5),
    		});
    
    		return new Response(response.text);
    	},
    };
    src/index.tsts
    import { DynamicWorkerExecutor } from "@cloudflare/codemode";
    import { createCodeTool } from "@cloudflare/codemode/ai";
    import { generateText, stepCountIs } from "ai";
    import { model } from "./model";
    import { weatherTools } from "./tools";
    
    export default {
     	async fetch(request, env): Promise<Response> {
     		const executor = new DynamicWorkerExecutor({ loader: env.LOADER });
     		const codemode = createCodeTool({ tools: weatherTools, executor });
    
     		const response = await generateText({
     			model,
     			prompt: await request.text(),
     			tools: { codemode },
     			stopWhen: stepCountIs(5),
     		});
    
     		return new Response(response.text);
     	},
    } satisfies ExportedHandler<Env>;

示例使用 generateText() 获取完整响应。可将相同 codemode tool 传给 streamText() 以流式传输。生成的 tool 描述包含 getWeather 的 TypeScript 定义。模型仍编写 JavaScript,例如:

async () => {
	const weather = await codemode.getWeather({ city: "Lisbon" });
	return weather.conditions;
};

默认命名空间为 codemodecreateCodeTool() 也接受自定义 description。在 Code Mode 应插入生成定义处包含 {{types}}

用 provider 组织 tool

Tool provider 将 tool 分组到一个沙箱命名空间下。每个 tool 属于 codemode.* 时直接传递 tool set。

与其他包的 provider 组合 AI SDK tool 时使用 aiTools()。以下可选 workspace 示例还需要 @cloudflare/shell

npm i @cloudflare/shell
import { AIChatAgent } from "@cloudflare/ai-chat";
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { aiTools, createCodeTool } from "@cloudflare/codemode/ai";
import { Workspace } from "@cloudflare/shell";
import { stateTools } from "@cloudflare/shell/workers";
import { weatherTools } from "./tools";

export class Chat extends AIChatAgent {
	workspace = new Workspace({ sql: this.ctx.storage.sql });

	codemodeTool() {
		return createCodeTool({
			tools: [aiTools(weatherTools), stateTools(this.workspace)],
			executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
		});
	}
}
import { AIChatAgent } from "@cloudflare/ai-chat";
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { aiTools, createCodeTool } from "@cloudflare/codemode/ai";
import { Workspace } from "@cloudflare/shell";
import { stateTools } from "@cloudflare/shell/workers";
import { weatherTools } from "./tools";

export class Chat extends AIChatAgent<Env> {
	workspace = new Workspace({ sql: this.ctx.storage.sql });

	codemodeTool() {
		return createCodeTool({
			tools: [aiTools(weatherTools), stateTools(this.workspace)],
			executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
		});
	}
}

此示例将 AI SDK tool 暴露为 codemode.*,workspace tool 为 state.*

要分配自定义命名空间,改为传递 provider 对象:

const executor = new DynamicWorkerExecutor({ loader: env.LOADER });

const codemode = createCodeTool({
	tools: [
		{ name: "weather", tools: weatherTools },
		{ name: "notifications", tools: notificationTools },
	],
	executor,
});
const executor = new DynamicWorkerExecutor({ loader: env.LOADER });

const codemode = createCodeTool({
	tools: [
		{ name: "weather", tools: weatherTools },
		{ name: "notifications", tools: notificationTools },
	],
	executor,
});

生成的代码可调用 weather.getWeather()notifications.send()。Provider 名称须唯一且为有效 JavaScript 标识符。

将 AI SDK 工具与持久运行时一起使用

当运行需要持久状态时使用 ToolSetConnector 或其 toolSetConnector() 便利函数。连接器将 AI SDK ToolSet 适配 createCodemodeRuntime()。辅助函数返回 new ToolSetConnector(ctx, options)

在 Agent 或另一 Durable Object 内创建 connector:

src/server.jsjs
import { AIChatAgent } from "@cloudflare/ai-chat";
import {
	createCodemodeRuntime,
	DynamicWorkerExecutor,
} from "@cloudflare/codemode";
import { toolSetConnector } from "@cloudflare/codemode/ai";
import { convertToModelMessages, streamText } from "ai";
import { model } from "./model";
import { operationTools } from "./tools";

// Export this manually when the @cloudflare/codemode/vite plugin is not configured.
export { CodemodeRuntime } from "@cloudflare/codemode";

export class OperationsAgent extends AIChatAgent {
	async onChatMessage() {
		const operations = toolSetConnector(this.ctx, {
			name: "operations",
			instructions: "Use these tools to manage customer requests.",
			tools: operationTools,
		});

		const runtime = createCodemodeRuntime({
			ctx: this.ctx,
			executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
			connectors: [operations],
		});

		const result = streamText({
			model,
			messages: await convertToModelMessages(this.messages),
			tools: { codemode: runtime.tool() },
		});

		return result.toUIMessageStreamResponse();
	}
}
src/server.tsts
import { AIChatAgent } from "@cloudflare/ai-chat";
import {
	createCodemodeRuntime,
	DynamicWorkerExecutor,
} from "@cloudflare/codemode";
import { toolSetConnector } from "@cloudflare/codemode/ai";
import { convertToModelMessages, streamText } from "ai";
import { model } from "./model";
import { operationTools } from "./tools";

// Export this manually when the @cloudflare/codemode/vite plugin is not configured.
export { CodemodeRuntime } from "@cloudflare/codemode";

export class OperationsAgent extends AIChatAgent<Env> {
	async onChatMessage() {
		const operations = toolSetConnector(this.ctx, {
			name: "operations",
			instructions: "Use these tools to manage customer requests.",
			tools: operationTools,
		});

		const runtime = createCodemodeRuntime({
			ctx: this.ctx,
			executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
			connectors: [operations],
		});

		const result = streamText({
			model,
			messages: await convertToModelMessages(this.messages),
			tools: { codemode: runtime.tool() },
		});

		return result.toUIMessageStreamResponse();
	}
}

示例手动导出 CodemodeRuntime。若按 创建持久 Code Mode 运行时 配置 Code Mode Vite 插件,移除该手动导出,因插件会添加。

省略 name 时连接器默认为 tools 命名空间。从无 execute 函数的工具中排除生成类型与沙箱绑定。

持久运行时添加执行日志、暂停/恢复行为与按需连接器发现。模型可用 codemode.search() 查找方法并用 codemode.describe() 检查类型。

审批行为

两种集成模式对 AI SDK 审批处理不同。

createCodeTool() 审批

createCodeTool() 过滤 needsApprovaltrue 或函数的工具。过滤的工具不出现在生成类型中,无法从沙箱代码运行。needsApproval: false 的工具仍可用。

此无状态路径不为 AI SDK 审批暂停执行。若工具需要 AI SDK 审批流程,在 Code Mode 外使用标准 AI SDK 工具。

ToolSetConnector 审批

ToolSetConnector 将 AI SDK needsApproval 映射到持久运行时的 requiresApproval 注解。调用该工具会暂停运行。应用可检查待处理操作并用 runtime.approve({ executionId }) 恢复同一执行。

函数值 needsApproval 无法在沙箱提供参数前求值。因此连接器将该工具视为始终需要审批。needsApproval: false 执行时不暂停。

此审批使用 Code Mode 运行时的持久暂停、审批与重放流程。不使用 AI SDK 按次审批流程。

这篇文档对您有帮助吗?