FAQ

常見錯誤、意外與「這應該這樣嗎?」的問題

配置與啟動

no valid LLM endpoint configured

no valid LLM endpoint configured; one of OCR_LLM_URL/OCR_LLM_TOKEN/OCR_LLM_MODEL,
~/.opencodereview/config.json, or ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_MODEL
must be set

OCR 走完整條端點解析鏈但沒找到完整的 (URL, token, model) 三元組。用 ocr config set llm.url … 等補齊,或匯出環境變數,然後 ocr llm test。

ocr llm test 回 401/403

token 缺 scope、過期或廠商不匹配。Anthropic 與 OpenAI 用不同 auth header 與 URL 格式——確認 llm.use_anthropic 與 URL 匹配。

not a git repository

ocr review 對目前目錄跑 git diff。不在 Git 工作樹內會提前退出。傳 --repo /path/to/repo。

"No tool calls parsed"(本地模型 / Ollama)

問題在模型,不是設定。OCR 完全透過工具呼叫驅動評審,因此模型必須支援原生工具呼叫(function calling)。只在文字輸出敘述工具呼叫的模型(如 deepseek-r1)永遠無法配合。選有 tools 標籤的模型(如 qwen3)。

過濾與規則

我的檔案沒被評審

跑 ocr review --preview(無 LLM 成本)——輸出每個候選檔與被保留/丟棄的原因:

src/foo.go              modified
src/foo_test.go         modified  (excluded: user_exclude)
node_modules/lib.js     added     (excluded: default_path)
imgs/logo.png           binary    (excluded: unsupported_ext)

unsupported_ext → 加進 include;default_path → 加進 include(覆蓋測試檔排除);user_exclude → 從 exclude 移除。

我的自訂規則沒觸發

跑 ocr rules check <file-path> 看匹配的層與 glob 模式。若層不對,多半是宣告順序——首條匹配生效,把更具體的規則前移。

評審

某檔顯示零評論——真的被評審了嗎?

開 Session Viewer 看該檔 main_task 泳道:有工具呼叫 + task_done 結束 → 乾淨評審;以錯誤卡片結束 → 偽裝成靜默的失敗。

評論的 start_line: 0 和 end_line: 0

OCR 無法把評論錨定到精確行——模型改寫了 existing_code 或 diff 格式異常。評論仍是真的,只是沒自動放置。多數 agent 整合讀 existing_code 自行定位。

"Max tool requests reached"

模型花了 30 輪工具呼叫沒調 task_done。到時的評論仍被收集。常見原因:模型不擅長遵從指令(換更強模型)、某工具持續報錯、檔案太大。用 --max-tools <n> 調整。

一些子 agent 失敗;運行仍以 0 退出

刻意為之。OCR 隔離 per-file 失敗——只要有成功的,聚合退出碼就是 0。看 JSON 的 warnings 陣列。

輸出與整合

--audience agent 仍有進度行

確認你看的不是 stderr。要屏蔽一切:ocr review --audience agent 2>/dev/null。

效能與成本

為什麼我的評審這麼貴?

如何減少 LLM 呼叫?

隱私與安全

OCR 會把我的程式碼發到別處嗎?

OCR 把你的 diff(及可選 read-tool 片段)發到你配置的 LLM 端點。其餘都不離開你的機器——會話 JSONL 與規則檔僅存於本地。遙測絕不導出 prompt 內容。

雜項

為什麼二進位叫 opencodereview 而 CLI 是 ocr?

Release 中的靜態二進位以專案命名(opencodereview);NPM wrapper 為方便安裝為 ocr。

如何解除安裝?

npm uninstall -g @alibaba-group/open-code-review        # NPM install
sudo rm /usr/local/bin/ocr                              # binary install
rm -rf ~/.opencodereview                                # all state
📖 教學解說:FAQ 深度導讀

「零評論 ≠ 沒評審」的三種判讀

收到零評論時,不要猜——用三步診斷:

  1. 看退出碼:0 = 正常完成(可能真的沒問題);1 = 致命錯誤。
  2. 看 warnings 陣列:JSON 輸出的 warnings 會列出失敗的子 agent。
  3. 開 Session Viewer:看該檔 main_task 泳道——有工具呼叫 + task_done 結束 = 乾淨評審;以錯誤卡片結束 = 偽裝成靜默的失敗。

