1. はじめに
最近、経済・産業ニュースを迅速にモニタリングする必要性が高まり、ニュースデータを自動収集し、LLM を活用してカテゴリ分類を行うシステムを構築しました。
本システム「NEPER」は、現在 ニュース収集 → 前処理 → LLM分類 → データ保存 までの主要パイプラインを実装済みです。
この記事では、NEPER の技術構成、実装内容、そして今後の開発予定について紹介します。
2. 全体アーキテクチャ(現在実装済み範囲)
News Sources
↓
Collector (Firebase Functions)
↓
Preprocess / Cleaning
↓
Google AI (LLM Category Classification)
↓
Firestore / Storage
↓
(開発予定) Nuxt3 Dashboard (SSR)
※ ダッシュボード部分は現在設計中で、今後実装予定です。
3. ニュース収集パイプライン
NEPER は RSS、公開 API、静的 HTML ページなど、複数のニュースソースからデータを取得できるようにしています。
収集段階で行っている処理:
- 重複 URL の排除
- URL 正規化
- タイトル抽出
- 極端に短い記事のフィルタリング
- 文字化け防止・エンコーディング調整
例:
export const fetchNews = async () => {
const res = await fetch(RSS_URL);
const xml = await res.text();
const parsed = parseRSS(xml);
return parsed.items.map(item => ({
title: item.title,
link: item.link,
published: item.pubDate
}));
};
4. LLM によるカテゴリ分類
Google AI (Gemini) を使用し、ニュースタイトルをカテゴリー分類しています。
const result = await model.generateContent({
contents: [{ role: "user", parts: [{ text: title }] }]
});
const category =
result.response.candidates?.[0]?.content.parts?.[0]?.text
?? "uncategorized";
多言語対応のための工夫
Google が返すカテゴリは英語ベースのため、NEPER では独自のカテゴリツリーを多言語マッピングして使っています。
例:
Business/Economy/Stock
→ ko: ビジネス/経済/株式
→ ja: ビジネス/経済/株式
5. Firestore のデータ構造
{
"title": "...",
"link": "...",
"publishedAt": "...",
"category": "Business/Market",
"score": 0.82,
"lang": "ja",
"createdAt": 123456789
}
設計上のポイント:
- 正規化されたカテゴリパス
- クエリ性能を意識した軽量スキーマ
- 重複データを避ける単一コレクション構成
6. 技術的に難しかった点
6.1 タイトルの曖昧性
ニュースタイトルは短く、主語が省略されがちで精度が落ちるため、プロンプト調整を行いました。
6.2 LLM コスト最適化
- LLM 呼び出し前の重複排除
- トークン無駄削減のための前処理
- 最小限の問い合わせ構造に最適化
6.3 Firestore インデックス最適化
- 複合インデックスの削減
- タイムスタンプ中心のシンプルな検索構造
7. 今後の開発予定(ロードマップ)
現在未実装で、これから開発予定の機能です。
- Nuxt3 (SSR) ベースのダッシュボード
- トレンド分析および期間別集計
- カテゴリ別統計・可視化
- 多言語 UI
- 経済シグナルのスコアリング
- 簡易的な時系列予測モデル
8. まとめ
NEPER は 「ニュース → 構造化データ → 意味のあるシグナル」 へ変換するパイプラインを自動化することを目的に構築しています。
現時点では主要 ETL と LLM 分類が完了しており、今後はダッシュボードと分析基盤を拡張していく予定です。
同様のシステムを検討されている方の参考になれば幸いです。
