生产环境 AI 代理的四层上下文工程:Deep Insight 如何在可运行代码中落地

AWS ML Blog 2026-11-05T03:56:01.427760

生产环境中的 AI 代理处理数据分析和报告生成这类任务时,上下文管理往往成为主要瓶颈。20 万 token 的窗口听起来很宽裕,但真实任务几分钟就能吃掉大半。数据分析和报告生成会让代理执行到一半就失败、准确率下降,或者成本飙升。

已有不少公开指南讨论过这个问题,但单项技术读起来容易,落地却不简单。把这些技术组合使用,效果相当可观:本文介绍的参考实现中,一个“写入并执行”工具把每个脚本添加到上下文的 token 减少了约 95%,按需加载技能则让系统提示词缩小了约 97%。本系列把这些指南整理成可以直接上手的实践。Anthropic 的工程博客和 Strands Agents SDK 内置的功能,最终汇聚成四层上下文工程:在架构层隔离上下文、通过提示控制上下文、将上下文外部化到文件系统、用独立代理和防护措施来验证上下文。

本文是第二部分,将介绍每一层如何工作,以及在可运行代码中长什么样。我们在 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 分钟)、生成 5 张时序分析图表(10 分钟)、统计验证(3 分钟)、最终报告生成(5 分钟)。整个过程耗时约 15 分钟,消耗超过 150K token。

把这类任务塞进单个上下文会出问题:任务做到一半窗口就溢出,过时的上下文拖累表现,一旦出错整个流程还得重跑。上下文越长,模型对关键信息的注意力越弱;效率一低,按 token 计费的成本也跟着上去。

随着上下文窗口里 token 数量的增加,模型准确回忆其中信息的能力会下降(即「上下文腐化」,Context rot)。

—— Anthropic,《Effective Context Engineering for AI Agents》(2025.09)

上下文工程正是冲着这些问题来的,而且它不只是一堆技巧的集合。它横跨架构设计、提示词撰写、工具实现和验证,是一个分层的实践体系——每一层都在补上一层的漏。本文会详细拆解这套四层方法,帮你有条理地管好上下文。

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

Anthropic 公布过多种应对长周期任务的技术方案。Deep Insight 把这些技术归为四层,每一层都在弥补其他层的不足。下表列出这四层。

层级 做法 核心原则 局限
第 1 层:架构 通过多智能体架构隔离上下文 每个智能体在独立的上下文中运行 仅靠隔离还不够时
第 2 层:提示词 输出控制与行为规则 通过提示词限制上下文摄入 仅靠提示词还不够时
第 3 层:工具 基于文件的上下文外置 把重量级内容留在上下文之外的文件里 仍然出现问题时
第 4 层:验证 智能体与防护机制 独立验证与防护 捕捉错误、防止上下文溢出

接下来的几节会依次讲每一层:它规定了什么、为什么单靠前面的层还不够、以及 Deep Insight 如何落地这套做法。

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

给每个专用智能体分配自己的上下文窗口,只把压缩后的结果交给编排器。Deep Insight 用一套层级结构来做这件事:协调器(Coordinator)、规划器(Planner)、计划审查器(Plan Reviewer)、监督器(Supervisor),以及各类工具智能体(编码器 Coder、验证器 Validator、报告器 Reporter、追踪器 Tracker、审计器 Auditor)。

如果只用单个智能体,所有信息——从用户请求到数据探查、分析、图表生成、验证、出报告——都会堆在同一个上下文里,很容易超出窗口。让每个智能体拥有自己的上下文后,即便用得最多的编码器,总消耗也能压在 25K token 以内。每个智能体只接收自己需要的东西,再用一条完成通知加简要摘要来告知其他智能体。

隔离的关键在于尽量少共享信息。Deep Insight 用一个 Python 字典 shared_state,其中只存四样东西:

clues 使用固定的 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 在《How We Built Our Multi-Agent Research System》一文中推荐的:编排器-工作者模式(orchestrator-worker),由主智能体把任务分派给专职子智能体,每个智能体只在自己的上下文中工作。你不需要自己实现这套机制:Strands Agents SDK 的“智能体即工具”(agents-as-tools)模式已经在框架层面提供了这种隔离。

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

