はじめに
RAGを評価する時に手動でQAサンプルを作成するのは時間と労力がかかり大変ですよね。
しっかりとした評価をしようと思った時に一問一答みたいなQAセットを作るだけではせっかくRAGのチューニングをしても正しく評価できないことがあります。
Ragasのライブラリでは、推論、条件付け、マルチコンテキストといった異なる特性を持つQAセットを自動で作成できるみたいです。
今回はRagasライブラリでDifyのナレッジから自動でテストセットを作成してみようと思います。
最後にはLangfuseに格納していつでも使えるようにしましょう。
ナレッジから合成テストセットを作成する
基本は以下を改造してDifyのナレッジから合成テストセットを作成します。
まずは必要なライブラリをインストールしましょう。
pip install ragas langfuse datasets langchain-openai
次に環境変数を設定してください。
import os
os.environ["LANGFUSE_SECRET_KEY"] = "LANGFUSE_SECRET_KEY"
os.environ["LANGFUSE_PUBLIC_KEY"] = "LANGFUSE_PUBLIC_KEY"
os.environ["LANGFUSE_HOST"] ="LANGFUSE_HOST"
os.environ["OPENAI_API_KEY"] = "OPENAI_API_KEY"
ではDifyからナレッジを取得しましょう。
基本はナレッジに入っているドキュメントを取得する形になります。
データセットIDとドキュメントIDで取得することがきます。
私はローカルのDify使ってるので、ホストがlocalhostですが適宜変更してください。
import requests
dataset_id = "dataset_id"
api_key = "api_key"
document_id = "document_id"
url = f"http://localhost/v1/datasets/{dataset_id}/documents/{document_id}/segments"
headers = {
"Authorization": f"Bearer {api_key}"
}
response = requests.get(url, headers=headers)
取得したナレッジをRagasライブラリが扱えるようにLangchainのDocumentオブジェクトに変換します。
from langchain_core.documents import Document
# レスポンスデータからすべてのセグメントデータを取得
segments_data = response.json()['data']
# すべてのセグメントデータをDocumentオブジェクトに変換
documents = []
for segment_data in segments_data:
document = Document(
page_content=segment_data['content'],
metadata={
"id": segment_data['id'],
"position": segment_data['position'],
"document_id": segment_data['document_id'],
"word_count": segment_data['word_count'],
"tokens": segment_data['tokens'],
"keywords": segment_data['keywords']
}
)
documents.append(document)
そしてRagasライブラリを使用して、合成テストセット作成します。
from ragas.testset.generator import TestsetGenerator
from ragas.testset.evolutions import simple, reasoning, multi_context
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
# generator with openai models
generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
critic_llm = ChatOpenAI(model="gpt-4")
embeddings = OpenAIEmbeddings()
generator = TestsetGenerator.from_langchain(
generator_llm,
critic_llm,
embeddings
)
# generate testset
testset = generator.generate_with_langchain_docs(documents, test_size=10, distributions={simple: 0.5, reasoning: 0.25, multi_context: 0.25})
そうすると以下のように合成テストセットが作成されます。簡単に作れますね。
Langfuseに格納
最後にいつでも使えるようにLangfuseに格納しておきましょう。
空のデータセットを作成してください。
from langfuse import Langfuse
# init
langfuse = Langfuse()
langfuse.create_dataset(name="synthetic_testset");
そして以下のような作成したデータセットを格納しましょう。
import json
for item in testset:
input_data = {
"question": item.question,
"contexts": item.contexts
}
langfuse.create_dataset_item(
dataset_name="synthetic_testset",
input=json.dumps(input_data),
expected_output=item.ground_truth
)
最後に
結構簡単にできるので今後はこれ使おうと思います。
Xをやっているので気になる方はフォローお願いします。