T
traeai
登录
返回首页
AWS Machine Learning Blog

使用Amazon Bedrock AgentCore突破上下文窗口限制

8.5Score
使用Amazon Bedrock AgentCore突破上下文窗口限制

TL;DR · AI 摘要

Amazon Bedrock AgentCore通过递归语言模型(RLM)架构,解决了长文档分析的上下文窗口限制问题,允许无上限处理文档并通过子LLM调用和代码解释器迭代分析。

核心要点

  • RLM架构通过将文档视为环境,使用根LLM编写代码与之交互,并通过子LLM处理特定段落,突破上下文窗口限制。
  • Amazon Bedrock AgentCore的代码解释器提供沙箱Python环境,保持工作内存状态,支持迭代分析长文档。
  • 实现需要结合Strands Agents SDK,通过分阶段的LLM调用和结果累积,最终生成基于完整文档的准确响应。

结构提纲

按章节快速跳转。

  1. 长文档分析面临上下文窗口限制,直接输入模型会导致请求失败或信息处理不全。

  2. RLM通过将文档视为可编程环境,利用根LLM编写代码并协调子LLM调用,实现无上限文档处理。

  3. 结合Strands Agents SDK和Bedrock AgentCore代码解释器,构建包含根LLM、执行环境和子LLM调用的三层架构。

  4. Bedrock AgentCore的沙箱Python环境支持持久化工作内存,通过llm_query()函数隔离子LLM结果。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • RLM with Bedrock AgentCore
    • Root LLM
      • Code Generation
      • Task Orchestration
    • Execution Environment
      • Persistent Python Variables
      • Document as External Environment
    • Sub-LLM Calls
      • Chunk Analysis
      • Semantic Interpretation

金句 / Highlights

值得收藏与分享的关键句。

  • RLM通过迭代循环将文档视为可编程环境,根LLM生成代码探索文档,将语义分析委托给子LLM处理选定段落,并在工作内存中累积结果。

    RLM架构概述

    ⬇︎ 下载 PNG𝕏 分享到 X
  • Amazon Bedrock AgentCore的代码解释器提供沙箱化Python环境,支持跨执行的持久化状态,实现无上下文限制的迭代分析。

    Bedrock AgentCore实现

    ⬇︎ 下载 PNG𝕏 分享到 X
  • 架构通过将子LLM结果存储为Python变量而非嵌入根LLM上下文,彻底解耦文档大小与模型限制。

    代码解释器功能

    ⬇︎ 下载 PNG𝕏 分享到 X
#Amazon Bedrock AgentCore#递归语言模型#Strands Agents SDK#上下文窗口限制#LLM编排
打开原文

当分析跨越数百万字符的文档时,你会遇到上下文窗口限制,即使最大型的上下文窗口也难以应对。模型要么拒绝输入,要么基于不完整信息生成答案。如何处理无法放入上下文窗口的文档?

本文将介绍如何通过 Amazon Bedrock AgentCore Code Interpreter 和 Strands Agents SDK 实现递归语言模型(RLM)。完成本文后,你将掌握以下能力:

  • 处理任意长度的文档,无上下文大小上限。
  • 使用 Bedrock AgentCore Code Interpreter 作为迭代文档分析的持久化工作内存。
  • 在隔离的 Python 环境中编排子大型语言模型(子LLM)调用,分析文档特定部分。

为什么上下文窗口不够用

以典型的财务分析任务为例:需要对比某公司过去两年年度报告的指标。每份报告长达 300-500 页,加上分析师报告、证券交易委员会(SEC)文件和补充材料,总字符数可达数百万。

直接将这些文档发送给模型时,要么输入超出模型的上下文窗口限制导致请求失败,要么输入勉强通过但模型难以关注长输入中间的信息,即所谓的“迷失在中间”问题。

这两种失败模式都源于上下文窗口大小是硬性限制,仅靠提示工程无法解决。我们需要将文档大小与模型上下文窗口解耦的方法。

RLM:将上下文视为环境

RLM(Zhang 等人在 arXiv:2512.24601 中提出)重构了这一问题。与其将整个文档填入模型上下文窗口,RLM 将输入视为模型可程序化交互的外部环境。

图1:递归语言模型(RLM)架构图,包含三层:顶部是生成最终响应的根LLM,中间是包含长提示变量和代码执行的REPL环境(工作内存),底部是并行子任务LLM调用的递归调用层。箭头显示迭代流程:用户查询进入REPL环境,根LLM生成代码进行符号化交互,Python变量返回上层,根LLM根据当前结果创建子任务,子响应返回工作内存。

_图1. 递归语言模型通过迭代循环运作:根LLM生成代码探索文档环境,将语义分析委托给选定片段的子LLM调用,并在工作内存中累积结果后再优化下一步操作。_

