@neural_avb: https://x.com/neural_avb/status/2063907440509571354

X AI KOLs Timeline 新闻

摘要

探索递归语言模型(RLM)中一个常见的失败模式,其中自由文本子代理响应会导致问题,并提出一种使用结构化输出提高可靠性的解决方案,通过NarrativeQA中的长上下文问答示例进行说明。

https://t.co/0bZ9bBrnnJ
查看原文
查看缓存全文

缓存时间: 2026/06/08 15:27

结构化输出让 RLM 智能体交流更健康

今天只有一个目标:理解递归语言模型常见的一种失败模式,以及一个简单酷炫的缓解方法。

递归语言模型让模型能回答远超其上下文窗口的问题,方法是将提示当作 Python REPL 中的一个变量。

如果你不熟悉 RLM,建议先阅读这篇文章,了解 RLM 的工作原理以及它与 ReAct、CodeAct 和普通子智能体等其他流行技术的区别。

AVB@neural_avb·3 月 21 日 文章递归语言模型——让我终于’顿悟’的时刻上个月我花了不少时间从头实现 RLM,并制作了 50 分钟的教程视频。在这个过程中,我在 Youtube 和 X 上回答了 100 多个问题……19119874171K

智能体编写代码来搜索、切片和分块文本,并且可以递归地在各个片段上生成子智能体。子智能体的答案会通过 REPL 值返回,也就是说,响应永远不会自动转储到父级上下文中。

生成一群子智能体来分治任务非常酷!但 RLM 的成败取决于它能否正确地提示子智能体:

(a) 它应该做什么, (b) 它应该返回什么, (c) 主智能体如何将子智能体的响应聚合为最终答案。

随着大实验室开始在其 RLM 框架内训练模型,我相信我们将看到语言模型自然进化,能够在 REPL 内高效地完成这些任务。但目前,模型仅仅通过上下文学习 RLM 模式和原始编程技能在 REPL 中工作。

换句话说,框架开发者的工作就是尽可能让语言模型在 RLM 中轻松工作。

我们在一个 LongBench/NarrativeQA 样本上遇到了所有这些问题:

上下文: 亨利·詹姆斯《科克森基金》全文约 107K 字符。基本上是一本故事书。

问题:“萨尔特拉姆的居住情况如何?”(萨尔特拉姆是故事中的一个人物)

正确答案:“他是马尔维尔家的客人。”

真相从未直接说出。整部小说中,弗兰克·萨尔特拉姆这个角色是马尔维尔家在温布尔登家中的永久房客(“inmate”)。

为什么这对于长上下文模型是一个技能测试任务?

这个事实只有通过阅读和联系才能得到。而不是通过关键词查找。

文字“萨尔特拉姆”通常并不靠近描述他住所的段落。

RLM 如何解决这种长上下文任务

当 RLM 遇到一个问题时,它的首要目标之一是决定是直接攻击问题,还是部署子智能体。

直接攻击意味着模型会尝试自己分割和分解输入上下文的各个部分,在自己的 REPL 中打印这些部分,然后找出答案。

部署子智能体意味着它会生成原始上下文的较短片段,让这些片段解决部分问题,然后将它们的发现聚合为一个连贯的响应。分而治之。

RLM 解决萨尔特拉姆问题的一种方法实际上是直接攻击,并在深度为 0 的 REPL 内完成。

这是正确答案,使用 Minimax M3 的成本约为 $0.04。而且它会起作用。模型会围绕关键数据点搜索并切片上下文,只读取那些相关部分!

但如果 RLM 选择子智能体方法呢?

子智能体 v1:自由文本扇出(失败)

在第一个实例中,智能体的直觉是教科书般的 RLM 操作:将上下文分块,并在每个块上映射一个子智能体,然后归约。这是几乎所有 RLM 系统提示中常见的模式之一,因此这并非无效选项。

它将约 107K 个字符分成固定大小的块,并行扇出自由文本子智能体,然后要求另一个智能体聚合这些响应!非常酷,但很快你就会看到一个问题:

接着它委托第二个语言模型来解决答案:

相当简单的技术。生成一群(62 个子智能体)来分析上下文的多个区域,然后让另一个智能体总结它们。但坏事发生了:

以下是它从这 62 个子智能体收到的一些响应:

  • sub2:“这段文字不包含直接引用描述萨尔特拉姆居住情况的句子。”

  • sub4:“文本中没有任何句子描述萨尔特拉姆的住所。萨尔特拉姆夫人只是被顺便提到……”

  • sub5:“提供的文本片段不包含关于萨尔特拉姆家、她的‘一套房间’或她住处的任何段落。”

  • sub0、sub1、sub3:……

结果呢?

