DEV Community

Cover image for Why Code Diffs Are Not Enough for AI Agent Changes
Raju Dandigam
Raju Dandigam

Posted on

Why Code Diffs Are Not Enough for AI Agent Changes

A pull request changes three lines in a prompt. The source diff is tiny. The resulting agent run adds a tool call, skips a planning step, changes its recovery path, and takes twice as long.

Which diff describes the risk more accurately?

Both do—but they describe different things.

I maintain AgentInspect, an open-source TypeScript toolkit for inspecting agent runs locally. I designed its run-diff workflow around a simple idea: code review tells us what the developer changed; execution evidence tells us what the agent did differently. The examples below use synthetic fixtures verified against agent-inspect@6.17.4.

Source changes and behavior are no longer tightly coupled

In ordinary deterministic code, a source diff is often a strong predictor of runtime change. Agent systems add several moving parts:

  • prompts and system instructions;
  • model versions and sampling behavior;
  • tool descriptions and schemas;
  • retrieval content;
  • external services;
  • memory and conversation state;
  • orchestration and fallback policies.

A large refactor can preserve the same trajectory. A one-word prompt change can alter tool selection. Identical code can behave differently when a model or external result changes.

That does not make code review obsolete. It means the review unit needs another layer:

source diff                    behavior diff
-----------                    -------------
what was edited?               what path changed?
what code owns the change?     where did runs diverge?
is the implementation sound?   which steps/errors/outputs differ?
Enter fullscreen mode Exit fullscreen mode

Capture two comparable runs

A useful behavioral comparison needs a deliberate baseline and candidate:

baseline
  same synthetic input
  pinned or recorded configuration
  known-good trace

candidate
  same synthetic input
  intended code/prompt/model change
  newly captured trace
Enter fullscreen mode Exit fullscreen mode

Control what you can. Record what you cannot. If the input, retrieval corpus, model, and tool fixtures all change at once, the diff may be accurate but difficult to interpret.

With two local run IDs, compare them from the CLI:

npx agent-inspect diff minimal-success minimal-error \
  --dir .agent-inspect
Enter fullscreen mode Exit fullscreen mode

The synthetic fixture output begins with the summary and first divergence:

Run diff
Left:  minimal-success
Right: minimal-error

Summary:
  Differences: 4
  Errors: 0
  Warnings: 3
  Info: 1

First divergence:
  run-status at (run)
    left: success
    right: error
Enter fullscreen mode Exit fullscreen mode

That “first divergence” is often more actionable than a long list of event differences. It gives the reviewer a starting point for the causal investigation.

Read added and removed steps as structural evidence

The same fixture reports:

Differences:
  [warning] run-status
    Run completion status differs
    left: success
    right: error
  [info] duration
    Run duration differs
    left: 120
    right: 70
  [warning] step-removed plan
    Step only in left run: plan
    left: step_root
    right: (undefined)
  [warning] step-added failing-step
    Step only in right run: failing-step
    left: (undefined)
    right: step_fail
Enter fullscreen mode Exit fullscreen mode

The evidence says that plan appears only in the left run and failing-step only in the right. It does not automatically say why.

Possible explanations include:

  • the candidate genuinely skipped planning;
  • a step was renamed;
  • instrumentation boundaries changed;
  • the agent chose a different path;
  • the run ended before reaching the step.

This is why a behavioral diff is an input to review, not an automatic verdict. Pair it with the source diff and inspect the execution tree around the divergence.

Focus the diff on the question you are asking

The CLI can limit the comparison to a specific check dimension. To inspect only structure:

npx agent-inspect diff minimal-success minimal-error \
  --dir .agent-inspect \
  --check structure
Enter fullscreen mode Exit fullscreen mode

That removes status and duration noise and leaves the added/removed steps. For a performance-oriented review:

npx agent-inspect diff minimal-success minimal-error \
  --dir .agent-inspect \
  --check timing \
  --duration-threshold 20ms
Enter fullscreen mode Exit fullscreen mode

The command also supports JSON output for automation, --ignore-duration, focus modes, and verbose output. A practical rule is to begin with the broad human-readable diff, then narrow the view when you know which hypothesis you are testing.

