2026 大厂 AI 编程经典面试题库(京东、字节、华为、阿里、腾讯、荣耀)
汇总京东、字节跳动、华为、阿里巴巴、腾讯、荣耀等一线互联网公司 AI 编程面试真题,涵盖大模型应用、Agent 开发、Prompt 工程、RAG 等核心考点
整理时间: 2026 年 3 月
适用岗位: AI 工程师、大模型应用工程师、Agent 开发工程师
技术栈: Claude Code、OpenAI API、LangChain、RAG、Prompt Engineering
目录
- 一、大模型基础与原理
- 二、Prompt Engineering
- 三、Agent 开发
- 四、RAG 检索增强生成
- 五、AI 编程实战
- 六、系统设计与架构
- 七、字节跳动特色题
- 八、华为荣耀特色题
- 九、阿里腾讯特色题
一、大模型基础与原理
1.1 Transformer 架构
Q1: 请详细解释 Transformer 的核心组件和工作原理
答案:
# Transformer 核心组件
# 1. Self-Attention(自注意力机制)
import torch
import torch.nn.functional as F
def scaled_dot_product_attention(query, key, value, mask=None):
"""
缩放点积注意力
query, key, value: [batch_size, seq_len, d_model]
"""
d_k = query.size(-1)
# 计算注意力分数
scores = torch.matmul(query, key.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k, dtype=torch.float32))
# 应用 mask(可选)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
# Softmax 归一化
attention_weights = F.softmax(scores, dim=-1)
# 加权求和
output = torch.matmul(attention_weights, value)
return output, attention_weights
# 2. Multi-Head Attention(多头注意力)
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
def forward(self, query, key, value, mask=None):
batch_size = query.size(0)
# 线性变换
Q = self.W_q(query) # [batch, seq_len, d_model]
K = self.W_k(key)
V = self.W_v(value)
# 分割多头
Q = Q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
K = K.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
V = V.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
# 自注意力
attn_output, _ = scaled_dot_product_attention(Q, K, V, mask)
# 合并多头
attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
# 输出线性层
output = self.W_o(attn_output)
return output
# 3. Position Encoding(位置编码)
class PositionalEncoding(nn.Module):
def __init__(self, d_model, max_len=5000):
super().__init__()
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
pe[:, 0::2] = torch.sin(position * div_term) # 偶数维度
pe[:, 1::2] = torch.cos(position * div_term) # 奇数维度
pe = pe.unsqueeze(0) # [1, max_len, d_model]
self.register_buffer('pe', pe)
def forward(self, x):
# x: [batch_size, seq_len, d_model]
return x + self.pe[:, :x.size(1)]
# 4. Feed-Forward Network
class FeedForward(nn.Module):
def __init__(self, d_model, d_ff, dropout=0.1):
super().__init__()
self.linear1 = nn.Linear(d_model, d_ff)
self.linear2 = nn.Linear(d_ff, d_model)
self.dropout = nn.Dropout(dropout)
self.activation = nn.ReLU()
def forward(self, x):
x = self.linear1(x)
x = self.activation(x)
x = self.dropout(x)
x = self.linear2(x)
return x
# 5. Layer Normalization
class LayerNormalization(nn.Module):
def __init__(self, d_model, eps=1e-6):
super().__init__()
self.gamma = nn.Parameter(torch.ones(d_model))
self.beta = nn.Parameter(torch.zeros(d_model))
self.eps = eps
def forward(self, x):
mean = x.mean(-1, keepdim=True)
std = x.std(-1, keepdim=True)
return self.gamma * (x - mean) / (std + self.eps) + self.beta
# 6. Transformer Block
class TransformerBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
super().__init__()
self.self_attn = MultiHeadAttention(d_model, num_heads)
self.ffn = FeedForward(d_model, d_ff, dropout)
self.norm1 = LayerNormalization(d_model)
self.norm2 = LayerNormalization(d_model)
self.dropout1 = nn.Dropout(dropout)
self.dropout2 = nn.Dropout(dropout)
def forward(self, x, mask=None):
# 多头注意力 + 残差连接 + Layer Norm
attn_output = self.self_attn(x, x, x, mask)
x = self.norm1(x + self.dropout1(attn_output))
# 前馈网络 + 残差连接 + Layer Norm
ffn_output = self.ffn(x)
x = self.norm2(x + self.dropout2(ffn_output))
return x
Transformer 核心思想:
- Self-Attention:捕捉序列中任意两个位置之间的关系
- Multi-Head:从多个子空间学习不同的表示
- Position Encoding:注入位置信息
- Feed-Forward:非线性变换
- Residual Connection:缓解梯度消失
- Layer Normalization:稳定训练
考点:
- 理解注意力机制的计算过程
- 多头注意力的作用
- 位置编码的必要性
- Residual Connection 和 Layer Norm 的作用
Q2: GPT、BERT、T5 的区别是什么?
答案:
# GPT (Generative Pre-trained Transformer)
# - 架构:Decoder-only
# - 训练目标:自回归语言建模(预测下一个 token)
# - 应用:文本生成、代码生成
# - 特点:单向注意力(只能看到左侧)
class GPTBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff):
super().__init__()
self.attn = MultiHeadAttention(d_model, num_heads)
self.ffn = FeedForward(d_model, d_ff)
self.norm1 = LayerNormalization(d_model)
self.norm2 = LayerNormalization(d_model)
def forward(self, x):
# Causal Mask(因果掩码):只能看到当前位置及之前
seq_len = x.size(1)
mask = torch.tril(torch.ones(seq_len, seq_len))
attn_output = self.attn(x, x, x, mask)
x = self.norm1(x + attn_output)
ffn_output = self.ffn(x)
x = self.norm2(x + ffn_output)
return x
# BERT (Bidirectional Encoder Representations from Transformers)
# - 架构:Encoder-only
# - 训练目标:Masked Language Model + Next Sentence Prediction
# - 应用:文本分类、命名实体识别、问答
# - 特点:双向注意力(可以看到整个序列)
class BERTBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff):
super().__init__()
self.attn = MultiHeadAttention(d_model, num_heads)
self.ffn = FeedForward(d_model, d_ff)
self.norm1 = LayerNormalization(d_model)
self.norm2 = LayerNormalization(d_model)
def forward(self, x, mask=None):
# 双向注意力,可以看到整个序列
attn_output = self.attn(x, x, x, mask)
x = self.norm1(x + attn_output)
ffn_output = self.ffn(x)
x = self.norm2(x + ffn_output)
return x
# T5 (Text-to-Text Transfer Transformer)
# - 架构:Encoder-Decoder
# - 训练目标:Text-to-Text(所有任务都转化为文本生成)
# - 应用:翻译、摘要、问答
# - 特点:Encoder 双向,Decoder 单向
class T5Block(nn.Module):
def __init__(self, d_model, num_heads, d_ff):
super().__init__()
self.encoder_attn = MultiHeadAttention(d_model, num_heads)
self.decoder_attn = MultiHeadAttention(d_model, num_heads)
self.ffn = FeedForward(d_model, d_ff)
self.norm1 = LayerNormalization(d_model)
self.norm2 = LayerNormalization(d_model)
self.norm3 = LayerNormalization(d_model)
def forward(self, x, encoder_output, decoder_mask, encoder_mask):
# Decoder Self-Attention(单向)
self_attn_output = self.decoder_attn(x, x, x, decoder_mask)
x = self.norm1(x + self_attn_output)
# Encoder-Decoder Attention(交叉注意力)
cross_attn_output = self.encoder_attn(x, encoder_output, encoder_output, encoder_mask)
x = self.norm2(x + cross_attn_output)
# Feed-Forward
ffn_output = self.ffn(x)
x = self.norm3(x + ffn_output)
return x
对比表格:
| 特性 | GPT | BERT | T5 |
|---|---|---|---|
| 架构 | Decoder-only | Encoder-only | Encoder-Decoder |
| 注意力方向 | 单向 | 双向 | Encoder 双向,Decoder 单向 |
| 训练目标 | 自回归 LM | MLM + NSP | Text-to-Text |
| 主要应用 | 文本生成 | NLU 任务 | 生成 + 理解 |
| 代表模型 | GPT-4, Claude | BERT, RoBERTa | FLAN-T5 |
| 推理方式 | 自回归 | 一次性推理 | 自回归 |
考点:
- GPT 适合生成任务(单向注意力)
- BERT 适合理解任务(双向注意力)
- T5 统一了生成和理解任务
- 选择模型时考虑任务类型
1.2 大模型训练与推理
Q3: 什么是 RLHF(Reinforcement Learning from Human Feedback)?
答案:
# RLHF 流程:3 个阶段
# 阶段 1: SFT(Supervised Fine-Tuning)监督微调
# 使用高质量的人类标注数据微调预训练模型
def supervised_finetuning(base_model, training_data):
"""
base_model: 预训练模型
training_data: (prompt, response) 对
"""
optimizer = torch.optim.AdamW(base_model.parameters(), lr=1e-5)
for prompt, target_response in training_data:
# 生成响应
generated = base_model.generate(prompt)
# 计算损失(交叉熵)
loss = cross_entropy_loss(generated, target_response)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
return base_model
# 阶段 2: RM(Reward Model)奖励模型训练
# 训练一个奖励模型来评估生成质量
class RewardModel(nn.Module):
def __init__(self, base_model):
super().__init__()
self.base_model = base_model
self.reward_head = nn.Linear(base_model.config.hidden_size, 1)
def forward(self, prompt, response):
# 编码 prompt + response
outputs = self.base_model(prompt + response)
hidden_state = outputs.last_hidden_state[:, -1, :] # [CLS] token
# 输出奖励分数
reward = self.reward_head(hidden_state)
return reward
def train_reward_model(reward_model, comparison_data):
"""
comparison_data: (prompt, response_a, response_b, preference)
preference: 1 表示 response_a 更好,-1 表示 response_b 更好
"""
optimizer = torch.optim.AdamW(reward_model.parameters(), lr=1e-5)
for prompt, response_a, response_b, preference in comparison_data:
# 计算两个响应的奖励
reward_a = reward_model(prompt, response_a)
reward_b = reward_model(prompt, response_b)
# Bradley-Terry 损失
if preference == 1:
loss = -torch.log(torch.sigmoid(reward_a - reward_b))
else:
loss = -torch.log(torch.sigmoid(reward_b - reward_a))
optimizer.zero_grad()
loss.backward()
optimizer.step()
return reward_model
# 阶段 3: PPO(Proximal Policy Optimization)强化学习
# 使用 PPO 算法优化策略模型
def ppo_training(policy_model, reward_model, prompts, kl_coef=0.1):
"""
policy_model: 要优化的策略模型
reward_model: 奖励模型
prompts: 提示词列表
"""
optimizer = torch.optim.AdamW(policy_model.parameters(), lr=1e-6)
for prompt in prompts:
# 1. 生成响应(当前策略)
response_new = policy_model.generate(prompt)
# 2. 生成响应(参考策略,用于计算 KL 散度)
with torch.no_grad():
response_ref = policy_model_ref.generate(prompt)
# 3. 计算奖励
reward = reward_model(prompt, response_new)
# 4. 计算 KL 散度(策略稳定性)
kl_divergence = compute_kl_divergence(
policy_model, policy_model_ref, prompt, response_new
)
# 5. PPO 目标函数
# objective = reward - kl_coef * kl_divergence
advantage = reward - baseline # 优势函数
# 计算概率比
log_prob_new = policy_model.log_prob(prompt, response_new)
log_prob_old = policy_model_ref.log_prob(prompt, response_new)
ratio = torch.exp(log_prob_new - log_prob_old)
# PPO Clip
clipped_ratio = torch.clamp(ratio, 1 - 0.2, 1 + 0.2)
policy_loss = -torch.min(ratio * advantage, clipped_ratio * advantage).mean()
# 总损失
total_loss = policy_loss - kl_coef * kl_divergence
# 反向传播
optimizer.zero_grad()
total_loss.backward()
optimizer.step()
return policy_model
# 完整 RLHF 流程
def rlhf_pipeline(base_model, sft_data, comparison_data, rlhf_prompts):
# 阶段 1: SFT
sft_model = supervised_finetuning(base_model, sft_data)
# 阶段 2: 训练奖励模型
reward_model = RewardModel(sft_model)
reward_model = train_reward_model(reward_model, comparison_data)
# 阶段 3: PPO
policy_model = copy.deepcopy(sft_model)
policy_model_ref = copy.deepcopy(sft_model)
final_model = ppo_training(policy_model, reward_model, rlhf_prompts)
return final_model
RLHF 的核心思想:
- SFT:让模型学会遵循指令
- RM:训练一个模型来判断生成质量
- PPO:用强化学习优化策略,使生成更符合人类偏好
考点:
- RLHF 的三个阶段及其作用
- 奖励模型的训练方法
- PPO 算法的核心思想
- KL 散度的作用(防止策略偏离太远)
Q4: 什么是 LoRA(Low-Rank Adaptation)?如何实现?
答案:
# LoRA: 低秩适应,用于高效微调大模型
import torch
import torch.nn as nn
class LoRALinear(nn.Module):
"""
LoRA 线性层
原始权重 W 冻结,添加低秩分解 A @ B
输出 = Wx + BAx = Wx + (BA)x
"""
def __init__(self, in_features, out_features, rank=8, alpha=16):
super().__init__()
self.in_features = in_features
self.out_features = out_features
self.rank = rank
self.alpha = alpha
# 原始权重(冻结)
self.weight = nn.Parameter(torch.randn(out_features, in_features))
self.weight.requires_grad = False
# LoRA 参数(可训练)
self.lora_A = nn.Parameter(torch.randn(rank, in_features))
self.lora_B = nn.Parameter(torch.randn(out_features, rank))
self.scaling = alpha / rank
def forward(self, x):
# 原始线性变换
result = F.linear(x, self.weight)
# LoRA 分支
lora_result = F.linear(F.linear(x, self.lora_A), self.lora_B)
return result + self.scaling * lora_result
# 应用 LoRA 到模型
def apply_lora_to_model(model, target_modules=["q_proj", "v_proj"], rank=8):
"""
target_modules: 要应用 LoRA 的模块名称
rank: LoRA 的秩
"""
for name, module in model.named_modules():
if any(target in name for target in target_modules):
if isinstance(module, nn.Linear):
in_features = module.in_features
out_features = module.out_features
# 替换为 LoRA 层
lora_linear = LoRALinear(in_features, out_features, rank)
lora_linear.weight.data = module.weight.data # 复制权重
# 替换模块
parent = model
for part in name.split('.')[:-1]:
parent = getattr(parent, part)
setattr(parent, name.split('.')[-1], lora_linear)
return model
# 训练时只训练 LoRA 参数
def train_with_lora(model, train_data):
# 冻结所有参数
for param in model.parameters():
param.requires_grad = False
# 只训练 LoRA 参数
for name, module in model.named_modules():
if isinstance(module, LoRALinear):
module.lora_A.requires_grad = True
module.lora_B.requires_grad = True
optimizer = torch.optim.AdamW(filter(lambda p: p.requires_grad, model.parameters()))
for batch in train_data:
loss = model(batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
return model
# 合并 LoRA 权重(用于部署)
def merge_lora_weights(model):
"""
将 LoRA 权重合并到原始权重
W_new = W + (alpha / rank) * B @ A
"""
for name, module in model.named_modules():
if isinstance(module, LoRALinear):
# 计算合并后的权重
lora_weight = module.scaling * (module.lora_B @ module.lora_A)
merged_weight = module.weight + lora_weight
# 更新权重
module.weight.data = merged_weight
return model
# LoRA 的优势
# 1. 参数量少:只训练低秩矩阵,参数量减少 1000x
# 2. 显存占用低:不需要存储完整梯度
# 3. 训练速度快:只更新少量参数
# 4. 可插拔:可以方便地切换不同的 LoRA adapter
# QLoRA (Quantized LoRA): 量化 + LoRA
# 进一步降低显存占用
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=bnb_config,
device_map="auto"
)
# 应用 QLoRA
model = apply_lora_to_model(model, rank=8)
LoRA 核心原理:
原始权重: W ∈ R^(d×d)
LoRA 分解: W' = W + ΔW = W + BA
其中: B ∈ R^(d×r), A ∈ R^(r×d), r << d
参数量对比:
- 原始: d²
- LoRA: 2dr
- 压缩比: d² / (2dr) = d / (2r)
当 d=4096, r=8 时:
- 原始: 16,777,216
- LoRA: 65,536
- 压缩比: 256x
考点:
- LoRA 的数学原理(低秩分解)
- 如何应用 LoRA 到现有模型
- LoRA 的优势(参数量、显存、速度)
- QLoRA 进一步优化
二、Prompt Engineering
2.1 Prompt 设计原则
Q5: 什么是 Few-shot Prompting?如何设计有效的 Few-shot Prompt?
答案:
# Few-shot Prompting: 通过示例引导模型
# 示例 1: 文本分类
prompt = """
任务:判断以下文本的情感倾向(正面/负面/中性)
示例 1:
输入:这个产品非常好用,强烈推荐!
输出:正面
示例 2:
输入:服务太差了,再也不会来了。
输出:负面
示例 3:
输入:今天天气不错,适合出去走走。
输出:中性
现在请判断:
输入:这个功能设计得很人性化,使用体验很好。
输出:
"""
# 示例 2: 代码生成
prompt = """
任务:根据描述生成 Python 代码
示例 1:
描述:计算斐波那契数列的前 n 项
代码:
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
def fibonacci_sequence(n):
return [fibonacci(i) for i in range(n)]
示例 2:
描述:实现快速排序算法
代码:
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
现在请生成:
描述:实现二分查找算法
代码:
"""
# 示例 3: Chain-of-Thought(思维链)
prompt = """
任务:解决数学问题
示例 1:
问题:小明有 5 个苹果,吃了 2 个,又买了 3 个,现在有几个苹果?
思考:
1. 初始有 5 个苹果
2. 吃了 2 个,剩下 5 - 2 = 3 个
3. 又买了 3 个,现在有 3 + 3 = 6 个
答案:6 个
示例 2:
问题:一个长方形的长是 10cm,宽是 5cm,面积是多少?
思考:
1. 长方形面积公式:面积 = 长 × 宽
2. 面积 = 10cm × 5cm = 50cm²
答案:50cm²
现在请解决:
问题:一个班级有 30 名学生,其中男生占 40%,有多少名女生?
思考:
答案:
"""
# Few-shot Prompt 设计原则
def design_few_shot_prompt(task_description, examples, test_input):
"""
设计有效的 Few-shot Prompt
参数:
- task_description: 任务描述
- examples: 示例列表,每个示例包含 input 和 output
- test_input: 测试输入
"""
prompt = f"任务:{task_description}\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"
prompt += f"输入:{test_input}\n"
prompt += f"输出:"
return prompt
# 示例:情感分析
examples = [
{
"input": "这个产品太棒了,非常喜欢!",
"output": "正面"
},
{
"input": "质量很差,不建议购买。",
"output": "负面"
},
{
"input": "还可以,没有特别的感受。",
"output": "中性"
}
]
test_input = "这次购物体验很愉快,物流很快。"
prompt = design_few_shot_prompt("判断文本情感", examples, test_input)
# Few-shot Prompt 优化技巧
# 1. 示例选择:选择多样性和代表性
def select_diverse_examples(all_examples, num_examples=3):
"""
选择多样化的示例
"""
# 简单策略:随机选择
selected = random.sample(all_examples, num_examples)
# 更好的策略:确保覆盖所有类别
# selected = []
# for category in categories:
# selected.append(random.choice(examples_by_category[category]))
return selected
# 2. 示例排序:从简单到复杂
def sort_examples_by_difficulty(examples):
"""
按难度排序示例
"""
# 简单示例:长度短、结构简单
# 复杂示例:长度长、结构复杂
return sorted(examples, key=lambda x: len(x['input']))
# 3. 示例格式:保持一致性
def format_example(example, template):
"""
统一示例格式
"""
return template.format(**example)
template = "输入:{input}\n输出:{output}\n"
# 4. 动态示例:根据任务动态选择
def dynamic_few_shot(task, query, example_pool, k=3):
"""
动态选择最相关的 k 个示例
"""
# 计算查询与示例的相似度
similarities = []
for example in example_pool:
sim = compute_similarity(query, example['input'])
similarities.append((sim, example))
# 选择最相似的 k 个示例
similarities.sort(reverse=True)
selected = [example for _, example in similarities[:k]]
return selected
# 完整的 Few-shot Prompt 生成函数
def generate_few_shot_prompt(task, examples, test_input, format="standard"):
if format == "standard":
return standard_few_shot_prompt(task, examples, test_input)
elif format == "cot":
return cot_few_shot_prompt(task, examples, test_input)
elif format == "dynamic":
return dynamic_few_shot_prompt(task, test_input, examples)
Few-shot Prompt 设计要点:
- 示例数量:通常 3-5 个示例效果最好
- 示例质量:选择高质量、无歧义的示例
- 示例多样性:覆盖不同场景和类别
- 示例排序:从简单到复杂
- 格式一致性:示例和测试输入格式一致
考点:
- Few-shot Prompt 的作用
- 如何选择和排序示例
- Chain-of-Thought 的应用
- 动态示例选择
Q6: 什么是 Chain-of-Thought(CoT)Prompting?
答案:
# Chain-of-Thought: 引导模型展示推理过程
# 标准 Prompt vs CoT Prompt
# 标准 Prompt(直接给出答案)
standard_prompt = """
问题:小明有 5 个苹果,吃了 2 个,又买了 3 个,现在有几个苹果?
答案:
"""
# CoT Prompt(展示推理过程)
cot_prompt = """
问题:小明有 5 个苹果,吃了 2 个,又买了 3 个,现在有几个苹果?
让我们一步步思考:
1. 初始有 5 个苹果
2. 吃了 2 个,剩下 5 - 2 = 3 个
3. 又买了 3 个,现在有 3 + 3 = 6 个
答案:6 个
"""
# Zero-shot CoT(零样本思维链)
zero_shot_cot_prompt = """
问题:小明有 5 个苹果,吃了 2 个,又买了 3 个,现在有几个苹果?
让我们一步步思考:
"""
# Few-shot CoT(少样本思维链)
few_shot_cot_prompt = """
问题:小红有 10 颗糖,给了弟弟 3 颗,妈妈又给了她 5 颗,现在有几颗糖?
让我们一步步思考:
1. 初始有 10 颗糖
2. 给了弟弟 3 颗,剩下 10 - 3 = 7 颗
3. 妈妈给了 5 颗,现在有 7 + 5 = 12 颗
答案:12 颗
问题:一个班级有 30 名学生,男生占 40%,有多少名女生?
让我们一步步思考:
1. 男生人数 = 30 × 40% = 12 人
2. 女生人数 = 30 - 12 = 18 人
答案:18 人
问题:一个长方形的长是 10cm,宽是 5cm,面积是多少?
让我们一步步思考:
1. 长方形面积公式:面积 = 长 × 宽
2. 面积 = 10cm × 5cm = 50cm²
答案:50cm²
问题:小明有 5 个苹果,吃了 2 个,又买了 3 个,现在有几个苹果?
让我们一步步思考:
"""
# CoT 的变体
# 1. Auto-CoT(自动思维链)
def auto_cot_prompt(question):
"""
自动生成 CoT Prompt
"""
prompt = f"""
问题:{question}
让我们一步步思考:
"""
return prompt
# 2. Self-Consistency(自洽性)
def self_consistency(model, question, num_samples=5):
"""
通过多次采样选择最一致的答案
"""
answers = []
reasoning_paths = []
for _ in range(num_samples):
# 生成推理路径和答案
response = model.generate(f"{question} 让我们一步步思考:")
# 提取推理路径和答案
reasoning, answer = parse_response(response)
reasoning_paths.append(reasoning)
answers.append(answer)
# 选择出现次数最多的答案
from collections import Counter
most_common_answer = Counter(answers).most_common(1)[0][0]
return most_common_answer, reasoning_paths
# 3. Tree-of-Thoughts(思维树)
def tree_of_thoughts(model, question, max_depth=3, branching_factor=3):
"""
探索多个推理路径
"""
from collections import deque
# BFS 搜索
queue = deque([(question, [])]) # (当前问题, 推理路径)
while queue:
current_question, path = queue.popleft()
if len(path) >= max_depth:
# 达到最大深度,生成答案
answer = model.generate(f"{current_question} 答案:")
return answer, path
# 生成分支
for _ in range(branching_factor):
next_step = model.generate(f"{current_question} 下一步思考:")
new_path = path + [next_step]
queue.append((next_step, new_path))
# 4. Program-of-Thoughts(程序思维)
def program_of_thoughts(question):
"""
将推理过程转化为程序
"""
prompt = f"""
问题:{question}
请编写一个 Python 程序来解决这个问题:
def solve():
# 你的代码
pass
print(solve())
"""
return prompt
# CoT 在不同任务中的应用
# 1. 数学问题
math_cot = """
问题:一个水池有两个进水口和一个出水口。进水口 A 每分钟进水 5 升,进水口 B 每分钟进水 3 升,出水口每分钟出水 4 升。如果三个口同时打开,多长时间可以注满 100 升的水池?
让我们一步步思考:
1. 计算每分钟净进水量:5 + 3 - 4 = 4 升/分钟
2. 计算注满时间:100 ÷ 4 = 25 分钟
答案:25 分钟
"""
# 2. 逻辑推理
logic_cot = """
问题:如果所有的猫都是动物,而且所有的动物都需要食物,那么所有的猫都需要食物吗?
让我们一步步思考:
1. 前提 1:所有的猫都是动物
2. 前提 2:所有的动物都需要食物
3. 推论:因为猫是动物,而动物需要食物,所以猫需要食物
答案:是
"""
# 3. 代码生成
code_cot = """
问题:编写一个函数,判断一个数是否为素数
让我们一步步思考:
1. 素数的定义:只能被 1 和自身整除的数
2. 判断方法:检查 2 到 n-1 是否有能整除 n 的数
3. 优化:只需要检查到 sqrt(n)
4. 边界情况:0、1 不是素数,2 是素数
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(n**0.5) + 1, 2):
if n % i == 0:
return False
return True
"""
# CoT 的优势
# 1. 提高复杂任务的准确性
# 2. 提供可解释的推理过程
# 3. 减少幻觉(hallucination)
# 4. 适用于需要多步推理的任务
# CoT 的局限性
# 1. 增加推理时间和计算成本
# 2. 不是所有任务都需要 CoT
# 3. 可能产生错误的推理路径
CoT 核心思想:
- 显式推理:让模型展示思考过程
- 分步解决:将复杂问题分解为多个步骤
- 可解释性:提高模型决策的透明度
- Self-Consistency:通过多次采样提高准确性
考点:
- CoT 的作用和原理
- Zero-shot vs Few-shot CoT
- Self-Consistency 的应用
- CoT 的适用场景
2.2 Prompt 优化技巧
Q7: 如何优化 Prompt 以提高模型性能?
答案:
# Prompt 优化技巧
# 1. 清晰的任务描述
# ❌ 差的 Prompt
bad_prompt = "写个代码"
# ✅ 好的 Prompt
good_prompt = """
任务:编写一个 Python 函数,实现快速排序算法
要求:
1. 函数名为 quicksort
2. 参数为一个列表
3. 返回