使用RAG、Milvus和Ollama简化法律研究
在这篇博客中,我们将探讨如何将RAG应用于法律数据。
法律研究可能非常耗时。您通常需要审查大量文档以找到所需的答案。检索增强生成(RAG)可以帮助简化您的研究过程。
什么是RAG?
检索增强生成(RAG)是一种通过整合额外数据源来增强LLM的技术。典型的RAG应用包括:
- 索引 - 从源摄取数据并进行索引的管道,通常包括在Milvus中加载、分割和排序数据。
- 检索和生成 - 在运行时,RAG处理用户的查询,从存储在Milvus中的索引中提取相关数据,LLM根据这个丰富的上下文生成响应。
在这篇动手指南中,我们将探索如何使用Ollama构建检索增强生成(RAG)系统,重点关注法律数据,并利用Milvus作为我们的向量数据库。
工具:
- Ollama:将LLM的强大功能带到您的笔记本电脑,简化本地操作。
- Milvus:我们用来高效存储和检索数据的向量数据库。
- Llama 3:Meta最新版本的大型语言模型。
- Voyage AI - 提供专门针对特定领域的嵌入模型。我们使用他们的法律嵌入模型,优化用于法律和长上下文检索。
准备工作
依赖项和数据
首先,安装所需的依赖项:
! pip install --upgrade pymilvus ollama tqdm pypdf voyageai openai wget
导入API密钥
如果您在.env文件中设置了API密钥,可以使用dotenv加载它,以避免在推送笔记本时泄露密钥。
import os
from dotenv import load_dotenv
load_dotenv()
VOYAGE_API_KEY = os.getenv('VOYAGE_API_KEY')
如果您没有.env文件,只需跳过dotenv导入。
准备数据
对于本教程,我们将使用来自伦敦皇家法院的数据。使用wget下载并保存在本地:
! wget https://www.judiciary.uk/wp-content/uploads/2024/07/Final-Judgment-CA-2023-001978-BBC-v-BBC-Pension-Trust-another.pdf
接下来,读取PDF文件并提取其内容以供我们的RAG应用使用:
from pypdf import PdfReader
reader = PdfReader("Final-Judgment-CA-2023-001978-BBC-v-BBC-Pension-Trust-another.pdf")
pages = [page.extract_text() for page in reader.pages]
print(pages[0])
这应该给您以下输出:
Neutral Citation Number [2024] EWCA Civ 767
Case No: CA-2023 -001978
IN THE COURT OF APPEAL ( CIVIL DIVISION)
ON APPEAL FROM THE HIGH COURT OF JUSTICE
BUSINESS AND PROPERTY COURTS OF ENGLAND AND WALES
BUSINESS LIST : PENSIONS (ChD)
The Hon Mr Justice Adam Johnson
[2023] EWHC 1965 (Ch)
Royal Courts of Justice
Strand, London, WC2A 2LL
Date: 09/07 /2024
Before :
LORD JUSTICE LEWISON
LADY JUSTICE FALK
and
SIR CHRISTOPHER FLOYD
嵌入您的文档
我们将使用voyage-law-2,这是一个专门针对法律领域的嵌入模型。
首先,定义一个函数,使用Voyage AI API生成文本嵌入:
import voyageai
voyage_client = voyageai.Client()
def embed_text(text: str) -> str:
return voyage_client.embed([text], model="voyage-law-2").embeddings[0]
生成一个测试嵌入并打印其维度和前几个元素。
result = voyage_client.embed(["hello world"], model="voyage-law-2")
embedding_dim = len(result.embeddings[0])
print(embedding_dim)
print(result.embeddings[0][:10])
1024
[0.000756315013859421, -0.02162403240799904, 0.0052010356448590755, -0.02917512319982052, -0.00796651840209961, -0.03238343447446823, 0.0660339742898941, 0.03845587745308876, -0.01913367211818695, 0.05562642216682434]
将数据加载到Milvus中
在Milvus中创建集合
from pymilvus import MilvusClient
milvus_client = MilvusClient(uri="./milvus_legal.db")
collection_name = "my_rag_collection"
将URI设置为本地文件,例如./milvus_legal.db,方便使用,因为它会自动使用Milvus Lite将所有数据存储在此文件中。对于大规模数据,您可以在Docker或Kubernetes上设置一个性能更好的Milvus服务器。
如果集合已经存在,则删除该集合,然后创建一个新的:
if milvus_client.has_collection(collection_name):
milvus_client.drop_collection(collection_name)
milvus_client.create_collection(
collection_name=collection_name,
dimension=embedding_dim,
metric_type="IP", # Inner product distance
consistency_level="Strong", # Strong consistency level
)
如果我们不指定任何字段信息,Milvus将自动为主键创建一个默认的id字段,并创建一个用于存储向量数据的向量字段。一个保留的JSON字段用于存储未定义模式的字段及其值。
插入数据
遍历我们文档的页面,创建嵌入,然后将数据插入Milvus。
我们引入一个名为text的新字段,这是集合模式中未定义的字段。它将自动添加到保留的JSON动态字段中,可以在高级别上视为正常字段。
from tqdm import tqdm
data = []
for i, page in enumerate(tqdm(pages, desc="Creating embeddings")):
data.append({"id": i, "vector": embed_text(page), "text": page})
milvus_client.insert(collection_name=collection_name, data=data)
Creating embeddings: 100%|███████████████████████████████████████████████████████████████████████████████████████| 20/20 [00:08<00:00, 2.45it/s]
{'insert_count': 20,
'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
'cost': 0}
构建基本RAG系统
接下来,让我们定义一个关于法庭听证内容的查询:
question = "who are the lawyers?"
我们将使用Milvus搜索我们的索引数据。稍后,我们将与LLM集成。
search_res = milvus_client.search(
collection_name=collection_name,
data=[
embed_text(question)
], # Use the `embed_text` function to convert the question to an embedding vector
limit=3, # Return top 3 results
search_params={"metric_type": "IP", "params": {}}, # Inner product distance
output_fields=["text"], # Return the text field
)
打印检索到的行及其距离:
import json
retrieved_lines_with_distances = [
(res["entity"]["text"], res["distance"]) for res in search_res[0]
]
print(json.dumps(retrieved_lines_with_distances, indent=4))
与我们的嵌入相关的文本相当长,但以下是Milvus返回的示例:
[" n nNeutral Citation Number [2024] EWCA Civ 767 n nCase No: CA-2023 -001978 nIN THE COURT OF APPEAL ( CIVIL DIVISION) nON APPEAL FROM THE HIGH COURT OF JUSTICE nBUSINESS AND PROPERTY COURTS OF ENGLAND AND WALES nBUSINESS LIST : PENSIONS (ChD) nThe Hon Mr Justice Adam Johnson n[2023] EWHC 1965 (Ch) nRoyal Courts of Justice nStrand, London, WC2A 2LL n nDate: 09/07 /2024 nBefore : n nLORD JUSTICE LEWISON nLADY JUSTICE FALK nand nSIR CHRISTOPHER FLOYD n n- - - - - - - - - - - - - - - - - - - - - n nBetween : n n BRITISH BROADCASTING CORPORATION Appellant n - and - n (1) BBC P ENSION TRUST LIMITED n(2) CHRISTINA BURNS nRespondent s n n- - - - - - - - - - - - - - - - - - - - - n n Michael Tennet KC and Edward Sawyer (instructed by Linklaters LLP ) nfor the Appellant n Brian Green KC and Joseph Steadman (instructed by Slaughter and May Solicitors ) nfor the First Respondent nAndrew Spink KC and Saul Margo (instructed by Stephenson Harwood LLP ) nfor the Second Respondent n nHearing dates: 25, 26 & 27/06/2024 n- - - - - - - - - - - - - - - - - - - - - n nApproved Judgment n nThis judgment was handed down remotely at 11.00am on 09/07/2024 by circulation to the nparties or their representatives by e -mail and by release to the Nat ional Archives. n n............................. n",
0.1101425364613533
],
使用LLM获取RAG响应
将检索到的文档合并为上下文,并为语言模型定义系统和用户提示:
context = "n".join(
[line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)
SYSTEM_PROMPT = """
Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided.
"""
USER_PROMPT = f"""
Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.
<context>
{context}
</context>
<question>
{question}
</question>
"""
Ollama有一个完全兼容的OpenAI API,这意味着我们可以使用OpenAI Python SDK调用Ollama:
from openai import OpenAI
client = OpenAI(
base_url = 'http://localhost:11434/v1',
api_key='ollama', # required, but unused
)
response = client.chat.completions.create(
model="llama3",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": USER_PROMPT},
],
)
print(response.choices[0].message.content)
According to the text, the lawyers involved in this case are:
* Andrew Spink KC (instructed by Stephenson Harwood LLP) for the First Respondent
* Saul Margo (also instructed by Stephenson Harwood LLP) for the First Respondent
* Mr. Tennet (representing the Second Respondent)
* Mr. Spink KC (also representing the Second Respondent)
* Arden LJ (mentioned as having given a previous judgment in Stena Line)
Note that "KC" stands for King's Counsel, which is a title of distinction conferred upon certain senior barristers in England and Wales.
结论
使用Milvus和Ollama为法律数据设置RAG可以使法律研究变得更容易、更高效。
欢迎查看Milvus、Github上的代码,并通过加入我们的Discord与社区分享您的经历。
注:本文为AI翻译,查看原文
技术干货
使用自定义AI模型扩展RAG的基础设施挑战
在Zilliz最近主办的非结构化数据 meetup 上,BentoML的创始人兼首席执行官Chaoyu Yang分享了在扩展带有自定义AI模型的RAG系统时基础设施方面的障碍,并强调了像BentoML这样的工具如何简化这些组件的部署和管理。本文将回顾Chaoyu Yang的关键点,并探讨高级推理模式和优化技术。这些策略将帮助您构建不仅功能强大而且高效和成本效益的RAG系统。
2024-11-29技术干货
使用Ruby和Milvus构建端到端的GenAI应用
在最近的一次演讲中,Source Labs LLC的解决方案架构师Andrei Bondarev介绍了一个名为LangChain.rb的LangChain的Ruby扩展,以使全栈工程师更容易在他们的软件项目中构建GenAI应用。
2024-11-29技术干货
使用 Milvus Lite、Llama3 和 LlamaIndex 搭建 RAG 应用
大语言模型(LLM)已经展示出与人类交互并生成文本响应的卓越能力。这些模型可以执行各种自然语言任务,如翻译、概括、代码生成和信息检索等。
2024-11-20