思考与分析
公开教程 · 无需登录

思考与分析

1关键字、向量与混合检索分别访问哪些组件?Qdrant 是否对客户端暴露?

现象观察与验证

分别使用原词与同义改写,请求 keyword、vector、hybrid 三种模式,并对照 query_vector、两路 score 与 rank 字段。使用原词时应有关键字命中且不产生问句向量;改写后关键字路径落空,向量路径仍可能命中。请求主机为本站 /week04/api。停止 Qdrant 后,关键字检索仍可返回正文,向量与混合模式返回 503。

设计含义

关键字检索判断词是否出现,向量检索判断语义是否接近。全文相关度与余弦相似度不能直接相加;混合模式按名次执行 RRF(k = 60),缺席的一路不贡献分数。Qdrant 不对外开放,班级过滤与回表查询均保留在服务端。

替代方案与权衡

分数归一化后加权求和,但更换嵌入模型需重新标定权重。仅保留混合模式时,一旦向量库故障,关键字路径便无法单独降级使用。引入交叉编码器重排序更准确,但延迟更高。若将 Qdrant 端口映射出来便于调试,客户端即可绕过认证直接访问。

关键字 只查 MySQL 全文索引。不调用嵌入,不访问 Qdrant 向量 问句嵌入 → Qdrant 按班级过滤 → 向量主键回表取正文 混合 两条路径均执行,过滤后按名次执行 RRF,而非分数相加
客户端仅调用本站检索接口。Qdrant 与两类模型网关均不作为浏览器入口。

2在请求中修改 class_id,能否检索到其他班级的切片?

现象观察与验证

以 A 班会话检索一个仅出现在 B 班正文中的词,第二次在请求体中写入 B 班的 class_id。两次响应均应返回 200 且 hits 为空,问答接口返回固定文案。以该会话打开 B 班材料详情,结果与不存在的标识一样为 404。

设计含义

班级取自会话,请求体中的 class_id 被丢弃。对外表现为无命中,从而避免以 403 泄露资料归属于其他班级。MySQL 与 Qdrant 使用同一会话班级值值;仅在单侧过滤时,另一侧仍会返回其他班级的候选。

替代方案与权衡

改为返回 403 虽可区分「无权访问」与「资源不存在」,但会泄露资源存在性。按班级拆分 Qdrant 集合可强化隔离,但集合数量随之增加。即便采用数据库行级安全策略,传入的班级值仍必须来源于会话。

请求体中的 class_id 解析后丢弃 会话中的 class_id 认证中间件已写入请求上下文 只使用该值 MySQL 查询条件 class_id = 会话班级 Qdrant 过滤条件 同一会话班级值
跨班级检索对外表现为无命中,而非 403。仅在单侧添加班级条件时,另一侧仍可能返回其他班级的候选。

3语料中不存在依据时,是否仍调用生成模型?

现象观察与验证

材料中确有依据的问题,其 [1]、[2] 标注与 citations 顺序一致。材料中不可能出现的问题(如天气、比分)仍返回 200,正文为固定文案,citations 为空。该固定文案由接口在检索之后直接返回。请求中携带的 system 消息应被丢弃。

设计含义

若在无切片情况下仍调用生成模型,回答将依赖训练记忆,无法回溯至本班材料。存在命中切片时,system 提示由服务端写入,仅允许模型依据编号对应的资料作答。

替代方案与权衡

在无依据时仍调用模型并要求其声明「不知道」,提示约束可能被忽略。若改为返回 404,则会将空结果与资源不存在混为一谈。若将弱相关候选一并送入模型,回答的可追溯性会随之下降。

最新一条提问 system 消息被丢弃 本班混合检索 取前 4 条 有切片 → 调用生成模型 [1]、[2] 与出处列表顺序一致 无切片 → 不调用生成模型 固定句,citations 为空
无命中时,请求在检索之后即结束。页面上出现文字,并不能证明生成模型被调用过。

4三种切分策略的输入分别是什么?更换策略后既有切片是否保留?

现象观察与验证

取同一份带标题的材料,分别以三种策略各重建一次索引。先记录切片条数与向量主键。若未重建,则旧切片仍然存在;未指定策略时等同于自动窗口(约 800 字,重叠 80 字)。预处理之后 body_text 仍为原文,切片偏移对应的是预处理后的文本。

设计含义

切片是检索的基本单位;重叠用于避免句子被截断在窗口边界。重建索引时先删除旧切片与旧向量,避免遗留过期主键。原文不随预处理发生改写。

替代方案与权衡

按句子或语义边界切分,切片长度不稳定。采用「子切片负责检索、父块送入模型」的方案需额外一次回表查询。仅对变更段落重新嵌入,则须具备判断哪一段发生变化的能力。

删除旧数据 旧切片与旧向量记录 按本次策略切分 未指定时按自动窗口处理 写入新切片 随后嵌入并写入向量 不改原文 body_text 仍是上传原文 预处理只作用于切分输入
已入库材料不会自动重新切分;更换策略必须显式重建索引。

5MySQL 与向量库各存什么形态的数据?二者如何关联?

现象观察与验证

取同一条切片对照两侧存储。MySQL 中保存 body_text、chunk_text 与字符偏移;Qdrant 中保存定长浮点向量,payload 仅含若干标识。向量主键、knowledge_chunks.id 与 payload.chunk_id 三者应相同。嵌入失败时 MySQL 记录仍然存在,向量库中无对应记录。

设计含义

正文保留在 MySQL,关键字检索与结果摘录均不依赖 Qdrant。主键一致即可直接回表查询,无需在向量库中重复保存一份字符串。

替代方案与权衡

将 chunk_text 写入 payload 可减少一次查询,但正文将存在两份副本。向量主键改用随机标识再建立映射,回表前需多一次查找。若将全文索引并入同一检索引擎,班级过滤与事务一致性设计都需重做。

MySQL · 关系行 形态:字符串 body_text:上传原文 chunk_text:切片正文 班级、条目、序号、字符偏移 全文索引建立在 chunk_text 上 Qdrant · 向量记录 形态:定长浮点向量 度量:余弦 payload:仅含标识 班级、材料、条目、切片、序号 不含 chunk_text 关联:向量主键 = knowledge_chunks.id = payload.chunk_id
摘录取自 MySQL 的 chunk_text 字段。向量库中不含该字符串,仅凭同一主键指回对应数据行。