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?

Claude Codeで競合X分析を自動化する:ループエンジニアリングで作るAIスペシャリストチーム

0
Last updated at Posted at 2026-06-23

🧭 本記事は Claude Code実務運用シリーズ の STEP 6「サブエージェント化する」です。
同じ設計を開発以外(競合X分析)に横展開できることを確認します。
シリーズ全体の地図と読む順は 親記事 にまとめています。

ChatGPT Image Jun 27, 2026, 03_17_48 PM.png

毎週の競合X(旧Twitter)動向レポートを、Claude Code で「データ取得 → 差分分析 → 検証 → PowerPoint 生成」まで半自動で回しています。設計の下敷きは ループエンジニアリング(Addy Osmani, Loop Engineering)。「設計の対象を “1回の振る舞い” から “回り続ける仕組み全体” に上げる」という考え方です。

ただし題材が 「数値KPI」ではなく「定性的な競合分析」 だったことで、定石どおりにはいきませんでした。本記事は、この仕組みを どう設計したか を実コードで具体化したものです。結論を先に言うと——

定性レポートでは決定論チェック(A)の射程は驚くほど狭く、主役は別モデルの評価役(B)になる。

この一点を中心に、ループの骨格と各パーツの実装を順に見ていきます。

題材は実在の競合Xアカウント(公開情報)ですが、評価基準・自社アクション・実数値はすべて架空のサンプルに置き換えています。手法だけ持ち帰ってください(情報は 2026/06 時点)。

対象読者

  • 定例の「調査・分析レポート」を毎週手で作っていて、AIに任せたいが品質が不安な人
  • 単発のAI自動化はできたが、「回り続ける仕組み」にしたい人
  • 出力が 数値ではなく文章・判断 の比率が高いレポートを自動化したい人(ここが本記事の主眼)

この記事で得られること

  • 「生成役と評価役を分ける」を、再計算できない定性レポートでどう実装するか
  • 本当に防ぐべき事故は「レイアウト崩れ」ではなく 「空データからの捏造」 だという視点と、その潰し方
  • 社名を知らなくてもブランドカラー規則を強制する 決定論チェックの小技
  • 全部入りの検証スクリプト(標準ライブラリ+python-pptx だけ、そのまま流用可)

題材:競合X週報パイプライン

やっていることはシンプルです。

  1. 取得:競合6社の公式Xアカウントのタイムラインを、ログイン済みブラウザ越しにスクレイプ(投稿本文・日時・views/RP)
  2. 分析:前週レポート(latest.md)と差分を取り、「今週何が変わったか・戦略の意図・自社への示唆」を Markdown で生成
  3. 生成:固定テンプレートの PowerPoint に、テキストだけ差し替えて経営層向けスライド化
  4. 検証 → 保存

よくある数値集計レポート(KPI・障害件数など)との決定的な違いは、成果物の中身が「数字」ではなく「所見」だということです。件数集計なら素値から合算し直して突き合わせられますが、競合分析の中身は「ある競合は割引施策を“冠イベント化”した(観察)」「狙いは休眠ユーザーの呼び戻しだろう(推測)」のような 判断 です。引用する 82,000 views のような数字も、Xの桁丸め表示の概算で、算術的に再導出できません

この「再計算できなさ」を前提に、ループはこう組んでいます。

全体構成:オーケストレーションプロンプトが“ループ本体”

ChatGPT Image Jun 23, 2026, 10_58_05 PM.png

実際の起動は、「順番」と「中止条件」だけを書いた1枚のプロンプトから始まります。これがループ本体で、実作業は2つの台本に丸ごと委譲します。Boris Cherny の "I just write loops" を定例レポートに落とすと、こうなります。

以下を順番に実行してください。

1. prompt/weekly_x_competitor_prompt.md を読み込み、指示に従って実行する
   (レポート生成・保存まで)

2. latest.md の作成日が今日の日付に更新されていることを確認してから、
   prompt/competitor_slides_prompt.md を読み込み、指示に従って実行する
   (pptx 生成・保存まで)

ステップ1が失敗した場合(latest.md が更新されていない場合)は、
ステップ2に進まず理由を報告して終了してください。

このプロンプトは 何も生成しません。やっているのは ① step1 → step2 の順番 と、② ステップ間のゲート(latest.md の作成日が今日か) だけ。肝は、次工程に進む判断を 生成役の「できました」という自己申告ではなく、ファイルの状態(作成日) で決めていること。「完了は本人に名乗らせない」を、検証だけでなく オーケストレーション層 にも効かせています。

構成は3層です。

