# **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\ { // 调用你们现有的 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 的阈值完全不是问题。