對你的程式碼最好的解釋, buried 在聊天記錄裡

你花了 45 分鐘和 Claude 設計一個 retry circuit。你解釋了 failure modes,因為 exponential backoff 會掩蓋 cascading pressure 而拒絕了它,確定了 token-bucket rate limiting with jitter,並生成了一個可執行的實作。解釋很清晰,推理很合理,程式碼也確實通過了測試。

然後你關掉了分頁。

兩週後,一位同事問為什麼 retry logic 使用 jitter 而不是 exponential backoff。你開啟一個新的 Claude session,憑記憶重構論證。新的解釋很接近,但並不完全相同。你創造了第二個略有不同的口頭傳統。兩者都無法被搜尋找到。兩者都無法在 pull request 中 review。兩者都會在你離開公司後消失。

這不是 tooling 的問題。這是一種 category error。我們把 LLM 對話當作 private scratchpads,而實際上它們已經是大多數工程師最接近 literate programming 的東西了。

Knuth 的本意,以及為什麼 LLM 偶然實現了它

Donald Knuth 在 1984 年將 literate programming 定義為將程式作為文學作品來編寫的活動。程式碼和文件被編織進單一的敘事中。讀者跟隨作者的推理,看到被考慮的替代方案,並理解最終形態為何存在。

四十年間,literate programming 始終是一種小眾實踐。WEB 和 CWEB 等工具需要紀律。大多數開發者在一個檔案中寫程式碼,在另一個檔案中寫文件,兩者立即分道揚鑣。

LLM 對話是偶然的 literate programming。你用散文陳述問題。模型提出澄清問題。你 refine constraints。它提出程式碼。你拒絕提議並解釋原因。它修訂。最終產物不僅僅是程式碼區塊。而是整個 thread:被丟棄的方法、trade-offs、domain assumptions。

問題在於 medium 是 ephemeral 的。Chat 介面是為 task completion 設計的,而不是 knowledge preservation。一旦 session 結束,敘事就被 frozen in amber,不可搜尋、無版本控制,且歸 vendor 所有。

為什麼對於複雜決策,聊天記錄勝過傳統文件

傳統文件描述最終狀態。它回答「是什麼」。好的聊天記錄回答「為什麼」,這是更難的問題,也是腐爛最快的問題。

考慮一個典型的 architecture decision record。它可能會說:「我們因為 strong consistency requirements 而為 inventory service 選擇了 PostgreSQL 而不是 DynamoDB。」這是一個結論。它沒有告訴你哪些查詢太慢、哪些 replication lag 是可接受的、哪些 vendor lock-in 被辯論後駁回。

一個 Claude thread 包含所有這些。它包含失敗的 schema iterations、讓你驚訝的 query plans,以及你意識到 composite index 必須 cover status filter 的那個時刻。它是一個帶有完整上下文的 decision record。

問題是上下文被困在對話格式中。翻閱一百個 turn 的 thread 來找到關於 index design 的一個 insight 是痛苦的。知識在那裡,但無法存取。

Chat-as-Docs 的三種失敗模式

將原始聊天記錄當作文件,會以可預測的方式失敗。每種失敗模式都有修復方法,但你需要有意圖地去做。

Hallucination drift。 Claude 會編造 API、引用不存在的論文,並自信地提出忽略你實際 constraints 的設計。作為文件保存的聊天記錄會將 hallucinations 與智慧一同保存。如果你不明確標記哪些部分被驗證過、哪些是推測性的,下一位讀者會把一切當作福音。

Narrative sprawl。 好的對話會蜿蜒。你探索 dead ends,被 edge cases 分散注意力,然後折返。這種蜿蜒對理解有價值,但對參考很糟糕。需要 retry policy 的新工程師不需要讀二十分鐘關於 TCP congestion control 的離題。

Vendor lock-in。 你的文件活在 Anthropic 的資料庫裡,在他們的搜尋介面後面,受他們的 retention policy 約束。如果帳戶過期或介面改變,你的文件就會消失。你無法 grep 的文件不是文件。

