internal/agent/agent.go — 評審編排核心

Agent.Run、loadDiffs、dispatchSubtasks、檔案過濾
套件:internal/agent/(agent.go + compression.go + preview.go + util.go)

大方向

internal/agent 是 OCR 的「大腦」。它編排完整評審管線:載入 diff → 過濾 → 對每個檔案分發子任務(每個子任務跑 plan+main 迴圈)→ 收集評論 → 交給輸出層。agent.go 是主迴圈與分發,compression.go 是記憶壓縮,preview.go 是檔案過濾。


1. 管線頂點

Agent.Run(ctx) agent.go管線頂部:loadDiffs → dispatchSubtasks → 回傳評論。

Run 是整個評審的進入點,依序:

  1. loadDiffs(ctx)——從 diff provider 載入 []model.Diff
  2. 建立 session、初始化 manifest(對 resume 支援做 input identity 指紋)。
  3. dispatchSubtasks(ctx)——把每個 diff 分發給子任務(每個子任務在 internal/llmloop 跑 plan+main)。
  4. 回傳收集到的 []model.LlmComment
loadDiffs() · injectDiffMap() agent.go載入 diff;把 diff 對照表注入給「其他變更檔」脈絡。

loadDiffs 呼叫 provider 的 GetDiff,套用 resume(applyResume)後存進 agent。injectDiffMap 建立 path → diff 的對照,供 {{change_files}} 佔位符使用——讓子 agent 知道 PR 裡還有哪些檔變了。

2. 檔案過濾入口

dispatchSubtasks() · countDispatchable() agent.go對每個可評審檔分發子任務;計算可分發數量。

dispatchSubtasks 遍歷每個 diff,先經 preview.go 的五重門過濾決定「可評審」與否(不可評審的記 warning),可評審的啟動子任務。countDispatchable 統計有多少檔真的會送評——這是進度與成本的預告。

3. 指紋與 resume

reviewItemFingerprint() · applyResume() agent.go算每檔指紋;resume 時複用未變檔的既有評論。

每檔算一個指紋(模式 + diff 內容 hash),resume 時比對——指紋相同的檔複用上次評論(省 token),不同的才重跑。sourceArtifactSHA256/ruleConfigSHA256/runtimeConfigSHA256 是更上層的「input identity」,保證 resume 只在相同輸入下有效。

4. 計數與報告

TotalTokensUsed() · Warnings() · ToolCalls() agent.go把 llmloop runner 的聚合資料轉成 agent 介面。

這些是薄包裝:token 統計、警告清單、工具呼叫計數都來自 internal/llmloopRunner(原子計數器)。BudgetExceeded 標記記憶體預算超限。

看完這頁你應該能說出Agent.Run 的三大步驟、五重門過濾在哪觸發、指紋 resume 如何省 token、以及 agent 與 llmloop 的職責分工(編排 vs 迴圈)。

下一步:internal/llmloop(per-file 迴圈)。