借助这个开源项目,我将 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 应用全栈开发

相关推荐
谢尔登11 分钟前
【Webpack】Hash 码
算法·webpack·哈希算法
程序和我有一个能跑就行。15 分钟前
【Python】递归
数据结构·python·算法·递归
Grayson_Zheng15 分钟前
【数据结构】环形队列(循环队列)学习笔记总结
c语言·数据结构·算法
知来者逆20 分钟前
探索基于知识图谱和 ChatGPT 结合制造服务推荐前沿
人工智能·语言模型·自然语言处理·chatgpt·知识图谱·大语言模型·多模态
吃什么芹菜卷29 分钟前
机器学习:opencv--特征检测
人工智能·笔记·opencv·机器学习·计算机视觉
背水31 分钟前
BFS之最短路径模型
算法·宽度优先
乐思智能科技有限公司32 分钟前
C语言编写一个五子棋游戏-代码实例讲解与分析
c语言·开发语言·嵌入式硬件·算法·游戏
漂流瓶jz33 分钟前
UVA-690 流水线调度 题解答案代码 算法竞赛入门经典第二版
c++·算法·深度优先·aoapc·算法竞赛入门经典·uva
乖巧乐芬达41 分钟前
NCU-机器学习-作业3:基于SVM的手写字识别
人工智能·机器学习·支持向量机