借助这个开源项目,我将 RAG 的准确性和召回率都提高了两倍!

本文首发于博客 LLM 应用开发实践

RAG(Retrieval Augmented Generation)是一种检索增强生成技术,它利用大型语言模型来处理用户查询,RAG 技术的主要组成包括数据提取---embedding---创建索引---检索---排序(Rerank)---LLM 归纳生成,不过实际落地过程来看,将用户查询转换为嵌入向量直接检索,很多时候的结果在相关度方面没有那么理想,本篇分享一种对用户查询进行重写再去进行检索从而提高准确性和召回率的方案。

RAG技术图解

直接检索的问题

将用户查询转换为嵌入向量直接检索会出现下面四类常见问题 👇:

查询结果不匹配

模型假设查询 embedding 和内容 embedding 在嵌入空间中是相似的,但基于要搜索的文本,匹配度不一定是最优的,仅仅靠内容在语义上相似的查询出的结果并不理想。

单一搜索后端

实际情况可能有多个搜索后端,每个后端都有自己的 API,可以考虑将查询路由到向量存储、搜索客户端、SQL 数据库等等。

文本搜索的局限性

文本搜索的限制是它仅限于单个字符串的复杂查询,牺牲了表达能力,无法使用关键词、过滤器和其他高级功能。例如,通过简单的文本搜索无法回答"我们上周解决了哪些问题",因为包含的关键词"问题"和"上周"的将在所有文档范围都存在。

有限的规划能力

假设查询是搜索后端的唯一输入,无法使用其他信息来改善搜索。

解决方案

将自然语言查询通过大语言模型转换为优化后的自定义查询语句,最终能够高效理解达到提高准确性和召回率的目的。

多个搜索后端RAG

案例一

比如搜索 "人工智能有哪些最新发展",通过系统内部限定发布日期范围和搜索域列表的方式重写查询。

python 复制代码
class DateRange(BaseModel):
    start: datetime.date
    end: datetime.date

class MetaphorQuery(BaseModel):
    rewritten_query: str
    published_daterange: DateRange
    domains_allow_list: List[str]

    async def execute():
        return await metaphor.search(...)

import instructor
import openai
# Enables response_model in the openai client
instructor.patch()
query = openai.ChatCompletion.create(
    model="gpt-4",
    response_model=MetaphorQuery,
    messages=[
        {
            "role": "system",
            "content": "You're a query understanding system for the Metafor Systems search engine. Here are some tips: ..."
        },
        {
            "role": "user",
            "content": "What are some recent developments in AI?"
        }
    ],
)

重写后的查询内容为在arxiv上搜索最近三个月带有 最新进展 先进人工智能 机器学习 几个关键字的论文,通过限定条件限制了查询范围,提高查询精度

json 复制代码
{
    "rewritten_query": "novel developments advancements ai artificial intelligence machine learning",
    "published_daterange": {
        "start": "2023-10-12",
        "end": "2021-07-12"
    },
    "domains_allow_list": ["arxiv.org"]
}

案例二

个人助理的例子,当你问智能助理"我今天有什么事情要做?",从一个模糊的查询中可能需要获取事件、邮件、提醒等,这些数据可能存在于多个后端,但你想要的是一个统一的结果汇总,这种场景下不能假设这些相关的文本都嵌入在一个搜索后端中,可能会有一个日历客户端、邮件客户端等等。

python 复制代码
class ClientSource(enum.Enum):
    GMAIL = "gmail"
    CALENDAR = "calendar"

class SearchClient(BaseModel):
    query: str
    keywords: List[str]
    email: str
    source: ClientSource
    start_date: datetime.date
    end_date: datetime.date

    async def execute(self) -> str:
        if self.source == ClientSource.GMAIL:
            ...
        elif self.source == ClientSource.CALENDAR:
            ...

class Retrival(BaseModel):
    queries: List[SearchClient]

    async def execute(self) -> str:
        return await asyncio.gather(*[query.execute() for query in self.queries])

import instructor
import openai

# Enables response_model in the openai client
instructor.patch()
retrival = openai.ChatCompletion.create(
    model="gpt-4",
    response_model=Retrival,
    messages=[
        {"role": "system", "content": "You are Jason's personal assistant."},
        {"role": "user", "content": "What do I have today?"}
    ],
)

重写后的查询为今天的邮件和日程表上有会议、电话、zoom等关键字的内容,通过查询列表路由到不同的搜索后端(电子邮件和日历),异步分发,也可以提高性能

python 复制代码
{
    "queries": [
        {
            "query": None,
            "keywords": None,
            "email": "jason@example.com",
            "source": "gmail",
            "start_date": "2023-10-12",
            "end_date": None
        },
        {
            "query": None,
            "keywords": ["meeting", "call", "zoom"],
            "email": "jason@example.com",
            "source": "calendar",
            "start_date": "2023-10-12",
            "end_date": None

        }
    ]
}

结语

能够实现这一切,得益于开源项目 instructor,封装了复杂的建模过程,拿来即用即可。 本文参考自 RAG is more than just embedding search

更多内容在公号:LLM 应用全栈开发

相关推荐
weixin_3077791318 分钟前
RAG 面试陷阱——混合检索并非无条件优越:一个条件反转实验
人工智能·python·面试·职场和发展
Sinokap28 分钟前
OpenAI 披露 AI 安全实验:智能体如何突破隔离边界?
人工智能·安全
云和数据.ChenGuang1 小时前
深入解析 Python 的 dir():从用法到 CPython 源码实现
开发语言·人工智能·python·langchain
重生之我在番茄自学网安拯救世界1 小时前
AI 开发者日报 第1期(本周精选)| 插件市场投毒、智能体搞出“官僚饥荒村”,十年前的 CNN 打赢大模型
人工智能·网络安全·大模型·ai编程·智能体
涛声依旧-底层原理研究所1 小时前
拆解 Cordis 底座:Agent 是如何被「组合」出来的
人工智能·架构
nice_lcj5202 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
秦先生在广东2 小时前
记忆不再是黑盒
人工智能
秦先生在广东2 小时前
49个AI智能体接管你的游戏开发
人工智能
骑着蜗牛撵大象3272 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp