Skip to content
advanced

Agent Improvement Loops: Traces, Failure Taxonomies, Regression Suites, and Hill Climbing

A prompt fix that passes the demo and fails two weeks later is not a bad prompt. It is an improvement process with no memory.

Published 2026-09-11Updated 2026-09-1218 min read
A young child observes a large green tractor in a vast open field under an overcast sky.
A young child observes a large green tractor in a vast open field under an overcast sky. Photo by Stephen Andrews on Pexels.

A prompt fix that passes the demo and fails two weeks later is not a bad prompt. It is an improvement process with no memory.

You ship a fix. The demo passes. Two weeks later the same class of failure is back, wearing a different costume: a new phrasing, a new tool, a new edge case, the same underlying defect. Nothing about the prompt was wrong. The process was. You made a local edit and called it progress, but you never wrote down what you learned, never froze a case that would catch the regression, and never measured against a baseline. Motion without accumulation.

This is the difference between editing and engineering. An edit changes behavior once. An improvement loop changes behavior and then defends the change against the next hundred commits. This article is about building that loop: traces as raw material, a failure taxonomy that earns its keep, regression cases that gate releases, trustworthy measurement, and a controlled hill-climbing cycle that does not fool you into overfitting your own suite.

We are operating one level up from the single agent loop. Assume you already know the act/observe/terminate contract of a run. This is about improving the agent between releases, not inside a single trajectory. Within-run revision, reflection, planning, and search are separate concerns with their own mechanics.

Why Prompt Edits Do Not Compound

The failure mode is not bad prompts. It is an improvement process with no memory, no baseline, and no gate.

When an agent misbehaves, there are three update surfaces you can touch:

  • Model weights — fine-tuning, distillation, adapter training.
  • Orchestration code — control flow, retries, routing, tool selection logic, state handling.
  • Context — prompts, instructions, skills, retrieved documents, examples.

Knowing which surface to change requires evidence, not intuition. A team that reaches for the prompt every time is not choosing the cheapest surface; it is choosing the surface it can edit without thinking. Sometimes the right fix is a tool schema. Sometimes it is a control-flow branch. Sometimes it is a model swap. The prompt is one option among three, and it is frequently the wrong one.

A loop is bounded. It has an input (observed behavior), a transformation (diagnosis and targeted change), a check (regression suite), and a termination or promotion condition. That structure is what makes improvement compound. Each cycle leaves behind a durable artifact — a labeled failure class, a frozen test case, a measured delta — that the next cycle inherits.

The invariant: every change must be traceable to a named failure class, gated by a regression case, and measured against a baseline before it ships.

Without that invariant, you are not improving an agent. You are rearranging its symptoms.

Traces Are the Raw Material

A trace records the full execution of an agent run: every model call, every tool invocation, every retrieval step, every intermediate output, and the sequence of decisions connecting them. It is the record of what the agent actually did with this input, under these conditions, in this run.

A raw trace tells you what happened. An enriched trace — scored by evaluators and annotated by reviewers — tells you what to do about it. The enrichment layer is the whole game. Raw traces pile up; enriched traces get acted on.

Trace sources differ in value, and you should be explicit about which one you are mining:

SourceWhat it gives youWhat it costs
ProductionThe real input distribution, including the failures you did not anticipateNoisy, private, hard to reproduce on demand
StagingFailures you can reproduce and iterate onDistribution drift from production
Test runs / benchmarksComparable across versionsNarrow, often stale
Local developmentFast iterationUnrepresentative, single-developer bias

Production carries the distribution you actually care about. Staging carries the failures you can reproduce on demand. You need both, but you should never confuse a green staging run for a healthy production agent.

A minimum viable trace schema for improvement work looks like this:

{
  "run_id": "run_8f3a...",
  "input": "user request or task spec",
  "steps": [
    {"type": "model_call", "prompt_version": "v14", "output": "..."},
    {"type": "tool_call", "tool": "search", "args": {...}, "result": "..."},
    {"type": "model_call", "prompt_version": "v14", "output": "..."}
  ],
  "final_output": "...",
  "scores": {"helpfulness": 0.4, "groundedness": 0.9},
  "annotations": [{"label": "wrong_tool", "reviewer": "human"}],
  "versions": {
    "model": "gpt-x-2025-01",
    "prompt": "v14",
    "tools": "schema-3"
  }
}

