当生产环境中的 AI 智能体处理数据分析和报告生成等任务时,上下文管理可能成为一大瓶颈。200K token 的窗口听起来很宽裕,但实际任务可能在几分钟内就消耗掉其中的大部分。数据分析和报告生成任务可能导致智能体在执行中途失败、准确率下降或成本上升。已有不少公开的指导资料讨论这个问题,但具体技巧读起来容易,应用起来却更难。将这些技巧结合使用能带来可衡量的效果:在本文介绍的参考实现中,一个兼具写入和执行功能的工具将每个脚本加入上下文的 token 数量减少了约 95%,而按需加载技能则将系统提示词缩短了约 97%。

本系列将这些指导整理为可以直接应用的实践。Anthropic 的工程博客文章与 Strands Agents SDK 内置的功能共同指向上下文工程的四个层次:在架构层隔离上下文,通过提示词控制上下文,将上下文外置到文件系统,并使用独立智能体和保障机制进行验证。在本文(第 2 篇)中,你将了解每个层次的工作原理,以及它在实际代码中的实现方式。我们在 Deep Insight 中应用了这些技巧。Deep Insight 是一个基于 Strands Agents SDK 和 Amazon Bedrock AgentCore 构建的开源多智能体数据分析解决方案,也是本文始终使用的参考实现。

系列文章

第一篇文章定义了生产环境中的多智能体系统必须解决的五大核心挑战,并通过代码示例介绍了 Strands Agents SDK、Amazon Bedrock 和 Bedrock AgentCore,以及 AWS Fargate 如何分别解决问题的不同层面。第二篇文章将介绍建立在该架构之上的上下文工程实践的四个层次,并展示每个层次的实现。第三篇文章将指导你在 Amazon Virtual Private Cloud (Amazon VPC) 的安全私有网络中部署和运行智能体,涵盖实际运营所需的全部内容。

什么是上下文工程?

上下文工程是一门优化大语言模型(LLM)有限上下文窗口中信息的实践,目的是让智能体发挥最佳性能。Amazon Bedrock 上提供的 Anthropic Claude Sonnet 4.5 拥有 200K 的上下文窗口,但复杂的生产任务很快就会超出这一容量。例如,“分析销售数据并创建一份 DOCX 报告”这样看似简单的请求,需要经历多个阶段:加载和探索数据(5 分钟)、按类别分析销售情况(3 分钟)、生成五张时间序列分析图表(10 分钟)、统计验证(3 分钟)以及生成最终报告(5 分钟)。这些阶段在 15 分钟内合计消耗超过 150K token。

在同一个上下文中处理此类任务会带来一系列问题:窗口在任务中途溢出,过时的上下文导致性能下降,出现错误后还需要重新运行整个流程。随着上下文增长,模型对重要信息的关注度会下降,而在按 token 计费的模式下,效率低下也会增加成本。

“随着上下文窗口中的 token 数量增加,模型从该上下文中准确回忆信息的能力会下降(上下文腐化)。”

— Anthropic,《AI 智能体的高效上下文工程” (2025.09)

上下文工程正是为了解决这些问题,而且它不只是一些技巧的集合。它涵盖架构设计、提示词编写、工具实现和验证,是一门分层的实践,每一层都能弥补前面几层的不足。本文将详细介绍如何运用这四个层次来高效管理上下文。

如何处理超出上下文窗口的任务

Anthropic 发布了多种处理长周期任务的技巧。Deep Insight 将这些技巧归为四个层次,每一层都针对其他层次的局限性提供补充。下表列出了这四个层次。

层次 实践 核心原则 局限性 第 1 层:架构 通过多智能体架构隔离上下文 每个智能体在独立的上下文中运行 仅靠隔离还不够时 第 2 层:提示词 输出控制和行为规则 通过提示词限制上下文的摄入 仅靠提示词还不够时 第 3 层:工具 基于文件的上下文外置 将大量内容保存在上下文之外的文件中 仍然出现问题时 第 4 层:验证智能体和保障机制 独立验证和保障机制 捕获错误并防止上下文溢出 最后一道防线

