
本文详解 langchain 中 chatprompttemplate 的消息类型分工,指出原链因混淆 system 与 human 角色导致翻译失效,并提供结构清晰、可复用的 prompt 链设计方法,确保改写与目标语言翻译同步准确完成。
本文详解 langchain 中 chatprompttemplate 的消息类型分工,指出原链因混淆 system 与 human 角色导致翻译失效,并提供结构清晰、可复用的 prompt 链设计方法,确保改写与目标语言翻译同步准确完成。
在 LangChain 的 ChatPromptTemplate 中,system、human(或 user)和 ai 三类消息承担严格区分的语义角色:
- system 消息用于设定模型身份、能力边界与行为准则(如“你是一个专业翻译助手”),不承载具体任务指令;
- human 消息才是触发模型执行动作的核心输入,必须明确、完整地描述待处理任务(如“请先改写以下文本,再译为德语”);
- ai 消息仅用于少样本示例(few-shot)场景,在推理链中通常不显式出现。
原代码的问题根源在于将关键任务指令(“重写并翻译为 {language}”)错误地置于 system 消息中,而 user 消息仅传递了原始文本 {input}。由于大模型更倾向于将 system 内容视为背景约束而非可执行指令,它仅完成了改写(默认语言),却忽略了翻译要求。
✅ 正确做法是:将角色定义放在 system,将具体多步任务明确写入 human 模板。以下是优化后的完整链实现:
# ✅ 正确定义 system + human 双消息结构
system_message = "You are a professional linguistic assistant skilled in paraphrasing technical documents and translating them accurately across European languages."
human_template = """Your task has two mandatory steps:
1. Rephrase the following text clearly and professionally, preserving all factual details and technical terms: {input}
2. Translate the rephrased version into {language}. Do NOT output anything other than the final translated text."""
chat_prompt = ChatPromptTemplate.from_messages([
("system", system_message),
("human", human_template),
])
# 绑定 LLM 与输出解析器
chain = chat_prompt | llm | StrOutputParser()
# 调用时传入用户输入和目标语言(注意:此处应传 language_code,如 "cs",而非显示标签 "Czech (CZ)")
answer = chain.invoke({
"input": user_input,
"language": selected_label # ← 关键修正:使用字典键(如 "cs")而非值(如 "Czech (CZ)")
})⚠️ 注意事项:
- 语言参数一致性:前端 language_options 字典的 key(如 "cs")才是标准语言代码,应直接传给 prompt;若传入 "Czech (CZ)",模型可能无法识别,导致翻译失败。
- 指令原子性:避免在 system 中混入操作指令;所有“做什么”必须出现在 human 模板中,并用编号、换行等增强可读性。
- 输出控制:添加 Do NOT output anything other than... 等强约束语句,可显著提升 StrOutputParser 解析稳定性,防止模型附加解释或格式符号。
通过严格遵循消息角色分工,并将任务逻辑内聚于 human 模板,即可构建出可靠、可维护、符合预期的 prompt chain。

















