CLI 參考

每個 ocr 子命令、參數與退出行為的完整參考

命令總覽

命令別名作用
ocr reviewocr r執行評審並輸出評論
ocr scanocr 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/commentssessions列出 / 查看已保存評審會話
ocr viewer—本機 Web UI(localhost:5483)瀏覽歷史評審
ocr version-V印出版本、commit、平台、建置日期

ocr review 參數

參數簡寫預設說明
--repo <path>—目前目錄Git 倉庫根
--from <ref>——diff 起始 ref
--to <ref>——diff 結束 ref(merge-base(from,to)..to)
--commit <sha>-c—評審單一 commit
--preview-pfalse跑過濾管線但跳過 LLM
--resume <session-id>——從之前評審會話恢復
--format <fmt>-ftexttext 或 json
--audience <who>—humanhuman(串流進度)或 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 並用。

JSON 輸出範例

{
  "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 失敗

ocr scan

不需 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

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

ocr config set provider anthropic
ocr config unset custom_providers.my-gateway
ocr config provider                  # 互動式 TUI
ocr config model                     # 互動式 model 選擇

ocr session

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

ocr viewer                  # binds localhost:5483
ocr viewer --addr :3000     # bind to all interfaces on port 3000

提示與注意

📖 教學解說:CLI 實戰指南

三種評審模式的選擇邏輯

不要糾結「該用哪個」——模式由你手上的變更決定:

  • 有 staged/unstaged 變更 → ocr review(工作區模式,最常用)
  • 要審某個 commit → ocr review -c <sha>
  • 要比較兩個 ref 之間 → ocr review --from main --to feature

三種模式互斥,混用直接報錯。這不是限制——是確定性保證。

--audience agent vs --format json 的根本差異

這是最常搞混的:--audience agent 控制的是 UI 輸出(屏蔽進度列),--format json 控制的是 資料結構(text vs JSON)。你需要同時屏蔽 UI 又要 JSON?必須兩個都傳。很多 CI 腳本只傳 --format json 然後抱怨 stdout 有雜訊——就是因為沒傳 --audience agent。

--background:提升品質最有效的參數

如果你只記一個參數,記 --background。它讓 LLM 知道「這段變更在解決什麼問題」,大幅減少無關評論。從 CI 呼叫時,傳 PR 標題或需求摘要。從 Claude Code 呼叫時,傳專案脈絡。這是 token ROI 最高的投資。

🔍 Worked Example:從零跑一次完整評審

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 的根本差異
  • 能列出 ocr review 的所有主要參數
看完這頁你應該能說出:三種評審模式與互斥規則、--audience agent vs --format json、JSON 外殼的 skipped 狀態、以及 ocr scan 與 ocr review 的根本差異。

延伸閱讀:架構總覽 · 設定 · 評審規則

① 進階真實情境 Worked Example:跨 session 追蹤與失敗續跑

情境

你在 CI 上跑一顆大型 PR 的評審,跑到一半 job 被中斷(runner 超時)。你要:① 確認哪些檔審完了、哪些沒審 ② 從失敗點續跑而不是從頭 ③ 把兩段評審的結果合併成一份報告。

Step 1 — 從 JSONL 找 session id

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

Step 2 — 確認中斷點:看哪個檔停在錯誤

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

Step 3 — 用 --resume 從中斷點續跑

ocr review --from main --to feature/upload --resume f3a9c2 \
  --format json --audience agent > review-part2.json

--resume 只支援區間 / 單 commit 評審——它會重讀原 session 的設定與已完成的結果,只重跑失敗與未完成的檔案,避免重複燒 token。

Step 4 — 合併兩段結果

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

② 深入原理擴充:session JSONL 是 CLI 的可程式化介面

JSONL 每行一個事件

~/.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>——事後依條件篩選評論。
  • 對 JSONL 寫 jq / python 分析工具軌跡(哪個工具用最多、哪些呼叫失敗)——比任何「輸出格式」都完整。
  • 拿 JSONL 當除錯證據——viewer 就是讀同一個檔。

「看起來通過 review 但其實有隱患」的案例

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 看不到剛跑的 sessionsession 存在 <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 看過濾原因;確認有變更

④ 進階挑戰題

  1. 挑戰一:寫一個 shell 函式,輸入「session id」與「severity filter」,輸出該 session 的「high severity、屬於 bug/security 分類」的評論(提示:ocr session comments)。
  2. 挑戰二:解釋 --format json 的 skipped 外殼存在的原因——為什麼不直接回傳空 comments?
  3. 挑戰三:設計一個 CI 腳本片段:跑評審 → 檢查 exit code → 檢查 warnings → 兩者都乾淨才 green。畫出條件分支。

① 專案級端到端 Worked Example:把 OCR 封裝成「團隊標準 CLI wrapper」

情境

團隊每個人呼叫 ocr review 的旗標都不一樣——有人忘 --audience agent、有人沒傳 --background、有人用錯模式。你要建立一個團隊 wrapper(tocr),把「團隊最佳實踐」寫進預設值,並統一 session 管理與報告。

Step 1 — 寫 wrapper(把最佳實踐變成預設)

#!/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']))
"

Step 2 — 統一報告輸出與失敗分級

# 讓 wrapper 的 exit code 有意義(不是一律 0)
# 0 = 審完無 high;1 = 有 high;2 = 執行失敗/零檔可審
tocr 2>/dev/null; echo "exit=$?"

Step 3 — session 管理:壞了可續跑

# wrapper 支援 --resume:遇到 CI 中斷,團隊可以接著跑
tocr --from main --to HEAD
# 中斷後:
SID=$(ocr session list | head -1 | awk '{print $1}')
tocr --from main --to HEAD --resume "$SID"

Step 4 — 版本化 + 測試 wrapper 本身

# 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%

② 效能 / 品質 / 安全深度:CLI 使用三面向

效能:減少 LLM 呼叫的三個旋鈕

每顆 PR 的成本 ≈ 檔數 × 每檔呼叫數。省成本的三個槓桿:① --concurrency(控並行,撞 429 會重試放大);② --max-tools(控「每檔最多幾輪」,模型迷路時把這調低直接止血);③ include/exclude(少審一檔省一檔)。先量(看 summary.total_tokens)再調——不要憑感覺。

品質:不要忽略 warnings 陣列

exit 0 + summary 漂亮不代表全部審完——子 agent 失敗是被刻意隔離的,失敗清單在 JSON 的 warnings。團隊 wrapper 應該把 warnings 非空當成黃燈(exit 3),否則「migrate.go 審失敗」會被誤讀成「審完沒問題」。

安全:flag 與輸出本身的安全面

① --format json 輸出含 diff 程式碼——別把 ocr-report.json commit 進公開 repo;② --provider/--model 可以覆蓋 config 指向惡意端點——wrapper 應鎖定允許的 provider 清單;③ session JSONL 含完整轉錄,~/.opencodereview 在共用機上要設 700 權限。

③ 文件間比較對照表

面向本文(CLI 參考)相關文差異說明
命令廣度全部命令 + 參數表quickstart.htmlquickstart 只教「跑通」的最小路徑;CLI 頁是「查表參考」
review 模式workspace/commit/range 三模式互斥scan.htmlscan 是「不需 Git diff」的第四種入口——CLI 頁把 scan 列為子命令,scan 頁獨立深談
session 命令list/show/commentsviewer.htmlCLI 提供「文字介面」存取 session;viewer 提供「視覺化泳道」——同一份 JSONL 的兩種讀法
輸出契約JSON 外殼 + 退出碼cicd.htmlCI 頁把「輸出契約」變成「閘道邏輯」——CLI 定義介面,CI 消費介面

④ 互動式檢核清單

進階驗收:你能把 CLI 變成團隊可靠的工具嗎?

  • - [ ] 能設計一個 wrapper 把 audience/format/background/concurrency 設成團隊預設
  • - [ ] 能讓 wrapper 的 exit code 表達「審完/有 high/失敗/零檔」四種狀態
  • - [ ] 能讀 warnings 陣列並把「部分失敗」當成黃燈
  • - [ ] 能在中斷後用 --resume 續跑並合併結果
  • - [ ] 能列出 --max-tools、--concurrency、include/exclude 的成本影響
  • - [ ] 能保護 JSON 輸出與 session 目錄的敏感資料