Open source · Apache 2.0

AI code review that reads your repository, not just the diff.

CodeReviewAgent puts a specialist agent on every changed file in a GitLab merge request, gives it a real checkout to search, and posts only the findings worth someone's time.

payments/refund.go
41 amount := order.Total - order.Refunded
42+ if err := tx.Save(&refund); err != nil {
43+ log.Printf("refund failed: %v", err)
44+ }
45 return tx.Commit()
review-bot · line 43
🔴 High severity issue

The error from tx.Save is logged and then swallowed, so tx.Commit() commits a refund that was never written. The caller reports success while the customer isn't refunded.

Suggested changeApply suggestion
    return fmt.Errorf("save refund: %w", err)
1️⃣2️⃣3️⃣4️⃣5️⃣ 2

Built against the reasons people mute review bots

A bot that sees only the diff has to guess, and its guesses produce the same false positives every time: "undefined symbol", "unused variable", "method not implemented". CodeReviewAgent is designed so it doesn't need to guess.

It reads the code

Each reviewer works over a checkout of the source branch, pinned to the exact commit, with read, grep and glob. "Is this defined anywhere?" becomes a question it can actually answer.

Fewer, better comments

Findings pass an in-diff gate, a false-positive purge, severity checks and duplicate suppression, then a budget. Silence is a valid answer.

Your conventions

Which files are reviewed, by which reviewer, and under which house rules is a YAML profile, plus instruction files that live in your repository.

Incremental by default

A re-run reviews only the commits since the last review and never re-posts a finding that's already on the merge request.

One-click fixes

When a fix is concrete code, the comment carries an Apply suggestion block. When it isn't, the comment describes the fix instead of posting fake code.

Measured, not assumed

Every comment gets 1–5 reactions. A collector turns ratings and replies into Grafana dashboards, so you can tell whether a model change made reviews better.

How a review runs

Deterministic where it can be, a model only where judgement is needed.

Fetch

Diff from the GitLab API; a shallow checkout of the source branch.

Classify

Your profile's rules route each file to its reviewers. No LLM involved.

Review

One agent per file and reviewer, in parallel, each with its own context.

Filter

Off-diff findings dropped, false positives purged, duplicates removed, budget applied.

Post

Inline comments, a one-time summary, and a review-effort label.

Describe your codebase in YAML

No forking prompts. A profile says which files exist, who reviews them, and the rules your team already argues about in review.

  • First match wins. Specific names before broad extensions.
  • Nine built-in reviewers: Go service quality, business logic against the ticket, SQL, tests, TypeScript, HTML, SCSS, and more.
  • House rules for every reviewer, or just one.
  • Validated at startup. A typo stops the run with a clear error instead of silently skipping files.
version: 1
exclude: ["vendor/*", "*.pb.go"]

file_types:            # first match wins
  - name: sql
    match: ["*.sql", "migrations/*"]
    reviewers: [sql_reviewer]
  - name: service
    match: ["*.go"]
    reviewers: [service_reviewer,
                service_business_reviewer]

instructions:
  sql_reviewer: |
    We do not use foreign keys.
    Primary keys are BIGINT identity.

Know whether the reviews are any good

An AI reviewer you can't measure is one you can't improve. The optional collector records every run and every human reaction, and the bundled Grafana dashboards turn that into answers.

  • One event per review run: files reviewed, findings by severity, comments posted, duration, model, and every error and warning, queryable on its own.
  • Humans grade the bot. Every comment is seeded with 1️⃣–5️⃣ reactions, and a GitLab webhook records each rating and each reply in the thread. No extra tool, no extra login.
  • Per-model quality. Ratings are attributed to the model that actually wrote the comment, even when a run failed over to a fallback, so a model switch is an experiment you can read.
  • Plain PostgreSQL. Point Grafana, DevLake or your own SQL at it.
Rating StatsIllustrative data · last 8 weeks
Average rating
4.2
▲ 0.8 since W27
Rating coverage
72%
of posted findings
Comments posted
318
across 94 MRs

Average rating per week (1–5)

012345
W27 · avg 3.4 / 5
W28 · avg 3.6 / 5
W29 · avg 3.5 / 5
W30 · avg 3.8 / 5
W31 · avg 3.9 / 5
W32 · avg 3.7 / 5
W33 · avg 4.1 / 5
4.2W34 · avg 4.2 / 5
W27W28W29W30W31W32W33W34
Hover a bar for its value. Illustrative numbers, not real data.

Run Stats

Is the reviewer healthy? Outcomes, throughput, durations and failover, for whoever runs it.

  • Success ratio
  • Duration avg & p95
  • Comments by severity
  • Re-review churn
  • Rate-limit failover

Rating Stats

Are the comments any good? Human ratings and replies by model, severity and project, down to the worst-rated comments.

  • Score distribution
  • Rating by model
  • Rating by severity
  • Worst-rated comments
  • Replies

Engagement

Is the team rating? Points, badges and weekly awards, with an optional weekly Mattermost digest. Filterable by person, so it's the board you share.

  • Leaderboard
  • Achievement wall
  • Weekly wins
  • Coverage by developer

Turn the volume up when you want it

Verbosity is a merge-request label, so a human can ask for more and re-run without touching CI configuration.

LabelPostsBudget
noneHigh severity, ranked10
review::-vHigh severity, everything that qualifies30
review::-vvHigh and medium, ranked30
review::-vvvHigh and medium, everything that qualifies30

Get started in five minutes

You need a GitLab token with api scope and a key for any OpenAI-compatible LLM endpoint.

# .gitlab-ci.yml in the project you want reviewed
ai-review:
  image: ghcr.io/systemgroup/codereviewagent:latest
  variables:
    GIT_STRATEGY: none        # the reviewer makes its own checkout
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - cd /app && python main.py --gitlab-mr "$CI_MERGE_REQUEST_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_IID"

# Settings → CI/CD → Variables: DEFAULT_LLM_API_KEY, DEFAULT_LLM_MODEL, GITLAB_URL, GITLAB_TOKEN

Review the reviewer

Apache 2.0 licensed. Issues, profiles for new stacks, and pull requests are welcome.