@johnsonshi86: https://x.com/johnsonshi86/status/2072112215097024961
摘要
描述了一种名为DR-DCI的优化方法,它将RAG与虚拟文件系统上的bash命令相结合,使代理能够进行精确的语料库检索,并讨论了为推理提供者扩展到分布式系统。
查看缓存全文
缓存时间: 2026/07/01 14:09
DR-DCI:作为推理提供商能力区分器的快速语料库检索
DR-DCI 是建立在 RAG 之上的一种优化方法,它让智能体能够在大规模文档集合中执行精确、可验证的搜索,而无需每次查询都扫描整个语料库。它保留了 RAG 式的第一遍扫描,即通过索引查找(如 BM25)将海量语料库缩小到一组可管理的候选文档。然后,它增加了第二层:这些候选文档被物化到一个虚拟文件系统,一个智能体可以直接操作的沙箱工作区。智能体随后在该工作区上执行真正的 bash 命令(grep、rg、cat、find)来搜索、交叉引用和验证证据。
这对推理提供商和框架构建者来说至关重要。围绕模型的框架(即它如何暴露工具、管理状态、限制模型可以触及的范围)越来越成为区分不同智能体栈的关键,而不是模型权重本身。框架设计直接影响工具调用的基准分数以及智能体在实际工作中的表现。
以下内容将 Dr-DCI 论文(通过 Jo Kristian Bergum 在 2026 年 AI 工程师世界博览会上的 X 帖子公开)转化为面向 Kubernetes 和分布式系统受众的系统术语,然后进行扩展:当语料库不在单台机器上时,运行此模式需要什么。这个差距正是使该模式在生产环境中大规模可用的关键,也是值得推理提供商探索和基准测试的地方。
约束:LLM 拥有固定大小的 RAM(内存),而不是磁盘
LLM 每次调用读取固定数量的 token,即上下文窗口。可以将其视为 RAM:速度快,但容量小且有界。文档集合(语料库)可能包含数十亿个文档。这是磁盘级别的数据。你不能将整个磁盘加载到 RAM 中。你需要一个索引,以及一种只获取相关部分的方法。
这个获取步骤在 AI 领域被称为“检索”。以下是执行检索的不同策略。
RAG:查询索引,获取文本块,完成
RAG(检索增强生成)是标准方法:
-
离线索引。 将每个文档分割成块(通常为 500 个 token)。将每个块通过嵌入模型处理,输出一个向量(几百个浮点数,代表含义,而不是精确的词语)。将所有向量存储在向量数据库中。
-
查询时。 将用户的问题嵌入到相同的向量空间中。对向量数据库运行近似最近邻搜索。返回最相似的 k 个块,通常为 5-20 个。
-
生成。 将这些块粘贴到 LLM 的上下文窗口中。LLM 仅使用提供的内容进行回答。
LLM 永远不会触及语料库的其余部分。它只进行一次检索,然后自行处理。
失败模式: 如果 top-k 结果集遗漏了真正的答案(因为块边界将事实分割成两半,或者嵌入相似性未能捕捉到同义改写),LLM 无法进一步查找。它只有一次对单个后端的请求,没有重试,没有回退,没有根据第一次响应进行第二次查询。
BM25:一种常见的检索器,嵌入的替代方案
BM25 是 RAG 中最典型的检索器之一,与基于嵌入的密集检索并列。它比神经嵌入早了几十年。不需要模型、GPU 或训练步骤。它是一种统计评分函数:根据查询词项在文档中出现的频率对文档进行排序,通过加权使得稀有词项比常见词项贡献更大,并根据文档长度进行归一化。构建一次倒排索引(词项到文档列表的映射,类似于任何全文检索引擎背后的索引:Lucene、Elasticsearch 的默认方式),然后直接查询。
索引直接来自语料库本身。在索引时对每个文档进行分词(拆分成单词、小写、去除停用词,有时还原为词根形式),每个存活下来的不同 token 都成为索引中的一个词项。查询在查询时以相同的方式进行分词。如果某个查询词项从未在任何文档中出现过,其倒排列表就是空的,没有匹配,而不是错误。
BM25 对于名称、ID、错误代码、代码符号的匹配快速且精确。但在将查询与使用不同词语表达相同含义的文本进行匹配方面,它不如嵌入方法,因为它需要查询和文档中有相同的 token,“car”和“automobile”没有共享任何 token,即使人类认为它们表示同一事物。
DCI:跳过索引,给智能体一个 Shell
直接语料库交互(DCI)是与 RAG 相反的另一极端。不进行预索引和排名,而是给 LLM 智能体提供真正的 Shell 工具:rg、grep、find、cat、read。智能体对原始语料库运行自己的命令,就像你对你没有索引的代码库运行 grep -r 一样。
这带来了 RAG 所不具备的精确性。智能体可以根据第一次搜索的结果发出第二次搜索,交叉引用两个文档,验证确切的字符串是否存在,遵循从文档 A 到文档 B 的引用。单次检索然后回答的过程无法做到这些。
失败模式: 在数十亿个文档上运行 grep -r 是没有索引的全扫描。与大规模查询未索引的表相同的问题:它会变慢,然后超时。
Dr-DCI:在 grep 之前使用 BM25 作为缓存填充步骤
如果你构建过缓存层,这部分应该会立即理解。Dr-DCI 使用 BM25 作为快速的第一遍扫描,填充一个小的工作集。然后智能体直接在这个工作集上执行 grep,即 DCI 部分。
循环过程:
-
智能体调用
pull(query, k)工具。这会在整个语料库上运行 BM25 搜索,并返回 k 个候选文档(整个文档,不是块)。 -
这些文档通过硬链接被物化为临时目录中的真实文件(工作区),因此没有复制成本。
-
智能体在该小目录(而非整个语料库)上运行 grep/rg/cat/read。
-
如果找不到需要的内容,它会使用不同的查询再次调用 pull。新的结果会被添加到同一个工作区。已经拉取的文件不会被重新获取。
即使底层语料库有 1000 万个文档,工作区也保持很小,大约 1000-1400 个文件。BM25 执行索引查找。一旦工作集缩小到足以容纳在本地磁盘上,DCI 就执行精确的、有状态的搜索操作。
为什么这更快且更准确
三种不同的失败模式,一种修复方法:
-
RAG。 分块会将事实分割到边界,智能体只看到一次获取的 top-k 片段。如果关键块不在 top-k 中,则无法进一步查找。
-
仅 BM25。 与 RAG 相同的片段限制:智能体看到的是片段的排序列表,而不是完整文档,并且无法跨结果进行交叉引用。
-
仅 DCI。 全语料库 grep 成本高昂,并且随着语料库分布到多台机器上而变得更加昂贵:每次搜索都触及一个分布式集合,而不是本地集合。
Dr-DCI 避免了所有这三种情况:BM25 将语料库缩小到一个小候选集,然后 DCI 对该有界集(而不是整个语料库)运行全精度搜索。
论文中的数字,相同基准、相同工具,仅访问模式不同:
原始 DCI 与 Dr-DCI 的挂钟时间对比。
原始 DCI 与 Dr-DCI 的挂钟时间对比。
相同的精度工具。挂钟时间快约 20 倍。因为智能体在大约 1000 个文件上操作,而不是整个语料库。
如何低成本填充工作区
挂钟时间的减少主要来自限制搜索范围,而不是通过某种预置技巧。无论语料库大小如何,工作区保持在大约 1000-1400 个文件,因此每次 grep 调用扫描几千个文件,而不是整个语料库。
填充这个有界工作区仍然需要低成本。论文中实现这一点的机制特定于单台机器:
-
硬链接,而不是复制。 物化一个拉取的文档会创建一个指向相同 inode 的新目录条目。不复制文件内容,不执行写操作。
-
拉取时去重。 框架在从调用 pull 添加新文档之前,会过滤掉工作区中已有的文档,因此重叠的检索结果不会重复工作。
-
根平面命名空间。 没有按排名或查询的文件夹。测试了按排名感知的子文件夹,但会降低准确性,脆弱的路径会混淆智能体的终端导航。排名在工具调用文本中报告,而不是在文件路径中。
-
有界读取。 读取和搜索工具的输出被截断并带有继续提示,因此一次跨工作区的 grep 不会淹没模型的上下文窗口。
硬链接之所以有效,是因为语料库、索引和工作区都在同一块磁盘上。论文从未明确说明这是一个假设。这是从机制中推断出来的:硬链接不能跨机器指向,因此这种设计仅当语料库、索引和工作区共享磁盘时才有效。将语料库分布在多台机器上,这个机制就会失效。
应用于分布式系统
论文在单台机器上运行所有内容。将工作区边界化的想法转化为能够在分布式语料库上维持的东西,基本上尚未探索,这也是下一步值得深入的部分。
论文直接测量了一种成本:跨语料库的搜索成本。原始 DCI 的全语料库终端搜索时间在其结果中超时,恢复的工具结果持续时间显示 p50/p90/p95/p99 单工具时间为 12.4 秒/97.0 秒/167.2 秒/310.2 秒,最大值为 24,418 秒。Dr-DCI 的工作区边界化解决了这一成本。
一旦语料库、索引和计算不在同一台机器上,就会浮现第二项成本:工作区创建和物化,即将检索到的文档字节从它们所在的位置移动到智能体的工具运行的位置。在单台机器上,这一成本是硬链接,免费。跨机器,这是真正的网络获取。
这是两项独立的成本:
-
分布式搜索成本。 在分片语料库上运行 BM25。通常的解决方式与任何分片搜索引擎相同:查询扇出到 N 个分片,每个分片本地评分,结果集中合并。
-
工作区创建和物化成本。 在 BM25 对相关文件进行排名后,必须将这些文件移动到沙箱工作区,智能体的 bash 工具才能操作。这个收集和预置的成本是独立的,一旦语料库不是本地存储,就会显现出来。
第二项成本与本地情况一样是有界的:每个查询大约 1000 个小文档,而不是整个语料库。假设每个文档 50KB,大约 50MB,可以并行获取。
弥合差距:五种模式
前四种模式是架构性的。第五种是操作性的。
1. 分片本地性
BM25 分片是语料库的一个分区:将语料库分成 N 份,每份拥有自己的倒排索引(从词项到包含该词项的文档列表的查找,包含词频和文档长度用于评分,仅基于该分片的文档构建)。该索引在离线状态下构建一次,在任何查询运行之前,写入磁盘作为静态文件,就像数据库构建并持久化索引而不是每次查询重新计算一样。查询分别对每个分片进行评分,然后每个分片的评分在中心合并并重新排序。
将分片与数据共置意味着将该分片的倒排索引和其分区中的实际文档文件存储在同一台主机上。只需要一个分片的查询永远不会离开该主机,没有网络跳转来物化结果。需要不同分片的查询会跨越主机边界,这是真正的成本,而不是像数据中心这样粗略的概念。
值得注意查询字符串本身的来源:在 Dr-DCI 中,pull(query, k) 接收的不是原始用户查询,而是智能体决定编写的任何搜索字符串。智能体本身已经在推理任务,因此查询公式化作为该推理的副产物发生,不需要单独的查询重写步骤。那些还没有 LLM 生成查询的系统(例如传统搜索框),通常出于相同原因会在 BM25 前面添加一个廉价的重写或扩展步骤:原始用户文本经常错过索引所需的确切 token。
2. 内容可寻址缓存,限定在不变的内容上
论文中的去重仅适用于一个智能体轨迹内部。一个由内容哈希键控的共享缓存将对同一文档的第二次引用变成缓存命中,而不是第二次获取。策略根据语料库是否变化而有所不同。
不可变内容(存档的新闻文章、完成的备案):按内容哈希键控,永久缓存。这与拉取式注册中心缓存(Harbor、Zot 或任何符合 OCI 规范的镜像)形状相同,按摘要寻址内容,没有可能的失效逻辑,因为键不能改变。多层版本(本地节点缓存,然后区域镜像,然后原始存储)以相同方式工作:一个层的未命中会检查下一层,然后再到原始存储,结果会写回所有发生未命中的层。
可变内容(Wiki 页面、工单、正在编辑的文档):当前内容的哈希不是一个稳定的键,因为内容一改变键就变了。过时的条目可能会默默地提供陈旧的数据。需要缓存失效。
可变内容的分层缓存:每节点内存缓存(L1,最快,最小),共享缓存如 Redis(L2,跨节点共享),以及其后的数据源(L3)。L2 易于保持正确:写穿透更新 Redis 和数据源一起。L1 是风险点:如果没有通知数据已更改,每个节点的本地副本可能会默默变陈旧。两种修复方法:L1 上的短 TTL,因此陈旧性有界且可自愈;或发布/订阅失效,即“此键已更改”事件(例如 Redis keyspace 通知)广播到每个节点,以便 L1 在收到时驱逐该键。TTL 更简单且最终一致。发布/订阅更精确,但增加了一个每个节点都必须正确处理依赖。
在实践中,大多数真实语料库同时需要两种路径:一个长期存在的内容可寻址缓存用于不可变的多数,以及一个版本化或写穿透路径用于变化的子集。
3. 快速沙箱设置和拆除
每次 pull() 调用会为一次查询物化一个工作区,然后丢弃它。如果该工作区是一个沙箱环境(微虚拟机或轻量级容器),而不是共享磁盘上的一个目录,那么创建和销毁成本与数据移动成本一样重要。
一个预置了语料库访问工具的基础镜像,加上每个查询的一个薄层写时复制层,可以使设置近乎瞬间,并消除拆除时的任何清理成本。这与智能体沙箱运行时已经为代码执行解决的问题相同,只是应用于语料库搜索工作区。
4. 基于排名预取
pull() 在智能体决定检查什么之前已经返回了一个排名列表。在智能体读取排名预览的同时,并行获取完整的 top-k 文件,可以将获取延迟隐藏在模型自身的推理步骤之后。
5. 预计算热门查询结果
一旦投入生产,查询模式并不是均匀的。某些文档被拉取的频率远高于其他文档。跟踪哪些文档在查询中最常返回,并提前将它们预置到共享缓存中,而不是等待第一次未命中时才填充。
具体到 BM25,还要为最常见的查询或查询词项缓存排名后的结果列表,以便重复查询完全跳过评分步骤,直接命中缓存。这使得模式 2 中的内容可寻址缓存能够在第一个真实查询到达之前变热,而不仅仅是反应性地填充。
来源论文:Dr-DCI: Scaling Direct Corpus Interaction via Dynamic Workspace Expansion,arXiv:2606.14885(2026年6月)。
原始帖子:Jo Kristian Bergum 在 X 上,2026 年 AI 工程师世界博览会。
致谢 @zhuofengli96475(及其他论文作者)和 @jobergum 的演讲。
相似文章
Dr-DCI:通过动态工作区扩展实现直接语料库交互的规模化
本文介绍了DR-DCI,一种由检索器引导的框架,通过动态扩展本地工作区来扩展直接语料库交互,从而在大型语料库的智能搜索中提高了准确性和效率。
@leerob: https://x.com/leerob/status/2065469795529588940
Cursor AI 描述了其用于扩展 Composer 模型训练的递归代理系统,该系统使用一组自我管理的代理,在出现问题时向人类发出警报。该系统支持并行实验并加速研究,将研究人员的时间视为最稀缺的资源。
@ryancarson: https://x.com/ryancarson/status/2064751272834593135
利用 Devin AI 设置自动化代理驱动灾难恢复的详细指南,涵盖两种备份策略(PITR 和异地备份)、执行行动手册以及现场破坏性测试。
@zhuofengli96475: DCI刚刚在Hugging Face每日论文中登顶第一!立即试用!@HuggingPapers https://huggingface.co/papers/2605.05242…
DCI(直接语料交互)提出使用简单的终端工具如grep和bash进行智能搜索,无需嵌入或向量索引,表现优于传统检索方法。
我刚刚为了可靠性重写了整个代理基础设施,有人也这样做吗?
作者描述了在遭遇级联故障后,使用DBOS持久化执行重写其AI代理基础设施以提高可靠性的经历,并向社区询问类似的经历、工具选择以及自建与购买决策。