The version identifiers are not optional. A score change you cannot attribute to a cause is noise dressed as signal.

Sampling discipline matters because you cannot review everything. Define what gets pulled into review: negative scores, high-cost runs, user escalations, and — this is the one teams forget — a random control slice. Without the control slice, you only ever see failures, and you lose the ability to detect silent degradation on work that used to succeed.

Knowledge check

Check your understanding

Answer this question before you continue.

A team has many complete execution traces but cannot decide which changes to try. What is the most useful next step according to the article?
Comparison Reasoning

Focus: Distinguish raw execution records from enriched traces when deciding what evidence can guide an improvement.

Building a Failure Taxonomy That Earns Its Keep

A taxonomy is a labeling scheme, not a document. Its only test is whether each label maps to a different repair. If two labels always lead to the same fix, they are one label.

Start from observed clusters, not from a borrowed list. Pull a batch of reviewed traces, group them by what went wrong in the trajectory, then name the class. The names should describe the failure, not the fix.

Here is the distinction that keeps taxonomies honest: a symptom is what you observed, a suspected cause is your hypothesis about why, and a repair surface is where you would intervene. These are three different fields, not one label. If you collapse them, you end up with labels that prescribe the fix before you have diagnosed the problem — and you stop being able to discover that your hypothesis was wrong.

A single trace can carry a symptom class like wrong_tool, a suspected cause like ambiguous_context, and a repair surface like tool_contract. The symptom is the stable, observable part. The cause and the surface are hypotheses the experiment will confirm or reject.

Use the repair surface as triage metadata, not as the taxonomy itself:

  • Context / retrieval — missing evidence, wrong documents, stale knowledge.
  • Tool contract — wrong tool, wrong arguments, malformed calls, ignored results.
  • Orchestration / control flow — wrong order, missing verification step, premature termination.
  • Evaluator — the agent did the right thing and the scorer marked it wrong.
  • Model capability — the task is genuinely beyond the current model.

That last category is important. If a large share of your failures land in "model capability," the bottleneck is not your improvement process. It is the model or the tool surface, and no amount of prompt editing will move it.

Keep the taxonomy shallow and stable. Ten to twenty classes with clear boundaries beats a hundred overlapping labels nobody applies consistently. Watch for the two pathologies:

  • Catch-all buckets that absorb everything and therefore teach you nothing.
  • Classes so narrow they describe a single trace and never recur.

Labeling cost is real. Decide early whether labels come from human review, an LLM judge, or a hybrid, and record which — because the reliability of the label depends on its source. A judge-labeled taxonomy is only as trustworthy as the judge.

Knowledge check

Check your understanding

Answer this question before you continue.

A run shows the agent selected the wrong tool. A reviewer suspects the context was ambiguous, and the proposed intervention is to revise retrieved context. Which classification keeps the taxonomy's fields distinct?
Scenario Interpretation

Focus: Separate a failure symptom, a suspected cause, and a repair surface when classifying an agent failure.

One Trace, End to End

The rules above are easy to nod at and hard to apply. Watch the loop run on a single trace.

The observed evidence. A support agent is asked to check whether a customer's recent charge is refundable. The trace shows the agent calling search with the query "refund policy," receiving a generic policy page, then calling submit_refund directly — without ever calling verify_charge or check_eligibility. The final answer says the refund was processed. The customer was not eligible.

The classification. The symptom is premature_action: the agent acted before verifying. The suspected cause is that the tool descriptions for search and check_eligibility both read as "look up information," so the model treated them as interchangeable. The repair surface is tool_contract. Note that we did not label this wrong_tool — the agent used a real tool correctly; it skipped a required step. Different symptom, different repair.

The regression case. The failure was procedural, so the assertion must be on the trajectory, not the final string:

tool_calls = [s["tool"] for s in trace["steps"] if s["type"] == "tool_call"]
assert "check_eligibility" in tool_calls
assert tool_calls.index("check_eligibility") < tool_calls.index("submit_refund")

The hypothesis and update surface. "The premature_action class is caused by search and check_eligibility having overlapping descriptions; rewriting check_eligibility to state that it is a required precondition for submit_refund should reduce skipped verification." That is falsifiable. The suite will tell us whether we were right.

The decision. Run the case several times to get a pass rate, not a single result. If the pass rate on this class improves, the golden set holds, and the cost delta is acceptable, promote the change and log it. If not, revert and record what the experiment ruled out.

That last step is the one teams skip. A rejected change is still a result. It narrows the space of causes, and it belongs in the log next to the accepted ones.

From Failure Class to Regression Case

A regression case is a frozen input plus an expected property of the output or trajectory — not a frozen exact string, unless the task genuinely admits one answer.

For open-ended agent work, prefer property and rubric assertions over exact-match assertions. Exact match produces brittle suites that fail for cosmetic reasons: a reworded but correct answer, a different but valid tool order, a citation formatted differently. You will spend your time updating expected strings instead of improving the agent.

# Brittle: fails on any rewording
assert output == "The refund window is 30 days."

# Durable: asserts the property that matters
assert "30" in output and "day" in output.lower()
assert rubric_judge(output, criteria="states the refund window correctly") >= 0.8

Capture the trajectory, not just the final answer, when the failure was procedural. If the agent used the wrong tool, called tools in the wrong order, or skipped a verification step, the final answer might still look fine — and your suite will miss the defect.

Every failure class you encode should stay in the suite permanently. That is what makes the suite a record of what the agent has learned to handle — and a gate that prevents future changes from reintroducing problems you already solved.

Curate a golden set of best-known-good examples as a floor. Future versions must not perform worse on work the agent already did well. The golden set is not a target to beat; it is a line you are not allowed to fall below.

Suite hygiene: deduplicate near-identical cases, tag each case with its failure class, and track which change added which case. A suite with no provenance becomes an archaeological dig the moment something breaks.

Knowledge check

Check your understanding

Answer this question before you continue.

A refund agent sometimes submits a refund before verifying eligibility. Which regression check best protects against this procedural regression?
Debugging

Focus: Choose a regression assertion that captures a procedural failure in an agent trajectory rather than only its final wording.

Assume `tool_calls` is the ordered list of tool names in the captured trajectory.

Scoring, Baselines, and the Noise Problem

A score change only means something if the measurement is trustworthy. Define the baseline before the change: same suite, same model version, same tool mocks, same seeds where the runtime allows them.

Non-determinism is the default. Run each case multiple times and report a distribution or pass rate, not a single lucky run. A single run that improved is not evidence; it is a coin flip you happened to win.

Distinguish the claim each check can support:

CheckClaim it supportsClaim it does not support
Schema validationOutput structure is correctOutput is useful
Rubric judgeA graded property holdsComparative performance
BenchmarkComparative performance under stated conditionsReal-world reliability
Human reviewGround truth on a sampleScale

Do not let one stand in for another. A passing schema check proves the JSON parses, not that the agent solved the task.

Judge reliability is a measurement problem in its own right. Track agreement between your judge and human labels on a held-out slice. A judge that disagrees with reviewers more often than it agrees is a noisy instrument, not a verdict — and a loop built on a noisy instrument will hill-climb into the noise.

Beware the metric you can move without improving the agent. Length, verbosity, and format compliance are common accidental targets. If your rubric rewards thoroughness, the agent will learn to be verbose. If it rewards conciseness, the agent will learn to omit. Watch for the metric that improved while the user experience did not.

Report cost and latency alongside quality. An improvement that doubles token spend for a two-point gain is a trade, not a win. State the trade explicitly so the decision is visible.

A Promotion Rule for Noisy Deltas