「No tool calls parsed」的根本原因

這不是設定問題——是模型問題。OCR 完全透過工具呼叫驅動評審。如果模型不支援原生 function calling(只在文字中描述工具呼叫),就永遠無法配合。解法:選有 tools 標籤的模型(如 qwen3、claude、gpt-4)。deepseek-r1 不行。

成本爆炸的三個隱藏殺手

三個讓評審變貴的隱藏因素:

  1. Plan 階段:diff ≥ 50 行就多一次 LLM 呼叫。大檔案多,plan 成本疊加。
  2. MAX_TOOL_REQUEST_TIMES = 30:很寬鬆。用滿輪數的模型(如不擅長遵從指令的)會產生巨量對話。
  3. 記憶壓縮:超過 60% 預算觸發非同步壓縮,超過 80% 同步壓縮——每次壓縮是一次 LLM 呼叫。

解法:加 include 清單、傳 --background、調低 --concurrency。

常見錯誤與診斷

錯誤訊息診斷修復
no valid LLM endpoint configured六步端點解析鏈沒找到完整三元組用 ocr config set 補齊或匯出 env
ocr llm test 回 401/403token 錯誤或過期確認 use_anthropic 與 URL 匹配
not a git repository不在 Git 工作樹內傳 --repo /path/to/repo
No tool calls parsed模型不支援原生 function calling選有 tools 標籤的模型
Max tool requests reached30 輪工具呼叫沒調 task_done換更強模型、調 --max-tools

練習 / 驗收清單

  • 能診斷最常見的三個啟動錯誤
  • 能解釋本地模型為何必須支援原生工具呼叫
  • 能用 --preview 除錯過濾
  • 能判讀「零評論 ≠ 沒評審」的三種可能
  • 能解釋成本爆炸的三個隱藏殺手
看完這頁你應該能說出:最常見的三個啟動錯誤與修法、本地模型必須支援原生工具呼叫、如何用 --preview 除錯過濾、以及「零評論 ≠ 沒評審」的三種判讀。

延伸閱讀:設定 · 評審規則 · Session Viewer · 遙測

① 進階真實情境 Worked Example:診斷一次「整批評論全數消失」的懸案

情境

昨天跑評審明明出了 12 條評論,今天同一顆 commit 重跑卻零評論、exit 0。你第一個念頭是「LLM 壞了」,但其實通常不是。你要用「從外到內」的順序系統性排除。

Step 1 — 排除「範圍不對」:真的是同一顆 commit 嗎?

git rev-parse HEAD  # 確認現在 HEAD
ocr review -c <昨天的 sha> --preview   # 同一 sha,看會審哪些檔

最常見的真相:昨天審的「工作區」今天已經被 commit,重跑 ocr review(無參數)變成「工作區沒有變更」→ 零檔可審。或昨天審的是 --from/--to 區間,今天 ref 已經被 force-push 移位。

Step 2 — 排除「過濾變嚴」:檢查 preview 的排除原因

ocr review --preview   # 是否有檔案? 每個檔被誰排除?

Step 3 — 排除「LLM 端點問題」:連通性 + 模型

ocr llm test
# 若過了 → 再查 session,看模型到底做了什麼
ocr session list | head

Step 4 — 用 viewer 看「模型真的審了沒」

開 Session Viewer,找該 session 的 main_task 泳道:有工具呼叫 + task_done 結束 → 模型真的審了但認為沒問題(低 Recall,不是故障);以錯誤卡片結束 → 偽裝成靜默的失敗。兩種是完全不同的故事。

為什麼選這條審查路徑

「評論消失」先別怪模型——範圍(Step 1)與過濾(Step 2)是兩個免費的檢查,前者一行 git rev-parse 就能驗證。真正的「硬體」問題(LLM、模型品質)反而是最後才該懷疑的。ocr llm test + viewer 的泳道是唯二能區分「審了但沒發現」與「根本沒審」的工具。

預期產出

診斷結果: 昨天審的是工作區 (unstaged),今天已 commit
→ 重跑無參數 = 零變更 = 零評論(非故障)
復原: ocr review -c <commit sha>  → 12 條評論全部回來

