Stateless AI–Human Interaction
- Published
Some thoughts on using REST’s concept of statelessness to improve AI–human interaction. I wrote this with the scenario of asking a coding agent to perform development work in mind, but similar approaches seem applicable to many kinds of knowledge work.
LLM context ≈ protocol state
As of August 4, 2025, maintaining context is crucial in conversations with coding agents. Starting a new session loses the preceding conversation and code-editing history, making it difficult for the agent to continue work coherently. Compacting the context in Claude Code can also cause a sudden drop in work quality.
“Context” in AI–human interaction is somewhat analogous to “state” in a communication protocol. When AI talks to a human or a human talks to AI, the context of their preceding conversation has to carry over.
Stateful and stateless protocols
Consider an air-conditioner remote to compare stateful and stateless protocols. We want to set the temperature to 24°C. Here is a stateful protocol:
- Remote: Tell me the current set temperature.
- Air conditioner: It is 25°C.
- Remote: Lower it by 1°C.
- Air conditioner: Done.
Here is a stateless protocol:
- Remote: Set the temperature to 24°C.
- Air conditioner: Done.
(In practice, most remotes have only a transmitter and no receiver, so they use a stateless protocol.)
One advantage of REST is statelessness. There is no need to know what was said previously: put everything you want to say into one self-contained request, and the recipient can handle it. “Lower the temperature by 1°C” is not self-contained; it also requires the current setting. “Set the temperature to 24°C” is self-contained.
Sending a self-contained request does, however, require state management. “Statelessness” means the recipient need not manage conversational state; the sender needs to manage it to construct self-contained requests.
For example, a remote remembers the current setting internally. When the user presses “temperature down 1°C,” it uses its internal state—the setting is currently 25°C—to construct “set the temperature to 24°C” and sends that command to the air conditioner. The air conditioner can execute the command without remembering previous conversations with the remote.
Applying this to coding agents
What if we applied this idea to AI agents?
Let a session consist of requesting one meaningful unit of work—adding a feature, fixing a bug, changing behavior, improving performance, and so on—and having the agent complete it.
If the next session’s request can be entirely independent of the preceding one, so that we can close the old conversation and start a new one, we have implemented something analogous to REST’s statelessness.
I would like this to work:
- Open a new conversation session.
- Send one request containing everything needed.
- Let the AI agent handle the request independently.
- Close the session.
Steps 1 and 4 are easy. Step 3 is easy if step 2 is done well and the model is sufficiently intelligent. Step 2 is the problem. Because it is difficult, tedious, or time-consuming, we do things like:
- Keep talking in the same session for as long as possible to preserve context.
- Rely on context-compression tricks such as Claude Code’s
compact. - Pay more to cram as much information as possible into context, as with Cursor’s Max mode.
But as context grows, AI starts behaving strangely, ignoring available information or doing things it was not asked to do: context rot. Needle-in-a-haystack benchmarks begin to seem beside the point. We burn tokens loading all sorts of source code into context in search of relevant information, but the service provider is the one having a good time.
It would be nice to make step 2 easy, using minimal LLM context and without excessive human effort.
Specifications
In his July 2025 talk The New Code - Specs: Write once, run everywhere, Sean Grove argues roughly as follows:
- In software configuration management, we manage source code, not artifacts derived from it, such as compiled binaries.
- This is because source code contains more information and intent through comments, variable names, and so on, while derived artifacts contain less.
- If code is derived from prompts, throwing away each prompt and managing only the source code is strange.
He is right.
“Source code is an important artifact and belongs under configuration management” generalizes to “primary artifacts that cannot be derived from other artifacts belong under configuration management.” Even generated source code—such as client stubs and server skeletons in networking code—is generally not version-controlled.
In agentic coding or vibe coding, we often write prompts carelessly, throw them away, and carefully maintain the resulting code. On reflection, that is the wrong way around. Writing and maintaining prompts well matters. Code is a by-product. Not quite yet, perhaps, but increasingly so.
“Write once, run everywhere” in the talk is actually Java’s slogan, and the analogy works in several ways.
- Give the JVM source code converted into bytecode, and it converts that into machine code for the environment and runs it.
- Give an LLM a prompt, and it converts that into source code for the language and environment you want. (Converting source code to machine code is already automated, so that part is not the problem.)
Returning to the point: if maintaining prompts well matters, what does a well-written prompt worth maintaining look like? A specification.
The growing practice of writing Markdown PRDs and asking AI agents to update them seems related to this line of thought. AWS released an agentic coding tool called Kiro on July 14, 2025, naming “spec-driven development” as its central differentiator.
But it matters what specific format and content a specification should have. I also think it needs supporting tools and processes. Every methodology consists of artifacts, tools, and processes. Consider UML, Rational Rose, and the Unified Process. Early agile methods favored “low-tech tools,” such as paper and sticky notes, which could create the illusion that they had no tools.
Specifications, tools, and process
More concretely, the following could enable stateless AI–human interaction:
- Specification: A document recording business context, a feature list, assessable acceptance criteria for each feature, dependencies between features, and so on. It should be semi-structured: machine-analyzable while readable and understandable to humans and LLMs.
- Tools: Traditional programs, probably a CLI, that analyze internal inconsistencies in the specification (mutual dependencies, features unrelated to business context, features lacking acceptance criteria); analyze traceability between specification and code (links between acceptance criteria and automated acceptance tests); and output text reports describing the overall project context, current state (measured by passing acceptance tests), and next task.
The process is:
- A human, assisted by AI, adds a feature and acceptance criteria to the specification.
- Open a new conversation session.
- Tell the AI: “Invoke the tool and perform the next task according to its output.”
- When invoked, the tool prints the project’s overall context and state, then identifies the next task. It also lists commands for obtaining more information. This resembles
git status. It also connects with REST’s HATEOAS: the AI needs to know only one command, through which it discovers the commands it can run next. - The AI agent works independently, invoking various tools as needed.
- Close the conversation session.
All important context lives in the specification and code, and tools automatically generate the context needed for the next instruction. We can therefore discard the entire conversation context at any time with confidence.
Implementation
I am experimenting with this in Agentic coding experiment 3. It is now reasonably capable of “dogfooding”: I am using the tool to develop the project that builds the tool itself.