Letting an LLM Review Our Pull Requests (So You Don't Have To)

created: Freitag, Aug. 8, 2025

Wir lieben Automatisierung. Wir nutzen sie, um unsere Infrastruktur zu betreiben, Workloads auf null zu skalieren und—zunehmend—um die Menge an menschlicher Aufmerksamkeit zu reduzieren, die nötig ist, um qualitativ hochwertigen Code auszuliefern. Ein Bereich, der sich noch hartnäckig manuell anfühlte, waren die Pull-Request-Reviews. Zwischen Cursor als IDE, ChatGPT/Codex für Prototyping und gemini-cli für schnelle Checks waren unsere lokalen Workflows schnell—aber die CI wartete immer noch auf einen Menschen.

Also stellten wir eine einfache Frage: Könnten wir ein großes Sprachmodell den Diff lesen lassen, Probleme erkennen und direkt im PR kommentieren lassen?

Es stellte sich heraus: ja. Es brauchte nur ein paar Zeilen GitHub Actions-Kleber, um hilfreiche, strukturierte Reviews für jeden Pull Request zu bekommen.


The goal

Wir wollten keine Menschen ersetzen. Wir wollten einen ersten Durchgang, der:

Wenn eine Änderung in Ordnung ist, soll der Bot das einfach sagen und sich zurückziehen.


The tools in our stack


The workflow, end to end

Here’s the full Action we’re running. Drop it into .github/workflows/gemini-pr.yml:

name: gemini-pr
on:
  workflow_dispatch:
  pull_request:
jobs:
  build:
    permissions: write-all
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        submodules: 'true'
        fetch-depth: 0
    - uses: actions-rust-lang/setup-rust-toolchain@v1
      with:
        components: rustfmt, clippy
        cache: false
    - uses: actions/setup-node@v4
      with:
        node-version: 20
    - name: install gemini
      run: |
        npm install -g @google/gemini-cli
    - name: gemini
      run: |
        echo "merging into ${{ github.base_ref }}"
        git diff origin/${{ github.base_ref }} > pr.diff
        echo $PROMPT | gemini > review.md
        cat review.md >> $GITHUB_STEP_SUMMARY
        gh pr comment ${{ github.event.pull_request.number }} --body-file review.md
      env:
        GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        PROMPT: >
          please review the changes of @pr.diff (this pull request) and suggest improvements or provide insights into potential issues. 
          do not document or comment on existing changes, if everything looks good, just say so.
          can you categorise the changes and improvesments into low, medium and high priority?
          Whenever you find an issue, please always provide an file and line number as reference information. if multiple files are affected, please provide a list of files and line numbers.
          provide the output in markdown format and do not include any other text.

Was jeder Teil macht


The prompt that makes it useful

LLM-Ausgaben sind nur so gut wie die Anweisungen. Unsere halten es praktisch:

Wir haben etwas iteriert, um hierher zu kommen. Die wirkungsvollsten Anpassungen waren: auf Datei-/Zeilenreferenzen zu bestehen und zusätzliche Prosa zu verbieten.


What the review looks like

Github Action Comment showing various errors

In einem typischen PR sehen wir Abschnitte wie:

Wenn alles in Ordnung ist, bekommen wir einen Einzeiler: “Looks good.” Perfekt—genau das wollen wir.


Gotchas and practical notes


Why this matters (beyond convenience)

Automatisierte Reviews machen Menschen wählerischer mit ihrer Aufmerksamkeit. Wir verbringen weniger Zeit mit “benenne diese Variable um” und mehr Zeit mit Architektur, Datenflüssen und Sicherheitsgrenzen. Das bedeutet:

Es ist außerdem überraschend gut in Sachen Konsistenz. Ein LLM vergisst nicht das vereinbarte Fehlerbehandlungs-Muster zwischen Services oder unsere bevorzugte Log-Struktur; es wendet diese Prüfungen bei jedem PR einheitlich an.


Variations you might try

Dieses Muster funktioniert mit nahezu jedem Modell oder CLI. Ein paar einfache Erweiterungen:


Results so far

Nichts davon ersetzt die menschliche Freigabe eines Merges. Es ist ein leichtgewichtiger Filter, der sich am ersten Tag auszahlt.