你的 Repo 從來都不是事情的全貌

程式碼只會顯示已存在的東西。真正的原因散落在規格、事故、資料與決策之中。

你的 Repo 從來都不是事情的全貌

在某個功能上線六個月後再打開儲存庫,你依然能重建出很多資訊。你可以追溯架構、檢視 schema、閱讀測試,並精確看出哪些程式碼行被改動過。

但你通常無法重建的,是那些讓這些程式碼行變得必要的對話。

程式碼不會告訴你,某條驗證規則之所以存在,是因為某個客戶會送出格式錯誤的匯出資料。它不會解釋,某個奇怪的重試策略其實是在防止下游系統出現重複交易。它也不會顯示,較乾淨的介面是在無障礙測試後被否決,或某個服務邊界反映的是合約限制,而不是工程上的偏好。

Git 很擅長保存程式碼歷史。只有當團隊刻意把意圖寫下來,並持續與實作保持連結時,它才會保存這些意圖。

這個落差一直都是軟體工程的一部分。AI 程式設計工具讓它變得更明顯。系統可以讀遍儲存庫中的每個檔案、追蹤每個符號,並產出一個在技術上看似很有說服力的 patch,卻仍然解決了錯的問題。

問題不在於程式碼具有誤導性,而在於程式碼回答的是一個更狹窄的問題。

工程真相的五個層次

大多數有意義的軟體變更,都依賴五個不同層次的證據。

  1. 意圖 — 使用者、客戶或業務想達成什麼結果?這可能存在於規格、工單、客服對話或會議筆記中。
  2. 限制條件 — 什麼不能被破壞?相容性承諾、安全邊界、法規、合約、預算與期限,往往都存在於儲存庫之外。
  3. 實作 — 系統目前是如何運作的?程式碼、測試、schema、相依套件與部署設定構成了這一層。
  4. 執行時證據 — 真實系統中正在發生什麼?日誌、追蹤、指標、生產資料與事故報告,可能會推翻那些在程式碼裡看起來合理的假設。
  5. 決策歷史 — 為什麼會選擇目前這種做法?Pull requests、設計討論、被否決的替代方案,以及過去的事故,都握有答案。

儲存庫在第三層最有優勢。它確實包含其他層次的一部分,但很少足以完整呈現它們。

這之所以重要,是因為軟體失敗往往出現在各層之間的邊界。實作符合的是過時的規格。修補滿足了工單,卻違反了營運限制。測試之所以通過,是因為它們編碼的是昨天的假設。程式碼在內部是一致的,但生產資料卻遵循著沒有人記錄下來的模式。

一個在局部看來正確的 patch,仍然可能是錯的變更。

儲存庫本身無法回答的事

試想一位使用者編輯了一份文件,接著搜尋更新後的句子,結果卻只在搜尋結果中看到舊版本。「讓搜尋立即更新」聽起來像是個明確的要求。儲存庫確實揭示了幾個可能的切入點,但它本身無法定義正確的修正方式。

問題 可能的來源
文件的哪個版本才是權威版本? 原始文件與修訂歷史
舊文字還殘留在哪裡? 同步日誌、擷取輸出、搜尋索引或快取
對這個產品來說,「立即」是什麼意思? 產品承諾或服務目標
文件的權限是否隨著內容一起變更? 原始權限與稽核歷史
過時的結果是否只限於某位使用者、某個來源或某個區域? 請求追蹤與正式環境指標

搜尋程式碼或許能解釋結果是如何回傳的,但它無法告訴你,真正的缺陷究竟是同步延遲、擷取內容過時、快取失效、權限傳播問題,還是產品從未定義清楚的預期。

在成熟系統中,這種區別會變得更加重要。看起來已經過時的欄位,可能仍在支援舊版客戶端。看似重複的服務,可能其實是在分隔具有不同權限需求的資料。表面上顯得多餘的檢查,可能是目前團隊從未親歷的某次正式環境事故,在程式碼層面留下的唯一痕跡。

刪除複雜性很有價值。刪掉偽裝成複雜性的歷史,代價卻很高。

即使有更多脈絡,仍可能得出錯誤答案

最直覺的解法,就是給 AI 更多材料:整個儲存庫、每一張工單、每一份文件、每一則訊息,以及每一筆日誌。

這帶來的是存取,不是理解。

來源可能已經過時、彼此矛盾、帶有推測性,或是為不同受眾而寫。腦力激盪內容不應凌駕於已核准的規格之上。六個月前的需求不應悄悄推翻昨天才做出的產品決策。正式環境日誌應該與產生它的版本、環境與程式碼路徑綁定。客戶提出的請求,在未確認適用範圍之前,不應被視為普遍需求。