模型仅接收查询和环境描述,然后通过代码迭代搜索、切片和分析文档。当需要理解特定段落的语义时,它会将分析委托给子LLM调用,将结果保留在Python变量中而非消耗上下文窗口空间。

这种递归结构使根LLM通过代码编排分析,按需调用子LLM处理语义任务,而完整文档从未进入模型的上下文窗口。

架构

以下是使用 Amazon Bedrock AgentCore Code Interpreter 作为执行环境实现RLM的架构。Bedrock AgentCore Code Interpreter 提供隔离的Python运行时环境,且执行状态可持久化。架构包含三个协同组件:

基于 Strands Agents SDK 构建的根LLM代理接收用户查询并决定执行代码。运行在 PUBLIC 网络模式下的 Amazon Bedrock AgentCore Code Interpreter 会话中,完整文档被加载为Python变量。沙箱中注入的llm_query()函数可直接调用 Amazon Bedrock 基础模型,使子LLM结果保留在Python变量中,而非回流到根LLM的上下文窗口。

_图2:使用 Amazon Bedrock AgentCore 实现RLM的架构图。流程分为三部分:(1)输入——长上下文文档和用户查询输入RLM代理;(2)RLM与执行环境——RLM代理通过Execute Python Tool向Bedrock AgentCore Code Interpreter发送代码,其中完整文档作为Python变量加载,llm_query()函数用于子LLM调用,子结果保留在变量中而非返回根LLM上下文;(3)Amazon Bedrock LLMs——Code Interpreter向外调用Bedrock基础模型进行文档片段的语义分析。_

_Figure 2. 使用 Amazon Bedrock AgentCore Code Interpreter 的 RLM 架构。根 LLM 代理会在预加载完整输入数据的沙箱环境中迭代编写并执行 Python 代码。在沙箱内部,代理可通过 Amazon Bedrock 调用子 LLM 对特定部分进行语义分析。中间结果会作为 Python 变量保留在沙箱中,使根 LLM 的上下文窗口能专注于编排任务。_

Amazon Bedrock AgentCore Code Interpreter 的公共网络模式通过允许沙箱向外发起 Amazon Bedrock API 调用来支持此架构。持久化的会话状态使变量、中间结果和提取的数据能在多次代码执行中积累,为模型在整个分析过程中提供持续的内存工作区。

实现

按照以下步骤设置并运行使用 Amazon Bedrock AgentCore Code Interpreter 的 RLM。

先决条件

要跟随本文操作,您需要:

  • 具有对 Amazon Bedrock 基础模型(FMs)访问权限的 AWS 账户
  • Python 3.10 或更高版本。
  • 配置好适当凭证的 AWS 命令行界面(AWS CLI)
  • 熟悉 Python 和 AWS SDK(Boto3)的基础用法。
  • 配置为公共网络模式的 Amazon Bedrock AgentCore Code Interpreter。
  • bedrock:InvokeModelbedrock-agentcore:StartCodeInterpreterSessionbedrock-agentcore:InvokeCodeInterpreterbedrock-agentcore:StopCodeInterpreterSession 具有 IAM 权限。

1: 启动代码解释器会话并加载文档

创建 Amazon Bedrock AgentCore Code Interpreter 会话并将文档写入沙箱:

python
import boto3
import json

# 启动 Bedrock AgentCore Code Interpreter 会话
client = boto3.client('bedrock-agentcore', region_name='us-east-1')
response = client.start_code_interpreter_session(
    codeInterpreterIdentifier=code_interpreter_id,
    name="rlm-session",
    sessionTimeoutSeconds=3600
)
session_id = response["sessionId"]

# 将文档写入沙箱
client.invoke_code_interpreter(
    codeInterpreterIdentifier=code_interpreter_id,
    sessionId=session_id,
    name="writeFiles",
    arguments={"content": [{"path": "_context.txt", "text": document}]}
)

Python

2: 在沙箱内初始化文档并定义 llm_query() 辅助函数

在沙箱内部加载文档并定义 llm_query() 函数(子 LLM 调用将使用此函数):

python
# 在 Bedrock AgentCore Code Interpreter 沙箱内运行
with open('_context.txt', 'r') as f:
    context = f.read()

def llm_query(prompt: str) -> str:
    """从沙箱内部查询子 LLM。"""
    response = bedrock_client.invoke_model(
        modelId=sub_model_id,
        body=json.dumps({
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 4096,
            "messages": [{"role": "user", "content": prompt}]
        })
    )
    result = json.loads(response['body'].read())
    return result['content'][0]['text']

Python

3: 创建 Strands Agent 并提交查询

创建一个使用单个 execute_python 工具的 Strands Agent(该工具在会话中运行代码),然后提交您的问题:

python
from strands import Agent

agent = Agent(
    model="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
    system_prompt=rlm_system_prompt,
    tools=[execute_python],
)

