AI News HubLIVE
站内改写3 分钟阅读

突破上下文窗口限制:使用 Amazon Bedrock AgentCore 实现递归语言模型

本文介绍了如何利用 Amazon Bedrock AgentCore Code Interpreter 和 Strands Agents SDK 实现递归语言模型(RLM),从而能够处理任意长度的文档,彻底摆脱上下文窗口的限制。通过将文档作为外部环境,模型通过编程方式迭代分析,调用子LLM进行语义理解,实现无上限的文档处理能力。

来源AWS Machine Learning Blog作者: Yuan Tian

在处理数百万字符的文档时,上下文窗口的限制往往成为瓶颈,即使是最大的上下文窗口也无法满足需求。模型要么拒绝输入,要么基于不完整的信息生成答案。那么,如何推理超出上下文窗口的文档呢?本文将介绍如何使用 Amazon Bedrock AgentCore Code Interpreter 和 Strands Agents SDK 实现递归语言模型(RLM),从而处理任意长度的文档,且不受上下文大小的限制。

上下文窗口为何不够

考虑一个典型的财务分析任务:比较一家公司两年年报中的指标。每份报告约300-500页,再加上分析师报告、SEC文件等,总字符数可达数百万。当直接将文档发送给模型时,要么输入超出模型上下文窗口限制导致请求失败,要么输入虽适合但模型难以关注长输入中间的信息,即“中间迷失”问题。这些失败模式皆因上下文窗口大小是硬限制,仅靠提示工程无法解决。需要一种将文档大小与模型上下文窗口解耦的方法。

RLM:将上下文视为环境

RLM 由 Zhang 等人在 arXiv:2512.24601 中提出,彻底改变了这一思路。RLM 不将整个文档塞入模型上下文窗口,而是将输入视为模型可通过编程方式交互的外部环境。模型仅接收查询和可用环境的描述,然后编写代码来迭代搜索、切片和分析文档。当需要对特定部分进行语义理解时,模型将该分析委托给子LLM调用,结果保留在工作内存中(Python变量),而非占用上下文窗口空间。这形成了一个递归结构:根LLM通过代码编排分析,按需调用子LLM执行语义任务,而全文从未进入模型上下文窗口。

架构

下图展示了如何使用 Amazon Bedrock AgentCore Code Interpreter 作为执行环境来实现 RLM。架构包含三个组件:

  • 根LLM代理:基于 Strands Agents SDK 构建,接收用户查询并决定执行什么代码。
  • Code Interpreter 会话:以 PUBLIC 网络模式运行,文档作为 Python 变量预加载。
  • llm_query() 函数:注入沙箱,直接从 Code Interpreter 内部调用 Amazon Bedrock,子LLM结果保留在 Python 变量中,不会流回根LLM的上下文窗口。

Amazon Bedrock AgentCore Code Interpreter 的 PUBLIC 网络模式允许沙箱进行对外 API 调用,持久化会话状态使得变量和中间结果在多次代码执行间累积,为模型提供贯穿整个分析的工作内存。

实现步骤

前提条件:拥有 AWS 账户及 Amazon Bedrock 基础模型访问权限;Python 3.10+;配置 AWS CLI;熟悉 Python 和 Boto3;配置 PUBLIC 网络模式的 Bedrock AgentCore Code Interpreter;相关 IAM 权限。

步骤1:启动 Code Interpreter 会话并加载文档 创建 Bedrock AgentCore Code Interpreter 会话,将文档写入沙箱:

import boto3
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}]}
)

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

with open('_context.txt', 'r') as f:
    context = f.read()

def llm_query(prompt: str) -> str:
    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']

步骤3:创建 Strands Agent 并运行查询 使用 Strands Agents SDK 创建代理,配备 execute_python 工具,然后提交问题。代理将迭代编写并执行 Python 代码,探索文档,提取相关部分,并在需要时调用 llm_query()。

评估结果

我们在 LongBench v2 的金融多文档问答子集上进行了评估,包含15个多选题,每个问题需分析多份财务报告,上下文长度达约200万字符。对比了三种方法:Base(直接发送文档,200K token窗口)、Long Context(使用Claude的100万token扩展窗口)和 RLM。

关键结果:

  • RLM 消除了上下文长度失败:Base 成功率为46.7%,Long Context 为93.3%,而 RLM 在所有配置下均达到100%成功率。
  • RLM 提升了多数模型的准确率:对于 Claude Sonnet 4.6 和 Opus 4.6,RLM 将准确率从60.0%和66.7%提升至73.3%和80.0%;Claude Haiku 4.5 从33.3%提升至66.7%。但 Claude Sonnet 4.5 无提升(均为66.7%),表明 RLM 效果依赖于根模型分解任务的能力。
  • 子LLM选择影响有限:使用 Haiku 4.5 作为子LLM与使用相同模型作为根和子LLM相比,准确率无显著差异。

此外,在代码仓库理解子集(50个问题)上的测试表明,RLM 同样适用于代码库导航和函数依赖解析等任务。

结论

递归语言模型通过将文档视为外部环境并利用编程式交互,成功突破了上下文窗口的限制。结合 Amazon Bedrock AgentCore Code Interpreter 的持久化沙箱和子LLM调用能力,RLM 能够以100%成功率处理任意长度的文档,同时提升准确率。这一方法为大规模文档分析、代码库理解等场景提供了可行的解决方案。