接下来的章节将依次介绍每个层次,说明该层的做法、为什么仅靠前面的层次还不够,以及 Deep Insight 如何实现这些实践。

1. 通过多智能体架构隔离上下文

为每个专业智能体提供独立的上下文窗口,只将压缩后的结果传递给编排器。Deep Insight 通过 Coordinator、Planner、Plan Reviewer、Supervisor 和 Tool Agents(Coder、Validator、Reporter、Tracker、Auditor)组成的层级结构实现这一点。

使用单个智能体时,从用户请求到数据探索、分析、图表生成、验证和报告的所有信息都会累积在同一个上下文中,很容易超出窗口容量。为每个智能体提供独立的上下文后,即使是消耗最多的 Coder,总用量也能保持在 25K token 以下。每个智能体只接收自己需要的信息,并通过完成通知和简短摘要向其他智能体传递结果。

隔离的关键是尽量减少共享信息。Deep Insight 使用一个 Python 字典 shared_state,只存储四项内容:

  • messages:上一个智能体的最终消息(而非完整对话历史)。
  • clues:从各个智能体收集的压缩摘要。
  • full_plan:由 Planner 生成、由 Tracker 更新的检查清单。
  • history:智能体名称和消息的简短日志。

这些线索采用固定的 CLUES_FORMAT:只传递压缩后的核心结果,而不是每个智能体的完整对话(数万 token)。

# coder_agent_tool.py -- context passing format
CLUES_FORMAT = "Here is clues from {}:\n\n<clues>\n{}\n</clues>\n\n"
RESPONSE_FORMAT = "Response from {}:\n\n<response>\n{}\n</response>\n\n*Please execute the next step.*"

# After Coder completes: add only compressed result to clues
clues += CLUES_FORMAT.format("coder", response["text"])

这种模式是 Anthropic 在其《我们如何构建多智能体研究系统》一文中推荐的。文章介绍了一种协调者—工作者模式:主智能体将任务委派给专门的子智能体,每个智能体都只在自己的上下文中工作。你不需要自己构建这种模式:Strands Agents SDK 中的 agents-as-tools 模式在框架层面提供了这种隔离。

2. 通过提示词控制上下文流入

仅靠第 1 层隔离还不够:即使各智能体的上下文相互独立,生成长篇回复的智能体仍会使 Supervisor 的上下文膨胀。第 2 层通过提示词限制每个智能体的输出。

在 Deep Insight 中,我们使用提示词来限制每个智能体向 Supervisor 返回的信息量。正如 Deep Insight 的提示词所示,主要依靠三条规则来实现这一点。

“从最强的模型和简单的提示词开始。然后根据实际观察到的失败案例,逐步添加具体指令。”

— Anthropic,《AI 智能体的有效上下文工程》(2025.09)

实现细节 2-1:为每个智能体明确设置输出 token 预算

每个智能体的提示词都规定了最大回复 token 数,防止过长的回复污染 Supervisor 的上下文。

智能体 输出 token 预算 原因 Coder 1,000–1,500 tokens 分析代码保存在文件中,因此智能体只返回状态、已完成任务和发现的摘要 Validator 800 tokens 验证结果保存在 citations.json 中。智能体只返回摘要 Reporter 1,000 tokens 智能体将报告生成为 DOCX 文件,只返回结果摘要

Anthropic 的《为智能体编写有效的工具》一文建议为工具提供 CONCISE 或 DETAILED 回复选项,以提高上下文使用效率。将同样的思路向上应用一层,放到每个智能体的系统提示词中。在 Deep Insight 中,所有智能体都采用同一种标准化格式:

## Status
[SUCCESS | PARTIAL_SUCCESS | ERROR]
## Completed Tasks
- [Task 1 from FULL_PLAN -- use exact wording so Tracker can match]
- [Task 2 -- be specific, not generic]
## Key Insights
- [Key finding 1 with numbers and ratios]
- [Key finding 2 with business implications]
## Generated Files
- ./artifacts/chart.png -- brief description
- ./artifacts/calculation_metadata.json -- N calculations

实现细节 2-2:自包含的代码理念

Coder 智能体的提示词明确指出:“变量不会在脚本之间持久保存。”每个脚本都必须包含所有必需的导入语句,并直接加载数据。提示词同时提供了错误和正确的示例:

# WRONG -- Attempting to use a variable from Turn 1 in Turn 2
# Turn 1:
df = pd.read_csv('data.csv')
total = df['Amount'].sum()

# Turn 2:
print(f"Total: {total}")  # NameError: name 'total' is not defined

# CORRECT -- Every script is self-contained
import pandas as pd
df = pd.read_csv('./artifacts/cache/df_main.csv')  # Load from cache
total = df['Amount'].sum()
print(f"Total: {total}")

这条规则之所以与上下文工程有关,是因为引用先前脚本中的变量需要智能体“记住”之前的对话,这意味着过去的代码必须保留在上下文中。自包含原则则意味着过去的代码可以安全地从上下文中移除。

实现细节 2-3:Supervisor 的章节完成规则

Supervisor 的提示词包含这样一条规则:“在当前智能体章节中的所有检查项都标记为 [x] 之前,不要转向下一个智能体。”我们将这条规则写进提示词,是因为要判断 Coder 的工作是否完成,Supervisor 需要利用 Tracker 更新中的信息来解读计划。这种判断很难仅用代码表达。

3. “上下文中只放指针,实际数据放在文件中”

第 1 层隔离了智能体之间的上下文,第 2 层限制了各智能体的输出。但当 Coder 智能体生成 100 行 Python 代码时,代码本身也会进入上下文。即使提示词要求“简短回复”,有些代码也无法简短地编写。第 3 层通过工具设计,将大量内容移出上下文,存入文件系统。主要收益来自四项技术,下面的实现细节将对此加以说明。

实现细节 3-1:使用 Write and Execute Tool 将代码移出上下文

Coder 阅读分析计划,编写 Python 代码,并执行代码以生成可视化结果。但当代码变长时,传统方法(分别使用文件写入工具和执行工具)会让每个脚本的 100 行代码直接进入上下文,累计超过 1,000 行。

解决办法是将这两个步骤合并到一个工具中,这样代码就不会作为消息进入上下文。Deep Insight 的 Coder 智能体为此使用了一个 write_and_execute_tool。

下面是 write_and_execute_tool 的一部分。写入并执行文件后,它只返回一条摘要:“已写入 105 行,执行成功,完成了对五个类别的分析。”代码保留在文件中,约三行摘要留在上下文里。根据这个例子,这样可以节省约 95% 的 token。

# write_and_execute_tool.py
def _handle_write_and_execute_tool(file_path, content, timeout=300):
"""Write a Python script and immediately execute it."""
# Step 1: Write file
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
# Step 2: Execute immediately
result = subprocess.run(
f"python {file_path}",
shell=True,
capture_output=True,
timeout=timeout
)
# Return only summary
return f"Written {len(content.split(chr(10)))} lines to {file_path}\n" \
f"Execution successful\n" \
f"Output: {result.stdout[:500]}"  # Only first 500 chars

“服务端过滤:在数据进入上下文之前,在执行层对其进行过滤,将 token 用量减少 98.7%(从 150K 降至 2K)。”

— Anthropic,《使用 MCP 执行代码》(2025.11)

实现细节 3-2:在 Coder 智能体中将通用逻辑作为模块复用

通用模块可以在不同分析中复用。无需每次都重新生成,只需将常用函数定义为模块,之后直接导入,就能避免浪费 token 和重复占用上下文。

