引註檢查
對已完成或進行中的文章草稿進行驗證。每項引用權威都會檢查其是否存在;每段引文都會與原文逐字比對;每個網址都會確認可解析;在可取得原始來源頁碼的情況下,頁碼引用會進行合理性檢查。確定性腳本負責執行提取與交叉引用解析,幾乎不消耗 token;模型代理則負責進行引文/頁碼比對驗證,採用逐一來源展開的方式,且每個高嚴重性發現都必須經過第二次檢查,確保檢查成果絕不會在未經確認的情況下進入報告。
它重複使用 legal-research 技能的機制 (check_cite.py、fetch_page.py、CourtListener token、預算遞減階梯) 及其內部規則(僅使用公開網路,絕不憑記憶驗證,無法取得的來源回報為「未驗證」——絕不擅自假設)。
檢查內容: 每則引註是否指向所聲稱的來源、案件名稱/作者/標題拼寫是否正確、判例彙編/卷號/起始頁/法院/年份是否正確、引文是否逐字正確或已誠實標記、supra/id. 交叉引用是否完整、網址是否有效。
涵蓋範圍記錄(新增於 2026-09-06)——以及仍不檢查的項目。 引文驗證單元是從引文建構的;單靠它們無法涵蓋所有未附引文的二手來源。現在 scripts/citation_ledger.py 會清查每則註腳中的每個引註實例(包含判例或二手來源、有無引文、已解析 Id./supra/簡稱鏈),針對未附引文的文章/書籍/法規/網址進行二手來源存在性檢查,報告的 H 節會為每個實例標示處理狀態——verified(已驗證)、finding(發現問題)、existence-only(僅確認存在)、unverifiable(無法驗證)、unchecked(未檢查)、xref(交叉引用)、unresolved-xref(無法解析的交叉引用)——並按註腳列出未檢查的項目。仍有兩項限制且報告必須載明:(1) 論點支持——未附引文的引註是否確實支持其所附著的句子——從不評估(這就是 existence-only 的意涵);(2) 頁碼僅在有引文錨定時才進行檢查。請將 existence-only 理解為「真實來源,但未閱讀」,絕非「已通過」。
外加明顯的格式問題(使用者於 2026-08-10 解除範圍鎖定——「解除鎖定,只要不妨礙你檢查明顯問題」)。 Form 階段會回報僅從草稿本身即可判定、無需查閱來源的項目:
- 簡稱——完整引註在 Bluebook 規則 10.9 的五則註腳窗口內重複出現,本應使用簡稱;案件簡稱超出該窗口或在任何地方無完整引註在前;二手來源在規則 4.2 要求使用
Author, supra note N時卻完整引用兩次。 - 字型(僅限
.docx)——信號詞 /Id./supra/quoting未使用斜體、斜體supra後的note N錯誤地使用斜體、斜體溢出到引註前的逗號、小型大寫字母在單字中斷裂、以及規則 2.1(a) 下的案件名稱斜體化(在引註子句中應為羅馬體,在正文句子或簡稱中應為斜體——這是唯一需要代理判斷的項目,因為模式無法區分這兩種情況)。
這些檢查仰賴 ${CLAUDE_PLUGIN_ROOT}/skills/legal-research/citeform.py,與 /proofread 使用同一個模組,因此兩個技能絕不會給出矛盾的建議。所適用的規則已明文記載於 ${CLAUDE_PLUGIN_ROOT}/skills/legal-research/bluebook-typeface-and-short-forms.md。格式發現會歸入報告末段的獨立章節,絕不會進入「需您關注」區——它們屬於整理性質,而非實質問題。
它仍然不是: 完整的 Bluebook 格式檢查器(信號詞順序、引註順序、以及引註是否構成正確均不在範圍內)、實質編輯器、或期刊引註檢查的替代品。與 /proofread 的分工維持不變:proofread 閱讀正文,cite-check 驗證引用權威——它們現在只是恰好共用引註格式層。
如何執行
1. 解析請求
- draftPath — 草稿路徑(必填)。
.docx格式(含真實 Word 註腳)為標準;.md/.txt格式(使用 pandoc 風格的[^n]註腳)可作為備案。 - footnotes — 可選的局部檢查,例如「註腳 45–80」或一個列表。預設值:整份草稿。
- deep — 可選;更深入的驗證(中等努力度的驗證代理,較高的軟上限)。在草稿接近完稿或使用者要求「深入」/「徹底」時開啟。
- 如果草稿有追蹤修訂,請告知並詢問是否要先接受全部修訂再檢查(解析器會讀取目前的/已接受的文字並跳過追蹤刪除,但一份大量標記的草稿值得提醒)。
1b. 詢問深入程度(由作者決定,2026-08-09——與 /proofread 步驟 1b 對應)
除非請求已明確指定,請一開始就詢問——一個 AskUserQuestion,標題 Depth,在預檢之前進行。將追蹤修訂的提醒(步驟 1)合併到同一則提問中,讓使用者一次回答所有問題,避免被中斷兩次。
跳過詢問的時機:用語已指明層級時(「深入」、「徹底」、「接近完稿」、「投稿前」、「快速」、「標準」)、本次階段已選擇層級後的局部重跑、或使用者僅要求檢查狹窄的註腳範圍時。
兩個選項——cite-check 沒有 fable 升級機制,因此階梯比 proofread 短:
| 選項 | 參數 | 說明文字 |
|---|---|---|
| 標準 | deep:false | 驗證代理使用低努力度,軟上限 650k。適用於進行中的草稿。 |
| 深入 | deep:true | 驗證代理使用中等努力度,軟上限 900k。對每段引文與其來源進行更仔細的比對——適用於接近完稿的草稿。 |
請勿在此重複 /proofread 的論述——兩者的 deep 運作機制不同。 Proofread 的深入模式會增加第二輪偏移提取(一種召回策略,基於約 75–80% 同模型重疊的發現)。Cite-check 的深入模式不會增加任何一輪或重新擷取任何資料:它只是將驗證代理的努力度從 low 提升為 medium(工作流程第 557 行)並提高軟上限。它買到的是每段引文更仔細的比對,而非更多引文。引文涵蓋率在兩種模式下完全相同——每個引文都會在兩個層級中被檢查——因此請不要暗示標準模式會跳過任何內容。
時間點在這裡的重要性不如 proofread(深入模式不會改變提取,因此後續重跑可透過 resumeFromRunId 從快取重播分段/存在性檢查),但驗證是執行過程中的主要部分——在 National Muffler 草稿中,33 個代理中有 26 個屬於驗證——因此改變層級仍然意味著重跑最昂貴的階段。請先詢問。
2. 預檢(請在啟動前執行——執行中途的權限提示可能會殺死代理)
- 讀取
~/.claude/settings.json;確認permissions.allow包含"WebFetch"和"WebSearch"(合併缺少的項目——絕不要取代整個陣列)。例行設定;無需提示。 - 確認 CourtListener token 正常運作。請進行測試,不要去找檔案——執行
python3 ${CLAUDE_PLUGIN_ROOT}/skills/legal-research/check_cite.py "347 U.S. 483";若 exit code 為 0 且"found": true,表示它正常運作且無需回報。check_cite.py會依序從COURTLISTENER_API_TOKEN、COURTLISTENER_TOKEN、檔案~/.config/courtlistener/token解析 token——按此順序,而且環境變數方式(通常設在~/.claude/settings.json的env區塊中)是標準安裝方式,因此缺少~/.config/courtlistener/目錄並不代表什麼。如果探測確實失敗,執行仍可繼續(案件存在性會回退到網路查詢),但請在交付時提及一次。Token 頁面:https://www.courtlistener.com/profile/api-token/ - 解析專案的 Zotero 文獻庫(專案各有不同——有些是共同作者群組文獻庫,有些是個人文獻庫):
a. 在專案資料夾的
CLAUDE.md(或AGENTS.md)中尋找Zotero library:行。如果存在,使用它所命名的 MCP 伺服器,並跳到 (c)。 b. 如果不存在,詢問使用者此專案使用哪個 Zotero 文獻庫(個人文獻庫或指定的群組文獻庫),然後將答案記錄為Zotero library: <名稱> → MCP server <伺服器>行,寫入專案資料夾的CLAUDE.md,以便未來執行時不再詢問。 c. 確認該 MCP 伺服器確實存在(個人 =zotero;群組文獻庫有自己的伺服器,例如zotero-group對應「5A general law」,群組 ID 在~/.claude.json中)。如果專案的文獻庫還沒有伺服器,此時就是主動提供新增的時機:在~/.claude.json中複製zotero條目為zotero-<slug>,設定ZOTERO_LIBRARY_TYPE=group和該群組的ZOTERO_LIBRARY_ID(可透過 zotero.org 群組網址或草稿的功能變數代碼找到);請注意這需要重新啟動 Claude Code,因此本次執行代理會回退到網路查詢。 d. 將伺服器名稱作為zoteroServer傳入(如果本次執行無可用伺服器,則傳入zotero:false)。
2b. 快照草稿(始終執行)
一份正在進行的 OneDrive/Word 共同編輯檔案可能在提取與交付之間變更,這將導致報告描述從未被檢查過的位元組。請複製草稿一次,將副本設為唯讀,計算其雜湊值,然後在後續所有流程中使用此快照。原始路徑僅在此處使用,絕不出現在工作流程參數或代理提示中。
cp "<draftPath>" "<scratch>/snapshot.docx" && chmod a-w "<scratch>/snapshot.docx"
shasum -a 256 "<scratch>/snapshot.docx" # 記錄此值;它會出現在報告頁尾
3. 提取與準備(確定性腳本——請自行執行,幾乎不消耗 token)
將中間 JSON 放在工作流程的代理可以讀取的位置(會話暫存區即可)。使用已安裝的腳本路徑,以便從任何資料夾都能運作(draftName 保持原始檔名,而非「snapshot」):
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/extract_cites.py "<scratch>/snapshot.docx" "<scratch>/extract.json"
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/prepare_units.py "<scratch>/extract.json" "<scratch>/units.json"
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/citation_ledger.py "<scratch>/extract.json" "<scratch>/ledger.json"
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/citation_ledger.py "<scratch>/extract.json" --compact > "<scratch>/ledger_args.json"
citation_ledger.py 會輸出 instance_count / by_kind / unique_secondary_cites / unresolved_xrefs。請查看 by_kind:如果 other 或 text 的計數很大,表示註腳使用了剖析器無法識別的引註格式——這些實例仍會包含在總帳中(狀態為 unchecked / not-a-citation),因此報告仍會誠實呈現,但請在交付時說明。--compact 檔案包含工作流程所需的兩個陣列(instances、secondary)。
extract_cites.py 會輸出摘要(註腳數量、正文/註腳引文數量、唯一判例引註數量、supra 問題候選數量,以及來自格式層的 form_findings / form_short_form / form_typeface / formatting_available / case_name_candidates)。prepare_units.py 會輸出 unit_count / case_cites / supra_problems。請讀取 extract.json 以獲取工作流程所需的陣列:unique_case_cites、supra_problem_candidates 以及整個 form_checks 區塊。
formatting_available: false 表示是 markdown/純文字草稿——簡稱檢查仍會執行,但字型檢查不會;請在交付時說明。如果出現 formatting_unaligned_footnotes,表示有這麼多則註腳未經字型分析(其格式化文字與經驗證的剖析器文字不符,因此該層拒絕執行以避免偏移不一致的風險)——僅在數量非同小可時提及。
對於局部檢查,請將註腳範圍解析為單元 ID:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/prepare_units.py "<scratch>/extract.json" --footnotes 45-80
(輸出 unit_ids——以 unitIds 參數傳入)。
4. 啟動工作流程
Workflow({
scriptPath: "${CLAUDE_PLUGIN_ROOT}/skills/cite-check/cite-check.workflow.js",
args: {
skillsDir: "${CLAUDE_PLUGIN_ROOT}/skills", // 打包的輔助腳本所在位置
extractPath: "<scratch>/extract.json", // 代理從此處讀取單元與完整上下文
draftName: "<草稿檔名(不含副檔名)>",
footnoteCount: <extract.footnote_count>,
unitCount: <prepare.unit_count>,
caseCites: <extract.unique_case_cites>, // 陣列
supraProblems: <extract.supra_problem_candidates>, // 陣列
formChecks: <extract.form_checks>, // 字型 + 簡稱(完整區塊)
ledger: <ledger_args.instances>, // 每個引註實例(緊湊形式)
secondaryCites:<ledger_args.secondary>, // 唯一的非引文二手來源
unitIds: <null | [來自 --footnotes 的 ID]>, // 僅局部檢查
deep: false,
zotero: true, // 如果本次執行無可用 Zotero 伺服器則為 false
zoteroServer: "<來自預檢 2.3>" // 例如 "zotero-group" (5A) 或 "zotero" (個人)
}
})
管線(所有模型階段使用 Sonnet,報告除外,它繼承會話模型):
- 分段/解析——分塊進行;每段引文與其附著的特定來源配對,沿
Id.鏈追溯到其真實的前身(可能是兩則註腳前的案件),並追蹤supra note N重新導向,使用
…
[翻譯內容已截斷]