前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LLM 回答更加准确的秘密:为检索增强生成(RAG)添加引用源

LLM 回答更加准确的秘密:为检索增强生成(RAG)添加引用源

作者头像
Zilliz RDS
发布2023-08-25 09:07:00
1.8K0
发布2023-08-25 09:07:00
举报
文章被收录于专栏:Reinvent Data Science

如何让你的大模型变得更强?如何确定其获取信息来源的准确性?

想要回答这两个问题,就不得不提到今天文章的主角——RAG。RAG,也就是检索增强生成(Retrieval-augmented generation) ,可以弥补现有 LLM 应用能力的技术。

当前,LLM 的最大问题就是缺乏最新的知识和特定领域的知识。对于这一问题,业界有两种主要解决方法:微调和检索增强生成。业内许多公司(如 Zilliz、OpenAI 等)都认为相比微调,RAG 是更好的解决方法。归根究底是因为微调的成本更高,需要使用的数据也更多,因此主要适用于风格迁移(style transfer)的场景。相比之下,RAG 方法使用例如 Milvus 之类的向量数据库,从而将知识和数据注入到应用中,更适用于通用场景。

采用 RAG 方法就意味着使用向量数据库存储真理数据,这样可以确保应用返回正确的信息和知识,而不是在缺乏数据时产生幻觉,捏造回答。不过,随着越来越多的文档、用例等信息被注入应用中,越来越多开发者意识到信息来源的重要性,它可以确保信息准确性,使得大模型的回答更加真实。

这就需要用到引用或者归属(attribution)。如果返回的响应带有引用或者归属,那么我们就可以了解该响应内容来自于哪个文档或文档中的哪个片段。因此,本文将详解为 LLM 加入引用的重要性,以及如何获取引用来源。

01.

如何添加 RAG 引用源?

正如上文所说,RAG(https://zilliz.com/use-cases/llm-retrieval-augmented-generation) 引用源是一种通用的解决方案,可以为 LLM 应用的响应添加引用源,从而为响应提供更多上下文信息。那么如何为响应添加 RAG 引用源呢?其实有很多解决方法。你既可以将文本块存储在向量数据库中,也可以使用 LlamaIndex 之类的框架。

接下来就让我们深入代码,学习如何同时使用 LlamaIndex 和 Milvus(https://zilliz.com/what-is-milvus) 为 LLM 响应添加引用源。

  • 开始之前

开始前,先通过 pip install milvus llama-index python-dotenv安装所需工具和框架。milvusllama-index是核心功能,而 python-dotenv用于加载环境变量,例如 OpenAI 的 API 密钥。

在本示例中,我们从百科中获取了不同城市的数据,并进行查询,最终获得带引用的响应。

首先,导入一些必要的库并加载 OpenAI API 密钥,同时也需要用到 LlamaIndex 的 7 个子模块。在本示例中,OpenAI用于访问 LLM,CitationQueryEngine用于创建引用查询引擎,MilvusVectorStore用于将 Milvus 作为向量存储数据库。此外,导入 VectorStoreIndex来使用 Milvus,SimpleDirectoryReader 用于读取本地数据,以及 StorageContextServiceContext用于访问 Milvus。最后,用 load_dotenv加载我们的 OpenAI API 密钥。

代码语言:javascript
复制
from llama_index.llms import OpenAI
from llama_index.query_engine import CitationQueryEngine
from llama_index import (
    VectorStoreIndex,
    SimpleDirectoryReader,
    StorageContext,
    ServiceContext,
)
from llama_index.vector_stores import MilvusVectorStore
from milvus import default_server

from dotenv import load_dotenv
import os
load_dotenv()
open_api_key = os.getenv("OPENAI_API_KEY")
  • 获取测试数据

首先准备和处理数据,下面的代码从百科 API 中获取了 wiki_titles列表中提到的页面并将结果保存到本地文件中。

代码语言:javascript
复制
wiki_titles = ["Toronto", "Seattle", "San Francisco", "Chicago", "Boston", "Washington, D.C.", "Cambridge, Massachusetts", "Houston"]
from pathlib import Path

import requests
for title in wiki_titles:
    response = requests.get(
        '<https://en.wikipedia.org/w/api.php>',
        params={
            'action': 'query',
            'format': 'json',
            'titles': title,
            'prop': 'extracts',
            'explaintext': True,
        }
    ).json()
    page = next(iter(response['query']['pages'].values()))
    wiki_text = page['extract']

    data_path = Path('data')
    if not data_path.exists():
        Path.mkdir(data_path)

    with open(data_path / f"{title}.txt", 'w') as fp:
        fp.write(wiki_text)
  • 在 LlamaIndex 中设置向量存储(Vector Store)

数据准备完成后,可以设置带应用逻辑。首先,我们需要启动向量数据库。在本例中,我们使用 Milvus Lite,因为它可以直接在笔记本电脑上运行。然后,用 LlamaIndex 的 MilvusVectorStore模块连接 Milvus,将其作为向量存储。

代码语言:javascript
复制
default_server.start()
vector_store = MilvusVectorStore(
    collection_name="citations",
    host="127.0.0.1",
    port=default_server.listen_port
)

接着,为索引创建上下文,从而帮助索引和检索器了解需要使用哪些服务。本例使用 GPT 3.5 Turbo。此外,我们还需要创建一个存储上下文,以便索引知道在哪里存储和查询数据。本例使用上述创建的 Milvus 向量存储。

代码语言:javascript
复制
service_context = ServiceContext.from_defaults(
    llm=OpenAI(model="gpt-3.5-turbo", temperature=0)
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

设置完成后可以加载此前爬取的数据,并创建向量存储索引。

代码语言:javascript
复制
documents = SimpleDirectoryReader("./data/").load_data()
index = VectorStoreIndex.from_documents(documents, service_context=service_context, storage_context=storage_context)
  • 带引用的查询

这一步可以创建一个引用查询引擎。可以设置向量索引,返回结果数量以及引用文本块大小。随后运行查询命令。

代码语言:javascript
复制
query_engine = CitationQueryEngine.from_args(
    index,
    similarity_top_k=3,
    # 此处我们可以控制引用来源的粒度,默认值为 512
    citation_chunk_size=512,
)
response = query_engine.query("Does Seattle or Houston have a bigger airport?")
print(response)
for source in response.source_nodes:
    print(source.node.get_text())

响应如下所示:

02.

总结

RAG 应用是流行的 LLM 应用。本文教学了如何为 RAG 添加引用或归属。

具体来看,可以使用 LlamaIndex 作为数据路由器,Milvus 作为向量存储来构建带有引用的 RAG 应用。本文提供的示例代码先从百科上获取一些数据,然后启动一个 Milvus 实例,并在 LlamaIndex 中创建一个向量存储实例。将数据存入 Milvus 中,并使用 LlamaIndex 构建引用查询引擎来追踪返回响应的归属和引用源。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ZILLIZ 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档