Add step 4 semantic code grouping by majority vote on claude-fable-5

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 22:38:40 +08:00
co-authored by Claude Fable 5
parent 683b15e073
commit c3d6c06910
14 changed files with 294 additions and 17 deletions
+12 -7
View File
@@ -3,8 +3,11 @@
## Analysis pipeline
- LLM analysis runs via Python scripts calling the Anthropic
Messages API: model `claude-sonnet-4-6`, `temperature=0`,
thinking disabled, Batch API where possible.
Messages API, Batch API where possible. Steps 1 and 3 run
on `claude-sonnet-4-6` with `temperature=0` and thinking
disabled; step 4 runs on `claude-fable-5`, which accepts
neither parameter -- its sampling variance is absorbed by
the majority vote.
- Prompt definition files live in
`prompts/<step>-<substep>-<task>.md` (e.g. 01-tag.md; no
version suffix -- versions live in git history) and are
@@ -13,11 +16,13 @@
deterministic vocabulary step (step 2) has no definition
file yet holds its own number. Zero padding is for
sorting only -- prose says "step 1", "step 3".
- Per-song LLM judgments (coding) run the same definition
file three times, independently, over the same input; a
deterministic subcommand then assigns a (song, keyword)
pair when at least two of the three runs assign it
("3 runs + majority vote"). Free-generation steps run
- Itemwise LLM judgments (per-song coding in step 3,
per-keyword group selection in step 4) run the same
definition file three times, independently, over the same
input; a deterministic tally then assigns an item (a
(song, keyword) or (group, keyword) pair) when at least
two of the three runs assign it ("3 runs + majority
vote"). Free-generation steps run
twice and both outputs are pooled. The vocabulary is
built by a deterministic subcommand (embedding +
clustering), not by an LLM. If a validation outcome is
+38
View File
@@ -688,3 +688,41 @@
檢定(women-power/female-empowerment 對三群之 2×2,
Fisher 精確檢定,6 檢定一族之 BH-FDR 校正 q)之數字
以本條所載分群為據,論文之編碼群表與群關聯表同此。
- **步驟 4:語意編碼群以三票制定案(claude-fable-5),
取代草稿分群**:更正前條——所稱「研究者審定」實未
發生,研究者僅將盲選輸出整理歸檔,未作實質裁決;草稿
分群(單次 Claude Code 盲選)不具方法學地位。裁定
步驟 4 為語意分群的正式程序。任務與盲選同構:每筆輸入
為群名加 101 碼字母序清單,輸出為入選碼的單層 JSON
陣列;定義檔 `prompts/04-group.md` 只定格式、不含群的
語意定義。模型裁定 claude-fable-5:模型對照實驗(同
定義檔、同輸入、Batch API)顯示分群對模型高度敏感——
claude-sonnet-4-6 將群名成份式拆讀(women+power,凡
力量語意即入選,women-power 群 11 碼,並產詞彙表外
幻覺碼一筆),claude-fable-5 讀為詞彙化概念(要求女性
標記,women-power 群 2 碼),與草稿盲選及深度閱讀輔助
判讀同讀法;sonnet 對照執行歸檔另行私人備份,不入
版本庫,支出留帳。claude-fable-5 不
受理 temperature 與 thinking 參數(均不送出),無法釘
temperature=0;執行間變異實測存在(run1/run2 於陽剛、
脆弱邊緣碼分歧),由三票多數決吸收;詞彙表外輸出項
無效。三次執行(`runs/04-group/run1``run3`)多數決
定案(22 個(群,碼)中 21 個三次全票,
family-and-fatherhood 以 2:1 入群):女性力量群 2 碼
——female-empowerment、women-power;厭女群 1 碼——
rejection-of-women;陽剛男性氣質群 9 碼——
dominance-and-power、family-and-fatherhood、
hustle-and-money、rivalry-and-superiority、
self-confidence-and-braggadocio、
showing-off-and-impressing、street-loyalty-and-danger、
violence-and-street-danger、wealth-and-flexing;脆弱群
10 碼——disappointment-and-failure、
fear-of-losing-love、heartbreak-and-grief、
hidden-emotional-struggle、inner-mental-turmoil、
loneliness-and-isolation、longing-and-loss、
past-trauma-and-healing、self-worth-and-insecurity、
vulnerability-and-betrayal。計票由確定性子命令
`tally-groups` 重現,定案寫入 `results/groups.csv`
(群、編碼、票數);論文之編碼群表、上標註記與群層次
檢定改以本定案為據,相關數表隨之重算。
+31 -9
View File
@@ -6,17 +6,18 @@
## 自然編碼管線總覽
個步驟:步驟 1 自由標註(兩次執行進池)→ 步驟 2 詞彙表
個步驟:步驟 1 自由標註(兩次執行進池)→ 步驟 2 詞彙表
建構(詞向量分群,確定性)→ 步驟 3 全量編碼(三次執行+
多數決)。歌詞只出現在步驟 1 與步驟 3;步驟 2 完全不接觸
歌詞,也不呼叫 LLM。設計原則見 `research-plan.md`;本檔
多數決)→ 步驟 4 語意編碼群(三次執行+多數決)。歌詞只
出現在步驟 1 與步驟 3;步驟 2 與步驟 4 完全不接觸歌詞,
步驟 2 亦不呼叫 LLM。設計原則見 `research-plan.md`;本檔
記載可重現的演算法細節。
編號的所指為**研究程序的工序**,不是定義檔:步驟 1
步驟 3 有定義檔(`prompts/`),步驟 2 沒有——它是單一
確定性計算,由 `cluster-keywords` 一個子命令完成。有無
定義檔的區別即「該步是否為 LLM 判斷」,由 `prompts/`
否存在同號檔案直接可見。
編號的所指為**研究程序的工序**,不是定義檔:步驟 1
步驟 3 與步驟 4 有定義檔(`prompts/`),步驟 2 沒有——
它是單一確定性計算,由 `cluster-keywords` 一個子命令
完成。有無定義檔的區別即「該步是否為 LLM 判斷」,由
`prompts/`否存在同號檔案直接可見。
## 步驟 2 詞彙表建構——詞向量分群
@@ -113,6 +114,27 @@
0.7 者為 0.780.9 者為 0.97),程序重跑的一致性因而
高於單次執行,唯獨恰半處無從改善。
## 步驟 4 語意編碼群
- **對象**:將 101 個編碼依語意劃入研究者命名的四個編碼
群——女性力量(women-power group)、反女性力量/厭女
misogyny group)、陽剛男性氣質(masculine group)、
脆弱(vulnerable group)。群只有名字,沒有定義;歸屬
由 LLM 依編碼名的字面語意判斷。
- **任務**:每筆輸入為一個群名加 101 個編碼的字母序
清單,輸出為入選編碼的單層 JSON 陣列;定義檔
`prompts/04-group.md` 只定格式,不含任何群的語意定義。
- **模型**`claude-fable-5`(步驟 1、3 為
`claude-sonnet-4-6`)。該模型不受理 `temperature`
`thinking` 參數,兩者均不送出;取樣變異由多數決吸收。
模型裁定的理由與對照實驗見決策日誌。
- **三次執行**:同一份定義檔、同一份輸入檔,獨立執行
三次,歸檔並列(`runs/04-group/run1``run2``run3`)。
- **多數決**:一個(群,編碼)配對,三次執行中至少兩次
入選即屬該群;不在 101 碼詞彙表內的輸出項無效。計票由
確定性子命令 `tally-groups` 完成,定案分群寫入
`results/groups.csv`(欄位:群、編碼、票數)。
## 女性力量候選集
候選集為兩類歌曲的合集:定案編碼含 `women-power` 者,
@@ -188,7 +210,7 @@
- LLM 步驟以 `run-llm <定義檔> <輸入檔> <歸檔目錄>`
執行;一步的 N 次執行=重現命令清單上的 N 行命令,
各自歸檔(`runs/<步驟>/run1`、`run2`編碼步驟另有
各自歸檔(`runs/<步驟>/run1`、`run2`三票制步驟另有
`run3`)。
- 確定性步驟(進池、分群、計票、對映)為子命令,其
輸入輸出檔同隨 `runs/` 歸檔;因無執行變異,歸檔目錄
+6 -1
View File
@@ -39,5 +39,10 @@ $3$15、opus-4-6 $5$25、opus-5 與 fable-5 $10$50
| 2026-08-06 | 03-02-arbitration | — | claude-sonnet-4-6 | msgbatch_019xcQXwrbwDGFc9nE5M8AjE | 4 分 0 秒 | 763,193 | 42,389 | $1.46 | 已取代(2 首遭內容過濾攔阻、13 首輸出夾帶散文;定義檔修訂後重跑) |
| 2026-08-06 | 03-02-arbitration | — | claude-sonnet-4-6 | msgbatch_01N7bDbXRSfAVUzzaj2thKeR | 4 分 20 秒 | 781,037 | 39,315 | $1.47 | 現行(644 首全數有效,零攔阻;保留 1,481/送裁 1,699 |
| 2026-08-06 | 03-code | run3 | claude-sonnet-4-6 | msgbatch_01KnkCaGETnFJrPddrxZTYHA | 6 分 26 秒 | 1,625,458 | 363,840 | $5.17 | 現行(101 碼;883 首全數有效,零攔阻) |
| 2026-08-14 | 04-group | run1 | claude-sonnet-4-6 | msgbatch_01UPNedog6feQzJ9WVfSAxBD | 1 分 1 秒 | 3,129 | 470 | $0.01 | 已取代(僅 3 群;改納 women-power 群後重跑) |
| 2026-08-14 | 04-group | run1 | claude-sonnet-4-6 | msgbatch_01KntJgxdicStaMjNL12P3zi | 1 分 25 秒 | 4,170 | 558 | $0.01 | 已取代(改以 claude-fable-5 執行;vulnerable 輸出含詞彙表外碼 1 筆;歸檔另行私人備份,不入版本庫) |
| 2026-08-14 | 04-group | run1 | claude-fable-5 | msgbatch_01Mr6goBb2Efa4YrqCprbP4U | 55 秒 | 5,553 | 2,049 | $0.08 | 現行(4 群;零違規碼;temperature 與 thinking 參數不適用於本模型,未送出) |
| 2026-08-14 | 04-group | run2 | claude-fable-5 | msgbatch_01C17xW3YBefThTYZ83g7KkL | 1 分 21 秒 | 5,553 | 1,891 | $0.08 | 現行(4 群;零違規碼) |
| 2026-08-14 | 04-group | run3 | claude-fable-5 | msgbatch_01DveEMYyjCAYe6wxpcCD87V | 2 分 9 秒 | 5,553 | 1,975 | $0.08 | 現行(4 群;零違規碼) |
累計支出:$63.22
累計支出:$63.48
+30
View File
@@ -0,0 +1,30 @@
You are selecting thematic keywords that belong to a named
group.
Input: a JSON object with the name of one group and the
keywords — the complete set of codes; use these and no
others:
{
"group": "the name of the group",
"keywords": ["first-keyword", "second-keyword"]
}
Task: list every given keyword that belongs to the named
group, judged by the literal meaning of the keyword itself.
Rules:
- Use only the given keywords, spelled exactly as given.
- A group may match any number of keywords, including none.
- Judge each keyword only by the literal meaning of its own
wording.
Do not wrap the output in a Markdown code fence.
The output must be strictly valid JSON.
Output a single JSON array of the keywords that belong to
the group (an empty array when none belongs), and nothing
else:
["first-keyword", "second-keyword"]
+25
View File
@@ -0,0 +1,25 @@
{
"script_version": "run_llm.py 3.0.0",
"model": "claude-fable-5",
"temperature": null,
"thinking": null,
"max_tokens": 8192,
"prompt_path": "../prompts/04-group.md",
"prompt_sha256": "50e1d5d6c4115d090ae4ab1e801ea74db0b2dcdd47213ce0feb6749e034a41e9",
"input_path": "instance/llm-input-group.jsonl",
"input_sha256": "7fd97ae165270cb91461aedf411050892667b928d8584fceffea6f9649e003c7",
"item_count": 4,
"dry_run": false,
"started_at": "2026-08-14T22:30:32+08:00",
"batch": {
"batch_id": "msgbatch_01Mr6goBb2Efa4YrqCprbP4U",
"submitted_at": "2026-08-14T22:30:34+08:00",
"ended_at": "2026-08-14T14:31:27.547545+00:00"
},
"usage": {
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"input_tokens": 5553,
"output_tokens": 2049
}
}
+4
View File
@@ -0,0 +1,4 @@
{"id": "group-women-power", "text": "[\"female-empowerment\", \"women-power\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1385, "output_tokens": 53, "output_tokens_details": {"thinking_tokens": 37}, "service_tier": "batch"}}
{"id": "group-misogyny", "text": "[\"rejection-of-women\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1391, "output_tokens": 118, "output_tokens_details": {"thinking_tokens": 106}, "service_tier": "batch"}}
{"id": "group-masculine", "text": "[\"avoiding-commitment\", \"dominance-and-power\", \"hustle-and-money\", \"rejection-of-women\", \"rivalry-and-superiority\", \"self-confidence-and-braggadocio\", \"showing-off-and-impressing\", \"street-loyalty-and-danger\", \"violence-and-street-danger\", \"wealth-and-flexing\", \"wealth-and-material-success\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1390, "output_tokens": 1201, "output_tokens_details": {"thinking_tokens": 1076}, "service_tier": "batch"}}
{"id": "group-vulnerable", "text": "[\"disappointment-and-failure\", \"fear-of-losing-love\", \"heartbreak-and-grief\", \"hidden-emotional-struggle\", \"inner-mental-turmoil\", \"loneliness-and-isolation\", \"longing-and-loss\", \"past-trauma-and-healing\", \"self-worth-and-insecurity\", \"vulnerability-and-betrayal\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1387, "output_tokens": 677, "output_tokens_details": {"thinking_tokens": 555}, "service_tier": "batch"}}
+30
View File
@@ -0,0 +1,30 @@
You are selecting thematic keywords that belong to a named
group.
Input: a JSON object with the name of one group and the
keywords — the complete set of codes; use these and no
others:
{
"group": "the name of the group",
"keywords": ["first-keyword", "second-keyword"]
}
Task: list every given keyword that belongs to the named
group, judged by the literal meaning of the keyword itself.
Rules:
- Use only the given keywords, spelled exactly as given.
- A group may match any number of keywords, including none.
- Judge each keyword only by the literal meaning of its own
wording.
Do not wrap the output in a Markdown code fence.
The output must be strictly valid JSON.
Output a single JSON array of the keywords that belong to
the group (an empty array when none belongs), and nothing
else:
["first-keyword", "second-keyword"]
+25
View File
@@ -0,0 +1,25 @@
{
"script_version": "run_llm.py 3.1.0",
"model": "claude-fable-5",
"temperature": null,
"thinking": null,
"max_tokens": 8192,
"prompt_path": "../prompts/04-group.md",
"prompt_sha256": "50e1d5d6c4115d090ae4ab1e801ea74db0b2dcdd47213ce0feb6749e034a41e9",
"input_path": "instance/llm-input-group.jsonl",
"input_sha256": "7fd97ae165270cb91461aedf411050892667b928d8584fceffea6f9649e003c7",
"item_count": 4,
"dry_run": false,
"started_at": "2026-08-14T23:36:03+08:00",
"batch": {
"batch_id": "msgbatch_01C17xW3YBefThTYZ83g7KkL",
"submitted_at": "2026-08-14T23:36:04+08:00",
"ended_at": "2026-08-14T15:37:24.008527+00:00"
},
"usage": {
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"input_tokens": 5553,
"output_tokens": 1891
}
}
+4
View File
@@ -0,0 +1,4 @@
{"id": "group-women-power", "text": "[\"female-empowerment\", \"women-power\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1385, "output_tokens": 62, "output_tokens_details": {"thinking_tokens": 46}, "service_tier": "batch"}}
{"id": "group-misogyny", "text": "[\"rejection-of-women\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1391, "output_tokens": 129, "output_tokens_details": {"thinking_tokens": 117}, "service_tier": "batch"}}
{"id": "group-masculine", "text": "[\"ambition-and-self-determination\", \"confidence-and-self-assurance\", \"dominance-and-power\", \"family-and-fatherhood\", \"hustle-and-money\", \"relentless-ambition\", \"rivalry-and-superiority\", \"self-confidence-and-braggadocio\", \"showing-off-and-impressing\", \"street-loyalty-and-danger\", \"violence-and-street-danger\", \"wealth-and-flexing\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1390, "output_tokens": 684, "output_tokens_details": {"thinking_tokens": 544}, "service_tier": "batch"}}
{"id": "group-vulnerable", "text": "[\"addiction-and-obsession\", \"alcohol-and-substance-abuse\", \"clinging-to-love\", \"disappointment-and-failure\", \"fear-of-losing-love\", \"heartbreak-and-grief\", \"hidden-emotional-struggle\", \"inner-mental-turmoil\", \"loneliness-and-isolation\", \"longing-and-loss\", \"past-trauma-and-healing\", \"self-worth-and-insecurity\", \"vulnerability-and-betrayal\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1387, "output_tokens": 1016, "output_tokens_details": {"thinking_tokens": 859}, "service_tier": "batch"}}
+30
View File
@@ -0,0 +1,30 @@
You are selecting thematic keywords that belong to a named
group.
Input: a JSON object with the name of one group and the
keywords — the complete set of codes; use these and no
others:
{
"group": "the name of the group",
"keywords": ["first-keyword", "second-keyword"]
}
Task: list every given keyword that belongs to the named
group, judged by the literal meaning of the keyword itself.
Rules:
- Use only the given keywords, spelled exactly as given.
- A group may match any number of keywords, including none.
- Judge each keyword only by the literal meaning of its own
wording.
Do not wrap the output in a Markdown code fence.
The output must be strictly valid JSON.
Output a single JSON array of the keywords that belong to
the group (an empty array when none belongs), and nothing
else:
["first-keyword", "second-keyword"]
+25
View File
@@ -0,0 +1,25 @@
{
"script_version": "run_llm.py 3.1.0",
"model": "claude-fable-5",
"temperature": null,
"thinking": null,
"max_tokens": 8192,
"prompt_path": "../prompts/04-group.md",
"prompt_sha256": "50e1d5d6c4115d090ae4ab1e801ea74db0b2dcdd47213ce0feb6749e034a41e9",
"input_path": "instance/llm-input-group.jsonl",
"input_sha256": "7fd97ae165270cb91461aedf411050892667b928d8584fceffea6f9649e003c7",
"item_count": 4,
"dry_run": false,
"started_at": "2026-08-14T23:39:37+08:00",
"batch": {
"batch_id": "msgbatch_01DveEMYyjCAYe6wxpcCD87V",
"submitted_at": "2026-08-14T23:39:43+08:00",
"ended_at": "2026-08-14T15:41:46.778015+00:00"
},
"usage": {
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"input_tokens": 5553,
"output_tokens": 1975
}
}
+4
View File
@@ -0,0 +1,4 @@
{"id": "group-women-power", "text": "[\"female-empowerment\", \"women-power\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1385, "output_tokens": 77, "output_tokens_details": {"thinking_tokens": 61}, "service_tier": "batch"}}
{"id": "group-misogyny", "text": "[\"rejection-of-women\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1391, "output_tokens": 207, "output_tokens_details": {"thinking_tokens": 195}, "service_tier": "batch"}}
{"id": "group-masculine", "text": "[\"dominance-and-power\", \"family-and-fatherhood\", \"hustle-and-money\", \"rivalry-and-superiority\", \"self-confidence-and-braggadocio\", \"showing-off-and-impressing\", \"street-loyalty-and-danger\", \"violence-and-street-danger\", \"wealth-and-flexing\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1390, "output_tokens": 846, "output_tokens_details": {"thinking_tokens": 740}, "service_tier": "batch"}}
{"id": "group-vulnerable", "text": "[\"disappointment-and-failure\", \"fear-of-losing-love\", \"heartbreak-and-grief\", \"hidden-emotional-struggle\", \"inner-mental-turmoil\", \"loneliness-and-isolation\", \"longing-and-loss\", \"past-trauma-and-healing\", \"self-worth-and-insecurity\", \"vulnerability-and-betrayal\"]", "stop_reason": "end_turn", "usage": {"cache_creation": {"ephemeral_1h_input_tokens": 0, "ephemeral_5m_input_tokens": 0}, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "inference_geo": "global", "input_tokens": 1387, "output_tokens": 845, "output_tokens_details": {"thinking_tokens": 723}, "service_tier": "batch"}}
+30
View File
@@ -0,0 +1,30 @@
You are selecting thematic keywords that belong to a named
group.
Input: a JSON object with the name of one group and the
keywords — the complete set of codes; use these and no
others:
{
"group": "the name of the group",
"keywords": ["first-keyword", "second-keyword"]
}
Task: list every given keyword that belongs to the named
group, judged by the literal meaning of the keyword itself.
Rules:
- Use only the given keywords, spelled exactly as given.
- A group may match any number of keywords, including none.
- Judge each keyword only by the literal meaning of its own
wording.
Do not wrap the output in a Markdown code fence.
The output must be strictly valid JSON.
Output a single JSON array of the keywords that belong to
the group (an empty array when none belongs), and nothing
else:
["first-keyword", "second-keyword"]