AI Engineer World's Fair 2025
Building Agents (the hard parts!)
Read the talk
Building Agents (the hard parts!)
A useful agent needs more than a model: it needs tools, persistent state and a workflow that can pause for approval without losing its place or repeating an action.
From a talk by Rita Kozlov
Before you start: Familiarity with APIs, basic TypeScript and the idea of an LLM calling tools will help; no prior Cloudflare experience is required.
From a first user to an automated workflow
What does it take to bring an application from its first line of code to its first user, and then to millions more? Rita Kozlov introduces that problem from her role leading product for Cloudflare’s developer platform, including Workers and Durable Objects. She reports that about 20% of internet traffic passes through Cloudflare, using Uber and food ordering as everyday examples. Alongside CDN, DNS and DDoS services, the platform supplies developer functions, storage, compute and AI inference—the infrastructure between an idea and a running product.
AI adds another application-building shift to the sequence of cloud, mobile and social. The pace matters because developers are moving from experimenting with model responses to building applications around them.
Kozlov recalls a year-earlier developer adoption figure of roughly 44% and an attributed Gartner forecast that half of knowledge workers would use AI by 2030. She contrasts those with talk-time claims of more than 76% of developers and over 75% of knowledge workers using AI. The matching research needs a narrower reading: the 2024 Stack Overflow survey counted 76% using or planning to use AI tools, with 62% currently using them versus 44% the previous year; it did not measure daily coding frequency. The Microsoft and LinkedIn Work Trend Index reported 75% usage among surveyed knowledge workers, based on February–March 2024 fieldwork. Those figures establish substantial adoption, but do not establish that the attributed Gartner forecast was surpassed on a comparable measure.
Kozlov suspects adoption has grown further since those reports. She also describes a change in the work developers are discussing: from training toward inference. OpenAI o1 illustrates her emphasis on post-training and inference; DeepSeek’s training optimizations illustrate her expectation that more effort will move toward inference. These are her framing of the workload shift, rather than measured allocations of industry compute or energy.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
An email draft becomes a campaign
Asking ChatGPT to draft an email is assistance. Asking an agent to run conference follow-up creates a process:
- Collect the customers you spoke with that week.
- Draft the campaign email.
- Send the draft to you for approval before it goes to customers.
- Notify you when customers respond.
The agent must coordinate actions across time, including a point where it cannot proceed without a human. The draft is only one intermediate result.
Kozlov reports some businesses seeing 20% revenue increases from sales automation agents, 90% faster support response times with AI agents, and roughly 50–75% time savings from agent use. The talk does not identify the studies, baselines or populations behind these figures, and the time-saving claim has no specified task. They motivate the opportunity; they are not capacity-planning assumptions for this campaign workflow.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Follow the request through four components
The campaign agent separates into four components. Keeping their responsibilities distinct makes it easier to see what a model call does—and what remains to be built around it.
| Component | Responsibility |
|---|---|
| Client | Let a human interact with the agent |
| AI | Reason about the request and choose what to do next |
| Workflows | Execute and coordinate the chosen actions |
| Tools | Provide access to external capabilities |
Workflows are the reasoning system’s executive branch: choosing an action does not itself execute it, and execution requires access to a tool.
For the CRM example, a voice request first travels over WebRTC, then through speech-to-text. A text interaction instead starts in a hosted chat UI. A gateway can provide caching and evaluations, helping track whether iterations improve the overall process, before the request reaches the LLM that produces the plan.
The workflow then records which actions have completed and which should happen next. Its tools might be a browser, an API, an internal service or a vector database containing additional knowledge. Selected actions also require human verification. The complete request path therefore includes both machine execution and the possibility of handing control back to a person.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Expose tools through MCP
Working backward from tools, Model Context Protocol (MCP) gives applications a common way to expose capabilities to LLM clients. Kozlov dates Anthropic’s introduction to the preceding November, but highlights another enabling change: models have become much better at tool calling. A standardized interface becomes more useful when the model can reliably choose and invoke the operations behind it. MCP preserves a client-server architecture, allowing conversations between a server and multiple clients.
The protocol separates several kinds of interaction:
- Resources: File contents, database records and other context the server can expose.
- Prompts: Reusable instructions that encode knowledge of how to interact with the system, including nuances its author understands best.
- Tools: Executable capabilities that connect a request to an action.
- Sampling: A server’s request for model generation through a supporting client.
Kozlov describes sampling informally as letting the LLM complete some thinking from shorthand, and says she had not seen it used in a production MCP server while preparing the talk. More precisely, the sampling specification defines sampling/createMessage: the client supplies model access and retains control over permissions.
The difficult implementation work remains transport, OAuth and memory. Kozlov mentions SSE and WebSockets together, but application WebSockets should be distinguished from standard MCP transport. The March 2025 transport specification defines stdio and Streamable HTTP, with optional SSE; Streamable HTTP replaced the earlier HTTP+SSE transport. WebSockets can support the surrounding real-time application without being one of those standard MCP transports.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Attach state to the agent
Cloudflare’s Agents SDK packages much of that infrastructure. It is distinct from OpenAI’s identically named SDK; Kozlov says the two can work together. The walkthrough uses Cloudflare’s McpAgent class for remote MCP hosting. In the historical integration, McpAgent handles transport, while workers-oauth-provider supplies authorization support: extending the class alone does not configure OAuth.
The stateful foundation is Durable Objects, which Kozlov describes as serverless functions with state attached directly to them. Code can retain information without requiring the application developer to separately provision and connect a database. Around that foundation, the SDK provides real-time WebSocket communication, React integration hooks and basic AI chat capabilities. Those pieces connect persistent server behavior to a live client interface.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Remember book preferences across interactions
The first walkthrough is a Goodreads-like recommendation server. Its class extends McpAgent and starts with empty state. An addGenre tool records a preference: Kozlov likes Patricia Highsmith, so her example adds thrillers. The important result is a persistent preference that later interactions can use.
A separate getRecommendations tool and a personalized MCP prompt can then use both preferred genres and previously read books. The following TypeScript captures that state transformation and prompt construction. Adding thrillers changes the preference list while preserving the read-book list:
typescript
type ReadingState = {
genres: string[];
readBooks: string[];
};
function addGenre(state: ReadingState, genre: string): ReadingState {
return {
...state,
genres: [...new Set([...state.genres, genre])],
};
}
function recommendationPrompt(state: ReadingState): string {
return [
`Recommend books for someone who likes: ${state.genres.join(", ") || "any genre"}.`,
`Previously read books: ${state.readBooks.join(", ") || "none recorded"}.`,
"Avoid recommending books already read.",
].join("\n");
}
const initialState: ReadingState = { genres: [], readBooks: [] };
const updatedState = addGenre(initialState, "thrillers");
const prompt = recommendationPrompt(updatedState);
The server must persist updatedState; returning a new JavaScript object alone does not make it durable. The prompt requests recommendations but does not itself execute a model call.
Add a genre without changing reading history
Constructed example: The TypeScript field names, empty-array representation, deduplication behavior and exact prompt wording are teaching details. Thrillers, initially empty state, persisted preferences and use of reading history come from the talk.
thrillers
Operation: Add thrillers to the genre list, preserve readBooks, and construct the recommendation prompt from the resulting state.
genres
[]
["thrillers"]
readBooks
[]
[]
prompt
Not present
Recommend books for someone who likes: thrillers. Previously read books: none recorded. Avoid recommending books already read.
As preferences and reading history accumulate, Kozlov expects recommendations to become more personalized. Because memory lives in the standalone MCP server, changing clients need not erase it. That depends on clients reaching the same stored identity; persistence alone does not define how identities are shared across clients.
The infrastructure comparison is between separately assembling storage and using state attached to the agent:
| Separate storage setup | State through McpAgent |
|---|---|
| Provision a database | Use built-in persistent state |
| Manage database connections | Access state through the agent |
| Coordinate compute and storage scaling | Rely on the platform’s scaling |
Kozlov also presents reduced infrastructure management, avoiding added database access latency, and execution close to the AI agent as benefits. The walkthrough supplies no latency measurement or placement guarantee.
For deployment, Kozlov points to a blog with a Deploy to Cloudflare button. The remote MCP deployment announcement provides a related historical entry point. Kozlov says an initial MCP server can be running in less than a minute and names Atlassian, Asana, Stripe and Intercom as companies building servers this way. That timing is her reported onboarding estimate.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Pause card issuance for human approval
Remembering a genre solves state within a tool interaction. A workflow must preserve state across an entire chain of interactions. A reasoning model may take several minutes; a human may respond after minutes, hours, days or months. The application needs to resume when the delayed task completes, while also handling persistent state, retries, WebSocket connections and horizontal scaling.
The customer example comes from Knock’s approval workflow. A user requests a new credit card, and their boss must approve it through email, Slack or an in-app notification. The chat request starts the process; it is not authorization to issue the card.
The setup proceeds in three steps:
- Connect the chat. Import
useAgentfrom the Agents React library to connect the client to an agent instance. - Gate the action. Wrap
issueCardwithrequireHumanInput, supplied by Knock Agent Toolkit in this historical example. Every invocation of the issuance tool must require human input. - Request approval and defer execution. Knock sends the approval notifications while the card-provisioning tool call remains paused.
The approval gate belongs on the executable tool. The workflow retains a pending call instead of issuing a card and asking a person afterward.
When the approval webhook returns, it must reach the same agent that owns the pending call. The walkthrough extracts the calling user’s ID from the tool call, looks up the agent by name using that ID, and routes the webhook to the existing agent’s Durable Object. Once an approved status arrives, the agent resumes the deferred tool execution, issues the card and tells the user it was approved.
The final part is duplicate prevention. Out-of-sync events must not approve or provision the same card twice. The agent records whether a request has already been processed and updates its approval status, so a later webhook can recognize completed work rather than repeat it. This persisted status is the walkthrough’s duplicate-handling mechanism; it does not by itself establish exactly-once behavior across an external card provider and every possible failure between issuance and recording the result.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Put the agent where users already work
With tools and workflows in place, the remaining choices are the reasoning model and the client. Kozlov leaves model selection and evaluations to other conference sessions, mentioning Logan’s talk about Gemini. This walkthrough therefore supplies the execution architecture, not a model-selection recipe.
MCP also creates a distribution option: build the server once and let users reach it through an existing client. Kozlov describes Cursor for developer users, followed by Claude and ChatGPT, as supporting remote MCP at the time of the talk. The architectural benefit is that an agent can become available inside a user’s existing workspace without first requiring a separately built UI; specific availability depends on the client’s support and access conditions.
A custom application remains useful when the workflow needs more control over both client and server. It need not be limited to text: Kozlov describes Cloudflare tooling that bridges WebRTC to WebSocket for voice interaction with an MCP client. Voice changes the input path, while the same server-side tools and coordination still carry out the work.
The finished system brings together a client, AI reasoning, workflows and tools. Kozlov recommends the Agents SDK as a starting point and says developers can get up and running in a few minutes. The campaign and card examples show what those pieces must accomplish together: accept a request, preserve its context, wait when approval is required, and resume the correct action when the response arrives.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
Further reading
Rita Kozlov and colleagues introduce stateful agents, React connections, embedded storage and agent routing.
Historical introduction to Cloudflare’s remote MCP hosting and its transport and authorization components.
A virtual-card walkthrough that defers issuance for human approval using Knock notifications and a stateful Cloudflare agent.
Survey results distinguish current AI tool use from planned adoption in development workflows.
Research on workplace AI adoption, including the reported 75% usage rate among knowledge workers.
- MCP transports: March 2025 specificationDocumentation
Historical specification for stdio, Streamable HTTP, SSE streaming and connection handling.
- MCP sampling: March 2025 specificationDocumentation
Explains how servers request model generation through clients while clients retain control over model access and permissions.
Read the transcript and explore slides
Loading transcript and slides…