Prompt工程:用语言精准指挥AI

作者:技术拾光

时间:2026-05-29

浏览:163

高质量提示词遵循黄金公式:清晰角色、明确任务、具体约束、期望格式。LangChain通过PromptTemplate和ChatPromptTemplate动态生成,结合Few-Shot示例与思维链推理,显著提升模型输出的准确性与可控性,使AI更精准可靠。

文章目录
```html

先抛一个问题:很多人学会调用大模型API之后,第一反应往往是——为什么同一个问题,有时候回答得让人眼前一亮,有时候却前言不搭后语?

答案几乎都藏在Prompt里。Prompt模板的质量,直接决定了AI输出表现的上限。

同样一个任务,随便写一个Prompt和精心设计一个Prompt,差距有多大?直接看个例子就明白了。

#  模糊的 Prompt
prompt_bad = "总结一下这篇文章"
# AI 可能输出:3 句话,也可能输出 3 段,风格不定,不知道要点

#  精准的 Prompt
prompt_good = """
请对以下文章进行总结。要求:
1. 用不超过 150 字
2. 必须包含:核心观点、关键数据、适用结论
3. 使用简洁的中文,避免专业术语
4. 格式为:【核心观点】... 【关键数据】... 【结论】...
文章内容:{article}
"""

那么,怎么才算一个好的Prompt呢?行业里其实有个黄金公式:高质量Prompt = 清晰角色 + 明确任务 + 具体约束 + 期望格式。遵循这个公式来构建Prompt模板,是提升AI应用效果的关键一步。

二、LangChain 为什么需要 Prompt 模板

在实际项目开发中,Prompt很少是写死的字符串。更多时候,它是根据用户的输入动态生成的。LangChain的Prompt模板就是为这个场景设计的,主要解决了三个问题:

  1. 复用性——同一个提示结构,可以填入不同的变量值,避免重复造轮子,显著提升Prompt模板的开发效率。
  2. 可测试性——模板和数据分离,单独调试模板逻辑,定位问题更高效。
  3. 与Chain集成——模板可以无缝接入LCEL链,让Prompt模板成为整个AI链路的标准化入口。

Prompt工程:用语言精准指挥AI

三、Step 1:基础 Prompt 模板

PromptTemplate:纯文本模板入门

先从最简单的纯文本模板入手。核心就是用 {} 标记变量,然后用 .format() 填充。这种Prompt模板适合快速原型验证。

from langchain_core.prompts import PromptTemplate

# ── 创建模板,用 {} 标记变量 ──────────────────────────────────
template = PromptTemplate(
    input_variables=["topic", "audience", "length"],
    template="""
你是一位经验丰富的科普作家。请为【{audience}】写一篇关于"{topic}"的科普文章。
要求:
- 文章长度:{length}字以内
- 语言:通俗易懂,避免专业术语
- 结构:先讲是什么,再讲为什么重要,最后给出实际例子
"""
)

# ── 填充变量生成最终 Prompt ──────────────────────────────────
formatted = template.format(
    topic="区块链",
    audience="初中生",
    length="300"
)
print(formatted)

ChatPromptTemplate:对话模板推荐使用

在实际工作中,更推荐用 ChatPromptTemplate。它能分角色定义消息——system负责设定身份和行为准则,human放用户的问题,整个结构更清晰,也更能发挥对话模型的效果。这是构建生产级Prompt模板的首选方式。

from langchain_core.prompts import ChatPromptTemplate

# ── 多角色对话模板 ────────────────────────────────────────────
chat_prompt = ChatPromptTemplate.from_messages([
    # system:定义 AI 的专业身份和行为准则
    ("system", """
你是一位专业的{role},拥有{years}年从业经验。回答时遵循以下规范:
- 先给出明确结论,再解释原因
- 如果问题超出专业范围,直接告知
- 用中文回答,简洁专业
"""),
    # human:用户的问题
    ("human", "{question}"),
])

# ── 格式化为消息列表 ──────────────────────────────────────────
messages = chat_prompt.format_messages(
    role="心脏病学医生",
    years=15,
    question="心率超过 100 次/分钟算正常吗?",
)

# messages 是一个列表:[SystemMessage(...), HumanMessage(...)]
for msg in messages:
    print(f"[{msg.__class__.__name__}]: {msg.content}")

把这个Prompt模板和LLM对接起来,有两种方式。一种是先格式化,再调用;另一种是用链的方式,更推荐后者,下一章会详细展开。

from langchain_openai import ChatOpenAI
import os

llm = ChatOpenAI(
    model="qwen-plus",
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

# 方式一:先格式化,再调用
messages = chat_prompt.format_messages(role="营养师", years=10, question="早餐吃什么最健康?")
response = llm.invoke(messages)
print(response.content)

# 方式二:用链(推荐,下一章深讲)
chain = chat_prompt | llm
response = chain.invoke({"role": "营养师", "years": 10, "question": "早餐吃什么最健康?"})
print(response.content)

四、Step 2:Few-Shot 提示(示例驱动)

什么情况需要Few-Shot?说白了就是"给几个例子"。你给模型展示几个"输入→输出"的例子,模型就能理解你期望的格式和风格,然后对新输入产生类似的输出。这是Prompt模板中处理特殊格式需求的有效手段。

适用场景很明确:

  • 需要特定格式的输出(JSON、表格、特定句式)
  • 需要特定风格(文言文、专业术语、儿童语言)
  • 模型不擅长的小众任务(情感分类、命名实体识别)

来看一个电商评论情感分析的例子,感受一下就清楚了。

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_openai import ChatOpenAI

# ── 定义示例:每个示例都是一个 dict ──────────────────────────
examples = [
    {
        "text": "这款手机电池续航太差了,一天充两次电,差评!",
        "sentiment": "负面",
        "reason": "用户对电池续航不满"
    },
    {
        "text": "物流超快,下单第二天就到了,包装也很严实。",
        "sentiment": "正面",
        "reason": "用户对物流速度和包装满意"
    },
    {
        "text": "质量还行,但价格有点贵,性价比一般。",
        "sentiment": "中性",
        "reason": "质量满意但价格不满意,整体中立"
    },
]

# ── 单个示例的展示模板 ────────────────────────────────────────
example_prompt = PromptTemplate(
    input_variables=["text", "sentiment", "reason"],
    template="评论:{text}\n情感:{sentiment}\n原因:{reason}"
)

# ── Few-Shot 模板 ─────────────────────────────────────────────
few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="你是一个电商评论情感分析专家。请分析以下评论的情感倾向(正面/负面/中性)并说明原因:\n\n参考示例:",
    suffix="\n评论:{text}\n情感:",  # 最后留空,让模型填写
    input_variables=["text"],
    example_separator="\n---\n",  # 示例之间的分隔符
)

# ── 调用 ─────────────────────────────────────────────────────
llm = ChatOpenAI(
    model="qwen-plus",
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

test_reviews = [
    "屏幕显示效果非常清晰,色彩还原准确,专业摄影师推荐!",
    "买了之后根本用不了,联系客服也没人回,气死了。",
]

for review in test_reviews:
    formatted = few_shot_prompt.format(text=review)
    response = llm.invoke(formatted)
    print(f"评论:{review}")
    print(f"分析:{response.content}")
    print("-" * 50)

Prompt工程:用语言精准指挥AI

五、Step 3:思维链提示(Chain of Thought)

直接让AI回答复杂问题时,它常常跳步推理,然后就出错了。思维链(CoT)的思路就是强制模型一步步思考,每个步骤都显式写出来。这样做,错误率明显下降,推理也更可靠。在Prompt模板中加入思维链引导,是处理复杂推理任务的重要技巧。

研究数据也印证了这一点:在复杂推理任务上,CoT提示可以将准确率提升20-50%。

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# ── 不带思维链(容易出错)────────────────────────────────────
no_cot_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是数学老师,直接给出答案。"),
    ("human", "{question}"),
])

# ── 带思维链(逐步推理)──────────────────────────────────────
cot_prompt = ChatPromptTemplate.from_messages([
    ("system", """
你是数学老师。解题时必须按以下格式逐步推理:
【分析】:理解题目,找出已知条件
【步骤1】:...(写出每一步的计算)
【步骤N】:...
【答案】:最终结果

绝不能跳过中间步骤,必须展示完整推理过程。
"""),
    ("human", "{question}"),
])

llm = ChatOpenAI(
    model="qwen-plus",
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
    temperature=0,  # 数学题用 0,确保结果稳定
)

question = """一家餐厅周一到周五每天接待 80 位顾客,周六接待 120 位,周日不营业。每位顾客平均消费 85 元,月均营业天数按 4.3 周计算。请计算该餐厅每月的营业额。"""

print("=" * 50)
print("不带思维链的回答:")
chain_no_cot = no_cot_prompt | llm
print(chain_no_cot.invoke({"question": question}).content)

print("\n" + "=" * 50)
print("带思维链的回答:")
chain_cot = cot_prompt | llm
print(chain_cot.invoke({"question": question}).content)

有时候连示例都不想给,怎么办?试试Zero-Shot CoT,只需要在问题末尾加上一句话,就能激活模型的推理模式:

# 只需要在问题末尾加上这句话,就能激活模型的推理模式
question_with_cot = f"{question}\n\n让我们一步一步地思考。"

六、Prompt 最佳实践速查

原则 1:具体优于模糊

#  模糊
"帮我改进这段代码"

#  具体
"检查以下 Python 代码的潜在 bug 和性能问题,按【问题】【位置】【修复建议】格式输出,重点关注:空指针、资源泄漏、时间复杂度"

原则 2:使用分隔符隔离数据

#  容易被用户内容干扰(Prompt 注入风险)
f"总结这篇文章:{user_input}"

#  用 XML 标签或分隔符隔离
f"""
总结以下
标签内的文章:
{user_input}
要求:100字以内,提取核心观点。 """

原则 3:角色设定要具体

#  过于泛泛
("system", "你是专家")

#  明确背景和能力
("system", """
你是一位拥有 10 年经验的全栈工程师,擅长 Python、React 和 AWS 架构。
当回答技术问题时,优先给出可直接运行的代码示例,并标注关键参数的作用。
""")

原则 4:控制输出格式

# 要求输出 JSON
("system", """
以 JSON 格式输出,字段包括:
- "summary": 文章摘要(50字以内)
- "keywords": 关键词列表(3-5个)
- "sentiment": 情感倾向(positive/negative/neutral)

不要输出任何 JSON 之外的文字。
""")

七、常见 Prompt 问题与调试方法

问题现象 可能原因 调试方法
输出格式不稳定 格式要求不够明确 在 prompt 中加入示例输出
答案偏离主题 系统提示太弱或无系统提示 强化 system 消息的约束
输出截断 max_tokens 设置太小 增大 max_tokens
数学计算出错 没有使用 CoT 加入逐步推理要求
多言混杂 没有语言约束 在 prompt 中明确"用中文回答"

最后说一个调试小技巧:先 print(prompt.format(...)) 看看格式化后的完整Prompt长什么样,很多时候毛病的根源一眼就能看出来。掌握Prompt模板的调试方法,能大幅提升AI应用的开发效率。

```

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章