オウンドメディア記事自動生成
補助金エージェント・スターター (バタフリー / キャタピー / トランセル)
補助金記事制作パイプラインを Claude Code のサブエージェント 3 体 で自律実行するためのスターターキット。
- バタフリー (
butterfree-subsidy-sync): 編集長。データ同期 + フロー管理 + 完了通知 - キャタピー (
caterpie-subsidy-writer): ライター。対話形式記事を執筆 + 図解画像生成 - トランセル (
metapod-subsidy-reviewer): レビュアー。22 項目チェックで品質ゲート
これ 1 セットを Claude Code に渡すと、毎時 :05 に「新しい補助金データを取り込む → 記事化が必要なものを抽出 → 1 件ずつ Writer が書く → Reviewer が査読 (合格まで最大 3 リトライ) → Discord に完了通知」を完全自律で回します。
---
⚠️ 配布物の前提と免責
これは hojokin-agent.jp の運用エージェントを「動く最小版」にダイエットしたものです。
- そのまま動かすには、最低限以下のセットアップが必要です (詳細は後述):
- Supabase プロジェクトを作って
supabase/schema.sqlを流す - Gemini / Jina の API キーを取る
.env.localを埋めるscripts/sync-data.sh(データ同期スクリプト) を自分のデータソースに合わせて書く
- 記事の表示 (Next.js + DialogueBubble コンポーネント + remark ディレクティブ) は同梱していません。記事は Markdown として DB に保存されるので、自分のフロントエンドで描画してください。Markdown のディレクティブ (
:::pointbox等) を解釈する remark プラグインが無い場合は、適宜 HTML や標準記法に書き換える必要があります。 - キャラ名・対話形式 (「佐藤」「室谷」「バタフリー」等) は補助金例のまま残しています。自分の業界に合わせて自由に差し替えてください。
- 無保証。コミュニティ配布用の参考実装です。
---
ディレクトリ構成
hojokin-agent-distribution/
├── README.md ← このファイル
├── .env.local.sample ← 環境変数テンプレ
│
├── .claude/
│ ├── agents/
│ │ ├── butterfree-subsidy-sync.md ← Orchestrator
│ │ ├── caterpie-subsidy-writer.md ← Writer
│ │ └── metapod-subsidy-reviewer.md ← Reviewer
│ ├── skills/
│ │ ├── agent-bootstrap/ ← 共通起動プロトコル (reflection)
│ │ ├── editorial-url-rules/ ← URL ルール
│ │ ├── subsidy-pipeline-orchestrator/ ← バタフリー専用 (フロー管理)
│ │ ├── subsidy-article-writer/ ← キャタピー専用 (執筆手順)
│ │ └── subsidy-article-reviewer/ ← トランセル専用 (査読手順)
│ ├── scripts/
│ │ └── notify-discord.sh ← Discord Webhook 通知
│ └── launchd/
│ ├── com.example.subsidy-pipeline.plist ← Mac launchd サンプル
│ └── cron-example.txt ← Linux cron 設定例
│
├── scripts/
│ ├── supabase-query.sh ← Supabase REST ラッパー
│ ├── start-reflection.sh ← reflection 行作成 + SQLite 自動初期化
│ ├── run-agent.sh ← top-level 起動 (launchd/cron から)
│ └── sync-data.sh ← データ同期 (★自分で実装★)
│
└── supabase/
├── schema.sql ← subsidies / prefectures / sync_logs + RLS
└── seed.sql ← サンプル補助金 3 件
---
セットアップ手順
1. 前提ソフトウェア
| ツール | 用途 | インストール |
|---|---|---|
| Claude Code CLI | エージェント実行 | https://docs.claude.com/claude-code |
| bash | 各種スクリプト | macOS / Linux に標準 |
| sqlite3 | reflection DB | macOS 標準 / apt install sqlite3 |
| curl | HTTP 通信 | 標準 |
| jq | JSON パース | brew install jq / apt install jq |
| python3 | check_article 実行 | 標準 |
2. プロジェクトを配置
# zip を展開した場所で
cd hojokin-agent-distribution
# .env.local を作成
cp .env.local.sample .env.local
3. Supabase プロジェクトを作成
- https://supabase.com にサインアップ → 「New Project」
- プロジェクト作成後、左メニュー → SQL Editor で
supabase/schema.sqlの中身を貼り付けて実行 - 動作確認用に
supabase/seed.sqlも実行 (サンプル補助金 3 件が入る) - Storage メニューで
article-imagesという名前の public バケットを作成
- File size limit:
5 MB - Allowed MIME types:
image/png,image/jpeg,image/webp
- Project Settings → API に移動して以下をコピーし、
.env.localに貼る:
Project URL→NEXT_PUBLIC_SUPABASE_URLservice_rolekey (★ anon key ではなく) →SUPABASE_SERVICE_ROLE_KEY
⚠️service_rolekey は RLS をバイパスする強力なキー。.env.localを絶対に commit しない。
4. AI API キーを取得
Gemini API (図解画像生成)
- https://aistudio.google.com/apikey にアクセス
- 「Create API key」で新規発行
.env.localのGEMINI_API_KEYに貼る- 料金: 無料枠あり (記事 1 本 = 図解 2 枚 ≈ 数円)
Jina AI (一次ソース取得)
- https://jina.ai/?sui=apikey にアクセス
- メール登録だけで API キーが発行される
.env.localのJINA_API_KEYに貼る- 料金: 月 1M トークンまで無料
5. Discord Webhook を作成 (任意)
完了通知が不要なら Skip 可。
- Discord サーバーの 設定 → 連携サービス → ウェブフック → 新しいウェブフック
- 名前・チャンネル・アイコンを設定して URL をコピー
.env.localのDISCORD_WEBHOOK_URLに貼る
6. 公開サイト URL を設定
PUBLIC_SITE_URL=https://your-domain.example を .env.local に書く。
ローカル検証だけなら http://localhost:3000 でも OK。
7. データ同期スクリプトを実装する (★必須★)
scripts/sync-data.sh は雛形のみ。自分のデータソースに合わせて中身を書きます。
例 1: jGrants API (政府の補助金検索) を使う場合
# scripts/sync-data.sh の中身を以下のような流れに
curl -s 'https://api.jgrants-portal.go.jp/exp/v1/public/subsidies?keyword=...' \
| jq -c '.result[]' \
| while read row; do
bash scripts/supabase-query.sh insert subsidies "$row"
done
例 2: 自治体の CSV を取り込む場合
curl -o /tmp/subsidies.csv https://example.pref.example/subsidies.csv
# CSV → JSON → Supabase upsert を python3 で書く
例 3: 既に Supabase に手動で入れている場合
scripts/sync-data.sh の中身は空のままでも OK。バタフリーが起動時に「未記事化リスト」を抽出して Writer に投げます。
8. 動作確認
手動起動 (Claude Code CLI 直接)
プロジェクトディレクトリで Claude Code を起動:
cd hojokin-agent-distribution
claude
Claude のプロンプトでバタフリーを呼ぶ:
バタフリー (butterfree-subsidy-sync) を起動して、補助金パイプラインを 1 周回してください。
→ Claude が .claude/agents/butterfree-subsidy-sync.md を読み、データ同期 → 未記事化リスト抽出 → Writer/Reviewer ループ → Discord 通知まで自律で動きます。
自動起動 (launchd / cron)
Mac (launchd):
# サンプル plist を編集して登録
sed "s|<YOUR_PROJECT_PATH>|$(pwd)|g" .claude/launchd/com.example.subsidy-pipeline.plist \
> ~/Library/LaunchAgents/com.example.subsidy-pipeline.plist
launchctl load -w ~/Library/LaunchAgents/com.example.subsidy-pipeline.plist
# 確認
launchctl list | grep subsidy-pipeline
Linux (cron):
.claude/launchd/cron-example.txt の中身を参考に crontab -e で登録。
---
アーキテクチャの要点
3 体の責任分離
- バタフリー (Orchestrator) が直接記事を書いたりレビューしたりすることは禁止。必ず
Task()ツールで subagent を呼ぶ。 - キャタピー (Writer) と トランセル (Reviewer) は Discord 通知禁止。バタフリーがまとめて通知。
- リトライループは最大 3 回。それ以上はスキップ。
skill 分離
各エージェントの agent.md は 人格・契約・自己診断のみ を持つ薄いラッパー。実行手順は .claude/skills/*/SKILL.md 側にあります。skill は agent.md の frontmatter skills: に書くと自動注入されます。
reflection (4 層)
全エージェントは起動時に .claude/db/agents.db の reflections テーブルに行を作り、完了時に 4 層 (what_done / quality_check / self_improvement / content_improvement) を書き込みます。subagent は parent_run_id で親に紐付けます。
DB は scripts/start-reflection.sh の初回実行時に自動作成されます。
品質ゲート
- Writer (キャタピー): 4 段階ファクトチェック + 3 段階プレデリバリー検証 (フォーマット / ファクト / レンダリング)
- Reviewer (トランセル): 22 項目チェックリスト +
check_articlePython 関数で E01〜E16 を機械検出 - 修正 vs 差し戻しの分岐:
- フォーマット系 (全角コロン、AI 臭フレーズ等) → Reviewer が直接修正
- 構造系 (話者逆転、図解画像不足等) → Writer に差し戻し
---
カスタマイズの指針
業界を変える
「補助金」以外で使いたい場合、最低限以下を書き換える:
- テーブル名:
subsidies→ 自分の業務エンティティ (e.g.,recipes,products)
supabase/schema.sql+ 全 skill 内のbash scripts/supabase-query.sh ... subsidies ...を一括 sed
- チェックリスト:
subsidy-article-reviewer/SKILL.mdの F 項目を自分の業界向けに書き換え - URL パターン:
editorial-url-rules/SKILL.mdの/subsidy/{id}を/recipe/{id}等に - 対話キャラ: 「佐藤・室谷」を自分のサイトのキャラに (
subsidy-article-writer/SKILL.md+subsidy-article-reviewer/SKILL.mdを一括 sed) - AI 臭フレーズ禁止リスト: 業界用語に合わせて追加・削除
キャラ名を変える
「バタフリー / キャタピー / トランセル」を別の名前に変えたい場合:
- 各
agent.mdのpokemon_jp:フィールド .claude/scripts/notify-discord.shのcase文- skill 内の言及
通知先を変える
.claude/scripts/notify-discord.sh を Slack / メール / LINE 等に書き換え。Webhook URL は .env.local から読む方式を維持すること。
データソースを変える
scripts/sync-data.sh の中身を書き換え。本配布版は雛形のみ。
---
トラブルシューティング
[supabase-query] ERROR: .env.local に NEXT_PUBLIC_SUPABASE_URL と SUPABASE_SERVICE_ROLE_KEY を設定してください
.env.local が無い、または読み込めていない。.env.local.sample をコピーして埋めること。
[notify-discord] DISCORD_WEBHOOK_URL not set in .env.local, skipping
Discord 通知を使わないなら無視して OK。使いたいなら .env.local の DISCORD_WEBHOOK_URL を埋める。
サブエージェントの reflection が親に紐付かない
バタフリーが Writer/Reviewer を呼ぶときの Task() の prompt 先頭で PARENT_RUN_ID={your AGENT_RUN_ID} を必ず渡す。これが無いと parent_run_id が NULL になり、ダッシュボードでツリーが切れる。
図解画像が記事に埋まらない
subsidy-article-writer skill は「画像 2 枚以上 + Supabase Storage で 200 OK」をプレデリバリー検証で必須としている。失敗してたら以下を確認:
article-imagesバケットが public になっているか- Gemini API キーが正しいか
SUPABASE_SERVICE_ROLE_KEYで Storage に PUT できる権限があるか
claude コマンドが launchd / cron から見つからない
scripts/run-agent.sh の claude を絶対パスにする (例: /usr/local/bin/claude または which claude の結果)。
plist の EnvironmentVariables で PATH を追加するのも有効。
---
ライセンス・クレジット
参考実装として自由に改変・再配布してください。
元のフルバージョンは hojokin-agent.jp (株式会社 MYUUU) で運用中。