如何從 ephemeral chat 中提取持久文件

解決方案是將 chat 視為初稿,而不是最終產物。你提取、驗證並發布。工作流程很簡單,每個重要決策大約需要十分鐘。

第一步:標記 turns。 在對話過程中標記關鍵決策。我使用一個簡單的約定。當 Claude 生成我打算保留的程式碼區塊時,我回覆 KEEP: <一行理由>。當它提出我拒絕的東西時,我回覆 REJECT: <理由>。這些標籤使提取變得 trivial。

第二步:提取到 markdown。 Session 結束後,將 thread 複製到 markdown 檔案中並去除噪音。刪除問候語、「讓我想想」的填充詞,以及你們倆都困惑的 turns。保留問題陳述、被考慮的替代方案、最終決定和驗證過的程式碼。結果應該讀起來像技術筆記,而不是 transcript。

如果你使用 Claude API 或將對話匯出為 JSON,以下腳本可以自動化提取:

#!/usr/bin/env python3
"""
Extract a readable technical note from a Claude conversation export.
Expects Anthropic's conversation JSON format.
"""

import json
import argparse
from pathlib import Path


def extract_note(conversation_path: Path, output_path: Path) -> None:
    with open(conversation_path) as f:
        data = json.load(f)

    turns = data.get("chat_messages", [])
    lines = []

    for turn in turns:
        sender = turn.get("sender", "unknown")
        text = turn.get("text", "").strip()

        if not text:
            continue

        # Skip pleasantries and meta-turns
        if any(phrase in text.lower() for phrase in [
            "hello", "how can i help", "you're welcome", "glad i could help"
        ]):
            continue

        if sender == "human":
            lines.append(f"**Q:** {text}\n")
        else:
            lines.append(f"**A:** {text}\n")

    with open(output_path, "w") as f:
        f.write("# Technical Note: Extracted from Claude Session\n\n")
        f.write("\n".join(lines))


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", type=Path, required=True)
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()
    extract_note(args.input, args.output)

第三步:驗證每個程式碼區塊。 執行提取的程式碼。如果它無法編譯或通過測試,在 markdown 中修復並記錄更正。提取的文件必須是 source of truth,而不是可能包含錯誤的對話 transcript。

第四步:commit 到倉庫。 將 markdown 存放在 docs/decisions/docs/notes/ 中,與其描述的程式碼並列。給它一個有意義的檔案名:retry-circuit-jitter-over-exponential.md,而不是 claude-chat-july-19.md。將其新增到與程式碼變更相同的 pull request 中,或立即開一個 follow-up PR。如果文件不在版本控制中,它就不存在。

什麼時候有效,什麼時候無效

這種方法對於 reasoning 與結果同樣重要的複雜、模糊的決策非常出色。Circuit design、schema migration strategies、API versioning policies 和 performance trade-offs 都是很好的候選。

它不適用於 reference documentation。關於如何認證內部 API 的聊天記錄是 structured OpenAPI spec 和 cURL example 的糟糕替代品。為工作使用正確的工具。

沒有 curation 也行不通。將原始聊天記錄 dump 進 wiki 不是文件。那是囤積。十分鐘的提取和編輯是不可協商的。如果你跳過它們,你生產的是可搜尋的垃圾。

一個實用的起點

你不需要新工具。你需要一個習慣。

下次你與 Claude 就某個 non-trivial design decision 進行了一次漫長而富有成效的 session 時,在關閉分頁之前匯出 thread。花十分鐘將其編輯成回答三個問題的 markdown note:我們在解決什麼問題?我們考慮並拒絕了哪些替代方案?我們決定了什麼,為什麼?

將那個 note commit 到你的 repo。從它描述的函數上方的 code comment 連結到它。下一個接觸那段程式碼的工程師會感謝你,而且不需要開啟 Claude 來重構你的推理。

你與 Claude 的對話可以成為文件。它只需要你像對待程式碼一樣對待它:被提取、被驗證、被版本控制、被維護。