DEV Community

xiaoru chen
xiaoru chen

Posted on

An Open-Source Code Review Tool, 7 Qwen Tiers, and the Real Cost of a Single PR

An open-source code review tool with 26k+ stars reviewing a Python file

The tool that made me curious

This week, Alibaba open-sourced open-code-review (CLI name ocr). It climbed to #1 on GitHub Trending with +15,028 stars in a week. Apache-2.0, Go binary, and — here is the part that caught my attention — it ships a built-in provider named dashscope whose base URL is DashScope's OpenAI-compatible endpoint, with Qwen models pre-listed.

No custom provider file to write. No YAML to assemble. Pick a provider, pick a model, and it works.

So I set up a single-variable experiment: one buggy file, seven Qwen tiers, and a real cost table. Not a per-million-token sticker price — the actual bill for one review.

What the tool does

ocr reads your code through tool calling (function calling). The model must natively support it; the project FAQ explicitly names qwen3 as working. Models that merely narrate tool calls in text output cannot drive it, regardless of how clever the prompt is.

It has four modes:

ocr review                                        # review staged/unstaged/untracked changes
ocr review --from main --to feature-branch         # review a branch range
ocr review --commit abc123                         # review a single commit
ocr scan --path some/dir                          # full-file scan, no git history needed
Enter fullscreen mode Exit fullscreen mode

The setup

Three things to know before you run it:

  1. DASHSCOPE_API_KEY alone is not enough. The resolver wants the full tuple of (URL, key, model). The env var supplies only the key. You still need ocr config set provider dashscope and ocr config set model <name>.

  2. The provider is built-in. internal/llm/providers.go in the repo defines dashscope with base URL https://dashscope.aliyuncs.com/compatible-mode/v1 and a model list that starts with five Qwen models. No need to register a custom provider.

  3. Region matters. API keys are region-bound. A Beijing key against a Virginia endpoint returns 401. If you migrated to a workspace domain, override the URL with ocr config set providers.dashscope.url https://<WorkspaceId>.cn-beijing.maas.aliyuncs.com/compatible-mode/v1.

The shortest path to a working setup:

npm install -g @alibaba-group/open-code-review
ocr config set provider dashscope
ocr config set model qwen3.8-max
ocr config set providers.dashscope.api_key sk-your-key
ocr llm test
Enter fullscreen mode Exit fullscreen mode

Create an API key in the Bailian console before the fourth command.

The experiment

One 64-line Python order service with four planted defects:

  • A fetchone() result used without a null check (crashes on missing user)
  • An f-string interpolated into SQL (textbook injection)
  • A counter += 1 without lock acquisition (concurrency bug)
  • An open() without with (handle leak)

Plus two decoys: an @lru_cache on a pure function (correct usage) and a redundant except Exception: raise (harmless, and the bare raise correctly preserves the traceback).

Same prompt, byte-identical input, seven Qwen tiers. Token counts from the API's own usage block. Unit prices from bl model list --model <name> --output json, a command that needs no account and no auth, so every price is checkable.

Prices are in CNY.

The table

Model Thinking tokens Found /4 Missed False + Score Wall time In tok Out tok Cost per review
qwen-turbo none 2 2 4 -2.0 7.4s 468 1,005 ¥0.0007
qwen3-coder-plus none 3 1 1 2.0 10.1s 464 712 tiered / see console
qwen-plus none 2 1 1 1.5 39.3s 464 1,766 ¥0.0039
qwen3.7-plus 1,182 4 0 0 4.0 23.4s 502 2,052 not published / see console
qwen3.6-flash 4,258 4 0 1 3.0 42.6s 502 5,075 not published / see console
qwen3.8-flash 9,517 4 0 0 4.0 241.0s 540 12,909 ¥0.0353
qwen3.8-max 9,770 4 0 0 4.0 293.1s 540 11,064 ¥0.4048

One run per configuration. Score is found minus false positives, out of 4. Three cells say "see console": qwen3-coder is officially tiered-priced, and qwen3.7-plus / qwen3.6-flash return no unit price from the lookup command. I do not fill gaps with guesses.

Three things I did not expect

The flagship bought nothing on this file. qwen3.7-plus scored 4.0 in 23.4 seconds. qwen3.8-max also scored 4.0, in 293.1 seconds. The extra 8,588 thinking tokens and 270 seconds bought three genuine findings I had not planted (including that amount <= 0 does not reject float('nan')), but no extra points.

The divider is thinking, not price. Three tiers that did not think all missed at least one bug. Five that thought missed nothing. Past roughly 1,200 thinking tokens the score stops moving.

Line numbers are only trustworthy on thinking tiers. turbo was 0 of 9 correct, plus 0 of 4. qwen3.7-plus and above were accurate to within one line. Treat a non-thinking tier's output as a lead list and find the code yourself.

One observation worth noting: qwen-plus missed the null deref, qwen3-coder-plus missed the race condition. Their blind spots did not overlap. Running both cross-reads the gaps, at the cost of stacked false positives and a human in the loop. Seven configurations measured once each — this is an observation, not a rule.

Unit price versus unit cost

qwen-turbo costs ¥0.3 per million input tokens. qwen3.8-max costs ¥12. That is 40x on the pricing page. Per review, turbo spent ¥0.0007 and max spent ¥0.4048, which is 545x, because the expensive run wrote eleven thousand output tokens and most of them were reasoning.

Budget from the pricing page and your invoice will not agree. Budget from a real review.

Balance scale weighing a price tag against thinking tokens

What I would pick

Scenario Tier Per review Reviews per ¥1
Coarse sieve on every commit, you read the code anyway qwen-turbo ¥0.0007 ≈1,345
Cheap pass with a published price qwen-plus ¥0.0039 ≈256
Default PR gate, line numbers you can jump to qwen3.7-plus ≤¥0.0799 (bound) price unpublished
Hard diff, deep reasoning qwen3.8-flash ¥0.0353 ≈28
The gnarliest file in the repo qwen3.8-max ¥0.4048 ≈2

The ¥0.0799 is a bound, not an estimate: priced at flagship rates, that run's tokens come to ¥0.0799, one fifth of the flagship's ¥0.4048, and its real price cannot be higher. For tiers with no published price, check the console model pages rather than any reposted number.

Recalculate it yourself

from decimal import Decimal, ROUND_HALF_UP

def cost(in_tok, out_tok, price_in, price_out):
    """prices in CNY per million tokens"""
    c = (Decimal(in_tok) * Decimal(price_in) + Decimal(out_tok) * Decimal(price_out)) / Decimal(1000000)
    return c.quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)

print(cost(540, 11064, "12", "36"))  # 0.4048: qwen3.8-max, one review
Enter fullscreen mode Exit fullscreen mode

Use Decimal with ROUND_HALF_UP, because Python's round() does banker's rounding and your invoice will not explain the gap.

Boundaries and honest limits

A community member reported 1,400 PRs taking over ten hours. A few-line PR still takes minutes. This is not a pre-commit tool. It does not replace SAST: a rules engine reports deterministic pattern hits, while ocr reports what a model understood about your code. And if your team already pays for a hosted review product that works, this is not a pitch to switch.

Sample size is one file, four bugs, one run per configuration. I ran two of the models twice and their scores moved. Read every number above as "this run", not as a benchmark.

The new-user free quota is per model and independent (typically 1M tokens each), valid for 90 days, Beijing region only, with no reissue after expiry and no automatic failover to another model when it runs out. Create the key here. Install the Bailian CLI to look up prices on your own machine with no account required.

Top comments (0)