大模型上下文原理解析
想知道为什么同一个问题,给不给 AI 项目信息,它给出的答案能差这么多?这章讲上下文。
从一个例子开始
让 AI 写函数
没有上下文:
你:写一个函数,验证用户邮箱格式是否正确
AI 返回:
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}能用,但有几个问题:
- 你项目用 TypeScript,它给了 JavaScript
- 你们用 zod 做验证,它写了个正则
- 错误要抛 ValidationError,它直接 return false
- 没注释,没类型,跟你现有代码风格不搭
有上下文:
你:写一个函数,验证用户邮箱格式是否正确
项目信息:
- 使用 TypeScript
- 使用 zod 库做验证
- 错误要抛出自定义的 ValidationError
- 参考 src/utils/validators.ts 中的其他函数
AI 返回:
import { z } from 'zod';
import { ValidationError } from '@/errors/ValidationError';
export const emailSchema = z.string().email({
message: '邮箱格式不正确'
});
export function validateEmail(email: string): string {
const result = emailSchema.safeParse(email);
if (!result.success) {
throw new ValidationError(result.error.errors[0].message);
}
return result.data;
}这次就对了:
- TypeScript + zod,符合技术栈
- 抛 ValidationError,符合错误处理规范
- 有导出、有类型、有注释,跟现有代码一个风格
一个道理
上下文就是给 AI 的背景信息。就像招个新员工,他不了解公司情况就只能按通用来做;你告诉他技术栈、规范、业务规则,他就能按团队要求来。
AI 一样——它懂 React、Vue、Python,但不知道你项目怎么组织的。上下文填补这个缺口。
上下文窗口是什么?
大模型一次对话能"记住"的最大 Token 数量,就是上下文窗口。
怎么理解
┌────────────────────────────────────────────────────┐
│ 大模型 │
│ │
│ 上下文窗口 = 200,000 tokens │
│ │
│ 里面装了: │
│ - 系统提示词 │
│ - 用户输入 │
│ - AI 之前的回复 │
│ - 工具调用结果 │
│ - 文档内容 │
└────────────────────────────────────────────────────┘把这当作 AI 的"工作记忆"就行。人脑工作记忆也有限,同时记几十条不相关信息容易乱。AI 也一样,需要个有限空间放当前任务要用的东西。
Token 是啥
Token是大模型处理文本的基本单位,可以理解为"词"或"字"。
不同语言的差异
英文:
- 大约 1 token = 4 个字符,或 0.75 个单词
- 单词边界清楚,tokenization 效率高
- "the"、"and"、"is" 这些通常是单个 token
中文:
- 大约 1 token = 1.5-2 个汉字
- 没明确单词边界,tokenization 效率低一些
- 中文字符集大(BPE 算法难找高频组合)
看个例子:
文本:Hello, world!
Tokens:Hello, | world | ! (约 3 tokens)
文本:你好,世界!
Tokens:你 | 好 | , | 世 | 界 | ! (约 6 tokens)中文为啥更贵
根据 2025 年的一些技术分析:
- 字符集差异: 英文基本字符 < 100 个,中文常用就 3000+
- 语言特性: 英文有清晰单词边界和词根词缀,中文靠单字组合
- BPE 算法: 字符集越大,越难找到高频字符组合来合并 token
有意思的是,微软 2025 年的研究发现,中文虽然 token 多,但信息密度更高——用中文推理有时能减少 token 消耗还能保持准确。DeepSeek 等模型推理时会"切换"到中文思考,就是这个原因。
各模型的上下文窗口
| 模型 | 上下文窗口 | 发布时间 | 备注 |
|---|---|---|---|
| GPT-3.5 | 16K | 2022 | 早期版本 |
| GPT-4 | 8K-32K | 2023 | 看版本 |
| GPT-4 Turbo | 128K | 2023 | 提升挺大 |
| GPT-4o | 128K | 2024 | 主力版本 |
| GPT-5 | 200K | 2025 | 最新 |
| Claude 3 Sonnet | 200K | 2024 | 性能和成本平衡 |
| Claude 3.5 Sonnet | 200K | 2024 | 开发者用得多 |
| Claude Opus 4.6 | 1M(beta) | 2026 | 目前最大 |
数据来源: Anthropic 官方文档(2026)、OpenAI 官方公告(2025)
趋势
上下文窗口从 2023 年的 4K 到 2026 年的 1M tokens,涨了 250 倍。几个原因:
- 技术突破: 线性 attention、稀疏 attention 降低了计算复杂度
- 应用需求: AI Agent、代码分析、长文档处理需要更大上下文
- 竞争: 厂商把上下文窗口当卖点
但要注意,更大的上下文不等于更好的效果。研究表明,上下文增长后准确性和召回率会下降,这叫"context rot"。
上下文在 AI 生成中的作用
AI 生成过程
┌──────────────┐
│ 用户输入 │
└──────┬───────┘
│
▼
┌─────────────────────────────────────┐
│ 大模型处理 │
│ │
│ 1. 读取上下文(包括对话历史) │
│ 2. 理解当前请求 │
│ 3. 从训练数据中检索相关知识 │
│ 4. 结合上下文生成回复 │
└─────────────────────────────────────┘
│
▼
┌──────────────┐
│ AI 输出 │
└──────────────┘AI 不是"凭空创造",而是在"上下文 + 知识库"基础上生成。
- 上下文: 当前任务的具体信息
- 知识库: 通用的知识和技能
缺一不可。
上下文的三个作用
1. 提供项目特定信息
AI 通用知识库有:
- React、Vue、Angular 怎么用
- Python、JavaScript、Go 语法
- 数据库、API 设计模式
但不知道:
- 你项目用什么技术栈
- 代码目录怎么组织
- 团队编码规范
- 业务特殊规则
上下文补上这些。
实际案例
问 AI:"如何实现用户登录功能?"
没上下文: AI 给通用回答,可能包含:
- JWT token 认证
- Session 认证
- OAuth 第三方登录
- 多种数据库方案
有上下文(项目用 Next.js + Prisma + PostgreSQL): AI 给针对性建议:
// 使用 NextAuth.js(跟 Next.js 深度集成)
// 使用 Prisma Adapter(跟现有数据库集成)
// 配置 PostgreSQL 作为 session 存储2. 维持对话一致性
没上下文窗口:
第 1 轮:
你:帮我写一个 User 类
AI:写了 User 类
第 2 轮(新对话):
你:给 User 类添加一个 email 字段
AI:啥 User 类?再说详细点有上下文窗口:
第 1 轮:
你:帮我写一个 User 类
AI:写了 User 类
第 2 轮(同一对话):
你:给 User 类添加一个 email 字段
AI:好的,这是加了 email 字段的 User 类...上下文让 AI "记住"之前的内容。
但这"记忆"有限——上下文窗口满了,最早的内容会被"挤出去",就像 FIFO 队列。
3. 引导 AI 的输出风格
上下文:代码规范文档
- 使用 TypeScript
- 函数名用 camelCase
- 类名用 PascalCase
- 必须有 JSDoc 注释
- 错误要抛出自定义异常
AI 输出会自动遵循这些规范实际对比
无风格约束:
// AI 生成的代码
function validate(u) {
if(!u.email) return false;
return true;
}有风格约束:
/**
* Validates user data
* @param userData - The user object to validate
* @returns True if valid, false otherwise
* @throws {ValidationError} When validation fails
*/
export function validateUserData(userData: UserData): boolean {
if (!userData.email) {
throw new ValidationError('Email is required');
}
return true;
}差异很明显——风格约束让代码更专业、更好维护。
上下文衰减与遗忘问题
问题:上下文不是无限记忆
上下文窗口虽然大(200K tokens),AI 对上下文的"理解"不均匀:
上下文窗口中的位置:
┌────────────────────────────────────────┐
│ 最早的内容 │ 中间的内容 │ 最新内容 │
│ ⚠️ │ ⚠️ │ ✅ │
│ 可能被遗忘 │ 可能被弱化 │ 记忆清晰 │
└────────────────────────────────────────┘
最新内容(接近当前请求) → AI 记忆最清晰
中间内容 → AI 可能"忽略"
最早内容 → AI 可能"忘记"技术上叫**"注意力衰减"(Attention Decay)**。
原因
技术层面
注意力机制:
- AI 生成每个 token 时,对上下文不同部分分配不同"注意力权重"
- 最新内容通常获得更高权重
- 类似人类"近因效应"——更容易记住最近发生的事
位置编码:
- Transformer 用位置编码理解 token 顺序
- 早期内容的位置编码在深层网络中可能被"稀释"
- 模型对早期位置"敏感度"下降
计算效率:
- 为保证生成速度,模型可能不会同等处理所有上下文
- 某些优化算法会"选择性忽略"部分内容
研究怎么说
2025 年 arXiv 论文《Efficient Attention Mechanisms for Large Language Models: A Survey》指出,标准 self-attention 的二次时间复杂度是长上下文建模的主要障碍。线性 attention 和稀疏 attention 等新技术有改善,但注意力不均匀问题还在。
实际影响
场景:长对话
对话开始(第 1-10 轮):
- 讨论了项目用 React + TypeScript
- 约定了用 Redux 做状态管理
- 确定了组件命名规范
... 50 轮对话后 ...
你:写一个新的组件
AI:(可能忘了之前的约定)
写了个不符合规范的组件这就像会上做了决定,几周忙碌后大家都忘了当初怎么约定的——除非有会议纪要(持久化文档)。
场景:代码审查
第 1 轮:约定代码风格(用 PascalCase 命名组件)
... 20 轮其他讨论 ...
第 21 轮:要求写新组件
AI:可能用了 camelCase,忘了最初的约定解决办法
办法 1:关键信息重复提及
每 10-20 轮对话后:
你:提醒一下,项目用的是 React + TypeScript,
用 Redux 状态管理,组件命名用 PascalCase优点: 简单直接,立竿见影 缺点: 手动维护成本高,容易漏
办法 2:用持久化文档(推荐)
把关键信息写文档里:
- 创建 project-context.md
- 每次对话引用:"参考 project-context.md"
- AI 会重新读最新内容优点:
- 集中管理,好维护
- 代码变更时同步更新文档
- 适合团队协作
缺点:
- 需要额外文档维护工作
办法 3:用 Projects 功能(比如 Claude Projects)
- 创建项目空间
- 上传关键文档
- AI 自动参考这些文档
- 不受对话长度影响优点:
- 最方便,自动管理
- 支持多个文档
- 适合长期项目
缺点:
- 依赖特定平台功能
Lost in the Middle:为什么中间内容会被忽略
现象
"Lost in the Middle"(中间迷失)是 2023 年 Stanford 等研究机构首次系统描述的现象:LLM 在处理长上下文时,对开头和结尾内容的关注度远高于中间部分。这个现象在 2025-2026 年的新模型中依然存在,只是程度有所改善。
上下文位置与 AI 关注度的关系:
关注度
↑
│ ████
│ ████ ████
│ ████ ████ ████
│ ████ ████ ████
│ ████ ████ ████ ████
│ ████ ████ ████ ████ ████
└──────────────────────────────→ 位置
开头 ↑ 中间 ↑ 结尾
首因效应 近因效应2024-2025 年研究进展
多篇论文系统研究了这个问题:
| 研究 | 年份 | 核心发现 |
|---|---|---|
| Stanford "Lost in the Middle" (2307.03172) | 2023 | 首次系统描述,模型对中间信息的召回率显著下降 |
| GM-Extract & Mitigations (2511.13900) | 2025 | 提出分段提取+关键信息定位的方法,将中间召回率提升 20-30% |
| Emergent Property (2510.10276) | 2025 | 论证中间迷失是信息检索压力的涌现属性,不是单纯的注意力缺陷 |
| Context Utilization via Attention Probing (2505.23277) | 2025 | 提出 Sentinel 方法,通过注意力探测判断哪些上下文被实际使用 |
| Neptune Analytics Memory | 2026 | 企业级方案,通过图结构解决长上下文中的关联检索 |
2026 年的真实情况
2026 年的一项实际测试(1M token 上下文窗口)结果如下:
| 信息位置 | 召回率(Claude 4) | 召回率(GPT-4o) | 召回率(Gemini 3) |
|---|---|---|---|
| 开头 10% | 92% | 88% | 95% |
| 中间 10% | 68% | 52% | 78% |
| 结尾 10% | 89% | 85% | 93% |
即使是 2026 年最好的模型,中间内容的召回率也明显低于两端。Gemini 3 表现最好(中间 78%),但仍然比两端低 15-17 个百分点。
缓解策略
策略 1:关键信息放两端
❌ 错误:
系统提示 → 技术栈文档 → API 文档 → 业务规则 → 关键约束条件
↑ 关键信息放最后
✅ 正确:
关键约束条件 → 系统提示 → 技术栈文档 → API 文档 → 业务规则
↑ 关键信息放开头 ↑ 最新指令可放结尾策略 2:分段提取(GM-Extract 方法)
arXiv 2511.13900 提出的方法:不依赖模型一次性处理整个上下文,而是分段提取关键信息后再整合。
# GM-Extract 简化思路
def gm_extract(long_text, queries):
# 1. 把长文本分成 N 段
segments = split_into_chunks(long_text, n=5)
# 2. 每段独立提取
results = []
for seg, query in zip(segments, queries):
result = llm.extract(seg, query)
results.append(result)
# 3. 合并提取结果
final = llm.synthesize(results)
return final策略 3:关键信息重复提及
重要的约束条件在对话中定期重申:
对话开始时:约定技术栈(React + TypeScript)
每 10-20 轮提醒:重申核心约定
任务开始时:再次确认策略 4:用结构化格式减少"迷失"
❌ 大段文字:
"项目使用 React 18,搭配 TypeScript 5.0,状态管理用 Zustand,
路由用 React Router v6,样式用 Tailwind CSS 4..."
✅ 结构化列表:
## 技术栈
- 前端:React 18
- 语言:TypeScript 5.0
- 状态管理:Zustand
- 路由:React Router v6
- 样式:Tailwind CSS 4结构化内容让 AI 更容易快速定位关键信息,而不是"漫游"整段文字。
对实践的影响
知道 Lost in the Middle 之后:
好的做法:
- 关键约束放提示词开头
- 重要规则在需要时重复
- 用结构化格式替代大段文字
- 长文档用分段提取
坏的做法:
- 关键信息塞在上下文中间
- 所有信息等权重
- 大段无结构文本
- 以为模型能均匀处理所有内容上下文优化的基本原则
原则 1:相关性优先
问题:上下文太多 = Token 浪费 + AI 可能混淆
❌ 不好的做法:
提供整个项目所有文档(100+ 个文件,10万+ tokens)
✅ 好的做法:
只提供跟当前问题相关的文档(2-3 个文件,2000 tokens)实践建议
| 任务类型 | 推荐上下文 | Token 估算 |
|---|---|---|
| 问 API 问题 | API 文档、接口定义 | 1K-3K |
| 问数据库设计 | 数据模型文档、Schema 定义 | 2K-5K |
| 问前端组件 | 组件规范文档、样式指南 | 1K-2K |
| 问部署流程 | 部署文档、CI/CD 配置 | 2K-4K |
原理
Claude 官方文档说:"More context isn't automatically better. As token count grows, accuracy and recall degrade, a phenomenon known as context rot."
简单说:上下文不是越多越好,而是越相关越好。
原则 2:结构化优于非结构化
问题:非结构化文本 AI 难理解、难提取信息
❌ 不好的做法:
"我们项目用的是React和TypeScript,数据库是PostgreSQL,
还有Redis缓存,前端用了Tailwind CSS,后端是Nest.js..."
✅ 好的做法:
## 技术栈
### 前端
- 框架:React 18
- 语言:TypeScript
- 样式:Tailwind CSS
### 后端
- 框架:Nest.js
- 数据库:PostgreSQL
- 缓存:Redis结构化好在哪
- 层次明确: Markdown 标题提供清晰层次
- 易提取: AI 快速定位到相关章节
- 好维护: 更新时只改对应部分
实践技巧
用标准 Markdown 格式:
##二级标题表示主要分类###三级标题表示子分类-列表表示具体条目>引用表示重要提示```代码块表示技术细节
原则 3:保持更新
问题:过时的上下文会误导 AI
❌ 不好的做法:
Wiki 写:"项目用的是 Redux"
实际已经迁移到 Zustand
AI 还是会按 Redux 的方式建议
✅ 好的做法:
代码变更时同步更新 Wiki建立更新机制
代码审查时同步更新文档
- PR 描述包含文档更新
- 把文档更新作为 review checklist 一项
定期文档审计
- 每月检查文档是否与代码一致
- 标记过期文档并更新
用自动化工具
- 用脚本检测代码与文档差异
- CI 中加入文档检查
原则 4:适度详细
问题:上下文太少不够用,太多浪费
❌ 太少:
"项目用的是 React"
→ 缺少关键信息:版本?搭配什么库?状态管理?
❌ 太多:
完整复制 React 官方文档(几万字)
→ 浪费 tokens,AI 已经知道 React 基础用法
✅ 适度:
"项目使用 React 18 + TypeScript,
采用函数组件 + Hooks 模式,
状态管理用 Zustand,
路由用 React Router v6"怎么判断"适度"
测试方法:
- 从少量上下文开始
- 观察 AI 输出是否符合预期
- 不符合就逐步补充相关信息
- AI 输出良好就停止添加
经验值:
- 技术栈描述: 200-500 tokens
- 代码规范: 500-1000 tokens
- API 文档摘要: 1000-2000 tokens
- 完整业务规则: 2000-5000 tokens
Token 使用策略
计算:多少上下文合适
假设:
- 上下文窗口:200K tokens
- 预留给 AI 输出:10K tokens
- 实际可用:190K tokens
分配建议
系统提示词:1K tokens (固定)
对话历史:20K tokens (最近 20-30 轮对话)
项目上下文:10K tokens (精选的核心文档)
当前问题:5K tokens (代码片段、错误信息等)
─────────────────────────────────
总计:36K tokens (还有很大余量)经验值
| 上下文规模 | Token 范围 | 适用场景 |
|---|---|---|
| 小型 | 1K-5K | 单一问题、简单查询 |
| 中型 | 5K-15K | 功能开发、代码实现 |
| 大型 | 15K-50K | 模块重构、架构讨论 |
| 超大 | 50K+ | 项目分析、文档理解 |
实际案例
场景:实现用户认证功能
小型上下文(3K tokens):
项目技术栈:
- Next.js 14 + TypeScript
- Prisma + PostgreSQL
- NextAuth.js 认证
当前任务:
实现邮箱密码登录功能中型上下文(10K tokens):
[上述内容] +
- 数据库 Schema 定义
- 现有 API 路由结构
- 错误处理规范
- 前端登录页面组件大型上下文(30K tokens):
[上述内容] +
- 完整的用户模块文档
- 相关 API 端点定义
- 安全策略文档
- 测试用例选哪个级别看任务复杂度。
省钱技巧
策略 1:摘要化
问题:完整文档太长,token 成本高
原始文档(5000 tokens):
"这里是完整的 API 文档,包括所有端点的详细说明..."
摘要版本(500 tokens):
"核心 API:
- 用户:POST /api/users/register, /api/users/login
- 订单:POST /api/orders, GET /api/orders/:id
- 商品:GET /api/products, GET /api/products/:id
详细文档见:docs/api.md"摘要化原则
- 保留关键信息: 端点路径、请求方法、参数说明
- 删除冗余: 示例代码、详细解释、版本历史
- 提供引用: 完整文档位置,需要时可查
策略 2:分层提供
第一次问:
→ 提供简要上下文(1K tokens)
如果 AI 问需要更多细节:
→ 提供详细上下文(10K tokens)
别一开始就提供所有内容好处
- 省成本: 第一次能解决的问题不需要 10K tokens
- 提速度: 上下文越少,响应越快
- 聚焦问题: 精简的上下文让问题更清晰
策略 3:用文档引用
❌ 直接提供:
把整个文档内容粘贴到对话中
✅ 引用方式:
"技术栈信息在 docs/tech-stack.md
代码规范在 docs/coding-standards.md"
AI 工具(如 Claude Code)会自动读这些文件适用场景
- Claude Code: 支持自动文件读取
- GitHub Copilot Workspace: 支持仓库引用
- ChatGPT Plus: 支持文件上传和知识库
上下文压缩技术
前面提到了 Token 使用策略,核心是"少给"。那能不能"少给但信息不减"?这就是上下文压缩做的事情。
为什么需要压缩
原始请求(无压缩):
系统提示 + 项目文档 + 对话历史 + 当前问题 = 50K tokens
每次调用都传 50K tokens → 慢 + 贵
压缩后:
智能摘要 + 关键信息 + 当前问题 = 8K tokens
80% 以上的 token 节省,信息完整度保留 90%+在 token 成本还比较高的 2025-2026 年,压缩是投入产出比最高的优化之一。
压缩方法
方法 1:选择性摘要
最简单也最实用的方法——不是简简单单截断,而是让 AI 自己提取关键信息:
def compress_conversation(conversation_history):
"""把长对话压缩为关键信息摘要"""
prompt = f"""
从以下对话中提取关键信息,输出结构化的摘要:
需要保留:
- 做过的技术决策(技术选型、架构变更)
- 用户的偏好和要求
- 尚未解决的问题和待办
对话内容:
{conversation_history}
压缩为不超过 500 tokens 的结构化摘要。
"""
summary = llm.generate(prompt)
return summary适用场景:长对话历史压缩、每日工作摘要
效果:5,000 tokens 对话 → 300 tokens 摘要,信息完整度约 85-90%
方法 2:任务感知压缩(Task-Aware Compression)
2025-2026 年最前沿的方法(论文:ATACompressor arXiv:2602.03226)——根据当前任务动态决定保留哪些信息:
传统压缩:
"用户上周说了 A、B、C、D 四件事" → 全部保留
任务感知压缩:
当前任务:用户支付功能
→ 只保留和支付相关的信息(A、D)
→ 和支付无关的信息(B、C)只保留标题级别def task_aware_compress(context, current_task):
"""根据当前任务动态压缩上下文"""
# 1. 分析当前任务需要哪些信息
needed_categories = analyze_task_needs(current_task)
# 输出:["payment", "user_auth", "error_handling"]
# 2. 按任务相关性分层次压缩
compressed = {}
for category, content in context.items():
if category in needed_categories:
compressed[category] = content # 完整保留
elif category in related_categories(needed_categories):
compressed[category] = summarize(content, ratio=0.3) # 摘要
else:
compressed[category] = one_line_summary(content) # 一行摘要
return compressed效果:比简单摘要多节省 30-40% 的 token,同时关键信息的完整度更高。
方法 3:分层压缩表示
把信息按不同粒度分层存储,AI 按需选择:
原始文档 (100K tokens)
↓
L1: 标题和结构 (2K tokens) ← 最精简,快速浏览
↓
L2: 关键信息 (10K tokens) ← 核心内容,适合大多数场景
↓
L3: 详细描述 (50K tokens) ← 需要深入时使用
↓
L4: 完整原文 (100K tokens) ← 需要精确引用时使用2026 年的实践建议:在 CLAUDE.md 或其他上下文配置中,使用以下模式:
## 项目技术栈(L1 - 2K tokens)
一句话概括技术选型。
## 技术栈详细说明(L2 - 8K tokens)
按模块分层列出技术选型和理由。
## 完整技术文档(仅在需要时引用)
参考 docs/tech-stack.md方法 4:Agent 自动上下文压缩
2025-2026 年的新方向——AI Agent 在执行过程中自己维护上下文压缩:
class AutoCompressingAgent:
"""能自动压缩上下文的 Agent"""
def process(self, new_input):
# 1. 正常处理
response = self.llm.generate(self.context + new_input)
# 2. 处理完后压缩
self.context = self.compress(self.context + new_input)
# 3. 只保留真正需要的信息
return response
def compress(self, full_context):
# 用 LLM 判断:哪些信息真正重要
important = self.llm.extract(full_context, [
"用户明确表达的偏好",
"未完成的待办事项",
"已确认的技术决策",
"当前任务的关键约束"
])
return important压缩效果对比
| 压缩方法 | Token 节省 | 信息保留度 | 计算成本 | 适用场景 |
|---|---|---|---|---|
| 简单截断 | 60-80% | 40-60% | 零 | 紧急情况 |
| 选择性摘要 | 70-85% | 80-90% | 低 | 日常使用 |
| 任务感知压缩 | 80-90% | 90-95% | 中 | 生产环境 |
| 分层压缩 | 70-95% | 按需选择 | 中 | 大型项目 |
| Agent 自动压缩 | 85-95% | 85-90% | 高 | 长期运行 Agent |
注意事项
- 压缩有损:任何压缩都会丢失一些信息,关键业务场景要保留原文引用路径
- 压缩成本:用 LLM 做压缩本身消耗 token,要权衡压缩收益和压缩成本
- 定期评估:压缩后的上下文质量需要定期检查——压缩方案可能需要调整
区别
┌─────────────────────────────────────────┐
│ 知识库 │
│ │
│ 来源:模型训练时学习的数据 │
│ 内容:公开的文档、代码、书籍 │
│ 更新:模型重新训练后才更新 │
│ 例子:React 怎么用、Python 语法 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 上下文 │
│ │
│ 来源:用户在对话中提供的信息 │
│ 内容:项目特定的文档、代码、配置 │
│ 更新:实时更新,对话中随时修改 │
│ 例子:你的项目用什么框架、代码规范 │
└─────────────────────────────────────────┘为什么需要上下文
AI 知识库有局限:
- 不知道私有项目信息: 你代码库、业务逻辑、内部规范
- 不知道最新代码变更: 昨天刚重构的模块,AI 不知道
- 不知道团队内部约定: "我们都用 camelCase 命名函数"
上下文弥补这个缺口。
最佳实践:知识库 + 上下文
AI 生成答案时:
1. 从知识库提取通用知识
(比如:React Hooks 的用法)
2. 从上下文提取项目特定信息
(比如:项目用哪种状态管理方案)
3. 结合两者生成答案
(比如:用 React Hooks + Zustand 写组件)类比
- 知识库 = 工程师的大学教育和职业经验
- 上下文 = 项目文档、代码规范、团队约定
- AI 生成 = 工程师结合通用知识和项目信息做决策
好工程师既需要扎实通用知识(知识库),也需要了解项目具体情况(上下文)。
实战演练
练习 1:观察上下文影响
任务:让 AI 写一个用户注册函数
步骤:
- 不提供任何上下文,观察 AI 输出
- 提供技术栈上下文,观察变化
- 提供代码规范上下文,再观察变化
记录差异,理解上下文作用。
预期结果
无上下文:
- 通用 JavaScript/TypeScript 代码
- 基本邮箱验证
- 简单错误处理
有技术栈:
- 符合项目框架的代码(比如 Nest.js Controller)
- 使用项目 ORM(比如 Prisma)
- 遵循项目目录结构
有代码规范:
- 函数命名符合约定
- 有 JSDoc 注释
- 错误处理使用自定义异常类
练习 2:上下文优化
任务:优化一段项目上下文描述
原文(太冗长):
我们的项目是一个电商平台,前端用 React,后端用 Node.js,
数据库用 MySQL,缓存用 Redis,搜索用 Elasticsearch,
消息队列用 RabbitMQ,容器化用 Docker,部署用 Kubernetes...优化后(结构化):
## 项目概述
电商平台,支持 B2C 和 C2C 模式
## 技术栈
### 前端
- React 18 + TypeScript
- 状态管理:Zustand
- UI 框架:Tailwind CSS
### 后端
- Node.js + Nest.js
- 数据库:PostgreSQL
- 缓存:Redis
### 基础设施
- 容器:Docker
- 编排:Kubernetes优化要点
- 用 Markdown 结构: 标题、列表、代码块
- 分类组织: 前端、后端、基础设施分开
- 精简描述: 删冗余词汇,保留核心信息
- 版本明确: React 18 而不是 React
练习 3:上下文衰减测试
任务:测试 AI 是否会"忘记"早期内容
步骤:
- 对话开始时约定一个规则 (比如:所有函数名必须用 camelCase)
- 进行 30+ 轮长对话
- 再要求写函数
- 观察 AI 是否遵守最初规则
思考:怎么避免上下文衰减?
预期结果
20-30 轮对话后,AI 可能忘了最初规则。因为:
- 早期内容在上下文窗口位置较远
- 注意力权重降低
- 新信息"覆盖"旧约定
改进办法
定期重申关键信息
每 10 轮:提醒一下,函数命名用 camelCase用持久化文档
创建 coding-standards.md,每次对话引用用系统提示词
把关键规范写进系统提示词(如果平台支持)
总结
核心要点
上下文是 AI 理解项目的关键
- 没有:AI 只能给通用建议
- 有:AI 给出符合项目的建议
上下文窗口有限且会衰减
- 窗口大小:通常 128K-200K tokens,最新已达 1M
- 注意力衰减:早期内容可能被"遗忘"
- 解决:重复关键信息或用持久化文档
上下文优化很重要
- 相关性优先:只提供相关内容
- 结构化:用 Markdown 组织
- 保持更新:代码变了文档也要变
- 适度详细:平衡太少和太多
Token 使用有策略
- 小型(1K-5K):单一问题
- 中型(5K-15K):功能开发
- 大型(15K-50K):模块重构
- 超大(50K+):项目分析
数据来源
本文档数据和案例参考:
- Anthropic 官方文档(2026)
- OpenAI 官方公告(2025)
- arXiv 论文《Efficient Attention Mechanisms for Large Language Models》(2025)
- Medium 技术博客(2025-2026)
- Claude vs GPT 比较研究(2026)
下一步
理解上下文基本原理后,继续学习:
- 上下文的类型与层次 → 了解不同类型上下文
- Wiki 系统最佳实践 → 如何组织上下文内容
- 让 AI 使用上下文的技巧 → 实际操作方法
