跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

可调用方法

最后更新 查看 MarkdownAgent 设置

Callable 方法允许前端调用 Agent 上的方法。使用 @callable() 标记方法后,通过 useAgent 或 AgentClient 连接的客户端就能通过类型化 stub 调用它,如同调用本地 async 函数一样。可将它们用于用户执行的操作,例如添加项目、批准步骤或停止运行。

@callable() 是 Agent 类在 WebSockets capability 上声明 callable 的方式。调用通过客户端的 WebSocket 连接传输。有关超时、错误和传输的信息,请参阅 Callable。

将方法标记为 callable

src/server.jsjs
import { Agent, callable } from "agents";

export class CounterAgent extends Agent {
	initialState = { count: 0 };

	@callable()
	increment(by) {
		if (!Number.isInteger(by)) throw new Error("by must be an integer");
		this.setState({ count: this.state.count + by });
		return this.state.count;
	}

	// Not decorated, so clients cannot call it.
	reset() {
		this.setState({ count: 0 });
	}
}
src/server.tsts
import { Agent, callable } from "agents";

export type CounterState = { count: number };

export class CounterAgent extends Agent<Env, CounterState> {
	initialState: CounterState = { count: 0 };

	@callable()
	increment(by: number): number {
		if (!Number.isInteger(by)) throw new Error("by must be an integer");
		this.setState({ count: this.state.count + by });
		return this.state.count;
	}

	// Not decorated, so clients cannot call it.
	reset() {
		this.setState({ count: 0 });
	}
}

任何已连接的客户端都可以调用 callable 方法,因此应将其参数视为不受信任的输入。只有经过 decorator 标记的方法才可调用。

从客户端调用

将你的 Agent 类作为 useAgent 的类型参数传入。随后,agent.stub 将具有相同的方法、参数和返回类型:

import { useAgent } from "agents/react";
import type { CounterAgent } from "./server";

export function Counter() {
	const agent = useAgent<CounterAgent>({ agent: "CounterAgent", name: "demo" });

	const add = async () => {
		const count = await agent.stub.increment(1);
		console.log(count);
	};

	return <button onClick={add}>+1</button>;
}

agent.call("increment", [1]) 可以完成相同操作,但不提供类型。当方法抛出异常时,客户端的 promise 会使用错误消息拒绝。

流式传输结果

设置 streaming: true 可在结果生成时发送结果。方法会接收 StreamingResponse 作为其第一个参数:

import { Agent, callable } from "agents";
import { streamText } from "ai";
import { createAI } from "agents/models/ai-sdk";

export class WriterAgent extends Agent {
	@callable({ streaming: true })
	async write(stream, prompt) {
		const ai = createAI({ binding: this.env.AI });
		const result = streamText({
			model: ai("anthropic/claude-opus-5.5"),
			prompt,
		});
		for await (const text of result.textStream) {
			stream.send(text);
		}
		stream.end();
	}
}
import { Agent, callable, type StreamingResponse } from "agents";
import { streamText } from "ai";
import { createAI } from "agents/models/ai-sdk";

export class WriterAgent extends Agent<Env> {
	@callable({ streaming: true })
	async write(stream: StreamingResponse, prompt: string) {
		const ai = createAI({ binding: this.env.AI });
		const result = streamText({
			model: ai("anthropic/claude-opus-5.5"),
			prompt,
		});
		for await (const text of result.textStream) {
			stream.send(text);
		}
		stream.end();
	}
}

StreamingResponse 提供 send(chunk)、end(finalChunk?) 和 error(message)。在客户端使用 stream callback 读取 chunk:

await agent.call("write", ["Write a haiku"], {
	stream: {
		onChunk: (chunk) => console.log(chunk),
		onDone: () => console.log("done"),
		onError: (error) => console.error(error),
	},
});

描述方法

@callable({ description }) 会附加描述。this.getCallableMethods() 会返回一个 map,将每个 callable 方法的名称映射到其元数据;你可以使用它列出 Agent 的操作。

不应使用 callable 的情况

Callable 用于 Worker 外部的客户端。当 Worker 或另一个 Agent 调用 Agent 时,请改用 Durable Object RPC:通过 getAgentByName() 获取 stub 并调用任何 public 方法,无需 decorator。有关详细信息,请参阅路由。

设置 decorator

@callable() 是 TC39 标准 decorator ↗。如果开发服务器因 SyntaxError: Invalid or unexpected token 而失败:

  1. 添加 agents/vite plugin,它会添加 Vite 的 Oxc transpiler 所缺少的 decorator transform:

    vite.config.tsts
    import agents from "agents/vite";
    
    export default defineConfig({
     plugins: [agents(), react(), cloudflare()],
    });
  2. 在 tsconfig.json 中扩展 agents/tsconfig,或自行设置 "target": "ES2021":

    tsconfig.jsonjson
    {
     "extends": "agents/tsconfig"
    }

后续步骤

Callable

任何 Durable Object 上 callable 的超时、错误、类型化 stub 和传输。

这篇文档对您有帮助吗?