Context Engineering

Context Engineering 2026:从提示词工程到上下文工程的范式跃迁

系统梳理 Context Engineering 的核心理念与工程实践,从上下文窗口管理到动态注入策略,揭示为什么 Context Engineering 正在取代 Prompt Engineering 成为 AI 应用开发的核心方法论。

2026 年,AI 工程领域发生了一个重要的术语更替:Prompt Engineering(提示词工程)正在被 Context Engineering(上下文工程)取代。这不是文字游戏——它反映了 AI 应用开发方法论的根本性转变。

从 Prompt 到 Context

Prompt Engineering 的局限

Prompt Engineering 关注的是”怎么写提示词”。这在 2023-2024 年是合理的——那时候模型能力有限,一个好的 prompt 能显著提升输出质量。但到了 2026 年,模型能力大幅提升,瓶颈已经不在”怎么问”,而在”给模型看什么”。

2023-2024: Prompt Engineering
┌──────────────────────────────┐
│  用户提示词(精心设计)        │
│    ↓                         │
│  模型推理                     │
│    ↓                         │
│  输出                        │
└──────────────────────────────┘
核心问题:怎么写 prompt 效果最好?

2025-2026: Context Engineering
┌──────────────────────────────┐
│  动态上下文组装               │
│  ├── 用户输入                │
│  ├── 相关代码片段             │
│  ├── 文档片段                │
│  ├── 对话历史                │
│  ├── 工具描述                │
│  └── 系统指令                │
│    ↓                         │
│  模型推理                     │
│    ↓                         │
│  输出 + 工具调用              │
└──────────────────────────────┘
核心问题:组装什么上下文、多少上下文、以什么顺序?

Context Engineering 的定义

Context Engineering 是系统性地设计、组装和管理发送给 LLM 的上下文的工程实践。它关注的是:

  1. 选择:哪些信息应该进入上下文
  2. 组织:信息以什么顺序和结构呈现
  3. 压缩:如何在有限窗口内放入最多有效信息
  4. 动态:如何根据任务实时调整上下文

上下文窗口的经济学

Token 预算管理

上下文窗口是有限资源,需要精打细算:

interface ContextBudget {
  total: number;        // 模型上下文窗口大小
  system: number;       // 系统指令预留
  tools: number;        // 工具描述预留
  history: number;      // 对话历史预留
  retrieved: number;    // 检索内容预留
  user: number;         // 用户输入预留
  reserve: number;      // 为输出预留
}

// Claude Opus 4.7 的典型预算分配(200K 窗口)
const defaultBudget: ContextBudget = {
  total: 200_000,
  system: 2_000,      // 1%
  tools: 8_000,       // 4%
  history: 40_000,    // 20%
  retrieved: 100_000,  // 50%
  user: 10_000,       // 5%
  reserve: 40_000,    // 20%(给模型输出)
};

动态预算分配

不同类型的任务需要不同的预算分配:

class ContextBudgetAllocator {
  allocate(taskType: string, total: number): ContextBudget {
    switch (taskType) {
      case 'coding':
        // 编码任务:更多空间给检索到的代码
        return {
          total,
          system: 1_000,
          tools: 10_000,
          history: 20_000,
          retrieved: 120_000,
          user: 5_000,
          reserve: 44_000,
        };

      case 'conversation':
        // 对话任务:更多空间给历史
        return {
          total,
          system: 2_000,
          tools: 5_000,
          history: 100_000,
          retrieved: 40_000,
          user: 5_000,
          reserve: 48_000,
        };

      case 'research':
        // 研究任务:更多空间给检索内容
        return {
          total,
          system: 3_000,
          tools: 5_000,
          history: 10_000,
          retrieved: 140_000,
          user: 5_000,
          reserve: 37_000,
        };

      default:
        return this.defaultBudget(total);
    }
  }
}

上下文组装策略

RAG 2.0:智能检索

传统 RAG 只做向量相似度搜索。2026 年的 RAG 需要更智能的检索策略:

class SmartRetriever {
  // 多路检索
  async retrieve(query: string, budget: number): Promise<ContextChunk[]> {
    const results = await Promise.all([
      // 1. 语义检索
      this.semanticSearch(query),

      // 2. 关键词检索
      this.keywordSearch(query),

      // 3. 结构化检索(代码的 AST 级别)
      this.structuralSearch(query),

      // 4. 时序检索(最近修改的文件优先)
      this.recencySearch(query),
    ]);

    // 合并去重
    const merged = this.mergeResults(results);

    // 重排序:综合相关性、新鲜度、重要性
    const ranked = this.rerank(merged, query);

    // 在预算内截断
    return this.fitToBudget(ranked, budget);
  }

  private rerank(chunks: ContextChunk[], query: string): ContextChunk[] {
    return chunks.sort((a, b) => {
      const scoreA =
        a.semanticScore * 0.4 +
        a.recencyScore * 0.2 +
        a.importanceScore * 0.2 +
        a.structuralScore * 0.2;

      const scoreB =
        b.semanticScore * 0.4 +
        b.recencyScore * 0.2 +
        b.importanceScore * 0.2 +
        b.structuralScore * 0.2;

      return scoreB - scoreA;
    });
  }

