上下文工程:让 AI 拥有正确的知识

什么是上下文工程?

2025 年 6 月,Andrej Karpathy 在 OpenAI 工程博客上给出了上下文工程的定义:“the delicate art and science of filling the context window with just the right information for the model to take the next step.”

这一定义非常精辟。与提示工程(Prompt Engineering)的核心区别在于:

  • 提示工程:优化"你说什么"(what you say)——关注输入指令的表达方式
  • 上下文工程:优化"模型知道什么"(what the model knows)——关注模型能获得的信息

想象一下:

  • 提示工程就像调整给厨师下达的菜单指令
  • 上下文工程就像为厨师准备完整的食材仓库

从 ChatGPT-3 到现在的 GPT-4o、DeepSeek-V2,模型的上下文窗口从 4K 爆炸式增长到 1M。这种变化让我们的关注点从"如何精简提示"转向了"如何有效利用巨大的上下文空间"。

起源与发展

Bill Schilit 的先驱工作

上下文工程的概念可以追溯到 1995 年 Bill Schilit 的博士论文《A System Architecture for Context-Aware Computing》(注意:是 1995 年,不是 1994 年)。这篇论文提出了上下文感知计算(Context-Aware Computing)的概念:

mermaid
flowchart LR
    A[用户行为] --> B[上下文收集]
    B --> C[上下文分析]
    C --> D[智能响应]

Schilit 定义了三类上下文:

  1. 计算上下文:设备状态、网络条件
  2. 用户上下文:位置、时间、身份
  3. 物理上下文:环境、传感器数据

虽然当时针对的是移动计算,但这些思想直接影响了后来 AI 中的上下文管理。

RAG 的出现

2020 年,Lewis 等人在 NeurIPS 会议上发表了《Retrieval-Augmented Generation over Pre-trained Language Models》,正式提出了 RAG(Retrieval-Augmented Generation)概念:

mermaid
flowchart LR
    A[用户查询] --> B[检索模块]
    B --> C[向量数据库]
    C --> D[相关文档]
    D --> E[大模型]
    E --> F[增强回答]

RAG 的核心创新在于:将外部知识库与大模型结合,解决了模型知识更新和幻觉问题。

上下文工程的正式提出

2025 年 9 月,Anthropic 正式提出"Context Engineering"概念,将其作为独立的工程学科。同年 6 月,Karpathy 在 X(Twitter)上大力推崇这个概念,让它在 AI 工程社区迅速传播。

四大支柱

1. 知识层(What the model knows)

这是上下文工程的基础层,决定了模型的基本认知框架。

核心组件

  • 系统提示:定义模型的基本行为准则
  • 工具定义:模型可调用工具的规范
  • 预训练知识:模型自带的基础能力

设计原则

yaml
1
2
3
4
知识层设计原则:
  - 最小化:避免不必要的冗余信息
  - 结构化:使用明确的格式便于解析
  - 层次化:核心知识优先,专业知识按需加载

实践示例

python
1
2
3
4
5
6
7
8
# 优秀的系统提示设计
system_prompt = """
你是一个专业的软件开发助手,专注于:
1. 代码质量:可读性、可维护性、性能
2. 最佳实践:设计模式、架构原则、编码规范  
3. 安全考虑:输入验证、错误处理、权限控制
请使用中文回复,专业术语保留英文。
"""

2. 记忆层(What the model remembers)

管理模型在对话过程中的信息存储和记忆管理。

记忆类型

  • 短期记忆:当前对话历史
  • 长期记忆:向量数据库中的持久化记忆
  • 工作记忆:当前任务的状态信息

KV Cache 基础: 现代大模型使用 KV Cache 来缓存注意力计算结果:

1
2
3
4
5
Token 1 → Key1, Value1
Token 2 → Key2, Value2  
Token 3 → Key3, Value3
...
Token N → KeyN, ValueN

优化策略

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 智能记忆压缩
def compress_memory(memory_chunks, max_tokens=4000):
    """
    对记忆进行重要性排序和压缩
    """
    # 1. 按重要性排序
    ranked_chunks = rank_by_importance(memory_chunks)
    
    # 2. 渐进式压缩
    compressed = []
    current_tokens = 0
    
    for chunk in ranked_chunks:
        if current_tokens + chunk['tokens'] <= max_tokens:
            compressed.append(chunk)
            current_tokens += chunk['tokens']
        else:
            break
    
    return compressed

3. 检索层(What the model retrieves)

这是上下文工程中最复杂但也最关键的环节,负责从海量信息中找到最相关的内容。

RAG 深入解析

向量化(Embedding)

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from sentence_transformers import SentenceTransformer

# 加载预训练模型
model = SentenceTransformer('all-MiniLM-L6-v2')

# 文档向量化
documents = [
    "Python 是一种解释型编程语言",
    "机器学习是人工智能的分支", 
    "深度学习使用神经网络架构"
]

embeddings = model.encode(documents)

