0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloudflare Workers + OpenAIで「AIインフラニュースBot」を作ってみた

0
Posted at

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_idwrangler.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

系の用途では特に強力でした。

同じような情報収集基盤を作りたい方の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?