Community研究與資料分析github.com

HighBridgeDragon/jp-diet-minutes-skill

NDL(國立國會圖書館)官方 API 搜尋日本國會(Kokkai)會議記錄——適用於 Claude Code / Cursor / Copilot 的 AI 代理技能。

jp-diet-minutes-skill 是什麼?

這是一個專為 AI 代理(如 Claude Code、Cursor、Copilot)設計的技能,用於透過 NDL(國立國會圖書館)官方 API 搜尋日本國會(1947 年以後)的會議記錄。它提供了一系列 shell wrapper 腳本(位於 `scripts/` 目錄下),用於簡化 API 呼叫,無需認證。主要功能包括:按議員姓名搜尋發言、按關鍵字進行全文檢索、按角色(如證人、參考人、公述人)篩選、列出會議,以及取得特定會議的完整記錄。該技能強調效率與 token 節約,引導使用者採用漸進式策略:先用輕量級端點(如 `list-meetings.sh` 或 `search-by-*.sh`)進行初步篩選,再視需要透過 `fetch-meeting.sh` 取得完整的會議記錄。官方文件明確禁止並行請求,連續呼叫之間應間隔 2-3 秒。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add HighBridgeDragon/jp-diet-minutes-skill

Installed? Explore more 研究與資料分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

國會會議記錄搜尋技能

透過 NDL(國立國會圖書館)的國會會議記錄搜尋系統 API 調查自國會成立(1947 年)以來的日本國會議事錄。無需認證。使用 bash scripts/<script>.sh wrapper 來呼叫。

帝國議會議事錄(〜1947 年)屬於不同 API,因此不在本技能範圍內。

基本規則

  • Base URL: https://kokkai.ndl.go.jp/api/
  • 回應格式: recordPacking=json(wrapper script 會強制設定)
  • 認證: 不需要
  • 呼叫方式: 使用 bash scripts/<script>.sh。直接使用 WebFetch / Invoke-RestMethod 僅限於 wrapper 未覆蓋的邊緣案例(請參閱下方「需要 raw curl 的情況」)
  • 速率限制: 官方明確規定「進行機械性存取時,禁止多重請求,應間隔數秒」。禁止並行處理,連續呼叫應間隔約 2-3 秒。
  • 查詢字串總長度上限為 2,000 位元組(日文字元經 URL 編碼後,每個字元約佔 9 位元組)。

端點選擇

根據使用者的需求選擇適當的 wrapper script。資訊量與消耗的 token 依 list-meetings.sh < search-by-*.sh < fetch-meeting.sh 的順序遞增,因此應從較輕量的端點開始逐步篩選。

「顯示某議員的發言」
  → bash scripts/search-by-speaker.sh 議員名稱 [from] [until] [limit] --sort <keys>
  ※ --sort 為必填。代表值為 date-desc(最新優先)

「搜尋關於某主題的發言」
  → bash scripts/search-by-keyword.sh 關鍵字 [from] [until] [limit] --sort <keys>
  ※ any 搜尋(AND 邏輯)。多個關鍵字以半形空格分隔。--sort 為必填

「抽取參考人質詢(包含證人喚問、陳述人)」
  → bash scripts/search-by-role.sh 角色名稱 [from] [until] [limit] --sort <keys>
  ※ role 可以是 證人 / 參考人 / 陳述人。--sort 為必填

「顯示某委員會的會議列表」
  → bash scripts/list-meetings.sh 委員會名稱 [from] [until] [limit] --sort <keys>
  ※ 輕量級端點。僅回傳會議中繼資料(不含發言本文)。`--sort` 為必填(僅接受 `date-asc` / `date-desc`)

「顯示特定會議的所有發言」「某委員會 YYYY-MM-DD 的完整議事錄」
  → 步驟 1: 使用 bash scripts/list-meetings.sh 找出目標會議的 issueID
  → 步驟 2: 使用 bash scripts/fetch-meeting.sh <issueID>
  ※ 一個請求會回傳完整會議內容,因此資料量較大。務必先進行篩選再呼叫。

詳細資訊請參閱 api-reference.md、parameters.md、response-format.md 與 recipes.md。

各端點的使用方法

1. search-by-speaker.sh — 依議員名稱搜尋發言(最常用)

