↓ Skip to main content

Three Feedback Loops of Sustainable AI Software Development

·17 mins
Michael Hönnig
Author
Michael Hönnig
Until autumn 2027 only available for consulting engagements with a small number of hours – remote, in German and English.

If AI programs faster and faster, who takes care of quality? This article presents three autonomous feedback loops for correctness, performance and architecture and shows why human steering still matters.

Speed Alone Does Not Make Software Development Sustainable
#

With agentic AI, we can now develop software at a speed that was hard to imagine a few years ago. AI agents implement features, write tests, fix bugs and create pull requests. More and more often, they can complete these tasks largely autonomously.

But speed alone does not make software development sustainable.

If we generate more and more code without keeping an eye on its long-term quality, a problem emerges: The software may work brilliantly today, but with every change it becomes harder to understand, extend and maintain.

The problem is not fundamentally new. Human developers under time pressure can accumulate technical debt as well. The difference lies in the speed at which AI can create such problems.

So the interesting question is:

Can we use agentic AI not only to develop new features, but also to continuously improve the existing software?

One interesting approach is autonomous feedback loops.

An agent observes certain quality attributes, identifies opportunities for improvement, changes the code and then checks whether its change actually brought an improvement.

Three particularly interesting examples are:

  1. Correctness: Systematically find and fix bugs.
  2. Performance: Measurably improve runtime behavior.
  3. Architecture: Reduce complexity and coupling to make future changes easier.
Three feedback loops between feature development and an improved codebaseAt the top, feature development with agentic AI. Below it, three loops: correctness with DST and tests, which find and fix bugs; performance with OpenTelemetry and benchmarks, which measure and optimize bottlenecks; architecture with deslop, which reduces complexity and coupling. At the bottom, the improved codebase on which the next feature development builds with new measurements.Agentic AI: Feature DevelopmentCorrectnessDST / TestsFind andfix bugsPerformanceOTel / BenchmarksMeasure and optimizebottlenecksArchitectureDeslopReduce complexityand couplingImproved CodebaseNext feature development with new measurements
Three feedback loops between feature development and a continuously improved codebase

Correctness: Finding Bugs Before Users Do
#

The first feedback loop tries to continuously improve the functional correctness of the software.

For that, an agent needs a way to detect bugs reliably.

One particularly interesting technique is Deterministic Simulation Testing (DST).

Deterministic Simulation Testing
#

DST is used, among others, by FoundationDB and TigerBeetle. The technique is also used outside of databases: Dropbox tests its sync engine this way, MongoDB and the Ethereum network use the Antithesis platform, which was created by the FoundationDB founders.

The idea is to run the actual application code in a controlled environment in which normally unpredictable influences are simulated.

These include, for example:

  • Network interruptions and delayed messages
  • Crashes of individual components
  • Different orderings of concurrent operations
  • Errors when reading and writing data
  • System time and random numbers

The decisive advantage: the simulated runs are reproducible.

If a particular combination of events triggers a bug, the same run can be executed again. An AI agent can analyze the bug, implement a fix and then check whether the bug has actually disappeared.

A very large number of different failure scenarios can be examined automatically this way.

Does Every Piece of Software Need DST?
#

No. For an ordinary business application with a REST API, a database and a few background jobs, a full DST system can cause disproportionate effort.

The underlying idea is transferable, though:

The more reliably we can detect and reproduce bugs automatically, the better our test system serves as a foundation for autonomous improvements.

For business applications, the following techniques come into question, among others:

  • Executable specifications, for example with Gherkin scenarios
  • Integration and scenario tests
  • Property-based testing
  • Mutation testing to assess test effectiveness
  • Static analysis and compiler checks
  • Targeted simulation of failure conditions

Executable specifications are particularly important here.

After all, an agent must not only know that a test fails. It must also be able to recognize which behavior is actually expected.

The Limit: Tests Do Not Automatically Know the Requirements
#

Even a perfect test system does not guarantee functionally correct software.

If a requirement is missing or has been specified incorrectly, the agent cannot reconstruct it from the test results alone.

A system can pass every test and still do exactly the wrong thing.

This is the difference between verification and validation: Verification checks whether the implementation matches its specification; validation checks whether the result actually achieves what was wanted (more on this in the article Agentic AI Is Like a Rocket).

So the validation question, what the software should do, remains separate from the verification question, whether the implementation meets these requirements.

