当索引超过窗口时,搜索范式本身就到了极限。
搜索已经成功了
我们讨论过RAG的局限。 嵌入相似度的不准确、分块的随意性、质量判断的不可能。
但那个讨论是关于搜索的质量。 “我们怎样才能搜索得更准确?”
现在必须问一个不同的问题。 假设搜索是完美的。 假设它只返回与查询精确相关的信息。
仍然有它不奏效的情况。
规模的问题
一个内部知识库有1000条陈述。 有一个索引。把索引放进上下文。查询。检索结果。 有效。
陈述增长到100,000条。 索引变大了。仍然能放进窗口。有效。
陈述增长到1000万条。 索引本身超出了窗口。
这不是搜索质量的问题。 无论搜索多么准确, 如果搜索必须查阅的索引放不进窗口, 搜索就根本无法开始。
而知识在增长。 企业文档每天增加。 Agent学到的东西不断积累。 世界的知识不会缩减。
更大的窗口能解决吗? 如果128K变成1M变成10M? 如果知识达到1亿条,同样的问题再次出现。 窗口总是有限的,知识总在增长。 这种不平衡是永久性的。
搜索和探索的区别
搜索通过一次查询获得结果。
查询:“三星电子2024年第三季度营业利润” -> 结果:9.18万亿韩元。
一次查询。完成。
探索通过多个步骤到达结果。
第一步:查看顶层知识地图。“企业”、“产业”、“宏观经济”、“技术”…… -> 选择"企业"。
第二步:查看企业地图。“三星电子”、“SK海力士”、“现代汽车”…… -> 选择"三星电子"。
第三步:查看三星电子地图。“财务”、“人事”、“技术”、“法务”…… -> 选择"财务"。
第四步:查看财务地图。“季度业绩”、“年度业绩”、“投资计划”…… -> 选择"季度业绩"。
第五步:从季度业绩中检索"2024年第三季度"。 -> 营业利润:9.18万亿韩元。
结果相同。 过程不同。
搜索是问"你有这个吗?" 探索是追踪"它可能在哪里?"
搜索要求索引对查询者可见。整个索引必须可访问。 探索只需要看到地图的当前层。每一步只有一层进入窗口。
图书馆类比
你去了一个社区图书馆。 它有3000本书。 你问图书管理员:“有李舜臣的传记吗?” 管理员记得:“在第三排书架的尽头。” 搜索。有效。
你去了国家图书馆。 它有1000万册藏书。 你问图书管理员:“有李舜臣的传记吗?” 管理员也不知道。没有人能记住1000万册书。
取而代之的是有一套分类体系。
你查看一楼目录。-> “历史"区在三楼。 你去三楼。-> “韩国史"在东翼。 你去东翼。-> “朝鲜王朝"在D排。 你去D排。-> “人物"在D排第三区。 你搜索第三区。-> 有李舜臣传记。
管理员的记忆容量没有变。 图书馆的规模变了。 方法从问管理员(搜索)变成了走分类体系(探索)。
关键在这里。 在每一步中,必须查看的内容大小都在管理员的记忆容量之内。 一楼目录。三楼区域图。东翼的排列表。D排的分区列表。 全部一眼就能看完。
所有馆藏的完整目录一眼看不完。 但每层楼的地图可以。
这就是探索与搜索的不同之处。 你不需要一次看到全部。 你只需要从当前位置判断下一个方向。
地图的地图
用技术术语来说,这是地图的层级结构。
第一层地图:所有知识的顶层分类。 “这个知识库包含企业、产业、宏观经济和技术方面的信息。” 几十个条目。放得进窗口。
第二层地图:每个顶层分类的子类别。 “企业类别包含三星电子、SK海力士、现代汽车……” 几十到几百个条目。放得进窗口。
第三层地图:每个子类别的详细类别。 “三星电子包含财务、人事、技术、法务……” 几十个条目。放得进窗口。
实际陈述:最低层地图指向的具体信息。 “三星电子2024年第三季度营业利润为9.18万亿韩元。”
如果每层的大小都在窗口之内, 无论知识的总规模多大,探索都是可能的。
即使有1000万条陈述, 如果每层有100个条目,5步探索就能到达目标。 100 -> 100 -> 100 -> 100 -> 100 = 覆盖可达100亿。 每一步只有100个条目进入窗口。
这和B-tree在磁盘上查找数据的方式一样。 它不会把所有数据加载到内存。 它只读取树的当前节点,然后移动到下一个。 无论数据规模多大,都可以在不超出内存的情况下探索。
上下文窗口是内存。 知识库是磁盘。 地图是B-tree节点。
Agent在行走
在多步探索中,每一步是谁选择方向?
Agent。
把第一层地图放进上下文。 Agent阅读它,与查询对比,选择"企业"方向。
请求第二层地图。 企业的子类别地图进入上下文。 Agent阅读它,选择"三星电子"方向。
请求第三层地图。 Agent选择"财务”。
这是Agent的工具使用。 阅读地图是一次工具调用。 选择方向是一次判断。 请求下一张地图是下一次工具调用。
在搜索中,Agent查询一次就收到结果。被动。 在探索中,Agent进行多次判断并选择方向。主动。
这就是上下文工程与Agent设计相遇的地方。 什么进入上下文,是通过Agent的判断一步一步决定的。 上下文的构建从静态组装转变为动态探索。
这个问题今天几乎没有被讨论
看看RAG社区的讨论, 大部分精力集中在搜索质量上。
更好的嵌入模型。 更好的分块策略。 重排器架构。 混合搜索。 Graph RAG。
都很重要。 都是关于"如何从一次搜索中获得更好的结果”。
“如果一次搜索不够怎么办?“几乎没有被讨论。
索引超出窗口的那个点。 结果多到放不下的那个点。 知识的规模打破搜索范式本身前提的那个点。
那个点正在到来。 知识在增长,窗口是有限的。
目前大多数解决方案是回避。 只检索top k。丢弃其余。 扩大窗口。成本增加。 分区知识。按领域分离向量存储。
当规模进一步增长时,所有这些都会再次遇到同样的问题。
探索的前提条件
探索要有效,知识必须处于可探索的结构中。
层级必须存在。 如果知识是平铺的,探索不可能。嵌入向量存储是平的。所有块在同一层级。没有层级,就没有"深入"的概念。
每层必须放得进窗口。 如果单张地图超出窗口,探索就失败。层级中每一层的选项数量必须是合适的大小。这是分类设计问题。
路径必须多样。 必须能通过多条路径到达同一信息。通过"三星电子 -> 财务 -> 营业利润"或者通过"半导体产业 -> 主要企业 -> 三星电子 -> 业绩”。因为自然的路径因问题而异。如果分类标准固定为一种,它适合某些问题,不适合另一些。
文件夹结构有层级但只有一条路径。 一个文件只属于一个文件夹。 只存在"三星电子/财务/营业利润"这条路径。 当一个关于"半导体产业"的问题来到时,通过这个文件夹结构自然探索是不可能的。
图有层级也有多样的路径。 一个节点可以连接到多个父节点。 三星电子节点可以通过"企业"路径、“半导体产业"路径或"KOSPI上市公司"路径到达。 无论问题从哪个上下文出发,都存在自然的路径。
这是一个未解决的问题
有一件事必须坦诚说明。
多步探索的需求是清楚的。 但目前还没有标准系统能有效地实现这一点。
如何自动生成地图的层级? 如何确定每层的合适大小? 当Agent选错方向时会怎样? 随着探索深度增加,延迟会怎样?
这些都是开放性问题。
但问题未被解决 不意味着问题不存在。
知识在增长。 窗口是有限的。 仅靠搜索不够的那个点正在到来。
探索必须作为那个时刻的答案准备好。 如果没有准备好, 剩下的选择只有扩大窗口或丢弃知识。
总结
搜索通过一次查询返回结果。 当知识规模增长到足够大时,这是不够的。 因为索引本身超出了窗口。
探索沿着层级地图,一边选择方向一边下行。 每一步必须查看的内容都在窗口之内。 无论总规模多大,每一步都是有限的。 就像B-tree在不把整个磁盘加载到内存的情况下查找数据。
Agent在每一步判断方向。 上下文的构建从静态组装转变为动态探索。 这就是上下文工程与Agent设计相遇的地方。
探索要有效,知识必须是层级化的,每层必须是有限的,路径必须是多样的。 文件夹结构只有一条路径。图有多样的路径。
这仍然是一个没有标准解决方案的未解决问题。 但只要知识在增长、窗口是有限的,它就是一个必须解决的问题。