VINO/WANG返回博客 ←

BLOG / POST

什么是上下文

上下文是 LLM 推理时能看到的全部信息状态,由系统提示词、工具定义、检索文档、消息历史、工具输出五部分组成。

  • context-engineering
  • llm

来源:Agent-Skills-for-Context-Engineering

什么是上下文?

上下文是指在推理过程中,大语言模型在生成回答时能够“看到”和“使用”的所有信息的完整状态。


上下文的5大组成部分

实际场景示例

场景:你让AI帮你分析一个Python代码文件

此时,AI的上下文包含以下5个部分:

1. 系统提示词(System Prompts)

作用:告诉AI“你是谁”和“你应该怎么做事”

<SYSTEM_PROMPT>
你是一个Python编程专家。
你的任务是帮助用户编写、调试和优化Python代码。
你应该:
- 提供清晰、可运行的代码示例
- 解释代码的工作原理
- 遵循Python最佳实践(PEP 8)
</SYSTEM_PROMPT>

特点

  • 会话开始时加载一次
  • 通常在整个对话中保持不变
  • 设置AI的行为边界和角色
  • 典型大小:500-2000 tokens

最佳实践

  • 使用 XML 标签或 Markdown 标题进行结构化组织
  • 在“过高”和“过低”的抽象级别之间找到平衡
  • 提供清晰的指导,同时保持灵活性

2. 工具定义(Tool Definitions)

作用:告诉AI“你能使用哪些工具”

[
  {
    "name": "read_file",
    "description": "读取文件内容",
    "parameters": {
      "file_path": "要读取的文件路径"
    }
  },
  {
    "name": "execute_python",
    "description": "执行Python代码",
    "parameters": {
      "code": "要执行的代码"
    }
  }
]

实际意义

  • AI知道它有能力读取文件
  • AI知道它可以运行Python代码
  • 工具描述决定了AI何时选择使用哪个工具

强化原则

如果人类工程师无法确定在给定情况下应该使用哪个工具,就不应该期望代理能做得更好。

特点

  • 每个工具:100-500 tokens
  • 随工具数量增长
  • 位置:序列化后通常在系统提示词之后

3. 检索文档(Retrieved Documents)

作用:动态加载的相关参考资料

用户问:"这个函数的性能如何优化?"

系统检索到:
├─ docs/performance_guide.md (性能优化指南)
├─ docs/best_practices.md (最佳实践)
└─ code/function_analysis.py (相关代码分析)

这些文档被添加到上下文中,AI可以基于这些信息回答

特点

  • 根据用户问题动态加载(RAG - 检索增强生成)
  • 只包含与当前任务相关的信息
  • 来自外部知识库或文档
  • 通常是上下文的最大消耗者之一

即时加载方法

  • 维护轻量级标识符(文件路径、存储查询、Web链接)
  • 使用这些引用在运行时动态加载数据
  • 类似人类认知:不记忆整个语料库,而是使用外部组织系统

4. 消息历史(Message History)

作用:记录整个对话过程

[对话历史示例]

用户1: "帮我分析这个Python文件的性能"
助手1: "好的,我先读取文件内容"
[助手调用了read_file工具]
助手2: "我看到这个文件包含数据处理逻辑..."

用户2: "主要关注data_process函数"
助手3: "明白了,data_process函数有以下问题..."

用户3: "如何优化?" ← 当前问题

特点

  • 包含用户之前问过的问题
  • 包含AI之前的回答
  • 让AI能够理解对话的上下文和进度
  • 在长任务中可能主导上下文使用

管理策略

  • 对于长对话,摘要历史对话轮次
  • 保留最近的完整对话
  • 在间隔处注入摘要(如每20轮)

作为草稿记忆

  • 跟踪进度
  • 维护任务状态
  • 在回合间保留推理
  • 有效管理对长视野任务完成至关重要

5. 工具输出(Tool Outputs)

作用:工具执行的结果

[示例:工具输出占据大量上下文]

用户:读取large_data.json文件
AI调用read_file工具