② 深入原理擴充:REVIEW_FILTER_TASK 是「評論消失」的隱藏兇手

過濾任務會移除「可證明為錯」的評論

即使模型真的發了 code_comment,REVIEW_FILTER_TASK 會對照 diff 逐條檢查,移除可證明為錯的(行號對不上、程式碼其實沒變、誤報)。這是 Precision 高的關鍵——但也可能把「其實對」的評論誤刪。Session 的 review_filter_task 泳道記錄了它移除什麼。

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

# 評論者用 existing_code 錨定:
existing_code = "return err"

# 但檔裡出現 3 處 "return err"(不同函式)
# 錨定演算法配到「第一處」→ 行號錯 → REVIEW_FILTER_TASK 判定「不匹配」→ 移除
# 真正有問題的第 2 處從沒被審

重複的 existing_code 片段是錨定失敗的溫床。防禦:existing_code 要含「足以唯一識別位置」的上下文(多帶一兩行);若不確定,看 viewer 的 re_location_task 泳道是否有頻繁觸發——那是「錨定系統在掙扎」的訊號。評論被過濾 ≠ 問題不存在,而是它無法被證明。

③ 診斷式疑難排解

症狀可能原因解決方案
同一 commit 重跑評論數不同非確定性 LLM + 模型版本/參數漂移固定模型與模板版本;把評審當「每 commit 一次」而非「重跑求同」
零評論但 exit 0可能是零檔可審(範圍)、全部被過濾、或真的審完無發現三步:--preview 看範圍 → viewer 看 main_task 泳道 → 才考慮模型
評論數在 filter 後大幅縮水REVIEW_FILTER_TASK 移除大量「可證偽」評論檢查 review_filter_task 泳道;改善 existing_code 的唯一性
昨天有評論今天沒有ref 被 force-push、或工作區被 commit 掉git rev-parse 對 sha;改用 -c <sha> 固定範圍
模型「審了但沒發現」低 Recall 的刻意取捨,或模型不懂你的 codebase寫規則、傳 --background、換更強模型;接受「少而準」

④ 進階挑戰題

  1. 挑戰一:設計一個「零評論 triage」流程:收到零評論時,依序檢查哪三件事、各自看哪個檔案/泳道,才能區分「沒審」「審了沒發現」「發現了被過濾」?
  2. 挑戰二:為什麼「existing_code 越短越容易誤錨」?舉一個 2 行與 5 行 existing_code 在同檔出現多次的對比案例。
  3. 挑戰三:判斷題——「OCR 評論數 = 該檔缺陷數」這句話錯在哪?提出一個更準確的指標。

① 專案級端到端 Worked Example:把 FAQ 變成「評審維運 Runbook」

情境

你的平台上了 CI 後,on-call 的同事開始收到「OCR 評審失敗」的告警,但沒人知道怎麼查。你要把散落的 FAQ 知識整理成可執行的 Runbook:每個常見症狀都有「診斷步驟 → 指令 → 判定標準 → 處置」,並自動化掉能自動化的部分。

Step 1 — 建立 Runbook 目錄結構

runbooks/
├── 00-triage.md          # 先做這個:區分「沒審/審了沒發現/失敗」
├── 01-endpoint.md        # no valid LLM endpoint / 401 / 403
├── 02-scope.md           # 零評論 / 零檔可審 / 評論消失
├── 03-tooling.md         # Max tool requests / 工具失敗
└── 04-cost.md            # 評審太貴

Step 2 — 把「零評論 triage」寫成可執行腳本(runbook 00)

#!/usr/bin/env bash
# triage-zero.sh <session-id> —— 三分鐘內判定「為何零評論」
ocr session show "$1" | jq -r '.events[] | select(.type=="subtask") | {file,status}'
# 1. 如果 subtask 是 error → 執行失敗(看 viewer 錯誤卡片)
# 2. 如果 main_task 有工具呼叫 + task_done → 真的審了但沒發現(低 Recall)
# 3. 如果零 subtask → 零檔可審(範圍問題,查 --preview)

Step 3 — 把「端點問題」自動化成健康檢查(runbook 01)

