三、大模型 prompt 工程(提示词工程)
在 LangChain 中,创建不同类型的 Prompt 主要依赖于 PromptTemplate、FewShotPromptTemplate 以及消息列表(ChatPromptTemplate)的组合。
以下是基于 LangChain Core (langchain-core) 实现的 6 种经典 Prompt 类型的代码示例。
前置准备
确保你已安装最新版 LangChain:
pip install -U langchain langchain-openai
1. 零样本提示 (Zero-Shot Prompting)
核心: 直接使用 PromptTemplate,只包含指令和输入变量。
from langchain_core.prompts import PromptTemplate
from connect_llm import qw_llm
# 定义模板
zero_shot_template = PromptTemplate.from_template(
"请将以下文本翻译成 {language}:\n{text}"
)
# 构建链
chain = zero_shot_template | qw_llm
# 调用
response = chain.invoke({"language": "英语", "text": "你好,世界"})
print(f"Zero-Shot: {response.content}")

2. 少样本提示 (Few-Shot Prompting)
核心: 使用 FewShotPromptTemplate 动态插入示例,或使用 ChatPromptTemplate 手动构建消息列表。这里展示更灵活的 ChatPromptTemplate 方式(推荐用于对话模型)。
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
from connect_llm import qw_llm
# 定义示例数据
examples = [
{"input": "快乐的", "output": "正面"},
{"input": "悲伤的", "output": "负面"},
{"input": "愤怒的", "output": "负面"},
]
# 创建示例提示模板 (定义示例的格式)
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "情感分析输入: {input}"),
("ai", "情感分类: {output}"),
]
)
# 创建少样本消息提示 (自动选取最相关的 k 个示例,这里全选)
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
input_variables=["input"], # 这里不需要额外变量,因为例子是固定的
)
# 主模板:包含系统指令 + 少样本示例 + 用户最终输入
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "你是一个情感分析助手。请根据示例判断用户输入的情感。"),
few_shot_prompt, # 插入示例
("human", "{input}"), # 用户实际输入
]
)
chain = final_prompt | qw_llm
response = chain.invoke({"input": "开心的"})
print(f"Few-Shot: {response.content}")

3. 思维链提示 (Chain-of-Thought, CoT)
核心: 在 Prompt 中显式加入“让我们一步步思考”的指令,或者提供带有推理过程的 Few-Shot 示例。
from langchain_core.prompts import PromptTemplate, FewShotChatMessagePromptTemplate, ChatPromptTemplate
from connect_llm import qw_llm
# 方法 A: 直接指令法 (最简单)
cot_template = PromptTemplate.from_template(
"问题:{question}\n"
"请一步步进行推理,最后给出答案。\n"
"推理过程:"
)
# 方法 B: 少样本 CoT (效果更好,提供带推理的示例)
cot_examples = [
{
"q": "罗杰有5个网球,又买了2筒(每筒3个),共有几个?",
"a": "罗杰原有5个。2筒每筒3个,即2*3=6个。总共5+6=11个。答案是11。"
},
{
"q": "食堂有23个苹果,用掉20个,又买来6个,现在有几个?",
"a": "原有23个。用掉20个剩3个。买来6个,3+6=9个。答案是9。"
}
]
# 构建带推理示例的 Few-Shot 模板
cot_few_shot = FewShotChatMessagePromptTemplate(
example_prompt=ChatPromptTemplate.from_messages([
("human", "{q}"),
("ai", "{a}")
]),
examples=cot_examples,
input_variables=["q"]
)
final_cot_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个数学专家。请先展示推理步骤,再给出最终答案。"),
cot_few_shot,
("human", "{q}")
])
chain = final_cot_prompt | qw_llm
response = chain.invoke({"q": "我有3个苹果,吃了1个,又分了剩下的一半给朋友,我还剩几个?"})
print(f"CoT: {response.content}")

4. 角色设定提示 (Role-Playing / Persona)
核心: 在 System Message 中详细定义角色的背景、语气和约束。
from langchain_core.prompts import ChatPromptTemplate
from connect_llm import qw_llm
role_template = ChatPromptTemplate.from_messages(
[
(
"system",
"你是一位拥有20年经验的资深 {role_name}。\n"
"你的性格特点:{personality}。\n"
"你的回答风格:{style}。\n"
"请严格遵守以下约束:{constraints}"
),
("human", "{user_input}")
]
)
chain = role_template | qw_llm
response = chain.invoke({
"role_name": "Python 架构师",
"personality": "严谨、直接、喜欢最佳实践",
"style": "使用技术术语,提供代码片段",
"constraints": "不要解释基础概念,直接指出性能瓶颈",
"user_input": "这段代码有什么性能问题?\nfor i in range(1000000): pass"
})
print(f"Role-Play: {response.content}")