  private fitToBudget(chunks: ContextChunk[], budget: number): ContextChunk[] {
    const result: ContextChunk[] = [];
    let used = 0;

    for (const chunk of chunks) {
      if (used + chunk.tokenCount > budget) break;
      result.push(chunk);
      used += chunk.tokenCount;
    }

    return result;
  }
}

上下文压缩

当内容超过预算时,需要智能压缩:

class ContextCompressor {
  // 摘要压缩:用更少的 token 保留核心信息
  async summarize(text: string, targetTokens: number): Promise<string> {
    const currentTokens = this.countTokens(text);
    if (currentTokens <= targetTokens) return text;

    const ratio = targetTokens / currentTokens;
    return this.llm.summarize(text, {
      targetRatio: ratio,
      preserveStructure: true,
      preserveKeyTerms: true,
    });
  }

  // 代码压缩:保留签名和关键逻辑,删除实现细节
  compressCode(code: string): string {
    const ast = this.parse(code);

    return this.transform(ast, {
      // 保留函数签名
      keepSignatures: true,
      // 保留类型定义
      keepTypes: true,
      // 保留关键注释
      keepDocComments: true,
      // 删除实现体(用 ... 替代)
      removeBodies: true,
      // 保留 import 语句
      keepImports: true,
    });
  }

  // 对话历史压缩
  compressHistory(messages: Message[], budget: number): Message[] {
    // 策略:保留最近的消息,压缩旧消息
    const recent = messages.slice(-10);  // 最近 10 条完整保留
    const older = messages.slice(0, -10);

    // 旧消息压缩为摘要
    const summary = this.summarizeConversation(older);

    const compressed = [
      { role: 'system', content: `之前的对话摘要:${summary}` },
      ...recent,
    ];

    // 如果还超预算,继续压缩
    if (this.countTokens(compressed) > budget) {
      return this.compressHistory(recent, budget);
    }

    return compressed;
  }
}

上下文排序

信息在上下文中的位置也影响模型的理解:

class ContextOrdering {
  // 最佳实践排序
  order(chunks: ContextChunk[]): ContextChunk[] {
    // 1. 系统指令在最前面
    // 2. 最相关的内容放在中间("注意力焦点")
    // 3. 次相关内容在后面
    // 4. 用户输入在最后(紧邻模型输出)

    const sorted = [...chunks].sort((a, b) => {
      // 系统指令始终第一
      if (a.type === 'system') return -1;
      if (b.type === 'system') return 1;

      // 用户输入始终最后
      if (a.type === 'user') return 1;
      if (b.type === 'user') return -1;

      // 其他按相关性排序
      return b.relevance - a.relevance;
    });

    return sorted;
  }
}

动态上下文注入

基于任务的上下文选择

不同的任务需要不同的上下文:

class DynamicContextBuilder {
  async buildContext(
    task: string,
    conversationHistory: Message[],
    availableSources: ContextSource[]
  ): Promise<string> {
    // 1. 分析任务类型
    const taskType = await this.classifyTask(task);

    // 2. 根据任务类型选择上下文源
    const relevantSources = this.selectSources(taskType, availableSources);

    // 3. 检索相关内容
    const retrieved = await this.retriever.retrieve(task, relevantSources);

    // 4. 组装上下文
    const context = this.assemble({
      system: this.getSystemPrompt(taskType),
      tools: this.getToolDescriptions(taskType),
      history: this.compressHistory(conversationHistory),
      retrieved: retrieved,
      user: task,
    });

    return context;
  }

  private selectSources(
    taskType: string,
    sources: ContextSource[]
  ): ContextSource[] {
    const sourceMap: Record<string, string[]> = {
      'code-review': ['codebase', 'style-guide', 'test-results'],
      'bug-fix': ['codebase', 'error-logs', 'issue-tracker'],
      'feature': ['codebase', 'requirements', 'api-docs'],
      'question': ['documentation', 'faq', 'codebase'],
    };

    const preferred = sourceMap[taskType] || ['codebase'];
    return sources.filter(s => preferred.includes(s.id));
  }
}

MCP 工具描述的上下文优化

MCP 工具描述也是上下文的一部分,需要优化:

// 差的工具描述(浪费 token)
const badToolDescription = {
  name: 'query',
  description: '这个工具可以用来查询数据库,支持各种 SQL 语句,' +
    '包括 SELECT、INSERT、UPDATE、DELETE 等。使用时需要注意...' +
    '[200 tokens 的冗余描述]',
};

// 好的工具描述(精准高效)
const goodToolDescription = {
  name: 'query-database',
  description: '执行 SQL SELECT 查询。返回 JSON 格式的查询结果。',
  parameters: {
    sql: {
      type: 'string',
      description: 'SELECT 查询语句。表名使用 snake_case。',
    },
    limit: {
      type: 'number',
      description: '最大返回行数,默认 100。',
      default: 100,
    },
  },
};

上下文工程的度量

关键指标

interface ContextMetrics {
  // 上下文利用率
  utilization: number;  // 使用的 token / 总窗口

