目录 展开 收起
搜索返回的五条记录,不等于五个向量候选;返回分数也不等于未经调整的余弦相似度。要解释漏召回或排序,先区分应用的检索阶段与接口字段。
本文沿 ChatCrystal 向量服务 提交 7642768 说明流程;以下常量描述该版本规则,不是通用的最佳检索参数。
两个入口处理不同问题
/api/notes?search=... 在标题与摘要上使用 SQL LIKE 条件,适合检查已有词项;/api/search?q=... 生成查询向量并检索笔记候选。前者也有 LIKE 通配语义,不能概括为任意输入都按字面匹配。
默认本机连接的 CLI 例子:
crystal --json notes list --search SQLite --limit 5
crystal --json search "SQLite 并发写入问题" --limit 5
第一个 JSON 是含 items 的列表对象,第二个是候选数组。JSON 分支会传递数量参数,避免 TTY 搜索界面使用自己的固定数量;符合条件的结果仍可能少于上限。
从笔记文本到候选
笔记使用选定字段建立向量,查询使用当前向量配置。两端需要匹配;换模型后应按 Embedding 配置指南 重建并验证。应用用段落分组生成多个 chunk,同一篇笔记可以拥有多个向量。
Vectra v0.15.0 的 LocalIndex 对候选计算相似度并保留 top K;这条路径不是 HNSW 或 LSH 的近似候选查找。检索成本和质量仍需按实际库规模与模型测试,不能从“本地索引”推导零成本或固定响应速度。
数据库核对、去重与排序
应用读取候选对应的数据库 chunk,并要求笔记状态为 done。索引中存在一个条目,不代表它能作为有效结果返回。多个 chunk 按笔记去重,保留较高分。
词项处理包括 ASCII 技术词与汉字二元组。候选包含全部提取词项时,分数至少提升到 0.82;否则低于 0.58 的候选会被过滤。这个加分发生在向量候选物化之后,不是独立扫描全库的关键词回退。
若去重、核对或筛选后候选不足,代码逐步扩大候选数,并受可取得的索引数量或停止条件限制。它可以补充候选,却不能保证始终返回请求数量,也不能证明语义相似的正确笔记一定入选。
用 API 对比关系扩展
查询通过 --data-urlencode 编码,避免手工拼接中文或特殊字符:
curl --get http://localhost:3721/api/search \
--data-urlencode 'q=SQLite 并发写入' \
--data-urlencode 'limit=5'
可选增加关系扩展:
curl --get http://localhost:3721/api/search \
--data-urlencode 'q=SQLite 并发写入' \
--data-urlencode 'limit=5' \
--data-urlencode 'expand=true'
当前扩展读取直接命中的一跳关系,要求关系 confidence 至少 0.5,关联结果按 直接分数 × 0.7 × confidence 折扣。它不是多跳路径搜索;已进入结果集合的笔记会跳过,因此不能说会为每条关联选择最强路径。扩展后结果可能超过直接命中的数量上限。
正确解释返回字段
HTTP 路由 用 data 包装数组,提供 note_id、conversation_id、标题、项目、分数、标签与 via_relation。via_relation 标记关系类型,不是完整关联路径,也不是来源内容已经正确的证明。CLI 数组已解包,不需 .data[]。
读取 note_id 对应正文,再核对原始会话和当前任务。用有答案、同义表述、精确词项和无答案查询比较两个入口与扩展开关;记录误匹配而不只展示漂亮的正例。实际复用流程见 找回调试方案,关系作为证据的边界见 RAG 与知识图谱。