光靠第 1 层隔离还不够:即使上下文彼此独立,只要某个智能体输出很长,Supervisor 的上下文照样会被撑大。第 2 层用提示词限制每个智能体的输出。在 Deep Insight 中,我们用提示词限制每个智能体返回给 Supervisor 的信息量。正如 Deep Insight 的提示词所示,三条规则承担了大部分工作。

“先用最强的模型和最简洁的提示词起步,再根据实际观察到的失败案例逐步补充具体指令。”
—— Anthropic,《Effective Context Engineering for AI Agents》(2025.09)

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

每个智能体的提示词里都规定了最大响应 token 数,避免冗长回复污染 Supervisor 的上下文。

Agent 输出 Token 预算 原因
Coder 1,000–1,500 tokens 分析代码会保存到文件,因此 agent 只返回状态、已完成任务和关键洞见的摘要
Validator 800 tokens 验证结果会写入 citations.json,agent 只返回摘要
Reporter 1,000 tokens agent 将报告生成为 DOCX 文件,只返回结果摘要

Anthropic 的《Writing Effective Tools for Agents》一文建议,为了节省上下文,给工具提供 CONCISE(简洁)或 DETAILED(详细)两种响应选项。把这个思路往上提一层,用到每个 agent 的系统提示词里。在 Deep Insight 中,所有 agent 共用同一套标准格式:

## 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 agent 的提示词明确写了「变量不会跨脚本保留」。每个脚本都必须带上所需的全部 import,并自行加载数据。提示词里同时给出了错误示例和正确示例:

# 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}")

这条规则跟上下文工程的关系在于:如果脚本要引用之前脚本里的变量,agent 就得「记住」之前的对话,也就意味着旧代码必须一直留在上下文里。而自包含原则让旧代码可以安全地从上下文里移除。

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

Supervisor 的提示词里有一条规则:「当前 agent 章节里的所有清单项都标记为 [x] 之前,不要切换到下一个 agent。」我们把这条规则写进提示词,是因为要判断 Coder 的工作是否完成,Supervisor 得结合 Tracker 的更新来解读计划。这种判断很难只用代码表达。

3. 「上下文只放指针,实际数据放文件」

Layer 1 把上下文隔离在各个 agent 之间,Layer 2 限制 agent 内部的输出。但 Coder agent 生成 100 行 Python 代码时,这些代码本身就会进入上下文。即便提示词要求「简短回复」,有些代码就是没法写短。Layer 3 靠工具设计,把体量大的内容挪到上下文之外,放进文件系统。下面的实现细节展示了其中四项技术,大部分收益都来自它们。

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

Coder 读取分析计划,编写 Python,再执行它生成可视化结果。可代码一长,常规做法(把写文件和执行拆成两个工具)每跑一个脚本就往上下文里塞 100 行,累积下来能超过 1000 行。解决办法是把这两步合并成一个工具,让代码不再以消息形式进入上下文。Deep Insight 的 Coder agent 为此用了一个 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
    )

