面包屑图标 当前位置: 首页
AI资讯
热点详情

利用混合搜索与重排序改进RAG检索效果(含代码示例)

AI热点日报
AI热点日报时间:2026-07-07
热点解读

RAG 在实际应用中,检索环节到底存在哪些“坑”?一个典型的场景是:精确匹配特定标识符(ID)。很多业务数据都带有唯一 ID,比如包含数字和字母的复杂组合,长度轻轻松松超过 10 个字符。这时候,如果只依赖基于向量的语义搜索(比如用 PGVector 存嵌入向量做相似性检索),结果往往差强人意。 语

RAG 在实际应用中,检索环节到底存在哪些“坑”?一个典型的场景是:精确匹配特定标识符(ID)。很多业务数据都带有唯一 ID,比如包含数字和字母的复杂组合,长度轻轻松松超过 10 个字符。这时候,如果只依赖基于向量的语义搜索(比如用 PGVector 存嵌入向量做相似性检索),结果往往差强人意。

语义搜索靠的是向量之间的软相似性来排序——计算余弦相似度,返回前 k 个最接近的文本块。处理语义相近的文本时确实好用,但碰上 ID 这种需要严格一致的活儿,就不灵了。举个具体例子:查询“1234567890XYZ”时,语义搜索可能把“1234567890ABC”排在前面,因为它俩在向量空间里距离不远;真正要的那个反而因为嵌入时的细微差异被挤到后面,甚至直接出局。这个问题在医疗记录查询(根据患者 ID 查病历)、金融交易追溯(按交易 ID 拿详情)等场景里,后果相当严重——检索结果错了,后续生成就全偏了。

怎么破?混合搜索是一条切实可行的路——把多种搜索技术组合起来,取长补短。具体分几步走:

基于 PGVector 的语义搜索

PGVector 是 PostgreSQL 里专门存向量和做相似性查询的扩展。第一步用它做语义搜索,能快速找到和查询语义相近的文本块。可以选一个合适的嵌入模型(比如 JinaAI 的“jina-embeddings-v2-base-en”),把文档和查询都转成向量,然后在数据库里高效检索。比如在新闻文章库里搜“科技行业最新动态”,PGVector 能迅速返回语义上相关的片段。但正如前面说的,它对精确 ID 匹配力不从心,所以需要其他搜索来补位。

PostgreSQL 全文搜索

这一步专门对付精确匹配和部分匹配。PostgreSQL 自带的全文搜索功能很强,正好弥补语义搜索的短板。

  • 精确匹配:用 to_tsvectorplainto_tsquery 函数,确保查询的 ID 在文本块里一个字符都不差地出现。比如查“1234567890XYZ”,to_tsvector('english', content) @@ plainto_tsquery('english', '1234567890XYZ') 这条语句能在 documents 表的 content 字段里找到完全匹配的记录。
  • 部分匹配:如果精确匹配没结果,就用 ILIKE 操作符做模糊匹配,例如 content ILIKE '%1234567890XYZ%'。这样能处理 ID 带拼写错误或格式变体的情况,尽量扩大召回范围。

合并结果

语义搜索和全文搜索的结果可能有重叠,需要去重。具体实现上,在 Python 里可以用集合或字典来合并,按文档 ID 或内容去重。合并后的集合既包含语义相关的,也包含文本精确匹配的,给后续重排序提供更全面的素材。

使用 Flash Re-Ranker 重排序

混合搜索拿到的结果,顺序不一定最优——最相关的可能排在后面。Flash Re-Ranker 就是干这个的:它用更复杂的算法,综合考虑语义、词汇匹配度、上下文等因素,对合并后的结果重新排序,把最相关的文本块推上前列。比如在产品描述库里搜特定产品 ID,它能把精确命中并且语义最匹配的描述排在最前面。

基于 LangChain 的实现

LangChain 这个框架很适合整合检索和文本处理流程。下面是一套完整的实现示例:

(一)基于 PGVector 的语义搜索实现

from langchain.vectorstores import PGVector
from jinaai import Embedding

# 初始化PGVector
vector_store = PGVector(
    connection_string="postgresql://myuser:mypassword@localhost/mydb",
    embedding_function=Embedding(model="jina-embeddings-v2-base-en")
)

# 执行语义搜索
query = "1234567890XYZ"
semantic_results = vector_store.similarity_search(query, k=10)
print(semantic_results)

代码中先用 PGVector 类创建向量存储对象,指定连接字符串和嵌入函数,然后用 similarity_search 方法做语义搜索,k 控制返回的结果数量。

(二)PostgreSQL 全文搜索实现

import psycopg2

# 定义自定义停用词
STOP_WORDS = {
    "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if",
    "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that",
    "the", "their", "then", "there", "these", "they", "this", "to", "was",
    "will", "with", "me", "my", "you", "your", "we", "our", "us", "he",
    "him", "his", "she", "her", "hers", "it", "its", "them", "so", "too"
}

