Vereinfachung der juristischen Recherche mit RAG, Milvus und Ollama
In diesem Blogbeitrag sehen wir, wie wir RAG auf juristische Daten anwenden können.
Juristische Recherche kann zeitaufwendig sein. In der Regel müssen Sie eine große Anzahl von Dokumenten prüfen, um die benötigten Antworten zu finden. Retrieval-Augmented Generation (RAG) kann dabei helfen, Ihren Rechercheprozess zu optimieren.
Was ist RAG?
Retrieval Augmented Generation (RAG) ist eine Technik, die LLMs durch die Integration zusätzlicher Datenquellen erweitert. Eine typische RAG-Anwendung umfasst:
Indexierung - eine Pipeline zum Aufnehmen von Daten aus einer Quelle und deren Indexierung, die in der Regel aus dem Laden, Aufteilen und Sortieren der Daten in Milvus besteht.
Abruf und Generierung - Zur Laufzeit verarbeitet RAG die Anfrage des Benutzers, ruft relevante Daten aus dem in Milvus gespeicherten Index ab, und das LLM generiert auf Grundlage dieses angereicherten Kontexts eine Antwort.
In diesem praxisorientierten Leitfaden untersuchen wir, wie man ein Retrieval Augmented Generation (RAG)-System mit Ollama einrichtet, mit Fokus auf juristische Daten und unter Nutzung von Milvus als unserer Vektordatenbank.
Die Tools:
Ollama: Bringt die Leistungsfähigkeit von LLMs auf Ihren Laptop und vereinfacht den lokalen Betrieb.
Milvus: Die Vektordatenbank, die wir verwenden, um Ihre Daten effizient zu speichern und abzurufen.
Llama 3: Metas neueste Iteration einer Reihe großer Sprachmodelle.
Voyage AI - Bietet Einbettungsmodelle, die auf bestimmte Domänen spezialisiert sind. Wir verwenden ihre spezialisierte juristische Einbettung, optimiert für juristischen Abruf und Abruf mit langem Kontext.
Vorbereitung
Abhängigkeiten und Daten
Installieren Sie zunächst die notwendigen Abhängigkeiten:
! pip install --upgrade pymilvus ollama tqdm pypdf voyageai openai wget
API-Schlüssel importieren
Wenn Sie Ihren API-Schlüssel in einer .env-Datei festgelegt haben, können Sie ihn mit dotenv laden, um zu vermeiden, dass der Schlüssel offengelegt wird, wenn Sie Ihr Notebook hochladen.
import os
from dotenv import load_dotenv
load_dotenv()
VOYAGE_API_KEY = os.getenv('VOYAGE_API_KEY')
Wenn Sie keine .env-Datei haben, überspringen Sie einfach den dotenv-Import.
Daten vorbereiten
Für dieses Tutorial verwenden wir Daten der Royal Courts of Justice in London. Laden Sie sie mit wget herunter und speichern Sie sie lokal:
! wget https://www.judiciary.uk/wp-content/uploads/2024/07/Final-Judgment-CA-2023-001978-BBC-v-BBC-Pension-Trust-another.pdf
Lesen Sie als Nächstes die PDF-Datei und extrahieren Sie ihren Inhalt zur Verwendung in unserer RAG-Anwendung:
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])
Dies sollte Ihnen die folgende Ausgabe liefern:
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
Ihre Dokumente einbetten
Wir verwenden voyage-law-2, ein Einbettungsmodell, das auf den juristischen Bereich spezialisiert ist.
Definieren Sie zunächst eine Funktion, um Texteinbettungen mithilfe der Voyage AI API zu generieren:
import voyageai
voyage_client = voyageai.Client()
def embed_text(text: str) -> str:
return voyage_client.embed([text], model="voyage-law-2").embeddings[0]
Generieren Sie eine Testeinbettung und geben Sie ihre Dimension sowie die ersten paar Elemente aus.
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]
Daten in Milvus laden
Die Collection in Milvus erstellen
from pymilvus import MilvusClient
milvus_client = MilvusClient(uri="./milvus_legal.db")
collection_name = "my_rag_collection"
Das Festlegen der URI als lokale Datei, z. B. ./milvus_legal.db, ist praktisch, da dadurch automatisch Milvus Lite verwendet wird, um alle Daten in dieser Datei zu speichern. Für groß angelegte Daten können Sie einen leistungsfähigeren Milvus-Server auf Docker oder Kubernetes einrichten.
Löschen Sie die Collection, falls sie bereits existiert, und erstellen Sie dann eine neue:
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
)
Wenn wir keine Feldinformationen angeben, erstellt Milvus automatisch ein Standard-id-Feld für den Primärschlüssel und ein Vektorfeld zum Speichern der Vektordaten. Ein reserviertes JSON-Feld wird verwendet, um nicht im Schema definierte Felder und ihre Werte zu speichern.
Daten einfügen
Iterieren Sie durch die Seiten unseres Dokuments, erstellen Sie die Embeddings und fügen Sie dann die Daten in Milvus ein.
Wir führen ein neues Feld namens text ein, ein nicht definiertes Feld im Collection-Schema. Es wird automatisch dem reservierten dynamischen JSON-Feld hinzugefügt, das auf hoher Ebene wie ein normales Feld behandelt werden kann.
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}
Das grundlegende RAG-System aufbauen
Als Nächstes definieren wir eine Frage zum Inhalt der Gerichtsverhandlung:
question = "who are the lawyers?"
Wir verwenden Milvus, um unsere indizierten Daten zu durchsuchen. Später integrieren wir dies mit einem 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
)
Geben Sie die abgerufenen Zeilen mit ihren Distanzen aus:
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))
```
Der mit unseren Embeddings verknüpfte Text ist ziemlich lang, aber hier ist ein Beispiel dafür, was Milvus zurückgibt
[" n nNeutrale Zitiernummer [2024] EWCA Civ 767 n nAktenzeichen: CA-2023 -001978 nIM COURT OF APPEAL ( CIVIL DIVISION) nIM BERUFUNGSVERFAHREN GEGEN 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 nDatum: 09/07 /2024 nVor : n nLORD JUSTICE LEWISON nLADY JUSTICE FALK nund nSIR CHRISTOPHER FLOYD n n- - - - - - - - - - - - - - - - - - - - - n nZwischen : n n BRITISH BROADCASTING CORPORATION Berufungsklägerin n - und - n (1) BBC P ENSION TRUST LIMITED n(2) CHRISTINA BURNS nBerufungsbeklagte n n- - - - - - - - - - - - - - - - - - - - - n n Michael Tennet KC und Edward Sawyer (beauftragt durch Linklaters LLP ) nfür die Berufungsklägerin n Brian Green KC und Joseph Steadman (beauftragt durch Slaughter and May Solicitors ) nfür die erste Berufungsbeklagte nAndrew Spink KC und Saul Margo (beauftragt durch Stephenson Harwood LLP ) nfür die zweite Berufungsbeklagte n nVerhandlungstermine: 25, 26 & 27/06/2024 n- - - - - - - - - - - - - - - - - - - - - n nGenehmigtes Urteil n nDieses Urteil wurde am 09/07/2024 um 11.00 Uhr aus der Ferne verkündet, durch Übermittlung an die nParteien oder ihre Vertreter per E -Mail und durch Freigabe an The Nat ional Archives. n n............................. n",
0.1101425364613533
],
Ein LLM verwenden, um eine RAG-Antwort zu erhalten
Kombinieren Sie die abgerufenen Dokumente zu einem Kontext und definieren Sie System- und Benutzer-Prompts für das Sprachmodell:
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 verfügt über eine vollständig kompatible OpenAI API, was bedeutet, dass wir das OpenAI Python SDK verwenden können, um Ollama aufzurufen:
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)
Dem Text zufolge sind die an diesem Fall beteiligten Anwälte:
* Andrew Spink KC (beauftragt durch Stephenson Harwood LLP) für die erste Berufungsbeklagte
* Saul Margo (ebenfalls beauftragt durch Stephenson Harwood LLP) für die erste Berufungsbeklagte
* Mr. Tennet (Vertreter der zweiten Berufungsbeklagten)
* Mr. Spink KC (ebenfalls Vertreter der zweiten Berufungsbeklagten)
* Arden LJ (erwähnt als Verfasserin eines früheren Urteils in Stena Line)
Beachten Sie, dass „KC“ für King's Counsel steht, einen Ehrentitel, der bestimmten hochrangigen Barristers in England und Wales verliehen wird.
Fazit
Die Einrichtung von RAG mit Milvus und Ollama für juristische Daten kann die juristische Recherche erheblich erleichtern und effizienter machen.
Schauen Sie sich gerne Milvus, den Code auf Github an und teilen Sie Ihre Erfahrungen mit der Community, indem Sie unserem Discord beitreten.
Weitere Ressourcen zu Milvus und Ollama:
Weiterlesen

We spent 8 years making vector databases faster. Then we stopped.
Rarely queried embeddings still need to stay searchable. See how Vector Lakebase enables on-demand vector search without always-on compute costs.

Why AI Databases Don't Need SQL
Whether you like it or not, here's the truth: SQL is destined for decline in the era of AI.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.



