「Claude APIって、1回のやりとりしかできないの?」

そんな疑問を持ったことはありませんか?実は、会話履歴をきちんと管理してあげれば、ChatGPTのような自然なマルチターン会話(複数回のやりとり)をClaude APIで実現できます。

ただ、最初は「どうやって会話の流れを覚えさせるの?」と迷う方も多いんですよね。今回は、Claude APIのマルチターン会話の仕組みをゼロから丁寧に解説します!

📌 この記事の対象読者

  • Claude APIを使ったことがある、または興味がある方
  • チャットボットを作ってみたい初〜中級者の方
  • 会話履歴の管理方法がわからなくて詰まっている方

マルチターン会話とは?まずイメージをつかもう

AI chatbot conversation
AI chatbot conversation / Photo by Matheus Bertelli via Pexels

Claude APIは、基本的に「1回のリクエストに対して1回のレスポンスを返す」設計になっています。

イメージとしては、毎回「初対面の人に話しかけている」感じです。前の会話は何も覚えていない状態でスタートします。

でも、チャットボットとして使うなら「さっき言ったことを踏まえて答えてほしい」ですよね。それを実現するのがマルチターン会話です。

解決策はシンプル。過去の会話履歴ごとAPIに渡すだけです。APIに「これまでのやりとりの記録」を毎回送ることで、Claudeは文脈(コンテキスト)を把握して返答できるようになります。

会話履歴の構造を理解しよう

Claude APIに渡す会話履歴は、messagesというリスト形式で表現します。各メッセージは「role(役割)」と「content(内容)」のセットです。

  • role: “user” → ユーザーの発言
  • role: “assistant” → Claudeの返答

つまり、会話のやりとりを交互に積み上げていくイメージです。実際にどんな形になるかを見てみましょう。

# 会話履歴の基本構造
messages = [
    {"role": "user", "content": "Pythonってどんな言語ですか?"},
    {"role": "assistant", "content": "Pythonはシンプルで読みやすい文法が特徴のプログラミング言語です。"},
    {"role": "user", "content": "初心者でも学べますか?"},  # ← 2回目の質問
]

このリストをそのままAPIに渡すことで、Claudeは「あ、この人はさっきPythonについて聞いていたんだな」と理解して答えてくれます。

基本的なマルチターン会話の実装

では、実際にPythonでマルチターン会話を実装してみましょう。まずは一番シンプルな形です。

import anthropic

client = anthropic.Anthropic()

# 会話履歴を格納するリスト
conversation_history = []

def chat(user_message: str) -> str:
    """ユーザーのメッセージを受け取り、会話履歴を維持しながら返答を返す"""

    # ユーザーの発言を履歴に追加
    conversation_history.append({
        "role": "user",
        "content": user_message
    })

    # APIを呼び出す(会話履歴ごと渡す)
    response = client.messages.create(
        model="claude-opus-4-5-20251101",
        max_tokens=1024,
        messages=conversation_history  # ← ここがポイント!
    )

    # Claudeの返答を取り出す
    assistant_message = response.content[0].text

    # Claudeの返答も履歴に追加しておく
    conversation_history.append({
        "role": "assistant",
        "content": assistant_message
    })

    return assistant_message


# 実際に会話してみる
print("Claude:", chat("私の名前はタロウです。よろしく!"))
print("Claude:", chat("さっき言った私の名前を覚えていますか?"))

ポイントをまとめるとこんな感じです 👇

  • conversation_historyというリストに会話をどんどん追加していく
  • APIを呼ぶたびに、このリスト全体をmessagesパラメータに渡す
  • ユーザーの発言だけでなく、Claudeの返答も必ず履歴に追加すること(これを忘れると会話がつながらなくなります)

インタラクティブなチャットボットにしてみよう


先ほどのコードを少し発展させて、ターミナル上でリアルタイムに会話できるチャットボットを作ってみましょう!

import anthropic

client = anthropic.Anthropic()

