Skip to content

检索策略 (Retrieval Strategy)

检索是 RAG 的核心。检索质量差,生成的内容就是“垃圾进,垃圾出”(Garbage In, Garbage Out)。

这是最基本的模式:计算 Query 向量和 Document 向量的 Cosine 相似度,取 Top K。

  • 优点:速度快,捕捉语义关联。
  • 缺点:对于专有名词、精确匹配(如“错误码 503”)效果不佳。

混合检索 = 向量检索 (Dense) + 关键词检索 (Sparse/BM25)

向量检索擅长语义理解,关键词检索擅长精确匹配。两者结合,互补短板。 Milvus、Weaviate 等向量库都支持混合检索。

Golang 伪代码逻辑

go
// 1. 并行执行两次搜索
// Goroutine A: 向量检索 -> Top 50
// Goroutine B: BM25 关键词检索 -> Top 50

// 2. 结果融合 (Reciprocal Rank Fusion, RRF)
func RRF(denseResults, sparseResults []Result) []Result {
    scores := make(map[string]float64)
    
    // RRF 公式: score = 1 / (k + rank)
    for rank, doc := range denseResults {
        scores[doc.ID] += 1.0 / (60 + float64(rank))
    }
    for rank, doc := range sparseResults {
        scores[doc.ID] += 1.0 / (60 + float64(rank))
    }
    
    // 排序返回
    return SortByScore(scores)
}

3. 终极杀器:重排序 (Re-ranking)

检索出的 Top K(比如 Top 100)文档中,可能有很多是不相关的。重排序模型 (Cross-Encoder) 可以对这 100 个文档进行精细打分,筛选出最相关的 Top 5 给大模型。

流程

  1. Retrieval: 先检索出 Top 50 (粗排)。
  2. Rerank: 使用 Rerank 模型计算 (Query, Doc) 对的相关性得分。
  3. Generation: 取 Top 5 (精排) 给 LLM。

调用 Rerank API (以 Cohere / BGE 为例)

在 Golang 中,我们通常调用 Rerank 服务的 HTTP 接口。

go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type RerankRequest struct {
	Model     string   `json:"model"`
	Query     string   `json:"query"`
	Documents []string `json:"documents"`
}

type RerankResponse struct {
	Results []struct {
		Index          int     `json:"index"`
		RelevanceScore float64 `json:"relevance_score"`
	} `json:"results"`
}

func Rerank(query string, docs []string) []int {
	url := "https://api.cohere.ai/v1/rerank" // 或者本地部署的 BGE Reranker
	apiKey := "your-cohere-key"

	reqBody, _ := json.Marshal(RerankRequest{
		Model:     "rerank-english-v2.0",
		Query:     query,
		Documents: docs,
	})

	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(reqBody))
	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, _ := client.Do(req)
	defer resp.Body.Close()

	var res RerankResponse
	json.NewDecoder(resp.Body).Decode(&res)

	// 返回重排序后的索引
	var topIndices []int
	for _, r := range res.Results {
		if r.RelevanceScore > 0.7 { // 设定阈值
			topIndices = append(topIndices, r.Index)
		}
	}
	return topIndices
}

总结

在生产级 RAG 中,“混合检索 + 重排序” 是标准配置。

  • 如果只用向量检索,准确率通常在 60%-70%。
  • 加上重排序,准确率可以提升到 80%-90%。
  • Golang 只需要负责并发调用这些接口并进行结果融合即可。

🚀 学习遇到瓶颈?想进大厂?

看完这篇技术文章,如果还是觉得不够系统,或者想在实战中快速提升?
王中阳的就业陪跑训练营,提供定制化学习路线 + 企业级实战项目 + 简历优化 + 模拟面试。

了解训练营详情