  // 检索精度
  retrievalPrecision: number;  // 检索到的内容中,有多少是相关的
  retrievalRecall: number;     // 所有相关内容中,检索到了多少

  // 压缩质量
  compressionRatio: number;    // 压缩比
  informationRetention: number; // 压缩后保留了多少关键信息

  // 任务效果
  taskSuccessRate: number;     // 任务完成率
  firstTryAccuracy: number;    // 一次成功率
}

class ContextAnalyzer {
  analyze(session: AgentSession): ContextMetrics {
    return {
      utilization: this.calcUtilization(session),
      retrievalPrecision: this.calcPrecision(session),
      retrievalRecall: this.calcRecall(session),
      compressionRatio: this.calcCompression(session),
      informationRetention: this.calcRetention(session),
      taskSuccessRate: this.calcSuccessRate(session),
      firstTryAccuracy: this.calcFirstTry(session),
    };
  }

  // 诊断:上下文是否是性能瓶颈
  diagnose(metrics: ContextMetrics): string[] {
    const issues: string[] = [];

    if (metrics.utilization > 0.9) {
      issues.push('上下文窗口接近满载,考虑增加压缩或减少检索量');
    }

    if (metrics.retrievalPrecision < 0.5) {
      issues.push('检索精度低,检查检索策略和查询质量');
    }

    if (metrics.compressionRatio > 0.8 && metrics.informationRetention < 0.6) {
      issues.push('压缩过度,关键信息丢失');
    }

    if (metrics.taskSuccessRate < 0.7 && metrics.utilization < 0.5) {
      issues.push('任务失败但上下文有余量,可能是上下文质量问题');
    }

    return issues;
  }
}

实战:构建上下文工程系统

完整的 Context Pipeline

class ContextPipeline {
  private retriever: SmartRetriever;
  private compressor: ContextCompressor;
  private ordering: ContextOrdering;
  private budgetAllocator: ContextBudgetAllocator;

  async process(request: ContextRequest): Promise<string> {
    // 1. 分配预算
    const budget = this.budgetAllocator.allocate(
      request.taskType,
      request.modelContextWindow
    );

    // 2. 检索相关内容
    const rawChunks = await this.retriever.retrieve(
      request.query,
      budget.retrieved
    );

    // 3. 压缩(如果需要)
    let chunks = rawChunks;
    const totalTokens = chunks.reduce((sum, c) => sum + c.tokenCount, 0);
    if (totalTokens > budget.retrieved) {
      chunks = await this.compressToFit(chunks, budget.retrieved);
    }

    // 4. 排序
    const ordered = this.ordering.order(chunks);

    // 5. 组装最终上下文
    return this.assemble({
      system: request.systemPrompt,
      tools: request.toolDescriptions,
      history: request.conversationHistory,
      retrieved: ordered,
      user: request.userQuery,
      budget,
    });
  }

  private async compressToFit(
    chunks: ContextChunk[],
    budget: number
  ): Promise<ContextChunk[]> {
    // 按重要性排序,低重要性的先压缩
    const sorted = chunks.sort((a, b) => b.importance - a.importance);

    let total = sorted.reduce((sum, c) => sum + c.tokenCount, 0);
    const result = [...sorted];

    // 从最不重要的开始压缩
    for (let i = result.length - 1; i >= 0 && total > budget; i--) {
      const chunk = result[i];
      const targetTokens = Math.floor(chunk.tokenCount * 0.5);
      const compressed = await this.compressor.summarize(
        chunk.content,
        targetTokens
      );
      total -= chunk.tokenCount - targetTokens;
      result[i] = { ...chunk, content: compressed, tokenCount: targetTokens };
    }

    return result;
  }
}

常见问题(FAQ)

Context Engineering 和 RAG 有什么区别?

RAG 是 Context Engineering 的一个子集。RAG 关注”如何检索相关内容”,Context Engineering 还包括:上下文压缩、排序、预算管理、动态注入、历史管理等。可以说 RAG 是检索环节,Context Engineering 是整个上下文生命周期。

需要为每个任务类型都设计上下文策略吗?

建议至少为高频任务类型设计专门的策略。一个”通用”策略往往在所有场景下都表现平庸。典型的分类:编码、对话、研究、创作——每种类型对上下文的需求差异很大。

如何评估上下文质量?

最直接的指标是任务成功率和一次成功率。如果模型经常需要多轮交互才能完成任务,很可能是上下文质量的问题。更细粒度的指标包括检索精度、压缩比、上下文利用率等。

总结

Context Engineering 是 AI 应用开发从”手工艺”走向”工程化”的标志。它不再是”怎么写一句好的 prompt”,而是”如何系统性地管理模型看到的信息”。

核心原则:

  1. 上下文是有限资源——像管理内存一样管理上下文窗口
  2. 质量胜于数量——10 条高相关信息胜过 100 条低相关信息
  3. 动态胜于静态——根据任务实时调整上下文策略
  4. 度量驱动优化——没有度量就没有改进

在 2026 年的 AI 工程实践中,Context Engineering 已经不是一个”可选的最佳实践”,而是构建高质量 Agent 系统的基本功。