有了 Oxigraph 图数据库,为什么我还要再塞一个 Qdrant 向量库?
很多看我之前文章的朋友问:"你不是已经有 Oxigraph 了吗?图数据库不是万能吗?为啥又加个 Qdrant?"
问得好。这个问题就像在问:"你家不是有图书馆吗?为啥还要用 Google?"
图数据库是图书馆管理员,向量数据库是搜索引擎。 图书馆管理员能精确找到索书号对应的书,但不能帮你搜"那本封面是蓝色、讲历史故事的书叫什么"。搜索引擎刚好相反------它能帮你模糊搜索,但没法告诉你"这本书的第三版和第二版到底改了哪几行"。
今天就来聊聊,我是怎么把这两个家伙凑在一起,让 AI Agent 的记忆系统既能"精确查户口",又能"模糊翻旧账"。
一、Oxigraph 的强项和软肋
Oxigraph 是个 RDF 图数据库。它的拿手好戏是精确的、结构化的、逻辑的查询。
比如:
- "找出
skill:rust-jwt-auth的所有前置依赖" → 秒出结果 - "任务
task:sales-q2的 5W2H 里的what是什么?" → 秒出 - "哪些 Agent 引用过
memory:session-042/block-017?" → 还是秒出
只要你能明确写出"主语是什么、谓语是什么、宾语是什么",Oxigraph 就是神。
但现实世界的问题,往往不是"精确的"。
比如:
- "我好像记得有个任务跟销售预测有关,但具体叫啥忘了"
- "有没有类似这次 JWT 认证的 Skill,但用 Python 写的?"
- "历史上哪个任务和当前这个最像?"
这些问题的共同点:你不知道精确的 IRI,只能描述一个模糊的印象。
这时候,Oxigraph 就像拿着模糊照片去图书馆找书------管理员只会礼貌地告诉你:"请提供索书号。"
二、Qdrant 填补的"模糊搜索"真空
Qdrant 是向量数据库,专门做"给你一个意思,还你一堆最接近的结果"。
工作流程:
- 把文本(比如任务描述、Skill 摘要)用 Embedding 模型转成向量(一串数字)
- 把这些向量存进 Qdrant
- 查询时,把新问题也转成向量
- Qdrant 返回和它夹角最小的那批向量对应的原始数据
比如你搜"销售数据分析",Qdrant 能找到 task:sales-q2、task:revenue-prediction 这些语义上接近的任务,哪怕它们的名字和 IRI 完全不一样。
这就是 Qdrant 的价值:它不靠精确匹配,靠"意思相似"。
三、它俩在我的 Agent OS 里怎么打配合?
核心设计就一句话:数据全存 Oxigraph,但给每个重要节点偷偷塞一张"语义名片"存在 Qdrant 里。
具体做法:
- 写入时 :每当一个任务、Skill、记忆块被写入 Oxigraph,系统自动提取它的核心描述(比如任务的
what字段、Skill 的summary字段),用 Embedding 模型生成向量,存进 Qdrant。然后把 Qdrant 返回的point_id写回 Oxigraph 节点:
json
{
"@id": "task:sales-q2",
"task:what": "分析Q2各区域销售数据",
"qdrant:pointId": "points/8732"
}
- 查询时 :
- 精确查询:走 Oxigraph → SPARQL,直接按 IRI、类型、属性过滤。
- 模糊查询 :走 Qdrant → 语义搜索,返回
point_id列表 → 用这些 ID 回 Oxigraph 反查完整节点。
这就构成了双通道检索:SPARQL 管精确,Qdrant 管模糊。
四、这个组合带来的架构收益
收益一:模式识别(SA 的感知器官 3)
我的 SA 调度器有个"模式识别"感知器官,专门在新任务到来时找历史上类似的任务,注入经验。
光用 Oxigraph: 只能按标签、类型匹配,比如"找所有 DataAnalysisTask"------但可能找到一堆不相关的任务,因为"数据分析"是个大箩筐。
加上 Qdrant: 把当前任务的 what 描述转成向量,在 Qdrant 里一搜,直接找到语义最接近的 3 个历史任务。然后拿它们的 IRI 回 Oxigraph 查完整上下文------当时用的什么 Skill、成功没有、踩过什么坑。
结果:每次新任务启动,Agent 都站在"巨人的肩膀上",而不是从零开始。
收益二:Skill 的智能发现
当 Agent 分析任务后,发现"我需要一个能处理时间序列的 Skill",但它不知道该 Skill 的精确 IRI。
- Oxigraph 查
skill:taggedFor time-series→ 可能没打这个标签 - Qdrant 搜"时间序列预测" → 直接返回
skill:forecasting,即使它的描述写的是"基于历史数据进行趋势预测"
这让 Skill 从"被动调用"升级为"主动发现"。
收益三:记忆的模糊唤醒
人类回忆时,很少说"我想起 2026 年 5 月 11 日下午 2 点的第 42 条记忆",而是"我记得我们上次讨论过类似的问题,好像是关于......"
Qdrant 给了 Agent 这种"人类式"的回忆能力。Agent 可以带着当前上下文,去 Qdrant 里"找找有没有类似的讨论",然后把相关的历史记忆 IRI 带回上下文。
五、一个具体的场景
用户:"我们之前是不是讨论过一个类似 JWT 的项目?好像也是 Rust 的。"
Agent 工作流:
- 把"类似 JWT 的项目,Rust 的"转成向量
- Qdrant 搜到 3 个最相似的记忆节点,返回
point_id - 用这些
point_id回 Oxigraph 查出完整记忆:memory:session-018/block-005(当时决定用 JWT),skill:rust-jwt-auth(相关 Skill) - 把摘要注入 LLM 上下文:"我们曾在 session-018 讨论过 JWT 认证,当时选择了 256 位密钥......"
- LLM 无缝接上:"对,上次用的 jsonwebtoken crate,这次要不要复用?"
整个过程,用户完全感觉不到背后有两套数据库在协作。
六、为什么不直接用 Qdrant 替代 Oxigraph?
向量数据库只能返回"相似的东西",不能返回"精确的关系"。
比如"找出 skill:rust-jwt-auth 的所有前置依赖"------向量数据库完全没法做。它没有"依赖"这个概念,它只知道"这几个向量看起来差不多"。
图数据库管逻辑,向量数据库管直觉。少一个,Agent 就是偏科生。
七、最后说句人话
Oxigraph 是 Agent 的"逻辑脑",Qdrant 是 Agent 的"直觉脑"。一个负责"这张表第三行第二列是什么",一个负责"我好像在哪见过你"。
合在一起,就是 RAG 的终极形态:不是把文档切碎了扔向量库,而是用向量库做模糊索引,再用图数据库做精确解剖。
我这套系统叫 Gliding Horse(流马) ,所有代码都在 GitHub 上:github.com/doiito/glid...
之前还写过为什么选 JSON-LD、为什么抄 CPU 缓存架构、以及 Oxigraph 命名图的妙用,感兴趣可以去翻翻。今天这篇是"图数据库 + 向量库 = 全能记忆体",希望能帮你在选型上少走点弯路。