RAG, Milvus, Ollama로 법률 리서치 간소화
이 블로그 게시물에서는 RAG를 법률 데이터에 적용하는 방법을 살펴보겠습니다.
법률 조사는 시간이 많이 걸릴 수 있습니다. 일반적으로 필요한 답을 찾기 위해 많은 수의 문서를 검토해야 합니다. Retrieval-Augmented Generation (RAG)은 조사 프로세스를 간소화하는 데 도움이 될 수 있습니다.
RAG란 무엇인가요?
Retrieval Augmented Generation (RAG)은 추가 데이터 소스를 통합하여 LLM을 향상시키는 기술입니다. 일반적인 RAG 애플리케이션에는 다음이 포함됩니다:
인덱싱 - 소스에서 데이터를 수집하고 인덱싱하기 위한 파이프라인으로, 일반적으로 Milvus에서 데이터를 로드, 분할 및 정렬하는 작업으로 구성됩니다.
검색 및 생성 - 런타임에 RAG는 사용자의 쿼리를 처리하고, Milvus에 저장된 인덱스에서 관련 데이터를 가져오며, LLM은 이 풍부해진 컨텍스트를 기반으로 응답을 생성합니다.
이 실습 가이드에서는 Ollama를 사용하여 Retrieval Augmented Generation (RAG) 시스템을 설정하는 방법을 살펴보며, 법률 데이터에 초점을 맞추고 Milvus를 벡터 데이터베이스로 활용합니다.
도구:
Ollama: LLM의 강력한 기능을 노트북으로 가져와 로컬 실행을 간소화합니다.
Milvus: 데이터를 효율적으로 저장하고 검색하는 데 사용하는 벡터 데이터베이스입니다.
Llama 3: Meta의 대규모 언어 모델 라인업의 최신 버전입니다.
Voyage AI - 특정 도메인에 특화된 임베딩 모델을 제공합니다. 우리는 법률 및 긴 컨텍스트 검색에 최적화된 특화 법률 임베딩을 사용합니다.
준비
종속성 및 데이터
먼저, 필요한 종속성을 설치합니다:
! pip install --upgrade pymilvus ollama tqdm pypdf voyageai openai wget
API 키 가져오기
API 키가 .env 파일에 설정되어 있다면, 노트북을 푸시할 때 키가 유출되는 것을 방지하기 위해 dotenv를 사용하여 로드할 수 있습니다.
import os
from dotenv import load_dotenv
load_dotenv()
VOYAGE_API_KEY = os.getenv('VOYAGE_API_KEY')
.env 파일이 없다면, dotenv import를 건너뛰면 됩니다.
데이터 준비
이 튜토리얼에서는 런던의 Royal Courts of Justice 데이터를 사용합니다. 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 n중립 인용 번호 [2024] EWCA Civ 767 n n사건 번호: CA-2023 -001978 n항소법원 (민사부)에서 n고등법원 판결에 대한 항소 n잉글랜드 및 웨일스 상사·재산 법원 n상사 목록 : 연금 (ChD) nThe Hon Mr Justice Adam Johnson n[2023] EWHC 1965 (Ch) nRoyal Courts of Justice nStrand, London, WC2A 2LL n n날짜: 09/07 /2024 n재판부 : n nLORD JUSTICE LEWISON nLADY JUSTICE FALK n및 nSIR CHRISTOPHER FLOYD n n- - - - - - - - - - - - - - - - - - - - - n n당사자 : n n BRITISH BROADCASTING CORPORATION 항소인 n - 및 - n (1) BBC P ENSION TRUST LIMITED n(2) CHRISTINA BURNS n피항소인들 n n- - - - - - - - - - - - - - - - - - - - - n n Michael Tennet KC 및 Edward Sawyer (Linklaters LLP 의 지시에 따름 ) n항소인을 대리 n Brian Green KC 및 Joseph Steadman (Slaughter and May Solicitors 의 지시에 따름 ) n제1 피항소인을 대리 nAndrew Spink KC 및 Saul Margo (Stephenson Harwood LLP 의 지시에 따름 ) n제2 피항소인을 대리 n n심리일: 25, 26 & 27/06/2024 n- - - - - - - - - - - - - - - - - - - - - n n승인된 판결문 n n이 판결은 2024년 07월 09일 오전 11시에 당사자 또는 그 대리인에게 이메일로 회람하고 National 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)
텍스트에 따르면, 이 사건에 관여한 변호사들은 다음과 같습니다:
* Andrew Spink KC (Stephenson Harwood LLP의 지시에 따름) 제1 피항소인을 대리
* Saul Margo (역시 Stephenson Harwood LLP의 지시에 따름) 제1 피항소인을 대리
* Mr. Tennet (제2 피항소인을 대리)
* Mr. Spink KC (역시 제2 피항소인을 대리)
* Arden LJ (Stena Line에서 이전 판결을 내린 것으로 언급됨)
참고로 "KC"는 King's Counsel을 의미하며, 이는 잉글랜드 및 웨일스의 특정 선임 변호사들에게 수여되는 명예 칭호입니다.
## 결론
법률 데이터에 Milvus와 Ollama를 사용해 RAG를 설정하면 법률 연구를 훨씬 더 쉽고 효율적으로 만들 수 있습니다.
[Milvus](https://github.com/milvus-io/milvus), [Github](https://github.com/stephen37/ollama_local_rag)의 코드도 확인해 보시고, [Discord](https://discord.gg/FG6hMJStWu)에 참여하여 커뮤니티와 경험을 공유해 보세요.
Milvus와 Ollama에 대한 추가 자료:
- [로컬 RAG 설정 시작하기: Ollama, Milvus, LangChain과 함께 Llama 3를 사용하는 초보자 가이드](https://zilliz.com/blog/a-beginners-guide-to-using-llama-3-with-ollama-milvus-langchain)
- [Llama3, Ollama, DSPy 및 Milvus를 사용하여 검색 증강 생성(RAG) 시스템을 구축하는 방법](https://zilliz.com/learn/how-to-build-rag-system-using-llama3-ollama-dspy-milvus)
- [Milvus, Ollama 및 LangGraph로 로컬에서 에이전트형 RAG 구축하기](https://www.youtube.com/watch?v=GMWEdjsgM6A)
계속 읽기

A Developer's Guide to Exploring Milvus 2.6 Features on Zilliz Cloud
Milvus 2.6 marks a shift from “vector search + glue code” to a more advanced retrieval engine, and it is now Generally Available (GA) on Zilliz Cloud (a managed Milvus service).

Introducing Zilliz Cloud Global Cluster: Region-Level Resilience for Mission-Critical AI
Zilliz Cloud Global Cluster delivers multi-region resilience, automatic failover, and fast global AI search with built-in security and compliance.

Vector Databases vs. Graph Databases
Use a vector database for AI-powered similarity search; use a graph database for complex relationship-based queries and network analysis.



