# Agents

> Build Cloudflare Agents SDK applications for autonomous multi-step tool use, AIChatAgent chat agents, Durable Object-backed state, tools, scheduling, callable methods, WebSockets, SQL state, and constrained agent behavior. Use when RAG or Workflows are not enough.

- Skill: `zllovesuki/agents` (Agent Skill)
- Install (CLI): `npx skillmds@latest add zllovesuki/agents`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zllovesuki/agents/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: zllovesuki (https://skillmd.com/u/zllovesuki)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/zllovesuki/agents

---

# Agents

Use this skill when building an autonomous tool-using system on Cloudflare. Do not use an agent when a deterministic Worker, RAG endpoint, Queue, or Workflow is sufficient.

## When to use Agents

Use Agents for:

- Autonomous multi-step tool use.
- Chat agents with durable state and resumable interactions.
- Systems that need model reasoning plus application tools.
- Long-lived per-user or per-task agent state.

Prefer alternatives for:

- Simple chatbot over documents: RAG endpoint.
- Ordered deterministic process: Workflow.
- Deferred background task: Queue.
- Shared realtime room without AI autonomy: Durable Object.

## Design rules

- Keep the agent's tools narrow, typed, and permission-checked.
- The model proposes actions; code enforces authorization and invariants.
- Store durable state intentionally. Do not rely on prompt memory alone.
- Include tenant/user boundaries in agent identity and storage.
- Add loop limits, budget limits, and stop conditions.
- Log tool calls, model decisions, and failures with a correlation ID.

## Agent skeleton

```ts
import { Agent, routeAgentRequest } from "agents";

export interface Env {
  AI: Ai;
}

export class SupportAgent extends Agent<Env> {
  async onRequest(request: Request): Promise<Response> {
    const input = await request.json<{ message: string }>();

    // Use explicit tools and deterministic checks here.
    const answer = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {
      messages: [
        { role: "system", content: "You are a support agent. Use tools only when needed." },
        { role: "user", content: input.message }
      ]
    });

    return Response.json(answer);
  }
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const agentResponse = await routeAgentRequest(request, env);
    return agentResponse ?? new Response("Not found", { status: 404 });
  }
} satisfies ExportedHandler<Env>;
```

Verify exact SDK imports and routing helpers against current Agents SDK docs.

## Wrangler binding

Agents require Durable Object bindings and migrations. Keep the binding name and class name aligned with the exported agent class.

```jsonc
{
  "durable_objects": {
    "bindings": [
      { "name": "SupportAgent", "class_name": "SupportAgent" }
    ]
  },
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["SupportAgent"] }
  ]
}
```

## Tool contract template

Every tool should specify:

```ts
type ToolContext = {
  tenantId: string;
  userId: string;
  requestId: string;
};

type ToolResult<T> =
  | { ok: true; data: T }
  | { ok: false; error: string; safeMessage: string };
```

Tool implementation rules:

- Validate inputs with a schema.
- Check tenant/user authorization inside the tool.
- Bound result size before returning to the model.
- Redact secrets and PII not required for the next step.
- Make mutating tools idempotent where possible.
- Require human confirmation for irreversible or expensive actions.

## State and memory

- Store durable facts in SQL/D1/DO storage, not only in chat transcripts.
- Summarize long transcripts into bounded memory.
- Keep user preferences separate from operational state.
- Allow users/admins to inspect and reset agent state.

## Anti-patterns

- Agent is allowed to call broad arbitrary HTTP/fetch tools.
- Tool output includes secrets or unrelated tenant data.
- The model decides authorization.
- No limit on tool-call loops or token spend.
- Using an agent for a deterministic CRUD flow.

