七位一體一次健檢,最高 leverage 不在 code review,在 Scout

整場 4 小時七位一體 memhall 巡檢,最高 leverage 的 P0 不是來自 code review agent,是 human-mediated Scout。一個對 multi-agent system 設計的反直覺洞察 + 7 commits 實戰紀錄。

七位一體一次健檢,最高 leverage 不在 code review,在 Scout

我的個人 PKI memory layer 叫 memory-hall(簡稱 memhall),是 Python FastAPI + SQLite + sqlite-vec + bge-m3 embedder 跑在 Mac mini 上的單機服務。今晚回家,原本打算花 30 分鐘做一次健康檢查,最後變成一場 4 小時的七位一體巡檢,外加 7 個 commits push 上去。

過程中真正讓我停下來的不是技術問題,是一個對 multi-agent system 設計的反直覺發現:整場 session 最高 leverage 的那個發現,不是來自 code review agent(Codex)也不是 schema analyst(Gemini),是來自 human-mediated Scout(Perplexity Max)。

這篇文章想把這個觀察寫下來。


七位一體是什麼

我的 daily AI workflow 把工作分給七個角色:

角色 對應
Chair 我自己
Architect / Judge Claude(透過 Claude Code 主對話)
Engineer Codex(CLI + file I/O)
Analyst Gemini(CLI + file I/O)
Scout-1(深度 research + 引用) Perplexity Max — 我手動帶問題清單去 max.ai 取回
Scout-2(即時社群情報) SuperGrok — 我手動帶問題清單去 grok.com 取回
Local Brain gemma4:31b on M4 Max(隱私資料 / 預處理 / 本地推論)

中間那兩個 Scout 是 human-mediated——不走 API(理由:不想付額外 token、UI DeepSearch 體驗優於 raw API、避免維護 yet another API client)。我寫好 5 題給 Max、5 題給 Grok,自己貼進瀏覽器,把答案貼回 markdown 給 Claude 整合。

聽起來很笨——「都已經有 Claude / Codex / Gemini 了還要 human-in-the-loop?」我以前也這麼想。今天這個 session 把我說服了。


今晚怎麼開始的

memhall 跑了一陣子,我想看看狀態。

七位一體的開場 SOP:

  1. Layer 1(Claude 自跑): API health / auth gate / hybrid search / write-dedup / auto-embed
  2. Layer 2(Statistical baseline): SSH 上 sqlite3 直查 entry 統計、namespace 分佈、agent 寫入比例、sync_status、principal
  3. Layer 3(Code review): 派 Codex 做 code review、派 Gemini 做 schema/data 分析

Layer 1 通通通過。Layer 2 找出 5 個結構性問題:

  • F1: Health endpoint 偶發 503 (~20% probe rate)
  • F2: 33% (72/220) entry sync_status=pending 沒 vector embedding(hybrid search 對這些 entry semantic miss)
  • F2.5: Search hybrid mode 對某個 query 回傳 RRF=0.0164 的奇怪低分
  • F3: 100% (220/220) entry created_by_principal=dev-local(auth attribution 缺)
  • F4: 文件 drift(CLAUDE.md 寫 mini2 冷備,實際是 NAS rsync)

Layer 3 派 Codex 跟 Gemini 並行做 code review。

Codex 找到:F1 root cause 是 cached health endpoint 的 sub-check fail 整體標 degraded 但錯誤被吞、F2 是 _embed_reindex_batch wait_for vs HttpEmbedder httpx hardcode 的 timeout mismatch + per-entry exception 被 silent swallow、F3 是 bearer middleware 跟 get_principal() 完全斷開(get_principal() 只認 HMAC header,否則固定回 dev-local)。

