From 7a58f37d9f2492a22ca270da829434ea081318c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E7=91=AA=E8=B2=93?= Date: Tue, 4 Aug 2026 17:22:52 +0800 Subject: [PATCH] Record the natural-coding pipeline design in the project documents Co-Authored-By: Claude Fable 5 --- CLAUDE.md | 27 ++++++++----- docs/decision-log.md | 51 ++++++++++++++++++++++++ docs/project-structure.md | 13 +++--- docs/research-plan.md | 83 ++++++++++++++++++++++++++++++++++----- 4 files changed, 149 insertions(+), 25 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 21a3713..181da6c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,17 +5,24 @@ - LLM analysis runs via Python scripts calling the Anthropic Messages API: model `claude-sonnet-4-6`, `temperature=0`, thinking disabled, Batch API where possible. -- Prompt definition files live in `prompts/-v.md` and - are passed verbatim as the system prompt. -- Every LLM step runs the same definition file twice, then a - separate arbitration step reconciles the two outputs - ("2 runs + 1 arbitration"). If arbitration output is - unexpected, revise the definition file and repeat the whole - cycle; never patch results by hand. -- Every execution is archived self-contained under - `runs//-/`: prompt snapshot, +- Prompt definition files live in + `prompts/--.md` (e.g. 01-01-tag.md; no + version suffix -- versions live in git history) and are + passed verbatim as the system prompt. +- LLM steps whose outputs are item-by-item comparable + (convergence, coding) run the same definition file twice, + then a separate arbitration step settles only the + script-computed disagreements ("2 runs + 1 arbitration"). + Free-generation steps run twice and both outputs are pooled, + unarbitrated. If arbitration output is unexpected, revise + the definition file and repeat that cycle; never patch + results by hand. +- The current execution of each step is archived + self-contained under + `runs//`: prompt snapshot, raw outputs of both runs, arbitration output, and `meta.json` - (model ID, parameters, timestamps, batch IDs). + (model ID, parameters, timestamps, batch IDs). A rerun + replaces the directory; superseded runs live in git history. - Scripts read the API key from the `ANTHROPIC_API_KEY` environment variable (`.env`, gitignored). diff --git a/docs/decision-log.md b/docs/decision-log.md index 4273ca6..e01a7cd 100644 --- a/docs/decision-log.md +++ b/docs/decision-log.md @@ -253,3 +253,54 @@ (config/database/models/utils)留頂層。理由:「指令 vs 共用底層」由目錄結構直接表達,與「哪個函式屬哪個工作」 的歸屬原則同型。 +- **自然編碼管線四步驟定案**:自由標註(tag,×2 全進池不 + 仲裁——自由詞彙兩次輸出無共享比對單位,仲裁即再生成)→ + 自然收斂(merge,2+1)→ 強制收斂至 50 內(cap,2+1)→ + 以定稿詞彙表全量編碼(code,2+1,附引述,逐首仲裁看 + 歌詞)。收斂步驟不看歌詞(目標是產生 codebook 而非編 + 碼);收斂仲裁的紀律:程式先算共識核(凍結)與分歧清 + 單,仲裁只裁分歧、不得引入新概念。編碼回歸採 LLM 直接 + 編碼為主儀器,理由:唯此能逐標籤附歌詞引述(偏差檢視的 + 依據)、標籤是模型對歌曲的直接斷言(批判對象乾淨、不混 + 收斂軌跡假影)、詞彙表出自模型自身故無語意干涉;軌跡 + 機械對映降為診斷副產品。此設計為對前導研究「映回後未 + 對照歌詞」限制的明文改良。 +- **2+1 協定適用原則重述**:由「每個 LLM 步驟」修正為 + 「輸出可逐項機械比對的步驟」;自由生成步驟改為兩次執行 + 進池。CLAUDE.md 同步修訂。理由:自由詞彙步驟強行仲裁 + 等於第三次生成,無稽核意義;可比步驟的一致率(逐詞塊、 + 逐首)才是有定義的穩定性證據。 +- **提示詞只定格式、不定語意**:LLM 定義檔不含任何主題 + 定義、判準、範例;研究者判準只住 codebook。理由:研究 + 對象是模型以網路語料知識背景所做的自然編碼,先給定義 + 即消毒了批判對象。此原則之落實:粒度鎖定 thematic + keywords(前導研究三粒度比較之繼承,執行前鎖定防事後 + 擇優);收斂輸入不附頻次(頻率的分析角色由編碼步驟承 + 擔;頻次誘使頻率剪枝與高頻主題細分)。引述歌詞證據為 + 必要輸出——檢視編碼偏差的依據,不屬語意干涉。 +- **「女性力量」單目標篩選降級為取樣補漏網**:候選集由 + 自然編碼(code 步驟)浮現;單目標篩選僅用於把模型「被 + 明示提醒後認得出」的歌撈進人工審視範圍,量測漏標方向 + 的偏差,不進偏差統計的定義。「全編碼+標籤詞提示」混合設計 + 取消——既非自然編碼亦非深度判準,量到的東西 + 無法解釋。screen 逐首 2+1、不給定義,標籤詞用 + `women-power-and-empowerment`。認清:此編碼是任意的—— + 基於研究目的由研究者決定,不是由資料產生(先導研究中的 + 來歷已不可考,不宣稱由下而上湧現)。選用理由:複合詞 + 同時涵蓋力量宣示與賦權論述兩半概念空間,補漏網寧廣勿 + 窄;「empowerment」正是研究對象的市場語彙;不押注單一 + 時代慣用語。同義詞清單不採——每多一詞即研究者多塑形 + 一分。已知限制:雙管詞語意模糊(無從分辨觸發自哪半), + 僅作召回之用,結果永不進統計的分子分母。標籤詞是 + screen 提示中唯一的語意種子,屬研究者的儀器選擇,據實 + 揭露。 +- **定義檔命名定案:軌-步前綴、不帶版本號**: + `prompts/<軌>-<步>-.md`——軌 01=由下而上自然編碼、 + 02=預先決定的 women-power-and-empowerment 篩選: + 01-01-tag、01-02-merge、01-03-cap、01-04-code、 + 02-01-screen;仲裁檔同 prefix 加 `-arb`。檔名不帶版本 + 號——版本即 git 歷史,失敗的版本不保留;每次執行的定義 + 檔快照隨 runs/ 自我完備,`runs/` 目錄改為 + `<定義檔名>/`——同理不編日期:只存一份,重跑即取代, + 被取代的執行在 git 歷史,時間戳在 meta.json。四次收斂執行(merge ×2、cap ×2) + 各存合併記錄 JSON 隨該次執行入 runs/。 diff --git a/docs/project-structure.md b/docs/project-structure.md index 0331b62..ad1074f 100644 --- a/docs/project-structure.md +++ b/docs/project-structure.md @@ -24,7 +24,8 @@ pop-fem-audit/ │ ├── songs.csv # 歌曲報表(人讀;進 git) │ └── artists.csv # 歌手報表(人讀;進 git) ├── prompts/ # LLM 定義檔(逐字作為 system prompt) -│ └── -v.md # 版本化:screen-v1.md、judge-v2.md… +│ └── <軌>-<步>-.md # 01-01-tag.md、02-01-screen.md… +│ # 不帶版本號,版本即 git 歷史 ├── tools/ # 輔助工具子專案(src-layout) │ ├── pyproject.toml # 發行名 pop-fem-audit-tools; │ │ # pip install -e tools/ 安裝 @@ -52,8 +53,9 @@ pop-fem-audit/ │ │ ├── models.py # SQLAlchemy ORM 資料模型 │ │ └── utils.py # 共用工具(format_duration) │ └── tests/ # 單元測試(unittest) -├── runs/ # 每次執行的完整稽核紀錄(進 git) -│ └── <階段>/<日期>-<定義檔版本>/ +├── runs/ # 現行執行的完整稽核紀錄(進 git; +│ │ # 重跑即取代,舊執行在 git 歷史) +│ └── <定義檔名>/ │ ├── prompt.md # 當次定義檔快照(自我完備) │ ├── run1.jsonl # 第一次執行原始輸出 │ ├── run2.jsonl # 第二次執行原始輸出 @@ -80,8 +82,9 @@ pop-fem-audit/ meta,讀者不需 git 考古即可稽核任一筆結果。 - **`runs/`(原始稽核資料)與 `results/`(最終表)分離**: 論文只引 `results/`,其來源可回溯至 `runs/`。 -- **`prompts/` 用檔名版本化**(不只靠 git 歷史):定義檔版本是 - 論文附錄的引用單位,須可直接指名(如 judge-v2.md)。 +- **`prompts/` 檔名不帶版本號**:版本即 git 歷史,失敗的 + 版本不保留;論文引用的單位是 `runs/` 內隨執行保存的定義檔 + 快照(每個執行目錄自我完備),不需檔名可指的版本名。 - **Commit 判準**:能由「committed 輸入+程式」決定性再生者不 commit(SQLite 工作儲存、LLM 輸入檔);源頭、捕捉、人工著作 一律以文字 commit。「可再生仍 commit」的例外有二: diff --git a/docs/research-plan.md b/docs/research-plan.md index cac106c..a8b406c 100644 --- a/docs/research-plan.md +++ b/docs/research-plan.md @@ -13,8 +13,17 @@ - **執行原則**:主會話只做討論;所有分析由 deterministic script 執行。LLM 步驟以 Python script 呼叫 Anthropic Messages API (個人 Console 帳號、Batch API 五折),定義檔逐字作為 system - prompt。每個 LLM 步驟「同一定義檔獨立執行兩次 + 一次仲裁」 - (2+1),仲裁結果不符預期則修訂定義檔重跑整個循環。 + prompt。2+1 協定依輸出可比性適用:輸出可逐項機械比對的步驟 + (收斂、編碼)「同一定義檔獨立執行兩次+一次仲裁」,仲裁 + 只裁程式算出的分歧清單;自由生成步驟(首步自由標註)兩次 + 執行全數進池、不仲裁——自由詞彙兩次輸出不共享比對單位, + 無物可裁。仲裁結果不符預期則修訂定義檔重跑該循環。 +- **提示詞只定格式、不定語意**:研究對象是通用 LLM 以其 + 網路語料知識背景所做的自然編碼,編碼結果本身是批判對象。 + LLM 定義檔只規定任務形狀(輸入、數量範圍、輸出格式), + 不給任何主題的定義、判準或範例;研究者的深度判準只寫在 + codebook(人工黃金標準用),兩者不互相滲透。LLM 編碼 + 一律要求逐標籤引述歌詞原句,作為檢視編碼偏差的依據。 - **模型**:`claude-sonnet-4-6`、temperature=0、thinking 關閉 (此組合非決定性最低、成本合理)。條件 A/B 盲點實驗為 自足設計:同語料、同模型、僅提示不同,對照黃金標準。 @@ -56,7 +65,7 @@ 建置失敗。 - **歌手背景防火牆**:歌手背景資料只進人工解讀階段(證據表、 論文討論),**絕不進 LLM 輸入**——LLM 分類的 user message - 維持歌詞-only,避免光環偏誤污染條件 A/B 實驗。women-power + 維持歌詞-only,避免光環偏誤污染條件 A/B 實驗。「女性力量」 候選歌曲的歌手另做深度背景(族裔以公開自我認同為準、音樂 場景),script 輔助、人工核定。 - **Pilot 歌詞沿用(私人匯入,不進發布管線)**:先導研究 @@ -74,19 +83,73 @@ `export-llm-input`(階段 2 前補上);之後再加報表 export 與統計。 +## 自然編碼管線(2026-08-04 定案) + +主題編碼採四步驟管線,歌詞只出現在第 1、4 步;第 2、3 步 +是純概念整理(目標是產生 codebook 詞彙表,不是編碼)。 + +1. **自由標註(tag)**:逐首歌請模型標註 thematic + keywords,附歌詞引述;提示零語意內容。獨立執行兩次, + 兩次輸出全數進池(記錄執行別),不仲裁。粒度鎖定 + thematic keywords:前導研究三粒度比較(keywords 過碎、 + themes 過早抽象)之繼承,於執行前鎖定,防止事後擇優。 +2. **自然收斂(merge)**:輸入為池中純去重關鍵字清單—— + 無歌詞、無頻次、無歌曲出處——模型按自身理解合併近似 + 概念。2+1:兩次收斂處理同一批輸入詞,程式先算出共識核 + (兩次都同組的詞塊,機械凍結)與分歧清單,仲裁者只裁 + 分歧清單,無權動共識核、無權引入新概念。 +3. **強制收斂(cap)**:同第 2 步形態,限制併至 50 個 + 以內。頻次不入收斂:頻率的分析角色由第 4 步編碼承擔; + 池中頻次含跨執行噪音;頻次會誘使模型以頻率剪枝(喪失 + 稀有主題)並把高頻大主題切細。代價(特異主題佔名額) + 已知並接受,換取主題多樣性與純語意歸併的可辯護性。 +4. **編碼(code)**:以定稿詞彙表對全部歌曲 2+1 編碼—— + 模型讀歌詞、逐標籤附引述;逐首計一致率,分歧逐首仲裁 + (仲裁者看歌詞與兩邊引述)。此為主儀器,「女性力量」 + 候選集由此浮現;亦是對前導研究「映回後未對照歌詞」 + 限制的明文改良。沿收斂軌跡的機械對映(純程式)保留為 + 零成本診斷副產品,量測收斂軌跡的扭曲,不作主結果。 + +另設**「女性力量」單目標篩選(screen)**:單目標提示、 +附引述、全量執行,僅作為黃金標準取樣的補漏網——把「模型 +被明示提醒後認得出」的歌撈進人工審視範圍,以量測模型漏標 +方向的偏差;不進偏差統計的分子分母定義。逐首 2+1(有/無 ++引述,逐首仲裁);同樣不給定義,提示僅含標籤詞與任務 +形狀。標籤詞用 `women-power-and-empowerment`。認清:此 +編碼是**任意的**——基於研究目的由研究者決定,不是由資料 +產生(其在先導研究中的來歷已不可考,不宣稱由下而上 +湧現)。選用理由:複合詞同時涵蓋力量宣示與賦權論述兩半 +概念空間,補漏網寧廣勿窄;「empowerment」正是研究對象的 +市場語彙;複合形式不押注單一時代的慣用語。同義詞清單的 +替代案不採——每多一詞即研究者多塑形一分。已知限制: +雙管詞語意模糊(無從分辨一首歌觸發自哪半概念),故僅作 +召回之用,其結果永不進任何統計的分子分母。標籤詞是 +screen 提示中唯一的語意種子,屬研究者的儀器選擇,據實 +揭露。 + +定義檔命名 `prompts/<軌>-<步>-.md`——軌 01=由下 +而上自然編碼、02=預先決定的 women-power-and-empowerment +篩選,步為軌內步驟序:01-01-tag.md、01-02-merge.md、 +01-03-cap.md、01-04-code.md、02-01-screen.md;仲裁定義檔 +同 prefix 加 `-arb`(如 01-02-merge-arb.md)。檔名不帶 +版本號——版本即 git 歷史,失敗的版本不保留,需要回看的 +舊版都在 git history;每次執行的定義檔快照隨 `runs/` +自我完備。四次收斂執行(merge ×2、cap ×2)各將合併記錄 +(哪些詞併入哪組)存成 JSON,隨該次執行入 `runs/`。 + ## 階段與時程(全文截稿 2026-08-15) | 階段 | 內容 | 方式 | 時程 | |---|---|---|---| | 0 | 基礎建設:git init、目錄結構、.gitignore、決策日誌、runner script(含 Batch API)、codebook v0 骨架 | script + 討論 | 7/30–7/31 | | 1 | 資料準備:`run_llm` 改走統一設定 → `build-db`(解析榜單成 songs/chart_entries/artists/song_artists)→ `import-lyrics`(pilot 2018–2025)→ `fetch-lyrics`(2016–17 與缺漏,Lyrics.ovh / LRCLIB)→ `fetch-artists`(Wikidata 快照)→ `export-llm-input` | 子命令 | 7/31–8/3 | -| 2 | 候選篩選:全部唯一歌曲高召回 women-power 候選篩選(寧可多抓,人工剔除) | API 2+1 | 8/2–8/3 | -| 3 | 黃金標準:依 codebook 人工逐首判定 genuine/peripheral/fake,附引用歌詞證據表(LLM 只做摘錄,不給判定建議);先以 10–15 首校準樣本試編並修訂 codebook 後凍結;同批校準樣本實測 Sonnet 4.6 vs Opus 5 一致率 | 人工 + script 輔助 | 8/4–8/8 | -| 4 | 受控比較(盲點實驗):條件 A(詞彙層提示)vs 條件 B(框架感知提示),各 2+1,對照黃金標準計算假陽/假陰率 | API | 8/6–8/9 | -| 4' | 由下而上歸納輪:LLM 對候選歌曲做無理論主題編碼(定義檔不含女性主義詞彙),與黃金標準做映射分析(交叉表;分析方法先寫入 methodology.md 再看結果) | API 2+1 + script | 與 4 並行 | -| 5 | pussy 修辭分析:script 找含詞歌曲 → LLM 分類(METONYM/ANATOMICAL/COWARD/OTHER + 說話者/指涉對象)2+1 → 人工核定 | script + API | 8/8–8/10 | -| 6 | 統計與圖表:一致率(kappa)、污染率、類型分布、年度趨勢、映射交叉表 | scripts | 8/10–8/11 | -| 7 | 撰寫全文+內部審稿(subagent 以審稿人視角挑毛病,特別是嘻哈女性主義/respectability politics 一題) | 討論 + subagent | 8/10–8/14 | +| 2 | 自然編碼管線:tag ×2 進池 → merge 2+1 → cap 2+1 → 詞彙表定稿 → code 2+1(全 883 首,附引述);另跑 screen 補漏網 | API + script | 8/4–8/7 | +| 3 | 黃金標準:依 codebook 人工逐首判定 genuine/peripheral/fake,附引用歌詞證據表(LLM 只做摘錄,不給判定建議);先以 10–15 首校準樣本試編並修訂 codebook 後凍結;同批校準樣本實測 Sonnet 4.6 vs Opus 5 一致率 | 人工 + script 輔助 | 8/5–8/9 | +| 4 | 受控比較(盲點實驗):條件 A(詞彙層提示)vs 條件 B(框架感知提示),各 2+1,對照黃金標準計算假陽/假陰率 | API | 8/8–8/11 | +| 4' | 映射分析:自然編碼結果(第 4 步)與黃金標準交叉表;軌跡對映 vs 直接編碼的扭曲診斷(分析方法先寫入 methodology.md 再看結果) | script | 與 4 並行 | +| 5 | pussy 修辭分析:script 找含詞歌曲 → LLM 分類(METONYM/ANATOMICAL/COWARD/OTHER + 說話者/指涉對象)2+1 → 人工核定 | script + API | 8/9–8/11 | +| 6 | 統計與圖表:一致率(kappa)、污染率、類型分布、年度趨勢、映射交叉表 | scripts | 8/11–8/12 | +| 7 | 撰寫全文+內部審稿(subagent 以審稿人視角挑毛病,特別是嘻哈女性主義/respectability politics 一題) | 討論 + subagent | 8/11–8/14 | 關鍵路徑:階段 3 人工編碼(僅研究者本人可做),排週末與晚間分批。