跳转到内容
搜索文档

调用 LLM

最后更新 查看 MarkdownAgent 设置

Agent 改变了你使用 LLM 的方式。在无状态 Worker 中,每次请求都从零开始——你重建上下文、调用模型、返回响应,然后遗忘一切。Agent 在调用之间保留状态,通过 WebSocket 与客户端保持连接,并可在无用户在场时按自己的计划调用模型。

本页介绍在 stateful Agent 内调用 LLM 时可能出现的模式。有关 provider 设置与代码示例,请参阅使用 AI 模型

状态即上下文

每个 Agent 都有内置的 SQL 数据库 与键值状态。Agent 将对话存储在自身存储中并从中构建 prompt,而不是在每次请求时从客户端传递完整对话历史。

import { Agent } from "agents";

export class ResearchAgent extends Agent {
	async buildPrompt(userMessage) {
		const history = this.sql`
			SELECT role, content FROM messages
			ORDER BY timestamp DESC LIMIT 50`;

		const preferences = this.sql`
			SELECT key, value FROM user_preferences`;

		return [
			{ role: "system", content: this.systemPrompt(preferences) },
			...history.reverse(),
			{ role: "user", content: userMessage },
		];
	}
}
import { Agent } from "agents";

export class ResearchAgent extends Agent<Env> {
	async buildPrompt(userMessage: string) {
		const history = this.sql<{ role: string; content: string }>`
			SELECT role, content FROM messages
			ORDER BY timestamp DESC LIMIT 50`;

		const preferences = this.sql<{ key: string; value: string }>`
			SELECT key, value FROM user_preferences`;

		return [
			{ role: "system", content: this.systemPrompt(preferences) },
			...history.reverse(),
			{ role: "user", content: userMessage },
		];
	}
}

这意味着客户端无需在每条消息中发送完整对话。Agent 拥有历史,可以裁剪、用检索文档丰富,或在发送给模型前摘要较早的轮次。

经受断连

DeepSeek R1 或 GLM-4 等推理模型可能需要 30 秒到数分钟才能响应。在无状态请求-响应架构中,客户端必须全程保持连接。若连接断开,响应会丢失。

Agent 在客户端断开后仍继续运行。当响应到达时,Agent 可将其持久化到状态,并在客户端重连时交付——即使相隔数小时或数天。

import { Agent } from "agents";
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class MyAgent extends Agent {
	async onMessage(connection, message) {
		const { prompt } = JSON.parse(message);
		const workersai = createWorkersAI({ binding: this.env.AI });

		const result = streamText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt,
		});

		for await (const chunk of result.textStream) {
			connection.send(JSON.stringify({ type: "chunk", content: chunk }));
		}

		this.sql`INSERT INTO responses (prompt, response, timestamp)
			VALUES (${prompt}, ${await result.text}, ${Date.now()})`;
	}
}
import { Agent } from "agents";
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class MyAgent extends Agent<Env> {
	async onMessage(connection: Connection, message: WSMessage) {
		const { prompt } = JSON.parse(message as string);
		const workersai = createWorkersAI({ binding: this.env.AI });

		const result = streamText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt,
		});

		for await (const chunk of result.textStream) {
			connection.send(JSON.stringify({ type: "chunk", content: chunk }));
		}

		this.sql`INSERT INTO responses (prompt, response, timestamp)
			VALUES (${prompt}, ${await result.text}, ${Date.now()})`;
	}
}

使用 AIChatAgent 时,消息会持久化到 SQLite,流在重连时可恢复——这一切自动处理。

自主模型调用

Agent 无需用户请求即可调用模型。你可以调度模型在后台运行——用于夜间摘要、定期分类、监控,或任何无需人工交互的任务。

import { Agent } from "agents";

export class DigestAgent extends Agent {
	async onStart() {
		this.schedule("0 8 * * *", "generateDailyDigest", {});
	}

	async generateDailyDigest() {
		const articles = this.sql`
			SELECT title, body FROM articles
			WHERE created_at > datetime('now', '-1 day')`;

		const workersai = createWorkersAI({ binding: this.env.AI });
		const { text } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: `Summarize these articles:\n${articles.map((a) => a.title + ": " + a.body).join("\n\n")}`,
		});

		this.sql`INSERT INTO digests (summary, created_at)
			VALUES (${text}, ${Date.now()})`;

		this.broadcast(JSON.stringify({ type: "digest", summary: text }));
	}
}
import { Agent } from "agents";

