Prompting·续2
async someTask(data) { await this.callReasoningModel(data.message); }
// Use the this.sql API within the Agent to access the underlying SQLite database async callReasoningModel(prompt: Prompt) { interface Prompt { userId: string; user: string; system: string; metadata: Record<string, string>; }
interface History { timestamp: Date; entry: string; }
let result = this.sql<History>SELECT * FROM history WHERE user = ${prompt.userId} ORDER BY timestamp DESC LIMIT 1000;
let context = [];
for await (const row of result) {
context.push(row.entry);
}
const client = new OpenAI({ apiKey: this.env.OPENAI_API_KEY, });
// Combine user history with the current prompt
const systemPrompt = prompt.system || 'You are a helpful assistant.';
const userPrompt = ${prompt.user}\n\nUser history:\n${context.join('\n')};
try { const completion = await client.chat.completions.create({ model: this.env.MODEL || 'o3-mini', messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt }, ], temperature: 0.7, max_tokens: 1000, });
// Store the response in history
this
.sqlINSERT INTO history (timestamp, user, entry) VALUES (${new Date()}, ${prompt.userId}, ${completion.choices[0].message.content});
return completion.choices[0].message.content; } catch (error) { console.error('Error calling reasoning model:', error); throw error; } }
// Use the SQL API with a type parameter
async queryUser(userId: string) {
type User = {
id: string;
name: string;
email: string;
};
// Supply the type parameter to the query when calling this.sql
// This assumes the results returns one or more User rows with "id", "name", and "email" columns
// You do not need to specify an array type (User[] or Array<User>) as this.sql will always return an array of the specified type.
const user = await this.sql<User>SELECT * FROM users WHERE id = ${userId};
return user
}
// Run and orchestrate Workflows from Agents async runWorkflow(data) { let instance = await env.MY_WORKFLOW.create({ id: data.id, params: data, })
// Schedule another task that checks the Workflow status every 5 minutes... await this.schedule("/5 * * * ", "checkWorkflowStatus", { id: instance.id }); } }
export default { async fetch(request, env, ctx): Promise<Response> { // Routed addressing // Automatically routes HTTP requests and/or WebSocket connections to /agents/:agent/:name // Best for: connecting React apps directly to Agents using useAgent from @cloudflare/agents/react return (await routeAgentRequest(request, env)) || Response.json({ msg: 'no agent here' }, { status: 404 });
// Named addressing // Best for: convenience method for creating or retrieving an agent by name/ID. let namedAgent = getAgentByName<Env, AIAgent>(env.AIAgent, 'agent-456'); // Pass the incoming request straight to your Agent let namedResp = (await namedAgent).fetch(request); return namedResp;
// Durable Objects-style addressing // Best for: controlling ID generation, associating IDs with your existing systems, // and customizing when/how an Agent is created or invoked const id = env.AIAgent.newUniqueId(); const agent = env.AIAgent.get(id); // Pass the incoming request straight to your Agent let resp = await agent.fetch(request);
// return Response.json({ hello: 'visit https://developers.cloudflare.com/agents for more' }); }, } satisfies ExportedHandler<Env>; </code>
<code> // client.js import { AgentClient } from "agents/client";
const connection = new AgentClient({ agent: "dialogue-agent", name: "insight-seeker", });
connection.addEventListener("message", (event) => { console.log("Received:", event.data); });
connection.send( JSON.stringify({ type: "inquiry", content: "What patterns do you see?", }) ); </code>
<code> // app.tsx // React client hook for the agents import { useAgent } from "agents/react"; import { useState } from "react";
// useAgent client API function AgentInterface() { const connection = useAgent({ agent: "dialogue-agent", name: "insight-seeker", onMessage: (message) => { console.log("Understanding received:", message.data); }, onOpen: () => console.log("Connection established"), onClose: () => console.log("Connection closed"), });
const inquire = () => { connection.send( JSON.stringify({ type: "inquiry", content: "What insights have you gathered?", }) ); };
return ( <div className="agent-interface"> <button onClick={inquire}>Seek Understanding</button> </div> ); }
// State synchronization function StateInterface() { const [state, setState] = useState({ counter: 0 });
const agent = useAgent({ agent: "thinking-agent", onStateUpdate: (newState) => setState(newState), });
const increment = () => { agent.setState({ counter: state.counter + 1 }); };
return ( <div> <div>Count: {state.counter}</div> <button onClick={increment}>Increment</button> </div> ); } </code>
<configuration> { "durable_objects": { "bindings": [ { "binding": "AIAgent", "class_name": "AIAgent" } ] }, "migrations": [ { "tag": "v1", // Mandatory for the Agent to store state "new_sqlite_classes": ["AIAgent"] } ] } </configuration> <key_points>
- Imports the
Agentclass from theagentspackage - Extends the
Agentclass and implements the methods exposed by theAgent, includingonRequestfor HTTP requests, oronConnectandonMessagefor WebSockets. - Uses the
this.schedulescheduling API to schedule future tasks. - Uses the
this.setStateAPI within the Agent for syncing state, and uses type parameters to ensure the state is typed. - Uses the
this.sqlas a lower-level query API. - For frontend applications, uses the optional
useAgenthook to connect to the Agent via WebSockets
</key_points> </example>
<example id="workers-ai-structured-outputs-json">
<description>
Workers AI supports structured JSON outputs with JSON mode, which supports the response_format API provided by the OpenAI SDK.
</description>
<code language="typescript">
import { OpenAI } from "openai";
interface Env { OPENAI_API_KEY: string; }
// Define your JSON schema for a calendar event const CalendarEventSchema = { type: 'object', properties: { name: { type: 'string' }, date: { type: 'string' }, participants: { type: 'array', items: { type: 'string' } }, }, required: ['name', 'date', 'participants'] };
export default { async fetch(request: Request, env: Env) { const client = new OpenAI({ apiKey: env.OPENAI_API_KEY, // Optional: use AI Gateway to bring logs, evals & caching to your AI requests // https://developers.cloudflare.com/ai-gateway/usage/providers/openai/ // baseUrl: "https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai" });
const response = await client.chat.completions.create({
model: 'gpt-4o-2024-08-06',
messages: [
{ role: 'system', content: 'Extract the event information.' },
{ role: 'user', content: 'Alice and Bob are going to a science fair on Friday.' },
],
// Use the response_format option to request a structured JSON output
response_format: {
// Set json_schema and provide ra schema, or json_object and parse it yourself
type: 'json_schema',
schema: CalendarEventSchema, // provide a schema
},
});
// This will be of type CalendarEventSchema const event = response.choices[0].message.parsed;
return Response.json({ "calendar_event": event, }) } } </code> <configuration> { "name": "my-app", "main": "src/index.ts", "compatibility_date": "$CURRENT_DATE", "observability": { "enabled": true } } </configuration> <key_points>
- Defines a JSON Schema compatible object that represents the structured format requested from the model
- Sets
response_formattojson_schemaand provides a schema to parse the response - This could also be
json_object, which can be parsed after the fact. - Optionally uses AI Gateway to cache, log and instrument requests and responses between a client and the AI provider/API.
</key_points> </example>
</code_examples>
<api_patterns>
<pattern id="websocket_coordination"> <description> Fan-in/fan-out for WebSockets. Uses the Hibernatable WebSockets API within Durable Objects. Does NOT use the legacy addEventListener API. </description> <implementation> export class WebSocketHibernationServer extends DurableObject { async fetch(request: Request, env: Env, ctx: ExecutionContext) { // Creates two ends of a WebSocket connection. const webSocketPair = new WebSocketPair(); const [client, server] = Object.values(webSocketPair);
// Call this to accept the WebSocket connection. // Do NOT call server.accept() (this is the legacy approach and is not preferred) this.ctx.acceptWebSocket(server);
return new Response(null, { status: 101, webSocket: client, }); },
async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): void | Promise<void> { // Invoked on each WebSocket message. ws.send(message) },
async webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean) void | Promise<void> { // Invoked when a client closes the connection. ws.close(code, "<message>"); },
async webSocketError(ws: WebSocket, error: unknown): void | Promise<void> { // Handle WebSocket errors } } </implementation> </pattern> </api_patterns>
<user_prompt> {user_prompt} </user_prompt>
The prompt above adopts several best practices, including:
- Using `<xml>` tags to structure the prompt
- API and usage examples for products and use cases
- Guidance on how to generate configuration (for example, `wrangler.jsonc`) as part of the model's response
- Recommendations on Cloudflare products to use for specific storage or state needs
### Additional uses
You can use the prompt in several ways:
- Within the user context window, with your own user prompt inserted between the `<user_prompt>` tags (**easiest**)
- As the `system` prompt for models that support system prompts
- Adding it to the prompt library or file context in your preferred IDE:
- Cursor: add the prompt to [your Project Rules ↗︎](https://docs.cursor.com/context/rules-for-ai)
- Zed: use [the `/file` command ↗︎](https://zed.dev/docs/assistant/assistant-panel) to add the prompt to the Assistant context
- Windsurf: use [the `@-mention` command ↗︎](https://docs.codeium.com/chat/overview) to include a file containing the prompt to your Chat
- Claude Code: add the prompt to your `CLAUDE.md` configuration after running `/init` to include best practices to a Workers project
- GitHub Copilot: create the [`.github/copilot-instructions.md` ↗︎](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot) file at the root of your project and add the prompt
Note
The prompts here are examples and should be adapted to your specific use case.
Depending on the model and user prompt, it may generate invalid code, configuration, or other errors. Review and test the generated code before deploying it.
## Use docs in your editor
AI-enabled editors, including Cursor and Windsurf, can index documentation. Cursor includes the Cloudflare Developer Docs by default: you can use the [`@Docs` ↗︎](https://cursor.com/docs/context/mentions#docs) command.
In other editors, such as Zed or Windsurf, you can use `llms-full.txt` files to provide comprehensive documentation context for indexing. For Workers-specific documentation indexing, use [`https://developers.cloudflare.com/workers/llms-full.txt` ↗︎](https://developers.cloudflare.com/workers/llms-full.txt). For the complete Cloudflare documentation archive, use the root level [`https://developers.cloudflare.com/llms-full.txt` ↗︎](https://developers.cloudflare.com/llms-full.txt) instead.
You can also link an agent to `llms.txt` files while prompting to provide similar context without the need for offline indexing. For workers-specific documentation, use [`https://developers.cloudflare.com/workers/llms.txt` ↗︎](https://developers.cloudflare.com/workers/llms.txt). For context of the entire Cloudflare documentation, use the root level [`https://developers.cloudflare.com/llms.txt` ↗︎](https://developers.cloudflare.com/llms.txt).
The *Copy Page* button is also available on any individual page to paste that page's content directly.
You can combine these with the Workers system prompt on this page to improve your editor or agent's understanding of the Workers APIs.
## Additional resources
To get the most out of AI models and tools, review the following guides on prompt engineering and structure:
- OpenAI's [prompt engineering ↗︎](https://platform.openai.com/docs/guides/prompt-engineering) guide and [best practices ↗︎](https://platform.openai.com/docs/guides/reasoning-best-practices) for using reasoning models.
- The [prompt engineering ↗︎](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview) guide from Anthropic.
- Google's [quick start guide ↗︎](https://services.google.com/fh/files/misc/gemini-for-google-workspace-prompting-guide-101.pdf) for writing effective prompts.
- Meta's [prompting documentation ↗︎](https://www.llama.com/docs/how-to-guides/prompting/) for their Llama model family.
- GitHub's guide for [prompt engineering ↗︎](https://docs.github.com/en/copilot/using-github-copilot/copilot-chat/prompt-engineering-for-copilot-chat) when using Copilot Chat.
Was this helpful?
YesNo
## On this page
[Docs](https://developers.cloudflare.com/)
```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workers/get-started/prompting/#page","headline":"Prompting","description":"Build Workers apps with AI prompts and MCP servers.","url":"https://developers.cloudflare.com/workers/get-started/prompting/","inLanguage":"en","image":"https://developers.cloudflare.com/workers/get-started/prompting/og.png?v=a646f8435e9f2f18","dateModified":"2026-10-10","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["AI","LLM"]}
description: GitHub repositories that are designed to be a starting point for building a new Cloudflare Workers project. title: Templates image: https://developers.cloudflare.com/workers/get-started/quickstarts/og.png?v=8b266957baa916c3
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt
Use this file to discover all available pages before exploring further.
