数据截至 (上游 commit c4cb19d8fa20)
第 4 章 · 巧妙之处、边界、对比与代码地图
4.1 巧妙之处(可借鉴的技术)
① 让知识图谱「先发言」精化问题。 不是把图谱结果直接喂答题,而是先用图谱上下文 + fast LLM 改写用户问题,再去向量检索。模糊口语问题 → 精准检索 query。见 retrieve_flow.py:66(retrieve)与 :120(_refine_user_question)。
② 检索主体是「关系」而非「实体」。 把「源实体(描述)→ 关系 → 目标实体(描述)」拼成一句话整体向量化(graph_store/helpers.py:100,get_relationship_description_embedding)。检索时直接对关系做近邻,实体跟着两端被带出。这让「关系语义」可被直接搜索,而不是搜到实体再猜关系。
③ 距离分段 + 配额的多跳扩散。 不是无脑取邻居 top-k,而是把每跳配额按距离段分摊,近段配额高、远段配额低、超阈值不要(DEFAULT_RANGE_SEARCH_CONFIG,graph_store/helpers.py:20;扩散逻辑 tidb_graph_store.py:507)。既保相关性又控发散。
④ 关系打分的「边际递减」权重。 权重分按区间累进、系数递减(get_weight_score,helpers.py:30),防止超高权重的单条关系霸榜。综合分还能叠加度数分偏好枢纽节点(calculate_relationship_score,helpers.py:51)。
⑤ 处处「ANN 粗筛多取 + 应用层精排」。 chunk 侧 limit(top_k × oversampling_factor) 再裁(tidb_vector_store.py:201);关系侧 limit(limit × 10) 再综合打分(tidb_graph_store.py:659)。统一对策:用数据库会的单一距离粗筛、把复杂打分留给应用层。
⑥ 两种融合各取所需。 chunk 融合按内容 hash 去重、取最大分(fusion_retriever.py:59);图谱融合按关系描述去重、权重累加(knowledge_graph/fusion_retriever.py:113)。融合策略贴合各自语义。
⑦ 全栈压在 TiDB 一个库上。 向量(HNSW 索引,VectorAdaptor(...).create_vector_index,tidb_graph_store.py:129)、图(实体/关系表)、聊天记录共用一个 TiDB,免去多组件运维。检索里还用 TiDB 的 storage hint(/*+ read_from_storage(tikv[...]) */,tidb_graph_store.py:379)在行存/列存间选执行路径。
4.2 边界与局限(诚实)
RetrieveFlow.retrieve的精化结果被丢弃。_refine_user_question的返回值没被接住(retrieve_flow.py:66-75),该路径上 chunk 检索仍用原始问题;只有ChatFlow真正用上 refined_question。详见第 1 章 1.1。- 对话主路径默认不做子问题分解。
search_relevant_chunks写死use_query_decompose=False(retrieve_flow.py:140);分解主要靠/retrieve/chunksAPI 配置或图谱侧打开。 - 多跳配额是硬编码的常 量。
search_number_each_depth = 10、四个距离段及比例都写死在代码/helpers 里(tidb_graph_store.py:510、helpers.py:20),没暴露成 per-request 配置,调参需改源码。 - 关系打分的
1 / embedding_distance对距离极小值敏感。 距离趋近 0 时该项会非常大(helpers.py:67),实际靠候选已是近邻、distance 不会真为 0 来兜底,但没有显式下限保护。 - 强绑定 TiDB + LlamaIndex + DSPy。 向量/图存储、HNSW 索引、storage hint 都依赖 TiDB,不易换底座。README 也标注项目仍处早期阶段。
- 图谱构建依赖 LLM 抽取质量。 实体/关系由 DSPy 程序从文本抽取(
indices/knowledge_graph/extractor.py,ExtractGraphTriplet),抽得不好则图谱检索上限受限——本文聚焦检索侧,构建质量不在此展开。
4.3 横向对比(同 shelf 兄弟项目的取舍)
| 维度 | AutoFlow | 典型纯向量 RAG | 典型 GraphRAG(社区检测式) |
|---|---|---|---|
| 检索单元 | 关系(整体向量化)+ chunk 双线 | chunk | 实体/社区摘要 |
| 图的作用 | 精化问题 + 提供结构上下文 | 无图 | 直接基于社区摘要答题 |
| 多跳 | 按距离分段配额扩散 | 无 | 按社区层级聚合 |
| 融合 | hash 去重取 max / 关系权重累加 | 单路或 RRF |