始めに
こんにちは、エンジニアの大橋です。
LLMを用いたRAG(Retrieval-Augmented Generation)アプリケーションの開発において、精度向上のための評価方法に悩まれている方も多いのではないでしょうか。
今回、AssuredではRAGアプリケーションの評価にPhoenixというツールを導入してみました。Phoenixを利用することで、LLMに何を入力しどんな出力を得られたのかを可視化し、品質を改善させるサイクルを素早く行えるようになり、RAGアプリケーションの精度向上に非常に有用だったので、その活用方法をご紹介したいと思います。
実はPhoenixを使い始める前に、DeepEvalというLLM評価ライブラリのみを利用して、LLMの生成結果の評価を行おうとした時期がありました。実際に事前評価(オフライン評価)としてユニットテストを実装し、評価を行ってみたのですが、以下のような問題があり、うまく改善のサイクルを回すことができませんでした。
- LLMのQuota制限があるため、エラー率が高くフレーキーテストになってしまう
- LLMのレイテンシが遅すぎるため、テストの実行に時間がかかって何度も実行できない
- スコアが低かったときの分析がしづらく改善作業に繋がりにくい
将来的には本番環境のデータを利用した事後評価(オンライン評価)も見据えていたため、小規模に始められるPhoenixに注目しました。
Phoenixとは
Phoenixは、LLMをはじめとしたAIの評価とトレーシングを行うためのオープンソースの可観測性(オブザーバビリティ)ライブラリです。
Phoenixサーバーをデプロイし、OpenTelemetry protocol(OLTP)に従ったトレーシング用のデータをサーバーに送信することで、RAGアプリケーション内部の動作を可視化し、評価することができます。llama-indexやlangchainなど、主要なLLMフレームワーク向けのライブラリも充実しています。
LangSmithやLangfuseなど、SaaSとして提供されているツールもありますが、このPhoenixは自社の環境にデプロイでき、非同期にデータを送信しアプリのレイテンシに影響を与えにくいため、とりあえずLLM評価の環境を小さく構築したい状況でも、本番環境のオブザーバビリティツールとしても、柔軟に利用しやすい点が魅力です。
PhoenixのUIはデモページで触れることができます。
https://phoenix-demo.arize.com/projects/UHJvamVjdDox
Phoenixを実際に利用してみて良かったこと
LLMのオンライン評価を非同期に回せるようになった
Phoenixでは、評価用のデータを一度永続化し、別のタイミングで評価を行うことが可能です。評価自体もLLMが行うため、Quotaの制限には注意しなければなりませんが、アプリ側でQuotaを消費するタイミングと分けて評価を実行することで、エラーになりづらく、またレイテンシをあまり気にせずに評価結果を取得することができるようになりました。また仮に評価の実行がエラーになったとしても、リトライもやりやすくなりました。
スコアが低い場合の分析がしやすくなった
Phoenixサーバーが提供するUIによって、RAGアプリケーション内部の実行パイプラインを可視化し、何が起こっているのかが非常にわかりやすくなりました。それまでスコアが低い場合にコンテキストの検索に失敗しているのか、プロンプトが悪いのかを類推しながら改善を行う必要がありましたが、生成結果の原因が掴みやすくなりました。
また副次的な効果ですが、チームのメンバーが評価結果を確認しやすくなったことで、どうやって結果を改善するのかの議論もやりやすくなりました。
AssuredでのPhoenixの構成
AssuredではGoogle Cloudを主に利用しており、今回はPhoenixをサーバーレス環境のCloudRunで構成しました。
参考までに、terraformはこのようになりました。
resource "google_cloud_run_v2_service" "phoenix" { name = "assured-phoenix" project = var.project location = var.region ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" template { execution_environment = "EXECUTION_ENVIRONMENT_GEN2" service_account = google_service_account.phoenix.email scaling { min_instance_count = 1 max_instance_count = 1 } volumes { name = "work" gcs { bucket = google_storage_bucket.phoenix.name read_only = false } } containers { name = "app" image = "arizephoenix/phoenix:version-4.24.0" ports { container_port = 6006 } resources { limits = { cpu = "2000m" memory = "4Gi" } } # CORSの設定をしないと画面表示でエラーになります env { name = "PROD_CORS_ORIGIN" value = format("http://%s/", replace(var.public_dns_record_name, "/.$/", "")) } env { name = "PHOENIX_WORKING_DIR" value = "/phoenix/work" } volume_mounts { name = "work" mount_path = "/phoenix/work" } } vpc_access { network_interfaces { network = data.google_compute_network.assured.name subnetwork = data.google_compute_subnetwork.assured.name } egress = "ALL_TRAFFIC" } } } # Phoenix永続化用のStorage # PhoenixではSQLite or PostgreSQLで永続化ができる resource "google_storage_bucket" "phoenix" { name = "assured-phoenix-persistence" project = var.project location = var.region } # LBで社内アクセスのみ許可しているため認証を外している resource "google_cloud_run_service_iam_binding" "phoenix" { project = var.project location = google_cloud_run_v2_service.phoenix.location service = google_cloud_run_v2_service.phoenix.name role = "roles/run.invoker" members = [ "allUsers" ] }
まとめ
LLM評価ツールであるPhoenixを導入することで、RAGアプリケーションの評価サイクルを高速に回すことができるようになりました。
今後、より実際のアプリケーションに近いテストデータや評価指標を用意し、CIのような形で実装を改善していける仕組みなどにもチャレンジしていけたらと思いますし、それによってより精度の高いRAGアプリケーションを開発できたらと思います。機能はまだ開発中ですが、リリースを心待ちにしています。
この記事がLLMを利用した機能を開発している方の参考になれば幸いです。