Robin docs: AI code review in GitHub Actions
Robin adds AI code review to a repository as a reusable GitHub Actions workflow. You add one workflow file and three secrets; Robin reviews every pull request with the LLM you choose, using your own API key. Setup takes a few minutes — here's the whole thing.
Quickstart
Run from the root of the Git repository you want Robin to review. The workflow and secrets are per repository; the companion agent skill is global per machine.
Do not run the installer from your home directory.
Install with npx — it adds the workflow file to the current repository:
npx robin-review No npm? Install with curl instead (read the script first at /script):
curl -fsSL https://robinreview.dev/install.sh | bash Run an installer separately in every repository that should use Robin. Re-running it keeps one canonical .github/workflows/robin.yml, archives recognized historical variants where GitHub cannot trigger them, and updates the global companion skill. Custom identity workflows stay intact; update their refs manually. Inspect and remove archived copies after confirming a migration.
Or add it manually — create .github/workflows/robin.yml:
name: Robin
on:
pull_request:
types: [opened, reopened, ready_for_review]
issue_comment:
types: [created]
permissions:
actions: read
contents: read
pull-requests: write
jobs:
review:
uses: antongulin/robin/.github/workflows/review.yml@main
secrets:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_MODEL: ${{ secrets.LLM_MODEL }} The three secrets
In your repo, go to Settings → Secrets and variables → Actions and add:
LLM_API_KEY— your provider API key.LLM_BASE_URL— the provider's OpenAI-compatible base URL.LLM_MODEL— the model to review with.
That's the only configuration Robin needs to start reviewing.
Custom review identity (optional)
Robin posts as github-actions[bot] by default. Your existing workflow and three
LLM secrets keep working. To post as a different account through the reusable workflow,
store its token as a repository secret and add this mapping to your review job:
# Add to the secrets mapping of your existing review job:
ROBIN_TOKEN: ${{ secrets.ROBIN_TOKEN }}
Omitting the mapping or leaving the secret empty keeps the default identity. A supplied
invalid token produces an API error. Use a workflow revision that supports ROBIN_TOKEN;
older pinned releases reject the extra secret. A caller using secrets: inherit
also passes ROBIN_TOKEN when that repository secret exists.
For your own GitHub App, create an installation token and run the direct Robin action in
the same job. For new setups, use the App’s Client ID as the token action’s
app-id input at @v2; existing numeric App IDs still work.
Do not pass that token between jobs: GitHub hides secret outputs and the
token action revokes its token when the creation job ends. Grant the App
Contents: read, Pull requests: write, and Actions: read.
A personal access token posts as its owner. It cannot request changes on that owner's PR,
and an older blocking review may need manual dismissal after a clean rerun. Prefer a
GitHub App for automation, or use request-changes: false for PAT advisor mode.
The installers preserve custom identity workflows, including their token steps, secret
aliases, and dependencies. They skip workflow regeneration and ROBIN_REF
overrides for these setups. Your review triggers, LLM settings, and command permissions
stay under your control. Follow the
complete setup examples.
Choosing an LLM provider
Robin works with any OpenAI-compatible endpoint. Common choices for LLM_BASE_URL:
| Provider | LLM_BASE_URL | Notes |
|---|---|---|
| OpenRouter (free models) | https://openrouter.ai/api/v1 | Free-tier models available — run Robin at $0. |
| OpenAI | https://api.openai.com/v1 | e.g. a small, fast model for cheap reviews. |
| Groq | https://api.groq.com/openai/v1 | Fast inference on open models. |
| Ollama (self-hosted) | http://localhost:11434/v1 | Fully local; requires a self-hosted runner. |
Set LLM_MODEL to any model that provider offers. If you're cost-sensitive,
start with a free OpenRouter model and upgrade only if you want stronger reviews.
Models that require a fixed temperature
Robin samples at temperature 0.1 by default so reviews stay near-deterministic.
A few providers accept only one fixed value — Kimi models require 1 and reject
the request otherwise. Set the optional llm-temperature input in the workflow's
with: block:
jobs:
review:
uses: antongulin/robin/.github/workflows/review.yml@main
with:
llm-temperature: "1" # Kimi accepts only 1
secrets:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
The accepted range is 0–2; out-of-range or non-numeric values log a warning and fall back to
0.1. Raising the temperature makes findings less repeatable, so change it only
when your provider requires it.
Commands
By default Robin reviews once when a pull request opens. You can also comment:
/robin— run another review pass (after pushing fixes)./summary— a short overview of the PR./help— list available commands.
Fork pull requests
GitHub does not expose repository secrets to workflows triggered by fork PRs, so Robin can't
auto-review an external contributor's PR. After you've looked it over, comment
/robin on the PR to run the review with your secrets. This is standard GitHub
Actions security behavior, not a Robin limitation.
Pinning a version
The workflow references @main, which always runs the latest release. Pin a
release tag instead — @v2 for the latest 2.x, or an exact version like
@v2.7.0 — if you want fully reproducible runs and to control when you pick up
changes. See the repository for the list of releases.
Review on every push (opt-in)
Out of the box Robin reviews a pull request when it opens (and when you comment
/robin or /review). It does not re-review on every push. To review each
push to an existing PR, add the synchronize event to the trigger and set
review-on-synchronize: true:
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
issue_comment:
types: [created]
permissions:
actions: read
contents: read
pull-requests: write
jobs:
review:
uses: antongulin/robin/.github/workflows/review.yml@main
with:
review-on-synchronize: true
secrets:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
Both are required: the event makes GitHub deliver the push, and the boolean makes Robin act on
it. Without the boolean, a synchronize run is skipped and the push is reviewed only
when you comment /robin.
Agent mode (opt-in)
Robin can review beyond the diff: instead of a single request, it reads full files, greps for
callers, and lists directories at the PR head commit before it decides what is a bug. Agent mode
is off unless you enable it. Set it in .github/robin.yml:
# .github/robin.yml
agent-mode: auto
agent-max-turns: 40 agent-max-turns caps the tool-calling turns (default 40, maximum 100), and
agent-max-diff-size caps the upfront diff (default 200000 characters). Leave
agent-mode unset to keep the single-shot review. When the model does not support tool
calling, Robin falls back to the single-shot review automatically.
Agent mode can send additional repository-file context to your chosen LLM endpoint and make more API calls. Leave it off to keep the single-shot diff review. Explicit workflow inputs override repository configuration for agent controls and reasoning effort.
Reasoning effort and token caps
Reasoning is provider-specific. When reasoning-effort is unset everywhere, Robin
sends no reasoning control and the provider/model default applies; set it in
.github/robin.yml (or the workflow with: block) to send a value, or set
off to send nothing explicitly. The value is always opt-in; there is no built-in
high default.
Set an optional max-output-tokens cap in the workflow's with: block.
Robin chooses a token-field name; if the provider rejects it, Robin tries the other spelling
(max_tokens or max_completion_tokens) and keeps the cap. If the endpoint
rejects both spellings, or the value itself is invalid, the provider error surfaces instead of
Robin quietly running without a cap.
Anthropic (Claude)
Set LLM_BASE_URL to https://api.anthropic.com/v1 and use your regular
Anthropic API key. This OpenAI-compatible endpoint ignores response_format and
reasoning controls. Robin omits reasoning controls there; it can still send a best-effort JSON
schema, but relies on the prompt and review parser rather than Anthropic enforcing that schema.
Guaranteed structured output would require the native Claude API, which Robin does not call.
Structured output (JSON mode)
When JSON mode is enabled, Robin requests a strict json_schema response by default,
stepping down to a plain JSON object and then to no response_format if the provider
rejects it. JSON mode is single-shot only, since many providers reject response_format
alongside tool calls. The schema preference is automatic while JSON mode is enabled; you can
disable JSON mode with use-json-response-mode: false. For providers that ignore or
reject format controls, prompt/parser fallback is best-effort and cannot guarantee valid output.
Going further
Advanced configuration — self-hosted runners, strict mode, and custom rules — is documented in the repository:
New to the idea? See what Robin is or read the blog.