def filter_stop_words(query):
    """从输入查询中去除停用词。"""
    words = query.split()
    filtered_words = [word for word in words if word.lower() not in STOP_WORDS]
    return " ".join(filtered_words) if filtered_words else query

def perform_full_text_search(query):
    conn = psycopg2.connect("dbname=mydb user=myuser password=mypassword host=localhost")
    cursor = conn.cursor()

    filtered_query = filter_stop_words(query)
    print(f"原始查询: {query}")
    print(f"过滤后的查询(不含停用词): {filtered_query}")

    # 精确匹配(过滤停用词后)
    cursor.execute(
        "SELECT * FROM documents WHERE to_tsvector('english', content) @@ plainto_tsquery('english', %s);",
        (filtered_query,)
    )
    exact_results = cursor.fetchall()

    # 部分匹配(ILIKE,不过滤停用词)
    cursor.execute("SELECT * FROM documents WHERE content ILIKE %s;", (f"%{query}%",))
    partial_results = cursor.fetchall()

    cursor.close()
    conn.close()
    return exact_results + partial_results

query = "I want to see details of 1234567890XYZ"
retrieved_chunks = perform_full_text_search(query)
print("结果:", retrieved_chunks)

这段代码先定义停用词集合,写了一个过滤函数 filter_stop_words,然后 perform_full_text_search 函数里分别做精确匹配(过滤停用词后)和部分匹配(ILIKE),最后合并返回。

(三)合并和重排序结果

from flashrank import FlashRanker

def re_rank_results(semantic_results, text_results):
    ranker = FlashRanker()
    semantic_texts = [{"text": doc.page_content} for doc in semantic_results]
    text_texts = [{"text": row[1]} for row in text_results]  # 假设文本在第二列
    combined_results = semantic_texts + text_texts
    reranked_results = ranker.rank(combined_results)
    return reranked_results

final_results = re_rank_results(semantic_results, retrieved_chunks)
print(final_results)

re_rank_results 函数提取语义和文本搜索的结果,合并后调用 Flash Re-Ranker 的 rank 方法完成重排序。

重要考虑因素

整个流程里有几个细节值得注意:

自定义停用词

全文搜索里停用词处理很关键。停用词是那些出现频率高但对检索没帮助的词(a、the、and 等)。自定义停用词列表可以根据场景灵活调整:科技文献里某些常用词可能很有意义,就需要移除;代码注释里则可能要把特殊符号加进去。合理的停用词配置能明显提升检索准确率。

PostgreSQL 配置

PostgreSQL 内置了多种语言的停用词列表,还支持创建自定义词典来实现更精细的处理。根据文本语言和应用场景选择合适的内置列表,或者建自定义词典来标记特殊词汇或做词形转换,能进一步优化全文搜索性能。

性能优化

去除停用词不仅能提高准确率,还能加快搜索速度——尤其是在处理大规模数据集时。去掉那些低频词汇后,数据库要处理的词数减少,索引也可以更小更高效。实际应用中需要根据数据集规模和特性,在停用词处理复杂度和性能提升之间做好平衡。

回到检索精度这个核心问题:通过 PGVector 语义搜索 + PostgreSQL 全文搜索 + Flash Re-Ranker 重排序的混合方案,能有效解决特定 ID 匹配不准确的老大难问题,让 RAG 系统在真实业务场景中跑得更稳、更准。

热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:利用混合搜索与重排序改进RAG检索效果(含代码示例)要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://www.53ai.com/news/RAG/2025042186197.html
ai 人工智能

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-07 20:10
Dzine AI图像设计工具 卓越构图与风格控制

Dzine是一款强调构图控制与风格管理的AI图像设计工具,提供样式库、图层操作、定位和素描工具,支持文生图与图生图,具备生成填充编辑、一键修复增强及最高6144像素超高清导出功能,降低设计门槛,兼顾新手与专业用户。

AI热点2026-07-07 20:09
Arrival基于云的SaaS解决方案

3D虚拟空间的搭建,过去往往依赖专业建模软件和大量手动操作,技术门槛相当高。但现在,一款名为Arrival的云端SaaS解决方案正凭借AI与拖放功能,将这件事变得像搭积木一样轻松便捷。 什么是Arrival? Arrival本质上是一套专业的软件工具,核心目标就是帮助用户快速构建一个3D虚拟空间。它

AI热点2026-07-07 20:09
AI用户访谈:洞察需求加速产品市场匹配

ZENAI通过AI自动完成用户访谈,省去人工招募与主持流程,并自动总结用户场景、痛点及人物画像。产品经理、设计师、研究员可借此快速验证假设、提炼场景、获取市场洞察,加速产品市场契合度(PMF)达成,提供基础与专业两种套餐。

AI热点2026-07-07 20:09
Meshcapade ME AI生成逼真数字人头像平台

MeshcapadeMe基于SMPL人体模型技术,提供API接口支持图像、视频、测量及3D扫描输入,自动生成统一格式的逼真数字分身,无需专业建模技能即可将各类素材转化为可动画、跨平台使用的数字人类,适用于虚拟现实、游戏与影视等领域。

延伸阅读