第二个子智能体变得困惑,因为它有 62 个需要分类的响应,而且全都是文本形式的。我运行了一个 max-depth=1 的 RLM,所以在第二级,子智能体不允许生成新的智能体。

接下来是一连串的挣扎——根智能体无法清晰地读取子智能体的返回(它一直在打印),最终它只是手动编写了一个答案:

它做了很多事情,但都没有成功。这不是正确答案。它被 62 个子智能体的简短答案淹没了。

如果子智能体不是返回自由格式文本,而是被迫返回结构化响应就好了。

子智能体 v2:结构化输出路由(成功)

第二次运行也进行了扇出,但使用了结构化输出来干净地完成。

它没有要求子智能体提供散文(“描述他的居住情况”),而是向每个子智能体询问一个带有 JSON Schema 约束答案的真/假问题,然后读取那些回答“真”的块。

这看起来非常相似,但仔细一看,其中有一个非常重要的变化:

fast-rlm 库中,结构化 I/O 以简单的方式工作。当子智能体(或主智能体)收到 schema 请求时,我们验证它返回给主智能体的响应完全符合该 schema。没有例外。

AVB@neural_avb·5 月 20 日今天发布了新版本的 fast-rlm (v1.14)

此版本的新功能:

  • 输入 RLM 不必是字符串,可以是任何 Python 字典
  • 输出 schema 声明 -> RLM 保证以你设计的结构化输出返回
  • 智能体可以使用显式……Show more41514719K

你也可以定义更复杂的 schema,包含嵌套列表和对象(你可以在 zod 或 pydantic 中定义的任何内容),库会进行验证以确保 schema 始终满足要求。

所以现在,模型不再需要解析 40 种不同的“这段中没有提及萨尔特拉姆的居住情况”,而是可以直接查看这一个布尔标志,一切就清楚了!

产生幻觉的可能性更低,因为模型从不需要一次将太多故事读取到它的上下文中!

结果:正确!

在第一种无子智能体深度为 0 的方法和这种深度为 1 的方法中,我们实际上使用了相同数量的 token。事实上,使用 Minimax-M3 时两者成本都约为 $0.04。

但子智能体方法中产生幻觉的范围大大减少,因为你没有看到大量无关且令人困惑的文本!低功耗的推理模型在一次性读取太多 token 时完全可能失去线索。

布尔值充当了原始上下文的直接注意力掩码!对输入提示的外部稀疏化!

注意:布尔 schema 只是这里 RLM 选择的一个例子。理论上,智能体可以选择任何 schema 要求。在传回之前,它们都会经过验证和确保!

在 RLM 内部验证结构化输出

最后,我会提及结构化输出功能在 RLM 内部是如何实现的。

结构化输出模式不仅适用于主智能体调用子智能体!用户也可以对根智能体强制执行这个契约。

结构化输出模式不仅适用于主智能体调用子智能体!用户也可以对根智能体强制执行这个契约。

  1. Schema 归一化(Python)

你/智能体可以传递所需的输出 schema:Pydantic 模型、原始类型如 intlist[Model] 泛型、或原始 JSON Schema 字典。我们将其全部转换为普通的 JSON Schema(对于 Pydantic 使用 model_json_schema(),对于泛型使用 TypeAdapter,对于原始类型使用查找表)。

2. 智能体在 REPL 启动时看到契约

在第 0 步,智能体开始任何工作之前,我们向它显示所需的 JSON schema。因此,模型在编写任何代码之前就知道它必须返回的确切形状。

  1. 每次 FINAL 时验证

当 LLM 在 REPL 中调用 FINAL(answer) 时,我们获取 answer 的内容,并将其从子智能体返回给其调用智能体。但在返回答案之前,我们会进行 schema 验证检查!

如果验证通过,我们将结果按预期返回给主智能体。但如果失败,我们会向当前智能体发送反馈,告知确切的格式验证错误以及必须执行的预期格式。

4. 重试,不重启

失败时,智能体会同时收到 schema 和具体的错误信息(例如 (root): must be boolean)。REPL 的工作保持不变,所以模型只需要修正值并重新调用 FINAL

如果 schema 匹配,我们再次验证并批准!

仅凭这个简单的验证机制,RLM 就能解锁一个全新的操作维度。将精确的契约要求传递给子智能体,这些要求可以直接在 REPL 中使用。

查看 fast-rlm 仓库:https://github.com/avbiswas/fast-rlm

相似文章

ACL-Verbatim: 面向研究的无幻觉问答系统

Hugging Face Daily Papers

ACL-Verbatim 引入了一系列轻量级抽取模型,用于有来源的检索增强生成(RAG),能够从源文档中返回精确文本片段,性能优于基于大型语言模型的提取器。