Multi-model review
Multi-model review sends the same diff or draft plan to Synthex's own Claude reviewers and to reviewers from other model families — OpenAI through the Codex CLI, Google through the Gemini CLI, a local model through Ollama, and more. Every reviewer works independently and in parallel; Synthex merges their findings into one ranked list and shows you which model raised each one. It is off by default.
Why use it
Different model families make different mistakes. A finding that Claude misses, GPT or Gemini may catch, and the reverse. When two families raise the same issue, you can trust it more. When only one family raises it, that disagreement is worth a look too.
The trade-off is cost and time: each external reviewer is an extra model call, plus one call to merge the results. That's why review-code/synthex:review-code only adds external reviewers to diffs that are big or risky enough to justify them (see the complexity gate).
When it runs
Two commands support multi-model review.
Code review
review-code/synthex:review-code picks a path once per run, in this order:
- Flags win.
--no-multi-modelalways runs native-only review.--multi-modelalways runs multi-model review and skips the complexity gate. The two flags can't be combined. - Both switches must be on. Without a flag,
multi_model_review.enabledandmulti_model_review.per_command.review_code.enabledmust both betrue. Both default tofalse. - The complexity gate decides. Small, low-risk diffs stay native-only. Everything else gets external reviewers.
The decision is cached for the whole review loop, so a re-review after fixes never flips between paths.
Every review report starts with a one-line header that says which path ran and why:
Review path: multi-model (auth path escalated; reviewers: 2 native + 3 external)
Review path: native-only (below-threshold diff; reviewers: 2 native)
Review path: multi-model (above-threshold diff; reviewers: 2 native, 0 external succeeded)The complexity gate
The gate reads multi_model_review.per_command.review_code.complexity_gate:
- If any changed file matches a glob in
always_escalate_paths, the review goes multi-model, whatever its size. The defaults are**/auth/**,**/payments/**,**/billing/**,**/migrations/**,**/security/**,**/secrets/**, and**/crypto/**. - Otherwise, it goes multi-model if the diff changes at least
threshold_lines_changedlines (default50) or touches at leastthreshold_files_touchedfiles (default3). - Anything smaller stays native-only.
Plan review
write-implementation-plan/synthex:write-implementation-plan has no complexity gate. When
multi_model_review.enabled and multi_model_review.per_command.write_implementation_plan.enabled
are both true, or you pass --multi-model, the Architect, Designer, and Tech Lead review the
draft alongside the external reviewers, and the Product Manager gets one merged findings list.
--no-multi-model forces native-only plan review.
How a multi-model review runs
The Multi-Model Review Orchestrator runs the review. It plugs into the same reviewer pipeline as a normal review:
- Preflight. Checks, in parallel, that each configured CLI is installed and logged in. It
then prints a summary such as
4 reviewers configured, 4 available, 3 families, aggregator: codex-review-prompter. - Context bundle. Builds one bundle: the artifact under review, your convention files, touched files, and matching specs. Every reviewer gets the identical bundle, so no reviewer sees a different version of the code. The bundle is capped at 200 KB, and files over 64 KB are summarized instead of sent in full.
- Fan-out. Native reviewers (Code Reviewer, Security Reviewer, …) and every external adapter run in one parallel batch. No reviewer waits on another.
- Consolidation. Duplicate findings are merged, conflicting severities are reconciled, and
contradictions are checked. Each finding keeps a
raised_bylist of the reviewers who flagged it. A finding raised by only one reviewer may be marked down a severity level, except security findings and findings the reviewer marked high-confidence. Findings are never dropped. - Aggregator. With
aggregator.command: auto, the strongest configured model merges the findings, picked from a fixed ranking (Claude Opus, then GPT-5, Claude Sonnet, Gemini 2.5 Pro, DeepSeek V3, Qwen 32B). If none of those is configured, your host Claude session does it. - Audit record. Each run writes a record to
docs/reviews/, and each adapter's raw output goes todocs/reviews/raw/.
The result looks like any other Synthex review report, with one row per native and external reviewer.
Adapters
Each external reviewer is a small adapter agent that wraps one CLI or API. Add an adapter by
listing its name under multi_model_review.reviewers.
| Adapter | Model family | Tier | Calls | Login check |
|---|---|---|---|---|
codex-review-prompter | openai | agentic | Codex CLI (codex exec) | codex login status |
gemini-review-prompter | google | agentic | Gemini CLI (gemini) | GEMINI_API_KEY or GOOGLE_API_KEY set; otherwise gcloud auth list |
claude-review-prompter | anthropic | agentic | A second Claude Code session (claude) | claude auth status |
ollama-review-prompter | local-<model> | text-only | Local Ollama HTTP API (localhost:11434) | None (the server must be running) |
llm-review-prompter | Taken from the model ID (gpt- → openai, …) | text-only | Simon Willison's llm CLI | None (keys are set per provider with llm keys set) |
bedrock-review-prompter | Taken from the Bedrock model ID | text-only | AWS CLI (aws bedrock-runtime invoke-model) | aws sts get-caller-identity |
Agentic adapters can read files from your repo inside their CLI's read-only sandbox. Text-only adapters see only the context bundle.
claude-review-prompter is for a narrow case: getting a second Claude opinion from a
different model than your host session (say, Opus when you run Sonnet). It doesn't add a new
family, so for real cross-family coverage pick Codex, Gemini, or a local model.
External CLIs run read-only by default; they can't edit files or run commands. You can change
that per CLI with multi_model_review.external_permission_mode, and the riskier
sandbox-yolo mode runs the CLI inside an OS sandbox and asks you to confirm first. The
adapter source is in
plugins/synthex/agents/.
What leaves your machine
Multi-model review sends your code, diffs, and (for write-implementation-plan) draft plan markdown to the configured external CLIs. Each CLI relays this content to its underlying provider (OpenAI, Google, etc.) per the provider's terms of service.
configure-multi-model/synthex:configure-multi-model shows this warning before it turns the feature on. To
keep review content on your machine, configure only local adapters (ollama-review-prompter, or
Bedrock with a model you host).
Synthex never stores API keys. Each CLI logs in its own way (codex login, gcloud auth login,
ollama serve, and so on).
Turning it on
-
Run configure-multi-model/synthex:configure-multi-model. It finds the CLIs you have installed and logged in, shows the data warning, and writes
enabled: trueplus those adapters to.synthex/config.yaml. init/synthex:init offers the same step on a new project. -
Turn it on for each command you want. The wizard sets only the master switch, and the per-command switches default to
false:# .synthex/config.yaml multi_model_review: enabled: true reviewers: - codex-review-prompter - gemini-review-prompter per_command: review_code: enabled: true complexity_gate: threshold_lines_changed: 50 threshold_files_touched: 3 write_implementation_plan: enabled: true -
Or skip config and run it once:
/synthex:review-code --multi-model.
Model choices belong in your user config, because which models are installed depends on
your machine, not on the repo. Synthex reads multi_model_review.per_reviewer from your user
config first:
# ~/.config/synthex/config.yaml
multi_model_review:
per_reviewer:
codex-review-prompter:
model: gpt-5
ollama-review-prompter:
model: qwen2.5-coder:32b
family: local-qwenTurning it off always works. An enabled: false in any config layer (user, shared project, or
project-local) keeps multi-model review off, even if another layer says true, so a repo can't
send your code to an external model after you opted out. See
Configuration.
Other keys
| Key | Default | What it does |
|---|---|---|
strict_mode | false | When true, any preflight failure aborts the review instead of continuing without that reviewer. |
include_native_reviewers | true | Run Synthex's Claude reviewers alongside the external ones. Set false for an external-only second opinion. |
min_family_diversity | 2 | Warn (never block) when fewer model families are available. Native reviewers count as anthropic. |
min_proposers_to_proceed | 2 | Abort when fewer reviewers (native plus available external) are available. |
per_reviewer_timeout_seconds | 180 | How long to wait on any single reviewer. |
aggregator.command | auto | Which model merges the findings. auto uses the ranking above. |
audit.enabled / audit.output_path | true / docs/reviews/ | Write a per-run audit record. |
external_permission_mode.<cli> | read-only | Per-CLI permission mode: read-only, parent-mediated, or sandbox-yolo. |
The full block, with comments, is in
defaults.yaml.
Billing
Synthex uses each CLI's own login, so you're billed however that CLI is set up. The Codex
adapter goes one step further to avoid surprise per-token charges: it removes CODEX_API_KEY
and OPENAI_API_KEY from the environment before calling codex exec, so Codex uses your
codex login session (for example, a ChatGPT plan) even when an API key is exported in your
shell. API-key billing is opt-in through the adapter's allow_api_key_billing setting. If you
aren't logged in, the Codex reviewer fails with a "Run codex login" hint instead of quietly
falling back to your API key.
When something fails
Multi-model review degrades one reviewer at a time. A failure doesn't take down the review.
- Missing or logged-out CLI. Preflight marks it
cli_missingorcli_auth_failedwith a fix (an install command, orcodex login). The review continues without it, unlessstrict_modeis on or you drop belowmin_proposers_to_proceed. - Slow reviewer. After
per_reviewer_timeout_seconds(default 180), that reviewer reportstimeout. The others aren't held up. - Unreadable output. The adapter retries once and asks the model for plain JSON. A second
failure reports
parse_failed. Empty output fails closed too: ifcodex execreturns no answer, the reviewer reportsparse_failed, not a clean review with zero findings. - Every external reviewer fails. Native reviewers ran in the same batch, so their findings
are already in hand. The review finishes with those, shows a warning that only the Anthropic
view is included, and lists each failed reviewer with its error. The header reads
0 external succeeded.
Multi-model review and standing pools
When standing_pools.enabled is true and a matching standing review
pool is running, review-code/synthex:review-code sends the
review to that pool first. The multi-model path applies only when the review isn't routed to a
pool.
Next
- Reviewer pipeline — fan-out, consolidation, and the review loop
- configure-multi-model/synthex:configure-multi-model — the setup wizard
- review-code/synthex:review-code — the command reference
- Configuration — config layers and precedence