Claudeの応答言語をシステムプロンプトで固定する方法
ユーザーの入力言語に関わらず特定の言語で応答させるには、systemパラメーターに言語指定を書きます。実装例と、2言語間の翻訳を固定する書き方、よくあるつまずきをまとめます。
応答言語がぶれるときはsystemに一文入れる
Claudeは会話の流れから応答言語を推測します。日本語で聞かれれば日本語、英語なら英語という挙動で、本番アプリでは推測に頼らず目的の言語を明示するのが筋です。Anthropicのドキュメントは、その置き場所として system パラメーターを挙げています。会話のどのターンでも指示が安定するためです。
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"system": "Always respond in French, regardless of the language the user writes in.",
"messages": [{"role": "user", "content": "How do I reset my password?"}]
}'ユーザーは英語で質問していますが、system に「ユーザーの言語に関わらず常にフランス語で応答する」と書いてあるので、狙いはフランス語での返答です。regardless of the language the user writes in の句が、ユーザー側の言語に引きずられないための一言になります。
ユーザーメッセージではなくsystemに書く理由
言語指定を毎回のユーザーメッセージに足す方法でも動くことはあります。ただ messages は会話が進むほど長くなります。system は毎回のリクエストで先頭に渡すので、何往復続いても同じ位置にあります。
キャッシュの面でも置き場所の差が出ます。プロンプトキャッシュのプレフィックスは tools、system、messages の順に作られ、あるレベルが変わるとそれ以降のキャッシュが無効になります。言語指定が system の固定部分にあれば、messages に会話が積み上がっても system までのキャッシュは使い回せます。仕組みの全体像はAnthropic APIのPrompt Cachingを理解するで扱っています。
固定言語の書き方
指示文は英語でも日本語でも、短い1文で足ります。日本語で固定するなら次のように書きます。
system: "常に日本語で応答してください。ユーザーがどの言語で入力しても、日本語で返答してください。"例文はいずれも英語で言語名を指定しており(Always respond in French など)、指示文の言語をシステムプロンプトの他の指示と揃えておくと保守しやすくなります。
言語指定は、役割・出力形式・禁止事項と混ぜず独立した1文にしておくと、後から探して直せます。役割説明の直後に置く配置が一例です。
あなたはカスタマーサポート担当のAIアシスタントです。
常に日本語で応答してください。ユーザーがどの言語で入力しても日本語で返答してください。
回答は3文以内で簡潔にまとめてください。後から英語対応を足すときも、言語の1文を条件分岐に置き換えるだけで済み、他の指示は動かしません。
翻訳タスクでは変換元と変換先を両方書く
翻訳用途の例文は次の形です。
Translate the user's message from German to Korean. Respond with only the translation.「AからB」の両端を名指しし、「翻訳だけを返す」という出力の指定まで1文に入っています。翻訳結果をプログラムで後続処理するなら、この2点が揃った形が出発点になります。
変換元が事前に決まらない場合は、変換元を「ユーザーが書いた言語」と相対的に書き、変換先だけ固定する書き方もあります。「ユーザーの入力言語から日本語へ翻訳し、翻訳結果だけを返してください」とすれば、入力が何語でも出力は日本語です。多言語の問い合わせを日本語に集約して社内で処理する用途に向きます。
UIで言語を選ばせるときの組み立て方
ユーザーがUIで言語を選べるアプリでは、推測に任せず選択結果をシステムプロンプトへ埋め込みます。実行時に言語を選ばせるなら、選択を system に差し込む形になります。
選択値を system に届ける3手順
- 1
選択を言語コードで受ける
UIのドロップダウンなら
jaenのようなコードが返ります。自由入力の欄は使いません。 - 2
許可リストで言語名に変換する
リストに無いコードは既定言語へ戻します。想定外の文字列が指示文に入る経路が消えます。
- 3
system の言語指定文に埋め込む
Always respond in {言語名}の形で組み立て、リクエストのsystemに渡します。
ALLOWED_LANGUAGES = {"ja": "Japanese", "en": "English", "es": "Spanish", "fr": "French"}
lang_code = request.get("lang", "ja")
if lang_code not in ALLOWED_LANGUAGES:
lang_code = "ja" # 既定言語にフォールバック
selected_language = ALLOWED_LANGUAGES[lang_code]
system_prompt = f"Always respond in {selected_language}, regardless of the language the user writes in."
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
system=system_prompt,
messages=[{"role": "user", "content": user_input}],
)許可リストを挟む理由は、Claude Codeの設定項目を見るとわかります(次の節)。
もう1点、動的に埋め込むと system の文字列が言語ごとに変わります。キャッシュのプレフィックスのハッシュには system の文字列が含まれるため、言語ごとに別のキャッシュエントリになります。tools までのキャッシュは共通のままです。cache_control を system の末尾までに置く構成なら、言語ごとにキャッシュが分かれても許容できるか、対応言語数と合わせて見積もっておく価値があります。
Claude Codeではsettings.jsonのlanguageで固定する
APIを自分で呼ばない場合、Claude Codeには同じ役割の設定項目 language があります。
{
"language": "japanese"
}値は "japanese" "spanish" "french" のような言語名の文字列で、既定は未設定です。固定の一覧はなく、Claudeが読める言語名なら通ります。Claude Codeは値をそのまま「常にその言語で応答する」という指示としてClaudeに渡し、検証をしません。綴りを間違えてもエラーにならず、間違った綴りのまま届きます。
同じ値は音声入力の言語と、自動生成されるセッションタイトルの言語にも使われます。未設定のとき、セッションタイトルは会話の言語に合わせて付きます。音声入力のほうには対応言語の固定リストがあるため、応答言語として通る名前が音声入力でも通るとは限りません。
固定リストは日本語(ja)を含む20言語で、指定は言語コード(BCP 47)でも言語名でも通ります。language がリストに無いと、/voice を有効にした時点で警告が出て、音声入力は英語に戻ります。Claudeのテキスト応答にこのフォールバックは影響しません。language が空のときも音声入力は英語が既定です。VS Code拡張では、空の場合に先にVS Codeの accessibility.voice.speechLanguage 設定が使われ、それも無ければ英語になります。
自前のアプリで自由入力をそのまま連結した場合も、同じことが起こります。前の節の許可リストは、この「検証されない値が指示文になる」経路を塞ぐ手当てです。
用途別の選び方
どの設定方法を使うか
固定言語(system に直接記述)
日本語専用のサポートボットのように、ユーザーの母語が確定している場合です。推測が要りません。
動的選択(UIの言語設定を埋め込み)
ユーザーごとに希望言語が違う多言語SaaS向けです。上の許可リストとセットで組みます。
翻訳固定(変換元・変換先を両方指定)
翻訳ツールや多言語要約のように、入力言語と出力言語が一致しない前提のタスクです。
言語の制約がない汎用チャットなら、指定せずClaudeの推測に任せる選択もあります。入力言語にそのまま追従させたい場合です。
固定した先の言語で精度は落ちるか
応答言語を固定しても、その言語での性能が保証されるわけではありません。ドキュメントには、英語を100%とした言語別の相対スコアが載っています。測定対象はSonnet 4.5とHaiku 4.5(拡張思考あり)で、MMLUを14言語に翻訳したテストセットでの値です。
英語を100%としたときの相対スコア
日本語
96.8% / 93.5%
Sonnet / Haiku
Swahili
91.1% / 78.3%
Sonnet / Haiku
Yoruba
79.7% / 52.7%
Sonnet / Haiku
日本語とYorubaの開きは、Sonnet 4.5で17.1ポイント、Haiku 4.5で40.8ポイントです。低リソース言語ほどモデル間の差が広がり、小さいHaikuで顕著に出ます。日本語は両モデルとも9割台前半以上で、固定先として大きな問題は出にくい水準です。表にあるのはこの2モデルだけで、現行のOpus 5.5(claude-opus-5-5)の値は載っていません。低リソース言語を固定するなら、自分のデータで試すのが確実です。表にない言語も使えます。標準的なUnicode文字を使う世界の大半の言語で入出力でき、表の外の言語でも多くの場合に対応できます。言語別の数字はClaudeの多言語性能を言語別データで見るに詳しくあります。
つまずきやすい点
ローマ字で渡さない。入力はローマ字に直さず、ネイティブスクリプトのまま渡すほうが結果が安定します。日本語ならひらがな・カタカナ・漢字です。
途中の言語切り替え。「ユーザーの言語に関わらず常に日本語」と書けば、文面どおりには「英語にして」という依頼も対象外になります。切り替えを許すなら「ユーザーが明示的に言語変更を求めた場合はそれに従う」という例外を書き添えます。規約上特定の言語でしか返せないサービスでは、例外を入れない判断も成り立ちます。
途中で言語を変えさせる場合、system を書き換えると、system 以降のキャッシュが無効になります(tools までは残ります)。代わりに、指示が必要になった時点の会話位置へ {"role": "system"} のメッセージを追加する方法があります(mid-conversation system message)。トップレベルの system は編集しないので、キャッシュ済みのプレフィックスはそのままです。対象はClaude Fable 5.1、Mythos 5.1、Fable 5、Mythos 5、Opus 5.5、Opus 4.8、Opus 5、Sonnet 5.5です。Sonnet 5では使えません。ユーザーが言語変更を求める設計なら、この方式に載せたほうが、切り替えのたびに system のキャッシュを捨てずに済みます。固定を絶対にするか、ユーザーが上書きできるかは、最初に決めておくと後で迷いません。
直訳感。「ネイティブスピーカーが話すような自然な表現で」(idiomatic speech as if it were a native speaker)と指示すると流暢さが上がります。フォーマルさや慣用表現は言語ごとに違うので、対象読者の文化圏に合った言い回しを求める一文も有効です。伝わる文章には、翻訳だけでなく文化や地域の感覚が要ることが多いからです。
まとめ
言語を誰が決めるかで、指示の書き場所が分かれます。運営側で固定するなら system の独立した1文、ユーザーが選ぶなら選択値を system へ埋め込み、会話の途中で変わるならmid-conversation system messageです。
指示文の設計はAgent SDKのシステムプロンプトをカスタマイズする4つのアプローチ、並列ツール呼び出しを増やす書き方は並列ツール呼び出しを増やすシステムプロンプトの書き方、API全体の構成はAnthropic API完全ガイドが参考になります。Claudeに名前やモデル名を正しく答えさせる書き方はClaudeに自己紹介とモデル名を正しく答えさせるプロンプト設計にあります。