Agent 上下文系统:构成、生命周期与工程实践

0 阅读24分钟

在这里插入图片描述

目录


1. 概述

1.1 什么是 Agent 上下文

Agent 上下文(Context)是指在 Agent 运行过程中,模型能够"看到"和"参考"的全部信息集合。它直接决定了 Agent 的行为质量、推理准确性和任务完成能力。

可以把上下文理解为 Agent 的"工作台"——桌上摆放的工具、图纸、备忘录和正在加工的工件,共同构成了 Agent 处理当前任务时所依据的完整环境。

1.2 上下文的重要性

一句话概括:模型的输出质量不可能超越输入信息的质量。即使是最强大的语言模型,如果上下文信息不完整、结构混乱或包含矛盾,其输出也会出现偏差。

上下文质量直接影响以下维度:

  • 指令遵循:模型能否准确理解和执行用户意图
  • 事实准确性:模型是否基于正确的信息做推理
  • 行为一致性:Agent 在不同轮次中是否保持稳定的角色和行为模式
  • 能力边界:模型知道自己能做什么、不能做什么

1.3 上下文信息流总览

flowchart TB
    subgraph input["输入层"]
        A1["用户消息"]
        A2["系统指令"]
        A3["工具定义"]
        A4["外部知识"]
    end

    subgraph process["处理层"]
        B1["消息格式化"]
        B2["Token 计数"]
        B3["上下文压缩"]
        B4["优先级排序"]
    end

    subgraph model["模型层"]
        C1["上下文窗口"]
        C2["注意力计算"]
        C3["推理输出"]
    end

    subgraph output["输出层"]
        D1["回复文本"]
        D2["工具调用"]
        D3["结构化输出"]
    end

    A1 & A2 & A3 & A4 --> B1
    B1 --> B2
    B2 --> B3
    B3 --> B4
    B4 --> C1
    C1 --> C2
    C2 --> C3
    C3 --> D1 & D2 & D3

    style input fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style A1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style process fill:#1b5e20,stroke:#2e7d32,color:#ffffff
    style B1 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style B2 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style B3 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style B4 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style model fill:#e65100,stroke:#bf360c,color:#ffffff
    style C1 fill:#ef6c00,stroke:#e65100,color:#ffffff
    style C2 fill:#ef6c00,stroke:#e65100,color:#ffffff
    style C3 fill:#ef6c00,stroke:#e65100,color:#ffffff
    style output fill:#b71c1c,stroke:#880e4f,color:#ffffff
    style D1 fill:#c62828,stroke:#b71c1c,color:#ffffff
    style D2 fill:#c62828,stroke:#b71c1c,color:#ffffff
    style D3 fill:#c62828,stroke:#b71c1c,color:#ffffff

2. 上下文的核心组成

2.1 组件总览

一条完整的 Agent 上下文由以下七个部分构成:

组件位置可变性作用
System Prompt消息列表最前端会话级固定定义角色、规则、输出格式
Tool DefinitionsSystem Prompt 之后会话级固定声明可调用的工具与参数
Conversation History消息列表中部每轮追加多轮对话的历史记录
Tool Returns消息列表中部每轮追加工具执行返回的数据结果
SkillsSystem Prompt 之后会话级固定可加载的专项能力模块
Current User Input消息列表末尾每轮变化当前轮次的用户请求
Injected Context按需插入动态变化检索增强、文件内容等外部信息

2.2 上下文组件关系图

