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.
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.
@google/gemini-cli in der CI, um den automatisierten Review-Schritt auszuführen.gh), um im PR zu kommentieren.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.
Checkout mit fetch-depth: 0, damit wir zuverlässig gegen den Basis-Branch des PR diffen können.
Rust-Toolchain installiert rustfmt und clippy, weil unsere Repos oft Rust-Code enthalten; diese laufen anderswo in unserer Pipeline, aber die Toolchain hier vorzubereiten vermeidet Überraschungen.
Node wird für das gemini-cli benötigt.
Wir installieren @google/gemini-cli global im Runner.
Wir erstellen eine Diff-Datei:
git diff origin/${{ github.base_ref }} > pr.diff
So sieht das Modell nur die zur Überprüfung stehenden Änderungen.
Wir leiten den Prompt in gemini (die CLI liest @pr.diff inline als Dateireferenz) und speichern die Markdown-Ausgabe des Modells in review.md.
Wir hängen die Review an die Job-Zusammenfassung ($GITHUB_STEP_SUMMARY), damit sie in der Actions-UI sichtbar ist.
Wir kommentieren im PR mit gh pr comment … --body-file review.md.
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.
In einem typischen PR sehen wir Abschnitte wie:
Wenn alles in Ordnung ist, bekommen wir einen Einzeiler: “Looks good.” Perfekt—genau das wollen wir.
GEMINI_API_KEY und GITHUB_TOKEN in den Repo- oder Org-Secrets. Halte die Berechtigungen eng. Die Action setzt permissions: write-all, weil sie einen Kommentar postet; beschränke das, wenn eure Richtlinie es erfordert.git diff origin/${{ github.base_ref }} den richtigen Kontext. Wenn euer Workflow nur den Merge-Commit holt, stellt sicher, dass der Basis-Branch verfügbar ist, oder passt es an github.event.pull_request.base.sha an.pull_request_target ausführen (mit sorgfältiger Härtung) oder die Review hinter Labels verstecken.pull_request aus (nicht bei jedem Push).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.
Dieses Muster funktioniert mit nahezu jedem Modell oder CLI. Ein paar einfache Erweiterungen:
failed, um Merges zu blockieren, bis das Problem behoben ist.gh CLI unterstützt das) für noch prägnanteres Feedback.ai-review-Label hinzufügt, oder automatisch ein needs-attention-Label setzen, wenn hochprioritäre Befunde auftauchen.Nichts davon ersetzt die menschliche Freigabe eines Merges. Es ist ein leichtgewichtiger Filter, der sich am ersten Tag auszahlt.