Callable 方法允许前端调用 Agent 上的方法。使用 @callable() 标记方法后,通过 useAgent 或 AgentClient 连接的客户端就能通过类型化 stub 调用它,如同调用本地 async 函数一样。可将它们用于用户执行的操作,例如添加项目、批准步骤或停止运行。
@callable() 是 Agent 类在 WebSockets capability 上声明 callable 的方式。调用通过客户端的 WebSocket 连接传输。有关超时、错误和传输的信息,请参阅 Callable。
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 });
}
}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 用于 Worker 外部的客户端。当 Worker 或另一个 Agent 调用 Agent 时,请改用 Durable Object RPC:通过 getAgentByName() 获取 stub 并调用任何 public 方法,无需 decorator。有关详细信息,请参阅路由。
@callable() 是 TC39 标准 decorator ↗。如果开发服务器因 SyntaxError: Invalid or unexpected token 而失败:
-
添加
agents/viteplugin,它会添加 Vite 的 Oxc transpiler 所缺少的 decorator transform:vite.config.tsts import agents from "agents/vite"; export default defineConfig({ plugins: [agents(), react(), cloudflare()], }); -
在
tsconfig.json中扩展agents/tsconfig,或自行设置"target": "ES2021":tsconfig.jsonjson { "extends": "agents/tsconfig" }