answer = agent("这些报告中的关键收入趋势是什么?")

Python

代理会迭代编写并执行 Python 代码来探索文档、提取相关部分,并在需要对特定片段进行语义分析时调用 llm_query()

评估

在我们的评估中,我们将 RLM 与两个基线方法进行比较,即 _Base_ 和 _Long Context_。在 Base 方法中,整个文档会直接通过单次 API 调用发送给模型,使用 200K 令牌上下文窗口。这是最直接的策略,但当文档超过模型上下文限制时会失败。Long Context 方法使用 Claude 的扩展 100 万令牌上下文窗口,可处理更大输入但仍有上限,并可能遇到“迷失在中间”等问题。

我们在 LongBench v2 的 Financial Multi-Document QA 子集上评估了该方法,该基准测试旨在评估 LLM 在需要跨长上下文进行推理的任务中的表现。此子集包含 15 个多项选择题,每个问题需要分析多个财务报告,上下文长度可达约 200 万字符。

我们报告了两个指标:_success rate_(模型成功处理问题且未超出输入限制或出错的百分比)和 _accuracy_(正确回答的百分比,未回答的问题计为错误)。

我们比较了三种方法:_Base_、_Long Context_ 和 _RLM_。我们在 RLM 上测试了四个作为根 LLM 的 Claude 模型,子 LLM 配置为与根模型相同或 Haiku 4.5(以平衡性能和效率)。我们选择 Haiku 4.5 作为子 LLM 是因为它在局部片段分析中提供显著更低的延迟和成本,而根模型则负责全局推理和编排。

_Table 1. LongBench v2 Financial Multi-Document QA(15 个问题)。Human expert accuracy 数据来自 LongBench v2 论文。Base 方法在 Claude Sonnet 4.6 和 Opus 4.6 上的结果被省略,因为这些模型默认具有 100 万令牌上下文窗口,使 Base 和 Long Context 方法等效。_

模型方法成功率准确率 Claude Haiku 4.5 Base 46.7%33.3% Claude Haiku 4.5 + Haiku 4.5 RLM 100.0%66.7% Claude Sonnet 4.5 Base 46.7%26.7% Claude Sonnet 4.5 Long Context 93.3%66.7% Claude Sonnet 4.5 + Haiku 4.5 RLM 100.0%66.7% Claude Sonnet 4.6 Long Context 93.3%60.0% Claude Sonnet 4.6 + Haiku 4.5 RLM 100.0%73.3% Claude Opus 4.6 Long Context 93.3%66.7% Claude Opus 4.6 + Haiku 4.5 RLM 100.0%80.0% Human Expert––40%

结果揭示了三个关键发现:

  • RLM缓解了上下文长度限制问题。 基础方法和长上下文方法因上下文限制无法处理部分输入。基础方法的成功率为46.7%(15个问题中7个成功),而长上下文方法达到93.3%(14/15)。相比之下,RLM通过完全解耦文档大小与上下文窗口大小,在所有配置中实现了100%的成功率。随着文档规模扩大,这种可靠性优势在实际部署中愈发重要。
  • RLM提升了大多数模型的准确率。 RLM将Claude Sonnet 4.6和Opus 4.6的准确率从长上下文的60.0%和66.7%提升至73.3%和80.0%,同时将Claude Haiku 4.5的基础准确率33.3%提升至66.7%。提升最显著的是Claude Haiku 4.5,而更强的模型(Sonnet 4.6、Opus 4.6)则表现出持续但较小的增益。Claude Sonnet 4.5在长上下文基准和RLM配置下均保持66.7%的准确率,这表明RLM的收益取决于根模型分解任务为子查询的能力,这可能限制了Sonnet 4.5在此场景下的改进空间。
  • 子LLM选择在此场景中影响有限。 进一步实验表明,使用Claude Haiku 4.5作为子LLM与根LLM/子LLM使用同一模型时,各配置的准确率无显著差异。这表明对于此任务,性能主要由根模型生成有效子查询的能力驱动,而非子LLM执行查询的具体能力。

扩展至代码仓库理解:LongBench v2 CodeQA

财务QA评估聚焦长文本推理。接下来我们考察其在不同领域的泛化能力:代码仓库理解,该场景需要遍历大型代码库、解析函数依赖关系并跨文件追踪逻辑,特别适合通过代码执行进行程序化探索。

我们基于LongBench v2的代码仓库理解子集进行测试,包含50道多选题。每道题提供完整的代码仓库作为上下文(规模从约10万到1600万个字符),要求回答涉及实现细节、API行为或架构决策的问题,需通过理解代码库进行解答。

架构与财务QA相同,将完整仓库加载到代码解释器沙盒中作为单一上下文变量。模型编写Python代码搜索相关文件、提取函数定义、追踪调用链,并通过llm_query()分析特定代码段。