如果不这样做,每次分析都定义 to_python_type() 或 track_calculation() 等函数,10 次分析下来就会产生 200–300 行重复代码。Deep Insight 会在第一个任务开始前生成一个名为 coder_analysis_utils.py 的模块,其中包含转换 numpy 类型、追踪计算元数据以及保存为 JSON 的函数。后续分析直接导入该模块,用两行导入语句替代重新生成的 20–30 行代码,既节省 token,也能提高一致性并方便调试。

# coder_analysis_utils.py -- common module generated before first task
import numpy as np
import json
from datetime import datetime

_calculations = []

def to_python_type(value):
"""Convert numpy/pandas types to Python native types"""
if isinstance(value, (np.integer, np.int64)): return int(value)
elif isinstance(value, (np.floating, np.float64)): return float(value)
elif isinstance(value, np.ndarray): return value.tolist()
return value

def track_calculation(calc_id, value, description, formula,
source_file, source_columns, importance):
"""Track calculation metadata -- Validator independently verifies later"""
_calculations.append({
"id": calc_id, "value": to_python_type(value),
"description": description, "formula": formula,
"source_file": source_file, "source_columns": source_columns,
"importance": importance
})

def save_calculation_metadata(path="./artifacts/calculation_metadata.json"):
"""Save all tracked calculations to JSON"""
with open(path, 'w', encoding='utf-8') as f:
json.dump({"generated_at": datetime.now().isoformat(),
"calculations": _calculations}, f, ensure_ascii=False, indent=2)

实现细节 3-3:通过结构化笔记保存和共享分析结果

我们使用结构化笔记来共享详细的分析结果,无需让这些结果经过每个智能体的上下文。Deep Insight 将这些结果存储在名为 all_results.txt 的文件中,供智能体按需读取。

例如,Coder 智能体在每次分析任务结束后,都会将结果追加到 all_results.txt 中:

with open('./artifacts/all_results.txt', 'a', encoding='utf-8') as f:
f.write(f"""
## Category Sales Analysis (completed at: 14:32)
- Top revenue category: Fruit (417,166,008 KRW, 45% of total)
- Top 3 categories: Fruit, Vegetables, Meat (78% of total)
- Generated file: ./artifacts/category_sales_chart.png
""")

Coder 在每次分析后将详细结果记录到这个文件中,Reporter 在撰写最终报告时读取该文件。其他智能体也通过 all_results.txt 以同样的方式协作。

不做笔记时,Coder 在每项任务结束后都会将详细结果传给 Supervisor,这些结果会不断累积在 Supervisor 的上下文中。做笔记时,只需传递一条约 30 个 token 的消息,例如“品类销售分析完成,发现 3 个关键洞察,详细结果已保存至 all_results.txt”,Reporter 在需要时读取该文件。

这种模式并不局限于单个文件。文件系统本身可以充当智能体之间的通信总线,Deep Insight 就是这样做的:

文件名 生产者 消费者 作用 all_results.txt Coder Reporter 分析结果的累积日志 calculation_metadata.json Coder Validator 数值计算记录:来源、公式和值(用于验证) citations.json Validator Reporter 经验证的引用数据(以 [1]、[2] 的形式插入报告) audit_findings.json Auditor Reporter 最终报告中发现的引用缺陷(用于驱动 Reporter 有针对性地重试) coder_analysis_utils.py Coder 所有脚本 共享工具函数(编写一次,反复导入) full_plan (shared_state) Planner/Tracker Supervisor 检查清单状态(更新 [x])

“‘即时’方法在运行时动态地将数据加载到上下文中,而不是预先处理所有相关数据,使上下文保持新鲜、相关,并能适应不断变化的任务状态。”

— Anthropic,《AI 智能体的有效上下文工程》(2025.09)

实现细节 3-4:使用 Skills 只加载所需知识

这种方法不会将所有专业知识都放进系统提示词,而是只在需要时加载。如果纳入每一份技能指南(数据结构检查、README 生成、技能创建、系统提示词编写、工具创建),就会增加超过 20K 个 token,在每次调用时向 Coder 智能体加载不必要的信息,而且每添加一项技能都必须重新部署。