```python
# 只返回摘要
    return f"已将 {len(content.split(chr(10)))} 行写入 {file_path}\n" \
           f"执行成功\n" \
           f"输出:{result.stdout[:500]}"  # 只取前 500 个字符

"服务端过滤:数据在到达上下文之前,先在执行层完成过滤,token 减少 98.7%(从 150K 降到 2K)。"
—— Anthropic,《Code Execution with MCP》(2025.11)

实现细节 3-2:在 Coder agent 里把常用逻辑复用为模块

同一批模块会在多次分析中反复用到。与其每次重新生成,不如把高频函数定义成模块、按需导入,既省 token,也避免上下文重复。否则每次分析都要重新定义 to_python_type() 或 track_calculation() 这类函数,10 次分析下来就会积累 200–300 行重复代码。Deep Insight 会在第一个任务开始前生成一个名为 coder_analysis_utils.py 的模块,里面包含 numpy 类型转换、计算元数据追踪、写入 JSON 等函数。后续分析直接导入它,原本需要重新生成的 20–30 行代码,现在只靠两行 import 就搞定——既省 token,也让代码更一致、更好调试。

# coder_analysis_utils.py -- 第一个任务前生成的公共模块
import numpy as np
import json
from datetime import datetime

_calculations = []

def to_python_type(value):
    """把 numpy/pandas 类型转换为 Python 原生类型"""
    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):
    """追踪计算元数据——之后由 Validator 独立校验"""
    _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 智能体每完成一次分析任务,就把结果追加到这个文件:

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,这些内容会不断堆积在它的上下文里。用了笔记之后,只需传一条大约 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,《Effective Context Engineering for AI Agents》(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

它返回完整的 SKILL.md 内容,约 3K token。每个技能对应一个 SKILL.md 文件,文件由 YAML frontmatter(前置元数据)和详细的 markdown 指南组成,包含名称、描述、许可证、allowed-tools 等元数据,以及 Overview、When to Use This Skill、详细说明和最佳实践。添加新技能时,只需在 skills/ 目录下新建一个目录,写一个 SKILL.md 文件,系统就会自动发现。启动时,agent 先加载约 500 token 的技能目录,而不是把 20,000 多 token 浪费在完整指南上,省下约 97%。需要时,再按需加载几千 token 的技能详细说明。

4. 用验证 agent 和安全网来验证质量

即使有了第 1–3 层,风险依然存在:agent 彼此独立,看不到对方的工作,所以如果 Coder 算错了,Reporter 会把这个错误带进报告。第 4 层就是最后一道防线。

“提供测试工具,让 agent 能自行验证功能,并修复仅靠代码不明显的 bug。让模型用描述性提交信息把进度提交到 git,并在进度文件中写进度摘要。”——Anthropic,《Effective Harnesses for Long-Running Agents》(2025.11)

实现细节 4-1:Tracker、Validator 和 Auditor agent:进度跟踪与质量保证

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 采用以下阈值:

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

异常情况下上下文仍可能溢出,所以在其他层之下保留一个安全网。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% 消息总结成一条,同时始终保留最近 10 条消息,以维持当前任务的上下文。总结 prompt(summarization.md)要求把线索、计划和跟踪状态逐字保留。

实现细节 4-4:按需启用 prompt 缓存以优化成本

上下文工程不只是节省 token,也包括成本优化。根据各 agent 被相同 prompt 调用的频率,可以为每个 agent 单独开启 prompt 缓存。Deep Insight 的逐 agent 设置如下:

Agent Prompt 缓存 工具缓存 原因
Supervisor 是 是 重复调用频率高,系统 prompt 和工具定义都很大
Coder 是 是 依次运行多个分析脚本,每次 prompt 相同
Reporter 是 是 逐节增量生成报告,prompt 复用频率高
Auditor 是 是 用相同的 prompt 和工具,多轮检查 DOCX 和 JSON 文件,并在每次 Reporter 重试后重新运行
Coordinator 否 否 一次性调用,缓存没有收益
Planner 否 否 每个请求调用一次,只在用户要求修改计划时再次调用
Validator 否 否 每次调用的数据都不同,缓存命中率低
Tracker 否 否 轻量任务,不用工具,没必要缓存

开启缓存的 agent 会把缓存点插入系统 prompt 和工具定义中,在重复调用时最多可减少 90% 的输入 token 成本。这是 Strands Agents SDK 原生支持的功能。

Plan Reviewer 没有出现在表中,因为它是一个 human-in-the-loop 步骤,负责收集用户批准或反馈,不调用模型。

结语

本文详细介绍了四层工程方法,可以用来高效管理超出上下文窗口的复杂任务所需的上下文。

这四层加起来构成一套防御体系,前一层漏掉的由后一层补上。架构隔离不够,就用提示词约束输出;提示词不够,就用工具把内容放到上下文之外;还是出问题,就靠校验把它抓出来。

这些做法在 Anthropic 的几篇工程博客里都有记录,包括《Effective Context Engineering for AI Agents》《Code Execution with MCP》和《How We Built Our Multi-Agent Research System》。其中不少已经内置在 Strands Agents SDK 里,不需要你自己去搭,比如 SummarizingConversationManager、提示词缓存,以及把智能体当作工具的「agents-as-tools」模式。

做生产级智能体时,光靠大语言模型(LLM)的上下文窗口往往不够用。用上这些上下文工程技巧,才能高效管理上下文,让智能体扛住生产负载。文中作为示例的参考实现 Deep Insight 已经开源,你可以去看代码,再按自己的业务领域扩展。

查看原文