← Vytvářejte agenty na Cloudflare / agents / harnesses / think
Nástroje
Think poskytuje v každém kole vestavěné nástroje pro práci se soubory workspace, a navíc integrační body pro vlastní nástroje, spouštění kódu a dynamická rozšíření.
Pořadí slučování nástrojů
Při každém kole Think sloučí nástroje z více zdrojů. Pokud se názvy shodují, novější zdroje mají přednost před staršími:
- Nástroje workspace,
read,write,edit,list,find,grep,delete,bash(vestavěné) getTools(): vaše vlastní nástroje na straně serveru- Nástroje rozšíření : nástroje z načtených rozšíření (s předponou podle názvu rozšíření)
- Nástroje Session,
set_context,load_context,search_context(zconfigureSession) - Nástroje typu Skill,
activate_skill,read_skill_resource,run_skill_script(zgetSkills(), přečtěte si Agent Skills) - Nástroje MCP : z připojených serverů MCP, když
includeMcpToolsjetrue - Klientské nástroje : z prohlížeče (viz Klientské nástroje)
Nástroje patří agentovi, který kolo vykonává. Pro orchestraci nadřazený/podřízený použijte Agents jako nástroje místo předávání jednorázových nástrojů přes chat().
Vestavěné nástroje pracovního prostoru
Každý agent Think získá this.workspace : Virtuální systém souborů podporovaný SQLite Durable Object. Nástroje pracovního prostoru jsou modelu k dispozici automaticky, bez nutnosti konfigurace.
| Nástroj | Popis |
|---|---|
read |
Přečíst text s čísly řádků; předat obrázky a PDF multimodálním modelům |
write |
Zapíše obsah do souboru (vytvoří nadřazené adresáře) |
edit |
Použije úpravu typu najít a nahradit v existujícím souboru (podporuje fuzzy porovnávání) |
list |
Vypsat soubory a adresáře v dané cestě |
find |
Najde soubory odpovídající vzoru glob |
grep |
Vyhledávání v obsahu souborů pomocí regulárního výrazu nebo pevného řetězce |
delete |
Smazat soubor nebo adresář |
bash |
Spuštění sandboxovaného skriptu Bash v souborech pracovního prostoru |
bash nástroj je ve výchozím nastavení povolen. Připojí soubory pracovního prostoru do just-bash virtuální systém souborů, běží s vypnutým přístupem k síti a zapisuje vytvořené, aktualizované a smazané soubory i prázdné adresáře zpět do pracovního prostoru. Použijte ho pro postupy ve stylu shellu, které kombinují více operací se soubory; pro jednoduché čtení, zápisy a úpravy použijte užší nástroje.
Aby volání nástroje zůstala omezená, nástroj Bash ve výchozím nastavení vytváří snímek až 1 000 souborů z workspace a vynechává soubory větší než 1 MB. Vynechané soubory se uvádějí ve výsledku nástroje a při zápisu zpět se považují za chráněné, takže skript nemůže omylem přepsat nebo smazat obsah, který nebyl připojen. Můžete upravit maxWorkspaceFiles, maxWorkspaceFileBytes, maxOutputBytes, timeout, a network přes workspaceBash.
Pro konzervativní nasazení zakažte výchozí nástroj Bash:
export class MyAgent extends Think {
workspaceBash = false;
getModel() {
/* ... */
}
}export class MyAgent extends Think<Env> {
workspaceBash = false;
getModel() {
/* ... */
}
}Přetečení do R2
Ve výchozím nastavení pracovní prostor ukládá vše do SQLite. Pro velké soubory přepište workspace pro přidání přetečení do R2:
import { Think } from "@cloudflare/think";
import { Workspace } from "@cloudflare/shell";
export class MyAgent extends Think {
workspace = new Workspace({
sql: this.ctx.storage.sql,
r2: this.env.R2,
name: () => this.name,
});
getModel() {
/* ... */
}
}import { Think } from "@cloudflare/think";
import { Workspace } from "@cloudflare/shell";
export class MyAgent extends Think<Env> {
override workspace = new Workspace({
sql: this.ctx.storage.sql,
r2: this.env.R2,
name: () => this.name,
});
getModel() {
/* ... */
}
}Vyžaduje to binding R2 bucketu:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"r2_buckets": [
{
"binding": "R2",
"bucket_name": "agent-files"
}
]
}[[r2_buckets]]
binding = "R2"
bucket_name = "agent-files"Vlastní nástroje
Přepsat getTools() pro přidání vlastních nástrojů. Jedná se o standardní AI SDK tool() definice se schématy z knihovny jako Zod nebo Valibot:
import { Think } from "@cloudflare/think";
import { tool } from "ai";
import { z } from "zod";
export class MyAgent extends Think {
getModel() {
/* ... */
}
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.weather.com/v1/current?q=${city}&key=${this.env.WEATHER_KEY}`,
);
return res.json();
},
}),
};
}
}import { Think } from "@cloudflare/think";
import { tool } from "ai";
import type { ToolSet } from "ai";
import { z } from "zod";
export class MyAgent extends Think<Env> {
getModel() {
/* ... */
}
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.weather.com/v1/current?q=${city}&key=${this.env.WEATHER_KEY}`,
);
return res.json();
},
}),
};
}
}Vlastní nástroje se automaticky sloučí s nástroji pracovního prostoru. Pokud má vlastní nástroj stejný název jako nástroj pracovního prostoru, má přednost vlastní nástroj.
Schvalování nástrojů
Nástroje mohou před spuštěním vyžadovat schválení uživatelem pomocí needsApproval možnost:
getTools(): ToolSet {
return {
deleteFile: tool({
description: "Delete a file from the system",
inputSchema: z.object({ path: z.string() }),
needsApproval: async ({ path }) => path.startsWith("/important/"),
execute: async ({ path }) => {
await this.workspace.rm(path);
return { deleted: path };
},
}),
};
}Když needsApproval vrací true, volání nástroje se odešle klientovi ke schválení. Konverzace se pozastaví, dokud klient neodpoví CF_AGENT_TOOL_APPROVAL.
Přepisy nástrojů pro jednotlivá kola
beforeTurn hook může pro dané kolo omezit nebo přidat nástroje:
beforeTurn(ctx: TurnContext) {
return {
activeTools: ["read", "write", "getWeather"],
tools: { emergencyTool: this.createEmergencyTool() },
};
}activeTools omezuje, které nástroje může model volat. tools přidává další nástroje pouze pro tento tah (sloučí se s existujícími nástroji).
Nástroje MCP
Think dědí podporu klienta MCP z Agent základní třída. Ve výchozím nastavení Think převádí nástroje z připojených MCP serverů na nástroje AI SDK a přidává je do každého kroku.
Nastavte waitForMcpConnections k zajištění toho, že jsou servery MCP připojeny před spuštěním inference:
export class MyAgent extends Think {
waitForMcpConnections = true; // default 10s timeout
// or: waitForMcpConnections = { timeout: 5000 };
getModel() {
/* ... */
}
}export class MyAgent extends Think<Env> {
waitForMcpConnections = true; // default 10s timeout
// or: waitForMcpConnections = { timeout: 5000 };
getModel() {
/* ... */
}
}Pokud zpřístupňujete nástroje MCP přes Code Mode nebo jiným mechanismem mimo automatickou sadu nástrojů Think, vypněte přímé zpřístupnění nástrojů přes AI SDK:
export class MyAgent extends Think {
includeMcpTools = false;
waitForMcpConnections = true;
getModel() {
/* ... */
}
}export class MyAgent extends Think<Env> {
includeMcpTools = false;
waitForMcpConnections = true;
getModel() {
/* ... */
}
}includeMcpTools řídí pouze automatické slučování nástrojů modelu. Připojení MCP se přesto registrují, obnovují, objevují a čekají. Přímý přístup ke katalogu, přímá volání, konektory Code Mode a explicitní this.mcp.getAITools() volání dál fungují.
Použijte tuto vlastnost místo odebírání názvů nástrojů MCP prostřednictvím activeTools v beforeTurn. Think schémata MCP převede ještě před tím, než zavolá beforeTurn, takže activeTools se této konverzi nemůže vyhnout. Konfiguraci runtime konektoru najdete v Použití nástrojů MCP s Code Mode.
Přidejte servery MCP programově nebo prostřednictvím @callable metody:
import { callable } from "agents";
export class MyAgent extends Think {
getModel() {
/* ... */
}
@callable()
async addServer(name, url) {
return await this.addMcpServer(name, url);
}
@callable()
async removeServer(serverId) {
await this.removeMcpServer(serverId);
}
}import { callable } from "agents";
export class MyAgent extends Think<Env> {
getModel() {
/* ... */
}
@callable()
async addServer(name: string, url: string) {
return await this.addMcpServer(name, url);
}
@callable()
async removeServer(serverId: string) {
await this.removeMcpServer(serverId);
}
}Nástroj pro spouštění kódu
Umožněte LLM psát a spouštět JavaScript v sandboxovaném Workeru, zaznamenaný v trvalém runtime Code Mode (přerušení a přehrání, schválení člověkem, auditní stopa, opakovaně použitelné úryvky). Vyžaduje @cloudflare/codemode a worker_loaders binding.
npm install @cloudflare/codemodeJednořádkový zápis odvozuje vše z agenta: state.* z this.workspace, executor z env.LOADER, a živý prohlížeč (cdp.*) z env.BROWSER pokud je vázán:
import { Think } from "@cloudflare/think";
import { createExecuteTool } from "@cloudflare/think/tools/execute";
export class MyAgent extends Think {
getModel() {
/* ... */
}
getTools() {
return {
execute: createExecuteTool(this),
};
}
}import { Think } from "@cloudflare/think";
import { createExecuteTool } from "@cloudflare/think/tools/execute";
export class MyAgent extends Think<Env> {
getModel() {
/* ... */
}
getTools() {
return {
execute: createExecuteTool(this),
};
}
}Kontrolní seznam nastavení:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"worker_loaders": [
{
"binding": "LOADER"
}
],
"browser": {
"binding": "BROWSER"
}
}[[worker_loaders]]
binding = "LOADER"
[browser]
binding = "BROWSER" # optional — enables cdp.*// worker entry — the runtime lives in a Durable Object facet, so the class
// must be exported (the @cloudflare/codemode/vite plugin does this
// automatically; the Think framework's generated entry already includes it)
export { CodemodeRuntime } from "@cloudflare/codemode";// worker entry — the runtime lives in a Durable Object facet, so the class
// must be exported (the @cloudflare/codemode/vite plugin does this
// automatically; the Think framework's generated entry already includes it)
export { CodemodeRuntime } from "@cloudflare/codemode";Každá chybějící část selže s chybou, která uvádí název daného kroku.
Uvnitř sandboxu model vidí typované jmenné prostory a platformní SDK:
tools.*: vaše nástroje AI SDK (argumenty jako objekt, ověřené podle jejich schémat). Pouze nástroje sexecutefunkce jsou zveřejněny. Nástroje na straně klienta nemohou v sandboxu běžet.state.*: souborový systém pracovního prostoru (state.readFile({ path }),state.glob({ pattern }),state.planEdits(...), a tak dále).cdp.*: prohlížeč, pokud je nakonfigurována vazba Browser Run. Nástroj execute má jako výchozí hodnotusession: { mode: "dynamic" }: relace platí vždy jen pro jedno provedení, pokud ji model nepovýší pomocícdp.startSession().codemode.search/codemode.describe/codemode.step/codemode.run: objevování, hranice vedlejších efektů a uložené úryvky.
Předejte přepisy pro cokoli nad rámec výchozích hodnot, například vlastní tools.* vedle stavu odvozeného z agenta:
execute: createExecuteTool(this, { tools: myDomainTools });execute: createExecuteTool(this, { tools: myDomainTools });Nebo zcela explicitní možnosti (bez odvozování agentem):
import { createWorkspaceStateBackend } from "@cloudflare/shell";
createExecuteTool({
ctx: this.ctx,
tools: myDomainTools,
state: createWorkspaceStateBackend(this.workspace),
browser: this.env.BROWSER,
loader: this.env.LOADER,
});import { createWorkspaceStateBackend } from "@cloudflare/shell";
createExecuteTool({
ctx: this.ctx,
tools: myDomainTools,
state: createWorkspaceStateBackend(this.workspace),
browser: this.env.BROWSER,
loader: this.env.LOADER,
});Schválení (s lidským zásahem)
Nástroj AI SDK s needsApproval se v sandboxu nespustí okamžitě, jeho volání trvale pozastaví běh. Pozastavení se vrátí jako běžný výstup nástroje ({ status: "paused", executionId, pending }), model sdělí uživateli, co potřebuje, a kolo končí. To se liší od schvalovacího postupu na straně klienta u běžného getTools() nástroje: uvnitř sandboxu funkční hodnota needsApproval nelze předem vyhodnotit vůči argumentům volání, a proto se z opatrnosti vždy vyžaduje schválení. Think obsahuje vestavěné volatelné funkce pro jeho vyřešení:
approveExecution(executionId): pokračuje v běhu tam, kde skončil. Již hotová práce se přehraje, nikoli znovu provede. Výsledek nahradí pozastavený výstup v přepisu a chat automaticky pokračuje.rejectExecution(executionId, reason?): ukončí běh s{ status: "rejected", reason }aby se model mohl přizpůsobit.pendingExecutions(): čekající akce (s úplnými argumenty) pro vykreslení UI pro schválení.
Funkční kartu schválení najdete v assistant příklad ↗.
Handle runtimu
createExecuteRuntime vrátí jednotlivé součásti pro případ, že host potřebuje víc než jen nástroj, a handle se zároveň přiřadí do this.codemode když je vytvořen z agenta:
import { createExecuteRuntime } from "@cloudflare/think/tools/execute";
const { runtime, connectors, tool } = createExecuteRuntime(this);
await runtime.executions(); // audit trail
await runtime.expirePaused(); // reclaim stale never-approved pauses (call from a scheduled task)
await runtime.saveSnippet("name", { executionId }); // promote a script for reuseimport { createExecuteRuntime } from "@cloudflare/think/tools/execute";
const { runtime, connectors, tool } = createExecuteRuntime(this);
await runtime.executions(); // audit trail
await runtime.expirePaused(); // reclaim stale never-approved pauses (call from a scheduled task)
await runtime.saveSnippet("name", { executionId }); // promote a script for reuseNástroje prohlížeče
Poskytněte svému agentovi přístup k Chrome DevTools Protocol (CDP) pro kontrolu webových stránek, získávání dat, snímky obrazovky a ladění. Vyžaduje @cloudflare/codemode a binding Browser Run.
import { Think } from "@cloudflare/think";
import { createBrowserTools } from "@cloudflare/think/tools/browser";
export class MyAgent extends Think {
getModel() {
/* ... */
}
getTools() {
return {
...createBrowserTools({
ctx: this.ctx,
browser: this.env.BROWSER,
loader: this.env.LOADER,
}),
};
}
}import { Think } from "@cloudflare/think";
import { createBrowserTools } from "@cloudflare/think/tools/browser";
export class MyAgent extends Think<Env> {
getModel() {
/* ... */
}
getTools() {
return {
...createBrowserTools({
ctx: this.ctx,
browser: this.env.BROWSER,
loader: this.env.LOADER,
}),
};
}
}{
"$schema": "./node_modules/wrangler/config-schema.json",
"browser": {
"binding": "BROWSER"
},
"worker_loaders": [
{
"binding": "LOADER"
}
]
}[browser]
binding = "BROWSER"
[[worker_loaders]]
binding = "LOADER"Tím se přidá trvalý nástroj CDP plus bezstavový Quick Action nástroje, pokud browser vazba je přítomna:
| Nástroj | Popis |
|---|---|
browser_execute |
Spouštějte JavaScript v živém prohlížeči přes CDP (snímky obrazovky, čtení DOM, vyhodnocování JS). |
browser_markdown |
Přečíst stránku nebo surové HTML jako Markdown. |
browser_extract |
Extrahuje strukturovaná data ze stránky pomocí AI. |
browser_links |
Vypsat odkazy na stránce. |
browser_scrape |
Získávejte konkrétní prvky pomocí selektoru CSS. |
Předejte quickActions: false k zachování pouze browser_execute, nebo předejte quickActions: { actions, maxChars, options } pro konfiguraci bezstavových nástrojů. Nástroje Quick Action sdílejí browser vazbu, nepotřebují Worker Loader a řeší ctx ze současného Agenta automaticky. Chcete-li použít pouze bezstavové nástroje, importujte createQuickActionTools z @cloudflare/think/tools/browser.
Nástroj je podpořen runtime Code Mode s cdp konektor: model píše asynchronní arrow funkce, které běží v izolovaném prostředí Worker isolate, s cdp.send(), cdp.attachToTarget(), cdp.spec() (živý, normalizovaný popis protokolu), pomocné funkce pro relace (cdp.startSession(), cdp.sessionInfo(), cdp.closeSession()), a pomocné funkce pro ladicí protokolování. Spouštění se zaznamenávají pro přerušení a opakované přehrání, takže relace prohlížeče přežijí pauzy na schválení.
Ve výchozím nastavení každé spuštění získá novou relaci prohlížeče (one-shot), který se ukončí po skončení běhu. Předejte session: { mode: "dynamic" } a umožněte modelu povýšit relaci pomocí cdp.startSession() aby pozdější spuštění pokračovala ve stejném prohlížeči, nebo session: { mode: "reuse", key } pro pojmenovanou dlouhotrvající relaci. Zastaralé relace uvolňuje konektor pomocí sweep() : Zavolejte ji z naplánované úlohy.
Pro vlastní endpoint Chrome předejte cdpUrl místo browser:
createBrowserTools({
ctx: this.ctx,
cdpUrl: "http://localhost:9222",
loader: this.env.LOADER,
});createBrowserTools({
ctx: this.ctx,
cdpUrl: "http://localhost:9222",
loader: this.env.LOADER,
});Úplné API konektoru CDP najdete v Procházet web.
Rozšíření
Rozšíření jsou dynamicky načítané sandboxované Workers, které za běhu přidávají nástroje. LLM může napsat zdrojový kód rozšíření, načíst ho a v dalším kole použít nové nástroje.
Rozšíření vyžadují worker_loaders binding:
import { Think } from "@cloudflare/think";
export class MyAgent extends Think {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
}import { Think } from "@cloudflare/think";
export class MyAgent extends Think<Env> {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
}Statická rozšíření
Definujte rozšíření, která se načtou při spuštění:
export class MyAgent extends Think {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
getExtensions() {
return [
{
manifest: {
name: "math",
version: "1.0.0",
permissions: { network: false },
},
source: `({
tools: {
add: {
description: "Add two numbers",
parameters: { a: { type: "number" }, b: { type: "number" } },
execute: async ({ a, b }) => ({ result: a + b })
}
}
})`,
},
];
}
}export class MyAgent extends Think<Env> {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
getExtensions() {
return [
{
manifest: {
name: "math",
version: "1.0.0",
permissions: { network: false },
},
source: `({
tools: {
add: {
description: "Add two numbers",
parameters: { a: { type: "number" }, b: { type: "number" } },
execute: async ({ a, b }) => ({ result: a + b })
}
}
})`,
},
];
}
}Nástroje rozšíření jsou rozdělené do jmenných prostorů: nástroj math rozšíření pomocí add nástroj se stává math_add v sadě nástrojů modelu.
Rozšíření řízená pomocí LLM
Poskytněte modelu createExtensionTools aby mohl dynamicky načítat rozšíření:
import { createExtensionTools } from "@cloudflare/think/tools/extensions";
export class MyAgent extends Think {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
getTools() {
return {
...createExtensionTools({ manager: this.extensionManager }),
...this.extensionManager.getTools(),
};
}
}import { createExtensionTools } from "@cloudflare/think/tools/extensions";
export class MyAgent extends Think<Env> {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
getTools() {
return {
...createExtensionTools({ manager: this.extensionManager! }),
...this.extensionManager!.getTools(),
};
}
}Tím model získá dva nástroje:
load_extension: načte nové rozšíření ze zdrojového kódu JavaScriptlist_extensions: vypíše aktuálně načtená rozšíření
Kontextové bloky rozšíření
Rozšíření mohou ve svém manifestu deklarovat kontextové bloky. Ty se automaticky registrují u Session:
getExtensions() {
return [{
manifest: {
name: "notes",
version: "1.0.0",
permissions: { network: false },
context: [
{ label: "scratchpad", description: "Extension scratch space", maxTokens: 500 },
],
},
source: `({ tools: { /* ... */ } })`,
}];
}Kontextový blok je zaregistrován jako notes_scratchpad (rozdělené do jmenných prostorů podle názvu rozšíření).
Vlastní backendy pracovního prostoru
Jednotlivé factory nástrojů jsou exportovány pro použití s vlastními úložnými backendy:
import {
createReadTool,
createWriteTool,
createEditTool,
createListTool,
createFindTool,
createGrepTool,
createDeleteTool,
createWorkspaceTools,
} from "@cloudflare/think/tools/workspace";import {
createReadTool,
createWriteTool,
createEditTool,
createListTool,
createFindTool,
createGrepTool,
createDeleteTool,
createWorkspaceTools,
} from "@cloudflare/think/tools/workspace";Implementujte rozhraní operací pro svůj backend úložiště:
const myReadOps = {
readFile: async (path) => fetchFromMyStorage(path),
stat: async (path) => getFileInfo(path),
};
const readTool = createReadTool({ ops: myReadOps });import type { ReadOperations } from "@cloudflare/think/tools/workspace";
const myReadOps: ReadOperations = {
readFile: async (path) => fetchFromMyStorage(path),
stat: async (path) => getFileInfo(path),
};
const readTool = createReadTool({ ops: myReadOps });Nebo vytvořte celou sadu z Workspace, volitelně s vypnutím nástroje Bash:
import { createWorkspaceTools } from "@cloudflare/think/tools/workspace";
const tools = createWorkspaceTools(myCustomWorkspace);
const toolsWithoutBash = createWorkspaceTools(myCustomWorkspace, {
bash: false,
});import { createWorkspaceTools } from "@cloudflare/think/tools/workspace";
const tools = createWorkspaceTools(myCustomWorkspace);
const toolsWithoutBash = createWorkspaceTools(myCustomWorkspace, {
bash: false,
});