Deep Insight 的 Skills 系统在启动时只加载一个约 500 个 token 的技能目录,技能列表中只包含名称和简短描述。当用户请求“创建一个 README 文件”时,智能体会判断“我需要 readme-generator 技能”,然后调用 skill_tool(skill_name="readme-generator")。SkillLoader 读取 readme-generator/SKILL.md,并返回一份约 3K 个 token 的详细指南。

# 1. Skill Discovery (at initialization)
from src.utils.skills.skill_utils import initialize_skills
available_skills, skill_prompt = initialize_skills(
skill_dirs=["./skills"],
verbose=True
)

# 2. Add to System Prompt (~500-token catalog)
system_prompt = base_prompt + skill_prompt

# 3. Runtime -- Agent loads skill when needed
# Agent decides: "This is README generation, I need the readme-generator skill"
# -> skill_tool(skill_name="readme-generator")
# -> Returns full SKILL.md content (~3K tokens)

每个技能都定义为一个 SKILL.md 文件,由 YAML 前置元数据和详细的 Markdown 指南组成。它包含 name、description、license 和 allowed-tools 等元数据,以及概览、何时使用此技能、详细说明和最佳实践。要添加新技能,只需在 skills/ 下创建一个新目录并编写 SKILL.md 文件,系统就会自动发现它。

启动时,智能体加载一个约 500 tokens 的技能目录,而不是在完整指南上消耗超过 20,000 tokens(减少约 97%)。需要时,它可以再加载相当于几千 tokens 的技能详细说明。

4. 使用验证智能体和保障措施验证质量

即使有第 1–3 层,仍然存在一个风险:相互隔离的智能体无法看到彼此的工作,因此如果 Coder 计算出错,Reporter 就会把这个错误带入报告。第 4 层是最后一道防线。

“提供测试工具,让智能体能够自行验证功能并修复仅凭代码不易发现的错误。让模型用描述清晰的提交信息将进展提交到 git,并在进度文件中编写进度摘要。”

— Anthropic,《长时间运行智能体的有效运行框架》(2025.11)

实现细节 4-1:Tracker、Validator 和 Auditor 智能体:进度跟踪与质量保障

Tracker 实时更新计划中的清单。Coder 完成数据加载后,Supervisor 会调用 Tracker,Tracker 根据“数据加载完成(1,000 行,5 列)”等信息,将计划项目从 [ ] 更新为 [x]。这有助于用户和系统准确了解当前进度。

Validator 独立重新执行 Coder 的计算,以验证准确性。它读取 calculation_metadata.json,根据源数据重新执行每项计算并进行比较:差值在 0.01 以内则通过,不匹配的结果会被标记。验证通过的计算结果会写入 citations.json,供 Reporter 引用。Reporter 完成工作后,Auditor 会对照 citations.json 和 calculation_metadata.json 检查最终的 DOCX 文件,而不修改这两个文件。它将引用缺陷记录在 audit_findings.json 中,并且最多可以要求 Reporter 进行两次针对性重试。

实现细节 4-2:确定计算验证的优先级

验证每一项计算的效率不高,因此应按重要性确定验证范围。Deep Insight 的 OptimizedValidator 采用以下阈值:

  • 超过 50 项计算:严格筛选,验证所有高优先级计算,另外只验证 10 项中优先级计算。
  • 超过 20 项计算:适度筛选,验证所有高优先级计算,另加 15 项中优先级计算。
  • 20 项或更少计算:验证大部分计算,包括所有高优先级、所有中优先级以及 5 项低优先级计算。

它还采用类型安全比较:为避免 numpy 与 Python 之间的类型问题,所有值都会转换为 float(),并检查绝对差值是否小于 0.01:

# validator.md -- type-safe numerical comparison
try:
match = abs(float(expected) - float(actual)) < 0.01
except:
match = str(expected) == str(actual)

