Cloudflare Workers + OpenAIで「AIインフラニュースBot」を作ってみた
TL;DR
Cloudflare Workers + OpenAI + D1 + Slack RSS App を使って、
AIインフラ関連ニュースを収集
↓
OpenAIで分類・要約
↓
重要なニュースだけランキング
↓
RSSとして再配信
↓
Slackへ通知
する「AI Infra News Bot」を作りました。
特徴:
- Cloudflare Workersでサーバレス運用
- OpenAI Batch処理で低コスト化
- D1で記事管理
- Slack RSS App利用でWebhook不要
- Top5ランキングでノイズ削減
- Freshness Emojiで一覧性改善
こんな人向け:
- AIインフラ情報を追いかけたい
- GPU/HPC/AI Factory系ニュースを整理したい
- Cloudflare Workersを触ってみたい
- 軽量AI SaaSを作ってみたい
完成イメージ:
🟥🏭 [AI Factory] NVIDIA launches ...
投稿日:
2026/05/09 14:22
Executive Summary:
NVIDIAが新しいAI Factory向けネットワークアーキテクチャを発表。
Implication:
AI Factory競争はGPU単体ではなく、East-West通信設計競争へ移行。
Cloudflare Workers + OpenAIで「AIインフラニュースBot」を作ってみた
はじめに
AIインフラ関連のニュースは、
- NVIDIA
- Cloudflare
- AWS
- Google Cloud
- OpenAI
- Anthropic
- HPCWire
- Kubernetes
など、多数の媒体に分散しています。
さらに、単純にRSSを購読するだけでは、
- ノイズが多い
- 同じ話題が大量に来る
- 「なぜ重要か」が分からない
- AIインフラ観点での意味づけが欲しい
という課題がありました。
そこで今回は、Cloudflare Workers + OpenAI を使って、
AIインフラ関連ニュースを収集
↓
OpenAIで分類・要約
↓
重要なニュースだけ選別
↓
RSSとして再配信
↓
Slack RSS Appで購読
する「AI Infra News Bot」を作ってみました。
完成イメージとしては、Slackに以下のような投稿が流れます。
🟥🏭 [AI Factory] NVIDIA launches ...
投稿日:
2026/05/09 14:22
Executive Summary:
NVIDIAが新しいAI Factory向けネットワークアーキテクチャを発表。
Technical Summary:
- NVLink Switch強化
- GPU間通信改善
- 推論クラスタ最適化
Implication:
AI Factory競争はGPU単体ではなく、
East-West通信設計競争へ移行。
この記事では、このシステムの作り方を解説します。
システム構成
今回の構成は以下です。
External RSS Feeds
↓
Cloudflare Workers Cron
↓
RSS Collection
↓
OpenAI Batch Analysis
↓
Ranking / Filtering
↓
Cloudflare D1
↓
/feed.xml
↓
Slack RSS App
ポイントは、
Slack Incoming Webhook
ではなく、
Slack RSS App
を利用する点です。
これにより、
- Slack App作成不要
- Bot token不要
- OAuth不要
- 管理者承認ハードルが低い
というメリットがあります。
使用技術
| 項目 | 技術 |
|---|---|
| Runtime | Cloudflare Workers |
| Database | Cloudflare D1 |
| AI | OpenAI API |
| Feed Parsing | fast-xml-parser |
| Framework | Hono |
| Notification | Slack RSS App |
| Deploy | Wrangler |
WSL2環境準備
まずはWSL2(Ubuntu)環境を準備します。
sudo apt update
sudo apt install -y curl git build-essential unzip
Node.jsはnvm経由で導入。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
source ~/.bashrc
nvm install --lts
確認。
node -v
npm -v
Cloudflare Workersプロジェクト作成
Wranglerを導入。
npm install -g wrangler
Cloudflareへログイン。
wrangler login
プロジェクト作成。
npm create cloudflare@latest ai-infra-news-bot
cd ai-infra-news-bot
選択肢は以下でOK。
Hello World example
Worker only
TypeScript
ライブラリ導入
npm install hono openai fast-xml-parser
D1 Database作成
npx wrangler d1 create ai_infra_news
出力された database_id を wrangler.jsonc に設定。
{
"d1_databases": [
{
"binding": "DB",
"database_name": "ai_infra_news",
"database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
}
Migration作成
mkdir -p migrations
migrations/0001_create_articles.sql
CREATE TABLE IF NOT EXISTS articles (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
url TEXT NOT NULL UNIQUE,
source TEXT,
published_at TEXT,
summary TEXT,
category TEXT,
relevance_score INTEGER,
implication TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
ローカル適用。
npx wrangler d1 migrations apply ai_infra_news --local
環境変数設定
.dev.vars
OPENAI_API_KEY=sk-xxxxx
RSS Feed定義
const FEEDS = [
// Cloud / Edge
"https://blog.cloudflare.com/rss/",
"https://aws.amazon.com/blogs/machine-learning/feed/",
"https://cloudblog.withgoogle.com/rss",
"https://azure.microsoft.com/en-us/blog/feed/",
// GPU / AI Factory
"https://blogs.nvidia.com/feed/",
"https://developer.nvidia.com/blog/feed/",
// AI Labs
"https://openai.com/news/rss.xml",
"https://www.anthropic.com/news/rss.xml",
"https://huggingface.co/blog/feed.xml",
// HPC
"https://www.hpcwire.com/feed/",
"https://www.nextplatform.com/feed/",
// OSS
"https://kubernetes.io/feed.xml",
];
RSS取得
fast-xml-parser を使ってRSS/Atomをパースします。
import { XMLParser } from "fast-xml-parser";
async function collectFeeds() {
const parser = new XMLParser({
ignoreAttributes: false,
});
const articles = [];
for (const feedUrl of FEEDS) {
const res = await fetch(feedUrl);
if (!res.ok) continue;
const xml = await res.text();
const parsed = parser.parse(xml);
// RSS
if (parsed.rss?.channel) {
const channel = parsed.rss.channel;
const items = Array.isArray(channel.item)
? channel.item
: [channel.item];
for (const item of items) {
articles.push({
source: channel.title,
title: item.title,
url: item.link,
publishedAt: item.pubDate,
});
}
}
}
return articles;
}
OpenAIによるBatch分析
最初は、
1記事 = 1 API call
で作っていましたが、RPM制限にすぐ到達しました。
そのため、
20記事 = 1 API call
に変更しています。
これがかなり重要です。
const response = await openai.responses.create({
model: "gpt-4.1-mini",
input: [...],
text: {
format: {
type: "json_schema",
name: "ai_infra_news_batch_analysis",
schema: {
type: "object",
properties: {
analyses: {
type: "array",
items: {
type: "object",
properties: {
index: {
type: "integer"
},
relevance_score: {
type: "integer"
},
category: {
type: "string"
},
executive_summary: {
type: "string"
},
technical_summary: {
type: "array",
items: {
type: "string"
}
},
implication: {
type: "string"
}
}
}
}
}
}
}
}
});
ランキング処理
ニュースが大量に来るので、
「本当に重要な5件だけ出す」
ようにしています。
ランキング要素:
- relevance_score
- freshness
- category weight
例えば:
const totalScore =
analysis.relevance_score * 3 +
freshness * 2 +
categoryWeight;
でスコアリング。
その後:
scored.sort((a, b) =>
b.totalScore - a.totalScore
);
const selected = scored.slice(0, 5);
でTop5を選別。
鮮度Emoji
Slack RSS Appでは一覧性が重要なので、タイトルに鮮度emojiを付けています。
function freshnessEmoji(dateString: string): string {
const diffHours = ...;
if (diffHours <= 24) {
return "🟥";
}
if (diffHours <= 72) {
return "🟨";
}
return "⬜";
}
カテゴリemojiも追加。
function categoryEmoji(category: string): string {
switch (category) {
case "GPU":
return "🖥️";
case "AI Factory":
return "🏭";
case "HPC":
return "⚡";
case "Cloud":
return "☁️";
default:
return "📰";
}
}
RSS Feed生成
/feed.xml をWorkersから返します。
app.get("/feed.xml", async (c) => {
const rows = await c.env.DB.prepare(`
SELECT *
FROM articles
ORDER BY created_at DESC
LIMIT 20
`).all();
const items = rows.results.map((article: any) => `
<item>
<title>
${freshnessEmoji(article.published_at)}
${categoryEmoji(article.category)}
[${article.category}]
${article.title}
</title>
<link>${article.url}</link>
<description><![CDATA[
投稿日:
${article.published_at}
Executive Summary:
${article.executive_summary}
Implication:
${article.implication}
]]></description>
</item>
`).join("\n");
return new Response(xml, {
headers: {
"Content-Type": "application/rss+xml"
}
});
});
Cron設定
日本時間:
- 07:00
- 12:00
- 18:00
に実行。
Cloudflare CronはUTC基準なので:
"triggers": {
"crons": [
"0 22 * * *",
"0 3 * * *",
"0 9 * * *"
]
}
としています。
Deploy
npx wrangler deploy
デプロイ後:
https://ai-infra-news-bot.<subdomain>.workers.dev/feed.xml
が公開されます。
Slack RSS App登録
Slackで:
/feed subscribe https://xxx.workers.dev/feed.xml
を実行。
これでAI要約済みニュースがSlackへ流れます。
実際に運用してみて感じたこと
今回作ってみて特に重要だったのは:
Batch化
です。
LLM APIは:
大量の小さいリクエスト
より:
少数の大きいリクエスト
のほうが圧倒的に扱いやすい。
また、Slack RSS Appを利用したことで:
- OAuth
- Bot token
- Slack App承認
を回避でき、かなりシンプルな構成にできました。
今後やりたいこと
今後は:
- embedding-based deduplication
- Obsidian連携
- 記事本文取得
- 週次AIインフラレポート生成
- source trust scoring
- novelty detection
- ABCI relevance scoring
などを試していきたいと思っています。
おわりに
Cloudflare Workers + OpenAI は、
軽量AI SaaS
を作るのにかなり相性が良いです。
今回のような:
- RSS aggregation
- AI filtering
- Slack integration
- Knowledge feed
系の用途では特に強力でした。
同じような情報収集基盤を作りたい方の参考になれば幸いです。