RAG 答非所问时,先查向量,再怪模型

RAG 答非所问时,先查向量,再怪模型

一次电子书问答项目里,检索回来的 top5 全是 [../Images/9.jpg] 这样的图片引用,相似度 0.08,而模型凭自身知识把问题答得头头是道------日志无报错,答案看似专业,知识库却形同虚设。这类故障最迷惑人,也最常见。

本文的判断:RAG 项目 80% 的故障不在模型,而在数据入库质量与检索质量验证。以下用一套 Milvus + LangChain + LangGraph 的真实链路说明如何定位、修复,以及为什么下一步必须是 Agentic RAG。文中入库与朴素问答部分实际运行通过;路由器部分代码运行未验证。

两条链,一个交汇点

text 复制代码
入库链:EPUB → 按章加载 → 分块(500字/重叠50) → 向量化 → Milvus(3042 条)
查询链:问题 → 向量化 → 相似度检索 top5 → 增强提示词 → 流式生成

几个决定成败的入库决策:主键用 书_章_块 格式(1_101_13)自带溯源;chunkOverlap: 50 防关键句被边界腰斩;索引选 IVF_FLAT(聚成 1024 个桶只扫目标桶,nprobe:16 控制扫几个)+ COSINE。入库与查询两侧的 index_type、metric_type 必须一致 ------查询侧写 HNSW 会让 SDK 把 ef 参数发给只认 nprobe 的 IVF_FLAT 索引。

破案:相似度分数是唯一的目击者

朴素 RAG 的查询链就是 LangGraph 两个节点:retrieve 调 similaritySearchWithScore 拿 [Document, score] 二元组,generate 把片段拼进提示词流式生成。检索后把每条的分数打印出来,是成本最低的质量观测手段。

问题暴露后,三步定位:

  1. 库里有没有正文? 按 content like "%阿朱%" 直接取样------正文存在,排除"没导入"。
  2. 向量是不是坏的? 取库中某条的存储向量,与同一段文字现算的向量算余弦。结果 0.0327(正常应接近 1)------那一批入库向量整体损坏。
  3. API 现在正常吗? 同文本两次现算余弦 = 1.0,且问题 vs 相关正文 = 0.30、vs 无关正文 = 0.24,区分度健康------删集合重灌即可修复。

这组数字值得收藏(COSINE、同模型实测):相关 ≈0.30 / 无关 ≈0.24 / 垃圾 ≈0.08。"平均分低于阈值就判检索失败"这个判据,写进代码就是将来 Agentic RAG 评估节点的雏形。

依赖与类型的暗坑,一次说清

  • @langchain/community 的可选 peer 依赖不自动安装:本项目依次缺 @zilliz/milvus2-sdk-node、epub2、html-to-text,外加 @langchain/textsplitters,逐个报 ERR_MODULE_NOT_FOUND。规律:静态 import 缺包启动即炸 ,动态 require 缺包跑一半才炸。
  • VarChar 字段传 JS 数字会插入报错(book_id 必须 "1")。
  • model.stream() 返回 Promise<AsyncGenerator>,漏 await 直接 for await 会报 stream is not async iterable。
  • new Milvus(单参数) 必 TypeError,构造签名是 (embeddings, args);连接已有集合应使用 Milvus.fromExistingCollection。

为什么朴素 RAG 必须升级

单行道 START → retrieve → generate → END 有五个结构性缺陷(项目 readme 原始记录):简单问题也走检索浪费 token;无检索质量评估;无法多步检索("四大恶人排第二是谁"得先查名单再查排名);纯语义检索对精确实体失灵("高血糖/低血糖"向量很近,方向却相反);库外内容只能靠模型硬编。

Agentic RAG 的解法是往图里插决策节点。第一步是查询路由,用 zod 枚举把 LLM 判断钉死成二选一:

js 复制代码
const RouteSchema = z.object({
  strategy: z.enum(["simple", "complex"]),
  reason: z.string(),
})
const router = await model.withStructuredOutput(RouteSchema).invoke(prompt)
// router.strategy 只能是 "simple" | "complex",条件边据此分流

枚举的价值在于封闭值域 :不约束的话模型会回答"相对简单""不算复杂",代码没法 if。初版代码有两个典型错误值得引以为戒------invoke 返回值没接收(拿到 undefined),枚举写成了自由字符串。修复后写法如上,运行未验证。

自检清单

发布一个 RAG 功能前过一遍:

  • 字段类型与 JS 传入类型一致(VarChar vs number)
  • 两侧索引类型、度量类型对齐
  • 抽查存储向量 vs 现算向量余弦 ≈ 1
  • top-k 分数低于阈值有兜底,不让 LLM 硬答
  • 图片引用等垃圾片段入库前清洗

遗留一个待验证的问题:坏向量批次的根因未定位(推测为 embedding 网关瞬时异常),说明检索质量需要长期监控而非一次性检查。下一步计划:实现评估节点 + 重写查询回环,把五个痛点逐条搬上图。


标签:RAG、Milvus、LangGraph、LLM、向量数据库

相关推荐
素男2 小时前
叫沉默的,和叫留白的——一次改名记
人工智能·agent·self-becoming·ai长期记忆·ai自我介绍
無a伟2 小时前
RAG演进路线与核心架构
agent·rag
枫叶丹42 小时前
AI 的记忆不是数据库:长期个性化如何避免过期与污染
人工智能·chatgpt·开源·agent·codex
看浪的路人2 小时前
第6讲:Agent 安全
agent
XLYcmy2 小时前
AI 时代,MOM(制造运营管理系统)该如何演进? 上
ai·llm·agent·模型·mom·harness·工业系统
浩瀚地学3 小时前
deepagents学习打卡day08
经验分享·笔记·python·学习·agent
無a伟3 小时前
彻底搞懂ToolCalling、MCP,Skills的核心区别,能力上的层层封装
大数据·agent·mcp·toolcalling·skills
七夜zippoe3 小时前
RAG 2.0:从向量检索到 Agent 自主知识治理的进化路径
ai·agent·向量检索·rag 2.0·自主知识治理
凉凉的知识库5 小时前
Agent 如何拥有长期记忆:六个主流项目的设计思路对比
开源·llm·agent