我们使用四种Claude模型对全部50题进行评估。基于财务QA中"子LLM选择影响有限"的发现,所有RLM实验固定使用Claude Haiku 4.5作为子LLM。

_Table 2. LongBench v2代码仓库理解(50题)_

模型方法成功率准确率 Claude Haiku 4.5 Base 30.0%20.0% Claude Haiku 4.5 + Haiku 4.5 RLM 100.0%64.0% Claude Sonnet 4.5 Base 30.0%20.0% Claude Sonnet 4.5 Long Context 60.0%46.0% Claude Sonnet 4.5 + Haiku 4.5 RLM 100.0%76.0% Claude Sonnet 4.6 Long Context 60.0%42.0% Claude Sonnet 4.6 + Haiku 4.5 RLM 100.0%66.0% Claude Opus 4.6 Long Context 60.0%44.0% Claude Opus 4.6 + Haiku 4.5 RLM 100.0%74.0%

结果与财务QA一致:RLM在所有模型中实现100%成功率,而基础和长上下文方法仅30-60%。RLM显著提升准确率,各模型在64%-76%之间,远高于基础和长上下文的20%-46%。

模型解决问题的流程示例

以下是一个评估问题的典型处理流程示例。模型需要比较约150万字符的两份年报中的财务指标。

首先,模型通过结构标记理解文档布局:

matches = re.findall(r'Table of Contents|ANNUAL REPORT', context)

Python

接着定位到具体章节提取收入表格:

code
revenue_section = context[450000:500000]
print(revenue_section)

Python

进行语义分析时委托给子LLM:

analysis = llm_query(f"Compare these revenue figures: {chunk}")

Python

最后聚合多部分分析结果得出最终答案。

实施考量

在将RLM用于文档分析工作负载时,需注意以下权衡因素:

  • 延迟。 RLM以延迟换取能力。根据我们对两个LongBench v2数据集的评估,RLM的单次运行时间从简单问题的约10秒到复杂问题(涉及大量上下文)的数分钟不等,大部分任务可在几分钟内完成。对于批处理或离线分析,这种权衡是合理的。若用于实时应用,请确认任务是否真的需要处理超出模型上下文窗口的文档。
  • 成本。 每次RLM运行都会涉及多次模型调用,包括主LLM的迭代推理和沙箱内的子LLM调用。对于成本敏感的工作负载,可通过使用较小模型(如Haiku 4.5)作为子模型,同时保留较大模型作为主模型,在保持准确率的同时降低成本。
  • 提示工程。 系统提示会影响模型使用工具的效率。若缺乏指导,模型可能通过代码执行进行不必要的子LLM调用,或生成冗长的中间摘要。明确说明何时使用代码执行、何时直接推理的指令可以减少不必要的工具调用,从而缩短端到端延迟。

清理资源

为避免持续产生费用,请在分析完成后停止Amazon Bedrock AgentCore代码解释器会话:

python
client.stop_code_interpreter_session(
    codeInterpreterIdentifier=code_interpreter_id,
    sessionId=session_id
)

Python

若您为本教程创建了专用代码解释器资源且不再需要,可通过Amazon Bedrock AgentCore控制台或AWS CLI删除该资源。

结论

递归语言模型为处理超出模型上下文窗口的文档提供了实用方案。通过结合Amazon Bedrock AgentCore代码解释器与Strands Agents SDK,可实现通过迭代代码执行和子LLM调用对任意长度输入数据进行推理的RLM架构。

在我们的评估中,结果显著:配备RLM的Claude Opus 4.6在LongBench v2金融问答数据集上达到80.0%的准确率(对比100万token上下文窗口的Long Context模型66.7%准确率,以及人类专家40%的准确率);配备RLM的Claude Sonnet 4.5在LongBench v2代码仓库问答数据集上达到76.0%准确率(对比20万token上下文窗口的Base提示法20.0%准确率,以及Long Context模型46.0%准确率)。

无论是财务分析、代码仓库理解、医疗与生命科学研究、法律审查还是合规审计等需要处理长上下文或大型参考库的任务,均可从该模式中受益。若您尝试将此方法应用于自己的文档分析工作负载,欢迎分享您的成果和体验。

开始使用本文所述方法时,可参考以下资源:

参考文献

  1. Zhang, A. L., Kraska, T., & Khattab, O. (2025). Recursive Language Models. arXiv:2512.24601
  2. Bai, Y., Tu, S., Zhang, J., Peng, H., Wang, X., Lv, X., Cao, S., Xu, J., Hou, L., Dong, Y., Tang, J., & Li, J. (2024). LongBench v2: Towards Deeper Understanding and Reasoning on Realistic Long-context Multitasks. arXiv:2412.15204
  • * *

作者简介

AI 可能会生成不准确的信息,请核实重要内容