AI Engineer World's Fair 2026

Agent Frameworks Considered Harmful — Rémi Louf, .txt

Read the talk

Agent Frameworks Considered Harmful

Rémi Louf’s attempt to get a morning brief waiting with his coffee became an event-driven runtime. Lost notes, duplicate messages, and prompt regressions explain why background agents need queues, causal logs, reconstructable context, and typed handoffs.

From a talk by Rémi Louf

At a glance

Ideas worth remembering

  • Schedules trigger work at a time; events trigger work because something happened. The morning brief combines both.

  • Background agents need ordinary operational machinery: attempt-aware queues for retries and an append-only, causally linked log for investigation.

  • Content-addressed prompt components make stored requests reconstructable, diffable, and replayable against another model.

  • A runtime can leave agent authoring flexible while checking typed tool calls and typed events where work crosses between components.

  • Build and operate a small workflow before choosing infrastructure: real use exposes requirements that an attractive abstraction can hide.

A morning without a remote control

The robot mower outside Rémi Louf’s office had the working arrangement he wanted: it did its job in the background without someone steering it. His own morning required reading market news, reviewing Linear and the CRM, taking an hour-long walk, and then processing the long voice note recorded along the way. The desired result was modest and concrete—a morning briefing waiting with his coffee.

After noticing a sharp improvement in agent capability, Louf took two weeks away from running the 15-person company .txt to explore that workflow. The question was what agents could actually do unattended, and which pieces of infrastructure they needed. The title is deliberately provocative; the experiment begins with a personal chore rather than a general indictment of every framework.

Terminal agents already handled useful coding and noncoding tasks. But using them resembled sitting on a self-driving tractor mower: the machine performed the work while the operator remained at the controls. Phone apps loosened that attachment without removing it. During his walk, Louf found himself sending instructions and correcting agents’ trajectories instead of thinking. Mobility had moved the remote control into his pocket.

That frustration led him to start coding, with an aside about hoping his board would not hear about it. He aimed for the smallest thing that could work. The resulting Zeta runtime would grow through failures discovered in daily use.

1:121:42
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

0:12 · section reference included

Move the prompt out of application code

The first irritation with existing frameworks was where routine changes happened. Editing an agent’s instructions meant editing prompts inside code. Moving agent definitions into Markdown files made the everyday task smaller: write a file, drop it in a folder, and let the runtime discover it. The files could still be versioned, compared, and reviewed in a pull request.

The market-watching agent needed to run every morning while Louf walked, so its first trigger was a conventional cron schedule. A schedule specified when work began; agents also published events. Markdown and cron formed a simple authoring interface, even though the machinery underneath was more complicated. At this point, it mostly worked. The meaning of “mostly” would arrive shortly.

4:174:47
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

4:17 · section reference included

Cron says when; an event says what happened

A voice note does not arrive at a predetermined time. Its arrival is the reason processing should begin. Dropping a note into the system therefore emits an event that wakes a subscriber. New emails, CRM entries, and opened or merged pull requests can use the same mechanism. Scheduling remains useful for the market watch; events handle work triggered by changes.

Follow the morning voice note through that change. Previously, the recording left an hour of processing for Louf after his walk. In the new workflow, the voice-note agent declares the event it accepts and the event it returns. It receives the recording, transcribes it, turns the transcript into persistent notes, and uses structured output to emit a processed-note event. The recording has become an input another agent can use without Louf issuing another instruction.

The daily-brief agent combines those notes with the scheduled market output and creates the brief. It then emits a Slack-post event. A separate process subscribes to that event and sends the message. The model’s information work and the external delivery action are separate steps, connected through an explicit handoff.

How do the scheduled market report and the unscheduled recording meet? The diagram shows their convergence on the daily brief, followed by a subscriber that delivers it. The arrows explain the flow; contributors do not maintain those arrows as a separate execution graph.

Subscriptions determine the connections. Several agents can consume one event, and an agent can use outputs from several producers: fan-out and fan-in follow from the event model. Adding an agent means declaring what it consumes and produces rather than wiring a new set of graph edges in code. That lowers the authoring barrier, while making knowledge of the system’s event types essential.

Two triggers, one morning brief

Scheduled market watchinputs — Runs each morning and publishes its output.
Voice note arrivesinputs — Submission emits an event.
Voice-note processorTranscribes, saves notes, and returns a processed-note event.
Daily-brief agentCombines market output and processed voice notes.
Slack delivery processSubscribes to the post event and sends the message.
Scheduled market work and a newly submitted voice note feed the brief. A delivery process consumes the resulting Slack-post event.
Read the diagram as text
  • Scheduled market watch. inputs — Runs each morning and publishes its output.
  • Voice note arrives. inputs — Submission emits an event.
  • Voice-note processor. Transcribes, saves notes, and returns a processed-note event.
  • Daily-brief agent. Combines market output and processed voice notes.
  • Slack delivery process. Subscribes to the post event and sends the message.
  • Voice note arrives → Voice-note processor: Arrival event.
  • Voice-note processor → Daily-brief agent: Processed-note event.
  • Scheduled market watch → Daily-brief agent: Scheduled output.
  • Daily-brief agent → Slack delivery process: Slack-post event.
5:476:17
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

5:47 · section reference included

Duplicates, disappearance, and prompt drift

The first implementation took about a day with Codex’s help. Then operation exposed three distinct failures: the daily brief appeared in Slack twice on the first day, a voice note vanished on Wednesday, and unversioned prompt edits made the market brief useless by the end of the week. Louf could no longer remember which edit caused the regression.

Each failure called for a different piece of ordinary software infrastructure:

  • Duplicate delivery → an attempt-aware queue. Several attempts had occurred without proper tracking or counting. The runtime needed a real queue and a count of attempts.
  • Lost recording → a permanent event log. Inputs and transitions needed to remain available so an operator could investigate what happened.
  • Untraceable regression → content-addressed prompts. The system needed to preserve the components used in a run, rather than depend on someone remembering a week of edits.

The queue addresses execution attempts; the log addresses history. Keeping those jobs distinct matters: remembering that two messages were sent does not itself prevent a second send. The recording explains why attempt tracking was added, without specifying an exactly-once delivery protocol.

The log became one append-only events table. New events extend the history, and causal links record which event triggered which subsequent event. For the voice-note workflow, that relationship lets debugging follow the input toward processing, briefing, and delivery, rather than inspect an undifferentiated list of messages. The history is queryable, and Louf found it valuable with only three or four agents—well before the system became large.

8:198:49
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

8:19 · section reference included

Store the components the model actually received

An event history answers what ran and what triggered it. It still leaves another question: what request produced this model response? A displayed chat can conceal changes to the submitted context, particularly when compaction replaces earlier conversation material. Louf wanted to reconstruct the request instead of inferring it from the chat interface. That reconstruction covers stored, submitted context; it does not reveal a provider’s hidden internal reasoning.

The solution borrows from build systems. Store the system prompt, each skill description, tool definitions, and the user message separately. Identify each component by a hash of its content. Before rendering text for the model, represent the prompt as a list of those hashes. Store the model answer in the same content-addressed system and connect it back to its prompt.

What must remain available to reconstruct an old request? The diagram follows stored components into a prompt and then a response. The component identities preserve the ingredients, while the prompt list preserves their arrangement. Following the response back to that list identifies which stored instructions, skills, tools, and question belonged to the run.

This design also resolves an apparent tension in the talk. The workflow does not require contributors to maintain an execution graph, but prompt storage deliberately uses a graph of references. Those are different jobs: subscriptions route work among agents; content references preserve the material assembled for a model request. Louf says manipulating that graph simplifies compaction and indirectly helps KV-cache management. The main developed benefit is being able to inspect a run’s inputs.

Two practical operations follow from the stored structure:

  • Diff runs. Compare component identities to locate changes in instructions, skills, tools, or messages. In the example described during the talk, three components remain identical, the user message changes, and additional messages continue the session. The comparison separates reused context from changed and added material.
  • Replay requests. Resolve the stored references and rebuild a previous request. Send it again, select another model, or deliberately alter part of the input. Reproducing the request supplies a controlled starting point for comparison; it does not promise the same answer.

Replay became useful when observability made rising costs visible. Louf wanted to evaluate open-source models on the requests his agents had already handled: were their answers satisfactory, and would prompts need to change? Rebuilding those requests made the comparison possible using actual work. The benefits arrive after implementing the content store and reconstruction machinery; even Louf’s description of getting them for free comes with that qualification.

Reconstructable model context

