2026年現在、AI技術の進化スピードはますます加速しています。「TLDR AI」や「AlphaSignal」などの海外ニュースレター、国内の主要ITメディアから日々発信される膨大な情報をキャッチアップすることは、多忙なエンジニアやスタートアップ経営者にとって極めて困難な課題です。
しかし、単に要約ニュースをSlackで受け取るだけの一方向の通知ツールでは、結局「読む時間がなくて未読が溜まる」という状態に陥りがちです。これからの時代に必要なのは、流れてきたニュースに対して「この技術は自社の開発にどう応用できるか?」「競合ツールとの違いは何か?」をその場ですぐにディスカッションできる自律的なパートナーです。
本記事では、RSSリーダー「Feedly」のフィード情報や各種技術ブログのRSSをトリガーに、OpenAI APIとSlack Bolt SDKを組み合わせて、Slackスレッド上でインタラクティブに壁打ちができる「AI技術顧問ニュースエージェント」を完全に内製する手順を解説します。
1. システムの全体像とアーキテクチャ
このシステムは、以下の3つのステップで動作します。
- ステップ1(定期収集&自動要約):
feedparserを用いてFeedlyなどでまとめた各種RSSフィードから最新記事を取得。OpenAI API(gpt-4o)で「サマリ」「想定されるビジネス影響」「関連推奨スタック」を自動生成し、社内Slackに投稿します。 - ステップ2(リレーションの保存): Slackに投稿した際の「スレッドID(タイムスタンプ:ts)」と、ニュース記事の本文をSQLiteデータベースに紐づけて保存します。
- ステップ3(スレッド内でのインタラクティブ対話): メンバーがSlackの投稿スレッドで「このフレームワークをNext.jsに導入する際、セキュリティ面の懸念はある?」などと質問すると、Slack Boltがイベントを検知。データベースから該当ニュースの元データを引き出してコンテキストに注入し、専門的な回答をスレッドに返します。
2. 開発環境の準備とライブラリのインストール
まずは必要なPythonライブラリをインストールします。非同期処理とSlackのSocket Modeに対応するため、以下のライブラリ群を使用します。
pip install slack_bolt feedparser openai python-dotenv
次に、プロジェクトのルートディレクトリに.envファイルを作成し、各種認証情報を設定します。Slack Appの設定画面から「Socket Mode」を有効化し、必要な権限(app_mentions:read, channels:history, chat:write)を付与しておいてください。
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
OPENAI_API_KEY=sk-proj-your-openai-api-key
SLACK_CHANNEL_ID=C0123456789 # ニュースを投稿するチャンネルID
3. データベース(SQLite)の設計
SlackのスレッドID(thread_ts)と、RSSから取得したニュース記事の全文およびURLを紐づけるため、軽量なSQLiteデータベースを使用します。これにより、ユーザーがスレッド内で質問した際に、AIが「どのニュースについて話しているか」を正確に把握できるようになります。
以下は、データベースを初期化するためのヘルパー関数です(db_manager.pyとして保存してください)。
import sqlite3
def init_db():
conn = sqlite3.connect("news_agent.db")
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS articles (
thread_ts TEXT PRIMARY KEY,
title TEXT,
link TEXT,
summary TEXT,
full_content TEXT,
published TEXT
)
""")
conn.commit()
conn.close()
def save_article(thread_ts, title, link, summary, full_content, published):
conn = sqlite3.connect("news_agent.db")
cursor = conn.cursor()
cursor.execute("""
INSERT OR REPLACE INTO articles (thread_ts, title, link, summary, full_content, published)
VALUES (?, ?, ?, ?, ?, ?)
""", (thread_ts, title, link, summary, full_content, published))
conn.commit()
conn.close()
def get_article(thread_ts):
conn = sqlite3.connect("news_agent.db")
cursor = conn.cursor()
cursor.execute("SELECT title, link, full_content FROM articles WHERE thread_ts = ?", (thread_ts,))
row = cursor.fetchone()
conn.close()
return row if row else None
4. メインプログラムの実装
RSSフィードをクロールしてSlackに要約を投稿するクローラー機能と、Slackスレッドでの対話をハンドリングするBoltサーバーを1つのスクリプトに統合します。以下のコードをapp.pyとして実装します。
import os
import feedparser
from datetime import datetime
from dotenv import load_dotenv
from openai import OpenAI
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from db_manager import init_db, save_article, get_article
load_dotenv()
# 各種初期化
init_db()
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
app = App(token=os.getenv("SLACK_BOT_TOKEN"))
RSS_FEEDS = [
"https://www.publickey1.jp/atom.xml", # 例: 国内IT技術ブログのRSS
# 必要に応じて任意のFeedly共有フィードや海外ニュースレターのRSSを追加
]
# 1. RSSから新着記事を取得し、AIで要約してSlackへ投稿する関数
def fetch_and_post_news():
channel_id = os.getenv("SLACK_CHANNEL_ID")
for feed_url in RSS_FEEDS:
feed = feedparser.parse(feed_url)
# 今回はデモとして、最新の1件のみを処理
for entry in feed.entries[:1]:
title = entry.title
link = entry.link
published = entry.get("published", datetime.now().isoformat())
content = entry.get("summary", "") or entry.get("description", "")
# OpenAI APIによるインテリジェントな要約の生成
prompt = f"""以下のITニュース記事をエンジニア向けに要約してください。
【タイトル】: {title}
【本文】: {content}
以下のフォーマット(プレーンテキスト)で出力してください:
■ 概要(3行以内)
■ 自社ビジネスへの影響・応用ポイント(2行以内)
■ 推奨技術スタック(関連する言語、フレームワーク、ツール)
"""
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
summary_text = response.choices[0].message.content
# Slackに基本情報を送信
slack_message = f"*【最新AI・ITトレンド】*\n*<{link}|{title}>*\n\n{summary_text}\n\n_※この記事について質問がある場合は、このスレッドでメンション付きで話しかけてください!_"
result = app.client.chat_postMessage(
channel=channel_id,
text=slack_message,
unfurl_links=False
)
# 投稿のタイムスタンプ(thread_ts)をキーにして、記事データをDBに保存
thread_ts = result["ts"]
save_article(thread_ts, title, link, summary_text, content, published)
print(f"Posted and saved thread: {thread_ts}")
# 2. Slackスレッド内でのメンション(質問)に対するインタラクティブ応答
@app.event("app_mention")
def handle_mentions(event, say):
thread_ts = event.get("thread_ts")
user_text = event.get("text")
user_id = event.get("user")
if not thread_ts:
# スレッド外でのメンションは、一般的な質問として受け付けるか、ガイダンスを返す
say("ニュースのスレッド内でメンションしていただければ、該当記事のコンテキストに基づいた専門的なアドバイスが可能です。")
return
# DBからスレッドに紐づく記事情報を取得
article_data = get_article(thread_ts)
if not article_data:
say("申し訳ありません。このスレッドに関連するニュースソースが見つかりませんでした。")
return
article_title, article_link, full_content = article_data
# コンテキストを考慮したOpenAIプロンプトの構築
prompt_messages = [
{
"role": "system",
"content": f"あなたは優秀なCTO兼技術顧問エージェントです。以下のニュース記事(タイトル: {article_title})に関する質問に、技術的な観点から具体的かつ客観的に答えてください。\n【記事本文】: {full_content}"
},
{
"role": "user",
"content": user_text
}
]
# スレッドへの返信であるため、インジケータを表示しながら回答を生成
say(text="技術分析を行っています。少々お待ちください...", thread_ts=thread_ts)
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=prompt_messages,
temperature=0.5
)
reply_text = response.choices[0].message.content
# Slackの同じスレッドに回答を投稿
say(
text=f"<@{user_id}> さん、ご質問ありがとうございます。このニュースに関する私の見解です:\n\n{reply_text}",
thread_ts=thread_ts
)
if __name__ == "__main__":
# クローラーの手動実行(通常はcronやバックグラウンドタスクで定期実行)
# fetch_and_post_news()
# Socket ModeでSlackアプリを起動
handler = SocketModeHandler(app, os.getenv("SLACK_APP_TOKEN"))
handler.start()
5. システムを200%使いこなす運用のコツ
このシステムをさらに実用的に運用するためのポイントを3つご紹介します。
① RSSソースの精緻なパーソナライズ
Feedlyの有料プラン(Feedly Pro+)を利用している場合、AI Feeds機能(Leo)を用いて事前にノイズ(宣伝記事や無関係なニュース)を除去したフィードを作成できます。そのフィードのRSS URLをシステムに登録することで、「真に価値のあるトレンド情報」だけをSlackに自動集約するフィルタリング網が構築されます。
② cronやGitHub Actionsによるスケジュール実行
新着記事のチェック(fetch_and_post_news関数)は、サーバー上のcronジョブや、GitHub Actionsのスケジュールトリガー(例: 毎朝8時)を利用して自動化するのが最適です。これにより、毎朝出社したタイミングで自動的に最新ニュースがSlackに蓄積された状態を作ることができます。
③ RAG(検索拡張生成)へのシームレスな移行
この記事では軽量化のためにSQLiteを使った「単一スレッド内のコンテキスト注入」を実装していますが、記事データを「Chroma」や「Pinecone」などのベクトルデータベース(Vector DB)に蓄積するように変更すれば、過去数ヶ月分の全ニュースデータから横断的に情報を検索して回答できる「自社専用のAIトレンド検索エンジン」へ簡単にアップグレードできます。
6. まとめ:情報を受け取る側から「AIを指導する側」へ
2026年、AIをただの「作業効率化の道具」として使っているだけでは、次々と登場する新しいサービスに圧倒されてしまいます。今回のように、情報のインプット、フィルタリング、そしてそれに対するディスカッションまでを自律型のエージェントシステムとして構築することで、あなたの働き方は「作業者」から「AIを監督し、経営判断を下す指導役」へと大きくシフトします。
まずは今回紹介したPythonコードをベースに、自社Slackに「技術顧問」を一人雇ってみてはいかがでしょうか?
関連サイト: https://www.aegis4.net/