📌 内容摘要

  • Claude 默认用用户输入的语言回复,但有时会”偷偷切换”——本文给出5种强制指定语言的方法,稳定性依次递增。
  • 从最简单的 System Prompt 一句话,到生产级的多语言路由架构,按需选用。
  • 每种方法附稳定性评分和适用场景,不是所有场景都需要最复杂的方案。
  • 附常见的语言设置失效原因,以及如何在代码里检测并修复语言偏移。

一、为什么 Claude 会”乱换语言”

Claude 默认的语言策略是:用用户输入的语言回复。大多数时候这个策略很好,但会在以下情况出问题:

  • 用户用中文问,但问题里夹杂了英文术语(如”Claude API怎么用”)→ Claude 可能回英文
  • 前几轮对话是英文,突然换中文提问 → Claude 可能维持英文
  • 代码相关问题 → Claude 倾向于用英文回答(代码本身是英文的)
  • System Prompt 是英文,用户消息是中文 → Claude 可能跟着 System Prompt 走
  • 引用了外文资料后提问 → Claude 可能用资料的语言回复
✅ 核心认知
Claude 的语言选择是基于上下文推断的,不是随机的。理解它为什么切换,比无脑加”请用中文”更有效。以下五种方法稳定性依次递增,根据你的场景选合适的就好。

方法一:System Prompt 里加语言指令(最简单)

稳定性:⭐⭐⭐(基础场景够用)

适用场景:你控制了 System Prompt,用户对话语言基本固定。

import anthropic

client = anthropic.Anthropic()

# 方法 1a:简单版(大多数情况够用)
response = client.messages.create(
    model      = "claude-sonnet-4-6",
    max_tokens = 1024,
    system     = "你是一个专业的助手。无论用户用什么语言提问,始终用中文回复。",
    messages   = [{"role": "user", "content": "What is machine learning?"}],
)
print(response.content[0].text)   # 应输出中文


# 方法 1b:强调版(遇到顽固切换时用这个)
response = client.messages.create(
    model      = "claude-sonnet-4-6",
    max_tokens = 1024,
    system     = """你是一个中文助手。

语言规则(最高优先级):
- 所有回复必须使用中文
- 无论用户用什么语言提问,一律用中文回答
- 即使引用英文内容,解释和分析也用中文
- 代码注释和说明文字用中文""",
    messages   = [{"role": "user", "content": "Explain Python decorators"}],
)
print(response.content[0].text)


# 切换到英文版只需改 system
response_en = client.messages.create(
    model      = "claude-sonnet-4-6",
    max_tokens = 1024,
    system     = "You are a professional assistant. Always respond in English regardless of the user's input language.",
    messages   = [{"role": "user", "content": "机器学习是什么"}],
)
print(response_en.content[0].text)   # 应输出英文

失效情况:当用户消息很长且全是英文时,Claude 有时候会”忘记”语言指令。这时候需要升级到方法二或三。

方法二:每条用户消息里附加语言提醒

稳定性:⭐⭐⭐⭐(明显比只用 System Prompt 稳)

适用场景:System Prompt 已经有语言指令但偶尔失效,或者语言要求很重要的生产场景。

def wrap_with_language(user_message: str, lang: str = "中文") -> str:
    """
    在用户消息里附加语言提醒
    放在消息最前面比放最后面稳定性更高
    """
    lang_prefix = {
        "zh": "【请用中文回复】",
        "en": "[Please respond in English]",
        "ja": "【日本語で回答してください】",
        "ko": "【한국어로 답해주세요】",
    }
    prefix = lang_prefix.get(lang, f"【请用{lang}回复】")
    return f"{prefix}\n\n{user_message}"


# 使用示例
response = client.messages.create(
    model      = "claude-sonnet-4-6",
    max_tokens = 1024,
    system     = "你是一个专业助手。",
    messages   = [{
        "role":    "user",
        "content": wrap_with_language(
            "Explain the difference between async and sync programming",
            lang="zh"
        )
    }],
)
print(response.content[0].text)   # 应输出中文


# 多轮对话时,每条用户消息都加前缀
def chat_with_forced_language(
    messages:    list[dict],
    user_input:  str,
    lang:        str = "zh",
) -> str:
    """每次用户发消息都附加语言提醒"""
    messages.append({
        "role":    "user",
        "content": wrap_with_language(user_input, lang)
    })

    response = client.messages.create(
        model      = "claude-sonnet-4-6",
        max_tokens = 1024,
        system     = "你是一个专业助手。",
        messages   = messages,
    )

    reply = response.content[0].text
    messages.append({"role": "assistant", "content": reply})
    return reply

方法三:Few-shot 示例固定语言风格