The first feedback loop can take over verification increasingly autonomously. Validation still needs domain goals and their review.

Performance: Measurable Optimization Instead of Gut Feeling
#

The second feedback loop deals with the speed and efficiency of the software.

A different approach suggests itself here: Instead of just detecting bugs, we can continuously measure performance indicators and try to improve them.

OpenTelemetry provides a technical foundation for this.

What Is OpenTelemetry?
#

OpenTelemetry, often abbreviated as OTel, is an open framework for collecting and transmitting observability data from software systems.

This includes in particular:

  • Metrics: Measurements such as response times, throughput, memory consumption and error rates
  • Traces: The processing of a request across different components
  • Logs: Recorded events and error messages

OpenTelemetry provides the instrumentation and transport of the data, not automatically the optimization itself.

An AI agent, however, can analyze this information to detect performance problems and propose targeted improvements.

Performance Hill Climbing
#

An interesting approach is what is known as hill climbing.

An optimization algorithm tries to approach a better result step by step.

For an AI agent, this could look as follows:

  1. Measure current performance.
  2. Identify a possible bottleneck.
  3. Make a targeted code change.
  4. Measure performance again under comparable conditions.
  5. Adopt the change if it is actually better.
  6. Otherwise discard the change and try a different approach.
Performance hill climbing as a cycleMeasure performance, develop an optimization, run the benchmark, then decide: better and correct? If yes, the change is adopted and the cycle starts again with a new measurement. If no, the change is discarded and a different optimization is developed.Measure performanceDevelop optimizationRun benchmarkBetter andcorrect?Discard changeAdopt changeNoYesmeasure again
Performance hill climbing: only changes that are measurably better and still correct are adopted

The result can be a step-by-step improvement.

Throughput over several optimization iterationsLine chart with seven iterations. Throughput rises from 300 requests per second in iteration 0 to 380 and 460. The attempt in iteration 3 drops back to 300 and is discarded; throughput stays at 460. Only the next attempt in iteration 4 improves it to 570 and is accepted; iterations 5 and 6 raise it to 650 and 730 requests per second.02004006008000123456IterationThroughput (requests/s)Attempt 3 regresses:discarded, stays at 460Attempt 4 improves:accepted
Illustrative measurements of a performance optimization over several iterations: the attempt in iteration 3 reduces throughput and is discarded; only the next attempt brings an improvement and is accepted

Not every optimization leads to an improvement; a regression is discarded under a simple hill-climbing strategy.

An example from a typical business application:

A REST endpoint takes 800 milliseconds at the 95th percentile. OpenTelemetry traces show that a substantial part of that time comes from repeated database queries.

The agent identifies an N+1 query problem, optimizes the data access and then runs the functional tests and performance benchmarks again.

If the response time drops to 250 milliseconds without violating other quality goals, it can adopt the change.

Performance Has Several Dimensions
#

An optimization is rarely as simple as “faster is better”, though.

For example, a caching layer can reduce response time but at the same time increase memory consumption and create new data consistency problems.

So this feedback loop also needs clear goals and limits.

One possible goal could be:

Minimize the P95 response time as long as memory consumption, error rate and data consistency stay within given limits.

Such goals are generally well suited to automation.

One prerequisite, however, is that the measurements are reliable and comparable. Otherwise, different load profiles or fluctuating environmental conditions can fake supposed improvements.

Architecture: Can AI Declutter Its Own Code?
#

The third feedback loop is perhaps the most interesting, and at the same time the most difficult.

It is not primarily concerned with whether software works or is fast enough, but with how easily it can be changed in the future.

This is where the term deslop increasingly appears in discussions about AI-generated code.

What Does Deslop Mean?
#

Slop is a derogatory term for low-quality AI-generated content, including unnecessarily complicated, redundant or poorly structured code.

Deslop accordingly refers to the attempt to remove such quality problems afterwards.

An AI agent could, for example:

  • Merge duplicate implementations
  • Remove unnecessary abstractions
  • Reduce superfluous error handling
  • Divide responsibilities between components more clearly
  • Break cyclic dependencies
  • Detect redundant tests
  • Simplify hard-to-understand control flows
  • Reduce coupling between modules

At first, this sounds like ordinary refactoring.

The difference is that such work no longer happens only as a by-product of concrete feature development, but regularly and deliberately as an improvement process in its own right.