5. 结构化/模板化提示 (Structured Prompting)
核心: 使用分隔符(如 XML 标签)清晰划分指令区、上下文区和数据区,防止注入并提高解析度。
from langchain_core.prompts import PromptTemplate
from connect_llm import qw_llm
# 优化后的 Prompt
structured_template = PromptTemplate.from_template(
"""# 角色
你是一名精准的数据提取助手。
# 任务
从下方的 <data> 标签中提取**所有被提及的人名**及其**文中明确提到或通过简单上下文可知的年龄**。
# 重要规则
1. **不要遗漏**:即使某个人物只是作为比较的参照物(例如“比王五大”中的王五),只要文中提到了他的名字和年龄,必须提取。
2. **直接提取**:优先提取文中直接给出的数字。如果年龄需要通过简单加减法得出(如“比...大2岁”),也可以计算后提取,但必须确保所有提及的人都出现在结果中。
3. **格式严格**:仅输出 JSON,无其他文字。
# 输出格式
{{"people": [{{"name": "姓名", "age": 年龄数字}}]}}
# 数据
<data>
{raw_text}
</data>
# 开始提取
"""
)
chain = structured_template | qw_llm
text_data = "张三今年25岁,李四比王五(30岁)大2岁。"
response = chain.invoke({"raw_text": text_data})
print(f"Optimized: {response.content}")

6. 自洽性/反思提示 (Self-Consistency / Reflection)
核心: 这通常不是一个单一的 Prompt 模板,而是一个链式工作流 (Chain)。
流程:生成答案 -> 让模型反思/验证 -> 修正答案。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from connect_llm import qw_llm
# 第一步:生成初始答案
generator_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个解题助手。"),
("human", "问题:{question}\n请给出一个初步解决方案。")
])
# 第二步:反思/验证 (Critic)
reflector_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个严格的审查员。检查以下方案是否有逻辑漏洞或错误。如果有,请指出并提供修正后的方案。"),
("human", "原始方案:{initial_answer}\n\n请审查并修正:")
])
# 构建反思链 (Generator -> Reflector)
# 注意:这里需要把第一步的输出作为第二步的输入
reflection_chain = (
generator_prompt
| qw_llm
| StrOutputParser() # 获取纯文本
| (lambda initial_answer: {"initial_answer": initial_answer, "question": None}) # 构造第二步的输入 (这里简化处理,实际需传递原问题)
# 上面 lambda 写法为了演示结构,实际完整写法如下:
)
# ✅ 正确的完整反射链写法 (使用 RunnablePassthrough 传递上下文)
from langchain_core.runnables import RunnablePassthrough
full_reflection_chain = (
{
"initial_answer": (generator_prompt | qw_llm | StrOutputParser()),
"question": RunnablePassthrough() # 保留原始问题传入下一步(如果需要)
}
| reflector_prompt
| qw_llm
)
# 由于 reflector_prompt 定义中只需要 initial_answer,我们调整一下 prompt 定义以匹配
reflector_prompt_simple = ChatPromptTemplate.from_messages([
("system", "审查以下方案,如有错误请修正:"),
("human", "方案:{initial_answer}")
])
final_self_consistency_chain = (
{
"initial_answer": (generator_prompt | qw_llm | StrOutputParser())
}
| reflector_prompt_simple
| qw_llm
)
response = final_self_consistency_chain.invoke("鸡兔同笼,头35,脚94,求鸡兔各几只?")
print(f"Self-Reflection: {response.content}")

总结与建议
| 类型 | LangChain 核心组件 | 关键点 |
|---|---|---|
| Zero-Shot | PromptTemplate |
简单直接,适合简单任务。 |
| Few-Shot | FewShotChatMessagePromptTemplate |
动态加载示例,适合格式模仿。 |
| CoT | FewShotChatMessagePromptTemplate (带推理示例) |
示例中必须包含“推理过程”。 |
| Role-Play | ChatPromptTemplate (System Message) |
System Prompt 定义越细,角色越像。 |
| Structured | PromptTemplate + XML 标签 |
用 <tag> 包裹用户输入,防注入。 |
| Reflection | RunnableSequence (链式组合) |
将“生成”和“审查”两个 LLM 调用串联。 |
最佳实践:在生产环境中,尽量使用 ChatPromptTemplate 而不是旧的 PromptTemplate,因为它更好地支持了 System/Human/AI 的消息角色分离,这对现代大模型(如 GPT-4, Qwen, Claude)的效果至关重要。
完整项目源码:
- https://github.com/Tangugo/langchain_project#
- commit id: 783ebf0
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)