役割 中身(概要)
オーケストレーション ループ本体=順番+中止条件 上記プロンプト。step1 →(作成日ゲート)→ step2
台本①:レポート データ → Markdown 調査対象(A/B/C枠)/保存要件(latest.md+素値アーカイブ)/分析手順(差分・異常値・戦略推測)/出力形式/データ十分性ゲート検証2段(A・B)
台本②:スライド レポート → PowerPoint テンプレ方式の絶対ルール/7スライドの差し替え対応/ブランドカラーパレット/作業手順/決定論チェック(verify_deck)

オーケストレーションが委譲している2つの台本の中身を、抜粋で示します(実名・実数値はサニタイズ済み)。これを見ると、1枚のオーケストレーションプロンプトが「何を任せているか」が具体的に掴めます。

台本①:レポート(weekly_x_competitor_prompt.md/抜粋)
# 役割
競合電子書籍アプリのXアカウントから「今週の変化」を抽出し、前回レポートとの差分を出す。

# ブラウザ制約(厳守)
- 既存のログイン済みブラウザ(127.0.0.1:9222)にのみ接続。新規/自動操作専用ブラウザは起動しない。
- 接続できなければ代替手段を使わず停止して報告。

# 調査対象
- A. 直接競合(4社)… 投稿タイプ・訴求・キャンペーン・導線まで詳細に差分を取る
- B. 市場トレンド枠(2社)… 新施策/新訴求/高反応投稿の有無だけ軽量確認
- C. 月次枠(1社)… 実行日が月の第1週のときだけ確認

# 保存要件
- latest.md に上書き + weekly_x_competitor_report_YYYY-MM-DD_wXX.md
- スクレイプ素値を raw/YYYY-MM-DD_wXX/ にアーカイブ(削除しない)

# 出力ルール(差分のみ・事実/観察/推測を分ける・推測は明記・未確認は「確認できず」)

# 出力形式
1.今週の要点(3点) / 2.直接競合の変化 / 3.市場トレンド / 4.市場全体 /
5.異常値 / 6.戦略変化の解釈(推測) / 7.自社アクション(優先度A/B/C) / 8.来週の注目 / 9.保存結果

# データ十分性ゲート(生成の前に判定)
- A枠で2社以上が取得不可なら、生成せず中止して理由を報告

# 検証(評価役・2段)
(A) verify_report.py(決定論・最大3回) → (B) 別モデルで素値と突合(最大2回)
台本②:スライド(competitor_slides_prompt.md/抜粋)
# 目的
競合X分析を、非技術者でも「何を意思決定すべきか」が分かる形にスライド化する。

# テンプレート方式の絶対ルール
- python-pptx でテンプレートを開き、テキストの差し替えのみ。
- 図形・カード・帯の追加/移動/サイズ変更/色変更/フォント変更は禁止。
- 差し替えは run 単位で元の書式を維持。テンプレ本体は変更せず別名保存。

# スライド構成(全7枚)
1.タイトル / 2.今週の結論(番号カード3) / 3.市場の変化 / 4.競合の動き(数値カード3) /
5.異常値 / 6.自社への示唆(キーワード3) / 7.アクションプラン(A-1/A-2)

# ブランドカラー(色変更禁止の“唯一の例外”)
- 各社の指定色を社名箇所に適用。明るい塗りの上の文字は必ず濃色(白文字は禁止)。

# 検証(評価役・決定論)
- verify_deck.py を実行。フッター/週/日付の一致・差し替え漏れ・文字数超過・パレット規則をチェック(最大3回修正)。

ここで効いているのは、台本の側にも「止まる条件」を書いてあることです。台本①の「接続できなければ停止」「A枠2社以上欠けたら中止」、台本②の「テキスト差し替えのみ・図形や色は触るな」。オーケストレーションが順番とゲートを、台本が現場の禁止事項と検証を持つ。この二段構えが効きます。

全体の流れを図にすると、こうです。中止条件=ゲートを菱形で明示しているのがポイントです(ここで止まれることがループの安全装置)。

「順番とゲートだけ書く」「実作業と検証は台本に委譲する」。この分離が、毎週同じ品質でループを回せる土台になっています。なお、役の受け渡し(生成役→別モデルの評価役)を主題にした2段検証は、次節でシーケンス図として見せます。

ループの骨格:6パーツの割り当て

Addy はループに必要な道具立てを6パーツに整理しています。このパイプラインでは、Claude Code と周辺の機能をこう割り当てました。

パーツ 役割 このパイプラインでの実装
Automations 起動 週次トリガー(手動起動でも可。Xログイン状態に依存するため現状は半自動)
Connectors(MCP) 外部接続 ブラウザ操作MCPでログイン済みXのタイムラインを取得
Skills / 台本 手順の固定 weekly_x_competitor_prompt.md / competitor_slides_prompt.md に検証手順まで明文化
Sub-agents 生成役と評価役の分離 生成は本体/検証は別モデル(例: Haiku)のサブエージェント
Memory 状態の永続化 latest.md(前週比較の基準)+ raw/ の素値アーカイブ
決定論チェック トークン不要のゲート verify_report.pyverify_deck.py(後述)