flowchart LR
    subgraph static["静态上下文(会话级固定)"]
        S1[&#34;System Prompt<br/>角色定义 / 行为规则&#34;]
        S2[&#34;Tool Definitions<br/>工具描述 / 参数 Schema&#34;]
        S3[&#34;Skills<br/>可加载的专项能力模块&#34;]
    end

    subgraph dynamic[&#34;动态上下文(每轮变化)&#34;]
        D1[&#34;Conversation History<br/>历史多轮对话&#34;]
        D2[&#34;Tool Returns<br/>工具执行返回结果&#34;]
        D3[&#34;Injected Context<br/>RAG / 文件 / 环境信息&#34;]
        D4[&#34;Current User Input<br/>当前用户消息&#34;]
    end

    static --> core[&#34;大语言模型&#34;]
    dynamic --> core

    style static fill:#311b92,stroke:#1a005c,color:#ffffff
    style S1 fill:#4527a0,stroke:#311b92,color:#ffffff
    style S2 fill:#4527a0,stroke:#311b92,color:#ffffff
    style S3 fill:#4527a0,stroke:#311b92,color:#ffffff
    style dynamic fill:#0d47a1,stroke:#002171,color:#ffffff
    style D1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style core fill:#bf360c,stroke:#8d2008,color:#ffffff

2.3 各组件详解

2.3.1 System Prompt

System Prompt 是整个上下文的"宪法",位于消息列表的最前端,对模型的行为具有最高约束力。

一个典型的 System Prompt 包含这些要素:

# 角色定义
你是一个专业的代码审查助手...

# 行为规则
- 审查代码时关注安全性、性能、可读性
- 给出具体的改进建议而非泛泛而谈
- 对于不确定的判断,明确标注置信度

# 输出格式
使用 Markdown 格式输出,包含以下章节:
1. 概述
2. 严重问题
3. 改进建议
4. 最佳实践提示

# 约束
- 不要生成未经验证的信息
- 不要泄露代码中的敏感信息

System Prompt 的设计原则:

  • 明确性:指令不含歧义,模型能唯一理解其含义
  • 可验证性:每条规则都可以通过输出验证是否被遵循
  • 适度性:规则数量适中,过多会导致模型注意力分散
  • 优先级:重要的规则放在前面,因为模型对 Prompt 开头的注意力权重更高

2.3.2 Tool Definitions

工具定义让 Agent 从纯文本生成器升级为能够与外部世界交互的行动者,通常以 JSON Schema 格式描述:

{
  "type": "function",
  "function": {
    "name": "search_codebase",
    "description": "通过语义搜索在代码库中查找代码",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "自然语言搜索查询"
        },
        "max_results": {
          "type": "integer",
          "description": "最大返回结果数",
          "default": 5
        }
      },
      "required": ["query"]
    }
  }
}

工具定义的质量直接影响模型的调用决策。好的工具定义应包含:

  • 清晰的命名:函数名自解释,模型能从名称推断用途
  • 详尽的描述:说明"什么时候用"和"怎么用"
  • 完整的参数说明:每个参数的含义、类型、是否必需、默认值
  • 返回值说明:模型需要知道调用后能获得什么

2.3.3 Conversation History

对话历史是多轮交互的核心载体。每一轮对话通常以 User-Assistant 消息对的形式追加到历史中。

sequenceDiagram
    participant U as 用户
    participant A as Agent

    U->>A: 第一轮用户消息
    A->>U: 第一轮 Agent 回复
    U->>A: 第二轮用户消息
    A->>U: 第二轮 Agent 回复
    U->>A: 第三轮用户消息(当前轮)
    Note over A: 模型看到完整历史 + 当前消息
    A->>U: 第三轮 Agent 回复

注意:并非所有历史消息都需要完整保留。随着对话轮次增加,历史消息会消耗大量 Token,需要配合上下文压缩策略使用。

2.3.4 Injected Context

注入上下文是指在运行时动态插入到消息列表中的外部信息,常见的注入来源有:

  • RAG 检索结果:从知识库中检索与当前问题相关的文档片段
  • 文件内容:当前编辑的文件、项目配置文件等
  • 环境信息:操作系统、运行时版本、环境变量等

注入位置通常选择 System Prompt 之后、对话历史之前,以确保这些信息具有较高的注意力权重。

2.3.5 工具返回结果(Tool Returns)

工具返回结果是 Agent 与外部系统交互后获得的数据,以 tool 角色的消息存在于上下文之中,是多步推理和任务推进的核心驱动力。

消息结构

{
  "role": "tool",
  "tool_call_id": "call_3c4d5e",
  "content": "搜索结果: 在 src/auth/login.ts 中找到登录逻辑..."
}

在上下文中的位置

工具返回结果紧跟在触发它的 assistant 消息之后,形成 assistant → tool → assistant 的交替序列。这种结构使模型能够基于工具返回的数据进行下一步推理。

flowchart LR
    A1[&#34;assistant<br/>发起工具调用&#34;] --> T1[&#34;tool<br/>返回结果数据&#34;]
    T1 --> A2[&#34;assistant<br/>基于结果继续推理&#34;]
    A2 --> T2[&#34;tool<br/>再次返回结果&#34;]
    T2 --> A3[&#34;assistant<br/>生成最终回复&#34;]

    style A1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style T1 fill:#e65100,stroke:#bf360c,color:#ffffff
    style A2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style T2 fill:#e65100,stroke:#bf360c,color:#ffffff
    style A3 fill:#1565c0,stroke:#0d47a1,color:#ffffff

Token 消耗问题

工具返回结果往往是上下文 Token 消耗的主要来源之一。一次数据库查询或文件读取可能返回数千 Token 的原始数据。控制手段包括:

  • 截断返回数据:在将结果注入上下文前,截取前 N 个字符或关键片段
  • 结构化摘要:对工具返回的 JSON 数据做字段筛选,只保留模型需要的字段
  • 分页加载:对于大量数据,分批返回并在模型确认需要时才加载更多

多工具并行调用的上下文排列

当 Agent 在同一轮次并行调用多个工具时,所有工具返回消息按调用顺序排列在 assistant 消息之后:

assistant: 同时调用 search_codebase 和 read_file
tool: search_codebase 的返回结果
tool: read_file 的返回结果
assistant: 基于两个工具的结果生成回复

2.3.6 Skills(技能模块)

Skills 是可加载的专项能力模块,用于扩展 Agent 在特定领域的行为能力。与工具定义描述"能用什么工具"不同,Skills 定义的是"怎么完成某类任务"的完整工作流。

Skill 的结构

一个 Skill 通常包含这些组成部分:

# Skill: frontend-design

## 描述
创建高质量的前端界面组件,适用于网页、Dashboard、Landing Page 等场景。

## 触发条件
当用户请求构建前端界面、设计网页、创建 UI 组件时触发。

## 工作流程
1. 分析用户需求,确定界面类型和功能
2. 选择合适的布局方案和技术栈
3. 生成完整的 HTML/CSS/JS 代码
4. 确保响应式设计和浏览器兼容性
5. 提供预览和交互说明

## 输出规范
- 使用语义化 HTML 标签
- CSS 类名使用 BEM 命名规范
- 代码包含详细的中文注释
- 支持主流浏览器(Chrome、Firefox、Safari)

## 约束
- 不引入不必要的第三方依赖
- 确保可访问性(a11y)达标
- 移动端优先的响应式设计

Skill 在上下文中的位置

Skill 内容注入到 System Prompt 之后、对话历史之前,与工具定义同属静态上下文,但 Skill 侧重于任务流程和行为规范的定义。在消息列表中的排列顺序为:

System Prompt → Tool Definitions → Skills → 对话历史 → 当前用户消息

Skill 的加载机制

Skill 并非全部加载到上下文中,而是根据当前任务动态选择:

flowchart TD
    U[&#34;用户输入&#34;] --> A[&#34;分析任务类型&#34;]
    A --> M[&#34;匹配 Skills 注册列表&#34;]
    M --> D{&#34;是否有匹配 Skill?&#34;}
    D -- &#34;是&#34; --> L[&#34;加载 Skill 内容到上下文&#34;]
    D -- &#34;否&#34; --> N[&#34;使用基础上下文&#34;]
    L --> R[&#34;Agent 按 Skill 流程执行&#34;]
    N --> R

    style U fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style M fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D fill:#e65100,stroke:#bf360c,color:#ffffff
    style L fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style N fill:#c62828,stroke:#b71c1c,color:#ffffff
    style R fill:#2e7d32,stroke:#1b5e20,color:#ffffff

Skill 与工具的关系

维度工具(Tool)Skill(技能)
定义内容函数签名、参数、返回值工作流程、行为规范、输出标准
作用层面原子操作(读文件、执行命令)任务流程(完成一类完整任务)
粒度单个函数多步骤工作流
类比一把螺丝刀一本装修手册
上下文占用每个工具定义较小每个 Skill 内容较大

Skill 通常会声明自己需要调用哪些工具,从而将两者串联起来。例如,frontend-design Skill 会指定需要使用 write_fileread_file 等工具来完成界面创建任务。


3. 上下文生命周期

3.1 生命周期阶段

一条消息从创建到进入模型上下文,经历这些阶段:

flowchart LR
    A[&#34;消息创建&#34;] --> B[&#34;消息格式化&#34;]
    B --> C[&#34;Token 估算&#34;]
    C --> D{&#34;是否超出窗口?&#34;}
    D -- &#34;否&#34; --> E[&#34;直接追加到上下文&#34;]
    D -- &#34;是&#34; --> F[&#34;触发上下文压缩&#34;]
    F --> G[&#34;压缩后重新检查&#34;]
    G --> E
    E --> H[&#34;送入模型推理&#34;]
    H --> I[&#34;生成响应&#34;]
    I --> J{&#34;是否需要工具调用?&#34;}
    J -- &#34;是&#34; --> K[&#34;执行工具 → 结果注入上下文&#34;]
    K --> B
    J -- &#34;否&#34; --> L[&#34;响应返回给用户&#34;]

    style A fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D fill:#e65100,stroke:#bf360c,color:#ffffff
    style E fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style F fill:#c62828,stroke:#b71c1c,color:#ffffff
    style G fill:#c62828,stroke:#b71c1c,color:#ffffff
    style H fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style I fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style J fill:#e65100,stroke:#bf360c,color:#ffffff
    style K fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style L fill:#2e7d32,stroke:#1b5e20,color:#ffffff

3.2 会话级生命周期

从整个会话的角度看,上下文经历初始化、增长、稳定和衰减四个阶段:

graph LR
    subgraph phase1[&#34;初始化阶段&#34;]
        I1[&#34;构建 System Prompt&#34;]
        I2[&#34;注入工具定义&#34;]
        I2b[&#34;加载匹配的 Skills&#34;]
        I3[&#34;添加初始上下文&#34;]
    end

    subgraph phase2[&#34;增长阶段&#34;]
        G1[&#34;追加用户消息&#34;]
        G2[&#34;追加 Agent 回复&#34;]
        G3[&#34;追加工具结果&#34;]
        G4[&#34;Token 持续增长&#34;]
    end

    subgraph phase3[&#34;稳定阶段&#34;]
        S1[&#34;触发压缩策略&#34;]
        S2[&#34;摘要替代原文&#34;]
        S3[&#34;Token 维持稳定&#34;]
    end

    subgraph phase4[&#34;衰减阶段&#34;]
        D1[&#34;上下文窗口滑动&#34;]
        D2[&#34;早期消息被截断&#34;]
        D3[&#34;仅保留核心信息&#34;]
    end

    I1 --> I2 --> I2b --> I3
    I3 --> G1
    G1 --> G2 --> G3 --> G4
    G4 --> S1
    S1 --> S2 --> S3
    S3 --> D1
    D1 --> D2 --> D3

    style phase1 fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style I1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style I2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style I2b fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style I3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style phase2 fill:#0d47a1,stroke:#002171,color:#ffffff
    style G1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style G2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style G3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style G4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style phase3 fill:#1b5e20,stroke:#2e7d32,color:#ffffff
    style S1 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style S2 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style S3 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style phase4 fill:#4a148c,stroke:#38006b,color:#ffffff
    style D1 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style D2 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style D3 fill:#6a1b9a,stroke:#4a148c,color:#ffffff

3.3 关键指标

在整个生命周期中,需要持续监控以下指标:

指标说明警戒值
Token 使用量当前上下文的 Token 总数窗口容量的 80%
消息轮次对话历史中的轮次数视任务复杂度而定
压缩触发次数上下文压缩被触发的频率频繁触发说明窗口偏小
信息保留率压缩后保留的信息比例低于 60% 说明压缩过度

4. System Prompt 构成

4.1 System Prompt 层次结构

System Prompt 不是一段扁平的文本,而是具有层次结构的信息组织:

flowchart TD
    SP[&#34;System Prompt&#34;] --> L1[&#34;身份层&#34;]
    SP --> L2[&#34;能力层&#34;]
    SP --> L3[&#34;行为层&#34;]
    SP --> L4[&#34;输出层&#34;]
    SP --> L5[&#34;安全层&#34;]

    L1 --> L1A[&#34;角色定义&#34;]
    L1 --> L1B[&#34;领域知识范围&#34;]

    L2 --> L2A[&#34;可调用的工具&#34;]
    L2 --> L2B[&#34;可用的资源&#34;]

    L3 --> L3A[&#34;工作流程&#34;]
    L3 --> L3B[&#34;决策规则&#34;]
    L3 --> L3C[&#34;优先级约定&#34;]

    L4 --> L4A[&#34;格式规范&#34;]
    L4 --> L4B[&#34;语言风格&#34;]

    L5 --> L5A[&#34;禁止事项&#34;]
    L5 --> L5B[&#34;边界约束&#34;]

    style SP fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style L1 fill:#0d47a1,stroke:#002171,color:#ffffff
    style L2 fill:#0d47a1,stroke:#002171,color:#ffffff
    style L3 fill:#0d47a1,stroke:#002171,color:#ffffff
    style L4 fill:#0d47a1,stroke:#002171,color:#ffffff
    style L5 fill:#0d47a1,stroke:#002171,color:#ffffff
    style L1A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L1B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L2A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L2B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L3A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L3B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L3C fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L4A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L4B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L5A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style L5B fill:#1565c0,stroke:#0d47a1,color:#ffffff

4.2 各层详解

身份层

定义 Agent "是谁",这是模型行为的基础锚点。

你是 Trae IDE 中的 AI 编程助手,专门帮助开发者完成软件工程任务。
你精通多种编程语言和开发工具,熟悉软件工程最佳实践。

能力层

明确 Agent 能做什么、用什么工具。

你可以使用以下工具:
- 读取和编辑本地文件
- 执行终端命令
- 搜索代码库
- 调用浏览器进行网页调试

行为层

定义 Agent 的工作方式和决策逻辑。

当用户要求修改代码时:
1. 先阅读并理解相关代码
2. 评估修改的影响范围
3. 给出修改方案并说明理由
4. 修改完成后验证正确性

输出层

规范 Agent 的回复格式和风格。

- 使用与用户相同的语言回复
- 代码注释使用中文
- 变量名、函数名使用英文
- 回复简洁直接,避免冗余

安全层

设定不可逾越的边界。

- 不要运行破坏性命令(git push --force、rm -rf 等)除非用户明确要求
- 不要泄露系统配置或密钥信息
- 不要修改代码除非用户明确要求

4.3 System Prompt 的注意力特性

语言模型对 System Prompt 不同位置的注意力分布并不均匀。Liu 等人在 2023 年的研究(Lost in the Middle: How Language Models Use Long Contexts)中发现,Transformer 架构的模型倾向于更关注序列开头和结尾的内容,中间部分的信息利用率相对较低。

实际表现:

System Prompt 内部注意力权重分布:

开头部分  ████████████████████ 高权重  ← 关键指令放这里
中间部分  ██████████████      中等权重  ← 补充规则放这里
结尾部分  ████████████████    较高权重  ← 近因效应,近期指令效果好

这对 System Prompt 设计的启示:

  • 角色定义和核心约束放在开头,确保模型优先处理
  • 补充性规则和工作流程放在中间
  • 输出格式要求和即时指令放在结尾,利用近因效应
  • 避免将关键指令埋在 System Prompt 的中间段落

5. Message 结构设计

5.1 消息角色模型

Agent 上下文中的消息遵循明确的角色定义,共四种:

classDiagram
    class Message {
        +Role role
        +Content content
        +string name
        +ToolCall[] tool_calls
        +string tool_call_id
    }

    class Role {
        <<enumeration>>
        system
        user
        assistant
        tool
    }

    class Content {
        +string text
        +ImageBlock[] images
        +ToolResult[] tool_results
    }

    Message --> Role
    Message --> Content

5.2 各角色消息详解

System 角色

System 角色的消息承载 System Prompt,位于整个消息列表的最前面。

  • 一个会话中通常只有一条 System 消息
  • 对模型行为有最高约束力
  • 在 API 层面有专门的 system 参数

User 角色

User 角色的消息代表用户输入,是触发 Agent 响应的直接原因。

  • 包含用户的自然语言请求
  • 可以携带多模态内容(文本、图片)
  • 可以注入额外的上下文信息

Assistant 角色

Assistant 角色的消息是模型的输出。

  • 包含模型的文本回复
  • 可以包含一个或多个工具调用请求
  • 在多轮对话中作为历史上下文保留

Tool 角色

Tool 角色的消息承载工具执行结果。

  • tool_call_id 字段关联到对应的 Assistant 消息中的工具调用
  • 包含工具返回的数据
  • 为模型提供执行反馈,支持多步推理

5.3 典型消息序列

一次完整的工具调用循环中的消息序列:

sequenceDiagram
    participant API as API 层
    participant M as 模型

    API->>M: [System] 角色定义 + 工具列表
    API->>M: [User] 帮我搜索代码库中的登录逻辑
    M->>API: [Assistant] 我来搜索 + tool_call(search_codebase)
    API->>M: [Tool] 搜索结果: 找到3个相关文件
    M->>API: [Assistant] 找到以下文件...
    API->>M: [User] 帮我修改第一个文件的密码验证逻辑
    M->>API: [Assistant] 我先读取文件 + tool_call(read_file)
    API->>M: [Tool] 文件内容: ...
    M->>API: [Assistant] 我来修改...

5.4 多模态消息结构

现代 Agent 上下文支持多模态内容。一条 User 消息可以同时包含文本和图片:

{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "请分析这个架构图并给出改进建议"
    },
    {
      "type": "image_url",
      "url": "https://example.com/architecture.png"
    }
  ]
}

多模态内容的排列顺序影响模型的理解:通常文本在前、图片在后,让模型先理解任务目标,再处理视觉信息。


6. 上下文窗口管理

6.1 上下文窗口的概念

上下文窗口(Context Window)是模型在一次推理中能够处理的最大 Token 数量,由模型架构决定,不同模型的窗口大小差异显著。

上下文窗口容量对比(截至 2026 年初):

Claude 3.5 Sonnet  ████████████████████████████████████████████████████████████████ 200K
GPT-4o           ██████████████████████████████████████████████ 128K
GPT-4 Turbo      ██████████████████████████████████████████████ 128K
DeepSeek-V3      ██████████████████████████████████████████████ 128K
Gemini 2.0 Flash ████████████████████████████████████████████████████████████████████████████████████████ 1M+
Qwen-2.5         ██████████████████████████████████████████████████████ 128K

窗口容量会随模型版本迭代变化,以上数据供量级参考。实际部署时应以官方文档为准。

6.2 Token 计算规则

上下文的 Token 消耗来自多个部分:

pie showData
    title Token 消耗分布(典型场景)
    &#34;System Prompt&#34; : 8
    &#34;Skills&#34; : 7
    &#34;工具定义&#34; : 5
    &#34;对话历史&#34; : 40
    &#34;当前用户消息&#34; : 5
    &#34;工具执行结果&#34; : 20
    &#34;Injected Context&#34; : 10
    &#34;输出缓冲&#34; : 5

Token 计算的关键规则

  • 英文:1 个 Token 约等于 0.75 个单词
  • 中文:1 个汉字约等于 1-2 个 Token
  • 代码:由于特殊字符和缩进,Token 密度介于中英文之间
  • JSON:括号、逗号等符号都会产生额外 Token
  • 消息格式:每条消息的 role、content 等字段都会产生结构性 Token 开销

6.3 窗口溢出的处理

当上下文超出窗口容量时,有这几种处理策略:

flowchart TD
    A[&#34;Token 估算完成&#34;] --> B{&#34;是否超出窗口?&#34;}
    B -- &#34;否&#34; --> C[&#34;直接使用&#34;]
    B -- &#34;是&#34; --> D{&#34;溢出处理策略&#34;}

    D -- &#34;截断策略&#34; --> E[&#34;从最早的消息开始截断&#34;]
    D -- &#34;压缩策略&#34; --> F[&#34;对早期消息做摘要&#34;]
    D -- &#34;滑动窗口&#34; --> G[&#34;保留最近 N 轮对话&#34;]
    D -- &#34;分层策略&#34; --> H[&#34;按重要性分层处理&#34;]

    E --> I[&#34;重新计算 Token&#34;]
    F --> I
    G --> I
    H --> I
    I --> J{&#34;是否仍然超出?&#34;}
    J -- &#34;否&#34; --> C
    J -- &#34;是&#34; --> D

    style A fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style B fill:#e65100,stroke:#bf360c,color:#ffffff
    style C fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style D fill:#e65100,stroke:#bf360c,color:#ffffff
    style E fill:#c62828,stroke:#b71c1c,color:#ffffff
    style F fill:#c62828,stroke:#b71c1c,color:#ffffff
    style G fill:#c62828,stroke:#b71c1c,color:#ffffff
    style H fill:#c62828,stroke:#b71c1c,color:#ffffff
    style I fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style J fill:#e65100,stroke:#bf360c,color:#ffffff

各策略的优缺点对比:

策略优点缺点适用场景
截断实现简单、可控丢失历史信息短对话场景
摘要压缩保留语义信息摘要可能丢失细节长对话场景
滑动窗口保留最近的交互完全丢失早期信息上下文无关的对话
分层策略精细控制、信息损失最小实现复杂复杂 Agent 系统

7. 上下文注入机制

7.1 注入时机与位置

上下文注入是指在 Agent 运行过程中,将外部信息动态插入到消息流中的过程。注入的时机和位置对效果有重要影响。

flowchart LR
    subgraph position[&#34;注入位置&#34;]
        P1[&#34;位置1: System Prompt 内<br/>静态知识(会话初始化)&#34;]
        P1b[&#34;位置1b: Skills<br/>静态技能(会话初始化)&#34;]
        P2[&#34;位置2: System 与 User 之间<br/>动态上下文&#34;]
        P3[&#34;位置3: User 消息末尾<br/>补充信息&#34;]
        P4[&#34;位置4: 工具执行结果<br/>运行时数据&#34;]
    end

    P1 -.-> N1[&#34;会话初始化时&#34;]
    P1b -.-> N1b[&#34;会话初始化时<br/>根据任务匹配加载&#34;]
    P2 -.-> N2[&#34;每轮推理前&#34;]
    P3 -.-> N3[&#34;用户消息构造时&#34;]
    P4 -.-> N4[&#34;工具执行后&#34;]

    style position fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style P1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P1b fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style P2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style N1 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style N1b fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style N2 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style N3 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style N4 fill:#2e7d32,stroke:#1b5e20,color:#ffffff

7.2 静态注入(System Prompt 内嵌)

静态注入将固定知识直接写入 System Prompt,适用于不会频繁变化的信息。

适用内容

  • 角色定义和行为规则
  • 固定的专业知识(如 API 文档摘要)
  • 输出格式模板
  • 工具定义
  • Skills(技能模块内容)

优点:实现简单、延迟低、Token 开销固定

缺点:不适用于大量或动态变化的信息,会增加每次推理的固定 Token 消耗

7.3 动态注入(RAG 模式)

动态注入通过检索增强生成(RAG)的方式,在推理前从知识库中检索相关信息并注入上下文。

flowchart LR
    Q[&#34;用户问题&#34;] --> E[&#34;Embedding 编码&#34;]
    E --> S[&#34;向量相似度搜索&#34;]
    K[&#34;知识库&#34;] --> S
    S --> R[&#34;检索结果 Top-K&#34;]
    C[&#34;上下文拼接&#34;] --> R
    C --> M[&#34;模型推理&#34;]
    Q --> C

    style Q fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style E fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style S fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style K fill:#4a148c,stroke:#38006b,color:#ffffff
    style R fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style M fill:#e65100,stroke:#bf360c,color:#ffffff

检索流程详解

  1. 问题编码:将用户问题通过 Embedding 模型转换为向量表示
  2. 相似度搜索:在向量数据库中检索与问题最相关的文档片段
  3. 重排序:对初步检索结果进行精排,提高相关性
  4. 上下文拼接:将排序后的结果按模板格式拼接,注入到消息流中

动态注入的 Token 控制

  • 设定最大注入 Token 数,避免检索结果占用过多窗口
  • 对检索结果做摘要,减少 Token 消耗
  • 设置相关性阈值,低于阈值的结果不注入

7.4 环境注入

环境注入将运行时环境信息提供给 Agent,使其能够基于真实环境做决策。

典型的环境注入内容:

[环境信息]
操作系统: Windows 10 Pro
工作目录: d:\codex\me
当前时间: 2026-06-12 14:30:00
Git 分支: main
Git 状态: 有 2 个未提交的修改文件

环境注入的关键是信息粒度——提供足够的信息帮助 Agent 做决策,但不过度注入无关细节。

7.5 注入优先级

当多种注入内容同时存在时,需要确定优先级:

flowchart TD
    subgraph priority[&#34;优先级层次&#34;]
        PR1[&#34;最高: 安全约束(System Prompt 内)&#34;]
        PR2[&#34;高: 工具定义 + Skills&#34;]
        PR3[&#34;中: 动态检索结果&#34;]
        PR4[&#34;中低: 环境信息&#34;]
        PR5[&#34;最低: 补充元数据&#34;]
    end

    style priority fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style PR1 fill:#b71c1c,stroke:#880e4f,color:#ffffff
    style PR2 fill:#e65100,stroke:#bf360c,color:#ffffff
    style PR3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style PR4 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style PR5 fill:#6a1b9a,stroke:#4a148c,color:#ffffff

8. 上下文压缩策略

8.1 压缩的必要性

随着对话轮次增加,上下文会持续膨胀。一个典型的长对话可能在 50 轮后消耗超过 100K Token。压缩是维持 Agent 长期运行能力的关键。

Token 增长趋势(无压缩):

轮次  1  5  10  15  20  30  50
Token ████ ████████████████████████████████████████████████
      ↑    ↑              ↑              ↑
      正常  开始紧张       频繁溢出       不可用

8.2 压缩策略分类

flowchart TD
    COMP[&#34;上下文压缩策略&#34;] --> C1[&#34;摘要压缩&#34;]
    COMP --> C2[&#34;选择性保留&#34;]
    COMP --> C3[&#34;结构化压缩&#34;]
    COMP --> C4[&#34;层级压缩&#34;]

    C1 --> C1A[&#34;LLM 摘要<br/>用模型生成对话摘要&#34;]
    C1 --> C1B[&#34;聚类摘要<br/>按主题聚类后分别摘要&#34;]

    C2 --> C2A[&#34;保留最近 N 轮<br/>丢弃早期对话&#34;]
    C2 --> C2B[&#34;保留关键轮次<br/>基于重要性评分&#34;]
    C2 --> C2C[&#34;保留锚点消息<br/>始终保留 System、Skills 和关键 User 消息&#34;]

    C3 --> C3A[&#34;提取实体<br/>提取对话中的关键实体和关系&#34;]
    C3 --> C3B[&#34;提取决策<br/>提取已做出的关键决策&#34;]

    C4 --> C4A[&#34;短期记忆<br/>最近几轮完整保留&#34;]
    C4 --> C4B[&#34;中期记忆<br/>近期对话摘要&#34;]
    C4 --> C4C[&#34;长期记忆<br/>持久化到外部存储&#34;]

    style COMP fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style C1 fill:#0d47a1,stroke:#002171,color:#ffffff
    style C2 fill:#0d47a1,stroke:#002171,color:#ffffff
    style C3 fill:#0d47a1,stroke:#002171,color:#ffffff
    style C4 fill:#0d47a1,stroke:#002171,color:#ffffff
    style C1A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C1B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C2A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C2B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C2C fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C3A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C3B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C4A fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C4B fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C4C fill:#1565c0,stroke:#0d47a1,color:#ffffff

8.3 摘要压缩详解

摘要压缩是最常用的策略,其核心思想是用一段精简的摘要替代原始的对话历史。

摘要生成流程

sequenceDiagram
    participant AC as 上下文管理器
    participant LLM as 语言模型

    AC->>AC: 检测 Token 超过阈值
    AC->>LLM: 发送对话历史 + 摘要指令
    Note over LLM: 生成结构化摘要
    LLM->>AC: 返回摘要文本
    AC->>AC: 替换原始历史为摘要
    Note over AC: 保留: System Prompt + 摘要 + 最近 N 轮

8.4 选择性保留策略

并非所有消息都同等重要。选择性保留策略根据消息的重要性评分决定保留或丢弃。

重要性评分维度

维度高重要性低重要性
消息类型User 指令、关键决策工具调用细节、中间过程
信息密度包含新信息、新约束重复信息、确认性回复
时效性最近的对话很早的对话
关联性与当前任务直接相关与当前任务无关

8.5 层级压缩架构

模仿人类记忆的三级模型,层级压缩将上下文分为三个层次:

flowchart TD
    subgraph working[&#34;工作记忆(Working Memory)&#34;]
        W1[&#34;当前轮完整上下文&#34;]
        W2[&#34;最近 N 轮完整消息&#34;]
        W3[&#34;Token 预算: ~20%&#34;]
    end

    subgraph short[&#34;短期记忆(Short-Term Memory)&#34;]
        S1[&#34;近期对话摘要&#34;]
        S2[&#34;活跃实体和状态&#34;]
        S3[&#34;Token 预算: ~15%&#34;]
    end

    subgraph long[&#34;长期记忆(Long-Term Memory)&#34;]
        L1[&#34;持久化存储(向量数据库/文件)&#34;]
        L2[&#34;按需检索注入&#34;]
        L3[&#34;Token 预算: ~10%&#34;]
    end

    W1 & W2 & W3 --> M[&#34;模型推理&#34;]
    S1 & S2 & S3 --> M
    L1 & L2 & L3 --> M

    style working fill:#0d47a1,stroke:#002171,color:#ffffff
    style W1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style W2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style W3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style short fill:#1b5e20,stroke:#2e7d32,color:#ffffff
    style S1 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style S2 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style S3 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style long fill:#311b92,stroke:#1a005c,color:#ffffff
    style L1 fill:#4527a0,stroke:#311b92,color:#ffffff
    style L2 fill:#4527a0,stroke:#311b92,color:#ffffff
    style L3 fill:#4527a0,stroke:#311b92,color:#ffffff
    style M fill:#e65100,stroke:#bf360c,color:#ffffff

9. 上下文与记忆系统

9.1 记忆层次模型

Agent 的记忆系统分为三个层次,与上下文形成互补关系:

flowchart LR
    subgraph context[&#34;上下文(模型可见)&#34;]
        C1[&#34;当前推理窗口内的信息&#34;]
    end

    subgraph memory[&#34;记忆系统(按需检索)&#34;]
        M1[&#34;会话记忆<br/>当前任务相关&#34;]
        M2[&#34;工作记忆<br/>项目级持久化&#34;]
        M3[&#34;长期记忆<br/>跨会话知识&#34;]
    end

    C1 <--> M1
    M1 --> M2
    M2 --> M3

    style context fill:#e65100,stroke:#bf360c,color:#ffffff
    style C1 fill:#ef6c00,stroke:#e65100,color:#ffffff
    style memory fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style M1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style M2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style M3 fill:#1565c0,stroke:#0d47a1,color:#ffffff

9.2 会话记忆

会话记忆存储当前任务执行过程中的状态信息。

存储内容

  • 任务进度和中间状态
  • 已确认的用户偏好
  • 已做出的关键决策
  • 错误和纠正记录

实现方式

会话记忆(内存数据结构):
{
  "task": "代码重构",
  "progress": "已完成模块 A,正在处理模块 B",
  "decisions": [
    "使用策略模式替代条件分支",
    "保留向后兼容的 API"
  ],
  "errors": [
    "模块 C 的单元测试失败,已修复"
  ]
}

生命周期管理

  • 写入时机:每轮对话结束后,从 Agent 回复中提取关键信息(决策、错误、进度更新)写入会话记忆。不需要每轮都写入,仅在检测到状态变更时更新。
  • 读取时机:新一轮推理开始前,将会话记忆内容注入到 System Prompt 之后,为模型提供任务进展上下文。
  • 过期策略:会话记忆与会话生命周期绑定,会话结束时归档到工作记忆(9.3),同时清除内存中的会话记忆数据。
  • 与上下文窗口的配合:会话记忆的体积通常只有几百 Token,远小于对话历史。当上下文压缩触发时,会话记忆作为锚点信息始终保留,不会被压缩或丢弃。

9.3 工作记忆

工作记忆是项目级别的持久化记忆,跨多个会话存在。

存储位置

  • 项目根目录的配置文件(如 .cursorrules.github/copilot-instructions.md
  • 向量数据库中的项目知识图谱
  • 文件系统中的重要文档

检索机制

flowchart LR
    Q[&#34;当前任务/问题&#34;] --> E[&#34;编码&#34;]
    E --> V[&#34;向量检索&#34;]
    DB[(&#34;向量数据库<br/>项目知识库&#34;)] --> V
    V --> R[&#34;相关记忆片段&#34;]
    R --> I[&#34;注入上下文&#34;]

    style Q fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style E fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style V fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style DB fill:#4a148c,stroke:#38006b,color:#ffffff
    style R fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style I fill:#2e7d32,stroke:#1b5e20,color:#ffffff

9.4 长期记忆

长期记忆存储跨会话的通用知识和用户偏好。

典型内容

  • 用户编码风格偏好
  • 常用技术栈和框架约定
  • 历史项目中的经验教训
  • 团队成员的角色和职责

长期记忆的维护

flowchart LR
    subgraph write[&#34;写入&#34;]
        A1[&#34;会话结束&#34;] --> A2[&#34;提取关键信息&#34;]
        A2 --> A3[&#34;去重和合并&#34;]
        A3 --> A4[&#34;写入存储&#34;]
    end

    subgraph read[&#34;读取&#34;]
        B1[&#34;新会话开始&#34;] --> B2[&#34;检索相关记忆&#34;]
        B2 --> B3[&#34;注入 System Prompt&#34;]
    end

    subgraph clean[&#34;清理&#34;]
        C1[&#34;定期审查&#34;] --> C2[&#34;标记过期信息&#34;]
        C2 --> C3[&#34;归档或删除&#34;]
    end

    style write fill:#1b5e20,stroke:#2e7d32,color:#ffffff
    style A1 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style A2 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style A3 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style A4 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style read fill:#0d47a1,stroke:#002171,color:#ffffff
    style B1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style B2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style B3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style clean fill:#311b92,stroke:#1a005c,color:#ffffff
    style C1 fill:#4527a0,stroke:#311b92,color:#ffffff
    style C2 fill:#4527a0,stroke:#311b92,color:#ffffff
    style C3 fill:#4527a0,stroke:#311b92,color:#ffffff

10. 工程实践

10.1 上下文构建流程

在实际工程中,一条完整的 Agent 上下文经过以下构建步骤:

flowchart TD
    START([&#34;开始构建上下文&#34;]) --> A1[&#34;加载 System Prompt 模板&#34;]
    A1 --> A2[&#34;注入角色和规则&#34;]
    A2 --> A3[&#34;加载工具定义&#34;]
    A3 --> A4[&#34;匹配并加载 Skills&#34;]
    A4 --> A5[&#34;拼接静态部分&#34;]

    A5 --> B1[&#34;检查是否有检索需求&#34;]
    B1 -- &#34;有&#34; --> B2[&#34;执行 RAG 检索&#34;]
    B2 --> B3[&#34;将结果注入上下文&#34;]
    B1 -- &#34;无&#34; --> B4[&#34;跳过检索&#34;]
    B3 --> C1
    B4 --> C1

    C1 --> C2[&#34;追加对话历史&#34;]
    C2 --> C3[&#34;追加当前用户消息&#34;]
    C3 --> C4[&#34;注入环境信息&#34;]

    C4 --> D1[&#34;计算总 Token 数&#34;]
    D1 --> D2{&#34;是否超出限制?&#34;}
    D2 -- &#34;是&#34; --> D3[&#34;执行压缩策略&#34;]
    D3 --> D1
    D2 -- &#34;否&#34; --> E1[&#34;上下文构建完成&#34;]
    E1 --> END([&#34;送入模型推理&#34;])

    style START fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style A1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A4 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style A5 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style B1 fill:#e65100,stroke:#bf360c,color:#ffffff
    style B2 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style B3 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style B4 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style C1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style C4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D2 fill:#e65100,stroke:#bf360c,color:#ffffff
    style D3 fill:#c62828,stroke:#b71c1c,color:#ffffff
    style E1 fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style END fill:#2e7d32,stroke:#1b5e20,color:#ffffff

10.2 上下文模板(Context Template)

在实际工程中,上下文通常通过模板引擎组装,而非硬编码拼接。上下文模板定义了各组件的占位符、排列顺序和条件渲染规则,是上下文工程的核心实践。

模板结构示例

{{#system}}
  {{role_definition}}
  {{behavior_rules}}
  {{output_format}}
  {{constraints}}
{{/system}}

{{#tools}}
  {{tool_definitions}}
{{/tools}}

{{#skills}}
  {{loaded_skills_content}}
{{/skills}}

{{#injected_context}}
  {{environment_info}}
  {{rag_results}}
  {{file_contents}}
{{/injected_context}}

{{#history}}
  {{conversation_history}}
{{/history}}

{{current_user_message}}

模板渲染规则

  1. 条件渲染{{#skills}} 区块仅在匹配到 Skill 时渲染,否则整个区块为空
  2. 顺序固定:模板中组件的排列顺序决定了最终上下文的排列顺序,直接影响注意力分布
  3. 占位符替换:每个 {{placeholder}} 在运行时被实际内容替换,替换后进行 Token 估算
  4. 截断保护:模板可设置每个区块的最大 Token 超限时自动截断并添加标记
flowchart LR
    T[&#34;模板定义<br/>占位符 + 条件 + 顺序&#34;] --> R[&#34;运行时渲染&#34;]
    R --> P1[&#34;替换 System Prompt&#34;]
    R --> P2[&#34;替换工具定义&#34;]
    R --> P3[&#34;条件渲染 Skills&#34;]
    R --> P4[&#34;替换注入上下文&#34;]
    R --> P5[&#34;追加历史消息&#34;]
    P1 & P2 & P3 & P4 & P5 --> A[&#34;组装完成&#34;]
    E[&#34;Token 估算&#34;] --> A
    A --> C{&#34;是否超限?&#34;}
    C -- &#34;是&#34; --> TR[&#34;按优先级截断&#34;]
    C -- &#34;否&#34; --> F[&#34;最终上下文&#34;]
    TR --> F

    style T fill:#1a237e,stroke:#0d47a1,color:#ffffff
    style R fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P3 fill:#6a1b9a,stroke:#4a148c,color:#ffffff
    style P4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style P5 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style A fill:#2e7d32,stroke:#1b5e20,color:#ffffff
    style E fill:#e65100,stroke:#bf360c,color:#ffffff
    style C fill:#e65100,stroke:#bf360c,color:#ffffff
    style TR fill:#c62828,stroke:#b71c1c,color:#ffffff
    style F fill:#2e7d32,stroke:#1b5e20,color:#ffffff

模板与硬编码拼接的对比

维度模板引擎硬编码拼接
可维护性修改模板无需改动代码每次修改需要改动代码
灵活性支持条件渲染、循环、嵌套逻辑固定,难以动态调整
可测试性可独立测试模板渲染结果需完整运行流程才能验证
团队协作产品/设计师可独立编辑模板仅开发者可修改
复杂度需要模板引擎基础设施实现简单

10.3 Token 预算分配

在上下文窗口有限的情况下,合理的 Token 预算分配至关重要。

典型预算分配方案(以 128K 窗口为例)

pie showData
    title Token 预算分配(128K 窗口示例)
    &#34;System Prompt + 工具定义&#34; : 6000
    &#34;Skills&#34; : 7000
    &#34;动态注入(RAG等)&#34; : 10000
    &#34;对话历史&#34; : 55000
    &#34;当前用户消息&#34; : 5000
    &#34;工具执行结果&#34; : 20000
    &#34;输出缓冲&#34; : 25000

预算分配原则

  • System Prompt 和工具定义作为固定开销,精确控制
  • 动态注入设置上限,防止单次检索结果过大
  • 对话历史是最大的变动部分,需要预留充足空间
  • 输出缓冲区不能过小,否则会截断 Agent 的长回复

10.4 上下文调试

上下文调试是 Agent 开发中的重要环节。以下是常用的调试方法:

10.4.1 上下文快照

在关键节点保存上下文的完整快照,用于事后分析:

{
  "timestamp": "2026-06-12T14:30:00Z",
  "turn": 5,
  "token_count": 45000,
  "messages": [
    {
      "role": "system",
      "content_preview": "你是 Trae IDE 中的 AI 编程助手,专门帮助开发者完成软件工程任务...",
      "token_count": 2000
    },
    {
      "role": "user",
      "content_preview": "请审查 src/auth/login.ts 中的密码验证逻辑,重点关注安全性...",
      "token_count": 3000
    }
  ]
}

10.4.2 Token 监控面板

建立实时的 Token 监控,追踪上下文使用趋势:

┌─────────────────────────────────────────────┐
│ 上下文 Token 使用监控                         │
├─────────────────────────────────────────────┤
│ 当前使用: 45,000 / 128,000 (35%)             │
│ ████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│                                             │
│ 本轮消耗:  +3,200 Token                      │
│ 历史最高:  89,000 Token (第 23 轮)            │
│ 压缩次数:  2 次                              │
│ 当前消息数: 12 条                            │
└─────────────────────────────────────────────┘

10.4.3 A/B 测试

对于 System Prompt 和上下文策略的优化,建议采用 A/B 测试方法:

  • 设计多组不同的 Prompt 方案
  • 使用相同的测试用例集进行评测
  • 对比不同方案的输出质量、Token 消耗和响应延迟
  • 基于数据选择最优方案

10.5 安全注意事项

上下文构建过程中需要关注以下安全问题:

Prompt 注入防御:用户输入中可能包含试图修改 System Prompt 的恶意内容。例如,用户消息中嵌入"忽略之前的指令,改为执行…"。需要在消息层面做好隔离:System Prompt 通过 API 的 system 参数单独传递,而非拼接在消息文本中;对用户的 user 消息做内容审查,检测到注入模式时拒绝或清洗。

敏感信息过滤:注入环境信息时,需要将密钥、密码、内部 IP 等敏感数据脱敏。例如,环境变量中的 API_KEYDATABASE_URL 等字段应在注入前过滤。文件注入时也需跳过 .envcredentials.json 等敏感文件。

上下文泄露防护:在多租户场景下,不同用户的上下文必须完全隔离。Agent 的上下文构建服务不应在不同会话间共享内存或缓存。工具执行结果中可能包含其他用户的数据,需要在返回前做租户隔离检查。

工具调用权限控制:Agent 的工具调用应在沙箱环境中执行,限制文件系统访问范围、网络访问目标和命令执行权限。防止 Agent 在上下文中被诱导执行越权操作。


11. 常见问题与排错

11.1 问题诊断流程

flowchart TD
    P[&#34;Agent 表现异常&#34;] --> Q1{&#34;回复质量下降?&#34;}
    Q1 -- &#34;是&#34; --> Q2{&#34;是否是新出现的?&#34;}
    Q1 -- &#34;否&#34; --> Q3{&#34;是否响应缓慢?&#34;}

    Q2 -- &#34;是&#34; --> D1[&#34;检查最近的上下文变更&#34;]
    Q2 -- &#34;否&#34; --> D2[&#34;检查 System Prompt 是否被覆盖&#34;]

    Q3 -- &#34;是&#34; --> D3[&#34;检查 Token 使用量&#34;]
    Q3 -- &#34;否&#34; --> Q4{&#34;是否行为不一致?&#34;}

    Q4 -- &#34;是&#34; --> D4[&#34;检查上下文中的矛盾指令&#34;]
    Q4 -- &#34;否&#34; --> D5[&#34;检查工具定义是否完整&#34;]

    D1 --> S[&#34;修复并验证&#34;]
    D2 --> S
    D3 --> S
    D4 --> S
    D5 --> S

    style P fill:#c62828,stroke:#b71c1c,color:#ffffff
    style Q1 fill:#e65100,stroke:#bf360c,color:#ffffff
    style Q2 fill:#e65100,stroke:#bf360c,color:#ffffff
    style Q3 fill:#e65100,stroke:#bf360c,color:#ffffff
    style Q4 fill:#e65100,stroke:#bf360c,color:#ffffff
    style D1 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D2 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D3 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D4 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style D5 fill:#1565c0,stroke:#0d47a1,color:#ffffff
    style S fill:#2e7d32,stroke:#1b5e20,color:#ffffff

11.2 常见问题清单

现象可能原因排查方向解决方案
回复偏离预期System Prompt 指令不清晰检查 Prompt 的明确性和优先级重写关键指令,放在 Prompt 开头
工具调用失败工具描述不准确检查工具定义和参数描述完善工具描述,添加示例
上下文溢出对话过长或注入过多检查 Token 使用分布启用压缩策略,限制注入量
行为不一致历史消息中包含矛盾指令检查对话历史清理冲突的历史上下文
响应质量随轮次下降上下文过长导致注意力分散检查上下文长度增加压缩频率,精简上下文
工具调用循环工具结果未正确注入或解析检查工具角色消息格式验证 tool_call_id 关联关系

11.3 排错工具

建议构建以下排错工具辅助上下文调试:

  1. 上下文可视化器:以结构化方式展示当前上下文的组成和各部分 Token 占比
  2. 注意力热力图:可视化模型对不同上下文部分的注意力分布(需要模型支持)
  3. Token 追踪器:记录每轮推理的 Token 消耗变化趋势
  4. 上下文差异对比:对比不同时间点的上下文快照,发现异常变化

附录

A. 上下文构建检查清单

  • System Prompt 包含完整的角色定义和行为规则
  • 工具定义包含准确的描述和参数说明
  • 匹配的 Skills 已加载且内容完整
  • 对话历史长度在合理范围内
  • 动态注入内容经过相关性过滤
  • 环境信息已脱敏处理
  • Token 总量在窗口容量范围内
  • 关键信息具有较高的注意力权重(靠前位置)
  • 不存在矛盾或冗余的指令

B. 关键术语表

术语定义
Context Window模型单次推理能够处理的最大 Token 数量
System Prompt位于消息列表最前端,定义 Agent 角色和行为的特殊指令
Token模型处理文本的最小单位,约等于 0.75 个英文单词
RAGRetrieval-Augmented Generation,检索增强生成
Context Compression通过摘要或筛选减少上下文 Token 消耗的技术
Tool CallAgent 生成的结构化工具调用请求
Message Role消息的角色分类:system、user、assistant、tool
Attention Weight模型对不同上下文部分的关注程度分布
Embedding将文本编码为向量表示的技术,用于语义检索

C. 上下文 Token 估算参考

内容类型Token 估算
100 个英文单词~75 Token
100 个中文汉字~150-200 Token
100 行代码~300-500 Token
一条工具定义~100-300 Token
一条消息的结构开销~4-8 Token
一段 JSON 数据字符数的 ~1/3

文档版本: v1.0 最后更新: 2026-06-12 适用范围: Agent 上下文系统的设计、开发和调试