export class DigestAgent extends Agent<Env> {
	async onStart() {
		this.schedule("0 8 * * *", "generateDailyDigest", {});
	}

	async generateDailyDigest() {
		const articles = this.sql<{ title: string; body: string }>`
			SELECT title, body FROM articles
			WHERE created_at > datetime('now', '-1 day')`;

		const workersai = createWorkersAI({ binding: this.env.AI });
		const { text } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: `Summarize these articles:\n${articles.map((a) => a.title + ": " + a.body).join("\n\n")}`,
		});

		this.sql`INSERT INTO digests (summary, created_at)
			VALUES (${text}, ${Date.now()})`;

		this.broadcast(JSON.stringify({ type: "digest", summary: text }));
	}
}

多模型流水线

由于 Agent 在调用之间保持状态,你可以在单个方法中串联多个模型——用快速模型做分类、推理模型做规划、嵌入模型做检索——且步骤之间不丢失上下文。

import { Agent } from "agents";
import { generateText, embed } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class TriageAgent extends Agent {
	async triage(ticket) {
		const workersai = createWorkersAI({ binding: this.env.AI });

		const { text: category } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: `Classify this support ticket into one of: billing, technical, account. Ticket: ${ticket}`,
		});

		const { embedding } = await embed({
			model: workersai("@cf/baai/bge-base-en-v1.5"),
			value: ticket,
		});
		const similar = await this.env.VECTOR_DB.query(embedding, { topK: 5 });

		const { text: response } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: `Draft a response for this ${category} ticket. Similar resolved tickets: ${JSON.stringify(similar)}. Ticket: ${ticket}`,
		});

		this.sql`INSERT INTO tickets (content, category, response, created_at)
			VALUES (${ticket}, ${category}, ${response}, ${Date.now()})`;

		return { category, response };
	}
}
import { Agent } from "agents";
import { generateText, embed } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class TriageAgent extends Agent<Env> {
	async triage(ticket: string) {
		const workersai = createWorkersAI({ binding: this.env.AI });

		const { text: category } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: `Classify this support ticket into one of: billing, technical, account. Ticket: ${ticket}`,
		});

		const { embedding } = await embed({
			model: workersai("@cf/baai/bge-base-en-v1.5"),
			value: ticket,
		});
		const similar = await this.env.VECTOR_DB.query(embedding, { topK: 5 });

		const { text: response } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: `Draft a response for this ${category} ticket. Similar resolved tickets: ${JSON.stringify(similar)}. Ticket: ${ticket}`,
		});

		this.sql`INSERT INTO tickets (content, category, response, created_at)
			VALUES (${ticket}, ${category}, ${response}, ${Date.now()})`;

		return { category, response };
	}
}

每个中间结果在方法执行期间保留在 Agent 内存中,最终结果持久化到 SQL 供日后参考。

缓存与成本控制

持久化存储意味着你可以缓存模型响应,避免冗余调用。这对嵌入或长推理链等昂贵操作尤其有用。

import { Agent } from "agents";

export class CachingAgent extends Agent {
	async cachedGenerate(prompt) {
		const cached = this.sql`
			SELECT response FROM llm_cache WHERE prompt = ${prompt}`;

		if (cached.length > 0) {
			return cached[0].response;
		}

		const workersai = createWorkersAI({ binding: this.env.AI });
		const { text } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt,
		});

		this.sql`INSERT INTO llm_cache (prompt, response, created_at)
			VALUES (${prompt}, ${text}, ${Date.now()})`;

		return text;
	}
}
import { Agent } from "agents";

export class CachingAgent extends Agent<Env> {
	async cachedGenerate(prompt: string) {
		const cached = this.sql<{ response: string }>`
			SELECT response FROM llm_cache WHERE prompt = ${prompt}`;

		if (cached.length > 0) {
			return cached[0].response;
		}

		const workersai = createWorkersAI({ binding: this.env.AI });
		const { text } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt,
		});

		this.sql`INSERT INTO llm_cache (prompt, response, created_at)
			VALUES (${prompt}, ${text}, ${Date.now()})`;

		return text;
	}
}

对于跨多个 agent 的 provider 级缓存与速率限制管理,使用 AI Gateway

后续步骤

使用 AI 模型

Workers AI、OpenAI、Anthropic 等的 provider 设置、流式与代码示例。

Chat agents

AIChatAgent 自动处理消息持久化、可恢复流式与工具。

调度任务

按延迟、计划或 cron 运行自主模型调用。

这篇文档对您有帮助吗?