Back to writing

Using AI Agents to Write ADRs While Building Features

ai-agentsadrarchitecture

AI agents helping organize Architecture Decision Records

Lately, I have been using AI agents more often while building backend features. Not only for generating code, but also for reading the existing code, comparing patterns, writing a small plan, and sometimes reminding me that I forgot to update a test. Very helpful, right?

But after using it for a while, I found another problem. The conversation with the agent can contain a lot of useful reasoning, but most of it disappears after the task is done.

The pull request only shows what changed. The commit message is usually too short. The chat history has the explanation, but I don’t want to search old agent conversations just to remember why I chose one pattern over another.

So I started asking the agent to help me write ADRs.

ADR means Architecture Decision Record. The idea is simple: when we make an architecture decision, we write down the context, the decision, the consequences, and the alternatives that we did not choose.

It does not need to be a long document. Actually, I prefer it short. If it becomes too long, it starts to feel like another implementation plan.

The ADR template that I usually use looks like this:

# Title

## Status

Proposed or Accepted.

## Context

What problem are we solving? What constraints do we have?

## Decision

What are we choosing?

## Consequences

What becomes easier? What becomes harder?

## Alternatives Considered

What did we reject, and why?

The boring format is good because I don’t need to think too much about the document structure. I only need to focus on the decision.

For example, when I create a feature that needs an async process, I don’t want the ADR to only say:

Use a queue.

That is too short and not useful for the future. I want it to explain why the queue is needed, why a normal synchronous request is not enough, what retry behavior is expected, and what failure case is acceptable.

Another example is an API response change. If the response shape changes, I want to know who consumes the API, which service owns the data, and why the new contract is better than the old one.

This is where the AI agent is useful. While working on the feature, the agent already has the code context in its head. It can inspect the nearby files, read the existing pattern, and summarize the trade-off faster than me writing everything from zero.

My workflow is usually like this:

  1. Ask the agent to inspect the existing ADRs and nearby code.
  2. Ask it to summarize the current pattern.
  3. Ask it to create a short implementation plan.
  4. If the plan introduces a new architecture decision, write an ADR.
  5. Build the feature based on the ADR.
  6. Update the ADR if the implementation changes the decision.

The important part is writing the ADR while the decision is still fresh. If I wait until the feature is already finished, I will usually forget the alternatives. Or worse, I will write a clean story that sounds good but does not describe the actual messy decision-making process.

Of course, I don’t create an ADR for every change. That would be too noisy. I usually create one when the change introduces something that can affect future work.

For example:

  • A new dependency or provider
  • A new database convention
  • A new service boundary
  • A new event or async callback flow
  • A new authentication or authorization behavior
  • A new caching strategy
  • A public API behavior change
  • A deployment or infrastructure pattern

If the change is only renaming a function or moving a small helper, an ADR is too much. A normal pull request description is enough.

The best part of this habit is the handoff.

When I come back to the feature a few days later, I can read the ADR and reload the context quickly. When another agent starts working in the repo, I can tell it to read the ADRs first. When I review the code, I can compare the implementation with the decision instead of only relying on memory.

It also makes discussion easier. Instead of saying “I think we chose this because…” I can point to the ADR and say, “This service owns this computation because we decided to keep the data ownership there.”

There are still some things to watch out for.

First, AI-generated ADRs still need editing. Sometimes the agent writes a generic explanation that sounds correct but does not match the real project. I need to remove that kind of text.

Second, keep it short. The ADR should explain the decision, not every task needed to ship the feature.

Third, make the agent read the ADRs. Documentation that is written but never read is just decoration. If the agent checks the ADRs before coding, then the documentation becomes part of the workflow.

That’s it. Using AI agents to write ADRs helps me keep the reasoning close to the code. The agent can move fast, but the ADR makes sure the speed leaves a trail.

Code tells us what we built.

The ADR tells us why we built it that way.