毎朝6時、スマホに「今日のAIニュース」が届きます。記事を選んだのも、日本語に要約したのも、音声で読み上げたのも、メールを送ったのも、すべてプログラムです。人間は一切関与していません。
この記事では、その仕組みをどう作ったか、そして89日間動かし続けて実際にいくらかかったかを、包み隠さず公開します。
作ろうと思ったきっかけは、自分の勉強と、生徒さんへの発信のためでした。 毎日AIの最新ニュースを追いかけるのが、だんだん大変になってきたのです。
しばらくは、他の発信者の方が出しているAIニュースに頼っていました。 精度がとても高くて、正直それで十分だったからです。
風向きが変わったのは、Claude Fable が使えるようになってからでした。 自分の用途に合わせてカスタマイズしたニュースサイトのほうが、 明らかに使いやすくなったのです。「既製品より自作のほうが便利」という線を、 AIの性能が越えてきたという実感がありました。
結論:91号を配信して、追加でかかった費用は103円
先に結果からお見せします。
| 項目 | 実績 |
|---|---|
| 配信したダイジェスト | 91号 |
| 生成したポッドキャスト | 75エピソード |
| 自動で育った用語辞書 | 79語 |
| Claude API 料金 | 68円 |
| 音声合成(Google TTS)料金 | 35円 |
| サーバー代 | 0円(GitHub Pages) |
| 実行環境の費用 | 0円(GitHub Actions 無料枠) |
| 追加費用の合計 | 103円 |
「AIで自動化」と聞くと月数千円かかりそうに思えますが、やり方を選べばほぼ無料で回ります。ポイントは4つです。
- 記事の選別と日本語化を Claude Code のサブスクリプション枠で動かす(従量課金APIを使わない)
- 音声合成を無料のものに切り替える(
edge-ttsを使用。Google TTSは最初の8本のみ) - 実行環境とホスティングを無料枠で完結させる(GitHub Actions + GitHub Pages)
- 記事の選別を機械任せにせず、AIに「捨てさせる」
4つ目が効きます。当初は取得した50件をそのまま全部載せていましたが、 AIに「AIに実質的に関係する記事だけを残す」と指示して8〜12件に絞ったところ、 読みやすさが劇的に変わりました。自動化の質は、何を出すかより何を捨てるかで決まります。
サブスクリプション枠で動かす方法
Claude Code には claude setup-token というコマンドがあり、
長期トークンを発行して GitHub Actions のシークレットに
CLAUDE_CODE_OAUTH_TOKEN として登録すれば、月額プランの枠内で実行できます。
ここで一度ハマりました。環境に古い ANTHROPIC_API_KEY が残っていると、そちらが優先されて認証に失敗します。
有効なトークンを持っていても 401 が返るので、トークンを使うときは
API キーを子プロセスの環境から外す必要がありました。
全体の流れ
処理は毎朝1本のスクリプトが順番に実行しています。
① RSS/APIからニュースを収集
↓
② キーワードで5カテゴリに分類
↓
③ Claude Haiku で日本語タイトル+要約を生成
↓
④ HTMLダイジェストを組み立てて保存
↓
⑤ 台本を書いて音声合成 → ポッドキャストMP3
↓
⑥ GitHubにpush(=サイトが自動更新)
↓
⑦ メールで配信
これを GitHub Actions の schedule で毎日叩いているだけです。パソコンの電源は関係ありません。GitHubのサーバーが勝手に動いてくれます。
40日間、気づかずに止まっていた話
正直に書いておきます。この仕組み、途中で40日間まったく動いていませんでした。
原因は障害でも不具合でもなく、GitHub の画面で ワークフローを「Disable」したまま忘れていただけです。 毎朝メールが届かないことに気づくまで、それなりの日数がかかりました。
ここから得た教訓は、動かなくなったことに気づく仕組みまで含めて自動化しないと、 自動化は静かに死ぬということです。実行ログを見に行かないと分からない状態は、 実質的に監視していないのと同じでした。
なぜ「自分のパソコン」で動かさないのか
自動化でつまずきやすいのが、ここです。自分のPCで cron を組むと、PCを閉じている間は動きません。旅行に行けば止まります。
GitHub Actions ならクラウド側で実行されるので、こちらは何もしなくていい。しかもパブリックリポジトリなら実行時間は無料です。
on:
schedule:
# UTC 21:00 = 日本時間の翌朝6:00
- cron: '0 21 * * *'
workflow_dispatch: # 手動実行もできるようにしておく
ひとつ落とし穴があります。GitHub Actions は UTC(協定世界時)で動くため、Pythonの中で普通に「今日の日付」を取ると日本時間とズレて前日扱いになります。日本時間基準で日付を確定させる処理を必ず入れてください。
JST = timezone(timedelta(hours=9))
target_date = datetime.now(JST).replace(tzinfo=None)
① ニュースをどこから集めるか
有料のニュースAPIは使っていません。無料のRSSフィードだけで十分な量が集まります。実際に使っているソースは次のとおりです。
- TechCrunch AI
- VentureBeat AI
- The Verge AI
- MIT Technology Review
- WIRED AI
- Ars Technica
- Hacker News(Algolia の検索APIで新着を取得)
RSSは requests で取ってきて xml.etree.ElementTree で解析するだけ。専用ライブラリも不要です。日付の書式がソースごとにバラバラなので、そこだけ複数フォーマットを試す処理を書いておくと安定します。
② 選別と日本語化 ─ ここが品質を決める
最初の実装では、分類をキーワードマッチ、日本語化を Google 翻訳の無料エンドポイントで 処理していました。API 呼び出しがほぼゼロで済むので安上がりだったのですが、 出てくるものがひどかった。
- MIT Tech Review のニュースレター名 The Download が「ダウンロード」と誤訳される
- 「カスタマー サービス エクスペリエンス」のような不自然な分かち書き
- AI と無関係な記事(コンビニチェーンのシステム移行など)が「研究」カテゴリに混入
- 敬体と常体が同じページに混在
安く済ませた分がそのまま品質に出ていたわけです。ここを Claude に置き換えました。 やらせているのは4つです。
- AI に実質的に関係する記事だけを残す(無関係なものを捨てる)
- 同じ出来事を報じた記事を1本にまとめる
- 翻訳ではなく、日本語の見出しとして書き直す
- 「何が起きたか」に加えて「なぜ重要か」まで要約に含める
3番目が肝でした。「翻訳して」と指示すると直訳が返ってきます。 「日本語の見出しとして書き直して。固有名詞は訳さないで」と指示を変えるだけで、 出力の質がまるで変わりました。
要約の精度は高い。でも「レベル感」は合わない
実際に動かしてみて感じたのは、最近のAIの要約そのものは、もう十分に精度が高いということです。 事実関係を取り違えることはほとんどありません。
ただ、ずっと変わらない不満がひとつあります。 誰に向けて書いているのかがはっきりしていないと、レベル感が合わないのです。
同じニュースでも、業界の人に向けた要約と、これから学ぶ人に向けた要約は まったく別物になるはずです。ところが指示を出さないと、AIは 「なんとなく全方位に向けた、誰にも刺さらない中間の文章」を書いてきます。 用語の説明を省くべきか足すべきかの判断ができないからです。
この不満が、次に作る機能の出発点になりました。