2026 大厂 AI 编程经典面试题库(京东、字节、华为、阿里、腾讯、荣耀)

2 阅读17分钟

2026 大厂 AI 编程经典面试题库(京东、字节、华为、阿里、腾讯、荣耀)

汇总京东、字节跳动、华为、阿里巴巴、腾讯、荣耀等一线互联网公司 AI 编程面试真题,涵盖大模型应用、Agent 开发、Prompt 工程、RAG 等核心考点

整理时间: 2026 年 3 月
适用岗位: AI 工程师、大模型应用工程师、Agent 开发工程师
技术栈: Claude Code、OpenAI API、LangChain、RAG、Prompt Engineering


目录


一、大模型基础与原理

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 核心思想:

  1. Self-Attention:捕捉序列中任意两个位置之间的关系
  2. Multi-Head:从多个子空间学习不同的表示
  3. Position Encoding:注入位置信息
  4. Feed-Forward:非线性变换
  5. Residual Connection:缓解梯度消失
  6. 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

对比表格:

特性GPTBERTT5
架构Decoder-onlyEncoder-onlyEncoder-Decoder
注意力方向单向双向Encoder 双向,Decoder 单向
训练目标自回归 LMMLM + NSPText-to-Text
主要应用文本生成NLU 任务生成 + 理解
代表模型GPT-4, ClaudeBERT, RoBERTaFLAN-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 的核心思想:

  1. SFT:让模型学会遵循指令
  2. RM:训练一个模型来判断生成质量
  3. 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 设计要点:

  1. 示例数量:通常 3-5 个示例效果最好
  2. 示例质量:选择高质量、无歧义的示例
  3. 示例多样性:覆盖不同场景和类别
  4. 示例排序:从简单到复杂
  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 核心思想:

  1. 显式推理:让模型展示思考过程
  2. 分步解决:将复杂问题分解为多个步骤
  3. 可解释性:提高模型决策的透明度
  4. 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. 返回