分块策略(Chunking)

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def smart_chunking(text, max_length=512, overlap=50):
    """
    智能分块算法:
    1. 按段落自然分割
    2. 保持语义完整性
    3. 添加必要的上下文标记
    """
    chunks = []
    paragraphs = text.split('\n\n')
    
    for para in paragraphs:
        if len(para) <= max_length:
            chunks.append(para)
        else:
            # 按句子进一步分割
            sentences = split_into_sentences(para)
            current_chunk = ""
            
            for sentence in sentences:
                if len(current_chunk) + len(sentence) <= max_length:
                    current_chunk += sentence + " "
                else:
                    chunks.append(current_chunk.strip())
                    current_chunk = sentence + " "
            
            if current_chunk:
                chunks.append(current_chunk.strip())
    
    return chunks

向量数据库

主要向量数据库对比:

数据库发布时间特色适用场景
Pinecone2021.08云原生、易用性强生产环境快速部署
Chroma2022.10开源、轻量级开发测试、本地部署
FAISS2017.03Facebook开源、高性能大规模向量计算
Milvus2019.04分布式、可扩展超大规模数据处理

重排序(Reranking)

检索结果的相关性排序问题。最著名的发现是 “Lost in the Middle” 问题

2023 年,Liu 等人(不是 Gao)发现:在长文档中,最相关的信息往往出现在开头或结尾,中间部分的信息容易被忽略。

解决方案

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from rank_bm25 import BM25Okapi

def lost_in_middle_fix(documents, query):
    """
    解决"Lost in the Middle"问题的重排序算法
    """
    # 1. BM25 初步排序
    tokenized_docs = [doc.split() for doc in documents]
    bm25 = BM25Okapi(tokenized_docs)
    
    # 2. 位置权重调整
    doc_scores = []
    for i, doc in enumerate(documents):
        # 给开头和结尾更高的权重
        position_weight = 1.0
        if i < len(documents) * 0.2 or i > len(documents) * 0.8:
            position_weight = 1.5
        
        score = bm25.get_scores(doc.split(), query)[0] * position_weight
        doc_scores.append((i, score))
    
    # 3. 重新排序
    doc_scores.sort(key=lambda x: x[1], reverse=True)
    return [documents[i] for i, _ in doc_scores]

4. 生成层(What the model generates)

确保模型输出的内容符合要求,结构合理。

核心控制机制

  • 输出约束:JSON 格式、字数限制
  • 思维链引导(Chain of Thought):逐步推理
  • 格式控制:Markdown 表格、代码块等

实践示例

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def structured_generation(prompt, schema):
    """
    结构化生成控制器
    """
    # 1. 添加格式约束
    constrained_prompt = f"""
请严格按照以下格式回答:

{schema['format']}

用户问题:{prompt}

请确保:
- 使用指定的格式
- 内容准确完整
- 语言清晰易懂
"""
    
    # 2. 调用模型
    response = call_llm(constrained_prompt)
    
    # 3. 格式验证和修正
    if validate_format(response, schema):
        return response
    else:
        return fix_format(response, schema)

上下文管理的核心挑战

Token 预算分配

不同信息的价值密度差异巨大:

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def value_based_allocation(context_tokens, total_budget):
    """
    基于价值的预算分配策略
    """
    priorities = {
        'system_prompt': 0.15,      # 系统指令 15%
        'core_context': 0.25,       # 核心上下文 25%
        'recent_history': 0.20,     # 近期历史 20%
        'tool_definitions': 0.15,   # 工具定义 15%
        'retrieved_docs': 0.25      # 检索文档 25%
    }
    
    allocated = {}
    remaining = total_budget
    
    for component, ratio in priorities.items():
        component_budget = int(total_budget * ratio)
        allocated[component] = min(component_budget, remaining)
        remaining -= allocated[component]
    
    return allocated

上下文窗口的进化

模型发布时间上下文特点
GPT-32020.064K奠基之作
GPT-3.52022.0316K首次突破限制
GPT-42023.0332K商业可用
Claude 22023.07100K长文本专家
GPT-4 Turbo2023.11128K实用化长上下文
DeepSeek-V22024.091M开源长上下文标杆
Gemini 1.52024.021M多模态长上下文

Prompt Caching 技术

Anthropic 的 Prompt Caching 可以节省 50-90% 的成本:

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class PromptCache:
    def __init__(self):
        self.cache = {}
    
    def get_cached_prompt(self, prompt_hash):
        return self.cache.get(prompt_hash)
    
    def cache_prompt(self, prompt_hash, prompt_data):
        self.cache[prompt_hash] = {
            'data': prompt_data,
            'timestamp': time.time(),
            'usage_count': 0
        }

混合策略:RAG + 长上下文

现代系统通常结合多种策略:

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
hybrid_context_strategy = {
    'short_term': {
        'memory_type': 'working_memory',
        'max_tokens': 2000,
        'refresh_rate': 'turn_by_turn'
    },
    'long_term': {
        'memory_type': 'vector_db', 
        'max_tokens': 8000,
        'refresh_rate': 'hourly'
    },
    'retrieval': {
        'method': 'semantic_search',
        'top_k': 5,
        'reranking': True
    }
}

动手入门:构建文档问答机器人

让我们构建一个完整的 RAG 系统,这是一个理解上下文工程的最佳实践。

