向量数据库 vs 关系数据库:Agent 什么时候用哪种——语义检索和精确查询的配合

我最早做 Agent 的时候,干过一件蠢事:把用户订单全部向量化,塞进向量数据库,然后天真地以为用语义搜索能搞定一切查询。结果第一个测试用户就翻车了——他问 "订单号 20240815 的物流信息",向量库给我返回了一堆相似的模糊文本,唯独没有那笔订单。我盯着屏幕愣了半天,才意识到一个基本问题:我在拿一把锤子拧螺丝。

AI technology illustration

后来我翻了不少资料,踩了无数坑,才慢慢理清这两种数据库各自的边界。今天这篇文章,想一次性讲明白:Agent 应该什么时候用向量数据库,什么时候用关系数据库,以及两者怎么配合。

关系数据库的信任基石:ACID 与精确匹配

关系数据库的核心,是建立在严格代数基础上的。你写 SELECT * FROM orders WHERE order_id = 20240815,它通过 B-tree 索引,一步就能锁到你想要的那行。这个过程是确定性的——同一条查询,无论执行多少次,结果都一样;事务保证并发读写时不会读到脏数据。这些特性从银行系统到订单中心,都是几十年验证过的硬要求。

对于 Agent 来说,业务状态查询——余额、物流、库存——恰恰是不能模糊的。你告诉用户 "订单已发货",结果因为相似度检索抽到了另一条,那就是事故。PostgreSQL 官方文档把事务的 ACID 特性讲得很清楚,而这也是PostgreSQL 官方文档最强调的部分。没有 ACID,Agent 的记忆再聪明,业务数据也会变成一团浆糊。

向量数据库的看家本领:语义召回与近似最近邻

向量数据库解决的是另一类问题。它让你把文本、图像、声音映射成高维向量,然后用 ANN(近似最近邻)索引快速找到 "语义上最接近" 的条目。Pinecone 的博客里有一个很形象的说法:Pinecone 对向量数据库的定位,就是处理非结构化和语义相关的数据。当你问 Agent "上次我那个订单怎么还没到?",它需要理解 "那个订单" 指的是你历史上最相关的那个,而不是用订单号去精确匹配。

这种能力来自 OpenAI Embeddings 文档里说的 embedding 模型——把语义相近的文本映射到空间中相近的位置。但要注意,接近永远带着近似的标签。ANN 索引(如 HNSW、IVF)牺牲了 100% 召回率来换取速度,它给你的是 "很可能正确" 的结果,而不是 "必定正确"。

为什么你不能用向量库做精确查询?

很多人(包括我)在刚开始时,以为 embedding 能同时搞定精确匹配。比如我尝试把订单号也编码进向量,问自己:不就能查了吗?这是一个根本性的误解。Embedding 是连续向量,天生就包含语义漂移——哪怕只改一个字符,向量也可能跑到奇怪的地方。精确匹配要求的是离散、等值、唯一,而向量空间是连续、相似、多维的。你没法违背这个数学性质。

更实际地看:如果你的 Agent 需要回答 "我的账户余额还有多少?",你希望它去向量库里"猜"一个相似数字吗?当然不。你要的是一个 SQL 查询返回明确的值。反过来,如果你的 Agent 需要从用户一段含糊的描述中找出相关文档,SQL 的 LIKE '%关键词%' 会漏掉大量同义表达,这时就需要向量检索召回候选。

一张表看透两种存储的真实边界

维度 关系数据库 向量数据库
查询核心 等值 / 范围 / 聚合 相似度排序 / 最近邻
数据结构 表、行、列,强约束 向量 + 标量属性
查询结果 确定、可复现 近似、受索引影响
事务与一致性 ACID,成熟可靠 弱一致,支持有限
性能瓶颈 表扫描、连接、磁盘 IO 维度灾难、召回率
最佳场景 订单、用户、权限、金额 文档相似、推荐、RAG

注意最后一行。这不是 "谁更好" 的问题,而是它们各自躺在一个不同的维度上。追求确定性和一致性的业务数据留在关系库,追求语义泛化的数据放进向量库。

Agent 的正确姿势:先向量召回,再精确校验