# CI 每日跑一次: 確認三元組 + 連通性
ocr llm test || {
  env | rg 'OCR_LLM|ANTHROPIC' | sed 's/=.*/=/'
  echo "→ 檢查 secret 是否過期、use_anthropic 是否與 URL 匹配"
}

Step 4 — 把 Runbook 綁進告警(故障自動帶出 SOP)

# 告警訊息直接附 runbook 連結 + 對應的診斷命令
# on-call 接到告警 → 照 runbook 走 → 3 分鐘內給出「根因 + 處置」

為什麼選這條路徑

FAQ 是「知識」;Runbook 是「可執行的知識」。把它們綁進告警(Step 4)是關鍵——on-call 的壓力下沒人會去翻 FAQ,但會照「告警訊息裡的下一步」做。診斷步驟裡能腳本化的(triage、llm test)全部自動化,剩下的人才介入。Runbook 版本化 + 每次故障後更新——「今天的故障」變成「明天的自動診斷」。

預期產出

告警: "OCR review failed: subtask error"
on-call: 跑 triage-zero.sh → 找到 internal/migrate.go 工具失敗
Runbook 03 → 判定「檔案超過 max-tokens 被丟棄」→ 調 --max-tokens
→ MTTR 從 45 分鐘降到 8 分鐘

② 效能 / 品質 / 安全深度:維運三面向

效能:診斷要便宜、先免費後付費

診斷的成本也該被管理:ocr review --preview 與 git rev-parse 免費、ocr llm test 便宜、viewer 讀本地檔零成本——這些「免費/便宜」的檢查要排在前面;直接重跑評審(最貴)放最後。Runbook 的順序就是成本排序:先排除範圍與過濾,再查 LLM,最後才重跑。

品質:把「評論消失」的誤判率降下來

「零評論」有至少三種成因(沒審/審了沒發現/發現了被過濾),錯誤處置是「重跑一次」——但非確定性 LLM 重跑未必能重現問題。品質措施:① 先開 viewer 看 main_task 與 review_filter_task 泳道,確認「是沒審還是被濾掉」;② 看 re_location_task 是否頻繁(錨定失敗的訊號);③ 只有「執行失敗」才該重跑,其餘是「設計行為」。

安全:故障資訊本身可能外洩

診斷輸出(env 清單、session 內容、diff)可能含敏感資訊。安全措施:① 診斷腳本一律 sed 's/=.*/=<redacted>/' 遮蔽 secret;② 不要把整個 JSONL cat 進告警訊息(改貼 viewer 連結);③ Runbook 的「環境檢查」輸出不要 log 到公開的 CI 日誌。

③ 文件間比較對照表

面向本文(FAQ)相關文差異說明
錯誤處理症狀 → 診斷 → 修復的表格cicd.htmlFAQ 是「人類查表」,CI 頁把同樣的判斷寫成「pipeline 的 exit code」——同一知識兩種形態
零評論判讀三步診斷(退出碼/warnings/viewer)viewer.htmlFAQ 告訴你要看 viewer;viewer 頁教你「泳道/卡片」怎麼讀——FAQ 是索引,viewer 是工具
成本三個隱藏殺手(plan/30 輪/壓縮)benchmarks.html / telemetry.htmlFAQ 講「為什麼貴」;telemetry 講「怎麼量」;benchmark 講「該是多少」——三層互補
模型問題No tool calls parsed 的根因configuration.htmlFAQ 說「問題在模型」;設定頁教你選支援 function calling 的模型並驗證

④ 互動式檢核清單

進階驗收:你能把維運經驗變成可執行的 SOP 嗎?

  • - [ ] 能把「零評論」做成三分鐘內的判定腳本(區分三種成因)
  • - [ ] 能自動化端點健康檢查並遮蔽 secret 輸出
  • - [ ] 能把每個常見症狀寫成一頁「診斷步驟 → 指令 → 判定 → 處置」的 runbook
  • - [ ] 能按「成本排序」排列診斷步驟(先免費後付費)
  • - [ ] 能決定「哪些該重跑、哪些是設計行為」(避免無效重跑)
  • - [ ] 能把故障後學到的處置回寫進 runbook(滾動改善 MTTR)