この中で、定性レポートだからこそ重く効いたのが Sub-agents(評価役の分離) と、それを 台本に固定する こと、そして暴走を止める ハード上限 です。順に実装を見ます。

設計①:生成役と評価役を分ける ― ただし(A)の射程は狭い

検証は2段。ここが本記事の肝です。Addy の主張は「コードを書いた本人は自分の作業に甘い(A model grading its own output is too generous)」。だから生成役と評価役を分け、評価役はできれば別モデルにする。

(A) 決定論チェック:トークン不要で弾けるものだけ

数値集計レポートなら「素値から合算し直して突合」が主役になります。定性レポートでは、決定論で弾けるのはこれだけ です。

  1. 作成日が当日か
  2. 比較対象(前週ファイル名)が明記されているか
  3. 取得状況(取得不可の有無)が明記されているか
  4. レポート中のカンマ区切り数値が、スクレイプ素値のどこかに存在するか(=転記ミス検出。算術的な再計算はできないが、「素値に無い数字=どこかから持ってきた疑い」は機械的に言える)

4番だけが「数字の検証」で、しかも 再計算ではなく存在チェック にまで弱まっているのがポイントです。

# scripts/verify_report.py(抜粋)
# カンマ区切り数値(4桁以上)を抽出し、素値アーカイブに存在するか確認
figs = sorted(set(re.findall(r"\b\d{1,3}(?:,\d{3})+\b", md)))
unmatched = []
for fig in figs:
    plain = fig.replace(",", "")
    if (fig in blob) or (plain in blob):   # blob = raw/*.json を結合した素値
        ok(f"数値 {fig} は素値に存在")
    else:
        unmatched.append(fig)              # 派生値 or 転記ミスの疑い → (B)で確認

82,000(素値の表示値)は素値にある=OK」「8.2万view(私が本文用に丸めた派生値)は素値に無い=WARN で (B) に送る」。決定論で言えるのはここまで、と割り切ります。

(B) 別モデルの評価役:ここが主役

