Engineering Discipline for Agentic Systems
The first version of an AI feature slice is a literal sequence of API calls in a single file, with no framework, abstraction, or agent loop.
Why Teams Reach for Structure Too Early
When engineers start building an AI feature, many reach for structure right away. They choose a framework, define an agent loop, create wrapper classes for every model call, and plan a set of abstractions for features that do not exist yet. This instinct comes from good habits in conventional software. In AI work, it often backfires. The first version becomes hard to read, hard to run, and hard to test before anyone has seen it do its basic job.
This article examines a belief that many builders hold: that the first version of an AI feature should already look like a finished system. The source argues the correct starting point is much smaller. The rest of this article explains what that smaller starting point looks like, why it is deliberate, and how the system grows from it.
Two Versions of the Same Feature
Before reading the correction, consider a simple situation. Suppose a feature runs several model calls in sequence, and the final reply is wrong. One version of the system is a single readable file with six steps written one after another. Another version is spread across a framework, a loop, and several helper classes.
What do you think happens?
Which version makes it easier to find the step that produced the bad reply?
Reveal answer
The single readable file with six steps in order
In the literal file, the path a value takes is the same as the order of the lines, so you can read down the sequence and check each step. In the layered version, the value may pass through a loop iteration and several helper methods before you can see what it became.
The Literal First Slice
The first slice of an AI feature is a literal sequence of API calls in a single file. There is no agent framework, no abstraction layer, and no agent loop. The whole flow is written out: receive the input, call the model with one prompt, parse its output, call the next model with a second prompt, format the result, and return it. Each of these steps is visible on its own line.
The source is candid that this code is not elegant. The file is ugly. It is also legible, and the source gives three reasons this matters. First, the customer can read it, so the people who care about the outcome can check what the system does. Second, the developer can run it directly, without setting up machinery first. Third, an evaluation set can run against it, so the first version can be measured from the start.
The literal version is a working baseline. Once a clear baseline exists, every later change can be compared against it.
The example below is a generic stand-in that runs without any external service. The function call_model represents one model call. In a real first slice it would be replaced by an actual API call. The rest of the file is the literal sequence: two model calls, a parsing step, a formatting step, and a return.
Answer: Check this summary for errors: Summarize the request: refund policy questioncall_modelis a stand-in for one model call- Each step stores its result in a named variable on its own line
handle_requestis the only function that decides the order of steps
Tracing Data Through the Sequence
Read the diagram below as a single path. Each arrow carries one value from one step to the next, and nothing has to be looked up elsewhere to follow the flow. This is the property that makes the literal version easy to debug: the path a value takes is the same as the order of the lines in the file.
Now trace the values one at a time. The variable user_text is the only input to the first model call, so it is the origin of everything downstream. The first call produces plan, which is raw text carrying a draft prefix. The line summary = parse_output(plan) strips that prefix, so summary is the value that the second prompt is built from. The second call produces review, and checked = parse_output(review) gives the value that format_reply wraps into the final reply.
Locating the source of a bad reply
The final reply in the code above contains an unwanted phrase. Which line should you examine first, and why?
- 1Start at the output
The reply comes from
format_reply(checked), so the last step to inspect is the formatting of checked. - 2Move up one line
checked comes from
parse_output(review). If checked is wrong, the question is whether review is wrong or whether parsing changed it. - 3Check the model result
review is the raw output of the second
call_model. If review already contains the phrase, the second prompt or the model output is the cause. - 4Move back to the start
If review is clean but the reply is not, the bug is in a later line. If review is already bad, keep moving up to plan and the first prompt.
Reading down the sequence and checking each named variable isolates the failing step. You change one line, rerun the file, and see whether the reply improves.
Fixed Sequence Versus Agent Loop
The literal slice runs its steps in a fixed order that is written into the code. An agent loop works differently. The source describes an agent loop as one of the structures that engineers often add too early. The diagram below contrasts the two control patterns. In the first, control moves straight down the file once. In the second, control returns to an earlier point until a stop condition is met.
The loop is not wrong in itself. The point of the literal slice is that the developer can see the full order of steps before adding a mechanism that decides the order at runtime. A loop hides the sequence behind a condition. When the reply is wrong, you first have to find out which iteration produced the bad value, and only then which step inside it did.
When Frameworks and Abstractions Earn Their Place
Frameworks and abstractions are useful. The source's position is that they belong in a later phase, and that the right phase is rarely the first slice. Once the literal sequence runs and the evaluation set can measure it, structure can be added where the code has shown a real need for it.
The diagram is an illustration of the layers the source names, not a fixed architecture. Each layer is something a team may add once the literal version shows the need. The source's reasoning is about timing: abstractions chosen before the working slice exists are chosen without evidence.
A developer who has not yet seen which steps repeat, which prompts change, or where failures cluster may create a layer that fits the imagined system instead of the real one. Growing from a working literal slice lets the structure be shaped by what the system actually does. In the example above, you would wait until the same pattern of call, parse, and call appears in several features before you extract it into a helper.
Mistakes Teams Make With the First Slice
Common mistake Designing the framework before the feature runs
Why it failsThe structure is chosen for an imagined system, so it may not match the steps the model actually needs.
Do this insteadWrite the literal sequence first, run it, and add structure only where the code shows a need.
Common mistake Treating the literal file as throwaway code
Why it failsThe literal version is the working baseline that later changes are compared against.
Do this insteadKeep it runnable and evaluate it against an eval set so every later change has something to be measured against.
Common mistake Hiding steps inside a loop before the order is understood
Why it failsWhen the order is decided at runtime, finding the step that produced a bad value takes more work.
Do this insteadName each intermediate result in its own variable, and move to a loop only after the fixed order is clear.
Common mistake Wrapping every model call in a class before the calls repeat
Trace the Literal Slice
Using the handle_request function from the earlier example, state which variable holds the input to the second model call, which line produces it, and what happens to its value between the two calls. Then say which line you would change first if the final reply were missing the word refund.
Hints
- Look for the line that builds the second prompt, and find the variable it uses.
- The value passed to the second call comes from
parse_outputapplied to the first model result. - Start at
format_replyand move up through checked, review, summary, and plan.
Engineering Discipline in Agentic Work
The difference between a production-ready agentic system and a demo that breaks on the first customer test is largely a matter of engineering discipline. The source's central claim is that good agents are mostly just software. The same disciplines apply as to any other software: the behavior should be visible, the steps should be testable, and failures should be traceable to specific places in the code. The literal first slice is a practical way to hold to those disciplines from the beginning.
Key Takeaways
- The first slice of an AI feature is a literal sequence of API calls in a single file, with no framework, abstraction, or agent loop.
- The literal version is legible to the customer, runnable by the developer, and evaluable against an eval set, which makes it a working baseline.
- In a literal slice, each intermediate result is named on its own line, so a failing step can be found by reading down the sequence and changing the relevant line.
- Frameworks, agent loops, and abstractions are useful, but they usually belong in a later phase, once the working slice shows where structure is needed.
- Good agentic systems are mostly software, so their behavior should be visible, their steps testable, and their failures traceable.