Claude APIでブログ記事の下書きを自動生成する方法

ブログ記事を書くのが億劫な理由の多くは「0から書き始める」ことのしんどさだ。Claude APIを使えば、テーマを与えるだけで構成と下書きを自動生成できる。この記事では実際に私が使っているパイプラインを紹介する。

全体の構成

テーマ・キーワード入力
      ↓
Claude APIで構成案生成
      ↓
構成案を人間がレビュー・修正
      ↓
Claude APIで本文生成
      ↓
Markdownファイルとして保存
      ↓
WordPressに下書き投稿

手を動かすのは「構成案のレビュー・修正」と「最終確認」だけ。それ以外はスクリプトが自動でやってくれる。

必要なもの

  • Python 3.10以上
  • Anthropic APIキー(`pip install anthropic`)
  • python-dotenv
  • pip install anthropic python-dotenv

    Step 1: 構成案を生成する

    まずテーマを受け取って記事の構成案を生成するスクリプトを作る。

    import anthropic
    import json
    from pathlib import Path
    
    def generate_outline(theme: str, target_length: int = 2000) -> dict:
        """記事の構成案を生成する"""
        client = anthropic.Anthropic()
    
        prompt = f"""
    あなたはプロの技術ブロガーです。以下のテーマで技術ブログ記事の構成案を作成してください。
    
    テーマ: {theme}
    目標文字数: {target_length}文字
    
    以下のJSON形式で返してください:
    {{
        "title": "記事タイトル",
        "slug": "english-slug",
        "sections": [
            {{
                "heading": "h2見出し",
                "points": ["書くべき内容1", "書くべき内容2"]
            }}
        ],
        "tags": ["タグ1", "タグ2"]
    }}
    """
    
        message = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            max_tokens=1024,
            system="必ずJSON形式のみで返してください。説明文は含めないでください。",
            messages=[{"role": "user", "content": prompt}]
        )
    
        return json.loads(message.content[0].text)
    
    
    # 使用例
    outline = generate_outline("PythonでWordPress REST APIを自動化する方法")
    print(json.dumps(outline, ensure_ascii=False, indent=2))

    Step 2: 本文を生成する

    構成案を承認したら、各セクションの本文を生成する。

    def generate_section(heading: str, points: list[str], context: str = "") -> str:
        """各セクションの本文を生成する"""
        client = anthropic.Anthropic()
    
        points_text = "\n".join(f"- {p}" for p in points)
    
        prompt = f"""
    以下のセクションの本文を書いてください。
    
    見出し: {heading}
    含めるべき内容:
    {points_text}
    
    条件:
    - 一人称(私)で書く
    - 実体験や具体例を含める
    - コードがある場合はPythonかJavaScriptで書く
    - 200〜400文字程度
    
    {f"記事全体の文脈: {context}" if context else ""}
    """
    
        message = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            max_tokens=1024,
            messages=[{"role": "user", "content": prompt}]
        )
    
        return message.content[0].text
    
    
    def generate_article(outline: dict) -> str:
        """構成案から記事全体を生成する"""
        sections = []
    
        for section in outline["sections"]:
            content = generate_section(
                heading=section["heading"],
                points=section["points"]
            )
            sections.append(f"## {section['heading']}\n\n{content}")
    
        return "\n\n".join(sections)

    Step 3: Markdownファイルとして保存する

    フロントマター付きのMarkdownファイルとして保存する。

    def save_draft(outline: dict, content: str, output_dir: str = "articles/drafts") -> Path:
        """下書きをMarkdownファイルとして保存する"""
        Path(output_dir).mkdir(parents=True, exist_ok=True)
    
        tags_str = ", ".join(f'"{t}"' for t in outline["tags"])
    
        frontmatter = f"""---
    title: {outline["title"]}
    slug: {outline["slug"]}
    category: AI・機械学習
    tags: [{tags_str}]
    status: draft
    ---
    
    """
    
        filepath = Path(output_dir) / f"{outline['slug']}.md"
        filepath.write_text(frontmatter + content, encoding="utf-8")
    
        print(f"保存しました: {filepath}")
        return filepath

    Step 4: 全部つなげて実行する

    def main():
        theme = input("記事のテーマを入力: ")
    
        print("構成案を生成中...")
        outline = generate_outline(theme)
    
        print("\n--- 構成案 ---")
        print(f"タイトル: {outline['title']}")
        for s in outline["sections"]:
            print(f"  ## {s['heading']}")
    
        confirm = input("\nこの構成で本文を生成しますか? (y/n): ")
        if confirm.lower() != "y":
            print("キャンセルしました")
            return
    
        print("本文を生成中...")
        content = generate_article(outline)
    
        filepath = save_draft(outline, content)
        print(f"\n完成: {filepath}")
    
    
    if __name__ == "__main__":
        main()

    コスト感

    Claude 3.7 Sonnet(claude-3-7-sonnet-20250219)を使った場合、2000文字の記事1本あたりのAPIコストは大体$0.01〜0.03程度。月50本書いても$1〜1.5。

    入力トークンは比較的安いので、詳細なsystem promptを書いてもコストへの影響は軽微。

    実際に使ってみた感想

    このパイプラインで生成した下書きを使って記事を書いていると、「ゼロから書く」負担が大幅に減った。生成される文章はそのまま使えるものではなく、あくまで「下書き」として手を加える必要があるが、構成と各セクションの骨格が揃った状態からスタートできるのが大きい。

    特に効果的だったのは構成案の生成。自分で考えると1つの視点に偏りがちだが、AIが生成した構成案には「あ、この観点を忘れてた」という気づきが含まれることが多い。

    まとめ

    Claude APIを使った記事下書き生成パイプラインの実装手順を紹介した。要点をまとめると:

  • 構成案と本文生成を分けて、人間のレビューポイントを設ける
  • system promptで出力形式(JSON)を厳密に指定する
  • 生成コンテンツは「下書き」として扱い、必ず人間が加筆修正する
  • このスクリプトはGitHubに公開予定。興味があれば参考にしてほしい。