让LLM写代码来读取1000万Token?RLM的工作原理
更大的上下文窗口并不能让AI更聪明。RLM通过让LLM编写代码从海量文档中选择性读取所需内容,彻底颠覆了传统思路。
“上下文窗口更大,模型就更强。”
这句话在2024年还是共识,到了2026年已经变成了陷阱。128K、1M甚至更长的上下文窗口确实在技术指标上不断刷新纪录,但实际使用中,把海量文本一股脑塞进去的效果远没有想象中那么好。RLM(Recursive Language Model)提出了一个完全不同的思路:别让模型硬啃所有内容,让它自己写代码去挑需要的部分来读。
上下文腐烂:为什么更大的窗口救不了你
LLM的工作本质是对输入Token序列计算概率分布。输入越长,相关信息和噪声混在一起的比例就越失控。
现实数据很残酷。号称支持128K上下文的模型,实际准确率的甜蜜区大约在10K Token左右。超过100K Token之后,性能会出现断崖式下跌 - 模型开始”忘记”早期内容,对中间片段的注意力严重不足,回答质量明显下降。
这就是所谓的”上下文腐烂”(Context Rot)。不是模型不够聪明,而是信噪比崩了。你塞给它一本500页的技术手册让它回答一个具体问题,它需要在海量文本中大海捞针。注意力分散到每一个Token上,真正有用的那几段反而被淹没了。
更大的上下文窗口解决的是”能不能放得下”的问题,但没有解决”能不能用得好”的问题。
RLM核心思路:不要全部读完,按需提取
RLM的核心理念用一句话概括:把LLM当CPU,把文本当硬盘。
传统方式是把所有文档塞进上下文窗口(相当于全部加载到内存),RLM则是把1000万Token的文档存储在Python变量里,让LLM编写代码来选择性读取需要的部分。每次实际处理的Token量大约只有5万 - 刚好落在模型表现最佳的区间。
这不是简单的RAG检索。RAG依赖向量相似度做粗粒度匹配,容易遗漏语义复杂的关联内容。RLM让模型自己决定”我要看哪一段、用什么逻辑去筛选”,本质上是把数据访问的决策权交还给了LLM本身。
三大核心组件
RLM的架构拆成三个部分,各司其职。
RLM Orchestrator(编排器)
整个系统的控制中枢。负责维护消息历史、控制迭代循环、判断何时终止并输出最终答案。它不直接处理文本,而是协调下面两个组件的工作节奏。
LMHandler(语言模型处理器)
一个Socket服务器,专门处理LLM的API请求。关键设计在于:它允许在代码执行过程中发起LLM调用。也就是说,LLM写的代码跑到一半,可以再调用LLM来处理中间结果 - 这就是”递归”的含义所在。
Environment / REPL(执行环境)
一个Python沙盒环境。文档内容存储在 context 变量中,LLM可以用标准Python语法对其进行切片、过滤、正则匹配等操作。同时提供 llm_query() 函数,支持在代码中递归调用LLM处理子问题。
三者配合的逻辑非常清晰:Orchestrator发出指令,LLM在REPL中编写并执行代码访问 context,需要进一步理解时通过 llm_query() 发起子查询,LMHandler接收请求并返回结果,最终Orchestrator汇总所有信息生成答案。
执行流程:探索、分解、聚合
一次典型的RLM执行过程分为四个阶段。
探索(Explore):LLM先试探性地了解数据结构。比如执行 print(context[:500]),看一眼前500个字符,搞清楚这份文档是什么格式、什么主题、怎么组织的。
分解(Decompose):根据探索结果,LLM把原始问题拆成多个子问题。对文档进行分块处理,针对每个块调用 llm_query() 提问。比如一份10M Token的代码库,LLM可能先按文件分块,再对每个文件问”这个文件和用户问题有关吗?”。
聚合(Aggregate):把所有子查询的结果收集起来,用Python做数据处理(排序、去重、统计),或者再调用一次LLM做最终综合。
终止(Terminate):当LLM认为已经收集到足够的信息,输出 FINAL(answer) 结束整个流程。
整个过程是迭代式的 - 如果某一轮的结果不够充分,Orchestrator会让LLM继续探索。
和Ralph Wiggum插件的关系
如果你用过Claude Code的Ralph Wiggum插件,会发现两者的哲学惊人地相似。
Ralph Wiggum的核心机制是Stop Hook - 在Claude Code即将终止时拦截退出信号,重新注入提示词让它继续工作。本质上就是一个迭代循环:执行、评估、如果没完成就继续。
两者共享的设计原则:
- 迭代循环:都不是一次性给出答案,而是通过多轮交互逐步逼近目标
- 失败即数据:某一轮没得到有用结果?没关系,这本身就是信息,用来指导下一轮的策略调整
- 自主决策:LLM自己决定下一步做什么,而不是按预定义流程走
区别在于应用场景:RLM专注于超大规模文本的理解和处理,Ralph Wiggum专注于自主开发任务的持续执行。但底层思路是一脉相承的 - 让AI成为主动的信息获取者,而不是被动的文本消费者。
实战建议
如果你想在自己的项目中借鉴RLM的思路,几条经验值得注意。
批量处理优于逐条处理。 不要一次只查询一个文档片段。把相关的片段打包一起处理,减少LLM调用次数。
正则预过滤。 在调用LLM之前,先用Python正则表达式做一轮粗筛。比如找特定函数的实现,先 re.findall() 定位到相关文件,再让LLM精读。这一步能砍掉90%以上的无关内容。
递归深度限制在1层。 虽然 llm_query() 理论上可以无限嵌套,但实践中递归超过1层后,成本爆炸、延迟飙升,而且结果质量反而下降。保持一层递归就够了。
滚动窗口管理历史。 Orchestrator的消息历史不能无限累积,否则又回到了上下文腐烂的老问题。保留最近几轮的关键信息,老的轮次做摘要压缩后存档。
结论
RLM给出的启示很明确:与其暴力扩大上下文窗口,不如让模型学会更聪明地访问数据。
上下文窗口从4K扩到128K再到1M,成本越来越高,边际收益越来越低。而RLM用5万Token的实际处理量,撬动了1000万Token的文档理解能力。差距不在于”看了多少”,而在于”怎么看”。
这和整个AI Agent的发展方向高度一致 - 从”一次性推理”走向”迭代式探索”,从”被动接收所有输入”走向”主动选择需要的信息”。未来的LLM应用,比的不是谁的上下文窗口更大,而是谁的信息获取策略更聪明。
订阅通讯
获取关于我最新项目、文章以及 AI 和 Web 开发实验的更新。