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)
계속 읽기

3 Easiest Ways to Use Claude Code on Your Mobile Phone
Run Claude Code from your phone with Remote Control, Happy Coder, or SSH + Tailscale. Comparison table, setup steps, and tools for typing, memory, and parallel tasks.

Zilliz Cloud BYOC Now Available Across AWS, GCP, and Azure
Zilliz Cloud BYOC is now generally available on all three major clouds. Deploy fully managed vector search in your own AWS, GCP, or Azure account — your data never leaves your VPC.

8 Latest RAG Advancements Every Developer Should Know
Explore eight advanced RAG variants that can solve real problems you might be facing: slow retrieval, poor context understanding, multimodal data handling, and resource optimization.