Gemini 從 schema 角度互補:confirm timeout mismatch 數字、找出 search semantic 在 embedder.embed(query) 設 2 秒硬超時、/v1/admin/* route 完全沒 principal/role gate(這個是 P0 安全缺口)。

Codex + Gemini 一起把 application 層的所有 root cause 鎖定。我以為 session 已經到頂。

然後 Max 的答案回來。


Scout 帶來的那一段

我給 Max 5 題(我列的問題清單可以參考[文末附錄])。其中 Q1 是 sqlite-vec WAL 不縮的問題——一個我以為是「sqlite-vec extension 自己的 bug」的小事。

Max 回的第一句:

「PASSIVE checkpoint 回 0|0|0 且 WAL 不縮,是已知且有文件的 SQLite 行為,不需要恐慌。」

OK,跟我猜的差不多。但接著:

SQLite 3.53.0(2026-04-09)和 3.51.3(2026-03-13)都修了一個「WAL-reset database corruption bug」——這代表之前版本(包含你可能跑的版本)確實有 WAL reset 時的 corruption 風險。強烈建議升到 SQLite 3.51.3 或 3.53.0,這是個 production 必要動作。」

我立刻 SSH 上 mini,跑 docker exec memory-hall-memory-hall-1 python3 -c "import sqlite3; print(sqlite3.sqlite_version)"

回傳:3.46.1

Production data 在 corruption bug 風險中。整整 4 個月。

這個發現的層次跟 F1-F5 完全不同:

  • F1-F4 是 memhall application 內部的 bug(健康檢查邏輯、reindex worker、auth chain、文件 drift)
  • F5 是 memhall 使用模式的 bug(Claude 寫了 91% 的 entry,違反「七位一體共用記憶大廳」設計初衷)
  • SQLite corruption bug 是底層 platform 的 bug(跟 memhall application code 完全無關)

這個層次只有 Scout 抓得到


為什麼 Codex / Gemini 抓不到?

不是 Codex 跟 Gemini 不夠強。是他們的 工作層次 跟這個問題的層次不對齊。

  • Codex (Engineer) 的守備範圍是「我寫的 code 有沒有 bug」。它讀完整個 src/memory_hall/,讀完 ADR、design doc、incident report,能給出 application-level 的 root cause。但它不會主動去查「我用的 SQLite 版本最近有沒有出新的 corruption bug」——因為它的 input 是我的 repo,不是「業界本月的 patch release」。

  • Gemini (Analyst) 的守備範圍是「資料 / schema / 演算法」。它從 220 entries 的 sync_status 分佈反推出 timeout mismatch、從 RRF 公式拆解出 0.0164 的數學成因。但它的 reference frame 一樣是 my application + my data,不是 SQLite upstream 的 changelog

  • Max (Scout-1) 的守備範圍是 「業界當下的 reference / 引用 / 最新研究」。我問 WAL 行為,它順手帶上「對了,3.51.3 和 3.53.0 修了一個 corruption bug」——這對它是輕鬆順手的事,因為它的訓練 / 工具就是設計來掃這層的。

換句話說:Code review agent 看「我自己」,Scout 看「世界」。 Production engineering 兩者都需要。我一直知道這個概念,但今晚是第一次親眼看到「假如沒有 Scout,整個 session 會 ship 一個錯失底層 corruption fix 的 release」。


量化驗證:7 commits 中最關鍵的那個 100% 來自 Scout

今晚最後 push 到 origin/main 的 commit list:

4539ca9 fix(deploy): 升 SQLite 3.46.1 → 3.53.0 修 WAL-reset corruption bug
59a0025 docs(council): Phase A reliability patches summary
467330e docs(api): Authorization header 形狀對齊 ADR-0007
21fa6c7 fix(health): sub-check error 不再吞 + cheap cached probe
00bda1c fix(search): hybrid 降級不再靜默 — 加 semantic_status 與 degraded 旗標
aee2cdc fix(reindex): 修 timeout mismatch 與 silent except 防 poison pill
29d979c docs(council): Codex Q1-Q3 review answer

我問自己:如果今天只能 ship 一個 commit,要選哪個?

不是 reindex retry(那解 33% pending 的 visibility 問題)。不是 search degraded flag(那解 silent fallback 的可觀測性問題)。是 4539ca9 那個 SQLite 升版——因為其他六個都是 reliability 改善,但 SQLite corruption bug 是正在累積 production data 風險

4539ca9 這個 commit 完全 trigger by Max 的一句話。沒有 Max,這個 commit 不會存在。

剩下六個 commits 反過來看,有沒有 Codex 跟 Gemini 都能寫,只是寫得慢一點/差一點。但 SQLite 升版不是。它需要「我跑的 SQLite 版本是什麼 + upstream changelog 最近改了什麼 corruption bug」這兩個 piece 同時出現——前者 Codex 能看,後者要靠 Scout。


那 Local Brain (gemma4) 在做什麼?

我把 Max 的答案 + Grok 的答案 + 5+5 題清單一起餵給 gemma4:31b,請它做 cross-analysis。

它輸出的最後一句:

「結論:證據鏈完整,無需額外 Scout,可直接進入 Synthesis 階段。」

這句話本身的價值,比 cross-analysis 表格還高。沒有它我可能會猶豫「要不要再 round 一次 Scout 補強」——這在 multi-agent system 裡是常見的 churn。gemma4 給了一個 deterministic gating signal 讓我(Claude)有信心進入下一步。

Local Brain 不只是 token 省,是 evidence chain validator。 這也是我以前低估的角色。


七位一體 routing 設計的反直覺洞察

今晚的 session 把幾個我以前模糊的東西具體化了:

1. 「越多 agent 越好」是錯的,「不同 layer 的證據獨立來源」才是核心

我以前的本能:跨 LLM 多家投票拿 consensus。但 agent council 的研究(DeepMind 2024 等)指出:獨立投票的錯誤會放大(17x),中央 chair + evidence-traceable synthesis 才壓得下來(4.4x)。今晚 cross-validation 工作得好,是因為每個 agent 在它的 layer 各自獨立提證據,不是互相投票。

2. Human-mediated Scout 不是過渡狀態

我以為 Path B(手動貼問題進瀏覽器)是「等 API 成熟前的暫時做法」。今晚反過來——這個摩擦本身就是價值。每次我要打 Max 之前,必須先寫 5 題清單。寫清單的過程強迫我把問題結構化、把假設說清楚——而這份清單本身就是 audit log。如果走 API 自動化,反而會變成「丟 raw context 進去拉 hallucinate 出來」的低品質回應。

3. Routing 決策樹要把 Scout 排在「概念性 / 跨領域」分支前面

我之前的 routing rule 是:

  • 時效性 → Scout
  • 概念性 → 先打 mk-brain(已 curated knowledge base),查不到才 Scout

今晚的教訓是:「最近 4 個月 upstream changelog」這種「概念性 + 時效性 + 跨領域」混合的問題,mk-brain 一定不知道(ingest 有 lag)。下次開 session 應該 default 把「最近的東西」這條指向 Scout,不要繞 mk-brain。

4. Scout 問題清單應該是 session 第一個 deliverable,不是中段補強

今晚 Scout 是中段才丟出去(Codex / Gemini 已經跑完才補)。回頭看,Scout 答案如果在開場就拿到,整個 routing 順序會更精準——Codex 的 briefing 可以直接帶 Max 的 reference 進去,避免 redundant 探索。

下一個 session 我會試把「寫 Scout 問題清單給 Maki 同步打」排在 Layer 1 後立刻做。


收尾

七位一體不是炫技,是當你的工作層次跨越「我自己 / 業界 / 社群 / 過去 curated knowledge」這幾個 frame 時,沒有單一 agent 能 cover 全部

今晚的 production data 沒在 corruption bug 中受損,是因為這個 routing 在那個關鍵時刻把對的問題交給了對的 agent。

如果你在做 multi-agent system,不要只 review 「不同 LLM 互相 cross-check」這層的價值。Human-mediated Scout 是更高層次的 leverage 點,雖然摩擦看起來大,但它 catch 到的是其他 agent 結構上看不到的問題。


附錄:今晚的 Scout 問題清單

給 Max(深度 research + 引用):

  1. sqlite-vec (v0.1.x) 在 production 的 stability 與 wal mode 互動有沒有 known issue?
  2. bge-m3 dim=1024 embed service 的合理 P99 latency?
  3. FastAPI health endpoint 反模式 / 業界 (k8s/Cloud Run) 健康檢查設計慣例?
  4. RAG hybrid (BM25+dense+RRF) 對 220 筆小資料量,k=60 是否過大?
  5. SQLite 個人尺度 sync_status=pending reconcile pattern 業界做法?

給 Grok(即時 X / 社群 insider):

  1. sqlite-vec WAL 永遠不縮的 issue 社群有沒有人遇到並解決?
  2. bge-m3 inference server 部署選擇(Infinity / TEI / Ollama / 自 wrap)哪個最不維運?
  3. python httpx async + Tailscale 偶發 timeout 有沒有 community retry / circuit breaker 最佳實踐?
  4. 個人 PKI memory layer 是現在 X 上的熱題嗎?有沒有同 scale 的 reference 架構?
  5. HMAC signature middleware in FastAPI 2026-Q1 有沒有更輕量 pattern?

兩份 5 題,覆蓋 sqlite / embedder / connectivity / RAG / auth 五個 layer。每個 layer 同時打 Max(深度 research)跟 Grok(社群 insider)做 cross-validation。

P0 那個 SQLite 升版來自 Q1 給 Max——但如果不是把問題寫得這麼具體(「sqlite-vec 的 WAL 不縮 issue」),Max 也不會主動順手帶上 changelog hint。問題清單的精細度,決定 Scout 能 catch 的層次。


memhall 是 open source: https://github.com/MakiDevelop/memory-hall