那么具体怎么配合?我总结了一个三步模式,目前在我自己的 Agent 工程里反复验证有效:

  1. 先向量召回:用户一句自然语言,先通过 embedding 在向量库找到 top-20 相关候选。这一步允许模糊,目的是 "别漏掉"。
  2. 再精确过滤:把候选的关键字段(比如订单号、用户 ID、时间范围)拿到关系数据库做结构化过滤,这一步是为了 "别错杀"。
  3. 最后业务查询:对通过校验的候选,在关系库执行最终查询,得到权威结果并生成回答。

举一个具体的例子:客服 Agent 收到消息 "我上周买的东西还没到,帮我查下物流"。向量库先检索出可能与 "买的东西" 相关的商品记录和用户历史订单(因为 "买的东西" 没有明确 ID),然后从这个候选集合里提取出真实的订单号,再到订单系统(关系库)查状态。如果直接拿整句话去 SQL 查订单号,必然失败;但若只用向量库的相似度结果就直接回答,又会瞎编。

这套模式实际上就是 RAG + 工具调用 的常见融合:向量库作为 Agent 的长期记忆和知识索引,关系库作为业务事实的唯一来源。OpenAI 的函数调用文档也强调了类似的分工——工具查询依赖结构化数据,对话检索依赖非结构化内容。

有没有 "二合一" 的数据库?有,但要认清限制

很多团队会想到用 pgvector 给 PostgreSQL 加上向量索引,一个数据库搞定两种查询。这听起来很美,但实践中要小心。pgvector 的实现基于 Postgres 的索引框架,它能让你在 SQL 里写 ORDER BY embedding <-> $1 做近邻搜索,也支持倒排和 HNSW 索引。但它终究不是一个为大规模向量原生设计的分布式数据库,当向量规模达到千万级、同时高并发写入时,性能可能不如 Milvus 这类专用向量库。

补充:什么时候可以考虑 pgvector?

如果你的向量数据量在百万级以下,团队不想维护两套存储,且对事务一致性要求很高,pgvector 是一个性价比不错的融合选择。但一旦你需要超低延迟、百万级以上的 ANN 检索,或者要和对象存储深度集成,专用向量数据库会更合适。

还有一类 混合检索 方案,比如 Elasticsearch 的 dense_text + BM25 多重评分。这类方案本质上是在同一个系统里同时跑精排和召回,但背后的存储引擎仍然是不同的。明白了这个原理,你就不容易被厂商的各种 "统一平台" 话术迷惑——物理上可以合并,逻辑上的分工不会消失。

边界线:什么时候打死也不能用向量库?

这里想分享一个我自己的认知转折。我一度以为,有了向量数据库,RAG 就能回答一切业务问题。直到有一次,我在一个金融 Agent 里看到它把用户 "转出 5000 元" 的指令匹配到了 "转入 5000 元" 的相似度最高的日志,差点造成资金操作事故。幸亏当时做了人工复核。

从那以后我立下一条铁律:凡是涉及资金、身份、权限的操作性指令,一律走结构化查询,不走向量检索。 向量检索只用于辅助理解用户意图的候选召回,永远不能作为唯一的事实来源。

常见误区一:向量数据库能替代关系数据库?

不能。至少在可见的未来,ACID 和精确查询仍然是业务系统的基石。向量数据库做近似搜索,但不保证一致性。

常见误区二:我可以在关系数据库里直接用 embedding 列?

可以,pgvector 就是干这个的。但你仍然需要面对存储、算力成本和索引调优的问题。

常见误区三:Agent 的记忆应该用什么存储?

聊天历史、语义知识 -> 向量库;用户身份、权限、状态 -> 关系库。不要把两者混在一个表里。

我的最终判断

回到标题的问题:Agent 什么时候用哪种?我的回答是:当你需要回答 "是什么/多少/哪个 ID",用关系数据库;当你需要回答 "哪几条最相关/内容大概在讲什么",用向量数据库。 两者不是替代关系,而是一个完整 Agent 的两条腿。未来肯定会有更多像 pgvector、Milvus 这样支持混合负载的数据库出现,但底层逻辑仍然清晰——语义检索和精确查询是两种不同的数学问题,融合只是让它们住得更近,并没有消除它们本质上的分工。

如果一定要给出最核心的选型建议,我会说:先画一张数据地图,把 Agent 需要的数据分成 "事实型" 和 "理解型" 两类,然后分别选择存储。 这比任何榜单评测都管用。希望这篇文章能帮你少踩一些我踩过的坑。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/633.html

(0)
上一篇 1天前
下一篇 1天前

相关推荐