The Problem: What Is a Good Architecture?
#

While correctness and performance can be measured objectively, at least in part, assessing a software architecture is harder.

An architecture is not good merely because it has few classes or looks particularly elegant.

It is good if it serves its purpose.

One decisive purpose is to make future changes as simple, safe and inexpensive as possible.

This is exactly where an interesting new way of measuring emerges.

Token Consumption as a Maintainability Metric
#

If AI agents take over a large part of our software development, we can measure their actual effort for changes.

For example:

MetricHard-to-maintain codeWell-maintained code
Files read458
Files changed173
Tokens required180,00035,000
Agent iterations123

Illustrative numbers for comparable changes, not empirical results.

The basic reasoning is convincing:

If an agent has to examine 45 files and change 17 files for a small business change, that may indicate excessive coupling or unclear responsibilities.

If the same business change can be implemented with considerably less effort, that could be a sign of a better architecture.

Token consumption thus becomes a potential externally observable metric for maintainability.

High token consumption is not just a symptom here, but a problem in itself. The more context an agent has to take in, the more likely details get lost in it; LLMs work measurably less reliably in very large contexts. More tokens therefore mean:

  • lower quality of results, because details get buried in the context
  • higher costs under usage-based API pricing
  • slower processing and longer feedback cycles
  • more context compactions, in which earlier findings are lost
  • a hard limit: if a change no longer fits into the context window, the agent has to split it or fails

Hard-to-maintain code thus makes exactly the work that is supposed to improve it more expensive and worse.

But Does Token Consumption Really Measure Architecture Quality?
#

Not directly.

Token consumption also depends on other factors:

  • Capability and behavior of the model used
  • Size and preparation of the provided context
  • Efficiency of the development tools used
  • Difficulty of the task at hand
  • Quality of the documentation
  • Number of correction attempts required

An agent that checks less thoroughly may need fewer tokens and still produce worse code.

So raw token consumption would be dangerous as an optimization target.

More interesting would be the effort per successfully and verifiably correct change, measured over a sufficiently large set of comparable tasks.

Local Improvements Are Not Automatically Global Improvements
#

Another difficult point is the time horizon.

Removing an abstraction can simplify the next ten changes but make the eleventh considerably harder.

Conversely, an additional abstraction can initially cause more code but simplify numerous changes in the long run.

An autonomous deslop agent often sees only a slice of the future requirements.

That is why such agents are particularly good at local improvements. Fundamental architecture decisions, on the other hand, need a broader view and, where necessary, human steering.

Three Feedback Loops, One Common Goal
#

The three techniques described target different quality attributes.

What is interesting is not the choice of exactly these three areas.

What matters is the separation between software development and continuous, measurable quality improvement.

In classic software development, quality improvement often only happens when someone notices a concrete problem and schedules time to fix it.

However, the different feedback loops must not make arbitrary changes independently of each other.

A performance optimization must not violate correctness. A refactoring must not degrade performance unnoticed. And a supposed architecture improvement must not remove important business requirements.

The various quality goals therefore have to be considered together.

Which Feedback Loops Does an Application Need?
#

The three examples are not a complete list, and certainly not a binding model for every piece of software.

Which attributes should be continuously optimized depends on the requirements of the respective system.

For a distributed database, simulating network failures and concurrent operations can be decisive.

For a typical business application, functional correctness, data integrity and maintainability may matter more than the last milliseconds of response time.

For a real-time system, on the other hand, latency bounds and predictability come first.

Further feedback loops are conceivable as well:

Quality areaPossible measurePossible optimization
SecurityConfirmed vulnerabilities, policy violationsFix vulnerabilities, reduce attack surface
ReliabilityError rates, downtimeImprove error handling and recovery
Resource consumptionCPU time, memory, energy demandUse resources more efficiently
TestabilityMutation score, test effortMake tests more effective and simpler
MaintainabilityChange effort, coupling, complexitySimplify architecture and code
AccessibilityAutomatable accessibility checksImprove accessibility of the user interface

Here too: not every attribute listed can be assessed fully automatically. Often, measurements only provide indications that have to be interpreted.

It would even be conceivable to adjust the selection and weighting of the feedback loops over the course of a project.

A young product may initially need different optimization goals than a system that has been in operation for ten years.

Can Such Feedback Loops Really Work Autonomously?
#

