大语言模型与 Prompt 工程
大语言模型与 Prompt 工程
简介
大语言模型(LLM)是基于 Transformer 架构的深度学习模型,通过海量文本训练获得语言理解和生成能力。Prompt 工程是与 LLM 交互的关键技术,通过精心设计提示词来引导模型输出高质量结果,无需修改模型参数。
大语言模型的核心能力源于两个关键机制:自注意力(Self-Attention)允许模型理解文本中任意位置之间的依赖关系,而自回归生成(Autoregressive Generation)让模型能够逐 token 生成连贯的文本。Prompt 工程的本质,就是找到一种有效的"指令编码"方式,让模型能够准确理解任务意图并生成符合预期的输出。在工程实践中,Prompt 不仅是几句提示词,更是一套包含角色设定、上下文注入、输出约束和安全边界的系统化设计。
特点
LLM 核心概念
Transformer 架构回顾
import torch
import torch.nn as nn
import math
class MultiHeadAttention(nn.Module):
"""
多头注意力机制——Transformer 的核心组件
LLM 的语言理解能力主要来源于此
"""
def __init__(self, embed_dim=512, num_heads=8):
super().__init__()
self.num_heads = num_heads
self.head_dim = embed_dim // num_heads
self.scale = self.head_dim ** -0.5
self.q_proj = nn.Linear(embed_dim, embed_dim)
self.k_proj = nn.Linear(embed_dim, embed_dim)
self.v_proj = nn.Linear(embed_dim, embed_dim)
self.out_proj = nn.Linear(embed_dim, embed_dim)
def forward(self, x, mask=None):
B, N, C = x.shape
q = self.q_proj(x).reshape(B, N, self.num_heads, self.head_dim).transpose(1, 2)
k = self.k_proj(x).reshape(B, N, self.num_heads, self.head_dim).transpose(1, 2)
v = self.v_proj(x).reshape(B, N, self.num_heads, self.head_dim).transpose(1, 2)
attn = (q @ k.transpose(-2, -1)) * self.scale
if mask is not None:
attn = attn.masked_fill(mask == 0, float('-inf'))
attn = attn.softmax(dim=-1)
out = (attn @ v).transpose(1, 2).reshape(B, N, C)
return self.out_proj(out)
# 演示注意力计算
attn = MultiHeadAttention(embed_dim=512, num_heads=8)
x = torch.randn(2, 20, 512) # batch=2, seq_len=20, dim=512
out = attn(x)
print(f"输入: {x.shape} → 输出: {out.shape}")LLM 文本生成过程
import torch
import torch.nn.functional as F
def generate_text(model, input_ids, max_new_tokens=50, temperature=1.0, top_k=50):
"""
自回归文本生成过程:
模型逐 token 预测下一个词的概率分布,
然后从中采样生成下一个 token,循环往复
"""
model.eval()
generated = input_ids.clone()
for _ in range(max_new_tokens):
# 获取模型输出
with torch.no_grad():
outputs = model(generated)
logits = outputs[:, -1, :] # 只取最后一个 token 的预测
# 温度调节:控制输出的随机性
logits = logits / temperature
# Top-K 采样:只保留概率最高的 K 个 token
if top_k > 0:
top_k_values, _ = torch.topk(logits, top_k)
logits[logits < top_k_values[:, -1:]] = float('-inf')
# 转换为概率分布
probs = F.softmax(logits, dim=-1)
# 采样下一个 token
next_token = torch.multinomial(probs, num_samples=1)
generated = torch.cat([generated, next_token], dim=-1)
return generated
print("自回归生成函数已定义")
print("关键参数:")
print(" temperature < 1.0 → 输出更确定性")
print(" temperature > 1.0 → 输出更多样性")
print(" top_k = 1 → 贪心解码(总是选概率最高的)")关键生成参数对比
| 参数 | 作用 | 推荐值 | 适用场景 |
|---|---|---|---|
| temperature | 控制随机性 | 0.0-0.3 确定性 / 0.7-1.0 创意性 | 低温度适合事实性任务,高温度适合创意写作 |
| top_p | 核采样阈值 | 0.9-0.95 | 与 temperature 配合使用,比 top_k 更平滑 |
| top_k | 限制候选 token 数 | 40-50 | 简单有效,适合大部分场景 |
| max_tokens | 最大生成长度 | 按需设置 | 控制成本,防止无限生成 |
| frequency_penalty | 降低重复 | 0.0-1.0 | 长文本生成时避免重复 |
| presence_penalty | 鼓励新话题 | 0.0-1.0 | 鼓励模型讨论更多话题 |
Prompt 基础技巧
角色设定
你是一位资深的 .NET 架构师,拥有 10 年以上微服务开发经验。
请根据以下需求,给出技术方案:
需求:设计一个支持百万级并发的订单系统
要求:
1. 使用领域驱动设计(DDD)拆分服务
2. 考虑分布式事务处理方案
3. 给出关键技术选型和理由
4. 提供架构图描述(用文本表示)# 用代码构建角色设定的 Prompt
def build_role_prompt(role: str, expertise: str, task: str, constraints: list[str]) -> str:
"""
构建结构化的角色 Prompt
好的角色设定包含:身份、专长、任务、约束
"""
prompt = f"""你是一位{role},拥有丰富的{expertise}经验。
你的任务:{task}
约束条件:
"""
for i, constraint in enumerate(constraints, 1):
prompt += f"{i}. {constraint}\n"
prompt += "\n请按以下结构输出:\n1. 方案概述\n2. 技术细节\n3. 风险评估\n4. 实施建议"
return prompt
# 使用示例
prompt = build_role_prompt(
role="资深系统架构师",
expertise="高并发分布式系统设计",
task="设计一个支持百万级并发的电商订单系统",
constraints=[
"使用微服务架构",
"考虑数据一致性",
"给出性能指标预估",
"包含容灾和降级方案"
]
)
print(prompt)Few-Shot 示例
请根据示例,将用户的自然语言转换为 SQL 查询:
示例1:
用户:查询所有年龄大于30的用户
SQL:SELECT * FROM users WHERE age > 30;
示例2:
用户:统计每个部门的员工数量
SQL:SELECT department, COUNT(*) FROM employees GROUP BY department;
现在请转换:
用户:查询最近7天销售额最高的前5个商品
SQL:def build_few_shot_prompt(examples: list[dict], query: str) -> str:
"""
构建 Few-shot Prompt 的通用函数
examples: [{"input": "...", "output": "..."}, ...]
"""
prompt = "请参考以下示例完成任务:\n\n"
for i, example in enumerate(examples, 1):
prompt += f"示例{i}:\n"
prompt += f"输入:{example['input']}\n"
prompt += f"输出:{example['output']}\n\n"
prompt += f"现在请处理:\n输入:{query}\n输出:"
return prompt
# Few-shot 示例
sentiment_examples = [
{"input": "这个产品非常好用,强烈推荐", "output": "正面"},
{"input": "质量太差了,浪费钱", "output": "负面"},
{"input": "还行吧,没什么特别", "output": "中性"},
]
prompt = build_few_shot_prompt(sentiment_examples, "发货很快,包装也很好")
print(prompt)Chain of Thought(思维链)
请一步步分析以下问题:
一个电商平台的用户反馈:搜索"手机壳"时,出现了手机充电器。
分析步骤:
1. 问题可能出在哪个环节?(搜索索引/分词/排序/推荐)
2. 每个环节可能的故障原因
3. 如何验证你的假设
4. 推荐的修复方案
请确保每一步都给出详细推理过程。def build_cot_prompt(problem: str, steps: list[str] = None) -> str:
"""
构建 Chain of Thought Prompt
关键:要求模型展示推理过程,而非直接给出答案
"""
if steps is None:
steps = [
"理解问题:明确问题的关键信息",
"分析原因:列出可能的原因",
"验证假设:给出验证方法",
"得出结论:基于分析给出答案"
]
prompt = f"请一步一步分析以下问题:\n\n问题:{problem}\n\n"
prompt += "请按以下步骤进行分析:\n"
for i, step in enumerate(steps, 1):
prompt += f"步骤{i}:{step}\n"
prompt += "\n请确保每一步都给出详细的推理过程。"
return prompt
# 使用示例
prompt = build_cot_prompt(
"系统在高并发时出现偶发的数据库连接超时",
steps=[
"确认问题范围:哪些接口受影响、并发量多少",
"排查连接池配置:最大连接数、超时时间、等待队列",
"分析数据库负载:慢查询、锁等待、资源瓶颈",
"给出解决方案:短期修复和长期优化"
]
)
print(prompt)Self-Consistency(自洽性采样)
def self_consistency_solving(model, problem: str, num_samples: int = 5):
"""
Self-Consistency 策略:
多次采样同一问题,取最一致的答案
通过多数投票提高推理准确性
"""
answers = []
for _ in range(num_samples):
# 使用较高的 temperature 进行多次采样
answer = model.generate(
prompt=problem,
temperature=0.7,
do_sample=True
)
answers.append(answer)
# 统计最频繁的答案
from collections import Counter
most_common = Counter(answers).most_common(1)[0]
print(f"采样 {num_samples} 次:")
for i, ans in enumerate(answers, 1):
print(f" 样本{i}: {ans}")
print(f"最终答案(出现{most_common[1]}次): {most_common[0]}")
return most_common[0]
print("Self-Consistency 采样策略已定义")
print("适用于:数学推理、逻辑判断等需要精确答案的任务")结构化输出
JSON 格式输出
请分析以下代码的性能问题,以 JSON 格式输出:
输出格式:
{
"issues": [
{
"type": "性能问题类型",
"description": "问题描述",
"severity": "高/中/低",
"fix": "修复建议",
"code": "修复后的代码"
}
],
"summary": "总体评价"
}import json
def structured_output_prompt(task: str, output_schema: dict) -> str:
"""
构建结构化输出 Prompt
关键:明确指定输出格式,减少格式错误
"""
prompt = f"""请完成以下任务:{task}
请严格按照以下 JSON 格式输出,不要输出任何额外内容:
```json
{json.dumps(output_schema, ensure_ascii=False, indent=2)}注意:
- 只输出 JSON,不要有其他文字
- 所有字段都必须填写
- 如果某字段不适用,填 null
"""
return prompt
使用示例
schema = {
"analysis": {
"sentiment": "正面/负面/中性",
"confidence": 0.0,
"keywords": ["关键词1", "关键词2"],
"aspects": [
{"aspect": "方面", "opinion": "观点", "sentiment": "正面/负面/中性"}
]
}
}
prompt = structured_output_prompt("分析这条用户评价的情感倾向", schema)
print(prompt[:300] + "...")
### 表格输出
```text
请对比以下 ORM 框架,以 Markdown 表格形式输出:
对比维度:EF Core、Dapper、RepoDB
对比项包括:
- 查询性能
- 学习曲线
- 功能丰富度
- 社区活跃度
- 适用场景
- 推荐指数(1-5星)def table_output_prompt(items: list[str], dimensions: list[str]) -> str:
"""
构建表格输出 Prompt
"""
prompt = "请以 Markdown 表格形式输出对比结果:\n\n"
prompt += f"对比对象:{'、'.join(items)}\n\n"
prompt += "对比维度:\n"
for dim in dimensions:
prompt += f"- {dim}\n"
prompt += "\n请确保表格完整、评价客观、有具体数据支撑。"
return prompt
prompt = table_output_prompt(
items=["React", "Vue", "Angular"],
dimensions=["学习曲线", "生态成熟度", "性能", "TypeScript 支持", "适用场景"]
)
print(prompt)高级 Prompt 模式
ReAct 模式(推理+行动)
你是一个数据分析助手。对每个问题,请按以下格式回答:
思考:分析问题需要什么信息
行动:决定使用什么工具或方法
观察:记录中间结果
...(可重复多轮)
回答:给出最终答案
问题:公司上个月的客户流失率是多少?与去年同期相比如何?自我审查
请完成以下任务,然后自我检查:
任务:编写一个 C# 泛型仓库接口
完成代码后,请按以下检查清单审查:
1. ✅/❌ 接口是否遵循 SOLID 原则
2. ✅/❌ 泛型约束是否合理
3. ✅/❌ 异步方法是否正确使用 CancellationToken
4. ✅/❌ 返回类型是否使用接口而非具体类型
5. ✅/❌ 是否考虑了分页场景
如果发现问题,请自行修正并说明修改内容。Tree of Thoughts(思维树)
def tree_of_thoughts_prompt(problem: str, num_branches: int = 3) -> str:
"""
Tree of Thoughts(ToT)Prompt:
让模型同时探索多条推理路径,
评估每条路径的可行性后选择最优方案
"""
prompt = f"""请用思维树方法分析以下问题:
问题:{problem}
请按以下步骤:
1. 生成 {num_branches} 条不同的解决思路
2. 对每条思路评估其可行性和潜在风险
3. 对有潜力的思路进一步展开
4. 最终选择最优方案并给出理由
请用以下格式输出:
思路1: [描述] → 可行性评估: [高/中/低] → 理由: [说明]
思路2: [描述] → 可行性评估: [高/中/低] → 理由: [说明]
思路3: [描述] → 可行性评估: [高/中/低] → 理由: [说明]
最优方案: [选择] → 理由: [详细说明]
"""
return prompt
prompt = tree_of_thoughts_prompt(
"如何将一个单体应用逐步迁移到微服务架构",
num_branches=3
)
print(prompt)Directional Stimulus Prompting
def directional_prompt(base_prompt: str, direction: str) -> str:
"""
方向性刺激提示:
在 Prompt 中嵌入特定的引导词,
影响模型的推理方向
"""
prompt = f"""{base_prompt}
提示:{direction}
"""
return prompt
# 示例:引导模型给出更谨慎的回答
prompt = directional_prompt(
"分析这段代码是否有安全漏洞",
"请特别注意注入攻击、权限校验和敏感数据处理"
)
print(prompt)Prompt 模板
通用模板
【角色】你是一个 {角色描述}
【背景】{上下文信息}
【任务】{具体要求}
【约束】
- {约束1}
- {约束2}
【输出格式】{期望的输出格式}
【示例】{可选的示例}代码生成模板
请用 {编程语言} 实现 {功能描述}:
要求:
- 使用 {框架/库}
- 遵循 {编码规范}
- 包含错误处理
- 添加必要的注释
- 提供 {数量} 个使用示例
输入:{输入描述}
输出:{输出描述}RAG 问答模板
def build_rag_prompt(question: str, retrieved_docs: list[str]) -> str:
"""
RAG 场景下的 Prompt 模板
关键:强调"基于给定资料",减少幻觉
"""
context = "\n\n".join(
f"[文档{i+1}] {doc}" for i, doc in enumerate(retrieved_docs)
)
prompt = f"""你是一个企业知识助手。请严格基于以下资料回答问题。
如果资料中没有相关信息,请明确说明"提供的资料未覆盖此问题"。
不要编造或推测任何信息。
资料:
{context}
问题:{question}
请回答:
"""
return prompt
# 使用示例
prompt = build_rag_prompt(
question="退款后发票怎么处理?",
retrieved_docs=[
"订单签收后7天内可申请退款,虚拟商品除外。",
"退款成功后原发票作废,如需重开请联系财务部门。",
]
)
print(prompt)Prompt 优化策略
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 明确指令 | 具体、清晰的任务描述 | 所有场景 |
| Few-Shot | 提供 2-5 个示例 | 格式化输出 |
| CoT | 要求分步推理 | 复杂推理 |
| 角色扮演 | 设定专业角色 | 专业领域 |
| 分解任务 | 大任务拆分为小步骤 | 复杂任务 |
| 自我验证 | 让模型自查输出 | 代码/数学 |
| 迭代优化 | 多轮对话逐步改进 | 创意写作 |
| Self-Consistency | 多次采样取最一致答案 | 数学/逻辑 |
Prompt 版本管理
from dataclasses import dataclass, field
from typing import Optional
import json
@dataclass
class PromptVersion:
"""Prompt 版本管理——生产环境必备"""
name: str
version: str
template: str
description: str = ""
variables: list[str] = field(default_factory=list)
eval_score: Optional[float] = None
known_failures: list[str] = field(default_factory=list)
created_at: str = ""
def render(self, **kwargs) -> str:
"""填充模板变量"""
result = self.template
for key, value in kwargs.items():
result = result.replace(f"{{{key}}}", str(value))
return result
def to_dict(self) -> dict:
return {
"name": self.name,
"version": self.version,
"template": self.template,
"description": self.description,
"variables": self.variables,
"eval_score": self.eval_score,
"known_failures": self.known_failures,
}
# 使用示例
qa_prompt = PromptVersion(
name="faq_qa",
version="v2.1.0",
template="你是{role}。请基于以下资料回答问题:{context}\n\n问题:{question}",
variables=["role", "context", "question"],
description="FAQ 问答 Prompt,强调基于资料回答",
eval_score=0.87,
known_failures=["多跳问题容易回答不完整", "对比类问题效果差"],
)
rendered = qa_prompt.render(
role="企业客服助手",
context="退款规则:签收后7天内可退。",
question="退货流程是什么?"
)
print(f"渲染结果: {rendered[:100]}...")
print(f"版本信息: {qa_prompt.to_dict()['version']}, 评分: {qa_prompt.eval_score}")常见 Prompt 失败模式
failure_modes = {
"幻觉(Hallucination)": {
"表现": "模型编造不存在的事实或数据",
"原因": "模型概率性生成,没有事实校验机制",
"解决": "RAG 注入真实上下文 + 明确要求引用来源 + 输出校验"
},
"指令误解(Instruction Misunderstanding)": {
"表现": "模型没有按照预期的方式执行任务",
"原因": "指令不够明确或有歧义",
"解决": "更精确的任务描述 + Few-Shot 示例 + 结构化输出约束"
},
"格式漂移(Format Drift)": {
"表现": "输出格式不稳定,JSON 解析失败",
"原因": "模型版本变化或上下文干扰",
"解决": "更强的格式约束 + 输出后校验 + 重试机制"
},
"安全越界(Safety Bypass)": {
"表现": "模型执行了不应该执行的操作",
"原因": "用户输入绕过了安全约束",
"解决": "输入过滤 + 输出审核 + 工具权限控制"
},
"上下文污染(Context Pollution)": {
"表现": "模型被检索结果或用户输入误导",
"原因": "注入的上下文包含错误或误导信息",
"解决": "上下文质量检查 + 来源标记 + 交叉验证"
}
}
for mode, info in failure_modes.items():
print(f"\n{mode}:")
print(f" 表现: {info['表现']}")
print(f" 解决: {info['解决']}")优点
缺点
总结
Prompt 工程核心技巧:角色设定明确身份,Few-Shot 给出示例引导格式,CoT 分步推理提升准确率,结构化输出用 JSON/表格控制格式。通用模板:角色 → 背景 → 任务 → 约束 → 输出格式。优化策略:明确指令 > 示例引导 > 分步推理 > 自我验证。实际使用中,迭代优化 Prompt 比一次写完更高效。生产环境中,Prompt 版本管理、评估集和失败样例追踪比优化技巧更重要。
关键知识点
- 先分清模型能力边界、数据边界和工程边界。
- 任何 AI 主题都不只看效果,还要看延迟、成本、可解释性和安全性。
- 评估方式和失败样例往往比"换哪个模型"更重要。
- 这类主题通常同时涉及表示学习、上下文建模和推理成本。
- temperature、top_p 等生成参数对输出质量有显著影响。
- Few-Shot 的核心价值是对齐格式和边界,而非传授知识。
项目落地视角
- 给数据来源、Prompt 模板、Embedding 版本、评估集和实验结果做版本管理。
- 上线前准备兜底策略,例如拒答、回退、人工审核或缓存降级。
- 观察错误类型时,区分数据问题、召回问题、提示词问题和模型问题。
- 把提示词拆成角色、任务、约束、输出格式和失败兜底几部分。
常见误区
- 只关注 Demo 效果,不考虑线上稳定性和可复现性。
- 没有评估集就频繁调参,最后无法解释为什么变好或变差。
- 忽略权限、审计、隐私和模型输出的安全边界。
- 把所有问题都归因于提示词,而忽略数据和模型能力边界。
- 用越来越长的 Prompt 试图解决所有问题,导致成本和不稳定性上升。
进阶路线
- 继续补齐训练、推理、评估、MLOps 和治理链路。
- 把主题放回真实业务流程,思考谁提供数据、谁消费结果、谁负责兜底。
- 把 PoC 逐步升级到可观测、可回滚、可演进的生产方案。
- 继续深入长上下文、结构化输出、提示模板管理和模型评估。
适用场景
- 当你准备把《大语言模型与 Prompt 工程》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合企业知识问答、内容生成、分类抽取和智能助手等场景。
- 当需求同时关注效果、时延、成本和安全边界时,这类主题最有价值。
落地建议
- 先定义评估集、成功标准和失败样例,再开始调模型或调提示。
- 把数据来源、分块方式、Embedding 版本和 Prompt 模板纳入版本管理。
- 上线前准备兜底策略,例如拒答、回退、人工审核或检索降级。
排错清单
- 先判断问题出在数据、检索、Prompt、模型还是后处理。
- 检查上下文是否过长、分块是否过碎或召回是否偏题。
- 对错误回答做分类,区分幻觉、事实过时、指令误解和格式错误。
复盘问题
- 如果把《大语言模型与 Prompt 工程》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《大语言模型与 Prompt 工程》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《大语言模型与 Prompt 工程》最大的收益和代价分别是什么?