实现细节 4-3:SummarizingConversationManager:最后一道安全网

在特殊情况下,上下文仍可能溢出,因此要在其他层之下保留一道安全网。Deep Insight 为此使用了 Strands Agents SDK 中的 SummarizingConversationManager。

# strands_sdk_utils.py -- safety net configuration at agent creation
agent = Agent(
model=llm,
system_prompt=system_prompts,
tools=tools,
conversation_manager=SummarizingConversationManager(
summary_ratio=0.5,  # summarize oldest 50% on overflow
preserve_recent_messages=10,  # always preserve 10 most recent messages
summarization_system_prompt=apply_prompt_template("summarization", {})
)
)

当上下文溢出时,LLM 会将最早的 50 percent 消息摘要合并为一条,同时始终保留最近的 10 条消息,以维持当前任务的上下文。摘要提示词(summarization.md)要求逐字保留 clues、plans 和 tracking status。

实现细节 4-4:通过选择性提示词缓存优化成本

上下文工程不仅涵盖节省 token,还包括成本优化。根据各 Agent 使用相同提示词的调用频率,为其分别启用提示词缓存。Deep Insight 为各 Agent 设置如下:

Agent 提示词缓存 工具缓存 原因 Supervisor 是 是 重复调用频繁,且系统提示词和工具定义篇幅较大 Coder 是 是 连续运行多个分析脚本,每次使用相同的提示词 Reporter 是 是 逐节生成报告,提示词复用频率高 Auditor 是 是 使用相同的提示词和工具,经过多轮检查 DOCX 和 JSON 文件,并在 Reporter 每次重试后重新运行 Coordinator 否 否 仅进行单次调用,缓存没有收益 Planner 否 否 每个请求调用一次,仅在用户要求修改计划时再次调用 Validator 否 否 每次调用的数据不同,缓存命中率低 Tracker 否 否 任务轻量,不使用工具,无需缓存

启用缓存的 Agent 会在系统提示词和工具定义中插入缓存点,在重复调用时将输入 token 成本降低最多 90 percent。这是 Strands Agents SDK 原生支持的功能。Plan Reviewer 未出现在表中,因为它是一个由人工参与的步骤,用于收集用户批准或反馈,而不调用模型。

结论

本文详细介绍了四层工程方法,可用于高效管理超过上下文窗口容量的复杂任务的上下文。

  • 第 1 层(架构级隔离):通过多 Agent 架构,让每个 Agent 在独立的上下文中工作,只传递压缩后的摘要。
  • 第 2 层(基于提示词的控制):输出 token 预算、标准化响应格式和自包含的代码设计理念主动限制上下文流入。
  • 第 3 层(文件系统的使用):write_and_execute_tool 将代码保存在上下文之外,文件系统充当 Agent 间的通信总线,知识仅在需要时才延迟加载。
  • 第 4 层(验证和保障措施):Validator 独立重新验证计算结果,Auditor 对最终报告的引用进行只读审计,Tracker 跟踪进度,SummarizingConversationManager 防止上下文溢出,选择性提示词缓存则帮助同时管理质量和成本。

每一层都构成一道防线,弥补前面各层的遗漏。当架构隔离不足时,提示词会限制输出。当提示词不足时,工具会将内容保留在上下文之外。如果问题仍然出现,验证环节会将其发现。

这些层次都记录在 Anthropic 的工程文章中:“Effective Context Engineering for AI Agents”、“Code Execution with MCP” 和 “How We Built Our Multi-Agent Research System”。他们推荐的许多功能已内置于 Strands Agents SDK 中,无需自行构建:SummarizingConversationManager、提示词缓存以及将 Agent 用作工具的模式。

构建生产环境中的 Agent 时,仅靠 LLM 的上下文窗口通常是不够的。运用这些上下文工程技术,可以高效管理上下文,并扩展 Agent 以应对生产工作负载。

本文使用的参考实现 Deep Insight 是开源的。查看代码,并针对你的领域进行扩展。