Gemini×Pythonで作る!全自動かつ「超・人間くさい」ブログ運営システムの裏側【第2回:3階層トレンド検索とファクトチェック】
連載第2回です。AIエンジニアとして日々LLMを触っていて思うのは、AIに「適当にトレンド記事を書いて」と指示しても、誰も検索しないようなフワッとしたポエムが出来上がるだけだということです。技術で承認欲求(と小遣い)を満たすには、「読まれるネタ」を戦略的かつシステマチックに発掘する必要があります。 ## 情報の入り口:RSSとGoogle News まずはトレンドの種を拾うところからです。`blogs.yml` に定義された各ブログ固有のソース(Google Newsの特定の検索クエリや、はてなブックマークのRSSなど)から、最新のニュースを引っ張ってきます。 ```python # trend_fetcher.py (一部抜粋) def fetch_trends(feed_url): parsed = feedparser.parse(feed_url) trends = [] for entry in parsed.entries[:5]: trends.append({"title": entry.title, "link": entry.link}) return trends ``` しかし、単なるニュースのタイトルをそのまま記事にしても、大手メディアにはSEOで絶対に勝てません。そこで「3階層トピック選定アルゴリズム」の出番です。 ## 3階層トピック選定アルゴリズム 拾ってきたニュースのタイトルをGeminiに渡し、以下の「3階層」でトピックをブレイクダウンさせます。 1. **Category (大粒度)**: 業界全体のニュース(例:「AIの進化と労働環境」) 2. **Interest (中粒度)**: 少し絞った興味関心(例:「AIを使った事務作業の効率化」) 3. **Query (超具体)**: ユーザーが実際に検索窓に打ち込む悩み(例:「Excel マクロ AI 自動生成 エラー 対処法」) プロンプト内で意図的に「超具体(70%)、中粒度(20%)、大粒度(10%)」の確率で出力するようにコントロールしています。 ```python prompt = f""" 以下のニュースソースをもとに、ブログのテーマをJSONで出力してください。 【確率コントロール】 以下の割合を目安に粒度を選択してください: - Category (大粒度): 10% - Interest (中粒度): 20% - Query (超具体): 70% 出力JSONフォーマット: {{ "granularity": "Query", "theme": "読者の具体的な悩みや検索キーワード" }} """ ``` 最新のLLMはこういう確率的な揺らぎを持たせた指示もかなり正確にこなしてくれます。これにより、長尾の検索キーワード(ロングテールSEO)を狙い撃ちした記事が自動生成されます。 ## 賢いファクトチェック(幻覚対策) 超具体的な検索クエリ(Query)を生成させたときによく起きる問題が、元のニュースソースとの乖離(ハルシネーション)です。例えば、政治のニュースから無理やり「主婦の節約術」のテーマをひねり出し、ソースとして政治ニュースのURLを添付してしまう現象です。 本システムでは、エンジニアリングによってこの幻覚をねじ伏せます。 ```python # fact_checker_service.py (一部抜粋) if not source_url or is_irrelevant(topic, source_url): # DuckDuckGoで生成されたテーマを再検索し、トップヒットを真のソースとする search_query = f"{topic} site:news.yahoo.co.jp OR site:itmedia.co.jp" new_source_url = search_duckduckgo(search_query) ``` 無関係なソースは破棄し、バックグラウンドでDuckDuckGoを叩いて「生成されたテーマに最もふさわしい現実のソース」を再取得して補完します。LLMの弱点を外部APIによるファクトチェックで補う、AIエージェントの基本的な設計思想です。 次回は、いよいよ本システムの真骨頂である「AIの無機質さを消す、MBTIペルソナ注入」について解説します。