Timing differences require controlled interpretation

The fixture reports 120 versus 70 milliseconds. It would be a mistake to generalize that single synthetic delta into a performance claim.

Agent latency can vary with network conditions, cache state, provider load, token volume, and concurrency. A timing diff is most useful when:

  • the tool and model calls are stubbed in a deterministic test;
  • the difference is large relative to expected noise;
  • multiple representative runs show the same pattern;
  • the structural diff explains the extra work.

Use --duration-threshold to suppress insignificant changes, but derive the threshold from your environment. Do not choose a number merely because it makes a current test pass.

A run diff does not rerun the agent

AgentInspect’s diff is a read-only comparison of persisted traces. It does not replay either agent, invoke a model, or prove that the difference will recur.

That property is useful for review: the comparison is deterministic for the two stored artifacts. It is also a limitation: representative capture remains your responsibility.

I think of the workflow as three separate actions:

execute -> capture evidence
compare -> describe observed differences
judge   -> decide whether the change is acceptable
Enter fullscreen mode Exit fullscreen mode

Only the middle action is the run-diff engine.

Add a behavior-evidence section to pull requests

For changes that can materially affect an agent path, a compact pull-request section can make review faster:

## Agent behavior evidence

- Fixture: `refund-eligible-order`
- Baseline run: `refund-before`
- Candidate run: `refund-after`
- Expected change: prefer cached policy when current
- First divergence: `retrieve-policy` replaced by `load-policy-cache`
- Contract result: pass
- Evidence artifact: attached CI bundle
- Reviewer note: no production or customer data used
Enter fullscreen mode Exit fullscreen mode

This is intentionally concise. The full trace should remain an artifact, not be pasted into the pull-request description.

The most important field is “expected change.” It tells reviewers whether an observed divergence is intentional. Without that statement, the diff is merely a list of facts.

Combine diffing with contracts

A diff answers “What changed?” A contract answers “Did a declared invariant still hold?” Use both.

Suppose a candidate run replaces remote retrieval with a cache hit. The structural diff should show the path change. A contract might still require:

  • successful completion;
  • no forbidden write tool;
  • validation before the final response;
  • a bounded tool-call count.

The candidate can therefore differ from the baseline and still pass the invariant gate. This is healthier than either extreme:

  • rejecting every structural change; or
  • accepting every change that ends with plausible prose.

What to compare in practice

Choose fixtures around decisions, not around random traffic. High-value comparisons include:

Prompt or instruction changes

Did tool selection, ordering, retry behavior, or token usage change?

Model upgrades

Does the new model reach the same goal with a different trajectory? Does it invoke a fallback more often in controlled cases?

Tool-schema changes

Did a renamed or re-described tool disappear, get replaced, or start failing?

Orchestrator refactors

Did parent-child structure, concurrency, or error propagation change even if final answers stayed stable?

Retrieval changes

Did the run add or skip retrieval, or generate before the required evidence step?

For each case, pair the behavioral observation with a domain-specific quality check. A shorter path is not necessarily a better answer.

Review what executed, not only what was edited

Code diffs remain the foundation of software review. Agent systems need an additional artifact because runtime behavior depends on more than source text.

A disciplined workflow is straightforward:

  1. capture a known-good baseline for a synthetic, representative fixture;
  2. capture the candidate with controlled inputs;
  3. inspect the first divergence and focused structural changes;
  4. run stable deterministic contracts;
  5. preserve the evidence with the pull request;
  6. apply human and semantic judgment to the result.

This does not eliminate nondeterminism. It gives reviewers something more precise than “I tried the prompt and it looked better.”

The tagged release and fixtures used for this article are available on GitHub. If you adopt behavior diffs in code review, begin with one high-risk fixture and learn which differences your team actually finds actionable.

Top comments (1)

Collapse
 
kevinpruett023_kevinpruet profile image
kevinpruett023 kevinpruett023

This is also good. I wanna discuss further about collaboration via telegram.
@morganruiz5363 this is my tg. how about you?