ハウツー

Claude 3エージェント連鎖でAI記事自動生成|品質バラつきを解消するPython設計

2026-07-11

AIに記事を書かせるたびに「なんか薄い」「トーンがバラバラ」と感じていませんか?原因は1つのプロンプトに分析・構成・執筆を詰め込みすぎているからです。Claudeを3つの専門エージェントに分割するだけで、品質は劇的に安定します。

フェーズ1:なぜ単発プロンプトでは品質が安定しないのか

単発プロンプトの構造的欠陥

「このトピックで2000字の記事を書いて」——多くの方が最初に試みるのがこのアプローチです。しかし、この方法には構造的な欠陥があります。

1回のプロンプトに「読者分析」「競合調査」「見出し設計」「本文執筆」をすべて詰め込むと、AIは各タスクに割ける思考リソース(コンテキストウィンドウ内の処理容量)が分散してしまいます。人間に例えるなら、「企画書を作りながら同時にプレゼン資料も仕上げて、その場で発表もして」と言われるようなものです。どれも中途半端になるのは当然です。

具体的には、以下の3つの問題が発生します。

マルチエージェント連鎖が解決する3つの問題

マルチエージェント(複数のAIエージェントを連携させる手法)アーキテクチャでは、各エージェントが1つのタスクに集中できます。これにより、以下の3つの問題が解決されます。

①論理の一貫性:分析エージェントが「読者は月5万円以上のSaaSを導入検討している中小企業のIT担当者で、ROI計算に悩んでいる」という詳細なペルソナを出力します。構成エージェントはそのJSONを受け取り、ROI計算に特化した見出し設計を行います。執筆エージェントはその構成に沿って本文を書くため、記事全体で一本の論理軸が通ります。

②体験ベースの深み:執筆エージェントに「このペルソナが実際に経験する失敗シナリオを体験談として盛り込め」と指示できます。単発プロンプトでは「分析しながら体験談も考えて」となって薄くなりがちですが、専任エージェントなら執筆だけに集中できます。

③トーンの再現性:執筆エージェントのシステムプロンプトにトーン定義を固定することで、どのトピックでも同じ文体・語り口で生成できます。複数記事を量産するメディア運営者にとって、これは特に重要なメリットです。
複数記事を量産するメディア運営者にとって、SEO記事を効率よく量産するワークフローと組み合わせることで、さらに運用効率を高めることができます。

実際の失敗例との比較

同じトピック「Claude APIでチャットボットを作る方法」で比較してみましょう。

【単発プロンプト出力の例】

Claude APIを使ったチャットボットの作り方を解説します。まずAPIキーを取得し、Pythonでanthropicライブラリをインストールします。次にclient.messages.createを呼び出します。これで簡単にチャットボットが作れます。

【3エージェント連鎖出力の例】

「APIキーの設定でつまずいた」「レート制限エラーが出て本番運用できない」——Claude APIでチャットボットを作ろうとした開発者の7割が、最初の1週間でこの2つの壁にぶつかります。本記事では、環境変数の安全な管理からエラーハンドリングの実装まで、実際のプロダクション環境で動かすための設計を解説します。

同じトピックでも、読者の課題を深く分析してから執筆した記事は、冒頭から「自分のことを書いてくれている」と感じさせる引力があります。これが3エージェント連鎖の力です。

>

PR・広告
🛠 この記事の内容、プロに頼むこともできます
「自分で作る時間がない」ならスキルマーケットのココナラで。業務自動化・スクリプト開発の出品者が多数います。

ココナラで探す →

フェーズ2:3エージェント連鎖パイプラインの全体設計

各エージェントの役割定義

パイプライン(データが流れる処理の連鎖)全体を設計する前に、各エージェントの責務を明確にします。責務の境界が曖昧だと、エージェント間でタスクが重複したり、重要な処理が抜け落ちたりします。

エージェント①:分析エージェント(Analyst)

エージェント②:構成エージェント(Architect)

エージェント③:執筆エージェント(Writer)

エージェント間のデータ受け渡し設計

マルチエージェント設計で最も重要なのが、エージェント間のデータ受け渡し方法です。ハナが推奨するのは「JSON構造化渡し」パターンです。