定性レポートの妥当性——事実/観察/推測の切り分け、他週・他社からの取り違え、取得不可アカウントを推測で埋めていないか——は、人間と同じく「読んで判断」しないと分かりません。だから (A) が PASS したら、生成役とは別モデル(例: Haiku)のサブエージェント に、latest.md と素値 raw/*.json を読ませて突き合わせさせます。

台本(プロンプト)にはこう固定してあります。

## (B) 検証サブエージェント(別モデルで文章を点検)
- (A) が PASS したら、別モデル(例: Haiku)に latest.md と raw/<...>/*.json を読ませ、
  - 各「変化・観察」が素値(実際の投稿)に裏付けられているか(捏造・取り違えが無いか)
  - 「事実 / 観察 / 推測」の切り分けが適切か
  - 「取得不可」を推測で埋めていないか
  を点検させる。要修正なら直して (A) からやり直す。往復は最大2回。

この2段の検証ループを図にすると、こうです。

数値集計レポートでは (A) が主・(B) が念押しになりがちですが、定性レポートでは比重が逆転 します。これが「数字が再計算できないレポート」での最大の設計判断でした。

設計②:データ十分性ゲート ― 本当の事故は“空データからの捏造”

評価役を入れても、そもそも入力データが空なら捏造を後追いで検出するだけ です。だから生成の前に止める決定論ゲートを置きます。

# データ十分性ゲート(生成の前に必ず判定)
- A枠(直接競合4社)で直近7日の新規投稿が1件も取れていないアカウントは「取得不可」と明記。
- A枠で2社以上が取得不可なら、差分分析の土台が崩れるので レポートを生成せず中止 し理由を報告。

「取れなかったら推測で埋める」ではなく「取れなかったら止める/明記する」。当たり前ですが、AIに任せると一番崩れる規律なので、コードと台本の両方 に書き下しています。Xはログイン要求で投稿が取れないことがあり、取れていないのに前週の記憶や“それっぽい推測”で埋まったレポート が、見た目だけ綺麗に出てしまうのが一番こわい事故だからです。

設計③:素値アーカイブ ― 遅延と「後から検証」に備える

ループエンジニアリングで一番AIっぽいと言われる落とし穴が「先週の値が翌日には変わっていた(遅延集計)」です。競合Xでも views/フォロワーは時間で動きます。だから スクレイプ素値を毎週 raw/YYYY-MM-DD_wXX/ に保存し、消さない

- 保存先: raw/YYYY-MM-DD_wXX/<account>.json(followers, 各投稿の dt/txt/aria を含む)
- このアーカイブは削除しないこと(突合可能な原本として残す)

これで「前週から継続」のような差分主張が、後から原本に当たって検証できます。(A)の数値トレーサビリティも、この原本があって初めて成立します。

設計④:スライドは固定テンプレ+テキストのみ+“社名を知らない”色チェック

スライド生成の原則はシンプルで、色・レイアウト・フォントはAIに触らせず、テキスト文言だけを差し替える(python-pptx で run 単位置換)。見た目を固定すると、毎週の差分が「数字と所見」だけになり、レビューが一瞬で終わります。

面白いのは、その決定論チェック側の工夫です。スライド4の各社ヘッダーバーは 週によって載る会社が変わる(今週はA社/B社/C社、来週は別の3社かもしれない)。なので「A社は黄色」と決め打ちで検査するとすぐ壊れます。代わりに 会社名を知らなくても成立する“規則そのもの” を検査します。

# slides/verify_deck.py(抜粋):パレット規則を会社非依存で強制する
BRAND_FILL  = {"F6AB00","E60012","0D2F54","2D5FAA","FFD400","06C755"}  # 6社の塗り
BRIGHT_FILL = {"F6AB00","FFD400"}  # 明るい塗り → 文字は必ず #2B2924

for bar, txt, card in [("Shape 5","Text 6","S4 カード1"),
                       ("Shape 11","Text 12","S4 カード2"),
                       ("Shape 17","Text 18","S4 カード3")]:
    bf = fill_hex(find(slide4, bar))
    if bf not in BRAND_FILL:                       # 塗りが6社ブランド色か
        fail(f"{card}: ヘッダーバー塗り={bf} がブランド色でない"); continue
    want = "2B2924" if bf in BRIGHT_FILL else "FFFFFF"   # 明/暗で文字色が決まる
    if run_color(find(slide4, txt), 0, 0) != want:
        fail(f"{card}: 社名文字色が塗り{bf}上の規則に反する")

「どの会社か」ではなく「明るい塗りの上に白文字を置いていないか」を見る。これなら毎週どの3社が来ても落ちません。差し替え漏れ(当週以外の週番号トークンの残存)や全角文字数オーバーも、ここで一緒に弾きます。soffice が無い環境でも動くので、画像化での目視に依存しません。

台本に固定する&ハード上限

肝心なのは、これらを 思いつきで毎回やらないこと。検証手順を2つのプロンプト(weekly_x_competitor_prompt.md / competitor_slides_prompt.md)に節として書き下し、毎週必ず同じ順で走るようにしています。

そして上限を切ります。Addy の言う "A loop running unattended is also a loop making mistakes unattended."(誰も見ていないループは、誰も見ていないまま間違え続ける)対策です。

  • (A) の修正ループ:最大3回
  • (B) の往復:最大2回
  • 超えたら未解決点を残して停止(トークン暴走の防止)

ここを切らないと、ログインが切れていたり投稿が取れない週に、ループが「直そう」として延々とトークンを焼き続けます。上限は品質のためというより、財布のための安全装置です。

回してみて効いた点/注意点

落とし穴 効いた防ぎ方
検証の積み残し 生成役と別の評価役((A)決定論+(B)別モデル)を台本に固定
空データからの捏造 データ十分性ゲートで生成前に中止(後追い検出より前で止める)
取り違え(先週/他社の所見の流用) (B)に素値との突合を明示的にやらせる
色・差し替え漏れ 会社非依存のパレット規則チェック+週トークン残存スキャン
トークン暴走 修正ループ・往復の回数にハード上限

派手に見えるのは (B) の別モデル評価役だけで、残りは 「素値を残す」「テンプレを固定する」「決定論で弾けるものだけ弾く」 という地味な配線です。けれど定性レポートで品質を安定させたのは、この地味な配線と、“自分で自分を採点しない” という一点でした。

まとめ:器はツールが用意する、物差しは人が持つ

この設計を一言でまとめると、こうなります。

数値レポートでは「素値から再計算して突合」が物差しになる。
定性レポートでは、再計算できる数字がほとんど無い。
だから物差しは「事実と推測を分けられているか」「取れていないものを取れたことにしていないか」という 判断基準 になり、それを別モデルと台本に書き下すしかない。

ツールが用意してくれるのは器(スケジュール・テンプレ・サブエージェント・素値の置き場)まで。「良い競合週報とは何か」 という物差しは、結局やってきた人間の中にしかありませんでした。

気になった方は、手元の定例レポートを1つ選んで、まず「素値の保存 → 固定テンプレ → 決定論で弾けるものだけ弾く → 残りは別モデルに読ませる」に分解してみてください。出力が数字寄りか判断寄りかで、(A)と(B)のどちらに重心を置くべきかが、すぐ腹落ちします。

参考


このシリーズの歩き方

Claude Code実務運用シリーズ ― 暴走させない、から仕組みにするまで。

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?