Knowing that one run is insufficient does not tell you when to ship. You need a decision rule, and it has three parts:

  1. A minimum improvement on the targeted class. The change must move the pass rate on the failure class it was designed to fix by more than the run-to-run variance you measured on the baseline. If the baseline pass rate swings by ten points across runs, a five-point gain is not a gain.
  2. A no-regression floor on the golden and holdout sets. The change must not drop the golden set below its established floor, and it must not degrade the held-out slice. A targeted win that costs you a previously-solved class is a trade you did not intend to make.
  3. A cost and latency budget. The change must stay inside the token, latency, and dollar budget you set before the experiment. If it does not, the decision is not "reject" — it is "renegotiate the budget," which is a different conversation.

When the result is uncertain — the targeted gain is inside the noise band, or the golden set moved slightly down — the default is to leave the change unpromoted and run more trials. Uncertainty is not a reason to ship and hope. It is a reason to buy more evidence.

Knowledge check

Check your understanding

Answer this question before you continue.

A candidate improves the targeted class by 5 percentage points, but baseline run-to-run variance is 10 points. The golden set is unchanged and cost is within budget. What should the team do?
Comparison Reasoning

Focus: Apply the promotion rule for a noisy candidate change using targeted improvement, regression floors, and resource budgets.

Hill Climbing Without Fooling Yourself

Hill climbing here means local search over the update surfaces: propose a change, measure on the suite, keep it if it improves, revert if it does not. It is a controlled improvement cycle, not a philosophy.

Change one thing at a time when you can. Bundled changes make attribution impossible and turn a regression into archaeology. When you must bundle — a model swap that forces a prompt change, for example — say so in the change log and accept that you have traded attribution for speed.

The hypothesis must name the failure class it targets and the mechanism by which the change should fix it. "Improve the prompt" is not a hypothesis. "The premature_action class is caused by overlapping tool descriptions; rewriting check_eligibility to state that it is a required precondition for submit_refund should reduce skipped verification" is a hypothesis. It is falsifiable, and the suite will tell you whether you were right.

Accept the local-maximum limit honestly. Hill climbing finds the best nearby configuration, not the best configuration. When the suite plateaus, the next move is a structural change — a different control flow, a new tool, a model swap — not another prompt tweak. Recognizing the plateau is the skill. Grinding on a plateau is how teams spend a quarter moving nothing.

Overfitting to the suite is the central risk. Hold out cases, rotate in fresh production traces, and treat a suite that only goes up as a warning sign.

A suite that only goes up usually means the agent is learning the suite, not the task. The fix is adversarial: keep adding fresh cases from production, keep a held-out slice the change is never tuned against, and periodically re-baseline.

Keep a change log that links each accepted change to its failure class, its measured delta, and its cost delta. That log is the compounding asset. Six months in, it is the only document that tells you what your agent actually learned and why. A minimal record looks like this:

{
  "change_id": "chg_042",
  "failure_class": "premature_action",
  "hypothesis": "overlapping tool descriptions cause skipped verification",
  "update_surface": "tool_contract",
  "baseline": {"premature_action_pass_rate": 0.42, "golden_set": 0.91},
  "candidate": {"premature_action_pass_rate": 0.78, "golden_set": 0.91},
  "cost_delta": {"tokens": "+3%", "latency_ms": "+40"},
  "decision": "promoted"
}

The fields that matter most are the ones teams omit: the baseline, the cost delta, and the decision. A log of accepted changes with no rejected ones is a highlight reel, not a record.

Wiring the Loop Into CI

A sparse circular workflow moves from a reviewed production trace to failure classification, a targeted change, repeated regression evaluation against baseline and golden-set floors, and a promote-or-revert decision; promoted changes are logged and deployed, while new production failures feed back into the trace queue.
A useful improvement loop turns each observed failure into a tested, attributable change—and blocks promotion when the targeted gain, regression floor, or budget check fails.

The regression suite belongs in CI as a gate, not in a notebook as a ritual. A change that fails the suite does not ship.

Separate fast gates from slow gates:

  • Every commit: cheap deterministic checks — schema validation, trajectory assertions, exact-match cases where they genuinely apply.
  • On a schedule or before release: expensive judge-based suites, multi-run distributions, golden-set evaluation.

