Skip to main content
LLMは自分自身の記憶を持ちません — モデルは、ほんの少し前にあなたが言ったことも覚えていません。「マルチターン会話」とは、実際には毎回のリクエストに会話履歴全体を送ることを意味します。このガイドでは、APIYI における 4 つの呼び出し形式がその履歴をどのように保持するかと、注意すべき落とし穴を説明します。
例ではエンドポイント https://api.apiyi.com と、あなたの APIYI token を使用します。参照しているモデル: gpt-5.4-mini, deepseek-v4-pro, gemini-3.5-flash, claude-sonnet-4-6

コア原則: 履歴は自分で保持する

一言で言うと、モデルはステートレスであり、あなた(クライアント)が履歴を保持して、毎ターンその全体を再送する ということです。
新しいターンごとに、前回の user メッセージと model の返信を history array の末尾に 追加 してから、全体を送信します。形式ごとの差分は、history array の呼び名と roles の書き方だけです。
APIYI では、常に「履歴を自分で保持する」方式を使ってください。 サーバー側の会話状態(OpenAI Responses の previous_response_id など)には依存しないでください — ゲートウェイ経由では動作が保証されないためで、その詳細は下の OpenAI ネイティブのセクションで説明しています。

OpenAI互換モード(複数モデルで動作)

最も汎用的な方法で、エンドポイント /v1/chat/completions。履歴は messages 配列にあり、各エントリには rolesystem / user / assistant)が含まれます。model 文字列を切り替えるだけで、同じコードで別のモデルを動かせます(gpt、deepseek、claude、gemini…)。
1つのコードベースで、複数モデルに対応: modeldeepseek-v4-proclaude-sonnet-4-6gemini-3.5-flash、または他の任意のモデルに変更しても、マルチターンのロジックは同じままです。モデルと料金の概要 を参照してください。

推論モデルの履歴の扱い

deepseek-v4-pro のような推論モデルは、追加の reasoning_content(思考の連鎖)フィールドを返します。
履歴には content だけを残し、reasoning_content は返さないでください。 思考は現在ターンの中間生成物にすぎず、これを返すと tokens を無駄にし、上流のルールにも違反します(DeepSeek の direct API ではこれに対して 400 が返ることもあります)。履歴へ追加する際は、content だけを使用します:
推論モデルのレスポンスの解析については、推論モデルの出力 を参照してください。

OpenAI ネイティブ形式(Responses API)

エンドポイント /v1/responses。マルチターンでは、input 配列として完全な履歴を渡します(各エントリには role / content を含めます)— compatible mode と同じ自己管理型のアプローチです:
サーバー側の状態 のような previous_response_id / conversation / store に依存しないでください。APIYI ゲートウェイ経由で確認したところ、previous_response_id を渡してもエラーにはならず(200 を返します)が、次のターンでは前回の内容を記憶しません。また、GET /v1/responses/{id} は利用できません。したがって APIYI では、上記のように 自己管理型の履歴input 配列)を使って Responses API を利用してください。

Gemini ネイティブ形式

エンドポイント /v1beta/models/{model}:generateContent。履歴は contents 配列に保持されます。役割は user / modelassistant ではありません)に注意してください。また、各エントリの content は parts に入ります。
さらに簡単: 公式 google-genai SDK の client.chats.create(...)contents の履歴を保持してくれるので、send_message を呼ぶだけです。手動でつなぎ合わせる必要はありません。
Gemini 3-series のレスポンスは parts に thoughtSignature を付与します。プレーンテキストのマルチターンでは、text だけを返せばコンテキストを維持できます(tokens も少なくて済みます)。function calling のように厳密な reasoning の継続が必要な場合のみ、thoughtSignature をそのまま返す必要があります。これは公式 SDK が自動で処理します。Gemini Native CallsFunction Calling を参照してください。

Anthropic ネイティブフォーマット

エンドポイント /v1/messages。履歴は messages 配列にあり、ロールは user / assistant です。content は通常の文字列にできます。max_tokens は必須です。
公式の anthropic SDK も、base_url を https://api.apiyi.com に指定することで利用できます。レスポンスは content の block 配列です。パースの詳細は Claude Streaming & Responses を参照してください。

4つの形式の比較

選び方: ベンダーをまたいで 1 つのコードベースを使いたい場合は OpenAI互換モード を優先してください; ベンダー固有のネイティブ専用機能(Gemini の thought signatures / code execution、Claude の thinking blocks とキャッシュ、OpenAI の組み込み tools)が必要なら、その ネイティブ形式 を使ってください。

よくある質問

はい。各ターンで履歴全体が再送されるため、input tokens はターン数に応じて増え、それに伴ってコストも上がります。節約の主な方法は コンテキストキャッシュ です。同一の履歴プレフィックスは自動的にキャッシュヒット率が適用され、定価よりはるかに低くなります。OpenAI cachingClaude cachingGemini caching をご覧ください。
厳密なルールはありませんが、履歴が長いほどコストは高くなり、モデルのコンテキストウィンドウを超える場合があります。一般的な対処法は次のとおりです。(1) スライディングウィンドウ — 直近の N ターンだけを保持する;(2) 要約圧縮 — 以前のターンを system prompt の段落に要約する;(3) システム指示と直近のターンを常に保持する。ユースケースに必要な「記憶量」とのバランスを取ってください。
OpenAI 互換と Anthropic: 会話の先頭に置きます(互換版では role:"system" を使用し、Anthropic ではトップレベルの system フィールドまたは最初のメッセージを使います)。Gemini: config.system_instruction を使用します。システム指示は 一度だけ 設定すればよく、毎ターン再追加する必要はありません。
いいえ。 thinking はそのターンの中間生成物です。履歴には最終的な content だけを残してください(Gemini では text のみ)。thinking を返すと token を無駄に消費し、一部の upstream では受け付けられません。例外は、関数呼び出しにおける Gemini の thoughtSignature です。公式 SDK が自動的に処理します。
APIYI ではこれは 推奨されません。OpenAI Responses の previous_response_id は、ゲートウェイ経由で確実に動作するとは限りません(検証済み: メモリなし)。どこでもクライアント側で履歴を自前管理する方法を使ってください。これはモデル間で最も安定しており、一貫性があります。

関連リンク