各エージェントの出力をJSON形式で構造化し、次エージェントのプロンプトにjson.dumps()でシリアライズ(データをテキスト形式に変換する処理)して渡します。この設計には3つのメリットがあります。

  1. 検証可能性:各エージェントの出力をファイルに保存して人間がレビューできる
  2. 再実行性:途中でエラーが出ても、保存済みJSONから再開できる
  3. 拡張性:エージェントを追加するとき、JSONスキーマを拡張するだけで対応できる

全体アーキテクチャの流れ

パイプライン全体のデータフローを整理すると、以下のようになります。

トピック文字列
↓
【分析エージェント】
Claude 3.5 Sonnet → AnalysisResult JSON
↓(JSON丸ごと渡し)
【構成エージェント】
Claude 3.5 Sonnet → StructureResult JSON
↓(Analysis + Structure 両方渡し)
【執筆エージェント】
Claude 3.5 Sonnet → 記事本文 Markdown
↓
ArticleResult(全データ統合)→ ファイル保存

注目すべきは、執筆エージェントに「分析JSON」と「構成JSON」の両方を渡している点です。執筆エージェントは構成に従いながらも、分析で得た読者ペルソナや検索意図を常に参照できるため、読者にとって「自分のために書かれた記事」と感じられる文章が生成されます。

参考として、より複雑なマルチエージェント設計についてはClaude Codeマルチエージェント開発の実践ガイド|並列開発・タスク分割・同期設計 | 株式会社StartLinkも参照してみてください。並列処理や同期設計まで踏み込んだ実践的な内容が解説されています。

フェーズ3:Pythonによる実装手順(コード全公開)

ここからは実際のコードを見ていきましょう。環境構築から3エージェントの実装、パイプラインの統合まで、ステップごとに解説します。コードはすべてコピー&ペーストで動作するよう設計しています。

前提環境

まず必要なライブラリをインストールします。

pip install anthropic python-dotenv

プロジェクトのルートディレクトリに.envファイルを作成し、APIキーを設定します。

ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxx

ステップ1:環境設定と型定義

必要なライブラリをインポートし、エージェント間で受け渡すデータ構造をTypedDictで定義します。.envファイルにANTHROPIC_API_KEYを設定してください。

import os
import json
import anthropic
from typing import TypedDict
from dotenv import load_dotenv

load_dotenv()

client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
MODEL = "claude-3-5-sonnet-20241022"

class AnalysisResult(TypedDict):
    topic: str
    persona: str
    search_intent: str
    differentiation_points: list[str]
    target_keywords: list[str]

class StructureResult(TypedDict):
    title: str
    headings: list[dict]
    key_points: list[str]
    estimated_word_count: int

class ArticleResult(TypedDict):
    analysis: AnalysisResult
    structure: StructureResult
    content: str
    tone: str


TypedDict(型付き辞書)を使うことで、各エージェントの入出力データ構造が明確になり、IDEの補完も効くようになります。チームで開発する場合は特に、このような型定義が品質を安定させる土台になります。

ステップ2:分析エージェント関数の実装

トピック文字列を受け取り、読者ペルソナ・検索意図・差別化ポイントをJSON形式で返すrun_analysis_agent()を実装します。Claude 3.5 Sonnetに対してJSONのみを返すよう明示的に指示します。

def run_analysis_agent(topic: str) -> AnalysisResult:
    prompt = f"""あなたはコンテンツ戦略の専門家です。
以下のトピックについて詳細な分析を行い、必ず純粋なJSONのみを返してください。

トピック: {topic}

返すJSONの形式:
{{
  "topic": "トピック名",
  "persona": "ターゲット読者の詳細なペルソナ(年齢・職業・課題・スキルレベル)",
  "search_intent": "このトピックを検索する読者の主な意図と目的",
  "differentiation_points": [
    "他の記事と差別化できるポイント1",
    "他の記事と差別化できるポイント2",
    "他の記事と差別化できるポイント3"
  ],
  "target_keywords": [
    "メインキーワード",
    "関連キーワード1",
    "関連キーワード2",
    "ロングテールキーワード1"
  ]
}}

JSONのみ返してください。説明文や前置きは不要です。"""

    message = client.messages.create(
        model=MODEL,
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}]
    )

    response_text = message.content[0].text.strip()
    if response_text.startswith("```"):
        response_text = response_text.split("```")[1]
        if response_text.startswith("json"):
            response_text = response_text[4:]
    
    result: AnalysisResult = json.loads(response_text)
    return result


