Simplificando a pesquisa jurídica com RAG, Milvus e Ollama
Neste post do blog, veremos como podemos aplicar RAG a dados jurídicos.
A pesquisa jurídica pode consumir muito tempo. Geralmente, você precisa revisar um grande número de documentos para encontrar as respostas de que precisa. A Geração Aumentada por Recuperação (RAG) pode ajudar a otimizar seu processo de pesquisa.
O que é RAG?
Geração Aumentada por Recuperação (RAG) é uma técnica que aprimora LLMs integrando fontes de dados adicionais. Uma aplicação típica de RAG envolve:
Indexação - um pipeline para ingerir dados de uma fonte e indexá-los, o que geralmente consiste em carregar, dividir e ordenar os dados no Milvus.
Recuperação e geração - Em tempo de execução, o RAG processa a consulta do usuário, busca dados relevantes no índice armazenado no Milvus, e o LLM gera uma resposta com base nesse contexto enriquecido.
Neste guia prático, exploraremos como configurar um sistema de Geração Aumentada por Recuperação (RAG) usando Ollama, com foco em dados jurídicos e aproveitando o Milvus como nosso banco de dados vetorial.
As ferramentas:
Ollama: Traz o poder dos LLMs para o seu laptop, simplificando a operação local.
Milvus: O banco de dados vetorial que usamos para armazenar e recuperar seus dados de forma eficiente.
Llama 3: A iteração mais recente da Meta de uma linha de grandes modelos de linguagem.
Voyage AI - Fornece modelos de embeddings especializados em domínios específicos. Estamos usando o embedding jurídico especializado deles, otimizado para recuperação jurídica e de contexto longo.
Preparação
Dependências e Dados
Primeiro, instale as dependências necessárias:
! pip install --upgrade pymilvus ollama tqdm pypdf voyageai openai wget
Importar Chaves de API
Se você tiver sua chave de API definida em um arquivo .env, poderá carregá-la usando dotenv para evitar vazar a chave quando enviar seu notebook.
import os
from dotenv import load_dotenv
load_dotenv()
VOYAGE_API_KEY = os.getenv('VOYAGE_API_KEY')
Se você não tiver um arquivo .env, basta pular a importação de dotenv.
Preparar os dados
Para este tutorial, usaremos dados das Royal Courts of Justice em Londres. Baixe-os usando wget e salve-os localmente:
! wget https://www.judiciary.uk/wp-content/uploads/2024/07/Final-Judgment-CA-2023-001978-BBC-v-BBC-Pension-Trust-another.pdf
Em seguida, leia o arquivo PDF e extraia seu conteúdo para uso em nossa aplicação 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])
Isso deve fornecer a seguinte saída:
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
Incorpore seus Documentos
Usaremos voyage-law-2, um modelo de embedding especializado para o domínio jurídico.
Primeiro, defina uma função para gerar embeddings de texto usando a API da Voyage AI:
import voyageai
voyage_client = voyageai.Client()
def embed_text(text: str) -> str:
return voyage_client.embed([text], model="voyage-law-2").embeddings[0]
Gere um embedding de teste e imprima sua dimensão e os primeiros elementos.
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]
Carregar dados no Milvus
Criar a coleção no Milvus
from pymilvus import MilvusClient
milvus_client = MilvusClient(uri="./milvus_legal.db")
collection_name = "my_rag_collection"
Definir o URI como um arquivo local, por exemplo, ./milvus_legal.db, é conveniente, pois usa automaticamente o Milvus Lite para armazenar todos os dados nesse arquivo. Para dados em larga escala, você pode configurar um servidor Milvus mais performático no Docker ou Kubernetes.
Exclua a coleção se ela já existir e, em seguida, crie uma nova:
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
)
Se não especificarmos nenhuma informação de campo, o Milvus criará automaticamente um campo id padrão para a chave primária e um campo vetorial para armazenar os dados vetoriais. Um campo JSON reservado é usado para armazenar campos não definidos pelo esquema e seus valores.
Inserir dados
Percorra as páginas do nosso documento, crie os embeddings e, em seguida, insira os dados no Milvus.
Introduzimos um novo campo chamado text, campo não definido no esquema da coleção. Ele será automaticamente adicionado ao campo dinâmico JSON reservado, que pode ser tratado como um campo normal em alto nível.
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}
Construir o sistema RAG básico
Em seguida, vamos definir uma consulta sobre o conteúdo da audiência judicial:
question = "who are the lawyers?"
Usaremos o Milvus para pesquisar nossos dados indexados. Depois, integraremos isso com um 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
)
Imprima as linhas recuperadas com suas distâncias:
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))
```
O texto associado aos nossos embeddings é bastante longo, mas aqui está um exemplo do que o Milvus retorna
[" n nNúmero de Citação Neutra [2024] EWCA Civ 767 n nProcesso nº: CA-2023 -001978 nNO TRIBUNAL DE RECURSO ( DIVISÃO CÍVEL) nEM RECURSO DO ALTO TRIBUNAL DE JUSTIÇA nTRIBUNAIS DE NEGÓCIOS E PROPRIEDADE DA INGLATERRA E DO PAÍS DE GALES nLISTA DE NEGÓCIOS : PENSÕES (ChD) nO Exmo. Sr. Juiz Adam Johnson n[2023] EWHC 1965 (Ch) nRoyal Courts of Justice nStrand, Londres, WC2A 2LL n nData: 09/07 /2024 nPerante : n nLORD JUSTICE LEWISON nLADY JUSTICE FALK ne nSIR CHRISTOPHER FLOYD n n- - - - - - - - - - - - - - - - - - - - - n nEntre : n n BRITISH BROADCASTING CORPORATION Recorrente n - e - n (1) BBC P ENSION TRUST LIMITED n(2) CHRISTINA BURNS nRecorrido s n n- - - - - - - - - - - - - - - - - - - - - n n Michael Tennet KC e Edward Sawyer (instruídos por Linklaters LLP ) npara a Recorrente n Brian Green KC e Joseph Steadman (instruídos por Slaughter and May Solicitors ) npara o Primeiro Recorrido nAndrew Spink KC e Saul Margo (instruídos por Stephenson Harwood LLP ) npara o Segundo Recorrido n nDatas da audiência: 25, 26 e 27/06/2024 n- - - - - - - - - - - - - - - - - - - - - n nSentença Aprovada n nEsta sentença foi proferida remotamente às 11h00 em 09/07/2024 por circulação às npartes ou seus representantes por e -mail e por divulgação aos Arquivos Nac ionais. n n............................. n",
0.1101425364613533
],
Use um LLM para obter uma Resposta RAG
Combine os documentos recuperados em um contexto e defina prompts de sistema e de usuário para o modelo de linguagem:
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 tem uma API OpenAI totalmente compatível, o que significa que podemos usar o SDK Python da OpenAI para chamar o 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)
De acordo com o texto, os advogados envolvidos neste caso são:
* Andrew Spink KC (instruído por Stephenson Harwood LLP) para o Primeiro Recorrido
* Saul Margo (também instruído por Stephenson Harwood LLP) para o Primeiro Recorrido
* Sr. Tennet (representando o Segundo Recorrido)
* Sr. Spink KC (também representando o Segundo Recorrido)
* Arden LJ (mencionada como tendo proferido uma sentença anterior em Stena Line)
Observe que "KC" significa King's Counsel, que é um título de distinção conferido a certos barristers seniores na Inglaterra e no País de Gales.
Conclusão
Configurar RAG com Milvus e Ollama para dados jurídicos pode tornar a pesquisa jurídica muito mais fácil e eficiente.
Sinta-se à vontade para conferir o Milvus, o código no Github, e compartilhar suas experiências com a comunidade juntando-se ao nosso Discord.
Mais recursos sobre Milvus e Ollama:
Continue lendo

Smarter Autoscaling in Zilliz Cloud: Always Optimized for Every Workload
With the latest upgrade, Zilliz Cloud introduces smarter autoscaling—a fully automated, more streamlined, elastic resource management system.

Demystifying the Milvus Sizing Tool
Explore how to use the Sizing Tool to select the optimal configuration for your Milvus deployment.

Introducing DeepSearcher: A Local Open Source Deep Research
In contrast to OpenAI’s Deep Research, this example ran locally, using only open-source models and tools like Milvus and LangChain.



