| 命令 | 別名 | 作用 |
|---|---|---|
ocr review | ocr r | 執行評審並輸出評論 |
ocr scan | ocr s | 不需 Git diff,掃描完整檔案 |
ocr rules check <file> | — | 顯示某檔路徑適用哪條規則與來源 |
ocr config set/unset/provider/model | — | 寫入 / 刪除設定、互動式 provider / model TUI |
ocr llm test / providers | — | 測試 LLM 連通性 / 列出內建 provider |
ocr session list/show/comments | sessions | 列出 / 查看已保存評審會話 |
ocr viewer | — | 本機 Web UI(localhost:5483)瀏覽歷史評審 |
ocr version | -V | 印出版本、commit、平台、建置日期 |
| 參數 | 簡寫 | 預設 | 說明 |
|---|---|---|---|
--repo <path> | — | 目前目錄 | Git 倉庫根 |
--from <ref> | — | — | diff 起始 ref |
--to <ref> | — | — | diff 結束 ref(merge-base(from,to)..to) |
--commit <sha> | -c | — | 評審單一 commit |
--preview | -p | false | 跑過濾管線但跳過 LLM |
--resume <session-id> | — | — | 從之前評審會話恢復 |
--format <fmt> | -f | text | text 或 json |
--audience <who> | — | human | human(串流進度)或 agent(靜默 stdout) |
--background <text> | -b | — | 注入需求 / 業務上下文(提升品質最有效的參數) |
--concurrency <n> | — | 8 | 並行評審的最大檔數 |
--timeout <minutes> | — | 10 | 每檔截止時間(0 關閉) |
--rule <path> | — | — | 自訂規則檔(覆蓋專案/全域) |
--max-tools <n> | — | 30 | 每檔最大工具呼叫輪數 |
--max-tokens <n> | — | 模板預設 | 每檔 prompt token 上限 |
--provider / --model | — | — | 本次執行的 LLM provider / model 覆蓋 |
模式參數互斥:傳 --from/--to、--commit、或都不傳(工作區)。混用直接報錯。--resume 僅支援區間 / 單 commit 評審,不能與 --preview 並用。
{
"status": "success",
"llm": { "provider": "anthropic", "model": "claude-opus-4-6" },
"summary": { "files_reviewed": 9, "comments": 1, "total_tokens": 21344 },
"comments": [{
"path": "src/foo.go",
"content": "Concurrent map access without a lock — wrap with sync.RWMutex.",
"start_line": 42, "end_line": 47,
"existing_code": "m[k] = v",
"suggestion_code": "mu.Lock(); defer mu.Unlock(); m[k] = v"
}]
}
無檔可審時回 skipped 外殼——讓呼叫方區分「無變更」與「無發現」。
| 碼 | 含義 |
|---|---|
0 | 評審完成(可能零評論,可能有非致命警告) |
1 | 致命錯誤——參數錯誤、無法解析 LLM 端點、所有子 agent 失敗 |
不需 Git diff 的全檔掃描——直接讀工作樹每檔現況交給 LLM 審。適合審計陌生 codebase 或沒有有意義 diff 的目錄。
ocr scan # 掃描整個倉庫
ocr scan --path internal/agent # 掃描單一目錄
ocr scan --path internal/agent,internal/llm/client.go
ocr scan --exclude '**/generated/*,*.pb.go'
ocr scan --preview # 看會掃哪些檔(不花 token)
ocr rules check src/main/java/com/example/Foo.java
# File: src/main/java/com/example/Foo.java
# Source: System built-in
# Pattern: **/*.java
# Rule: …java.md 內容…
ocr config set provider anthropic
ocr config unset custom_providers.my-gateway
ocr config provider # 互動式 TUI
ocr config model # 互動式 model 選擇
ocr session list
ocr session show <session-id>
ocr session comments <session-id>
ocr session comments --severity high --category bug,security <session-id>
ocr viewer # binds localhost:5483
ocr viewer --addr :3000 # bind to all interfaces on port 3000
--audience agent 並不隱含 --format json——前者控 UI、後者控結構,需要兼得時組合使用。--background 是提升評審品質最有效的參數之一——從其他 agent 呼叫時,永遠傳入需求 / PR 描述。MAX_TOKENS 的 80% 會在呼叫 LLM 前被丟棄(記 log 但不失敗)。不要糾結「該用哪個」——模式由你手上的變更決定:
ocr review(工作區模式,最常用)ocr review -c <sha>ocr review --from main --to feature三種模式互斥,混用直接報錯。這不是限制——是確定性保證。
這是最常搞混的:--audience agent 控制的是 UI 輸出(屏蔽進度列),--format json 控制的是 資料結構(text vs JSON)。你需要同時屏蔽 UI 又要 JSON?必須兩個都傳。很多 CI 腳本只傳 --format json 然後抱怨 stdout 有雜訊——就是因為沒傳 --audience agent。
如果你只記一個參數,記 --background。它讓 LLM 知道「這段變更在解決什麼問題」,大幅減少無關評論。從 CI 呼叫時,傳 PR 標題或需求摘要。從 Claude Code 呼叫時,傳專案脈絡。這是 token ROI 最高的投資。
Step 1 — 確認 Git repo 狀態
cd /path/to/repo && git status
Step 2 — 預覽會評審哪些檔(不花 token)
ocr review --preview
Step 3 — 加入背景脈絡跑評審
ocr review --background "重構 user service 的錯誤處理" --format json --audience agent > review.json
Step 4 — 查看評審結果
cat review.json | python3 -m json.tool | head -50
Step 5 — 開啟 Session Viewer 看細節
ocr viewer
預期產出
{
"status": "success",
"summary": { "files_reviewed": 5, "comments": 2 },
"comments": [
{ "path": "src/user.go", "content": "缺少 error wrapping...", "start_line": 42 },
{ "path": "src/auth.go", "content": "token 過期未驗證...", "start_line": 18 }
]
}
| 錯誤訊息 | 診斷 | 修復 |
|---|---|---|
Cannot find merge-base | 淺克隆(shallow clone) | GitHub: 保留 fetch-depth: 0;GitLab: 保留 GIT_DEPTH: 0 |
no valid LLM endpoint configured | 端點解析鏈沒找到完整三元組 | 跑 ocr config set llm.url … 或匯出 env |
Max tool requests reached | 模型 30 輪沒調 task_done | 換更強模型、檢查檔案大小、調 --max-tools |
skipped 外殼(零檔案可審) | 所有檔案被過濾 | 跑 ocr review --preview 看過濾原因 |
--audience agent vs --format json、JSON 外殼的 skipped 狀態、以及 ocr scan 與 ocr review 的根本差異。你在 CI 上跑一顆大型 PR 的評審,跑到一半 job 被中斷(runner 超時)。你要:① 確認哪些檔審完了、哪些沒審 ② 從失敗點續跑而不是從頭 ③ 把兩段評審的結果合併成一份報告。
ocr session list
sessions:
f3a9c2... repo=acme/app started=2026-08-17T10:02:11Z status=interrupted
7b1e01... repo=acme/app started=2026-08-16T22:40:00Z status=completed
ocr session show f3a9c2 | jq -r '.events[] | select(.type=="subtask") | {file, status}'
file: internal/auth/handler.go status: completed
file: internal/upload/store.go status: error ← 卡在這
file: web/src/api.ts status: pending
ocr review --from main --to feature/upload --resume f3a9c2 \
--format json --audience agent > review-part2.json
--resume 只支援區間 / 單 commit 評審——它會重讀原 session 的設定與已完成的結果,只重跑失敗與未完成的檔案,避免重複燒 token。
jq -s '[.[] | .comments[]]' <(cat part1.json) <(cat review-part2.json) \
| jq 'unique_by(.path + ":" + .content)'
大型 PR + 中斷 = 續跑場景。選 --resume 而不是「重跑整顆」的原因是成本與一致性:重跑整顆會把已完成的檔也重新審一遍(多燒 token、且結果可能因模型非確定性而不同)。--resume 保留已完成的評論,只補失敗的——讓「中斷後續跑」的結果與「沒中斷」的結果儘可能一致。
預期產出
part1: 9 files reviewed, 4 comments
resumed: 2 files re-reviewed, 1 comment recovered + 2 new
merged: 11 files total, 7 unique comments
~/.opencodereview/sessions/<repo>/<session>.jsonl 每行一個事件:llm_request、llm_response、tool_call、comment…。它是 append-only 的——所以「中斷」就只是「檔案停在某一行」。這讓 CLI 可以做很多 --format json 之外的事:
ocr session comments --severity high --category bug,security <id>——事後依條件篩選評論。ocr review --format json --audience agent > review.json
# exit code = 0,你以為一切正常
jq '.summary' review.json
# → { files_reviewed: 12, comments: 1 }
exit 0 + 12 檔審完,看起來漂亮。隱患藏在 warnings:
jq '.warnings'
# → ["subtask failed for internal/db/migrate.go: context deadline exceeded"]
migrate.go 的審查其實失敗了——但 OCR 設計上「子 agent 失敗被隔離」,聚合仍 exit 0。JSON 的 warnings 陣列才是真實失敗清單,不看它就會把「有檔沒審」誤判成「審完沒問題」。CI 腳本應該把 warnings 非空當成黃燈。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
--resume 報「不支援」 | resume 只支援 range / single-commit,不支援 workspace 模式 | 改用 -c <sha> 或 --from/--to 重跑;或先 commit 再 resume |
--preview 與 --resume 衝突 | 兩者互斥 | 分開跑:先 preview 看範圍,再 resume 續跑 |
| session list 看不到剛跑的 session | session 存在 <encoded-repo-path> 目錄;或路徑含不可見字元 | 檢查 ~/.opencodereview/sessions/ 目錄樹;用 find 找最近 jsonl |
| JSON 輸出被 ANSI 轉義碼污染 | 忘了 --audience agent,進度 UI 混進 stdout | 加 --audience agent 2>/dev/null 屏蔽 UI 與 stderr |
skipped 外殼一直出現 | 所有檔案被五重門過濾(例如剛 clone 沒變更) | 先 ocr review --preview 看過濾原因;確認有變更 |
ocr session comments)。--format json 的 skipped 外殼存在的原因——為什麼不直接回傳空 comments?warnings → 兩者都乾淨才 green。畫出條件分支。團隊每個人呼叫 ocr review 的旗標都不一樣——有人忘 --audience agent、有人沒傳 --background、有人用錯模式。你要建立一個團隊 wrapper(tocr),把「團隊最佳實踐」寫進預設值,並統一 session 管理與報告。
#!/usr/bin/env bash
# tocr —— 團隊統一 OCR wrapper
set -euo pipefail
ARGS=(--format json --audience agent --concurrency 6)
if [[ -z "${PR_TITLE:-}" ]]; then
ARGS+=(--background "$(git log -1 --format=%s HEAD 2>/dev/null || echo 'no title')")
fi
ocr review "${ARGS[@]}" "$@" > ocr-report.json
python3 -c "
import json,sys
d=json.load(open('ocr-report.json'))
print('status=%s files=%s comments=%s tokens=%s' % (
d['status'], d['summary']['files_reviewed'],
d['summary']['comments'], d['summary']['total_tokens']))
"
# 讓 wrapper 的 exit code 有意義(不是一律 0)
# 0 = 審完無 high;1 = 有 high;2 = 執行失敗/零檔可審
tocr 2>/dev/null; echo "exit=$?"
# wrapper 支援 --resume:遇到 CI 中斷,團隊可以接著跑
tocr --from main --to HEAD
# 中斷後:
SID=$(ocr session list | head -1 | awk '{print $1}')
tocr --from main --to HEAD --resume "$SID"
# tocr 進 repo,並用 shellcheck + 一個「對空 repo 跑 --preview」的冒煙測試
# → 改 wrapper = 開 PR = 走 code review(dogfood 自己的工具)
CLI 參數是「團隊紀律的載體」——把最佳實踐寫進 wrapper 預設值,比寫進 wiki 有效。wrapper 統一了「audience/format/background/concurrency」四件事,還把 exit code 從「0=跑完」升級成「分級狀態」,CI 可以直接吃。單一入口也讓「改預設值」變成一次 PR 的事,而不是逐個 repo 改。
預期產出
tocr → status=success files=12 comments=5 tokens=41200
tocr 遇到 high-severity → exit=1 → CI 卡 PR
中斷後 --resume → 只重跑失敗檔,token 省 ~70%
每顆 PR 的成本 ≈ 檔數 × 每檔呼叫數。省成本的三個槓桿:① --concurrency(控並行,撞 429 會重試放大);② --max-tools(控「每檔最多幾輪」,模型迷路時把這調低直接止血);③ include/exclude(少審一檔省一檔)。先量(看 summary.total_tokens)再調——不要憑感覺。
warnings 陣列exit 0 + summary 漂亮不代表全部審完——子 agent 失敗是被刻意隔離的,失敗清單在 JSON 的 warnings。團隊 wrapper 應該把 warnings 非空當成黃燈(exit 3),否則「migrate.go 審失敗」會被誤讀成「審完沒問題」。
① --format json 輸出含 diff 程式碼——別把 ocr-report.json commit 進公開 repo;② --provider/--model 可以覆蓋 config 指向惡意端點——wrapper 應鎖定允許的 provider 清單;③ session JSONL 含完整轉錄,~/.opencodereview 在共用機上要設 700 權限。
| 面向 | 本文(CLI 參考) | 相關文 | 差異說明 |
|---|---|---|---|
| 命令廣度 | 全部命令 + 參數表 | quickstart.html | quickstart 只教「跑通」的最小路徑;CLI 頁是「查表參考」 |
| review 模式 | workspace/commit/range 三模式互斥 | scan.html | scan 是「不需 Git diff」的第四種入口——CLI 頁把 scan 列為子命令,scan 頁獨立深談 |
| session 命令 | list/show/comments | viewer.html | CLI 提供「文字介面」存取 session;viewer 提供「視覺化泳道」——同一份 JSONL 的兩種讀法 |
| 輸出契約 | JSON 外殼 + 退出碼 | cicd.html | CI 頁把「輸出契約」變成「閘道邏輯」——CLI 定義介面,CI 消費介面 |
warnings 陣列並把「部分失敗」當成黃燈--resume 續跑並合併結果--max-tools、--concurrency、include/exclude 的成本影響