资讯动态

面向AI Agent的联邦搜索:多源检索编排的架构与落地

发布时间:2026/8/28 2:34:09 来源:尧图企业网站定制
最近在帮一个团队梳理AI客服Agent的检索链路。这个场景里真正缺的是Federated Search for AI Agents也就是面向AI Agent的联邦搜索。他们的Agent后面接了八个数据源内部Wiki、产品说明书、工单系统、退货政策、物流信息、商品数据库、历史对话、用户画像服务。单看每个数据源都能回答一部分问题但用户一旦问“我昨天买的商品为什么还没发货如果拒收要收手续费吗”Agent就开始串源先查订单再查物流再查退货政策最后还花了一轮对话去猜“拒收”到底是什么意思。整个过程接近20秒结果还把旧政策和新政策搞混了。这个问题不是“多接几个数据源”能解决的。这是检索架构的问题。Agent需要的不是更多工具而是一层能够统一规划、分发、融合和溯源的检索编排层。这层东西在信息检索领域其实有一个并不新的名字——联邦搜索但当调用者从“人”变成“AI Agent”时问题变得更复杂也更值得重新讲一遍。我有一个比较明确的判断面向AI Agent的联邦搜索真正价值不是把多个搜索结果拼在一起而是让Agent在信息分散、来源异构、口径不一的环境里仍然能做到“查得对、查得快、查得可验证”。如果只把它理解成“多个搜索接口的聚合器”落地时一定会被权限、延迟、融合和评测问题反复卡住。下面我会从问题模型、核心链路、落地路径、场景取舍、排查方式、长期能力六个角度展开。这篇文章不绑定某一个具体开源项目或商业产品而是讲清楚一个团队如果要自己做这层能力应该怎么思考。1. 先搞清楚Agent 的检索困境到底卡在哪1.1 Agent 缺的不是工具而是“检索编排层”我们看现在的大模型应用架构。Agent普遍通过 function calling 或者 MCP 这类方式挂载工具。工具的本质是“可调用的API”每一个API背后可能是一个知识库、一套系统、一组权限。这个架构本身没有错但它把“找哪个工具、按什么顺序调用、怎么比较结果”这整件事全部交给了模型的实时推理。这就是问题所在。工具少的时候比如只有两个工具模型还能蒙对。一旦工具变成八个、二十个、五十个模型就会反复犯三类错误选错源用户问的是订单状态模型去查了商品规格表。反复轮询模型不确定该查哪个就把所有工具挨个调一遍。结果冲突无法处理多个工具返回了不同口径的答案模型只能选一个“看起来合理”的但无法解释为什么另几个不对。我用一个类比解释Agent现在很像一个刚入职的实习生。老板只说“你去把这事查清楚”然后给了他一整张通讯录但没告诉他谁负责什么、谁有权限、回答格式是什么、应该先找谁。他只能挨个打电话碰到回答含糊的再打一遍最后把几个人的说法拼在一起分辨不出哪个更可信。联邦搜索要做的不是再给他加几个电话而是给他一张“分工表、统一话术和结果复核流程”。这里的核心概念是检索编排层。它不是数据源也不是模型而是Agent与多个信息源之间的一个中间层。它负责决定查哪里、怎么查、结果怎么合并、权限怎么过滤、引用怎么保留。1.2 很多团队目前做的其实是“伪联邦”另一种常见做法是把公司里所有文档、工单、客服记录全部同步到一个向量数据库做成统一的知识库然后让Agent只对着这个库做检索。这在一部分场景中确实有效但它不是联邦搜索。我把这种方案叫“伪联邦”因为它的入口是统一的但代价是破坏了源自治权限边界被抹掉。所有数据导入同一个向量库最细粒度可能只能做到“文档级别”的可见性很难还原每个源内部的团队级、账号级权限。实时性被牺牲。源数据变化到索引更新存在时间窗订单状态、工单状态这种高频变化的字段容易查到旧值。结果归因变难。文档在向量库里经过切分、嵌入之后和原始系统的关联链容易被拉长Agent无法直接跳回原系统核对。伪联邦不是不能做。对一个内部资料相对稳定、权限不敏感、内容以文档为主的场景集中式索引反而是更简单的方案。但如果你想构建的是一个能回答订单、物流、政策、账单等多类型问题的Agent你必须面对一个现实很多数据不应该、也无法全部集中到一个库里。这时候联邦搜索就不是“可选项”而是“不得不做的架构”。下表可以帮团队快速判断自己属于哪种形态形态实现方式典型问题适用场景集中式RAG所有数据入库统一索引权限粗、更新慢、归因弱静态文档知识库伪联邦接入多个工具模型自行选择调用误选、重复调用、结果冲突工具数量少的小验证真联邦统一路由、归一化、融合、引用工程复杂、需要评测多源、异构、权限敏感的业务系统这里不是说得不到结论而是说如果Agent要长期面对分散的信息系统联邦搜索应该被当成一个独立架构去设计而不是作为模型的临时发挥。2. 联邦搜索的核心链路一次查询怎么变成多源协同2.1 一次典型查询的完整路径先把链路拆开。一次面向AI Agent的联邦搜索通常包含以下步骤Agent收到用户问题。调度层判断需要哪些信息源可能先从源注册表里筛选候选源。查询改写每个源对查询格式、参数、语义的要求不同需要生成适配每个源的查询。并发分发对多个源发起查询而不是串行等待。源内检索每个源在自己的系统里执行检索返回本地结果。结果归一化把不同源的字段、分数、格式统一成一套结构。融合排序合并相同主题的结果计算新的排序。权限校验与过滤确保Agent当前会话只能看到有权限的内容。引用组装把结果映射回原始系统带上可点击、可回查的引用。返回给Agent由模型生成最终答案。这个链路和普通元搜索最大的不同在第3、4、8、9步。普通元搜索更多是“把结果并列展示给用户”而Agent需要的是“把结果压缩成可用于推理的上下文”同时还要保证权限和引用可验证。这也是为什么不能把旧的联邦搜索代码直接照搬过来。2.2 三个关键机制路由、归一化、融合排序从工程实现角度有三个机制决定了这个链路是否能真落地。第一是查询规划和路由。你不可能每次查询都打给所有源。正确的做法是建立源注册表为每个源描述能力边界、字段结构、鉴权方式、延迟、最大条目数、更新频率。调度层根据用户问题、历史命中率、目标源可用性来做路由。路由策略可以从简单规则开始比如“用户问题中包含订单号就路由到订单系统包含退货就路由到退货政策库”。当源数量增多后再考虑用分类模型或轻量级 rewrite 模型做自动路由。不要一开始就上模型规则足够稳定。第二是结果归一化。不同源返回的结果字段命名可能完全不同。比如“标题”在A源叫 title在B源叫 name“时间”可能是 int 时间戳也可能是字符串。如果不做归一化融合阶段会非常痛苦。归一化层至少要输出一个统一结构doc_id、source_id、title、snippet、content、url、authority、timestamp、ext_permission。第三是融合排序。最简单高效的方法之一是 Reciprocal Rank Fusion简称 RRF。核心思想是对于同一个候选结果在多个源的排名越靠前它的融合分越高。RRF 对分数域不敏感不需要每个源返回标准化的 score。它的公式大致是score sum over sources of 1/(k rank)其中 k 是平滑常数常见取 60。RRF 适合做第一版。后续可以在 RRF 选出的 Top 候选上再让一个重排模型根据用户问题语义做精排。对 Agent 场景我不建议一上来就上重排模型先用 RRF 把候选压到 20 条以内再交给模型成本和效果都更容易控制。2.3 一个最小协议示例下面是一个统一检索请求的示意结构不绑定某个具体框架只说明字段应该长什么样{ query: 昨天买的商品为什么还没发货, session_id: user_123, user_permissions: [order.read, logistics.read], max_results: 15, sources: [ {id: order_system, params: {order_id: xxx}}, {id: logistics_service, params: {keyword: 发货 延迟}} ], timeout_ms: 3000 }对应的统一结果片段{ results: [ { doc_id: order_system:ord_001, source_id: order_system, title: 订单 20240912, snippet: 当前状态已出库物流等待揽收, url: http://order-system/internal/ord_001, timestamp: 1725955200, score: null, rank_in_source: 1 } ], total_elapsed_ms: 180 }score 可以留空让融合层自己算。rank_in_source 比 score 更重要因为 RRF 依赖的是排名而不是分数。注意超时一定不能只靠外部兜底。每个源的超时、整体链路的超时、以及融合阶段的截断都要在协议里显式定义否则一个慢源会拖垮整个 Agent 响应。3. 落地实操从“两源一查”开始建一个检索层3.1 不要先建中台先定义清楚“源”很多团队一听要做统一检索层第一反应是造一个庞大的“搜索中台”把所有源都接进来再做统一配置、权限、监控。我建议反过来先把两个你最能控制、最有业务价值的源接入跑通一次端到端查询然后再逐步加源。原因是联邦搜索的复杂度不会在一开始暴露而是在接入第三个源、第五个源之后才出现。如果一开始就把所有源纳入你会同时面对字段不一致、权限差异、延迟波动、重复文档等问题根本分不清先修哪个。启动前需要给每个源写一份配置。这是最小配置source_id: order_system description: 用户订单状态查询 auth: internal_service_account endpoint: http://order-service/search query_fields: - order_id - user_id response_schema: id: id title: title content: raw_text timestamp: updated_at permissions: - order.read timeout_ms: 1500 max_results: 10这一份配置会同时被路由层、归一化层和权限层使用。命名尽量统一后面接入更多源时维护成本才低。3.2 一个最小可用流程假设现在有两个源一个是内部知识库存的是政策和流程文档一个是工单系统存的是历史客服工单。用户的问题是“退货要收手续费吗”。最小流程可以按下面几步写先用规则路由问题包含“退货”“手续费”关键词选择政策知识库和历史工单两个源。并发调用两个源各返回自己的检索结果。把结果统一成同样的结构并保留 source_id 和 rank。用 RRF 做融合排序取 Top 8。把结果拼装成 Agent 可用的上下文每个结果前面加上来源标签。在上下文中附带引用信息例如“源自知识库的《退货政策》原文链接”。伪代码示意sources route(query, source_registry) raw_results parallel_query([knowledge_base, ticket_system], query) normalized [normalize(r, source.schema) for r in raw_results] fused rrf_fusion(normalized, k60) top fused[:8] context build_context_with_citations(top) answer agent.generate(query, context)这里真正重要的是第5、6步。Agent 看到的不应该是一堆碎片文档而是带有来源、时间和可信度提示的结果片段。这样模型在生成时才知道引用哪个来源而不是把多个来源的冲突信息混在一起。3.3 关键参数先保守再收紧第一版跑通时大部分参数应该先给一个保守默认值不要追求极限性能。下面是一张建议起点表参数含义建议起点风险单源超时每个源最多等待多久1.5s~3s太短会漏结果太长会拖慢整体整体超时联邦层整体最迟返回3s~5s必须小于Agent外层超时并发数同时查询几个源3~5源过多时容易打满下游单源max_results每个源最多返回多少条10~20太大会浪费上下文融合后Top N最终给Agent多少条8~15太大会造成大模型“上下文过载”去重阈值文本相似度达到多少算重复0.85以上阈值过高会放过重复内容缓存TTL同一查询缓存多久30s~5min太长会导致实时信息滞后我见过很多项目失败在“全部调成最大的参数”上。并发拉到20源来不及响应max_results拉到50Agent 的上下文被碎片塞满幻觉反而更严重。联邦搜索的第一目标不是“查到最多”而是“在有限上下文里给出最有依据的结果”。4. 三个典型场景帮你判断该怎么取舍4.1 企业内部知识库与工单系统权限优先这是最常见的企业 Agent 场景。用户问“报销流程怎么走”答案可能是制度文档也可能是某个真实工单的处理记录。两者分开存在不同系统里但 Agent 需要把它们合并成一个答案。这类场景的第一原则是权限边界前置。也就是说权限过滤必须发生在源发起查询时而不是等结果汇聚后再统一过滤。原因很简单一旦结果已经进入融合层你很难追溯它原本属于哪个租户或团队而且把无权限内容取回来本身就有安全风险。实现上每个源在接收查询请求时应该携带用户权限上下文源侧根据自己的数据权限模型做过滤。联邦层只负责透传和校验不负责“二次猜测”。4.2 研发场景代码和 Issue 混合检索实时性优先研发知识场景有一个特点静态文档和动态数据混在一起。代码库、函数文档、Issue、CI日志、内部设计文档每个源的变化频率不同。如果全部同步进一个向量库代码提交和 Issue 状态的变化会滞后。这种场景我建议采用混合检索架构对相对稳定的设计文档可以建立集中式向量索引适合语义检索对代码库、Issue 这种高频变化的内容走联邦搜索让查询直接打到 Git、跟踪系统上取实时数据。融合顺序也要调整先看实时源的精确匹配结果再看文档向量库的语义结果。这样模型才能理解“代码现在长什么样而不是上周长什么样”。4.3 公开信息聚合去重和时效优先如果你在构建一个面向公开信息的 Agent比如新闻聚合、竞品监控那么不同源返回高度重复内容是常态。一家公司发了新闻稿可能同时出现在官网、微博、公众号、第三方媒体上。这个场景最重要的就是内容指纹去重。可以用正文的规范化哈希作为去重键同时保留多个来源的 URL 作为交叉验证。排序时可以根据“源权威度、发布时间、内容完整度”综合排序而不是单纯看每个源给自己的打分。还有一个容易忽略的点公开信息源经常不稳定反爬、限流、字段变化都很常见。联邦搜索层需要对源的健康状态做监控动态摘除故障源而不是每次查询都因为某个源报错而整体失败。5. 最容易踩坑的四个环节以及一套排查链路5.1 四个高频坑我根据实际观察总结出四个高频问题。它们不像“模型效果不好”那么容易被归因但危害更大。第一个坑是单个源拖垮整个链路。某个工单系统慢Agent 响应整体超时。解决方式是在每个源上设置独立超时超时的源直接降级为“本次不参与”而不是反复重试。第二个坑是字段映射错误导致内容丢失。A 源返回的 content 字段在归一化层被误认为 snippet导致模型拿到的只有摘要没有正文。这个现象通常在接入第五个源后开始大量出现。第三个坑是权限过滤发生在融合之后。结果先从权限更高的源取回来融合后再过滤看起来正常但日志会记录到无权限内容这是审计上不能接受的。第四个坑是重复内容反复进入上下文。同一份政策文档可能同时在 Wiki 和工单系统里都存在结果被当成两条结果传给模型白白消耗 token还容易造成答案冲突。5.2 五层排查链路遇到联邦搜索结果不对时不要急着换模型。按下面五层逐层排查层级检查点常见问题输入层用户问题是否完整、意图解析后是否丢失查询被改写得太泛路由选错源路由层是否选中了正确源、有没有漏选或多选关键词规则覆盖不到同义表达源层每个源是否正常返回、延迟和错误码鉴权失败、接口限流、源数据缺失融合层字段映射、去重阈值、RRF参数分数域不一致、时间字段格式混乱输出层上下文是否过大、引用是否可溯源snippet截断、url丢失、权限标记漏掉排查顺序不是任意的。先确认“有没有查”再确认“查没查到”再确认“查到后有没有正确合并”最后才是“Agent 用得对不对”。如果路由层就选错了源后面再怎么调融合参数都无效。另外要保留日志。每次查询至少记录用户问题、路由决策、每个源的结果数、耗时、融合后的前 5 条 doc_id。没有这些日志出了问题只能靠猜。6. 再往后走联邦搜索之上还需要补什么6.1 缓存与结果复用联邦搜索有一个非常明显的性能优化点同一个问题尤其是同一类问题会被反复查询。例如“退货政策是什么”“发货要几天”这类问题每天可能有几百次相似请求。在联邦搜索层加一个短 TTL 缓存能显著降低下游压力。但缓存必须注意权限隔离。政策类文档可以按内容做全局缓存但订单、工单这类含用户隐私的数据必须按用户维度缓存不能跨用户复用。最简单的实现是在缓存 key 里带上用户权限标识。6.2 可观测性与评测集联邦搜索的评测比普通 RAG 更难因为它涉及路由、融合、源质量多个环节。建议团队从第一天就建一个评测集不需要很大50 到 100 条足够起步。每条样例包含用户问题、期望命中的源、期望结果的关键信息、是否需要权限过滤。评测指标建议分两层看检索层每个源是否被正确命中、Top N 是否有正确答案。Agent 层最终答案是否采用了正确来源、引用是否真实可回查。不要只看“答案看起来对不对”还要看“它是不是从正确来源里来的”。这是联邦搜索和集中式 RAG 在评测上的本质区别。6.3 反馈闭环当 Agent 给出的答案被用户点击、点赞、采纳或用户再次追问“你确定吗”时这其实是联邦搜索层的天然反馈信号。记录“哪个来源的结果被最终采纳”这件事比任何模型调参都更有价值。你可以先做一个很简单的反馈记录表user query - source_id - adopted? - timestamp。积累两到四周后通过统计哪个源被采纳率高来优化路由权重、源排序和缓存策略。这一步不需要复杂机器学习普通的统计报表就能带来明显改进。回到开头那个客服 Agent 的例子。真正解决它的问题的不是再给 Agent 多接一个数据源也不是把八个源全部灌进同一个向量库而是承认信息天然是分散的然后专门构建一层能够统一编排、融合、校验的联邦搜索层。如果最后只留一条建议我会说从两个源开始选一个用户每天都在问的真实问题先跑通一次带引用、带权限、带日志的完整查询。把这条链路做稳比搭建一个听起来很庞大、但永远处于调试阶段的“中台”有用得多。面向 AI Agent 的联邦搜索目前还谈不上已经成熟但它解决的是一个非常明确的问题当 Agent 要面对真实世界里的分散信息时它得有一个靠谱的“信息总调度”而不是靠模型临场发挥。这个方向值得每一个想把 Agent 真正落到生产环境的团队认真对待。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价