Pdf metadata filler
Claude Code skill: auto-fill Title/Author/DOI metadata of academic paper PDFs via OpenAlex/CrossRef/CiNii + OCR + LLM fallback
npx -y skills add eUmeda/pdf-metadata-fillerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
論文PDFの Title/Author/DOI を自動補完する。「PDFのメタデータを埋めたい」「論文PDFにメタデータがない」「PDFのメタデータ補完」「PDF走査して補完」「/pdf-meta」「/pdf-metadata」で使用。ファイル名DOI→本文DOI→OpenAlex→CrossRef→CiNii(和文紀要)→OCR→LLM(Gemini/Groq)の多段で書誌を取得し pypdf/exiftool で書込。
SKILL.md
5.8 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
PDF Metadata Filler
PDF ディレクトリの Title/Author/DOI 欠損を多段フォールバックで補完する。 エンジンは OpenAlex/CrossRef/CiNii + OCR + LLM(Gemini/Groq, REST 直叩き)。 (earlier private tooling を統合・置換した公開版, 2026-06)
取得チェーン(fill_pdf_metadata.py)
ファイル名DOI → 本文DOI → OpenAlex(DOI) → CrossRef(DOI)
→ OpenAlex(title) → CrossRef(title) → CiNii(title=和文紀要に強い)
→ (スキャンPDF) OCR(eng+jpn) → LLM テキスト提案(Groq→Gemini)
- 書込: 本体は pypdf(アトミック書込:
.pdf.tmp→os.replace。元 PDF は失敗時も無傷)。 helper のupgrade_matched.py/fuzzy_fill.pyは exiftool 書込。 - バックアップ契約(全書込スクリプト共通): 変更前に
<name>.pdf.bakを未存在時のみ作成。 既存.bakは原本なので再実行でも決して上書きしない。バックアップ失敗時はそのファイルを書き込まない。 - DOI は
/Subjectに格納(dedup キー)。title 類似度ゲート(0.6) で誤一致抑止。 LLM は本文に無ければ doi 空(捏造禁止)。
スクリプト(scripts/)
| script | 役割 |
|---|---|
fill_pdf_metadata.py | 本体。<dir> [--dry-run] [--only-list FILE] [--redo] [--keys PATH] |
verify_proposals.py | LLM提案(done_groq_proposal)のタイトルを OpenAlex/CrossRef/CiNii 照合 → matched/unmatched/no_title/error(read-only。error=API一時障害、再実行で再照合) |
upgrade_matched.py | matched を実 DOI/著者で格上げ(exiftool) → status done |
fuzzy_fill.py | no-title を 強制OCR(eng+jpn)+ファイル名で LLM ファジー全埋め → done_fuzzy(LLM 必須・キー未設定は設定エラーで即終了) |
- helper 3 スクリプトは対象 dir を第1引数(または環境変数
PAPERS_DIR)で受け取る。未指定は明示エラー。 --keys PATHは全スクリプト共通。既定の解決順:--keys → リポジトリ直下(scripts/ の親)の api_keys.json →(fill_pdf_metadata.py のみ)走査対象 dir。- 書込対象パスは対象 dir 内に限定(containment チェック。
../等で外の PDF は書き換えない)。 - helper は
exiftool/tesseractを起動時に確認し、無ければ LLM トークン消費前に終了する。
標準運用: ①fill_pdf_metadata.py <dir> --dry-run で件数確認 → ②本実行(in-place, .bak退避) → ③verify→upgrade→(必要なら)fuzzy。
無料枠ガード(オーバーフロー防止)
プロバイダ別日次トークン予算 + RPM スロットル + プロンプト縮小 + 429/5xx の Retry-After 尊重バックオフ。
予算超過・走行中 429 は失敗でなく deferred_quota(翌日 resume で継続)。
書誌 API の一時障害(429/5xx/接続断)は deferred_api で保留し、未検証の LLM 提案にフォールバックしない。
モデル不存在(404)等の恒久エラーは当該プロバイダを無効化(誤って翌日に保留しない)。
LLM 優先 Groq→Gemini。使用量は対象 dir の _llm_usage.json に永続化。
--only-list FILE が空のときは「対象0件」(全走査にフォールバックしない安全策)。
status 規約(信頼度)
done=API検証済(高信頼) / done_ocr_fallback=ヒューリスティックOCR(未検証) /
done_groq_proposal=LLM提案(未検証) / done_fuzzy=OCR+ファイル名のLLMファジー(未検証) /
deferred_quota=LLM無料枠待ち / deferred_api=書誌API一時障害(再実行で継続) / failed。
書込フィールド
/Title=論文タイトル, /Author=第一著者(複数は "First et al."), /Subject=DOI: … | 誌名 | 年, /Keywords=DOI。
鍵・依存
api_keys.json(雛形api_keys.example.json):openalex.email・openalex.api_key・cinii.appid・gemini.api_key/model・groq.api_key/model。実鍵は commit/同期しない(gitignore)。- OpenAlex は 2026-02-13 以降 API キー必須(無料)。未設定なら警告のうえテスト枠で試行、 401/403/409 で OpenAlex 段をスキップ。CiNii は appid 必須(NII 開発者登録・無料)、未設定なら CiNii 段スキップ。
- メールが空/プレースホルダ(example.com / your-email 等)のとき mailto は一切送信しない(匿名 User-Agent)。
- Gemini 無料枠は送信テキストが Google の製品改善(人手レビュー含む)に使われうる。機密 PDF は有料枠か Groq を使う。
- 依存:
pypdf requests pypdfium2 pytesseract Pillow+tesseract(eng+jpn)+exiftool(helper 書込用)。 LLM SDK(groq / google-generativeai)は不要(requests による REST 直叩き)。 - 実行時 state(
pdf_metadata_status.json/_llm_usage.json/_proposals_verified.csv)は すべて対象 papers ディレクトリ側に置く。壊れた state は*.corrupt-<時刻>に退避して保全。 - 自動再開(launchd/cron)・creds 管理・大規模運用は各自の環境に合わせて構成すること。
CiNii(和文紀要) 対応を内蔵。OCR/LLM 経路で scan PDF にも対応。 dedup / quarantine スクリプトは本 repo の範囲外(Roadmap 参照)。
What ships with it: 10 files
121.1 KB alongside SKILL.md, 4 of them executable
scripts/
- fill_pdf_metadata.pyruns79.4 KB
- fuzzy_fill.pyruns14.0 KB
- upgrade_matched.pyruns6.6 KB
- verify_proposals.pyruns5.7 KB
- api_keys.example.json3.0 KB
- CITATION.cff397 B
- .gitignore417 B
- LICENSE1.1 KB
- README.md9.9 KB
- SECURITY.md665 B
Gives 0 of the 12 instructions most pdf office docs skills give in ~2.1k tokens
Counted across 636 of the 690 authors here whose files we hold, read 2026-08-07
- extract text using pdfplumberin 89 of 636, across 23 files
- create PDFs using reportlabin 83 of 636, across 16 files
- read forms.md to fill out pdf formsin 80 of 636, across 13 files
- OCR scanned PDFs using pytesseractin 77 of 636, across 10 files
- merge or split PDFs using qpdfin 70 of 636, across 3 files
- use excel formulas instead of hardcoded calculated valuesin 68 of 636, across 13 files
- unpack edit xml and repack existing documentsin 63 of 636, across 8 files
- document sources for hardcoded valuesin 61 of 636, across 9 files
- write minimal python code without unnecessary commentsin 59 of 636, across 7 files
- run the recalculation script after adding or modifying formulasin 59 of 636, across 7 files
- fix all identified formula errors and recalculatein 58 of 636, across 6 files
- format years as text stringsin 57 of 636, across 5 files
Said here and by no other author read
- Run a multi-stage fallback chain for bibliographic lookup
- Write the main PDF via pypdf using atomic replacement
- Create a backup only if one does not already exist
- Store DOIs in the /Subject metadata field
- Apply a title similarity score gate of 0.6
- Keep write targets strictly inside the target directory
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.