はじめに
arXivの最新論文を自動取得 → Claude APIで要約 → GitHubに保存 → Slackで通知するワークフローを構築しました。
この記事でわかること
- Claude API(Sonnet 4.5)を使った実用的な自動要約システムの実装方法
- コスト最適化の具体的手法(重複排除、予算管理)
- GitHub Actionsによる完全自動化のノウハウ
- 検証時の実績(2026-02-15時点:21論文を$0.2041で処理)
システム概要
処理フロー
主要な機能
| 機能 | 説明 |
|---|---|
| 自動取得 | arXiv RSS + APIフォールバック(週末対策) |
| AI要約 | Claude Sonnet 4.5で構造化要約(日本語) |
| GitHub保存 | カテゴリ・月別ディレクトリ構造(MD + JSON) |
| Slack通知 | Block Kitフォーマットで結果共有 |
| 重複排除 | 処理済み論文をスキップ(20〜30%削減) |
| 予算管理 | 日額$0.50ドル・月額$10ドルの上限設定 |
| 統計追跡 | INDEX.md + stats.jsonで進捗可視化 |
対象カテゴリ
- cs.AI — 人工知能
- cs.LG — 機械学習
- cs.CV — コンピュータビジョン
- cs.SE — ソフトウェア工学
- cs.DS — データ構造・アルゴリズム
- cs.AR — ハードウェアアーキテクチャ
アーキテクチャ
モジュール構成
src/
├── config.py # 設定管理(dataclass + env)
├── arxiv_client.py # arXiv RSS + API fetcher
├── summarizer.py # Claude API統合 + リトライ
├── dedup.py # 重複チェック(JSON永続化)
├── budget_manager.py # 予算管理 + アラート
├── github_publisher.py # GitHub API(PyGithub)
├── slack_notifier.py # Slack Block Kit通知
├── index_generator.py # INDEX.md + stats.json生成
└── logger.py # 構造化ログ
実装のポイント
1. arXiv RSSの週末問題とAPIフォールバック
arXiv RSSは週末に更新されず、空のフィードを返すことがあります。これに対処するため、APIフォールバックを実装しました。
def fetch_papers(category: str, max_results: int = 5) -> list[Paper]:
papers = _fetch_via_rss(category, max_results)
if not papers:
logger.info("RSS empty, falling back to arXiv API")
papers = _fetch_via_api(category, max_results)
time.sleep(3) # API rate limiting
return papers
2. カテゴリ横断の重複排除で20〜30%のコスト削減
cs.AIとcs.LGなど、複数カテゴリに跨がる論文が存在します。これを検出して1度だけ処理することで、コスト削減を実現しました。
# ※実際はarXiv ID文字列のリストを扱います
class DedupTracker:
def filter_new(self, arxiv_ids: list[str]) -> list[str]:
"""Return only new arXiv IDs not yet processed."""
new_ids = [aid for aid in arxiv_ids if aid not in self._processed]
if skipped := len(arxiv_ids) - len(new_ids):
logger.info("Skipping %d already-processed papers", skipped)
return new_ids
def mark_processed(self, arxiv_id: str) -> None:
"""Mark a single paper as processed."""
self._processed.add(arxiv_id)
# 年次バケットに振り分けて永続化を最適化
3. 予算管理による暴走防止
Claude APIのコストは入力$3/MTok、出力$15/MTokです。予算オーバーを防ぐため、日次・月次の上限を設けました。
class BudgetManager:
def check_budget(self, estimated_cost: float = 0.0) -> bool:
"""Check if request is within budget limits."""
if self.today_spent + estimated_cost > self.daily_limit:
logger.warning("Daily budget exceeded")
return False
if self.month_spent + estimated_cost > self.monthly_limit:
logger.warning("Monthly budget exceeded")
return False
return True
デフォルト設定:
- 日額上限: $0.50
- 月額上限: $10.00
- 週1実行(5カテゴリ × 5論文): 実測 $0.20 → 月額約$0.80〜$1.00
4. 構造化された日本語要約の生成
System Promptで日本語4セクション構造を指定し、一貫性のある要約を生成します:
- 概要: 1-2文で論文の主要貢献を説明
- 手法: 主要なアプローチを2-3文で記述
- 結果・意義: 主な成果と重要性を2-3文で説明
- キーワード: 3-5個の関連キーワード
- 全体で300単語以内に制限し、技術的精度を重視
5. GitHub への自動プッシュ
PyGithubを使い、カテゴリ・月別のディレクトリ構造で保存します。処理済み論文は年次分割アーキテクチャでパフォーマンスを最適化しています。
arxiv_summaries/
├── cs.AI/2026-02/2026-02-15.{md,json}
├── cs.LG/2026-02/...
├── processed_papers/ # 年次分割構造
│ ├── index.json # 年リスト
│ ├── 2025.json # 年ごとの処理済みID
│ └── 2026.json
├── budget_history.json
├── stats.json
└── INDEX.md
6. Slack Block Kit 通知
視覚的に見やすい通知を実現しました。
# ※説明のため簡略化しています(実際は詳細な統計情報も含みます)
def notify(self, results_by_category: dict, published_paths: dict,
github_repo: str, budget_summary: str = "") -> bool:
blocks = [
{"type": "header", "text": {"type": "plain_text", "text": "📚 arXiv要約完了"}},
{"type": "section", "text": {"type": "mrkdwn",
"text": f"*{len(results_by_category)}カテゴリ* で処理完了"}},
]
self._client.chat_postMessage(channel=self._channel, blocks=blocks, text="...")
return True
セットアップ手順
1. リポジトリクローン
git clone https://github.com/MameMame777/arxiv-summaries.git
cd arxiv-summaries
pip install -r requirements.txt
2. 環境変数設定
cp .env.example .env
.envファイルを編集:
ANTHROPIC_API_KEY=sk-ant-xxxxx
GITHUB_TOKEN=github_pat_xxxxx
GITHUB_REPO=MameMame777/arxiv-summaries
SLACK_BOT_TOKEN=xoxb-xxxxx
SLACK_CHANNEL=arxiv_mame
ARXIV_CATEGORIES=cs.AI,cs.LG,cs.CV,cs.SE,cs.DS
MAX_PAPERS_PER_CATEGORY=5
CLAUDE_MODEL=claude-sonnet-4-5-20250929
DAILY_BUDGET_LIMIT=0.50
MONTHLY_BUDGET_LIMIT=10.00
3. Slack Bot設定(オプション)
- Slack APIで新規アプリ作成
-
OAuth & Permissions →
chat:writeスコープ追加 - ワークスペースにインストール
- Bot Tokenを取得 →
.envのSLACK_BOT_TOKENに設定 - チャンネルにBotを招待:
/invite @your-bot
4. ローカル実行(動作確認)
# 通常実行
python main.py
# ドライラン(API呼び出しなし)
python main.py --dry-run
# カテゴリ指定
python main.py --categories cs.AI,cs.LG
# 論文数指定
python main.py --max-papers 3
5. GitHub Actions設定
リポジトリの Settings → Secrets and variables → Actions に追加:
ANTHROPIC_API_KEY-
SLACK_BOT_TOKEN(Slack使用時) -
SLACK_CHANNEL(Slack使用時)
注:
GITHUB_TOKENはActions自動提供。ワークフローにpermissions: contents: writeが必要。
6. GitHub Actionsワークフロー
.github/workflows/arxiv_summary.yml:
on:
schedule:
- cron: '0 9 * * 1'
workflow_dispatch:
permissions:
contents: write
検証結果(2026-02-15)
テスト実行(2026-02-15)
条件: 5カテゴリ × 5論文/カテゴリ
| カテゴリ | 取得 | 新規 | スキップ | 処理時間 |
|---|---|---|---|---|
| cs.AI | 5 | 4 | 1 | ~40秒 |
| cs.LG | 5 | 4 | 1 | ~40秒 |
| cs.CV | 5 | 3 | 2 | ~30秒 |
| cs.SE | 5 | 5 | 0 | ~50秒 |
| cs.DS | 5 | 5 | 0 | ~50秒 |
| 合計 | 25 | 21 | 4 | ~210秒 |
コスト実績
総処理: 21論文
総コスト: $0.2041
平均コスト/論文: $0.0097
予算状況:
日次: $0.21 / $0.50 (42.7%)
月次: $0.21 / $10.00 (2.1%)
アラート: OK
週1実行の月額コスト試算: $0.20 × 4週 = 約$0.80
生成された要約例
論文: UniT: Unified Multimodal Chain-of-Thought Test-time Scaling
## 概要
マルチモーダルLLMのテスト時スケーリングを統一的に扱うUniTを提案。
CoT推論と候補選択を組み合わせ、複数ベンチマークで有効性を示した。
## キーワード
マルチモーダルLLM, Chain-of-Thought, テスト時スケーリング
GitHubリポジトリ内の保存構成
arxiv_summaries/
├── INDEX.md
├── stats.json
├── processed_papers.json
├── budget_history.json
└── cs.*/YYYY-MM/YYYY-MM-DD.{md,json}
コスト最適化のまとめ
| 施策 | 効果 | 実測 |
|---|---|---|
| 重複排除 | 想定20〜30%削減 | 今回: 4/25論文スキップ(16%) |
| 週1実行 | 頻度最適化 | 月4回 × $0.20 = $0.80 |
| 予算制限 | 暴走防止 | 日額$0.50、月額$10上限 |
| カテゴリ選定 | 必要最小限 | 5カテゴリに絞り込み |
結論: 本検証条件(週1・5カテゴリ・各5件)では、月額約$0.8〜$1.0で運用可能です。
まとめ
本記事では、arXiv論文の自動要約システムを以下の技術で実装しました:
- Claude Sonnet 4.5 — 高品質な日本語要約
- GitHub Actions — 週次自動実行
- PyGithub — カテゴリ・月別の整理保存
- Slack Block Kit — チームへのリアルタイム通知
- 重複排除 + 予算管理 — コスト最適化
おわりに
論文の調査を自動化しました。
Claude APIの使い方や、Slackへの通知などを学習できました。
参考リンク
- GitHubリポジトリ: https://github.com/MameMame777/arxiv-summaries
- Claude API Documentation: https://docs.anthropic.com/
- arXiv API: https://info.arxiv.org/help/api/index.html