第 1 步:环境准备

python
1
2
3
4
5
6
7
# requirements.txt
sentence-transformers==2.2.2
chromadb==0.4.18
langchain==0.1.0
openai==1.3.7
numpy==1.24.3
pandas==2.0.3
bash
1
pip install -r requirements.txt

第 2 步:文档处理

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from document_processor import DocumentProcessor

# 初始化处理器
processor = DocumentProcessor(
    chunk_size=512,
    chunk_overlap=50,
    embedding_model='all-MiniLM-L6-v2'
)

# 加载文档
documents = processor.load_documents([
    'data/company_handbook.pdf',
    'data/tech_specs.md',
    'data/policies.txt'
])

# 处理文档
processed_chunks = processor.process_documents(documents)

# 创建向量数据库
vector_db = processor.create_vector_db(processed_chunks)

第 3 步:检索系统

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class DocumentRetriever:
    def __init__(self, vector_db, reranker=True):
        self.vector_db = vector_db
        self.reranker = reranker
        self.bm25 = None
        
        if reranker:
            self.initialize_bm25()
    
    def initialize_bm25(self):
        """初始化 BM25 重排序器"""
        from rank_bm25 import BM25Okapi
        
        # 准备 BM25 索引
        all_chunks = [chunk['text'] for chunk in self.vector_db.get_all_chunks()]
        tokenized_chunks = [doc.split() for doc in all_chunks]
        self.bm25 = BM25Okapi(tokenized_chunks)
    
    def retrieve(self, query, top_k=5):
        """两阶段检索:向量搜索 + 重排序"""
        # 第一阶段:向量搜索
        vector_results = self.vector_db.search(query, top_k * 2)
        
        # 第二阶段:重排序
        if self.reranker and self.bm25:
            reranked = self.rerank_results(query, vector_results)
            return reranked[:top_k]
        else:
            return vector_results[:top_k]
    
    def rerank_results(self, query, results):
        """处理 Lost in the Middle 问题"""
        texts = [r['text'] for r in results]
        scores = self.bm25.get_scores(query.split(), texts)
        
        # 添加位置权重
        final_scores = []
        for i, (result, score) in enumerate(zip(results, scores)):
            position_weight = 1.0
            if i < len(results) * 0.2 or i > len(results) * 0.8:
                position_weight = 1.3
            
            final_scores.append((result, score * position_weight))
        
        # 重新排序
        final_scores.sort(key=lambda x: x[1], reverse=True)
        return [result for result, _ in final_scores]

第 4 步:问答系统

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class RAGSystem:
    def __init__(self, retriever, llm_client):
        self.retriever = retriever
        self.llm_client = llm_client
    
    def generate_response(self, query, context_window=4000):
        """生成回答"""
        # 1. 检索相关文档
        relevant_docs = self.retriever.retrieve(query)
        
        # 2. 上下文构建
        context = self.build_context(relevant_docs, context_window)
        
        # 3. 生成回答
        prompt = self.create_prompt(query, context)
        response = self.llm_client.generate(prompt)
        
        return response, relevant_docs
    
    def build_context(self, docs, max_tokens):
        """智能上下文构建"""
        context_parts = []
        used_tokens = 0
        
        # 按重要性排序文档
        sorted_docs = self.rank_documents_by_importance(docs)
        
        for doc in sorted_docs:
            if used_tokens + doc['tokens'] <= max_tokens:
                context_parts.append(doc['content'])
                used_tokens += doc['tokens']
            else:
                break
        
        return "\n\n".join(context_parts)
    
    def rank_documents_by_importance(self, docs):
        """基于重要性排序文档"""
        # 简单实现:按相关性分数排序
        return sorted(docs, key=lambda x: x['score'], reverse=True)

第 5 步:系统集成

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def main():
    """主程序"""
    # 初始化组件
    processor = DocumentProcessor()
    retriever = DocumentRetriever(processor.vector_db)
    llm_client = OpenAIClient(api_key="your-api-key")
    
    # 创建 RAG 系统
    rag_system = RAGSystem(retriever, llm_client)
    
    # 测试问答
    query = "公司的加班政策是什么?"
    response, sources = rag_system.generate_response(query)
    
    print("回答:", response)
    print("来源:", sources)

if __name__ == "__main__":
    main()

局限与未来

当前局限

  1. 被动信息供给:上下文工程主要优化的是"给什么信息",但无法主动决定"应该给什么信息"
  2. 执行控制缺失:知道正确信息 ≠ 能正确执行
  3. 反馈循环不足:缺乏执行效果的验证和修正机制
  4. 长周期自主性:无法处理需要多步决策的复杂任务

未来发展方向

  1. 主动上下文选择:AI 自主决定需要哪些信息
  2. 执行安全控制:在执行过程中的实时约束
  3. 多轮反馈机制:基于执行结果动态调整上下文
  4. 自主决策能力:从"会回答"到"会行动"的跃迁

上下文工程是 AI 工程化进程中的重要里程碑。它让我们从"如何让 AI 说对"进化到了"如何让 AI 知道正确信息",这为下一阶段的 AI 驾驭工程奠定了基础。