工具返回:
{
  "file_path": "large_data.json",
  "content": "
  {
    'users': [
      {'id': 1, 'name': 'Alice', 'email': 'alice@example.com', ...},
      {'id': 2, 'name': 'Bob', 'email': 'bob@example.com', ...},
      ... (10,000条用户记录)
    ]
  ",
  "size": "2.5MB"
}

关键洞察

  • 研究显示:工具输出可占据总上下文的 83.9%
  • 无论信息是否相关,都会消耗上下文
  • 需要策略:观察掩码、压缩、选择性保留

示例工具输出类型

  • 文件内容
  • 搜索结果
  • 命令执行输出
  • API响应
  • 数据库查询结果

完整的上下文结构示例

═══════════════════════════════════════════════════
                    上下文结构
═══════════════════════════════════════════════════

【系统提示词】500 tokens
└─ 你是一个Python编程专家...
   你应该遵循最佳实践...

【工具定义】800 tokens
└─ read_file: 读取文件内容
└─ write_file: 写入文件内容
└─ execute_python: 执行代码
└─ search_docs: 搜索文档

【检索文档】2,000 tokens
└─ <document source="python_performance.md">
     Python性能优化技巧:
     1. 使用列表推导式...
     2. 避免全局变量...
     ...

【消息历史】1,500 tokens
└─ User: 帮我优化这段代码
└─ Assistant: 我先看一下代码
└─ User: 代码在script.py中
└─ Assistant: [调用read_file工具]

【工具输出】5,000 tokens ⚠️ 最大消耗者
└─ <tool_result>
     def process_data(items):
         results = []
         for item in items:
             # 复杂的处理逻辑
             ...
     </tool_result>

【当前用户输入】100 tokens
└─ "这个函数的性能如何优化?"

═══════════════════════════════════════════════════
总计:~10,000 tokens
═══════════════════════════════════════════════════

上下文类型的分类

静态上下文(Static Context)

特点:会话期间基本不变

示例:
- 系统提示词
- 角色定义
- 工具描述
- 格式规范

动态上下文(Dynamic Context)

特点:随对话不断变化和增长

示例:
- 检索的文档(RAG)
- 对话历史
- 用户偏好
- 会话状态

临时上下文(Ephemeral Context)

特点:只在当前回合相关

示例:
- 当前工具输出
- 中间推理步骤
- 草稿内容

为什么理解上下文很重要?

问题1:上下文限制

假设模型的上下文窗口是 200,000 tokens

如果你不加控制:
- 读取几个大文件 → 50,000 tokens
- 长对话历史 → 30,000 tokens
- 多个工具调用 → 80,000 tokens
──────────────────────────
总计:160,000 tokens

 问题:继续对话很容易超出限制
 后果:无法添加新信息或被迫截断旧信息

问题2:注意力分散(Lost-in-Middle现象)

上下文越长 = AI越容易"迷失"

长上下文的问题:
✓ 开头的信息:记得清楚
✗ 中间的信息:容易遗忘
✓ 结尾的信息:记得清楚

这被称为"迷失在中间"(Lost-in-Middle)现象

注意力预算约束

  • 语言模型通过注意力机制处理token,创建所有token之间的成对关系
  • 对于n个token,需要计算n²个关系
  • 随着上下文长度增加,模型捕获关系的能力“被稀释”
  • 模型从训练数据学习到的注意力模式主要针对短序列
  • 结果:存在一个有限的“注意力预算”,会随上下文增长而消耗

问题3:成本和性能

更多上下文 = 更高成本 + 更慢响应

Token消耗的影响:
-  成本:线性增长(2倍tokens = 2倍价格)
-  速度:指数增长(2倍tokens > 2倍时间)
-  质量:可能下降(注意力分散)

即使有前缀缓存,长输入仍然昂贵

位置编码和上下文扩展

  • 位置编码插值允许模型通过适应最初训练的较小上下文来处理更长的序列
  • 但这种适应会在token位置理解中引入退化
  • 模型在更长上下文下仍然高度 capable,但在信息检索和长程推理方面显示降低的精度

上下文工程的核心任务

理解了上下文的组成后,上下文工程就是:

上下文工程 = 精心管理进入模型的每一个token

目标:

  1. 最大化:相关信息 → 放在重要位置
  2. 最小化:无关信息 → 不加载或移除
  3. 优化:信息组织 → 结构清晰、易于理解
  4. 平衡:速度 vs 完整性 → 渐进式披露

核心原则: 信息性 > 全面性

  • 包含对当前决策重要的内容,
  • 排除不重要的内容,
  • 并设计能够按需访问额外信息的系统。

关键概念:渐进式披露(Progressive Disclosure)

这是上下文工程的核心设计原则:

渐进式披露 = 只在需要时加载信息

启动阶段:
├─ 只加载技能名称和描述
└─ 足够判断何时需要某个技能

任务执行阶段:
├─ 当技能被激活时
└─ 才加载完整的技能内容

优势:
✓ 保持代理快速启动
✓ 按需访问深度上下文
✓ 避免不相关的信息污染

应用层次

  • 技能选择
  • 文档加载
  • 工具结果检索

文件系统访问

  • 代理可以使用文件系统自然地实现渐进式披露
  • 外部存储参考资料、文档和数据
  • 仅在需要时使用标准文件系统操作加载文件
  • 避免用可能不相关的信息填充上下文

Thinking:

总的来说,我理解的上下文工程就是要消除噪音、提供模型最需要需要的数据

(完)