Prompt componentsSystem instructions, individual skills, tool definitions, and user message.
Content-addressed storageEach component is stored under its content hash.
Prompt as a list of hashesReferences the components before text rendering.
Rendered model requestCan be rebuilt from the stored graph for replay.
Stored model responseContent-addressed and traceable back to its prompt.
Hashes identify separately stored components. A prompt records their arrangement, and the stored response links back to that prompt.
Read the diagram as text
  • Prompt components. System instructions, individual skills, tool definitions, and user message.
  • Content-addressed storage. Each component is stored under its content hash.
  • Prompt as a list of hashes. References the components before text rendering.
  • Rendered model request. Can be rebuilt from the stored graph for replay.
  • Stored model response. Content-addressed and traceable back to its prompt.
  • Prompt components → Content-addressed storage: Store and hash separately.
  • Content-addressed storage → Prompt as a list of hashes: Assemble component references.
  • Prompt as a list of hashes → Rendered model request: Resolve and render.
  • Rendered model request → Stored model response: Model returns an answer.
  • Stored model response → Prompt as a list of hashes: Trace back to submitted context.
11:1211:42
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

11:12 · section reference included

A kernel that checks the handoffs

The runtime’s responsibilities now resemble those of a kernel: schedule an agent, isolate it, and journal its activity. The agent resembles a process whose internal task can vary. Markdown belongs to the authoring layer, so it need not define the runtime itself. Louf already had another front end that did not use the Markdown format. This separates a convenient way to write agents from the services required to operate them.

Structured outputs became essential at the handoffs. .txt had worked on them for three years, and the runtime became a substantial internal use of that expertise. Louf reports that roughly 20 percent of his generated events were malformed and rejected when using Anthropic in this workflow. That is a workload-specific observation, and it explains the decision to strengthen event generation rather than rely on loose text passing between agents.

Two boundaries need machine-checkable structure:

  • Typed tool calls connect agents to external actions. A call must refer to an available tool and fit the permitted interface. The runtime should exclude requests such as calling a tool that does not exist.
  • Typed events connect agents to each other. Producers must return an event shape consumers can accept. A malformed handoff should be prevented or rejected before it becomes the next agent’s input.

Louf describes the goal as making bad actions impossible at these boundaries. Its useful scope is structural: a valid tool call or well-formed event can still contain a poor decision. Types remove classes of interface errors; they do not establish that the brief is insightful or that an otherwise permitted action is wise.

After a month of company deployment, the system had 20 agents, including contributions from nontechnical colleagues. Briefs and other outputs appeared in an internal interface called the intranet. The file-based authoring decision had a visible organizational effect: extending the system no longer belonged exclusively to people who wrote application code.

15:1115:41
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

15:11 · section reference included

Operate a small workflow before choosing infrastructure

The morning example finally reaches its intended result. Louf returns from his walk to a brief in his inbox, with his recorded thoughts already processed. He judges it probably better than the version he would have assembled manually. The improvement he values is the unattended experience: the work appears without a sequence of phone instructions.

The difficult parts turned out to be familiar orchestration problems. Queues track attempts, logs preserve events, causal links explain propagation, and stored prompt components explain input changes. The model supplies useful work inside that machinery; capability alone had not supplied the machinery.

For these noncoding tasks, open-source models became sufficient. Louf says he replaced his third-party model APIs and also uses a local model on his laptop. He explicitly leaves coding outside that judgment. The earlier replay mechanism supplies a practical way to consider such a substitution: rebuild requests from the existing workload and assess whether the alternative produces satisfactory results.

His purchasing advice follows from that experience: build before buying, especially when a small company has a technical leader who can explore without pulling engineers away from their planned work. Operating an initial workflow reveals what the organization needs and where available infrastructure falls short. This recommendation comes from his experience of an unsettled category, rather than a claim that every framework has the same deficiencies.

Framework builders receive the corresponding request: use the systems in daily work. Duplicate delivery, disappearing inputs, and malformed events become hard to overlook when they interrupt your own morning. Louf credits the two-week immersion with changing his company’s trajectory and urges leaders to interrupt the constant pursuit of the next business task long enough to learn what agents can do for their company.

The closing invitation is to take the code and learn from it. This runtime is not a product .txt sells or intends to sell. It is the result of trying to make a useful workflow work every morning.

3:1717:41
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

17:41 · section reference included

Resources

From the talk

  • Explore the code behind the talk’s event-driven agents. The repository documentation includes an inbox-summarizer example, event schemas, queue inspection, and prompt tracing.

  • A practical guide to inspecting stored prompts, comparing their components, rebuilding requests, and comparing model responses.

  • The .txt structured-output library provides a concrete place to explore constrained generation and reliable machine-readable handoffs.

Transcript download
Read the transcript and explore slides

Loading transcript and slides…