因此,嚴謹的脈絡系統需要的不只是檢索。它還需要一種方式來推理:

  • 權威性: 哪個來源有資格定義需求?
  • 時效性: 哪些資訊是目前有效的,哪些已被取代?
  • 來源脈絡: 每一項主張、限制或結論是從哪裡來的?
  • 關聯性: 哪些 issue、release、customer、dataset 與 code path 是彼此相關的?
  • 權限: 哪些來源可用於這項任務,並可展示給這個人?

脈絡不是一堆 token。它是一個帶有時間、權威性與邊界的圖譜。

更多脈絡應該帶來更多證據,而不是在沒有證據的情況下帶來更高的信心。

真正的工作單位是變更

編輯器與程式工具是圍繞檔案來組織的,因為檔案是我們修改的對象。工程團隊則是圍繞變更來組織的。

一項變更始於某個原因。它會成為需求,觸及程式碼與資料,經過審查,進入正式環境,並產生新的證據。如果這些階段彼此脫節,未來的每一項任務都得再來一輪考古。

一個處理真實軟體的 AI 系統,應該遵循這個生命週期。

在實作之前,它應該辨識請求內容、相關限制,以及任何彼此衝突的來源。它應該知道自己是在修正缺陷、改變預期行為,還是引入新的契約。

在實作期間,它應該將每一個有意義的選擇都連結到證據。為什麼是這個模組?為什麼採用這種遷移策略?為什麼要保留這個分支?這些說明應該在產生程式碼的那段對話之外,依然能夠留存。

實作完成後,系統應將驗證結果、審查決策,以及新發現的限制條件附加到這次變更上。否則,下一個人——或下一次 AI 工作階段——就必須重新把這些資訊找出來。

這就是只能編輯儲存庫的工具,與能參與工程工作的系統之間的差別。

AI 應該減少重建成本,而不是取代判斷

更好的上下文有時被視為通往自主軟體開發的路徑。但它眼前的價值沒那麼戲劇化,卻更實用:在做出變更之前,降低重建現實狀況的成本。

AI 可以把原始需求帶到相關程式碼旁邊。它可以找出那起事件,說明某個不尋常保護機制為何存在。它可以把失敗的指標連回造成變化的那次發布。它也可以在實作開始前,就指出兩個權威來源彼此不一致。

這些能力不會消除工程判斷。它們會讓判斷建立在更充分的資訊之上。

仍然需要由人來決定哪種取捨可以接受、需求是否完整,以及一次發布可以承擔多少風險。系統應該讓證據可見,讓推理可供檢視,而不是用一個看似漂亮的 patch 掩蓋不確定性。

標準不是「它能產生程式碼嗎?」

標準是「它能解釋為什麼現在這是正確的變更嗎?」

從感知儲存庫到感知工作

程式設計助理最初之所以變得有用,是因為它們能理解開發者眼前的檔案。接下來的重要一步,是具備儲存庫感知能力:找出相關程式碼、追蹤符號,並在整個專案中套用變更。

下一步,是感知儲存庫周圍正在進行的工作。

這意味著要把程式碼連結到提出它的規格、釐清它的對話、對它提出挑戰的生產證據,以及之後應被記住的決策。這也意味著要排除無關、過時,或超出使用者權限範圍的上下文。

在打造 Dvina 的過程中,這是我們反覆回到的一個想法。工作不會只發生在單一檔案、單一應用程式或單一對話裡。意義存在於它們之間的連結,以及那些連結如何隨時間改變。

儲存庫仍然至關重要。它是系統行為可執行的事實來源。只是對於產品意圖、營運現實或組織記憶而言,它並不是完整的事實來源。

完整脈絡會改變最終打造出的東西

如果只有程式碼,自然會問的是:

什麼樣的變更適合這個系統?

有了更廣的上下文後,問題就會變成:

什麼樣的變更適合這個系統、這項需求、這段歷史,以及此刻的情境?

第二個問題能在限制演變成回歸之前,先把它們揪出來。它讓審查者理解實作背後的推理。它也幫助新加入的團隊成員明白,為什麼系統會長成現在這個樣子。它也為 AI 賦予一個立足於事實的角色:不是編輯器裡的神諭,而是能在整個工作脈絡中彙整證據的參與者。

你的 repo 從來都不是故事的全部。

真正的機會,在於打造能讀懂其餘部分的系統——而且還能把推理過程攤開來看。

加入 Dvina

免費註冊,將你所有工具整合到一個簡潔的工作空間。

探索更多


我們只會收集維持服務順暢運作所必需的分析資料。