僅回傳符合搜尋條件的發言。Token 效率最佳。--sort 為必填,這迫使使用者明確瞭解 API 的排序規則(針對 #41 的對策)。

# 依議員名稱抽取發言(部分比對 OR),日期降序
bash scripts/search-by-speaker.sh 岸田文雄 2024-01-01 2024-12-31 50 --sort date-desc

所有參數規格(包含可用的 sort key 詳細資訊)請參閱 bash scripts/search-by-speaker.sh -h。

回應為 speechRecord[] 陣列。每個元素會扁平化包含會議中繼資料(如 issueID、session、nameOfHouse、nameOfMeeting、date 等)。

2. search-by-keyword.sh — 關鍵字搜尋(any 搜尋,AND 邏輯)

針對發言本文進行全文搜尋。多個關鍵字以半形空格分隔,進行 AND 組合。--sort 為必填。

# AND 搜尋: 包含「マイナンバー」且包含「個人情報」的發言,日期降序
bash scripts/search-by-keyword.sh 'マイナンバー 個人情報' 2024-01-01 2024-12-31 50 --sort date-desc

所有參數規格請參閱 bash scripts/search-by-keyword.sh -h。回應結構與 search-by-speaker.sh 相同。

3. search-by-role.sh — 依角色搜尋發言(例如參考人質詢)

根據 speakerRole 來篩選發言者的角色。用於抽取證人喚問、參考人質詢或陳述人的發言。--sort 為必填。

# 僅限參考人質詢,日期降序
bash scripts/search-by-role.sh 參考人 2024-01-01 2024-12-31 50 --sort date-desc

role 只能是 證人 / 參考人 / 陳述人 其中之一。指定其他值時,API 會回傳 HTTP 400 錯誤。

所有參數規格請參閱 bash scripts/search-by-role.sh -h。

4. list-meetings.sh — 會議列表(輕量級索引)

僅回傳會議中繼資料。不包含發言本文,因此適合用於產生列表或進行初步篩選。用於找出 issueID。--sort 為必填(僅接受 date-asc / date-desc)。

# 特定日期的預算委員會列表,日期升序
bash scripts/list-meetings.sh 預算委員會 2024-03-01 2024-03-31 50 --sort date-asc

所有參數規格請參閱 bash scripts/list-meetings.sh -h。

回應為 meetingRecord[] 陣列。每個元素下的 speechRecord[] 包含最低限度的發言中繼資料(speechID、speechOrder、speaker、speechURL)。取得本文需要呼叫 search-by-* 或 fetch-meeting.sh。

5. fetch-meeting.sh — 完整會議記錄(最終手段)

回傳完整會議記錄。一個請求就會回傳所有發言,因此資料量較大。請先使用 list-meetings.sh 找出 issueID 後再呼叫。

# 依 issueID 取得完整會議記錄
bash scripts/fetch-meeting.sh 121405254X00220241004

參數規格請參閱 bash scripts/fetch-meeting.sh -h。maximumRecords=1 為固定值(因為 issueID 是唯一的)。--sort 在此端點不適用(因為是取得單一會議;必要時可使用 jq 對輸出進行後處理)。

fetch-meeting.sh 的 speechRecord[] 包含所有欄位(speech、speakerYomi、speakerGroup、speakerPosition、speakerRole、startPage、createTime/updateTime)。

Token 節約指引

bash scripts/fetch-meeting.sh 一個會議的資料量可能達到數百 KB 到 MB 等級。應遵守以下事項:

  1. 優先使用 search-by-*.sh: 以發言為單位時,可以只取得需要的部分。bash scripts/fetch-meeting.sh 僅在使用者明確要求「完整會議記錄」時使用。
  2. 明確指定 maximumRecords: 預設值 30 足夠時可省略。需要取得大量資料時,可提高上限(search-by-*/list-meetings: 100、fetch-meeting: 10)以減少總請求數。
  3. 採用兩階段搜尋: 先使用 list-meetings.sh 或 search-by-*.sh 篩選目標並取得 issueID,再視需要呼叫 fetch-meeting.sh 取得完整記錄。不要一開始就直接呼叫 fetch-meeting.sh。
  4. 命中 0 筆時的重新嘗試,請嘗試不同表記: 議員名稱可依序嘗試 福島 みずほ / 福島瑞穗 / 平假名。黨派名稱必須使用正式名稱(自民黨 ❌ / 自由民主黨 ✅)。

結果篩選的陷阱

取得回應後,請注意以下事項:

  1. speechOrder 為 0 的行是議事錄資訊標頭: 這些是議事日程、審議案件等結構化資訊,並非實際發言。speaker 固定為 會議記錄資訊。統計發言時,應排除 speechOrder 為 0 的行。
  2. imageKind 的值: 預設情況下,除了 會議記錄 之外,目次 / 索引 / 附錄 / 追錄 也可能混入。抽取發言時,應將 imageKind 的值過濾為僅 會議記錄 的行(請求參數 contentsAndIndex / supplementAndAppendix 預設均為 false,因此通常可省略。只有在需要明確混入這些項目時才指定 true)。
  3. closing 會在值為 false 時回傳 null: 在未設定閉會中旗標的一般會議中,其值為 null。判斷是否為閉會中審查時,應檢查 closing 的值是否為 true(應使用與 true 的比較,而非與 false 的比較)。
  4. nameOfHouse 的無效值會被靜默忽略: API 會回傳 HTTP 200 但結果未套用篩選。請透過檢查 numberOfRecords 的合理性來確認篩選意圖是否被正確反映。
  5. 發言本文的換行為 CRLF (\r\n): 並非僅有 LF。進行文字處理時,可能需要進行正規化。
  6. search-by-*.sh 的回應結構是扁平化的: 不像 fetch-meeting.sh 那樣有 meetingRecord 包裝。若要編寫通用解析器,需要進行分支處理。
  7. API 的排序順序固定為「會議召開日期的降序」: 官方規格保證排序為降序,API 端沒有排序參數(search-by-speaker / search-by-keyword / list-meetings / fetch-meeting 皆同)。本技能的 wrapper script 的 --sort 並非 API 參數,而是透過 jq 進行的客戶端排序後處理(search-by-*.sh / list-meetings.sh 為必填)。雖然方便,但若使用 maximumRecords 進行部分擷取,則只會回傳最新的 N 筆。
    • 判斷最新發言: 可透過部分擷取的開頭確認(maximumRecords=1 即足夠)。
    • 判斷最舊發言: 不要根據部分擷取的結果來判斷最舊發言。需要取得 numberOfRecords 的所有頁面,或者使用 from/until 將期間縮小到年等單位,直到命中筆數 ≤ maximumRecords 後再進行判斷。
    • 同一天內的次要排序為 speechOrder 升序(實測結果,非官方規格): 如果不縮小期間,直接使用 startRecord=<numberOfRecords>&maximumRecords=1 存取最後一頁,由於 API 固定為降序,會取得期間內最舊日期的當日最後一筆發言(speechOrder 最大),從而錯過真正的第一筆發言。請使用 from/until 將期間縮小到 numberOfRecords ≤ 100 並取得所有筆資料,然後使用 wrapper 的 --sort date-asc,speech-order-asc 在一個請求內確定。(詳細請參閱 recipes/oldest-speech-by-speaker.md)。
  8. 同時使用 any 與 speaker 會產生交集(筆數大幅減少): 若為了搜尋議員 A 的發言而同時指定 any=A&speaker=A,搜尋結果將僅限於同時滿足兩個條件的發言(即 A 本人在發言中提到自己名字的情況),筆數會比單獨使用其中一個條件大幅減少(實測: 單獨使用 speaker=石原慎太郎 為 2,098 筆 / 兩者併用為 647 筆)。要取得議員 A 的所有發言,請單獨使用 speaker;要搜尋提及 A 的發言,請單獨使用 any。不同意圖的使用方式請參閱 parameters.md 的相關章節 與 recipes/speaker-vs-any-disambiguation.md。
  9. (19004)startRecord 超出範圍 錯誤中的「搜尋筆數」是指同一查詢的 numberOfRecords: 錯誤訊息 (19004)startRecord には 1 から検索件数までの値を指定してください。 中的「搜尋筆數」指的是同一查詢下的 numberOfRecords(實測結果,官方規格未明確說明)。若根據不同查詢(例如未加上 from/until 的簡單搜尋、單獨使用 speaker vs 併用、或過去取得的快取值)所取得的筆數來決定 startRecord,就可能觸發 19004 錯誤。要進行原因釐清,請針對同一查詢發送一個 startRecord=1&maximumRecords=1 的請求,重新確認 numberOfRecords。這種情況在項目 8 的交集操作或加上 from/until 導致筆數減少時經常發生(詳細請參閱 api-reference.md 中的 19004 說明)。

常用搜尋模式範例

議員特定時期內的發言

bash scripts/search-by-speaker.sh 石破茂 2024-10-01 2024-10-31 100 --sort date-desc

法案審議追蹤(時間序列)

bash scripts/search-by-keyword.sh マイナンバー法 2023-01-01 '' 100 --sort date-asc

抽取內閣總理大臣演說

speakerPosition 參數 wrapper 未支援,因此需要使用 raw curl:

# wrapper 未支援,使用 raw curl
curl -s 'https://kokkai.ndl.go.jp/api/speech?speakerPosition=%E5%86%85%E9%96%A3%E7%B7%8F%E7%90%86%E5%A4%A7%E8%87%A3&nameOfMeeting=%E6%9C%AC%E4%BC%9A%E8%AD%B0&from=2024-01-01&recordPacking=json'

參考人質詢

bash scripts/search-by-role.sh 參考人 2024-01-01 '' 100 --sort date-desc

特定會議的完整議事錄(兩階段)

# 步驟 1: 找出 issueID(nameOfHouse 篩選 wrapper 未支援,因此從列表中手動選擇)
bash scripts/list-meetings.sh 預算委員會 2024-03-01 2024-03-01 50 --sort date-desc

# 步驟 2: 取得完整記錄
bash scripts/fetch-meeting.sh <issueID>

分頁

所有端點通用。

  • 將回應中的 nextRecordPosition 傳遞給下一次請求的 startRecord。
  • 判斷最後一頁的方式:
    • JSON: nextRecordPosition 的值為 null。
    • XML: <nextRecordPosition> 元素本身不存在。
  • 連續取得資料時,請間隔數秒(速率限制)。

輸出格式

向使用者呈現發言時的建議格式:

【發言者】○○○○(所屬黨派・職稱)
【會議】第XXX屆國會 眾議院 ○○委員會 第X號(YYYY-MM-DD)
【發言】
發言本文引用(將 CRLF 正規化為換行)

【出處】國會會議記錄搜尋系統 https://kokkai.ndl.go.jp/txt/<issueID>/<speechOrder>

呈現會議列表時:

【會議列表】N 筆
- YYYY-MM-DD: 第XXX屆國會 眾議院 ○○委員會 第X號
  https://kokkai.ndl.go.jp/txt/<issueID>
- ...

需要 raw curl 的情況

以下參數 wrapper script 未涵蓋。必要時,請直接使用 curl / Invoke-RestMethod 呼叫 API:

  • sessionFrom / sessionTo(以屆次篩選)
  • contentsAndIndex / supplementAndAppendix(目次・索引・附錄)
  • closing=true(僅限閉會中審查)
  • nameOfHouse / nameOfMeeting 等次要篩選條件(未包含在 wrapper 的參數中)
  • 分頁(連續呼叫 startRecord + nextRecordPosition)
  • 同時指定 any 與 speaker(用於議員本人的自我提及等,刻意利用兩者交集的用途。詳細請參閱 recipes/speaker-vs-any-disambiguation.md 模式 3)

範例:僅抽取第 213 屆國會的預算委員會(需要使用 sessionFrom/sessionTo,wrapper 未支援)

curl -s 'https://kokkai.ndl.go.jp/api/meeting_list?sessionFrom=213&sessionTo=213&nameOfMeeting=%E4%BA%88%E7%AE%97%E5%A7%94%E5%93%A1%E4%BC%9A&maximumRecords=30&recordPacking=json'

對於使用 WebFetch 等內建摘要模型的工具,已觀察到它們會將回應中不存在的欄位作為幻覺(hallucination)混入,因此不應用於取得原始資料(詳細請參閱 response-format.md)。

詳細參考資料

  • api-reference.md: 端點規格・分頁・錯誤回應
  • parameters.md: 搜尋參數的完整規格・搜尋方式・組合範例
  • response-format.md: 回應結構・實際 JSON 範例・實測基礎的陷阱
  • recipes.md: 複合模式集(議員 × 關鍵字篩選等,scripts 無法涵蓋的案例)

相關技能