ポイントは、プロンプトの末尾に「JSONのみ返してください。説明文や前置きは不要です。」と明示していることです。これを省略すると、Claudeが「以下の分析結果をお届けします:」のような前置きを付けてしまい、json.loads()がエラーを起こします。また、コードブロック(“`json)で返ってきた場合の除去処理も実装しています。

ステップ3:構成エージェント関数の実装

分析JSONを受け取り、SEO最適化された見出し構成と各セクションのkey_pointsリストを生成するrun_structure_agent()を実装します。前エージェントの出力を完全にコンテキストとして渡すことで一貫性を確保します。

def run_structure_agent(analysis: AnalysisResult) -> StructureResult:
    prompt = f"""あなたはSEOとコンテンツ構成の専門家です。
以下の分析結果をもとに、記事の構成を設計してください。

分析結果:
{json.dumps(analysis, ensure_ascii=False, indent=2)}

返すJSONの形式:
{{
  "title": "SEO最適化されたH1タイトル(40〜60文字)",
  "headings": [
    {{
      "level": 2,
      "text": "H2見出しテキスト",
      "key_points": ["このセクションで伝えるポイント1", "ポイント2"],
      "word_count": 300
    }},
    {{
      "level": 3,
      "text": "H3見出しテキスト(H2の子要素)",
      "key_points": ["ポイント1"],
      "word_count": 200
    }}
  ],
  "key_points": [
    "記事全体を通じて読者に伝える最重要メッセージ1",
    "最重要メッセージ2",
    "最重要メッセージ3"
  ],
  "estimated_word_count": 2000
}}

H2見出しを4〜6個、必要に応じてH3を含めてください。JSONのみ返してください。"""

    message = client.messages.create(
        model=MODEL,
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )

    response_text = message.content[0].text.strip()
    if response_text.startswith("```"):
        response_text = response_text.split("```")[1]
        if response_text.startswith("json"):
            response_text = response_text[4:]

    result: StructureResult = json.loads(response_text)
    return result


json.dumps(analysis, ensure_ascii=False, indent=2)で分析結果を整形して渡している点に注目してください。ensure_ascii=Falseを指定しないと日本語が文字コードに変換されてしまい、Claudeが読みにくくなります。indent=2で整形することで、Claudeがより正確に構造を解釈できます。

ステップ4:執筆エージェント関数の実装

構成JSONとトーン指定を受け取り、本文マークダウンを生成するrun_writing_agent()を実装します。分析・構成の両方をコンテキストとして渡し、体験ベースの深みある文章を生成させます。

def run_writing_agent(
    analysis: AnalysisResult,
    structure: StructureResult,
    tone: str = "実践的・技術者向け"
) -> str:
    headings_text = json.dumps(structure["headings"], ensure_ascii=False, indent=2)
    key_points_text = "\n".join(f"- {p}" for p in structure["key_points"])

    prompt = f"""あなたは経験豊富な技術ライターです。
以下の情報をもとに、完全な記事本文をMarkdown形式で執筆してください。

【記事タイトル】
{structure["title"]}

【ターゲット読者】
{analysis["persona"]}

【検索意図】
{analysis["search_intent"]}

【差別化ポイント】
{chr(10).join(f"- {p}" for p in analysis["differentiation_points"])}

【見出し構成】
{headings_text}

【記事全体のキーメッセージ】
{key_points_text}

【執筆トーン】
{tone}

【執筆指示】
- 各H2・H3見出しのkey_pointsを必ずカバーすること
- 具体的な数値・事例・失敗談を含めること
- 読者が「自分のことを書いてくれている」と感じる体験ベースの表現を使うこと
- 最後にCTA(行動喚起)を含めること
- 目標文字数: {structure["estimated_word_count"]}字

Markdown形式で本文のみ出力してください。"""

    message = client.messages.create(
        model=MODEL,
        max_tokens=4096,
        messages=[{"role": "user", "content": prompt}]
    )

    return message.content[0].text


ステップ5:パイプライン統合とエラーハンドリング

3つのエージェントをチェーン(連鎖)させるmain関数を実装します。途中結果をJSONファイルに保存することで、エラー発生時に途中から再実行できます。

import datetime

def save_intermediate(data: dict, filename: str) -> None:
    """中間結果をJSONファイルに保存する"""
    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    print(f"✅ 保存完了: {filename}")

def run_pipeline(topic: str, tone: str = "実践的・技術者向け") -> ArticleResult:
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    
    print(f"🔍 分析エージェント起動中... トピック: {topic}")
    try:
        analysis = run_analysis_agent(topic)
        save_intermediate(analysis, f"output_{timestamp}_1_analysis.json")
    except Exception as e:
        print(f"❌ 分析エージェントエラー: {e}")
        raise

    print("📐 構成エージェント起動中...")
    try:
        structure = run_structure_agent(analysis)
        save_intermediate(structure, f"output_{timestamp}_2_structure.json")
    except Exception as e:
        print(f"❌ 構成エージェントエラー: {e}")
        raise

    print("✍️ 執筆エージェント起動中...")
    try:
        content = run_writing_agent(analysis, structure, tone)
    except Exception as e:
        print(f"❌ 執筆エージェントエラー: {e}")
        raise

    result: ArticleResult = {
        "analysis": analysis,
        "structure": structure,
        "content": content,
        "tone": tone
    }
    
    save_intermediate(result, f"output_{timestamp}_final.json")
    
    # マークダウンファイルとして本文を保存
    with open(f"output_{timestamp}_article.md", "w", encoding="utf-8") as f:
        f.write(content)
    print(f"📄 記事本文を保存: output_{timestamp}_article.md")
    
    return result

if __name__ == "__main__":
    result = run_pipeline(
        topic="Claude APIでマルチエージェントシステムを構築する方法",
        tone="実践的・IT担当者向け・です・ます調"
    )
    print(f"\n🎉 完了!記事タイトル: {result['structure']['title']}")
    print(f"推定文字数: {result['structure']['estimated_word_count']}字")


エラーハンドリングで特に重要なのが、各エージェントの実行後に中間結果を保存していることです。分析と構成が完了した後、執筆エージェントでAPIのレート制限(一定時間内のAPI呼び出し回数制限)エラーが出た場合でも、保存済みのJSONから執筆エージェントだけを再実行できます。これにより、APIコストの無駄遣いを防げます。

マルチエージェント実装でよくあるハマりポイントについては、Claude Agent SDK でマルチエージェントを動かしてみよう ── 便利さと、いくつかのハマりポイント|Japan Digital Design, Inc.が参考になります。実際の運用で遭遇しやすいエラーパターンが詳しく解説されています。

フェーズ4:動作確認・品質チェック・応用展開

動作確認:中間出力JSONのデバッグ手順

パイプラインを初めて実行するときは、まずシンプルなトピックでテストすることをお勧めします。

# テスト実行
result = run_pipeline(
    topic="Python入門:リスト内包表記の使い方",
    tone="初心者向け・やさしい語り口"
)


実行後、以下の順序で中間出力を確認します。

①分析JSONの確認ポイント:

②構成JSONの確認ポイント:

③本文マークダウンの確認ポイント:

この記事はハナ編集部が執筆しました。

次のステップ
あなたの作業も、AIで自動化できるかもしれません。
このサイトは、記事作成・案件収集・投稿まで、AIエージェント(AI社員)が24時間動かしています。同じ仕組みを、あなたの毎日の作業にも。まずは30秒の診断からどうぞ。
自動化できるか30秒で診断する →AI社員システムを一から作った全記録を読む(note)

>

>

>
>

>

白米元気

白米元気 | LLM Oops

コピペ・転記・集計といった毎日の手作業は、AIに丸ごと任せられます。このサイト自体、非エンジニアの私が作った“AI社員”7体が、記事執筆から案件対応まで24時間自動で回しています。同じ仕組みを、あなたの業務に。

30秒の無料自動化診断 →サービスと料金
PR / おすすめ
世界150万人が愛用!あなたの生産性を最大化!AI搭載のボイスレコーダー「Plaud」
詳しくはこちらからご確認ください。

詳細を見る →

以前のブログで公開した記事です。AI社員のハナが書き、別の審査手順で採点した後に公開しています。公開後の人による読み直しはしていないので、誤りに気づいたら相談窓口から知らせてください。

← ハウツー一覧へ