稳定性:⭐⭐⭐⭐(对特定语言模式稳定性最高)

适用场景:有固定的回复风格要求,或者 System Prompt + 消息提醒还是偶尔失效。

def build_messages_with_examples(
    user_input:  str,
    examples:    list[dict] = None,
) -> list[dict]:
    """
    在对话历史开头加几条示例,告诉 Claude 期望的语言模式
    Few-shot 示例的作用:直接演示输出格式,比语言指令更直观
    """
    # 默认示例:英文问题→中文回答
    default_examples = [
        {
            "role":    "user",
            "content": "What is Python?"
        },
        {
            "role":    "assistant",
            "content": "Python 是一种高级编程语言,以简洁易读著称。它支持多种编程范式,包括面向对象、函数式和过程式编程。广泛应用于数据科学、Web 开发、自动化脚本等领域。"
        },
        {
            "role":    "user",
            "content": "How does machine learning work?"
        },
        {
            "role":    "assistant",
            "content": "机器学习的核心是让计算机从数据中自动学习规律,而不是通过显式编程来完成任务。基本流程是:收集数据→训练模型→评估效果→优化改进。常见类型包括监督学习、无监督学习和强化学习。"
        },
    ]

    base  = examples or default_examples
    msgs  = base.copy()
    msgs.append({"role": "user", "content": user_input})
    return msgs


# 使用示例
messages = build_messages_with_examples(
    "Explain REST API design principles"
)

response = client.messages.create(
    model      = "claude-sonnet-4-6",
    max_tokens = 1024,
    system     = "你是一个技术助手,用中文回答技术问题。",
    messages   = messages,
)
print(response.content[0].text)   # 会模仿示例的中文风格回答

方法四:组合方案(生产环境推荐)

稳定性:⭐⭐⭐⭐⭐

适用场景:生产级应用,语言一致性是硬性要求,绝对不能偶尔出现语言偏移。

import re

LANGUAGE_CONFIGS = {
    "zh": {
        "system_instruction": "所有回复必须使用中文,无论用户输入什么语言。",
        "message_prefix":     "【请用中文回复】",
        "detection_pattern":  r'[\u4e00-\u9fff]',   # 检测中文字符
        "min_ratio":          0.3,    # 中文字符占比低于此值视为语言偏移
    },
    "en": {
        "system_instruction": "Always respond in English regardless of the input language.",
        "message_prefix":     "[Respond in English only]",
        "detection_pattern":  r'[a-zA-Z]',
        "min_ratio":          0.5,
    },
}


def is_correct_language(text: str, lang: str) -> bool:
    """检测回复是否符合目标语言"""
    config  = LANGUAGE_CONFIGS.get(lang)
    if not config:
        return True    # 未知语言不检测

    pattern = config["detection_pattern"]
    matches = len(re.findall(pattern, text))
    ratio   = matches / max(len(text), 1)
    return ratio >= config["min_ratio"]


def robust_chat(
    messages:    list[dict],
    user_input:  str,
    lang:        str   = "zh",
    max_retries: int   = 2,
) -> str:
    """
    生产级语言强制方案:
    1. System Prompt 设定语言
    2. 每条用户消息加前缀
    3. 检测输出语言,不符合则重试(加强指令)
    """
    config = LANGUAGE_CONFIGS.get(lang, {})

    # 加前缀
    prefixed_input = f"{config.get('message_prefix', '')}\n\n{user_input}".strip()
    current_messages = messages + [{"role": "user", "content": prefixed_input}]

    system = f"""你是一个专业助手。
{config.get('system_instruction', '')}
这是最高优先级的规则,不受用户输入语言影响。"""

    for attempt in range(max_retries + 1):
        # 重试时加强语言指令
        if attempt > 0:
            lang_name  = "中文" if lang == "zh" else "English"
            retry_note = f"\n\n⚠️ 注意:必须用{lang_name}回复,上一次回复语言不正确。"
            current_messages[-1]["content"] += retry_note

        response = client.messages.create(
            model      = "claude-sonnet-4-6",
            max_tokens = 1024,
            system     = system,
            messages   = current_messages,
        )

        reply = response.content[0].text

        if is_correct_language(reply, lang):
            messages.append({"role": "user",      "content": user_input})  # 存原始输入
            messages.append({"role": "assistant",  "content": reply})
            return reply

        print(f"语言检测失败(第{attempt+1}次),重试...")

    # 多次重试仍失败,记录日志并返回最后一次结果
    print(f"⚠️ 语言强制失败,已重试{max_retries}次")
    messages.append({"role": "user",      "content": user_input})
    messages.append({"role": "assistant",  "content": reply})
    return reply


