Stop reviewing AI-generated code first. Review the results.

a computer screen with a bunch of code on it

Coding agents are fast. The problem is that fast code generation creates a new bottleneck: understanding what the agent actually built.

Keivan Esbati hit this wall while building ML applications with coding agents. His review habit stayed constant while the codebase grew. Eventually he was reading hundreds of lines of diffs per session, and the code was becoming meaningless without understanding what the application was actually computing.

The fix was not a better diff tool. It was a different unit of review entirely.

The Code Review Trap

Early on, reviewing the diff after each agent session is manageable. The codebase is small, the changes are contained, and you can still hold the whole thing in your head.

Then the application grows. A single feature in an ML app might touch preprocessing, model inference, postprocessing, and application logic. The agent adds several hundred lines in one session. At some point, reading the code stops being the same thing as understanding the application.

Esbati describes the problem precisely: he was spending most of his time reviewing the agent’s implementation rather than the application output. He was trying to control the means instead of the result.

a train traveling through a forest filled with lots of trees

️ The Framework Shift: Explicit, Inspectable Pipelines

Without code review, the application collapses into a black box:

Input → [ ? ? ? ? ? ] → Output

The fix was to ask the agent to compose the application as a set of explicit, named steps rather than arbitrary functions and modules:

Pipeline([
    Preprocess(...),
    Inference(...),
    Postprocess(...),
    ApplicationLogic(...),
])

The agent still writes the implementation behind each step. The code is still there. But the developer no longer needs to read the entire codebase to understand what the computation is doing.

With named pipeline steps, intermediate data becomes visible:

Input → Preprocess → Inference → Postprocess → Application Logic → Output
  │          │            │            │              │
  ▼          ▼            ▼            ▼              ▼
 data      input        result       result         state

When something goes wrong, the useful question shifts from what did the agent change? to at which step did the result stop looking right? That narrows the problem immediately.

Why This Works for ML Specifically

ML applications are fundamentally computations over data with state management layered on top. But the standard toolkit for understanding them, source code, logs, and final outputs, leaves a large gap in the middle.

The final output tells you what you got. The source code tells you how it was implemented. The intermediate results tell you what actually happened along the way. For ML correctness, the intermediate results often matter more than either of the other two.

This framework makes those intermediate results a first-class object in the development workflow rather than something you reconstruct after the fact by reading the code.

3D rendered ai text on dark digital background

How It Changes the Agent Workflow

Structuring applications as inspectable pipelines changes what you ask the agent to do. Instead of asking it to produce code that seems plausible, you ask it to structure code so that the computation is observable at each boundary.

This creates a shared structure between developer and agent. The agent handles implementation details within each step. The developer reasons at the level of steps. When a problem surfaces, the developer can point the agent to the specific failing step instead of asking it to debug the entire application from scratch.

Code review does not disappear. Performance, concurrency, resource management, and security still require reading implementation. But it moves to second in the review order, not first. Results first, code second.

When This Works

  • ML applications where intermediate data transformations drive correctness more than code structure does
  • Any AI-assisted development workflow where agent sessions produce large diffs
  • Projects where debugging time is dominated by figuring out where something broke rather than why

When It Does Not

  • Applications where the computation is trivial and a single input-output check is sufficient
  • Domains like security and concurrency where implementation details are the risk, not data flow
  • Very early prototypes where structure introduces more overhead than value

‍ The Open Source Implementation

Esbati built a small framework around this idea called ml-pipes, available on GitHub under trained-by-humans/ml-pipes. The goal is to compose applications as pipelines you can run, inspect, trace, and benchmark.

The examples in the repository show the pipeline structure, data flowing through each step, and how to inspect the computation in practice. If you are building ML applications with coding agents and spending more time reading diffs than checking outputs, the examples are worth twenty minutes.

As code generation gets faster, the question that matters is not how to review more generated code. It is how to observe what the computation is actually doing.

Stay on top of AI & Automation with BizStack Newsletter
BizStack  —  Entrepreneur’s Business Stack
Logo