LLM 基础原理:理解你的 AI 搭档 🧠
"不理解工具的工作原理,就无法发挥它的全部潜力。"
1. Transformer 架构核心
1.1 Attention 机制:LLM 的"思考"方式
Transformer 的核心是 Self-Attention,它允许模型在处理每个 token 时"关注"输入序列中的所有其他 token。
输入: "The cat sat on the mat because it was tired"
↓
"it" 指的是什么?
Attention 权重:
"it" → "cat": 0.72 ← 最高权重,模型理解 it 指 cat
"it" → "mat": 0.15
"it" → "sat": 0.08
...工程启示:
- 模型能理解长距离依赖,但 Attention 计算是 O(n²),这解释了上下文窗口限制
- 相关信息放得越近,模型理解得越准确
1.2 上下文窗口 (Context Window)
| 模型 | 上下文窗口 | 约等于 |
|---|---|---|
| GPT-4o | 128K tokens | ~100 页文档 |
| Claude 3.5 Sonnet | 200K tokens | ~150 页文档 |
| Gemini 1.5 Pro | 1M tokens | ~700 页文档 |
关键概念:
┌─────────────────────────────────────────────────────────────┐
│ Context Window (128K) │
├──────────────┬──────────────────────────┬───────────────────┤
│ System Prompt│ User Messages & │ Model Output │
│ (固定) │ Assistant History │ (生成中) │
│ │ (动态增长) │ │
└──────────────┴──────────────────────────┴───────────────────┘
↑ ↑ ↑
通常 1-5K 可能占满 模型在此续写"Lost in the Middle" 问题: 研究表明,模型对上下文开头和结尾的信息记忆最好,中间部分容易被"遗忘"。
python
# 最佳实践:重要信息放在开头或结尾
system_prompt = """
[CRITICAL RULES - READ FIRST] # ← 开头
...important rules...
[CONTEXT]
...background info...
[REMINDER] # ← 结尾
Always follow the CRITICAL RULES above.
"""2. Tokenization:模型如何"看"文本
2.1 什么是 Token
LLM 不直接处理字符,而是处理 Token——介于字符和单词之间的文本单元。
输入文本: "Hello, world! 你好世界"
GPT-4 Tokenization:
["Hello", ",", " world", "!", " 你", "好", "世", "界"]
1 2 3 4 5 6 7 8 = 8 tokens
注意:
- 英文单词通常是 1 token
- 中文每个字通常是 1-2 tokens
- 标点符号通常独立成 token
- 空格可能附着在后面的单词上2.2 Token 计费与优化
javascript
// 粗略估算 (实际使用 tiktoken 库)
function estimateTokens(text) {
// 英文: ~4 字符 = 1 token
// 中文: ~1.5 字符 = 1 token
const englishChars = text.replace(/[\u4e00-\u9fa5]/g, '').length;
const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
return Math.ceil(englishChars / 4 + chineseChars * 1.5);
}成本优化技巧:
| 技巧 | 描述 | 节省比例 |
|---|---|---|
| Prompt Caching | 缓存 System Prompt,只付一次钱 | 可达 90% |
| 压缩上下文 | 摘要历史对话而非完整保留 | 30-50% |
| 选择合适模型 | 简单任务用小模型 | 10-100x |
3. 生成过程:概率采样
3.1 Next Token Prediction
LLM 的核心任务是:给定上下文,预测下一个 token 的概率分布。
输入: "The capital of France is"
模型输出概率分布:
"Paris" : 0.92 ← 采样这个
"the" : 0.03
"Lyon" : 0.02
"a" : 0.01
...3.2 采样参数详解
Temperature (温度)
控制概率分布的"锐利程度"。
原始概率: Paris(0.6), Lyon(0.2), Marseille(0.1), Bordeaux(0.1)
Temperature = 0.0 (Greedy):
→ 始终选择 Paris (概率最高)
→ 确定性输出,适合代码生成
Temperature = 1.0 (原始分布):
→ 按原始概率采样
→ 平衡创造性和准确性
Temperature = 2.0 (更平坦):
→ 概率变得更均匀: Paris(0.35), Lyon(0.25), Marseille(0.2), Bordeaux(0.2)
→ 更多随机性,可能产生意外输出前端场景推荐设置:
| 场景 | Temperature | 理由 |
|---|---|---|
| 代码生成/重构 | 0.0 - 0.2 | 需要精确,避免 API 幻觉 |
| Bug 修复 | 0.0 | 要么对要么错,不需要创意 |
| 文案生成 | 0.7 - 0.9 | 需要多样性和创意 |
| 头脑风暴 | 1.0+ | 需要发散思维 |
Top-P (Nucleus Sampling)
只从累积概率达到 P 的 token 中采样。
概率排序: Paris(0.6) > Lyon(0.2) > Marseille(0.1) > Bordeaux(0.1)
Top-P = 0.8:
累积: Paris(0.6) + Lyon(0.2) = 0.8 ✓
→ 只在 [Paris, Lyon] 中采样
→ 排除低概率的长尾选项Top-K
只从概率最高的 K 个 token 中采样。
Top-K = 2:
→ 只在 [Paris, Lyon] 中采样 (概率最高的 2 个)组合使用:
javascript
// OpenAI API 调用示例
const response = await openai.chat.completions.create({
model: "gpt-4",
messages: [...],
temperature: 0.2, // 低温度保证稳定
top_p: 0.1, // 只考虑最可能的 token
// 通常不需要同时设置 top_k
});4. 模型能力边界
4.1 LLM 擅长什么
✅ 模式匹配与生成
- 代码补全、翻译、摘要
- 遵循格式和模板
✅ 知识检索 (训练数据内)
- 解释概念、回答常见问题
- 但可能不是最新信息
✅ 推理 (有限)
- 简单逻辑推理
- Chain-of-Thought 可增强复杂推理
4.2 LLM 不擅长什么
❌ 精确计算
// LLM 可能出错的场景
"计算 7823 * 4521" // 可能给出近似值,不保证精确
// 解决方案:让 LLM 生成代码,然后执行
"写一个 Python 表达式计算 7823 * 4521,然后执行它"❌ 实时信息
// LLM 不知道今天的信息
"今天的股价是多少?" // 无法回答
// 解决方案:提供工具让 LLM 查询 API❌ 持久记忆
// 每次对话是独立的
对话 1: "记住我喜欢 TypeScript"
对话 2: "我喜欢什么语言?" // LLM 不记得
// 解决方案:外部记忆存储 + RAG❌ 多步精确执行
// 长任务容易出错
"重构这 20 个文件,每个文件做这 5 件事"
// 解决方案:拆分为多次调用,每次做一件事4.3 幻觉 (Hallucination)
模型可能自信地输出错误信息,尤其是:
- 不存在的 API:
React.useAsyncState()(虚构的) - 错误的版本信息: "React 18 移除了 useEffect" (错误)
- 虚假的引用: "根据 MDN 文档..." (可能是编造的)
减少幻觉的策略:
- 提供上下文: 给出真实的 API 文档
- 要求引用: "只使用我提供的文档中的 API"
- 验证输出: 通过工具执行代码检查语法
- 降低温度: Temperature = 0 减少随机性
5. Prompt 如何影响模型行为
5.1 In-Context Learning
模型能从 Prompt 中的示例"即时学习"模式,而无需微调。
markdown
# Few-shot 示例
将以下英文 API 响应转换为中文用户友好的消息:
Input: {"error": "RATE_LIMITED", "retryAfter": 60}
Output: 您的操作太频繁了,请 60 秒后再试。
Input: {"error": "INVALID_TOKEN", "field": "email"}
Output: 邮箱格式不正确,请检查后重新输入。
Input: {"error": "QUOTA_EXCEEDED", "limit": 100}
Output: [模型会学习模式并生成类似格式的输出]5.2 角色设定的本质
角色设定不是"让模型变成另一个人",而是激活特定的知识和行为模式。
markdown
# 有效的角色设定
你是一名有 10 年经验的 React 性能优化专家。你熟悉:
- React DevTools Profiler 的使用
- useMemo/useCallback 的正确使用场景
- 虚拟列表和懒加载的实现
- 服务端渲染优化
# 为什么有效?
- 激活了训练数据中关于 React 性能的知识区域
- 建立了"专家"的行为预期(谨慎、有依据)
- 锁定了技术术语的语境5.3 System Prompt vs User Prompt
| 特性 | System Prompt | User Prompt |
|---|---|---|
| 位置 | 对话开头,固定不变 | 每次用户输入 |
| 用途 | 定义角色、规则、格式 | 具体任务和问题 |
| 优先级 | 通常更高 | 可能覆盖 System |
| 缓存 | 可以被缓存,节省成本 | 每次不同 |
javascript
const response = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
system: `你是一名前端架构师。
规则:
1. 只使用 TypeScript
2. 优先使用函数组件
3. 不使用 class 组件`, // System Prompt - 持久规则
messages: [
{ role: "user", content: "实现一个 Modal 组件" } // User Prompt - 具体任务
]
});6. 实战:诊断 Prompt 问题
6.1 常见问题诊断
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 输出格式不稳定 | 格式要求不够明确 | 提供 JSON Schema 或示例 |
| 忽略某些规则 | 规则太多或矛盾 | 精简规则,检查冲突 |
| 输出与预期差异大 | 上下文不足 | 提供更多背景信息 |
| API 名称错误 | 幻觉 | 提供真实 API 文档 |
| 回答太啰嗦 | 未限制长度 | 明确要求简洁 |
6.2 调试工作流
1. 明确预期输出
↓
2. 检查 Prompt 是否包含足够信息
↓
3. 降低 Temperature 测试确定性输出
↓
4. 添加更多约束或示例
↓
5. 检查是否有规则冲突
↓
6. 尝试拆分复杂任务7. 关键要点总结
- LLM 是概率模型: 不是数据库,输出基于"最可能的下一个 token"
- 上下文窗口有限: 重要信息放开头或结尾
- Temperature 控制随机性: 代码任务用低值,创意任务用高值
- 了解能力边界: 计算、实时信息、持久记忆需要外部工具
- 减少幻觉: 提供真实上下文,要求引用来源,验证输出
延伸阅读
- Attention Is All You Need - Transformer 原始论文
- The Illustrated Transformer - 可视化讲解
- Tokenizer Playground - OpenAI Token 可视化工具