Files
AIclinicalresearch/docs/08-项目管理/08-技术方案-跨语言检索优化.md
HaHafeng 40c2f8e148 feat(rag): Complete RAG engine implementation with pgvector
Major Features:
- Created ekb_schema (13th schema) with 3 tables: KB/Document/Chunk
- Implemented EmbeddingService (text-embedding-v4, 1024-dim vectors)
- Implemented ChunkService (smart Markdown chunking)
- Implemented VectorSearchService (multi-query + hybrid search)
- Implemented RerankService (qwen3-rerank)
- Integrated DeepSeek V3 QueryRewriter for cross-language search
- Python service: Added pymupdf4llm for PDF-to-Markdown conversion
- PKB: Dual-mode adapter (pgvector/dify/hybrid)

Architecture:
- Brain-Hand Model: Business layer (DeepSeek) + Engine layer (pgvector)
- Cross-language support: Chinese query matches English documents
- Small Embedding (1024) + Strong Reranker strategy

Performance:
- End-to-end latency: 2.5s
- Cost per query: 0.0025 RMB
- Accuracy improvement: +20.5% (cross-language)

Tests:
- test-embedding-service.ts: Vector embedding verified
- test-rag-e2e.ts: Full pipeline tested
- test-rerank.ts: Rerank quality validated
- test-query-rewrite.ts: Cross-language search verified
- test-pdf-ingest.ts: Real PDF document tested (Dongen 2003.pdf)

Documentation:
- Added 05-RAG-Engine-User-Guide.md
- Added 02-Document-Processing-User-Guide.md
- Updated system status documentation

Status: Production ready
2026-01-21 20:24:29 +08:00

5.8 KiB
Raw Blame History

08-技术方案-跨语言检索优化

状态: 🟢 建议采纳
日期: 2026-01-20
问题描述: 中文查询搜英文文献时,因向量空间差异,相似度低于 0.3 导致无结果。
核心策略: Query Translation (查询翻译) + Query Expansion (查询扩展)。

1. 问题根因分析

现象 原因
同语言检索 Query(英) 与 Doc(英) 的向量在同一个语义高密度区,相似度通常 > 0.5。
跨语言检索 Query(中) 与 Doc(英) 虽然语义相关,但向量空间存在“对齐损耗”,相似度往往在 0.25 - 0.35 之间。
阈值陷阱 我们设置的 0.3 阈值对于同语言是合理的过滤噪音线,但对于跨语言则是“高墙”。

2. 解决方案LLM 查询重写 (Query Rewriting)

不要直接拿用户的中文去搜英文库。在检索之前,加一个极轻量的 LLM 步骤,把中文翻译并扩展成英文。

2.1 流程图

graph TD
A[用户输入: "帕博利珠单抗治疗肺癌的效果"] --> B{包含中文?}
B -- No --> C[直接检索]
B -- Yes --> D[LLM 查询重写]
D --> E[生成英文查询: "Pembrolizumab efficacy in lung cancer"]
E --> F[生成同义扩展: "Keytruda NSCLC treatment outcomes"]
F --> G[向量检索 (Vector Search)]
G --> H[混合检索 (Keyword Search)]
H --> I[Rerank 重排序]
I --> J[最终结果]

2.2 为什么这个方案最好?

  1. 解决向量距离问题:将“中-英”匹配转化为“英-英”匹配,相似度会直接飙升到 0.5 以上,突破 0.3 的阈值。
  2. 激活关键词检索:你们架构中使用了 pg_bigm。如果用户搜中文pg_bigm 在英文文档里永远匹配不到关键词。只有翻译成英文,关键词检索才能生效!
  3. 医学术语校准LLM 可以把口语化的“治肺癌的那个K药”精准翻译成医学术语 “Pembrolizumab (Keytruda) for NSCLC”大幅提升专业性。

3. 代码实现指南

在 KnowledgeBaseEngine 中增加一个私有方法 rewriteQuery。

3.1 定义 Prompt (Prompt Template)

在 capability Schema 的 Prompt 表中新增一条:

code: KB_QUERY_REWRITE
system: |
你是一个医学检索专家。用户的查询可能是中文。
请将其翻译为精准的英文医学术语,并提供 1-2 个相关的同义扩展查询。
只返回 JSON 数组格式,不要废话。
user: "{query}"
# 示例输出: ["Pembrolizumab efficacy in lung cancer", "Keytruda treatment for NSCLC"]

3.2 改造检索逻辑 (TypeScript)

// backend/src/common/rag/KnowledgeBaseEngine.ts

export class KnowledgeBaseEngine {

/**
* 智能检索入口
*/
async search(kbIds: string[], query: string) {
// 1. 检测是否包含中文 (简单正则)
const hasChinese = /[\u4e00-\u9fa5]/.test(query);

let searchQueries \= \[query\];

// 2\. 如果含中文,调用 LLM 进行重写 (Query Translation)  
if (hasChinese) {  
  const rewritten \= await this.rewriteQueryWithLLM(query);  
  // 将原中文查询和生成的英文查询合并,既保底又增强  
  searchQueries \= \[...searchQueries, ...rewritten\];  
}

// 3\. 执行并行检索 (对每个 Query 都搜一遍)  
const allResults \= await Promise.all(  
  searchQueries.map(q \=\> this.vectorSearchInternal(kbIds, q))  
);

// 4\. 结果去重与合并 (RRF \- Reciprocal Rank Fusion)  
const fusedResults \= this.rrfFusion(allResults.flat());

// 5\. Rerank (可选,但在跨语言场景下非常推荐)  
// 使用重写后的第一个英文 Query 进行 Rerank效果最好  
const finalRanked \= await this.rerank(fusedResults, searchQueries\[1\] || query);

return finalRanked;  

}

/**
* 调用 LLM 进行查询重写
*/
private async rewriteQueryWithLLM(query: string): Promise<string[]> {
// 调用你们现有的 LLM 网关
// 使用 fast model (如 DeepSeek-V3 或 Qwen-Turbo) 降低延迟
const response = await llmService.chat({
promptCode: 'KB_QUERY_REWRITE',
variables: { query }
});

try {  
  return JSON.parse(response.content);  
} catch (e) {  
  console.error("Query rewrite failed", e);  
  return \[query\]; // 降级策略:失败了就用原词  
}  

}
}

4. 备选方案对比

方案 描述 评价 适用场景
方案 A: 调低阈值 将阈值从 0.3 降到 0.15。 不推荐。会导致大量的噪音False Positives搜出完全不相关的东西。 仅做 MVP 快速演示
方案 B: 翻译插件 接入百度/Google 翻译 API。 😐 一般。通用翻译不懂医学术语(比如把 "K药" 翻译成 "K Drug" 而不是 "Keytruda")。 通用领域
方案 C: LLM 重写 (推荐) LLM 翻译 + 扩展。 最佳。懂医学,且解决了关键词匹配问题。 医学/专业领域

5. 实施建议

  1. 不要在前端做:让后端处理,前端只管发用户的原始输入。
  2. LLM 模型选择:这个任务很简单,用最便宜、最快的模型(如 Qwen-Turbo 或 DeepSeek-Lite不要用 GPT-4否则检索延迟会增加 2-3 秒。
  3. 缓存重写结果:对于热门查询(如“肺癌指南”),把重写结果缓存到 Redis (或你们的 Postgres Cache) 里,下次直接查,实现 0 延迟。

通过这个方案,你的检索链路就变成了:
中文 Query -> (LLM) -> 英文 Query -> (Vector) -> 英文 Doc
这就是标准的**“英-英”**高精度检索0.3 的阈值完全不是问题。