ocr scan 直接從工作樹讀取每個檔案的目前內容交給 LLM 評審,不需要 Git 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)
| 參數 | 簡寫 | 預設 | 說明 |
|---|---|---|---|
--path <list> | — | 整個倉庫 | 逗號分隔的 repo 相對目錄或檔案 |
--exclude <patterns> | — | — | 逗號分隔的 gitignore 風格排除模式;與 rule.json 的 excludes 合併 |
--preview | -p | false | 列舉並過濾但跳過 LLM |
與 ocr review 一樣接受 --format json、--audience agent、--resume、--provider、--model、--max-tokens 等。
| 面向 | ocr review | ocr scan |
|---|---|---|
| 輸入 | Git diff(三種模式) | 整個工作樹檔案 |
| 需要 Git 歷史 | 是 | 否 |
| 適用 | PR / commit 評審 | 整檔審計、陌生 codebase |
| 預覽 | --preview | --preview |
ocr review 審的是「變更了什麼」(Git diff),ocr scan 審的是「檔案長什麼樣」(完整內容)。這不是功能差異——是使用場景差異:
--path 接受逗號分隔的目錄或檔案,可以精確控制掃描範圍。配合 --exclude 排除生成碼:
ocr scan --path src/api,src/db --exclude '**/generated/*,*.pb.go'
這只掃描 API 和 DB 層,排除 protobuf 生成檔。
跑 ocr scan --preview 可以不花 token 看到會掃描哪些檔案。這是第一次 scan 的必跑步驟——確保你不會掃到不該掃的(如含敏感資料的目錄)。
ocr scan 與 ocr review 的根本差異(diff vs 整檔)、--path 與 --exclude 的用法、以及何時該用 scan。你的產品明天要上線,但沒有正式的安全 team。你要用 OCR 做一次「最小可行安全審計」:掃描所有對外暴露的入口(API handlers、auth、上傳、SQL mapper),在預算內找到最該修的洞,產出一份可交差的報告。
# 對外入口通常在: api / handler / controller / router
find src -type d \( -name api -o -name handler -o -name controller -o -name router \)
ocr scan --path src/api,src/auth,src/upload --preview
ocr scan --path src/api,src/auth,src/upload \
--max-tokens 200000 --format json --audience agent > security-scan.json
jq -r '.comments[] | select(.content | test("SQL|injection|auth|token|XSS|CSRF|traversal|SSRF"; "i"))' \
security-scan.json
jq '.comments | length' security-scan.json # 總數
# 依內容分 Critical/High/Medium,列成上市檢查清單
安全審計不適合 ocr review——上線前「整個工作樹」的狀態才是重點,不是「最近改了什麼」。ocr scan --path 讓我們只審對外暴露面(auth/upload/API),token 預算花在刀口上。用 --preview 先確認範圍(避免掃到開發工具目錄)、用 --max-tokens 給足上下文(讓 Agent 有餘裕讀完整 handler 追蹤流程)——這是「有預算上限的審計」的正確姿勢。
預期產出
security-scan.json: 6 files, 14 comments
過濾出 6 條安全相關:
CRITICAL: auth/login.go — token 過期未驗證即可進入
HIGH: upload/store.go — 未驗證 user-supplied path
MED: api/v1/users.go — SQL 字串拼接風險
→ 上市前必須修: 2 條;建議: 1 條;其餘觀察
ocr scan 對每個檔案獨立跑一個子 agent(跟 review 的 per-file 一樣),所以 --max-tokens 是「每檔」的 prompt 上限。整批掃描的總成本 ≈ 每檔上限 × 檔案數。這就是為什麼 --path 縮小範圍對成本影響巨大——掃 10 檔 vs 100 檔,token 差 10 倍。
# 你的 scan 只審了「source 目錄」:
ocr scan --path src --exclude '**/test/**'
# 但真正的 secret 藏在: config/prod.yaml ← 不在 src、也不在 Git 追蹤 (gitignore)
# scan 從工作樹讀檔 → config/prod.yaml 根本不在候選清單
# 審計報告「零 secrets」→ 但 prod.yaml 裡有 DB 密碼硬編碼
「掃不到 = 乾淨」是 scan 的最大盲點——它只掃它被指定掃的。隱患:範圍外的洞(config、.env、部署 manifest)完全不可見。防禦:審計前先「列全目錄」對照 Git 追蹤清單,確認沒有「該審但沒被掃」的檔;--preview 的輸出要跟 git ls-files 比對,找出「存在但被排除」的意外。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| scan 掃完零評論 | 掃描範圍外有洞;或 --path 沒覆蓋到真正熱點 | 對照 git ls-files 與 --preview;擴大範圍 |
| 某檔被截斷「審一半」 | 該檔超過每檔 --max-tokens | 調高 --max-tokens 或縮小檔案(拆模組) |
| 掃到 vendor / 生成碼拖慢 | 沒設 --exclude | 加 --exclude '**/vendor/**,**/generated/**' |
| 評論多到無法消化 | 一次掃太多檔案 | 分層掃:先核心目錄(auth/payment)再往外;用 jq 過濾分級 |
| secrets 掃不到 | secrets 檔在 scan 範圍外(config/.env) | 把 config、部署 manifest 加進 --path;或另跑 gitleaks |
git ls-files + ocr scan --preview 設計一個「範圍差異檢查」:找出「存在於 repo 但 scan 沒掃到」的檔。