INTEGRITY Dokumentace

Začínáme

Sestavte chatovacího agenta s perzistentní pamětí, vestavěnými nástroji pro práci se soubory a streamováním, krok za krokem.

Pokud jste s Cloudflare Agents zcela noví, projděte si alespoň zběžně Co jsou agenti? nejprve kvůli základním konceptům. Jinak můžete postupovat podle tohoto textu od začátku.

Na konci tohoto tutoriálu budete mít agenta Think, který:

Předpoklady

1. Vytvořte projekt

mkdir my-think-agent && cd my-think-agent
npm init -y

Nainstalujte závislosti:

npm install @cloudflare/think @cloudflare/ai-chat agents ai @cloudflare/shell zod workers-ai-provider react react-dom
npm install -D wrangler @cloudflare/vite-plugin @cloudflare/workers-types @vitejs/plugin-react @tailwindcss/vite tailwindcss typescript vite

2. Nakonfigurujte wrangler

Vytvořit wrangler.jsonc:

{
	"name": "my-think-agent",
	"compatibility_date": "2026-01-28",
	"compatibility_flags": ["nodejs_compat"],
	"ai": { "binding": "AI" },
	"assets": {
		"not_found_handling": "single-page-application",
		"run_worker_first": ["/agents/*"]
	},
	"durable_objects": {
		"bindings": [{ "class_name": "MyAgent", "name": "MyAgent" }]
	},
	"migrations": [{ "new_sqlite_classes": ["MyAgent"], "tag": "v1" }],
	"main": "src/server.ts"
}
name = "my-think-agent"
compatibility_date = "2026-01-28"
compatibility_flags = [ "nodejs_compat" ]
main = "src/server.ts"

[ai]
binding = "AI"

[assets]
not_found_handling = "single-page-application"
run_worker_first = [ "/agents/*" ]

[[durable_objects.bindings]]
class_name = "MyAgent"
name = "MyAgent"

[[migrations]]
new_sqlite_classes = [ "MyAgent" ]
tag = "v1"

Vytvořit vite.config.ts:

import { cloudflare } from "@cloudflare/vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
	plugins: [react(), cloudflare(), tailwindcss()],
});
import { cloudflare } from "@cloudflare/vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
	plugins: [react(), cloudflare(), tailwindcss()],
});

Vytvořit tsconfig.json:

{
	"extends": "agents/tsconfig"
}

3. Definujte agenta

Vytvořit src/server.ts:

import { Think } from "@cloudflare/think";
import { createWorkersAI } from "workers-ai-provider";
import { routeAgentRequest } from "agents";

export class MyAgent extends Think {
	getModel() {
		return createWorkersAI({ binding: this.env.AI })(
			"@cf/moonshotai/kimi-k2.6",
		);
	}

	getSystemPrompt() {
		return "You are a helpful assistant with access to a workspace filesystem.";
	}
}

export default {
	async fetch(request, env) {
		return (
			(await routeAgentRequest(request, env)) ||
			new Response("Not found", { status: 404 })
		);
	},
};
import { Think } from "@cloudflare/think";
import { createWorkersAI } from "workers-ai-provider";
import { routeAgentRequest } from "agents";

export class MyAgent extends Think<Env> {
	getModel() {
		return createWorkersAI({ binding: this.env.AI })(
			"@cf/moonshotai/kimi-k2.6",
		);
	}

	getSystemPrompt() {
		return "You are a helpful assistant with access to a workspace filesystem.";
	}
}

