挖掘迴圈:變更如何化為組織記憶
> Git 提交會轉化為結構化的變更日誌條目與架構決策紀錄,再回饋給 AI 代理人,成為可查詢的組織記憶。
本文中的數字反映發布當下(2026 年 2 月)的系統狀態。目前最新數字請參見我們的團隊頁面。
每個工程團隊都面臨同樣的難題:變更不斷發生,但這些變更背後的原因卻不斷流失。六個月後,有人問「我們當初為什麼在 pipeline 各階段採用 DuckDB?」而答案只存在於當初做出這個決定的人腦中 — 前提是那個人還在團隊裡。
我們打造了一套挖掘工作流程,補上了這個缺口。變更透過 git 提交流動,經我們的挖掘管線處理後,化為結構化的變更日誌條目與架構決策紀錄,再透過 CLI 查詢回饋給我們的 AI 代理人。結果就是:人類與 AI 都能存取的組織記憶。
問題所在:決策會蒸發
想想一個典型情境。某位開發者提交了:
feat(canonical): add DuckDB runtime for pipeline stages
這筆提交代表了一項重大的架構抉擇。團隊評估了多個選項、權衡了各種取捨,最終基於特定原因選擇了 DuckDB。但這些脈絡全都存在於:
- 某個 Slack 討論串中(大概已經被刪掉了)
- 某人的記憶裡(肯定正在淡去)
- 程式碼中的一則註解(也許有,如果你夠幸運的話)
三個月後,一位新加入的團隊成員問道:「這個新階段該用 DuckDB 還是 SQLite?」若沒有組織記憶,他們要嘛重新發明輪子,要嘛做出不一致的選擇。
這個迴圈:從提交到情境
我們的挖掘工作流程,會將 git 歷史轉化為可查詢的知識:
Git Commits
│
▼
┌─────────────────────┐
│ mine sync │ ← Build index from git history
└─────────────────────┘
│
▼
┌─────────────────────┐
│ mine candidates │ ← Surface commits for review
└─────────────────────┘
│
▼
┌─────────────────────┐
│ Classification │ ← Human or LLM assessment
│ (changelog or ADR) │
└─────────────────────┘
│
├──────────────────────┐
▼ ▼
┌─────────────┐ ┌───────────────┐
│ Changelog │ │ Decisions │
│ Ledger │ │ Registry │
│ (JSONL) │ │ (YAML files) │
└─────────────┘ └───────────────┘
│ │
▼ ▼
┌─────────────┐ ┌───────────────┐
│ CHANGELOG.md│ │ orkestra CLI │
│ per package │ │ queries │
└─────────────┘ └───────────────┘
│ │
└──────────────────────┘
│
▼
┌───────────────┐
│ AI Agents │
│ (via CLI) │
└───────────────┘
關鍵洞察在於:變更日誌與架構決策都源自同一份 git 歷史,經由統一的管線處理。這確保了不會有任何內容遺漏。
挖掘機制如何運作
步驟一:同步索引
uv run orkestra mine sync
此指令會掃描 git 歷史,為所有提交建立索引,並從每筆提交中擷取結構化訊號:
- 慣例提交類型(
feat、fix、chore、docs) - 範圍(屬於哪個套件或領域)
- 重大變更標記
- 異動檔案與複雜度指標
步驟二:檢查涵蓋率狀態
uv run orkestra mine status
我們目前的狀態如下:
Mining Status
=============
Decisions
---------
Coverage: 100.0%
Processed: 15637 (of 15637)
Extracted: 476
Skipped: 15161
Changelog
---------
Coverage: 100.0%
Processed: 15637 (of 15637)
Released: 6799
Skipped: 8838
已處理 15,637 筆提交,其中 476 筆成為架構決策,6,799 筆成為變更日誌條目,每一筆提交都已完成分類。
步驟三:取得待審核候選項目
uv run orkestra mine candidates --limit 50 --full
這會列出尚未處理的提交,並附上供分類使用的完整脈絡:
on
{
"sha": "90571786d99166c0039ca2e80e4d9cd96184bd85",
"date": "2026-01-26",
"subject": "feat(canonical): add DuckDB runtime for pipeline stages",
"signals": {
"commit_type": "feat",
"scope": "canonical",
"breaking": false,
"is_releasable_type": true,
"domains_affected": ["pipeline", "data-architecture"]
},
"body": "Establishes DuckDB as canonical in-process analytical database...",
"files_changed": ["packages/canonical/pipelines/stages/duckdb_runtime.py", "..."],
"stats": {"files": 8, "insertions": 450, "deletions": 120}
}
這些訊號有助於引導分類:is_releasable_type: true 顯示這應該出現在變更日誌中;較大的新增行數與基礎架構檔案,則顯示它也可能是一項架構決策。
步驟四:為提交分類
從這裡開始分成兩條路徑:變更日誌條目,以及架構決策。
針對變更日誌條目:
uv run orkestra mine classify abc123 --changelog added
這會記錄提交 abc123 應出現在變更日誌的「新增」類別下。
針對架構決策:
首先,取得一個真實的決策編號:
uv run orkestra decisions new --domain pipeline --dry-run
# Returns: DEC-PL-143
接著使用該決策編號進行分類:
uv run orkestra mine classify abc123 --decision DEC-PL-143
這會將該提交連結到一份即將建立或更新的決策紀錄。
針對批次處理(我們實際採用的方式):
# Generate classifications file with LLM assistance
uv run orkestra mine commit --input classifications.jsonl
JSONL 格式讓兩種領域能一次處理完成:
on
l
{"sha":"abc123","domain":"changelog","action":"release","category":"added","summary":"Add DuckDB runtime for pipeline stages"}
{"sha":"abc123","domain":"decisions","action":"extract","decision_id":"DEC-PL-142"}
{"sha":"def456","domain":"changelog","action":"skip","reason":"Chore: dependency update"}
步驟五:渲染輸出
uv run orkestra changelog render --package <pkg>
這會依帳本內容產生各套件專屬的 CHANGELOG.md 檔案。變更日誌屬於衍生產物 — 就算刪除它們,也能從來源帳本完美重新生成。
決策紀錄的結構
擷取出的決策會化為附帶豐富中繼資料的 YAML 檔案:
id: DEC-PL-142
title: Adopt DuckDB as Canonical Processing Runtime for Pipeline Stages
domain: pipeline
status: active
created: '2026-01-26'
summary: |
Establishes DuckDB as the canonical in-process analytical database for pipeline
stage transformations. Provides a shared runtime module that resolves settings
from pipeline defaults with stage-level overrides.
context: |
Pipeline stages performing data transformations each independently configured
DuckDB connections. This led to inconsistent settings, duplicated configuration
code, and no way to tune DuckDB globally for a pipeline run.
rationale:
- DuckDB provides efficient in-process OLAP with zero configuration deployment
- Centralized runtime module eliminates duplicated DuckDB setup across stages
- Hierarchical settings enable global tuning with stage-level overrides
- Memory limits and thread counts can be adjusted per-pipeline
impact:
positive:
- Consistent DuckDB configuration across all pipeline stages
- Single point of control for memory/thread tuning
- Reduced code duplication in conversion and export stages
negative:
- Adds dependency on shared runtime module
- Stages must adopt new configuration pattern
source_commits:
- sha: 90571786d99166c0039ca2e80e4d9cd96184bd85
message: 'feat(canonical): add DuckDB runtime for pipeline stages'
date: '2026-01-26'
role: primary
files:
- packages/canonical/pipelines/stages/duckdb_runtime.py
- packages/canonical/pipelines/runner.py
- packages/canonical/pipelines/stages/convert_hdx_admin_boundaries_to_geoparquet.py
related:
- DEC-DA-014 # Data architecture decisions that influenced this
每項決策都會回連其來源提交,每項決策都會指明其影響的檔案,決策彼此之間的關係也都明確標示。
CLI 整合:查詢組織記憶
這正是迴圈閉合之處。代理人可以透過 CLI 查詢決策:
# Search by topic
uv run orkestra decisions search --query "retry"
回傳與重試邏輯、錯誤處理、復原模式相關的決策。
# Get full details on a specific decision
uv run orkestra decisions info DEC-PL-142
回傳包含情境、理由與影響的完整決策紀錄。
# List recent decisions for context
uv run orkestra decisions list --limit 15
顯示近期做出了哪些架構抉擇。
代理人如何運用這套機制
我們協調器的基準指令中包含:
**Essential CLI commands:**
- `orkestra decisions search "X"` — Find architectural decisions
當代理人被要求實作與 DuckDB 相關的內容時,它可以先檢查:
uv run orkestra decisions search --query "DuckDB"
並發現 DEC-PL-142,從中了解:
- 我們為何選擇 DuckDB(脈絡)
- 該如何正確使用它(代理人指引)
- 該查看哪些檔案(檔案)
- 有哪些相關決策(相關項目)
代理人不必重新發明輪子,而是能在既有模式的基礎上繼續建構。
三問測試
並非每筆提交都值得建立決策紀錄,我們以「三問測試」來篩選:
- 這個決定當初難做嗎? 是否需要大量分析、取捨評估或討論?
- 改變它的代價高嗎? 若要推翻這項決策,是否需要大幅重做?
- 它是否具有全系統層級的影響? 是否影響多個套件,或建立了其他人將遵循的模式?
只要一筆提交對這三個問題中至少一項回答「是」,就是決策擷取的候選對象。我們的一般比例是:每 100 筆提交約產生 1 到 4 項決策(約 1% 到 4%)。
至於變更日誌條目,門檻較低:任何面向使用者的變更(功能、修正、改善)都會被記錄下來;內部雜務、文件更新與重構通常會被略過。我們的一般比例是:每 100 筆提交約產生 30 到 50 則變更日誌條目。
資料儲存:僅可附加的帳本
挖掘系統採用僅可附加(append-only)的 JSONL 帳本,以支援無衝突的多代理人作業:
packages/orchestration/ai_assets/reference/changelog/
├── commits_processed.jsonl # Classification ledger (both domains)
├── release_notes.jsonl # Changelog entries
└── commits_index.yaml # Derived index (gitignored)
packages/orchestration/ai_assets/reference/decisions/
├── registry.yaml # Decision index
└── records/
├── DEC-AD-001.yaml
├── DEC-AD-002.yaml
└── ...
這種以 merge=union 儲存於 .gitattributes 的 JSONL 格式,代表多個代理人可以同時為提交分類,而不會產生合併衝突 — 每一行都是獨立的。
驗證關卡
在任何一次挖掘作業開始前,我們都會執行驗證:
uv run orkestra mine validate --quick
此驗證會檢查:
- SHA 格式是否有效
- 決策編號格式是否符合規範
- 同一個 SHA 是否有重複項目
- 所參照的決策是否確實存在
分類完成後,我們會在提交變更前再次驗證。
為什麼這很重要
我們建構的這個回饋迴圈,解決了幾項問題:
對新進團隊成員而言: 他們不必再問「我們當初為什麼這麼做?」,而是可以直接搜尋決策登錄檔,脈絡都被完整保留。
對 AI 代理人而言: 它們不必在真空中運作,可以在提出建議前先查詢組織知識。當被要求新增一個 pipeline 階段時,它們能發現 DuckDB 這項模式,並依循它。
對架構一致性而言: 決策是明確且可搜尋的。當有人提出與既有決策相牴觸的做法時,系統能夠揭露這項衝突。
對變更日誌生成而言: 發布說明不再是最後一刻的臨時拼湊,而是開發過程中持續分類所產生的副產品。
對新人上手而言: 新進代理人會繼承程式碼庫的完整脈絡。它們看到的不只是程式碼本身,還有塑造出這些程式碼的種種決策。
目前狀態
截至目前為止:
- 已透過此管線處理 15,637 筆提交
- 已擷取並記錄 476 項架構決策
- 已記錄 6,799 則變更日誌條目
- 兩個領域的涵蓋率皆為 100%
自我們開始執行以來,每一筆提交都已完成分類,組織記憶完整且可查詢。
開始使用
若你想實作類似的機制:
-
從慣例提交格式開始。 當提交具備結構化前綴(
feat:、fix:、chore:)時,挖掘管線的效果最好。 -
定義你的領域。 我們使用像
pipeline、agent-design、observability、data-modeling這樣的領域,用以依區塊整理決策。 -
養成分類的習慣。 當團隊定期為提交分類時,挖掘機制才會奏效;搭配 LLM 協助的批次處理,有助於擴大規模。
-
讓決策可被查詢。 當代理人能透過 CLI 搜尋決策時,其價值會不斷複利累積;請將輸出結構化,以利機器讀取。
-
閉合這個迴圈。 決策應該影響未來的工作,請在代理人指令與程式碼審查檢查清單中納入決策參照。
目標並非追求完美的文件,而是讓變更背後的原因,無論是今天還是六個月後,都能讓人類與 AI 同樣觸手可及。當變更化為組織記憶,團隊便能在既有模式的基礎上持續建構,而不必一再重新發明。
這套挖掘工作流程是我們協調引擎的一部分,具體來說,屬於我們協調套件中的情境引擎模組。
延伸閱讀
更多來自 Maguyva 開發日誌的內容
我們為何將程式碼搜尋升級至 voyage-4-large_
我們將程式碼嵌入模型換成了 voyage-4-large — 目前在公開的 RTEB 程式碼檢索排行榜上排名第一。這是誠實的版本:我們做了什麼取捨、我們實際索引的是什麼,以及我們為何願意為高階嵌入模型付費。
語言遞迴自我改進:在近 280 種語言中打磨程式碼智慧_
我們為近 280 種語言提供程式碼智慧支援,沒有人力能逐一手動稽核。因此我們打造了一套語言遞迴自我改進迴圈 — 抽查、LLM 擔任評審、修正單一問題、重新驗證 — 並以一支隔離代理人艦隊持續執行,直到擷取結果真正正確,而不只是綠燈通過。
多模態融合搜尋:為每個查詢挑選正確的檢索方式_
像「parseConfig 定義在哪裡」這樣的查詢,需要的搜尋方式和「auth 是如何運作的」截然不同。Maguyva 會先分類查詢意圖,據此為四種檢索模式加權,再以加權版的 Reciprocal Rank Fusion(倒數排名融合)演算法整合結果。