Skip to content
back to work
Engineer · Built at work

Multi-Agent Code Review

An automated first-pass reviewer for a legacy enterprise language that had no linter, no formatter, and no static analysis. Four specialists review in parallel, every finding is cited, and every line number is checked against the real file before the report goes out.

Multi-agent AILLM toolingRAGDeveloper toolingBashREST
RoleEngineer · Built at work
Timeline2026

The problem

I work on a legacy enterprise platform whose language has no linter, no formatter, and no static analysis. Every other language on our stack has all three. When a change ships, a human opens the project and reads it, but what they realistically check is traceability: the right ticket number, the right objects, the naming convention. All of that is metadata. Nobody has a spare hour to read 200 lines looking for a SQL injection.

So the semantic half of code review did not happen at all. Not because reviewers miss things, but because no tool did it and there was no time to do it by hand. I built the tool.

Why a generic AI assistant does not close the gap

It cannot cite its sources. Paste this code into any chat assistant and it gives plausible advice, some of it right, some of it generic advice from another language wearing this one's syntax. A reviewer that cannot show its source is one nobody trusts twice.

The context is not in the file, and this is the whole project. A program here carries no record of when it runs. That lives in the platform's metadata, in a different place entirely. And when the code runs decides whether it is correct:

audit = createRecord("FILE_AUDIT")
audit.processName = source.processName
audit.timestamp  = now()
audit.insert()

In a "before save" hook, this is correct, expected code. In a "page load" hook, it is a serious defect: the write lands outside the transaction, so the row persists even if the user cancels, and it re-runs on every redisplay of the screen. Nothing about the four lines changes, only when they run. No tool that reads the file alone can catch this. It needs a second input the file does not contain.

How it works

merge request
Runner

Pulls the code and its execution context straight from the change ticket over REST, so the one input the whole review depends on can no longer be typed in wrong.

SQL safety
injection, transaction control
Execution context
right code, wrong lifecycle hook
Performance
loop invariants, allocations
Standards
typing, scope, naming

Four specialists, each reading only its own cited rules.

Orchestrator

Dedupes findings, caps severity centrally so no specialist can inflate its own, and verifies every cited line against the real file before anything ships.

Cited report + verdict
One run: fetch, fan out to four read-only specialists, merge, verify, report.

The runner constrains every specialist to read-only tools, so the agent cannot change our code even if a prompt tells it to, and it fans out the same way on every run rather than leaving that to the model. Each specialist reads only its own rules and emits structured findings, never prose. The orchestrator is the only agent that writes the report, which is what keeps its shape stable no matter which specialist found what. And getting the execution context from the change ticket instead of a person is the point of the whole integration: it is the one input the review depends on, and now it is the one input a human cannot get wrong.

Grounded in real documentation

The reference manuals run to several thousand pages, far too many for any prompt, yet the reviewer has to cite them. So the knowledge lives in three tiers:

TierWhatWhere
In the prompt27 rule cards, each with a fix and a page citationloaded every run
On diskthe full manuals, extracted to searchable textqueried by a tool
Referencethe deep API documentationsearched on demand

Every rule was written by finding a real citation for it, and anything I could not source got dropped. Every rule set also ends with a "do not flag" list, which turned out to be the highest-value part of the whole thing: a reviewer that flags correct code gets switched off within a week and never switched back on.

Does it actually work?

I calibrated against a sanitized sample with three planted critical defects, plus two controls:

  • The three criticals and the "block" verdict are stable across every run. They are pattern matches against a cited rule with a centrally enforced severity ceiling, so they do not drift.
  • The clean control returns "approve" and invents nothing, which is the evidence that this is a reviewer and not a machine that always finds problems.
  • The sharpest challenge has a ninety-second answer: re-run the same file with a different execution context, and the context-dependent critical correctly drops off, because in that context the code is legal. Same code, different answer, for the right reason.

What I took away

The hard part was never the plumbing. It was deciding that correctness lived in context the file did not contain, and that the tool should cite its sources and admit what it could not check. It does not replace the human reviewer, and I say so plainly: the traceability checks a person does today need inputs the tool is not given. The next step is wiring the deterministic runner into CI, so the first-pass review happens before a human ever opens the change.