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

TL;DR · AI 摘要
Amazon Bedrock AgentCore通过递归语言模型(RLM)架构,解决了长文档分析的上下文窗口限制问题,允许无上限处理文档并通过子LLM调用和代码解释器迭代分析。
核心要点
- RLM架构通过将文档视为环境,使用根LLM编写代码与之交互,并通过子LLM处理特定段落,突破上下文窗口限制。
- Amazon Bedrock AgentCore的代码解释器提供沙箱Python环境,保持工作内存状态,支持迭代分析长文档。
- 实现需要结合Strands Agents SDK,通过分阶段的LLM调用和结果累积,最终生成基于完整文档的准确响应。
结构提纲
按章节快速跳转。
长文档分析面临上下文窗口限制,直接输入模型会导致请求失败或信息处理不全。
RLM通过将文档视为可编程环境,利用根LLM编写代码并协调子LLM调用,实现无上限文档处理。
结合Strands Agents SDK和Bedrock AgentCore代码解释器,构建包含根LLM、执行环境和子LLM调用的三层架构。
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处理选定段落,并在工作内存中累积结果。
Amazon Bedrock AgentCore的代码解释器提供沙箱化Python环境,支持跨执行的持久化状态,实现无上下文限制的迭代分析。
架构通过将子LLM结果存储为Python变量而非嵌入根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. 递归语言模型通过迭代循环运作:根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的上下文窗口。
_
_
_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:InvokeModel、bedrock-agentcore:StartCodeInterpreterSession、bedrock-agentcore:InvokeCodeInterpreter和bedrock-agentcore:StopCodeInterpreterSession具有 IAM 权限。
1: 启动代码解释器会话并加载文档
创建 Amazon Bedrock AgentCore Code Interpreter 会话并将文档写入沙箱:
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 调用将使用此函数):
# 在 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(该工具在会话中运行代码),然后提交您的问题:
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
接着定位到具体章节提取收入表格:
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代码解释器会话:
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%准确率)。
无论是财务分析、代码仓库理解、医疗与生命科学研究、法律审查还是合规审计等需要处理长上下文或大型参考库的任务,均可从该模式中受益。若您尝试将此方法应用于自己的文档分析工作负载,欢迎分享您的成果和体验。
开始使用本文所述方法时,可参考以下资源:
- **Amazon Bedrock AgentCore** – 了解AgentCore服务及其构建生产就绪代理程序的功能
- **AgentCore代码解释器** – 深入了解本文实现中使用的代码解释器工具
- **Strands Agents SDK** – 探索用于构建本文RLM编排层的开源SDK
参考文献
- Zhang, A. L., Kraska, T., & Khattab, O. (2025). Recursive Language Models. arXiv:2512.24601
- 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
- * *