RAG、Milvus、Ollamaによるリーガル・リサーチの簡素化
このブログでは、リーガル・データにRAGを適用する方法を紹介する。
法務調査は時間がかかるものです。必要な答えを見つけるためには、通常、大量の文書をレビューする必要があります。Retrieval-Augmented Generation (RAG)はリサーチプロセスの効率化に役立ちます。
RAGとは?
Retrieval Augmented Generation(RAG)は、追加のデータソースを統合することによってLLMを強化する技術です。典型的なRAGアプリケーションには以下が含まれる:
インデックス作成** - データソースからデータを取り込み、インデックスを作成するパイプライン。
検索と生成** - 実行時に、RAGはユーザーのクエリを処理し、Milvusに格納されたインデックスから関連データをフェッチし、LLMはこのエンリッチされたコンテキストに基づいてレスポンスを生成する。
このハンズオンガイドでは、Ollamaを使用したRAG(Retrieval Augmented Generation)システムのセットアップ方法を、法律データに焦点を当て、ベクターデータベースとしてMilvusを活用しながらご紹介します。
**ツール
Ollama](https://ollama.com/):LLMのパワーをラップトップにもたらし、ローカル操作を簡素化する。
Milvus](https://github.com/milvus-io/milvus):データを効率的に保存・検索するために使用するベクトルデータベース。
Llama 3](https://llama.meta.com/llama-downloads):Metaの大規模言語モデルの最新版。
Voyage AI](https://www.voyageai.com/) - 特定のドメインに特化した埋め込みモデルを提供。法律や長い文脈の検索に最適化されている。
準備
依存関係とデータ
まず、必要な依存関係をインストールします:
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` インポートをスキップしてください。
データの準備
このチュートリアルでは、ロンドンの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])
これで次のような出力が得られるはずだ:
中立引用番号 [2024] EWCA Civ 767
事件番号 CA-2023 -001978
控訴裁判所(民事部)
高等法院からの控訴
イングランドおよびウェールズのビジネスおよび財産裁判所
企業リスト:年金(ChD)
アダム・ジョンソン裁判官
[2023] EWHC 1965 (Ch)
王立裁判所
ロンドン、ストランド、WC2A 2LL
日付: 2024年7月9日
前
ルウィソン判事
フォーク判事
そして
クリストファー・フロイド判事
ドキュメントを埋め込む
法律領域に特化した埋め込みモデルである voyage-law-2 を使用します。
まず、Voyage AI APIを使って埋め込みテキストを生成する関数を定義します:
インポート 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")
コレクション名 = "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", # 内積距離
consistency_level="Strong", # 強い一貫性レベル
)
フィールド情報を指定しない場合、Milvusは自動的にプライマリキー用のデフォルトidフィールドと、ベクトルデータを格納するためのベクトルフィールドを作成します。予約されたJSONフィールドはスキーマで定義されていないフィールドとその値を格納するために使用されます。
データの挿入
ドキュメントのページを繰り返し、埋め込みを作成し、Milvusにデータを挿入します。
コレクションスキーマの非定義フィールドである text という新しいフィールドを導入する。これは予約されたJSON動的フィールドに自動的に追加され、高レベルでは通常のフィールドとして扱うことができる。
from tqdm import tqdm
data = [] (データ)
for i, page in enumerate(tqdm(pages, desc="埋め込みを作成する")):
data.append({"id": i, "vector": embed_text(page), "text": page})
milvus_client.insert(collection_name=collection_name, data=data)
エンベッディングの作成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 = "弁護士は誰ですか?"
インデックスされたデータを検索するためにMilvusを使う。後で、これをLLMと統合する。
search_res = milvus_client.search(
コレクション名=コレクション名、
data=[
embed_text(question)
], # `embed_text`関数を使って質問を埋め込みベクトルに変換する
limit=3, # 上位3つの結果を返す
search_params={"metric_type":"IP", "params":{}}, # 内積距離
output_fields=["text"], # テキストフィールドを返す
)
検索された行とその距離を表示する:
インポート 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が返すものの例を示します。
[中立引用番号 [2024] EWCA Civ 767 n 事件番号 CA-2023 -001978 nIN THE COURT OF APPEAL ( CIVIL DIVISION) nNON APPEAL FROM THE HIGH COURT OF JUSTICE nBUSINESS AND PROPERTY COURTS OF ENGLAND AND WALES nBUSINESS LIST : n n Michael Tennet KC および Edward Sawyer(Linklaters LLP が代理) n n 控訴人の代理人 n Brian Green KC および Joseph Steadman(Slaughter and May Solicitors が代理) n 第1被控訴人の代理人 n Andrew Spink KC および Saul Margo(Stephenson Harwood LLP が代理) n 第2被控訴人の代理人 n 審問日
0.1101425364613533
],
LLMを使ってRAGレスポンスを取得する
検索された文書をコンテキストに結合し、言語モデルに対するシステムとユーザーのプロンプトを定義する:
コンテキスト = "n".join(
[line_with_distance[0]、line_with_distance in retrieved_lines_with_distances)
)
system_prompt = """
Human: あなたはAIアシスタントです。あなたは提供された文脈に沿った文章の断片から質問の答えを見つけることができます。
"""
USER_PROMPT = f""
<question>タグで囲まれた質問に対する答えを提供するために、<context>タグで囲まれた以下の情報の断片を使ってください。
<context>
{コンテキスト}
</context>
<question>
質問
</question>
"""
Ollamaは完全に互換性のあるOpenAI APIを持っています。つまり、OpenAI Python SDKを使ってOllamaを呼び出すことができます:
from openai import OpenAI
client = OpenAI(
base_url = 'http://localhost:11434/v1'、
api_key='ollama', # 必須だが未使用
)
response = client.chat.completions.create(
model="llama3"、
messages=[
{"role":"system", "content":system_prompt}、
{"role":"user", "content":USER_PROMPT}、
],
)
print(response.choices[0].message.content)
本文によると、この件に関与した弁護士は以下の通り:
* アンドリュー・スピンクKC(Stephenson Harwood LLPの代理人)が一審被告を担当。
* ソール・マーゴ(同じくStephenson Harwood LLPの代理人
* テネット氏(第二被申立人の代理人)
* スピンクKC(同じく二審被告代理人)
* アーデン法務大臣(Stena Line事件で判決を下したことがある。)
KC」はKing's Counselの略であり、イングランドおよびウェールズの特定の上級法廷弁護士に与えられる称号である。
結論
MilvusとOllamaで法律データのRAGをセットアップすることにより、法律調査がより簡単で効率的になる。
Milvus](https://github.com/milvus-io/milvus)やGithubにあるコードを自由にチェックし、私たちのDiscordに参加してコミュニティと経験を共有してください。
MilvusとOllamaに関するその他のリソース:
Kickstart Your Local RAG Setup: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)
読み続けて

Why and How to Migrate from Self-Hosted Milvus to Zilliz Cloud
A simple, step-by-step guide to migrating from Milvus to Zilliz Cloud. Learn both endpoint and backup methods for a smooth, scalable vector database migration.

Zilliz Cloud Update: Tiered Storage, Business Critical Plan, Cross-Region Backup, and Pricing Changes
This release offers a rebuilt tiered storage with lower costs, a new Business Critical plan for enhanced security, and pricing updates, among other features.

What Exactly Are AI Agents? Why OpenAI and LangChain Are Fighting Over Their Definition?
AI agents are software programs powered by AI that can perceive their environment, make decisions, and take actions to achieve a goal—often autonomously.