def run_chatbot():
    """ターミナル上でClaudeと会話できるチャットボット"""

    print("=" * 40)
    print("Claudeチャットボット起動中...")
    print("終了するには 'quit' または 'exit' と入力してください")
    print("=" * 40)

    # 会話履歴(セッション中は保持し続ける)
    conversation_history = []

    # システムプロンプト(Claudeの役割・性格を設定)
    system_prompt = "あなたは親切で丁寧な日本語アシスタントです。わかりやすく簡潔に答えてください。"

    while True:
        # ユーザーの入力を受け取る
        user_input = input("\nあなた: ").strip()

        # 終了コマンドの確認
        if user_input.lower() in ["quit", "exit", "終了"]:
            print("チャットを終了します。またね!")
            break

        if not user_input:
            print("何か入力してください。")
            continue

        # 会話履歴にユーザーの発言を追加
        conversation_history.append({
            "role": "user",
            "content": user_input
        })

        # APIを呼び出す
        try:
            response = client.messages.create(
                model="claude-opus-4-5-20251101",
                max_tokens=1024,
                system=system_prompt,  # システムプロンプトは別パラメータで渡す
                messages=conversation_history
            )

            assistant_reply = response.content[0].text

            # Claudeの返答を履歴に追加
            conversation_history.append({
                "role": "assistant",
                "content": assistant_reply
            })

            print(f"\nClaude: {assistant_reply}")

            # 会話ターン数を表示(デバッグ用)
            turns = len(conversation_history) // 2
            print(f"(会話ターン数: {turns})")

        except Exception as e:
            print(f"エラーが発生しました: {e}")


if __name__ == "__main__":
    run_chatbot()

このコードで大事な点が1つあります。システムプロンプトはmessagesリストではなく、systemパラメータとして別に渡すのがClaude APIの作法です。会話履歴と混ぜないようにしましょう。

会話履歴が長くなりすぎる問題とその対策

「会話をずっと続けていたら、履歴がどんどん長くなっていくよね?」と思った方、鋭いです!😄

Claude APIにはコンテキストウィンドウ(一度に処理できるトークン数の上限)があります。会話が長くなりすぎると、エラーになったりコストが増えたりします。

実用的な対策を2つ紹介します。

対策①:直近N件のみ保持する「スライディングウィンドウ」方式

最新の会話だけをAPIに渡す、シンプルで効果的な方法です。

def chat_with_limit(user_message: str, history: list, max_turns: int = 10) -> tuple:
    """会話ターン数を制限してAPIを呼び出す"""

    # ユーザーの発言を追加
    history.append({"role": "user", "content": user_message})

    # 直近のN件だけ切り出す(max_turns × 2 = user + assistant のペア数)
    recent_history = history[-(max_turns * 2):]

    response = client.messages.create(
        model="claude-opus-4-5-20251101",
        max_tokens=1024,
        messages=recent_history  # ← 直近の履歴だけ渡す
    )

    assistant_reply = response.content[0].text

    # 全履歴にも追加しておく(ログとして保持)
    history.append({"role": "assistant", "content": assistant_reply})

    return assistant_reply, history

対策②:会話の要約をコンテキストに入れる方式

会話が一定回数を超えたら、過去の内容をClaude自身に要約させて、その要約を新しい履歴の先頭に入れるテクニックもあります。より自然な会話継続ができますが、実装は少し複雑になります。まずはスライディングウィンドウ方式から試してみるのがおすすめです。

コンテキスト設計の3つのコツ

マルチターン会話をうまく動かすための設計ポイントをまとめておきます。

  1. システムプロンプトでゴールを明確にする:Claudeにどんな役割を担ってほしいかを最初に明確に伝えましょう。「カスタマーサポート担当」「コードレビュアー」など具体的に設定すると会話の質が上がります。
  2. ユーザーとアシスタントを交互に並べる:メッセージの並び順が崩れると意図しない動作になります。必ずuser→assistant→user→assistant…の順番を守りましょう。
  3. 履歴の長さを意識する:目安として、直近10〜15ターン程度に絞るだけでもコスト・速度のバランスが取りやすくなります。

まとめ


今回は、Claude APIでマルチターン会話を実現する方法を解説しました。

  • Claude APIは会話履歴を自分で管理して渡す必要がある
  • 履歴はmessagesリストuser / assistantを交互に積み上げる形式
  • システムプロンプトはsystemパラメータで別に渡す
  • 長くなりすぎたら直近N件だけを渡すスライディングウィンドウで対応

仕組み自体はシンプルなので、まずは今回のサンプルコードをそのままコピーして動かしてみてください。動いた瞬間、「なるほど!こういう仕組みか」とスッと理解できるはずですよ 😊

ぜひ自分なりのチャットボットを作って、いろいろな役割を試してみてください!一緒に学んでいきましょう。

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

もしも

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

AIコーディングの現場活用法を学ぶ一冊

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。