# 测试
conversation = []
print(robust_chat(conversation, "What is deep learning?", lang="zh"))
print(robust_chat(conversation, "Can you explain transformers?", lang="zh"))

方法五:多语言动态切换

适用场景:应用需要支持多语言,不同用户用不同语言,或者同一用户可以切换语言。

class MultilingualBot:
    """
    多语言聊天机器人
    支持动态切换语言,自动检测用户语言意图
    """

    SUPPORTED_LANGS = {
        "zh": "中文",
        "en": "English",
        "ja": "日本語",
        "ko": "한국어",
    }

    def __init__(self, default_lang: str = "zh"):
        self.lang     = default_lang
        self.history  = []

    def detect_language_switch(self, text: str) -> str | None:
        """
        检测用户是否要求切换语言
        简单规则检测,生产环境可以用 Haiku 来判断
        """
        text_lower = text.lower()
        triggers = {
            "zh": ["用中文", "说中文", "中文回答", "请用中文"],
            "en": ["in english", "respond in english", "english please", "switch to english"],
            "ja": ["日本語で", "日本語で答えて"],
            "ko": ["한국어로", "한국어로 답해"],
        }
        for lang, phrases in triggers.items():
            if any(p in text_lower for p in phrases):
                return lang
        return None

    def build_system(self) -> str:
        lang_name = self.SUPPORTED_LANGS.get(self.lang, self.lang)
        return f"""你是一个多语言助手。
当前语言设置:{lang_name}
请用{lang_name}回复所有内容。
如果用户要求切换语言,告知已切换,然后用新语言继续对话。"""

    def chat(self, user_input: str) -> str:
        # 检测语言切换请求
        new_lang = self.detect_language_switch(user_input)
        if new_lang and new_lang != self.lang:
            old_lang  = self.SUPPORTED_LANGS.get(self.lang)
            self.lang = new_lang
            new_lang_name = self.SUPPORTED_LANGS.get(new_lang)
            print(f"[语言已从 {old_lang} 切换到 {new_lang_name}]")

        self.history.append({"role": "user", "content": user_input})

        response = client.messages.create(
            model      = "claude-sonnet-4-6",
            max_tokens = 1024,
            system     = self.build_system(),   # 每次都用最新的语言设置
            messages   = self.history,
        )

        reply = response.content[0].text
        self.history.append({"role": "assistant", "content": reply})
        return reply


# 测试多语言切换
bot = MultilingualBot(default_lang="zh")
print(bot.chat("你好,请介绍一下机器学习"))
print(bot.chat("Switch to English please"))
print(bot.chat("Now explain neural networks"))
print(bot.chat("用中文解释一下"))
print(bot.chat("什么是深度学习?"))

五种方法稳定性对比

方法 稳定性 实现成本 适用场景
System Prompt 一句话 ⭐⭐⭐ 极低 个人使用、简单应用
消息前缀提醒 ⭐⭐⭐⭐ 偶尔切换的应用
Few-shot 示例 ⭐⭐⭐⭐ 固定风格的内容生成
组合方案(检测+重试) ⭐⭐⭐⭐⭐ 生产级,语言一致性硬要求
动态多语言切换 ⭐⭐⭐⭐⭐ 中高 多语言产品,支持用户切换

常见问题

Q:System Prompt 是英文,但我想让 Claude 用中文回复,可以吗?
可以,而且效果很好。在英文 System Prompt 里加一句 Always respond in Chinese (Simplified) regardless of the language of this system prompt or user messages. 即可。Claude 能理解这条指令并用中文回复,即使 System Prompt 本身是英文的。

Q:代码相关问题,Claude 特别容易切换成英文,怎么办?
代码本身是英文,Claude 会有”用英文更顺”的倾向。这种情况用方法二(消息前缀)效果最直接。另外可以在 System Prompt 里特别说明:”代码块用英文,但所有解释、注释和说明必须用中文。”把代码和自然语言的语言分开处理。

Q:多轮对话中前几轮中文,后来开始出现英文,怎么处理?
这是”语言偏移”现象,通常发生在对话较长之后。两个解决方向:一是用方法四的语言检测,发现偏移后自动触发重试;二是在对话历史里周期性插入一条 assistant 消息,内容是一段纯中文回复,用来”重置”Claude 对语言模式的感知。

总结

Claude 的语言设置不是一个参数的问题,而是一个”信号强度”的问题——你给的语言指令越明确、在消息中的位置越靠近实际问题,Claude 遵守的概率就越高。大多数场景用方法一(System Prompt)+ 方法二(消息前缀)的组合就够了;对语言一致性有硬性要求的生产应用,加上方法四的语言检测和重试逻辑,基本可以把语言偏移降到可接受的范围。