Here we have to distinguish between two things:

  1. Optimization within given goals
  2. Setting and evaluating these goals

Agentic AI can take over the first task increasingly autonomously.

The second is considerably harder.

An agent can optimize a response time. But should it double memory consumption to do so?

It can simplify a complex architecture. But may it remove extension points that will only be needed next year?

It can run every test successfully. But how does it know that the tests cover all the important requirements?

The goals, limits and acceptable risks therefore have to be set explicitly.

That does not mean every single change has to be reviewed by a human.

Rather, we can also automate the approval of optimizations based on risk.

Feedback Loops and Risk-Based Approval
#

My previous approach to risk-based AI software development, the Gray Software Factory, focuses on the question under which conditions an agent may adopt changes on its own.

A natural complement emerges here.

The feedback loops produce improvements. The risk-based development process decides which of these changes can be accepted automatically.

Feedback loops and risk-based approvalHuman goal setting with requirements, quality goals and limits steers the autonomous feedback loops, which measure, optimize and verify. Every change goes into risk-based approval. With low risk and passed checks it is adopted automatically and flows into the further development of the codebase. If a human assessment is required, a human decides on approval or rejection. If limits are violated, the change is rejected or reworked. Rejected changes and the further developed codebase flow back into the feedback loops.Human Goal SettingRequirements, quality goals and limitsAutonomous Feedback LoopsMeasure · Optimize · VerifyRisk-BasedApprovalAdoptautomaticallyHumandecisionReject orrework changeFurther developmentof the codebaselow risk,checks passedassessment requiredlimits violatedapprovedrejected
Feedback loops produce improvements; risk-based approval decides which of them are adopted automatically

A small refactoring that is well covered by tests could thus be adopted automatically.

A fundamental change to the module architecture, on the other hand, could require a human decision.

The goal is explicitly not to perform as many human reviews as possible. It is about applying human attention where it actually adds value.

Two different mechanisms thus complement each other:

Risk-based quality control protects against changes whose risks are not sufficiently under control.

Continuous quality improvement tries to systematically improve the codebase across many changes.

How Do We Measure Whether the Software Really Gets Better in the Long Run?
#

This may be the biggest challenge.

For a single change, we can determine fairly easily whether tests pass or a benchmark measurement has improved.

But how do we recognize whether the entire codebase has actually become better after a year of autonomous development?

Classic internal metrics such as complexity, coupling, code coverage or mutation score can provide hints. However, they are not direct measures of the economic or practical value of an architecture.

It would be more interesting to also measure the externally observable consequences:

  • How often do changes cause new bugs?
  • How long does it take to fully implement a business change?
  • How many correction attempts are required?
  • How high is the compute and token effort per successfully completed change?
  • How often do already completed changes have to be reworked later?

The change effort in particular could become systematically observable for the first time through agentic AI.

AI agents leave extensive machine-readable traces of their work process. We can record how many files they read, which tools they call, how many attempts they need and how much time and compute they consume.

This creates new opportunities to study the long-term maintainability of software empirically. Architecture quality would no longer be judged solely by internal code properties, but by its actual effects on future development work.

Such measurements must remain comparable, however. A project that implements increasingly demanding requirements may need more effort even though its architecture has improved.

Conclusion: Sustainable AI Software Development Needs More Than Fast Code Generation
#

Agentic AI not only changes the speed of software development but also opens up new possibilities for continuous quality care.

The three feedback loops are examples of a more general principle:

Software quality should not only be checked when individual changes are accepted, but continuously improved throughout the entire lifecycle.

AI can detect, examine, implement and evaluate many opportunities for improvement. Humans, however, still have to make sure that the right goals are pursued and that essential risks are adequately taken into account.

The combination of autonomous improvement processes and risk-based approval could thus become an important foundation of sustainable AI software development.

Perhaps we should measure the success of agentic AI less by how much code it produces today, and more by how simply, reliably and efficiently that code can be developed further tomorrow.

Sources and Further Reading
#

This article was prompted by a post on X by Nikita M. (@meln1k), which juxtaposes Deterministic Simulation Testing, OpenTelemetry metrics and so-called deslop skills as three ways of continuous AI-assisted code improvement and proposes token consumption in day-to-day changes as a measure of architecture quality. The classification and extension presented here is an independent take on that idea.

This article was translated from German with AI assistance.