
毎朝、AIが選んだ1本が届く。RSS×LLMで作るニュース配信と“重複させない”工夫
こんにちは!Accel-Hack (アクセルハック)開発チームです。
社内AIアシスタント「Airi」の開発プロセスをお届けする開発記ブログ。
第16回目の今回から、連載は新しい章に入ります。
これまでは「頼まれたことをこなす」機能を作ってきましたが、ここからは Airi が自分から情報を届けにくる機能たちの紹介です。
第一弾は、毎朝エンジニア向けのニュースを届ける news機能 です。
前回の Vol.15 までで、打刻・申請・入社といった「依頼応答型」の機能が出揃いました。
今回はその発想を反転させ、ユーザーが何もしなくても価値が届く仕組みを作ります。
しかも、ただ配るだけではありません。
数あるニュースの中から「今日の1本」をAIに選ばせ、なおかつ無駄なく一度だけ処理する工夫が、この機能の見どころです。
1. 「調べる」を待たない。届くという価値
技術のトレンドを追うのはエンジニアの習慣ですが、忙しい日々の中でニュースサイトを巡回するのは、意外と後回しになりがちです。
「あとで読もう」がたまっていく感覚は、誰しも覚えがあるのではないでしょうか。
そこで Airi は、毎朝、その日の注目IT記事を1本だけ Slack に届けることにしました。
大量のニュースをそのまま流しても埋もれるだけ。
だからこそ「1本に絞る」ことに意味があります。
エンジニアが朝いちばんに Slack を開くと、AIが選んだ話題が待っている――情報を「探しにいく」から「向こうから届く」へ。
この小さな転換が、チームの学びの習慣を後押しします。
2. 仕組みの骨格
処理の流れそのものは、驚くほどまっすぐです。
Vol.7 で設定した Cron Trigger(定時実行) が毎朝 getDailyNews() を起動し、次の一直線を辿ります。
RSS を取得 → AIが1本選定 → Slack に配信 → Home にも表示。
シンプルですが、この中に「軽量に扱う」「AIに任せる」「無駄なく一度だけ」という3つの工夫が詰まっています。
順に見ていきましょう。
3. RSS を“生”で、軽量に扱う
ニュースの仕入れ先は、Yahoo ニュースの IT トピックス RSS です。
RSS は記事一覧を配信する昔ながらの仕組みで、URL を叩けば記事のタイトルやリンクが XML で返ってきます。
Airi では、この XML を専用ライブラリを使わず、正規表現で軽くパースしています。
<item> の中からタイトル・リンク・日付を抜き出し、対象期間のものだけを残して、最大20件に絞る。
たったこれだけです。
const res = await fetch("https://news.yahoo.co.jp/rss/topics/it.xml");
const xmlText = await res.text();
// <item> から title / link / pubDate を正規表現で抽出し、期間で絞り込む本格的なXMLパーサを持ち込めば厳密ですが、バンドルサイズがシビアなエッジ環境(Vol.7)では、依存を増やさない軽さも立派な設計判断です。
「必要十分に、軽く」――エッジらしい割り切りです。
4. AIに「1本選んでもらう」
集めた20件を、次は LLM に丸ごと渡します。
プロンプトはとてもストレート。
「この一覧から、ITエンジニアにとって最も面白そうなものを1つ選び、タイトル・URL・推薦理由を出力して」とお願いするだけです。
ここで効いてくるのが、Vol.8 の Drizzle でも活躍した Zod スキーマです。
出力の“型”をあらかじめ定義しておくことで、LLM の返答を「タイトル・URL・コメント」という決まった形の構造化データとして、安全に受け取れます。
const newsSelectionSchema = z.object({
title: z.string().describe("選定したニュースのタイトル"),
url: z.string().describe("選定したニュースのURL"),
comment: z.string().describe("なぜ面白いのか、エンジニア向けに1〜2文で"),
});
「AIに選ばせて、結果は型で受け止める」。
この組み合わせによって、単なる転載ではない、推薦コメント付きの“キュレーション”が自動で生まれます。
5. 賢く、一度だけ――KVキャッシュと分散ロック
さて、ここが最大の工夫です。
この定時ジョブ、実は同じ日に複数回起動される可能性があります。
そのたびに RSS を取得し、LLM に問い合わせていては、無駄なAPIコストがかさむうえ、日によって「今日の1本」がコロコロ変わってしまいます。
そこで Airi は、「その日の選定は一度だけ」を徹底しています。

まず Vol.7 の KV に「今日の1本」がキャッシュされていないかを確認します。
あれば、それを即座に返して終了。
無ければ、分散ロック(withKvLock)を取得してから RSS 取得と LLM 選定に進み、結果を KV に24時間の期限付きで保存します。
このロックが、地味ですが重要です。
もし複数の処理がほぼ同時に「キャッシュが無い!」と判断しても、実際に取得・選定を行えるのはロックを取れた1つだけ。
他は少し待ってから、先に完成したキャッシュを共有して受け取ります。
おかげで、RSS取得もLLM呼び出しも、その日はきっちり1回。
コストと一貫性を、この小さな仕組みが守ってくれています。
6. おわりに
今回は、Airi が「自分から情報を届ける」第一歩として、RSS × LLM × KV で組み立てたニュース配信をお届けしました。
軽量にニュースを仕入れ、AIに1本選ばせ、キャッシュとロックで無駄なく一度だけ。
派手ではありませんが、コストと品質の両方に目を配った、実運用に耐える設計です。
次回は、同じ「自動化」でも、チームの活動そのものに光を当てます。
「Vol.17: 日報は書くだけ、まとめはAIが。KV×D1×LLMで作る進捗の自動可視化」 として、日報・週報スレッドの自動生成と、LLM を使った1週間の進捗サマリーの仕組みをお届けします。
お楽しみに!
この記事は以下の体制で作成されました。
ドラフト作成・執筆: Airi (社内AIアシスタント)
アイデア出し・レビュー: CTO
デザイン: 事務スタッフ
Accel-Hackでは、テクノロジーを駆使して世の中の課題を解決していく仲間を募集しています。
私たちの取り組みに少しでも興味を持っていただけたら、ぜひ採用ページや会社サイトも覗いてみてくださいね。