export default {
	async fetch(request: Request, env: Env) {
		return (
			(await routeAgentRequest(request, env)) ||
			new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;

Toto je funkční agent. Think automaticky poskytuje:

4. Připojte klienta React

Vytvořit src/client.tsx:

import { createRoot } from "react-dom/client";
import { useAgent } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";

function Chat() {
	const agent = useAgent({ agent: "MyAgent" });
	const { messages, sendMessage, status } = useAgentChat({ agent });

	return (
		<div>
			<h1>Think Agent</h1>
			{messages.map((msg) => (
				<div key={msg.id}>
					<strong>{msg.role}:</strong>
					{msg.parts.map((part, i) =>
						part.type === "text" ? <span key={i}>{part.text}</span> : null,
					)}
				</div>
			))}

			<form
				onSubmit={(e) => {
					e.preventDefault();
					const input = e.currentTarget.elements.namedItem("input");
					if (!input.value.trim()) return;
					sendMessage({ text: input.value });
					input.value = "";
				}}
			>
				<input name="input" placeholder="Send a message..." />
				<button type="submit">Send</button>
			</form>

			<p>Status: {status}</p>
		</div>
	);
}

const root = document.getElementById("root");
if (root) {
	createRoot(root).render(<Chat />);
}
import { createRoot } from "react-dom/client";
import { useAgent } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";

function Chat() {
	const agent = useAgent({ agent: "MyAgent" });
	const { messages, sendMessage, status } = useAgentChat({ agent });

	return (
		<div>
			<h1>Think Agent</h1>
			{messages.map((msg) => (
				<div key={msg.id}>
					<strong>{msg.role}:</strong>
					{msg.parts.map((part, i) =>
						part.type === "text" ? <span key={i}>{part.text}</span> : null,
					)}
				</div>
			))}

			<form
				onSubmit={(e) => {
					e.preventDefault();
					const input = e.currentTarget.elements.namedItem(
						"input",
					) as HTMLInputElement;
					if (!input.value.trim()) return;
					sendMessage({ text: input.value });
					input.value = "";
				}}
			>
				<input name="input" placeholder="Send a message..." />
				<button type="submit">Send</button>
			</form>

			<p>Status: {status}</p>
		</div>
	);
}

const root = document.getElementById("root");
if (root) {
	createRoot(root).render(<Chat />);
}

Vytvořit index.html:

<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Think Agent</title>
	</head>
	<body>
		<div id="root"></div>
		<script type="module" src="/src/client.tsx"></script>
	</body>
</html>

5. Spusťte to

npx vite dev

Otevřete prohlížeč a odešlete zprávu. Agent odpoví streamovaným textem a modelu jsou automaticky k dispozici nástroje pro práci se soubory workspace.

6. Přidejte trvalou paměť

Přepsat configureSession k poskytnutí zapisovatelné paměti modelu, která přežije restarty:

export class MyAgent extends Think {
	getModel() {
		return createWorkersAI({ binding: this.env.AI })(
			"@cf/moonshotai/kimi-k2.6",
		);
	}

	configureSession(session) {
		return session
			.withContext("soul", {
				provider: {
					get: async () =>
						"You are a helpful assistant. Remember important facts about the user.",
				},
			})
			.withContext("memory", {
				description: "Important facts about the user and conversation.",
				maxTokens: 2000,
			})
			.withCachedPrompt();
	}
}
export class MyAgent extends Think<Env> {
	getModel(): LanguageModel {
		return createWorkersAI({ binding: this.env.AI })(
			"@cf/moonshotai/kimi-k2.6",
		);
	}

	configureSession(session: Session) {
		return session
			.withContext("soul", {
				provider: {
					get: async () =>
						"You are a helpful assistant. Remember important facts about the user.",
				},
			})
			.withContext("memory", {
				description: "Important facts about the user and conversation.",
				maxTokens: 2000,
			})
			.withCachedPrompt();
	}
}

Nyní model vidí MEMORY sekci ve svém systémovém promptu a získá set_context nástroj k jeho aktualizaci. Fakta zapsaná do paměti se ukládají v SQLite a přežijí hibernaci i restart Durable Object.

Když používáte configureSession, systémový prompt se sestavuje z kontextových bloků, nikoli z getSystemPrompt(). "soul" blok výše slouží jako systémová identita: je pouze pro čtení a vždy se zobrazuje jako první. "memory" blok je zapisovatelný a model ho proaktivně aktualizuje, kdykoli se dozví něco užitečného.

Viz Dokumentace Sessions pro kontextové bloky, kompakci, vyhledávání, skills a podporu více relací.

7. Přidejte vlastní nástroje

Přepsat getTools() pro přidání vlastních nástrojů vedle vestavěných nástrojů pracovního prostoru:

import { tool } from "ai";
import { z } from "zod";

export class MyAgent extends Think {
	getModel() {
		/* ... */
	}
	configureSession(session) {
		/* ... */
	}

	getTools() {
		return {
			getWeather: tool({
				description: "Get the current weather for a city",
				inputSchema: z.object({
					city: z.string().describe("City name"),
				}),
				execute: async ({ city }) => {
					const res = await fetch(
						`https://api.weatherapi.com/v1/current.json?key=${this.env.WEATHER_KEY}&q=${city}`,
					);
					return res.json();
				},
			}),
		};
	}
}
import { tool } from "ai";
import { z } from "zod";

export class MyAgent extends Think<Env> {
	getModel(): LanguageModel {
		/* ... */
	}
	configureSession(session: Session) {
		/* ... */
	}

	getTools(): ToolSet {
		return {
			getWeather: tool({
				description: "Get the current weather for a city",
				inputSchema: z.object({
					city: z.string().describe("City name"),
				}),
				execute: async ({ city }) => {
					const res = await fetch(
						`https://api.weatherapi.com/v1/current.json?key=${this.env.WEATHER_KEY}&q=${city}`,
					);
					return res.json();
				},
			}),
		};
	}
}

Think automaticky slučuje nástroje z více zdrojů. V každém kole má model přístup k:

  1. Nástroje workspace : read, write, edit, list, find, grep, delete, bash (vestavěné)
  2. Vaše nástroje : z getTools()
  3. Nástroje rozšíření : z načtených rozšíření
  4. Nástroje Session : set_context, load_context, search_context (z configureSession)
  5. Nástroje typu Skill : activate_skill, read_skill_resource a volitelně run_skill_script (z getSkills())
  6. Nástroje MCP : z připojených serverů MCP (pokud existují)
  7. Klientské nástroje : z prohlížeče (pokud existují)

8. Přidejte hooky životního cyklu

Think poskytuje hooky, které se spouští v každém kole bez ohledu na vstupní cestu:

export class MyAgent extends Think {
	getModel() {
		/* ... */
	}

	beforeTurn(ctx) {
		console.log(
			`Turn starting: ${Object.keys(ctx.tools).length} tools available`,
		);
	}

	onChatResponse(result) {
		console.log(`Turn ${result.status}: ${result.message.parts.length} parts`);
	}
}
import type {
	TurnContext,
	TurnConfig,
	ChatResponseResult,
} from "@cloudflare/think";

export class MyAgent extends Think<Env> {
	getModel(): LanguageModel {
		/* ... */
	}

	beforeTurn(ctx: TurnContext): TurnConfig | void {
		console.log(
			`Turn starting: ${Object.keys(ctx.tools).length} tools available`,
		);
	}

	onChatResponse(result: ChatResponseResult) {
		console.log(`Turn ${result.status}: ${result.message.parts.length} parts`);
	}
}

Viz Hooky životního cyklu pro úplnou referenci.

Další kroky