Production traces close the loop. Route negative-score and escalated runs into a review queue, and promote confirmed failures into the suite. This is the flywheel: today's production failure becomes tomorrow's regression case. The teams that do this well reduce the lag between observing a failure and defending against it from weeks to days.

Version everything the loop depends on — prompts, tool schemas, evaluator versions, and suite contents — so a score change can be attributed to a cause. An unversioned evaluator is a silent variable in every experiment you run.

Rollback must be a first-class path. Keep the last known-good configuration retrievable, and define who decides to revert. A gate that blocks a merge is useful; a gate that blocks a merge with no rollback plan is a bottleneck.

Human judgment has a specific job here: adjudicating ambiguous labels, curating the golden set, and approving changes that trade quality against cost. It does not belong in the routine path of every change. Reserve it for the decisions that need it.

When This Loop Is the Wrong Tool

Not every agent needs this machinery. The overhead exceeds the value in several cases, and you should recognize them before investing.

  • One-shot, low-stakes, cheap to verify by eye. If a human can glance at the output and know it is fine, you do not need a suite. You need a reviewer.
  • Failures dominated by a single missing capability. If the agent cannot do the task because the model cannot do the task, the bottleneck is the model or the tool surface, not the improvement process. Fix the capability first.
  • Failures you cannot reproduce even approximately. If you cannot reproduce it, you cannot regression-test it. Invest in environment fidelity — better mocks, better logging, better state capture — before investing in the suite.
  • An evaluator that disagrees with reviewers more often than it agrees. Fix measurement first. A loop built on a noisy signal will hill-climb into the noise.
  • Small teams with no review capacity. Start with a manual review queue and a dozen cases. The loop earns automation after it has proven it finds real failures. Do not build the CI gate before you have something worth gating.

The decision boundary is simple: build the loop when failures recur, when you can reproduce them, and when you can measure whether a fix worked. Skip it when any of those three is false.

Your First Move

Do not build the whole loop this week. Build one turn of it.

Pick one recurring failure class from the last two weeks of traces — something you have seen at least three times. Write it as a single regression case with a property-based assertion. Record the current baseline on that case, running it several times so you know the pass rate rather than a single result. Then make one targeted change that names the failure class and the mechanism by which it should fix it.

Measure. If the case improves beyond the noise band, the golden set holds, and the cost delta is inside budget, keep the change and log it. If it does not, revert and write down what you learned. Either way, you now have a loop with one turn in it, and the next turn is cheaper.

The decision rule to carry forward: a change ships only when it names its failure class, passes the suite, and reports its quality, cost, and latency delta. When the suite plateaus and no nearby change moves it, stop tweaking and start diagnosing — the plateau is a signal that the loop has found the local maximum and the next gain lives in the structure, not the prompt.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

A team has tried several nearby prompt edits one at a time, and the regression suite has plateaued while holdout performance remains unchanged. What is the article's recommended next move?
Question 1 of 2Scenario Interpretation

Focus: Recognize when a plateau indicates the need for a structural change rather than another local prompt adjustment.

Which situation most clearly meets the article's decision boundary for building the improvement loop?
Question 2 of 2Misconception Check

Focus: Decide whether the improvement loop is appropriate by checking recurrence, reproducibility, and measurability of failures.

References

  1. The Agent Improvement Loop Starts with a Tracewww.langchain.com
  2. Human judgment in the agent improvement loopwww.blog.langchain.com
  3. Agent-in-the-Loop: A Data Flywheel for Continuous Improvement in LLM-based Customer Support - ACL Anthologyaclanthology.org
8sources checked
8source domains
10searches run

Research updated Sep 11, 2026

Related sites

Build the foundations behind advanced AI systems

Use LearnLLMFast for practical LLM application foundations and LearnPyFast for the Python mechanisms that support implementation work.

LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast
Python tutorialstutorial

LearnPyFast

Beginner-friendly Python tutorials, examples, and learning paths for practical programming foundations.

PythonProgrammingBeginners
Visit LearnPyFast

Keep exploring

Related AI engineering tutorials

Continue with adjacent system layers, implementation patterns, and current AI engineering ideas.