如果说 prompt 工程是"怎么说话",上下文工程就是"让模型能看到什么"。这是 2025–2026 年 AI 工程师的核心能力——因为模型能力本身已经够强,前 80% 的产出差距来自上下文喂得对不对

4.1 三种获取"知识"的方式

模型要"知道事情",只有三条路:

┌─────────────────────────────────────────────────────────────┐
│ 1. Pretrain   :训练时就背在脑子里了                              │
│ 2. Context    :你这次对话贴进来,模型看到了                      │
│ 3. Tool Call  :模型调用工具(搜索、读文件、grep)拿到结果          │
└─────────────────────────────────────────────────────────────┘

三者构成一个预算三角:pretrain 是免费的但有时效与范围;context 是最贵但最准确;tool call 介于两者之间,但要模型"会调用"。

关键洞察:所有"AI 编程工具"——Cursor、Claude Code、Copilot Workspace、OpenCode——做的核心事都是这三种方式的自动调度

4.2 RAG:检索增强生成

RAG 解决一个矛盾:你想让模型回答某个文档里的事,但塞全文进 context 太贵太脏。做法是先检索 → 拿到相关片段 → 把片段塞进 context

# RAG 的极简伪代码
def answer(query: str, knowledge_base: list[str]) -> str:
    # 1. 把知识库切成 chunk 并预计算 embedding
    chunks = [chunk for doc in knowledge_base for chunk in split(doc, size=512)]
    chunk_embeddings = embed(chunks)

    # 2. 用 query 检索 top-k 相关 chunk
    query_emb = embed(query)
    top_k = cosine_topk(query_emb, chunk_embeddings, k=5)

    # 3. 把片段塞进 prompt
    return client.messages.create(
        model="claude-...",
        messages=[{
            "role": "user",
            "content": f"基于以下资料回答:\n\n{top_k}\n\n问题:{query}"
        }]
    )

RAG 的工程陷阱

陷阱 现象 解法
切分粒度太粗 命中文章却错过段落 按 “语义边界"切(章节、heading)而非定长
Chunk 没元信息 命中旧文档以为是新规章 给每个 chunk 加 source / version / updated_at
检索召回低 用户问的就是答案却没召回 加 hybrid search(向量 + BM25 关键词)
答非所求 模型把无关片段当依据 给片段加 confidence,低分不加进 context

4.3 长上下文:直接塞满整个项目

2026 年的城市主流模型普遍 200k–1M token 上下文,看起来"塞全部源文件"可以了——但事情没那么简单。

Lost-in-the-middle 效应

研究人员发现,模型对开头和结尾的注意力高,对中间的注意力低。这意味着:

❌ 把整个 repo 塞前面 → 模型"问题"被挤到结尾时已疲软
⚠️ 把全部搜索结果铺开 → 中间的 20 条几乎被忽略
✅ 把最相关的放头尾,无关的不塞

实操:在 Claude Code / OpenCode 等工具里,你不需要手动管这个——它们有截断 / 重排序策略。但写自己的 harness 时务必考虑。

项目正常大小 vs 上下文窗口

项目              代码 token   上下文够吗      现实策略
─────────────────────────────────────────────────────
单功能 demo        <10k         一发塞完       ✅ 直接全塞
单人一周项目       30–100k      边缘           🟧 检索后塞
中型团队项目       200k+        不够           ❌ 走 RAG / MCP
大型工程           >1M          远远不够       ❌ 走 Agent 分治

4.4 三种长上下文实战策略

策略 1:压缩 + 重排

让模型先总结回答

PASS 1(总结):读下面 [50 个文件],每文件给我 50 字总结,按功能分组。
PASS 2(回答):基于上一步的总结 + 你需要的原文件(自己去 grep),回答问题。

代价:双步成本翻倍,但有显著准确度收益。

策略 2:渐进式加载

让 Agent 拿目录树 → 拿几个文件 → 在 scope 内展开。这是 Claude Code、Codex 的核心机制:

# OpenCode 风格的渐进加载策略
async def load_repo(path):
    files = await list_all_markdown(path, depth=2)      # 拿个目录树
    summary = await summarize_files(files, k=10)        # 让 AI 看 10 篇
    candidate = await ai_pick_files(summary, query)     # AI 自己挑
    return await read_files(candidate)                  # 才真正全文加载

策略 3:分布式 Agent(第五篇实战)

如果项目太大(>1M token),单个上下文塞不下,让多个 Agent 分而治之——每个 Agent 拿一个模块、调外部协调 Agent。这一节在 28 实战:多 Agent 协作 展开。

4.5 上下文工程的五个原则

把"让模型看到什么"当一种投资组合:

  1. 越靠近 → 越贵:根目录的 README.md 放 context 比放 RAG 检索召回要直接
  2. 越小越好:你能给 5 个文件就别给 50 个;让模型主动去 grep
  3. 可解释优先:模型必须能"说出"它看到了什么——不做"静默吞掉”
  4. 结构 > 散文:项目结构、front matter、明确分隔符比自然语言叙述更省 token
  5. 存量复用 > 重复生成:把"反复被查的"沉淀成 MCP 资源Skill

4.6 一道实操:手动模拟 RAG

任何能用 Python 的环境都能做:

pip install openai pyarrow                    # 一个 embedding + 一个本地 chunk
export OPENAI_API_KEY=...

python -c "
import openai, numpy as np
docs = ['用户登录用 JWT', '订单表是 orders', '限速中间件叫 rate_limit', 'JWT 30 分钟过期']
emb = openai.embeddings.create(model='text-embedding-3-small', input=docs).data[0].embedding
print(len(emb))
"

再实现一下 cosine_topk + 选 top 2 + 拼进 prompt。整个流程会让你瞬间明白 RAG 不是黑魔法,是一行加权和。

4.7 小结

  • 三条知识路径:pretrain / context / tool call
  • RAG = 检索 + 塞片段,长上下文 ≠ 万灵药
  • 五原则:靠近越贵 → 越小越好 → 可解释 → 结构化 → 沉淀复用

下一篇:《05 主流 AI 编程工具全景》——当别人在用工具时,你要明白它们各自擅长什么。

Summary: 三种知识路径 + RAG/长上下文权衡 + 五原则,构建给模型"喂"上下文的投资组合。