Skip to content

大模型上下文原理解析

想知道为什么同一个问题,给不给 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 年的一些技术分析:

  1. 字符集差异: 英文基本字符 < 100 个,中文常用就 3000+
  2. 语言特性: 英文有清晰单词边界和词根词缀,中文靠单字组合
  3. BPE 算法: 字符集越大,越难找到高频字符组合来合并 token

有意思的是,微软 2025 年的研究发现,中文虽然 token 多,但信息密度更高——用中文推理有时能减少 token 消耗还能保持准确。DeepSeek 等模型推理时会"切换"到中文思考,就是这个原因。

各模型的上下文窗口

模型上下文窗口发布时间备注
GPT-3.516K2022早期版本
GPT-48K-32K2023看版本
GPT-4 Turbo128K2023提升挺大
GPT-4o128K2024主力版本
GPT-5200K2025最新
Claude 3 Sonnet200K2024性能和成本平衡
Claude 3.5 Sonnet200K2024开发者用得多
Claude Opus 4.61M(beta)2026目前最大

数据来源: Anthropic 官方文档(2026)、OpenAI 官方公告(2025)

趋势

上下文窗口从 2023 年的 4K 到 2026 年的 1M tokens,涨了 250 倍。几个原因:

  1. 技术突破: 线性 attention、稀疏 attention 降低了计算复杂度
  2. 应用需求: AI Agent、代码分析、长文档处理需要更大上下文
  3. 竞争: 厂商把上下文窗口当卖点

但要注意,更大的上下文不等于更好的效果。研究表明,上下文增长后准确性和召回率会下降,这叫"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 给针对性建议:

typescript
// 使用 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 输出会自动遵循这些规范

实际对比

无风格约束:

javascript
// AI 生成的代码
function validate(u) {
  if(!u.email) return false;
  return true;
}

有风格约束:

typescript
/**
 * 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)**。

原因

技术层面

  1. 注意力机制:

    • AI 生成每个 token 时,对上下文不同部分分配不同"注意力权重"
    • 最新内容通常获得更高权重
    • 类似人类"近因效应"——更容易记住最近发生的事
  2. 位置编码:

    • Transformer 用位置编码理解 token 顺序
    • 早期内容的位置编码在深层网络中可能被"稀释"
    • 模型对早期位置"敏感度"下降
  3. 计算效率:

    • 为保证生成速度,模型可能不会同等处理所有上下文
    • 某些优化算法会"选择性忽略"部分内容

研究怎么说

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 自动参考这些文档
- 不受对话长度影响

优点:

  • 最方便,自动管理
  • 支持多个文档
  • 适合长期项目

缺点:

  • 依赖特定平台功能

上下文优化的基本原则

原则 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

结构化好在哪

  1. 层次明确: Markdown 标题提供清晰层次
  2. 易提取: AI 快速定位到相关章节
  3. 好维护: 更新时只改对应部分

实践技巧

用标准 Markdown 格式:

  • ## 二级标题表示主要分类
  • ### 三级标题表示子分类
  • - 列表表示具体条目
  • > 引用表示重要提示
  • ``` 代码块表示技术细节

原则 3:保持更新

问题:过时的上下文会误导 AI

❌ 不好的做法:
Wiki 写:"项目用的是 Redux"
实际已经迁移到 Zustand
AI 还是会按 Redux 的方式建议

✅ 好的做法:
代码变更时同步更新 Wiki

建立更新机制

  1. 代码审查时同步更新文档

    • PR 描述包含文档更新
    • 把文档更新作为 review checklist 一项
  2. 定期文档审计

    • 每月检查文档是否与代码一致
    • 标记过期文档并更新
  3. 用自动化工具

    • 用脚本检测代码与文档差异
    • CI 中加入文档检查

原则 4:适度详细

问题:上下文太少不够用,太多浪费

❌ 太少:
"项目用的是 React"
→ 缺少关键信息:版本?搭配什么库?状态管理?

❌ 太多:
完整复制 React 官方文档(几万字)
→ 浪费 tokens,AI 已经知道 React 基础用法

✅ 适度:
"项目使用 React 18 + TypeScript,
采用函数组件 + Hooks 模式,
状态管理用 Zustand,
路由用 React Router v6"

怎么判断"适度"

测试方法:

  1. 从少量上下文开始
  2. 观察 AI 输出是否符合预期
  3. 不符合就逐步补充相关信息
  4. 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"

摘要化原则

  1. 保留关键信息: 端点路径、请求方法、参数说明
  2. 删除冗余: 示例代码、详细解释、版本历史
  3. 提供引用: 完整文档位置,需要时可查

策略 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: 支持文件上传和知识库

上下文 vs 知识库

区别

┌─────────────────────────────────────────┐
│              知识库                       │
│                                         │
│  来源:模型训练时学习的数据               │
│  内容:公开的文档、代码、书籍             │
│  更新:模型重新训练后才更新               │
│  例子:React 怎么用、Python 语法          │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│              上下文                       │
│                                         │
│  来源:用户在对话中提供的信息             │
│  内容:项目特定的文档、代码、配置          │
│  更新:实时更新,对话中随时修改           │
│  例子:你的项目用什么框架、代码规范        │
└─────────────────────────────────────────┘

为什么需要上下文

AI 知识库有局限:

  1. 不知道私有项目信息: 你代码库、业务逻辑、内部规范
  2. 不知道最新代码变更: 昨天刚重构的模块,AI 不知道
  3. 不知道团队内部约定: "我们都用 camelCase 命名函数"

上下文弥补这个缺口。

最佳实践:知识库 + 上下文

AI 生成答案时:
1. 从知识库提取通用知识
   (比如:React Hooks 的用法)

2. 从上下文提取项目特定信息
   (比如:项目用哪种状态管理方案)

3. 结合两者生成答案
   (比如:用 React Hooks + Zustand 写组件)

类比

  • 知识库 = 工程师的大学教育和职业经验
  • 上下文 = 项目文档、代码规范、团队约定
  • AI 生成 = 工程师结合通用知识和项目信息做决策

好工程师既需要扎实通用知识(知识库),也需要了解项目具体情况(上下文)。


实战演练

练习 1:观察上下文影响

任务:让 AI 写一个用户注册函数

步骤:

  1. 不提供任何上下文,观察 AI 输出
  2. 提供技术栈上下文,观察变化
  3. 提供代码规范上下文,再观察变化

记录差异,理解上下文作用。

预期结果

无上下文:

  • 通用 JavaScript/TypeScript 代码
  • 基本邮箱验证
  • 简单错误处理

有技术栈:

  • 符合项目框架的代码(比如 Nest.js Controller)
  • 使用项目 ORM(比如 Prisma)
  • 遵循项目目录结构

有代码规范:

  • 函数命名符合约定
  • 有 JSDoc 注释
  • 错误处理使用自定义异常类

练习 2:上下文优化

任务:优化一段项目上下文描述

原文(太冗长):

我们的项目是一个电商平台,前端用 React,后端用 Node.js,
数据库用 MySQL,缓存用 Redis,搜索用 Elasticsearch,
消息队列用 RabbitMQ,容器化用 Docker,部署用 Kubernetes...

优化后(结构化):

markdown
## 项目概述
电商平台,支持 B2C 和 C2C 模式

## 技术栈
### 前端
- React 18 + TypeScript
- 状态管理:Zustand
- UI 框架:Tailwind CSS

### 后端
- Node.js + Nest.js
- 数据库:PostgreSQL
- 缓存:Redis

### 基础设施
- 容器:Docker
- 编排:Kubernetes

优化要点

  1. 用 Markdown 结构: 标题、列表、代码块
  2. 分类组织: 前端、后端、基础设施分开
  3. 精简描述: 删冗余词汇,保留核心信息
  4. 版本明确: React 18 而不是 React

练习 3:上下文衰减测试

任务:测试 AI 是否会"忘记"早期内容

步骤:

  1. 对话开始时约定一个规则 (比如:所有函数名必须用 camelCase)
  2. 进行 30+ 轮长对话
  3. 再要求写函数
  4. 观察 AI 是否遵守最初规则

思考:怎么避免上下文衰减?

预期结果

20-30 轮对话后,AI 可能忘了最初规则。因为:

  • 早期内容在上下文窗口位置较远
  • 注意力权重降低
  • 新信息"覆盖"旧约定

改进办法

  1. 定期重申关键信息

    每 10 轮:提醒一下,函数命名用 camelCase
  2. 用持久化文档

    创建 coding-standards.md,每次对话引用
  3. 用系统提示词

    把关键规范写进系统提示词(如果平台支持)

总结

核心要点

  1. 上下文是 AI 理解项目的关键

    • 没有:AI 只能给通用建议
    • 有:AI 给出符合项目的建议
  2. 上下文窗口有限且会衰减

    • 窗口大小:通常 128K-200K tokens,最新已达 1M
    • 注意力衰减:早期内容可能被"遗忘"
    • 解决:重复关键信息或用持久化文档
  3. 上下文优化很重要

    • 相关性优先:只提供相关内容
    • 结构化:用 Markdown 组织
    • 保持更新:代码变了文档也要变
    • 适度详细:平衡太少和太多
  4. 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)

下一步

理解上下文基本原理后,继续学习:


← 返回文章目录 | 继续学习:上下文的类型与层次 →

最近更新

基于 Apache 2.0 许可发布