Skip to content

Repository files navigation

Multi-Lens Agentic Code Review — Demo

This repo demonstrates a workflow for having a coding agent (e.g. Claude Code) build a Python function and review its own work through multiple independent "lenses" — separate reviewer personas that each focus on a different failure mode — before proposing a fix.

The point isn't the functions themselves. It's the process:

prompt → spec (human approval) → implementation + tests
       → parallel lens reviews → synthesis → scoped fix pass

A single pass of this loop is already checked into the repo as a worked example (see Sample run below), so you can see the shape of the output before running it yourself.

Why lenses, not one review

A single reviewer prompt tends to average across concerns — a bit of correctness, a bit of style, whatever it happens to notice first. Splitting review into named lenses (e.g. "an adversarial correctness engineer" vs. "a staff engineer optimizing for long-term ownership") gets each reviewer to dig deeper along its one axis instead of skimming several. The synthesis step then does the job a human tech lead would do anyway: merge, deduplicate, resolve disagreements, and decide what's actually worth fixing now.

How the workflow works

Defined in AGENTS.md (CLAUDE.md is a symlink to the same file, so it's picked up by either convention):

  1. Spec first. Given a prompt describing a function, the agent drafts specs/function_spec_<stub>.md (signature, types, requirements, edge cases, out of scope) and presents it for approval before writing code.
  2. Implement. Once approved, the agent generates the function in src/ plus unit tests, and doesn't move on until all tests pass.
  3. Review, in parallel. The agent spawns one subagent per row in the Agent Roles table below, each reading its own prompt file and writing its findings to reviews/<lens>_review_<stub>.md.
  4. Synthesize. Findings from all lenses are merged, deduplicated, conflicts resolved, and prioritized into reviews/synthesis_<stub>.md.
  5. Human picks scope, agent fixes. You choose how much of the synthesis to act on; the agent applies it, updates the spec/tests if needed, and re-verifies everything still passes.

Reviewer lenses currently defined

Lens Prompt Focus
Correctness prompts/correctness_reviewer.md Adversarial: concurrency, edge cases, contract violations, memory
Maintainability prompts/maintainability_reviewer.md Staff-engineer lens: complexity, testability, extensibility, readability

Adding a new lens (security, performance, API-design, whatever you want the agent to dig into) is just: write a new prompts/<name>_reviewer.md in the same format, and add a row to the Agent Roles table in AGENTS.md.

Repo layout

Path Contents
AGENTS.md / CLAUDE.md Workflow definition, project parameters, spec template
prompts/ Reviewer lens definitions
specs/ Generated function specs
reviews/ Generated per-lens reviews + synthesis
src/ Generated implementation code
tests/ Generated unit tests
sample_session_summary.md Narrative write-up of the sample run below

Sample run

One full pass is already in the repo: a thread-safe, priority-lane rate limiter, built from the single prompt:

generate an efficient python function that enforces rate limits with thread safety and priority lanes

See sample_session_summary.md for the narrative (spec, implementation, both reviews, synthesis, fix pass), or read the raw artifacts directly:

Notably, the correctness lens caught two real, empirically-verified bugs a maintainability-only review would likely have missed (a NaN-cost bypass that silently disabled rate limiting, and a non-monotonic-clock bug that let tokens over-credit) — a concrete illustration of why a dedicated adversarial lens earns its keep.

Try it yourself

Prerequisites: uv installed, and this repo open in a coding agent that reads AGENTS.md/CLAUDE.md (e.g. run claude from the repo root).

Give the agent one prompt describing a function to build — it drives the rest of the loop (spec → approval → implementation → parallel review → synthesis → fix) on its own from there. To try something other than the rate limiter already in the repo, here are a few prompts that tend to surface different kinds of findings:

  1. Thread-safe LRU cache with per-entry TTL

    Generate a thread-safe LRU cache with a fixed max size and a per-entry TTL, evicting on whichever comes first (capacity overflow or TTL expiry), with O(1) get/put.

    Stresses the maintainability lens more than the correctness lens — eviction-policy interactions and state complexity tend to dominate over raw concurrency bugs.

  2. Bounded blocking object pool

    Generate a thread-safe bounded pool of reusable objects (e.g. connections) that blocks with a timeout when exhausted, and is safe to use as a context manager so a checked-out object is always returned even if the caller raises.

    Stresses correctness around blocking/timeout semantics and resource-leak edge cases (exceptions mid-checkout, pool shutdown while threads are waiting).

  3. Circuit breaker

    Generate a thread-safe circuit breaker (closed/open/half-open states) wrapping calls to an unreliable dependency, with a configurable failure threshold, cooldown period, and limited trial calls while half-open.

    Stresses state-machine correctness (valid/invalid transitions, races on the transition boundary) and gives the maintainability lens a meaty "is this cyclomatic complexity justified" question.

Run any of these (or your own idea) and compare the resulting reviews/*_review_*.md and reviews/synthesis_*.md files against the sample run — same process, different bugs surface depending on what the function actually has to get right.

Local development

uv sync                    # install dependencies
uv run pytest tests/ -v    # run the unit test suite

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages