検索結果
空の検索で36件の結果が見つかりました。
- Langfuse / LangSmith 比較レポート
本記事は、LLM(大規模言語モデル)アプリケーション開発プラットフォームであるLangfuse と LangSmith を比較するものです。両プラットフォームは、開発者が LLM を活用したアプリケーションを構築・運用することを支援しますが、その出自、焦点、実装において違いがあります。各セクションで、主要な基準で両者を比較し、対比を行なっていきます。なお内容は 2025年2月26日時点においての公開情報をもとに作成されております。 またセルフホスト版における費用比較は LangSmith 側の Web 上などに公開情報がないため、対象外となっています。 ------ TL;DR (2025年04月25日 修正) 多くの相違点と類似点がありますが、最終的に論点は以下に点に収束します。 ぜひ皆様のユースケースに照らし合わせてご確認ください。 OSS が持つガバナンスや今後のロードマップなどの透明性 (Langfuse) or 従来型のProprietary (LangSmith) という観点からの Pros/Cons の検討 自分の環境内に立てたいか (セキュリティポリシー的の観点) or SaaS 厳密なコスト計算シナリオ (ただし SaaS の場合は大きく変わらない) LangChain との緊密なインテグレーションをどの程度重要視するか ------ 1. 基本概要 (Basic Overview) Langfuse: 開発元: Langfuse GmbH (Finto Technologies) 概要: オープンソースのLLMアプリケーションエンジニアリングプラットフォーム。 主な目的: チームがLLMアプリケーションを「共同でデバッグ、分析、反復」することを支援すること。開発ワークフローを加速するために、すべての機能が統合されています。 特徴: 特定のフレームワークに依存しない。 本番環境での利用を想定して構築。 オープンソースであるため、高い柔軟性とカスタマイズ性を持つ。 LangSmith: 開発元: LangChainチーム 概要: プロプライエタリ(閉鎖的)なエンドツーエンドのプラットフォーム。 主な目的: LLMアプリケーションのライフサイクルのあらゆる段階に対応する、オールインワンの開発者プラットフォームを提供すること。 特徴: 特にLangChainユーザーを対象としているが、あらゆるLLMアプリケーションで利用可能。 綿密な監視と評価に重点を置き、開発者が信頼性の高いアプリケーションを迅速に提供できるよう支援。 SaaS (Software as a Service) として提供される (エンタープライズ向けのセルフホストオプションあり)。 LangChainエコシステムと緊密に統合されている。 要約: Langfuse (Langfuse GmbH) はオープンソースでフレームワーク非依存。LangSmith (LangChain) はLangChainユーザー向けに設計されたプロプライエタリなエンドツーエンドプラットフォームですが、あらゆるLLMアプリケーションで利用可能です。どちらも、LLMアプリケーションの開発/監視/運用の効率化を目指しています。 2. 主要機能 (Main Features) 両プラットフォームは、トレース、デバッグ、プロンプト管理、評価、フィードバック収集など、豊富な機能セットを提供します。以下の表では、主要な機能を比較し、実装や重点の違いを強調します。 機能 Langfuse LangSmith トレース & デバッグ LLM可観測性: 完全な実行トレース (LLM呼び出し、ツール呼び出しなど) を完全なコンテキストとともにキャプチャ。ネストされたチェーン、並列呼び出し、マルチモーダルデータをサポート。複数ターンの会話のためのセッションビューと、レイテンシをデバッグするためのタイムラインビューを提供。開発者は、LangfuseのSDKまたは統合を介してコードを計測し、各ステップをログに記録。 可観測性 & トレース: LangChain/LangGraphアプリ用の組み込みトレース (自動計測) と、あらゆるアプリ用のAPI/SDKを提供。カスタムダッシュボードとアラートでトレースを分析可能。呼び出しシーケンスを完全に可視化し、エラーやボトルネックをリアルタイムで特定。トレースをリンクで共有して共同作業を可能にし、2つのトレース実行を並べて比較することも可能 (回帰デバッグ用)。 プロンプト管理 中央集約型プロンプト管理: プロンプトを共同で作成、編集、バージョン管理するためのコンソールを提供。プロンプトはコードから分離されており、新しいバージョンはアプリを再デプロイすることなくデプロイ可能。複数形式のプロンプト (テキストまたはチャット) をサポートし、バージョン管理とロールバック機能を備える。非開発者はUIを介してプロンプトを更新可能 (役割ベースのアクセス)。プロンプトの変更は経時的に追跡され、トレースにリンクされて影響を確認可能。また、 Playground を提供し、プロンプトを単独で即座にテスト可能。 LangSmith Hub (プロンプトエンジニアリング): プロンプトを作成し、自動バージョン管理で反復するためのWeb UI。ユーザー (非エンジニアを含む) は、プロンプトテンプレートを作成し、入力変数を設定し、コメントや共同作業が可能。すべてのプロンプト編集は追跡され、ロールバックと比較が可能。統合された Prompt Playground により、デプロイ前にモデル (カスタムまたはOpenAI互換エンドポイントを含む) に対してプロンプトをテスト可能。LangSmithのプロンプトハブはチームの共同作業に重点を置いており、プロンプトはチームメンバー間で簡単に議論および共有可能。 評価 (自動化) LLM-as-a-Judge: 出力に対するLLMによる自動評価をサポート。Langfuseは、トレース (本番環境またはテストシナリオ) に対して「Evaluator」を実行し、スコアを生成可能。開発者は評価基準 (例: 正確性、関連性あるいは独自に基準) を定義し、モデルを使用して応答をスコアリング可能。これらのスコア (数値、ブール値、カテゴリ) は、トレースまたは特定のステップに付加。Langfuseは、カスタム評価指標をログに記録するためのAPI/SDKも提供。 AI支援評価: LangSmithは、関連性、正確性、有害性など、一般的な基準に対するカスタム評価器と 既製の評価器 の両方を提供。ユーザーは、LLMと提供されたプロンプトを使用して出力を自動的にスコアリングするか、事前に構築された評価モジュールを使用可能。LangSmithは 回帰テスト と オンライン評価 を重視しており、ライブ実行を継続的に評価し、品質の低下を検出可能。評価結果は各実行のメトリックとして保存され、品質がしきい値を下回った場合にアラートをトリガー可能。 フィードバック & アノテーション ユーザーフィードバック: Langfuseは、出力に関するエンドユーザーのフィードバックを収集し、トレースに付加することを可能にする。たとえば、ユーザーからのGood/Badなどを、Browser SDKまたはAPIを介して取り込むことが可能。すべてのフィードバックはトレースデータに付加されなり、低品質の結果を特定するために使用可能。 手動アノテーション: Langfuseには、内部レビュー担当者が出力にラベルを付けたり、手動でスコアリングしたりするための アノテーションキュー システムが含まれる。これは、トレースのサンプルに対してグラウンドトゥルースラベルを作成するのに役立つ。プラットフォームは、人間のアノテーターのワークフローをサポートし、自動スコアとともにその判断を追跡。 人間のフィードバック統合: LangSmithは、任意の実行に対して 「人間のフィードバックを重ね合わせる」 ことを可能にする。チームは、LangSmithアプリで アノテーションキュー を設定し、人間にモデル出力をレビューおよびラベル付けさせることが可能。これは、体系的な評価やファインチューニングデータの収集に役立つ。エンドユーザーのフィードバックもキャプチャ可能 (たとえば、アプリケーションがユーザーに応答を評価するように求める場合)。すべてのフィードバックはトレースとともにログに記録され、ダッシュボードで使用したり、メトリックを計算したりするために使用可能。LangSmithのUIはアノテーション用に統合されており、割り当てられたレビュー担当者はプラットフォーム内で直接ラベル付け可能。 データセット & テスト データセット & 実験: Langfuseでは、実際の例 (特に失敗例や重要なクエリ) からデータセットを構築可能。これらのデータセットは、テストスイートまたはベンチマークとして機能。これらのデータセットに対して プロンプト実験 またはチェーン実験を実行可能。たとえば、同じ入力セットに対して異なるプロンプトバージョンまたはモデル設定を並べて比較。プラットフォームは、各実験のメトリック (精度、コスト、レイテンシ、またはカスタムスコア) を表示し、最適化をガイド。これは、 デプロイ前のテスト (新しいバージョンを出荷する前の回帰テスト) と、本番環境の外れ値を定期的にテストセットに追加することによる 継続的な改善 をサポート。 データセット & 評価スイート: LangSmithは、デバッグ実行またはアップロードされたデータから データセットを構築 するためのツールを提供。これらのデータセットは、体系的なテストのために、入力と期待される出力 (または参照出力) をグループ化。LLMベースの評価器またはカスタムテスト関数のいずれかを使用して、データセットに対して バッチ評価 を実行可能。プラットフォームは 回帰テスト をサポートしており、同じデータセットでアプリケーションのパフォーマンスをバージョン間で比較。たとえば、プロンプトまたはモデルを更新した後、保存したデータセットを再実行し、評価スコアが向上したか低下したかを確認可能。これにより、各反復で品質が確実に向上。 監視 & メトリクス ダッシュボード: Langfuseには、品質スコア、レイテンシ、LLM呼び出しのコストなどの主要なメトリックを監視するための組み込みダッシュボードが含まれる。トレースがストリーミングされると、これらの集計メトリックを経時的に追跡可能 (例: 平均応答時間、成功率、ユーザーフィードバックのスコア)。Langfuseはこれらの洞察をアプリ内で提供することに重点を置いているが、ドキュメントにはカスタムアラートルールについては明示的に言及されていない。(必要に応じて、APIを介してデータをエクスポートし、外部監視を行うことは可能。) コスト追跡は、ユーザーごとまたは全体的なAPI使用料を監視するためにサポート。タグ、ユーザーID、またはバージョンによるトレースの詳細なフィルタリングがUIでサポートされており、特定のシナリオを掘り下げることが可能。 ダッシュボード & アラート: LangSmithは監視に重点を置いている。ユーザーは、1秒あたりのリクエスト数、エラー率、レイテンシ、コストなどのメトリックを経時的に表示するためのカスタム ダッシュボード を作成可能。プラットフォームでは、 アラート/自動化ルール を設定可能。たとえば、メトリックがしきい値を超えた場合や、評価スコアが低下した場合に通知。LangSmithは オンライン評価監視 もサポートしており、ライブトラフィック (AIまたはメトリックを使用) を継続的に評価し、リアルタイムで問題をフラグ付け可能。組み込みのフィルタリングと検索は、トレースデータを (モデル、時間枠、タグなどによって) 分割するのに役立ち、インターフェースは調査のために異常 (エラーまたはレイテンシのスパイク) を強調表示。 共同作業 チームコラボレーション: オープンソースツールであるLangfuseは、セルフホストして複数のチームメンバーで使用可能。組織向けの役割ベースのアクセス制御 (RBAC) をサポート (上位プランで利用可能)。それぞれのOrganizationやプロジェクトといった単位を活用しながら、1つのインスタンスで管理できる。コラボレーションは主に、Langfuseダッシュボード、プロンプト、トレース、データセットなどへのの共有アクセスを通じて行われる。 共有 & コラボレーション: LangSmithはチームワークを念頭に置いて構築。複数のユーザーと組織に対してきめ細かい権限 (Plus/Enterpriseプラン) を提供。特に、 トレース共有 は機能の1つであり、開発者はトレースへの公開共有可能なリンクを生成し、同僚や利害関係者に送信可能。このリンクを使用すると、他のユーザーは透明性のために実行チェーン全体を表示可能。 LangSmith Hub は、プロンプト設計におけるコラボレーションも可能にし、チームメンバーはプロンプトにコメントでき、非技術的な専門家は直接貢献可能。要約すると、LangSmithはすぐに使えるより多くのアプリ内コラボレーションツール (コメント、共有リンク) を提供する一方、Langfuseは複数ユーザーアクセスと外部ディスカッション (またはサードパーティ統合) に依存してコラボレーションを行う。 機能における主な違い: 両プラットフォームは、エンドツーエンドのLLM開発サイクル (プロンプト設計から監視まで) をカバーしています。Langfuseはオープンソースであるため、セルフホスト環境での柔軟性と統合を重視しており、 可観測性 と 評価パイプライン を中心に強力なコアを備えています。LangSmithはマネージドサービスとして、LangChainとの容易な統合、既製の評価器、カスタムダッシュボード/アラート、組み込みのコラボレーション (共有とコメント) などの ユーザーエクスペリエンス 機能に特に重点を置いています。LangChainを頻繁に使用する場合 (計測のオーバーヘッドがない) はLangSmithが優位に立つ可能性があり、一方、Langfuseはフレームワーク非依存のカスタマイズ可能なソリューションが必要な場合や、セルフホストのオープンソースを好む場合に優れています。 3. 統合性 (Integration) LangfuseとLangSmithはどちらも、さまざまなツール、ライブラリ、APIと統合して使いやすさを向上させています。以下に、統合機能の比較を示します。 言語SDK & API: 両者とも、複数の言語の公式SDKを備えたAPIファーストのアプローチを提供。 Langfuse: Python と TypeScript/JavaScript SDK 、および適切に文書化されたREST APIを提供。 LangSmith: 同様に Python と JS/TS SDK 、およびトレースをログに記録するためのREST APIを提供。 つまり、どちらのプラットフォームも、APIを呼び出すかSDKメソッドを使用することで、あらゆる環境 (バックエンド、フロントエンドなど) で使用できます。両者とも開発者に優しく、カスタムワークフローやLangChain以外のアプリケーションに統合できます。 フレームワーク & ツール統合: Langfuse: フレームワーク非依存 の設計。 幅広いコミュニティ統合を持つ。 LangChain, LlamaIndex, Haystack, OpenAI SDK, Vercel AI SDK, LiteLLM, Langflow, Flowiseなど、一般的なLLMフレームワークやツールをすぐにサポート。 これらの統合は、多くの場合、Langfuseにデータを自動的に送信する計測モジュールまたはコールバックとして提供される。 例: Langfuseには、チェーンをログに記録するためのLangChainコールバック統合があり、エンタープライズトレースシステムと統合するためのOpenTelemetryサポートさえある。 LangSmith: LangChainエコシステムと深く統合 。 LangChain (または新しいLangGraphフレームワーク) を使用している場合、LangSmithは追加のコードをほとんど必要としない。環境変数とコールバックハンドラを設定するだけでトレースを有効にできる。 OpenTelemetry計測、Vercel AI SDK、カスタムLLM APIなど、他のシナリオとの統合に関するガイドも提供。 LangSmithは、LangChain以外のネイティブ統合はLangfuseよりも少ないが、SDKを介して任意のカスタムワークフローをサポート。 LangChainチームは、SDKまたはAPIを介してトレースをログに記録することで、「LangChainを使用しているかどうかに関係なく」LangSmithを使用できることを明示的に示している。 プラットフォーム/リージョンサポート: Langfuse: セルフホスト可能であるため、任意のクラウドまたはオンプレミス環境にデプロイでき、インフラストラクチャ (データベース、監視ツール) への統合は非常に柔軟。 Langfuse Cloud (ホスト型サービス) は現在、コンプライアンスのために米国またはEUリージョンでのデータホスティングを提供。 LangSmith: 主にホスト型SaaS (LangChain Inc.がホスト) であり、サービスを使用する際にリージョンオプション (米国またはEU) を提供。 データレジデンシー要件がある企業向けに、LangSmithは エンタープライズセルフホスト オプションを提供 (下記の「デプロイメント」を参照)。 両プラットフォームともAPIを介してデータを公開しているため、必要に応じて、その出力 (トレース、メトリック) を他の分析ツールまたはBIツールと統合可能。 要約: Langfuse は幅広い統合フックを提供し、特定のライブラリに縛られないため、多様な技術スタックに適しています (複数のLLMOpsツールの統合もリストされています)。LangSmith はLangChainとシームレスに統合されており、LangChainユーザーには非常に摩擦の少ないセットアップを提供し、他のユーザーにはSDKを介した汎用的な統合もサポートします。実際には、すでにLangChainを使用している場合はLangSmithの方が簡単に組み込める可能性がありますが、LangfuseもLangChainはサポートしており簡単なインテグレーションが可能です。どちらもPython/JS SDKとREST APIを備えており、事実上すべてのプラットフォームまたは言語との統合が可能です。 4. デプロイメント (Deployment Options) このセクションでは、クラウドとセルフホストオプションを含め、各プラットフォームをデプロイまたは使用する方法を比較します。 ホスト型クラウドサービス: 両方ともクラウドホスト型サービスを提供。 Langfuse Cloud: Langfuseチームによるフルマネージドサービス。サインアップすると、ダッシュボードとバックエンドがホストされる。インフラストラクチャを保守したくない場合に最適。 LangSmith: 本質的にマネージドクラウドプラットフォーム (smith.langchain.com経由でアクセス可能)。ほとんどのユーザーにとって、LangSmith はクラウドサービスとして使用することになる。 セルフホスティング: 大きな違いはセルフホスティング。 Langfuse: オープンソースであるため、 誰でも簡単にセルフホスト可能 。 すべてのコアLangfuse機能はMITライセンスの下で利用可能。つまり、独自のサーバーまたはクラウドアカウントでプラットフォームを無料で実行でき、使用制限はない。 Langfuse社が Docker, Kubernetes, またはVMを介してインフラストラクチャにデプロイするためのガイドや公式のHelm, Terraform などをおおお提供。 個人情報保護や自社セキュリティ基準などの理由から、オンプレミスソリューションが必要なチームや、データを完全に制御したいチームに最適。 LangSmith: 一般公開のセルフホスティングは提供していない (クローズドソースプラットフォーム)。 ただし、 エンタープライズ顧客 は、Enterpriseプランの一部としてLangSmithのセルフホスト/オンプレミスデプロイメントを取得可能。 このシナリオでは、LangChainチームは、Kubernetesクラスターで実行できるコンテナ化されたバージョンのLangSmithを提供し、データが環境内に留まることを保証。 このオプションは、(通常、厳格なデータ要件を持つ大企業向けの) 商用契約でのみ利用可能。 クラウド vs オンプレミス: Langfuseのオープンソース版はクラウド版と同じコアソフトウェアであるため、セルフホストユーザーは 完全な機能セット を利用できる (さらに開発も可能)。 Langfuseのセルフホスティングには機能的な損失はなく、実際、Langfuseは 「セルフホスティング時にはすべてのコア機能が無制限で利用可能」 と述べている。 LangSmithのセルフホスト (エンタープライズ) は、おそらくクラウドバージョンと同等の機能を備えている (環境にデプロイされるだけ) が、これは無料または小規模チーム向けではない。 LangSmithはクラウドに頻繁に更新をプッシュする可能性があることに注意。エンタープライズデプロイメントは、手配された更新を介してそれらを受け取る。 要約: Langfuseはデプロイメントにおいて最大限の柔軟性を提供します。クラウドを使用することも、(自分のクラウドまたはオンプレミスに) 自分でデプロイすることもでき、エアギャップ環境でも、コア機能のライセンス料はかかりません。LangSmithは主にクラウドサービスです。オンプレミスが必要な場合は、エンタープライズ契約を介してのみ可能です。オープンソースまたは自己管理ソリューションを優先する組織はLangfuseに傾く可能性があり、ターンキーSaaSを好み (サードパーティがデータをホストしても構わない) 組織はLangSmith も選択肢になりえます。 5. 価格 (Pricing Plans) Langfuse とLangSmith は異なる価格モデルを持っています。以下にクラウド版の費用の要約します。どちらも始めるための無料枠がありますが、Langfuse の無料枠はイベントによって使用量が制限され、LangSmith の無料枠はユーザーとトレースによって制限されます。そして有料プランでは、より高いクォータとサポートが導入されます。 プラン Langfuse (Langfuse Cloud) LangSmith (LangChain) 無料枠 Hobby Plan – 無料 . 特定の制限付きですべてのコア機能が含まれる。例: 月間最大 5万 イベント、30日間のデータ保持、最大2ユーザー。クレジットカードは不要。コミュニティサポート (Discord & GitHub経由) のみ。プロトタイプや趣味のプロジェクトに最適。 Developer Plan – 無料 . シングル開発者向け。 1ユーザー と月間最大 5,000 トレースを許可。5,000トレースを超えると、従量課金制 (追加の1,000トレースあたり0.50ドル)。すべての機能 (トレース、評価、プロンプト管理など) が含まれる。この無料枠は機能的には寛大だが、ボリュームとシート数に制限がある。 ミドルレベル Pro Plan – $59/月 . 中程度のボリュームでの本番環境での使用に適している。Hobbyのすべてに加え、より高い制限が含まれる: 月間 10万 観測 (その後、追加の10万件あたり10ドル)、無制限のデータ保持、 無制限のユーザー と評価器。サポートはメール/チャット経由。 Team Plan – $499/月 . 大規模なチーム向けで、Proのすべてに加え、高度なセキュリティ機能が含まれる: シングルサインオン (SSO) 統合、きめ細かいRBAC、コンプライアンス (SOC2、ISO27001)。プライベートSlackチャネルを介した優先サポートも含まれる。ProとTeamはどちらも大規模な商用利用を許可し、Teamはエンタープライズのようなコントロールを追加する。 Plus Plan – $39/ユーザー/月 . 小規模チーム向け。Developerのすべての機能をより高いクォータで含む: 月間 1万 トレース (プール)、最大10ユーザーシート。1万トレースを超える追加トレースは、1,000件あたり0.50ドル。このプランではチームコラボレーション (複数シート) が導入され、LangChainチームからの メールサポート が付属。レート制限は無料枠よりも高い。価格はユーザー数に応じてスケーリング (ユーザーごとの価格設定)。 エンタープライズ Enterprise Plan – カスタム価格 . Teamのすべてに加え、エンタープライズグレードのサポートとカスタム条件が含まれる。特に、Enterpriseは稼働時間SLA、サポートSLA、専任サポートエンジニア、アーキテクチャレビューさえ提供。価格は交渉による (AWS Marketplace経由の請求などのオプションを提供)。 セルフホスティングコスト: Langfuseのコアソフトウェアはセルフホストが無料 (ライセンス料なし)。企業は無料でセルフホストし、必要に応じてエンタープライズサポートプランの料金のみを支払うことを選択できる。Langfuseは追加のサービスまたはサポートのためにセルフホストのPro/Enterpriseライセンスを提供しているが、すべての機能はセルフマネージドモードで無料で使用可能。 Enterprise Plan – カスタム価格 . 大企業が必要とする組織全体の機能を追加。この階層にはPlusのすべてが含まれ、 SSO統合 (Oktaなど) 、エンタープライズレベルのSLAコミットメント、そして重要なことに セルフホストデプロイメント のオプションが追加される。エンタープライズ顧客は、データプライバシーのために独自のクラウド/KubernetesでプライベートLangSmithインスタンスを取得可能。価格は相談による。LangChainには特別な Startupsプログラム (初期段階のスタートアップ向けの割引価格) もあり、採用を促進している。これは階層そのものではなく、割引プログラムである。 クラウド版のコストに関する考慮事項: Langfuse の価格はイベントベースで月額固定であり、使用量が含まれるクォータ (例: 10万イベントで月額59ドル) に収まる場合は、より予測しやすい可能性があります。 一方でLangSmithの価格はシートごとおよび使用量ベースであり、無料の割り当てを超えたトレースに対して課金されます。チームメンバーが多い場合やトレース量が多い場合は、コストが高くなる可能性がありますが、単独の開発者にとっては低コストのエントリが可能です。どちらもプラットフォームを試用するための無料枠があります。Langfuseの無料枠は、LangSmithの無料枠 (5,000トレース) よりもはるかに高いボリューム (5万イベント) を許可し、LangSmithの1ユーザーに対して2ユーザーを許可します。これは、即時のコストなしで小規模なコラボレーションを行う場合に有益です。ただし、LangSmithの無料枠には使用量ベースのオーバーフローが含まれています (5,000で打ち切られるのではなく、追加料金を支払うことができます)。一方、LangfuseのHobby枠は、常に5万件のイベントを超える場合はアップグレードが必要になります。要約すると、 Langfuse は従来の階層型サブスクリプションモデル (明確な制限とアップグレードパス付き) を提供し、 LangSmith はハイブリッドモデル (従量課金制の無料枠、その後チーム向けのユーザーごとのサブスクリプション) を使用します。エンタープライズニーズを持つ大規模組織は、カスタム価格設定のために両方を利用できます。Langfuseはライセンス料なしでセルフホストするオプションを提供し、インフラストラクチャが問題にならない場合はコストを削減できる可能性があります。 6. サポートとコミュニティ (Support & Community) ドキュメント: 両プラットフォームとも十分に文書化されている。 Langfuse: ウェブサイトで包括的なドキュメント (ガイド、リファレンス、インタラクティブなデモ、ビデオウォークスルーなど) を提供。ドキュメントは複数の言語 (英語、日本語、韓国語、中国語) で利用可能であり、グローバルなコミュニティを反映。また日本語でのBlogやコミュニティのアウトプットなども数多く確認されている。 LangSmith: ドキュメントは、より広範なLangChainドキュメントサイトの一部。クイックスタート、ハウツーガイド、各SDKのAPIリファレンス、概念ガイドが含まれる。主に英語だが、LangChainのコミュニティはブログなどで非公式にコンテンツを翻訳している。公式のLangSmithドキュメントは英語のみ。 どちらのドキュメントも、統合手順、機能の使用法、ベストプラクティスを徹底的にカバー。LangSmithは新しい (2023年半ばに「LangChain Plus」として開始) ため、そのドキュメントは製品とともに急速に進化しており、一方もLangfuseの公式ドキュメントはAIによる性能も非常に高いと評価できる。 コミュニティとオープンソース: Langfuse: オープンソースであるため、GitHub (コアリポジトリはGitHubにある) に活発なユーザーと貢献者のコミュニティがある。問題や機能リクエストはそこで直接開くことができる。チームは、サポートとQ&AのためにDiscordコミュニティを介して関与。このオープンモデルは、より迅速なコミュニティ主導の改善と透明性を意味する。 LangSmith: それ自体はオープンソースではない (コードは公開されていない) が、LangChainの巨大なオープンソースコミュニティの恩恵を受けている。多くのLangChainユーザーは、LangChainのDiscordまたはフォーラムでLangSmithについて議論しており、LangChainのGitHubの問題はLangSmithの統合トピックをカバーする場合がある。さらに、(ブログ投稿やdev.toの記事で見られるように) サードパーティの比較やツールは、LangSmithがオープンな代替手段とどのように比較されるかについて、コミュニティ全体で関心が高まっていることを示している。 サポートチャネル: Langfuse: 階層型サポートを提供。 Hobbyユーザー: コミュニティサポート (Discord、GitHubディスカッション)。 有料プラン: Langfuseチームからの直接サポート (Proユーザーはメールまたはチャット、TeamユーザーはプライベートSlackチャネル、Enterpriseは専任サポートエンジニアとSLA)。 これにより、ミッションクリティカルなデプロイメントはタイムリーな支援を受けることができる。 また日本においてはガオ株式会社 (GAO,Inc) が日本語サポートと円建て請求書払いなどにも対応。 LangSmith: 無料のDeveloper階層: 直接サポートは含まれない (コミュニティチャネルを除く)。 Plusプラン: LangChainチームからの メールサポート が付属。 Enterprise顧客: 専用のサポート担当者、SLA、およびアカウントマネージャーがいる可能性が高い。(個別に要確認) さらに、LangChainはイベント (「Interrupt」カンファレンスなど) を主催し、教育コンテンツ (ブログ、LLMアプリケーションのテストに関する電子書籍) を共有しており、これらはLangSmithユーザーの間接的なサポートおよび学習リソースとして機能。 コミュニティの感情と採用: どちらのツールも、LLMアプリケーションの可観測性のための主要なソリューション。 Langfuse: 独立したオープンプロジェクトとして、「最も使用されているオープンソースLLMOpsプラットフォーム」を自称し、特にセルフホストツールを好むユーザーの間で急速にユーザーベースを拡大。 LangSmith: LangChainの人気に支えられ、すぐに大規模なユーザーベースを獲得 (LangChainのサイトではLangSmithに「25万人以上がサインアップ」と記載)。 要約: Langfuseは、開発者への直接チャネルを備えた強力なオープンソースコミュニティの雰囲気を提供します (CEOやCTOでさえDiscordで頻繁に関与しています)。そのドキュメントと国際化サポートは、世界中で親しみやすいものにしています。加えて、Langfuseは製品ロードマップを公開しており、ユーザーから度々要求を受けつけている点などにも特徴があります。 Langfuse は直近のリリース や 今後のロードマップをオープンに公開している LangSmithはLangChainの名声の恩恵を受けています。LangChainのユーザーは、おそらくどこで助けを求めればよいかを知っており、LangChainチームのリソース (ブログ、ガイド) はサポートエクスペリエンスを向上させます。 コミュニティ主導の開発と透明性を重視するユーザーにとって、Langfuseのモデルは魅力的です。マネージドソリューションとベンダーからの専門的なサポートを希望し、すでにLangChainエコシステムにいるユーザーにとって、LangSmithもまた同様に選択肢になりうるでしょう。 結論 LangfuseとLangSmithはどちらも、LLMアプリケーションのトレース、デバッグ、プロンプトの反復、および評価のための堅牢なソリューションを提供しますが、異なる哲学を持っています。 Langfuse: オープンソースでセルフホストを念頭に置いているプラットフォーム であり、モデル/フレームワークに依存しない。 データ制御が最優先される環境や、カスタマイズが必要な環境で優れている。 その機能セット (トレース、プロンプト管理、評価、データセット、プレイグラウンド) は、柔軟性に重点を置いてライフサイクル全体をカバー。 チームは1つの機能 (例: トレースのみ) から始めて、徐々により多くを採用できる。 コストモデルはわかりやすく、無料枠のユーザーに対するコミュニティサポートも強力。 また日本においてはコミュニティの規模も成長しており、エンタープライズ向けにガオ株式会社 (GAO,Inc) が日本語サポートと円建て請求書払いなどにも対応。 LangSmith: プロプライエタリなマネージドプラットフォーム (オプションでエンタープライズ向けのオンプレミス) であり、特にLangChainユーザーにとって、利便性と緊密な統合を提供する。 最小限のセットアップ、豊富な監視およびコラボレーションツール、組み込みの評価フレームワークを備えたエンドツーエンドの開発者エクスペリエンスを提供。 LangChainスタックをすでに使用しているチームにとっては、すべてのLLMOpsニーズに対応する1つのまとまったインターフェースを提供することで、開発を加速する可能性がある。 価格は使用量とシートベースであり、チームの規模に応じてスケーリングできる。 どちらかを選択する際は、セルフホスト (自社クラウド環境やオンプレミスへの設置) の必要性、オープン性 vs 利便性、コスト構造、LangChainへの依存度などの要素を考慮してください。たとえば、LangChainで迅速にプロトタイプを作成するスタートアップは、LangSmithのプラグアンドプレイの性質と既製の評価ツールから価値を得る可能性があります。顧客データなどを自社内に置く必要がある企業や、オープンソースを好む企業は、Langfuseが良いオプションになるでしょう LangfuseとLangSmithはどちらも同じ主要な 機能領域 (トレース、プロンプトのバージョン管理、評価、監視、フィードバック収集) をカバーしていますが、 提供方法 (オープン vs クローズド) と一部の 機能のニュアンス (例: LangSmithのカスタムダッシュボード/アラートと組み込みの評価モジュール vs Langfuseのより優れた統合拡張性とセルフホストの自由) が異なります。どちらを選択しても、本番環境でのLLMアプリケーションの動作に対する非常に必要な可視性と制御を得ることができますので、社内ポリシーなどに応じて適切なツールを選択することが肝要です。
- Langfuse 入門 、そしてなぜ Langfuseが支持をされているのか
1. はじめに: Langfuseとは何か? 生成AIアプリケーションを本番投入したものの、 「何が悪いか分からないが生成AIアプリが思ったように動かない」「ちょっとプロンプトを変えるだけで、アプリ自体をもう一度リリース」「プロンプトやモデルを変えたら精度は上がような気がするが、どれくらい良くなったのかなどは感覚でしかない」「エージェントが暴走して 無限にAPIを叩き続けているが原因が分からない」「どのユーザーセッションで不具合が起きたか追えない」「そもそも役に立ってるのかも分からない」 ・・・・ このような悩みはありませんでしょうか? こうした 開発・運用・改善の断絶 は、プロダクトマネージャー, SRE, 生成AIの企画担当者 まで誰もが抱える悩みです。Langfuse はそれらの悩みを “Trace” という一本のバックボーン に集約し、以下のような役割の課題を解決します。 開発者 … 処理の可視化、プロンプト管理、リリース前テストで開発工程を短縮 運用担当 … コスト, レイテンシ, 品質をモニタリングで異常を発見し、原因を特定 生成AI企画・業務担当者 … ROI や品質を判断して、改善に繋げる Langfuse は OSS をベースにして Self-hostedと SaaS という2種類の提供オプションを持ち、ロードマップは常に公開・更新されており透明性があり、OSS コアモデルがゆえに国内外で活発なコミュニティが形成されている、非常にユニークな「LLM エンジニアリング プラットフォーム」です。 2. Langfuseが提供する主な機能 以下の表は、Langfuseが提供する主な機能をまとめたものです。 これらの機能が非常にわかりやすい GUI や API で提供されています。 機能 目的 代表ユースケース Tracing レイテンシ・エラー・再試行・トークン・コストをまとめて記録 ボトルネック解析/コスト急騰の問題解決 Prompt Management バージョン管理・ラベル付け・保護 破壊的変更の防止、チーム共有、プロンプト変更とリリースの高速化 Evaluations ユーザーフィードバック+LLM as a Judge +人手評価 生成AIの効果測定/A/B テスト Datasets 良質 Q&A を蓄積し学習ループを構築 継続学習・RAG 強化 Dashboards & Playground/Experiments KPI 分析+GUI テスト+並列実験 仮説検証を高速化し部門間共有 この画像は実際のTracing 画面のキャプチャです。画像左側のバーに実際の処理の流れとコンポーネントが表示されており、クリックするとその中身が右側に詳細が表示されます。 Trace画面の例: 非常に見やすく、可視化や分析にすぐに役立つ 3. “Trace” を中心に循環するオペレーティングモデル 最近では、生成AIアプリケーション市場の高まりに合わせて、Proprietary から OSS まで、さまざまな可視化ソリューションが登場してきました。しかしながら、単なる可視化ソリューションの導入は前述のような課題の一部のみを解決するものであり、LLMの品質を上げるためには可視化された情報を活用することこそが重要です。Langfuse はその点において、ひとつのプラットフォームとして、必要とされる一連の流れをカバーできるということに大きな強みがあります。参考までに、どのように Langfuse の各機能が Trace に紐づいているかをまとめたものが以下の表です。 サイクル 役割 キーとなる Trace の利用法 Prompt Management プロンプトを一元管理し、Trace の入力/出力とプロンプトもリンク 使用されているプロンプトが、品質・コストへ与える影響をTraceごとに確認 Evaluations Trace ごとにユーザ評価/ 自動評価 / 人的評価を与える 評価をTraceに紐づけることで、問題の特定 Datasets テスト用などのデータを管理 Trace から直接データセットを作りし、問題があった Trace などをプロンプトやモデルの変更などで試験することで、改善サイクルを回すことができる Dashboards コスト、評価、利用状況などを一元管理 Trace から KPI を判断 このようにTrace さえ送れば 管理→評価→最適化 が芋づる式に回り、GenAIOps/LLMOps の“理想形”を最短で実装できることが、LLMエンジニアリングプラットフォームとされている所以とも言えるでしょう。 例えば以下の画像は前出のTrace画像の一部ですが、トークンやコストだけではなく、この処理で使われたモデル名 "gpt-4o-mini " や プロンプト名 "qa-answer-withcontext-chat -v47" が紐づいていることが確認できます。またこのTraceを直接 dataset に入れることができる "Add to datasets" や 人的評価 (Human Annotation) をする "Annotate" もTraceから実施できることがわかります。 このように Langfuse は個々の機能を単に提供しているだけではなく、それらが Trace を軸にして全て結びついて設計がされているということに特徴を持ちます。 また今回は触れませんが、Langfuse外のツール 例えば異常を検知するガードレール機能やRAGASのような別の評価・スコアリングとも連携し、APIを通じてTraceにスコアをつけることなども可能であり、まさにプラットフォームとして幅広く利用することができます。 4. 導入パターン Langfuse では SaaS と Self-hosted の2パターンでの提供がされています。 SaaS と同様の機能を Self-hosted で利用でき、かつ OSS から手軽に始めることができることも Langfuse の大きな特徴です。まずは無償のSaaS版や OSS で簡単に立ち上げ、その後に本格導入することができるため、企業への導入の敷居も非常に低いと言えるでしょう。 方式 主に利用されているケース SaaS (Langfuse Cloud) 従量課金 (無償版あり)でも問題がない。 個人プロジェクト、PoC やスタートアップ、メンテ不要で素早やく試したい。 Self-hosted (Docker Compose, Helm, Terraform, AWS CDK などによるインストール) 固定費用 (OSS版なら無償)が予算の都合が良い。 セキュリティ要件として、自社内のNWに情報を保管する必要がある。 検証用でローカル環境で手軽に試したい。 Self-hosted において、どのパターンでインストールするかについては、 こちらの Blog も参考になさってみてください。 Docker compose などを使えば、すべての手順が数分で完了しますので、ぜひまずはとりあえずサクッとお試しください。 5. ロードマップとコミュニティ ― “公開・参加型”の進化エコシステム Langfuse は OSSをベースとして展開しており、その運営も非常にユーザーフレンドリーで透明性が高く、以下のような特徴を持ちます。 公開されたロードマップ GitHub Discussions に専用スレッドを設け、公式ページは機能計画とステータスが随時更新されています。また採択・却下の理由まで閲覧可能で、ユーザーのニーズを汲み取りながらも、非常に透明性の高い運営がされています。 ロードマップ: https://langfuse.com/docs/roadmap コミュニティサポート もし Bug と思われる挙動を発見した場合には、Github の Issue で報告をすることができます。有償サポートほどではないですが、開発者をはじめとしてコミュニティから多くのサポートを得られます。 フィードバックが反映 Idea ボードで提案に投票→優先度が可視化されます。Issue/PR はコメント付きでレビューされ、採用までの過程がすべて残ります。 定例イベント Discord Community Session(隔週) と Town Hall(毎月) で最新リリースをライブ解説。アーカイブは YouTube に公開され、非参加者もキャッチアップが可能。 日本発コミュニティ 「Langfuse Night」 Langfuse Night #1 (2025/1/28、虎ノ門)と #2 (2025/3/25)が 50〜60 名規模で開催されています。資料・動画を全公開。国内でも知見循環が急速に広がっています。また AWS でのハンズオン なども開催され、関連エコシステムとの連携も発展しています。 Langfuse の Github レポジトリはこちらです。ぜひご確認ください。 https://github.com/langfuse/langfuse まとめ Langfuse は生成AIアプリケーション / エージェント の開発から運用までを一貫して支援するプラットフォームです。その導入は非常にシンプルで、Cloud版やSelf hosted のDocker版なら数分で利用を開始することができます。まずはTraceの可視化を見える化から 始めて、その後にプロンプト管理や評価などをそこに付け足していくことで、生成AIのビジネス効果が高めていくことが可能です。 ガオ株式会社はサポートや有償版のリセールなどを行なっている Langfuse の 日本/APAC唯一のパートナーです。不明点など、お気軽にご相談ください。
- LLMOpsとは? MLOpsとの違いや生成AIの評価について解説
LLMOps とは? LLMOps(Large Language Model Operations)とは、大規模言語モデル(LLM)を利用した生成AIアプリケーションの開発から運用、改善までを一貫して管理するための考え方や仕組み(フレームワーク)です。多くの企業では、自社でモデルをゼロから構築するのではなく、OpenAI、Google、Anthropic などが提供する基盤モデルを活用し、プロンプト設計やファインチューニング(微調整)を通じて目的に合った生成AIアプリケーションを開発しています。LLMOpsは、こうした開発・運用プロセスを効率化し、品質管理やガバナンスを実現する上で重要な役割を果たします。 LLMOps のメリットとユースケース LLMOps は「便利ツール」ではなく、品質・コスト・リスクを同時に最適化する運用メソドロジーです。以下はその主なメリットの例です。 開発スピードの加速 - プロンプト管理、モデル、確立されたテスト手法により、開発効率の向上 (プロンプト管理に関しては こちら のブログを参照) 品質の継続的改善 LLM as a Judge、 ユーザーフィードバック、 Human Annotationなどをワンループで運用し、リリース後の精度向上を仕組み化 コスト最適化 Trace単位でトークン数と請求額を可視化、高コスト箇所を改善 ガバナンスと監査対応 全入出力・モデルバージョン・評価結果を一元ログ化し、生成物の説明責任 (Explainability) を担保、有事の際におけるトレーサビリティの確保 チーム横断コラボレーション データサイエンティスト/エンジニア/業務担当が 共通ダッシュボード で指標を共有し、改善案を合意形成しやすい スケールと未来対応力 新モデル登場やワークロード拡大時も、同じパイプラインにプラグインするだけで リスクなく横展開 ROI の可視化 Trace と KPI を結びつけ、「生成 AI がビジネス成果を生んでいるか」 を定量的に証明 またユースケースとしては、以下のようなものが想定されます。 生成AI導入によるカスタマーサポート平均対応時間の削減 生成AIの処理を可視化し、回答を継続的に評価、改善することで人件費削減 あわせて顧客の待ち時間も削減し、顧客満足度を向上 法務ドキュメントレビュー の時間削減 一次評価を全て生成AIで実現しつつも、発生するエッジケースに対して、Trace から LLM as a Judge による誤りケースを検出し、専門家レビューによる改善 パーソナライズド広告コピー生成クリック率 の向上 効果的なプロンプト をTraceのTagで判別し、A/Bテストを実施し、プロンプトを改善しつつ、効果的なものを瞬時に本番適用 LLMOps を導入せず当初の仮説だけでリリースした場合、こうした効果は期待できず、ビジネスにおける ROI も限定的なものとなってしまう恐れがあります。 MLOps と LLMOps の違い 従来のMLOps が一般的な機械学習モデルの開発と改善を対象とするのに対し、LLMOps はLLM を活用した生成AIアプリケーションやエージェント特有の課題に対応するためのものです。その主な特徴として運用プロセスにおいてモデルの出力に対する ユーザーからのフィードバック収集や自動的な評価の実行結果などを改善に活用する ことが重視されます。これらの結果がプロンプトや 自動評価自体の改善、モデル選定や 評価データセットの構築などに活用されることになります (具体的なプロセスは後述)。 LLMOps とGenAIOps の違いと関係性 LLMOps と似た用語にGenAIOps(Generative AI Operations)があります。GenAIOps は、テキストだけでなく画像、音声、動画などの生成モデルを含む、あらゆる生成AIを対象とした、より広範な概念です。一方、LLMOps は生成AIの中でも特に「大規模言語モデル(LLM)」を利用した言語生成にフォーカスしています。つまり、LLMOps はGenAIOps の一部分(サブセット)と位置づけられ、特に言語生成に特化したプロセスが重視されます。 LLMOps は GenAIOps の一部 生成AIアプリケーションのデプロイ、その後の課題 IT部門やDX部門などにより開発・導入された生成AIアプリケーションが、通常のシステムと同様に 最初から100% の品質でユーザニーズを満たすことはまずありません 。そして、アプリケーションの使われ方、ユーザーフィードバックの獲得、定量的な評価などが何もない状況であれば、当然その状況は 永遠に改善されません 。結果として経営層がそのプロジェクトにROI を見出せなければ継続することが難しくなるかもしれません。 生成AI は一見すると正しいように見える出力をする特性があり、出力結果はそのまま使えないが必ずしも全てが間違えているとも言い切れず、残念ながらユーザはモヤッとした不満を心に抱えることになります。その状況で仮にIT部門がアンケートを定期的にとったところで、低い解答率で曖昧な回答を受け取ることになり、具体的な改善に繋げることは難しいでしょう。 このような問題を解決するために必要な手法が LLMOps です。 LLMOps に必要な構成要素 生成AIを利用したアプリケーションやエージェントの継続的な改善を実現させるためのLLMOps には以下のような構成要素が含まれます。 Tracing ユーザ入力とモデルの出力 (Trace)の取得および保管、および処理内容の可視化 プロンプト管理 生成結果の品質向上のためのプロンプト修正、テスト、評価など ユーザ フィードバックの取得 ユーザがどの処理に対して、どのような評価をしたのかを具体的に収集・管理 Human Annotation 業務の専門家から見て、適切な回答をしているのかどうかの評価 自動評価 LLM as a Judge などを活用して、3や4の効率化・一次評価に利用 Dataset管理 ユーザの実際の入力などをデータセットとして管理し、テスト資材などのために管理 利用傾向の把握と分析 コスト, プロンプト, モデル, ユーザ, アプリケーションなどの様々な観点で、どのような傾向があるのかを分析 生成AIアプリケーションはこれらのプロセスを通じて継続的に改善し続けることで、初めてビジネスに価値を生み出すことが可能となります。続いて、この中から重要な要素であるTracingと評価 (ユーザーフィードバック, Human Annotation, 自動評価) に焦点をあてて、説明をしていきます。 Tracing - LLM アプリの“挙動”を可視化するバックボーン Tracing (または Trace ) はユーザーのインプットと LLM のアウトプットをまとめ、どのモデルを使い・何を参照し・何秒かかり・いくらコストが発生し・どんな結果を返したかなどを時系列で残す仕組みです。このTraceを軸に評価 (Evaluation) やデバッグなどが行われることから、LLMOps におけるバックボーンと言えるでしょう。以下はTracing によって得られる一般的なパターンです。 ビジネス課題 Tracing が解決すること 例 品質管理 失敗した Generation をクリックし、入力→Retrieval→出力を時系列で確認 “Hallucination が起きたのは Retrieval が空集合だった”と即判明 コスト抑制 Trace 単位でトークン数と課金額を自動記録 月次レポートで高コスト プロンプトを可視化し、短縮を提案 SLA/レイテンシ Span 間のタイムスタンプでボトルネックを特定 「埋め込み検索が 600 ms → Pinecone にインデックス分割」で改善 A/B テスト 異なるプロンプトを与えたTrace毎に結果を比較 プロンプト v2 の CS 工数削減率が +12 % を確認 Tracing は LLM アプリの全イベントを “1 本のストーリー” に束ねることで、 品質・コスト・パフォーマンスをワンクリックで照会 評価(LLM as a Judge、Human Annotation、User Feedback)との橋渡し プロンプトやパラメータが与える影響の確認 監査/セキュリティ要件への対応 と言ったLLMOps の道筋を作る重要な役割、最初の一歩の役割を持ちます。 これにより Tracing → 評価 (Evaluation) → 改善 のループが完成し、GenAIOps/LLMOps の継続的改善が“仕組み”として回り始めます。 生成AI においては評価が鍵 Tracing がされている前提で、LLMOps の構成要素の中で、特に重要なのは "評価" です。 生成 AI アプリケーションは、モデルが生成したアウトプットが実際にユーザーの課題解決に役立っているかを常に確認し、改善し続けることでなければ ROI を証明できません。 特に GenAIOps/LLMOps では、 オンライン指標(ユーザー行動) オフライン指標(定義済みデータセットによるテスト) モデル/人による定性評価 これら3つを組み合わせ、素早くループを回すことが成功の分水嶺になります。 1. ユーザーフィードバック:最も信頼できるオンライン評価 評価例 実装方法 オンライン 👍/👎、5 段階評価、自由コメント UI コンポーネントはできる限りワンクリックで完結させる オフライン クリック率、編集率、滞在時間 既存の分析基盤と Trace ID をひも付ける オフライン CS 工数削減、処理時間短縮 業務システム側で自動計測 → Langfuse の score API に送信 Langfuse では数値・カテゴリ・真偽値いずれのフィードバックも Trace 単位で保存、Exportすることが可能です。またダッシュボード上でスコア分布も即時確認できます。 2. Human Annotation:ドメイン知識を注入する評価の“最後の砦” Langfuse には以下の図のような極めて分かりやすい Human Annotation 専用の UI があり、次項で説明する自動評価でスコアが悪い Trace を Queue に入れ、Queueにいるそれらを簡単にドメインエキスパート (業務の専門家) が評価することができます。 実際の INPUT と OUTPUT をみて、手動でカテゴリや点数などで専門家が判定(評価軸は独自設定が可能) 3. 自動評価──“LLM as a Judge” で 指標 を ビジネス価値 に変換する BLEU/Rouge のような機械翻訳系メトリクスは「表層的一致」を測るには有効ですが、 本当にUX に寄与しているのか 業務 KPI(例:チケット処理時間、法令順守率)に直結しているのか という問いには答えてくれません。 ここで鍵になるのが LLM as a Judge ――LLM 自身を “審査員 (Evaluator) ” として使い、 独自プロンプト でタスク固有の評価軸を採点させる手法です。 なぜ「独自プロンプト評価」が効くのか? 業務コンテキストを埋め込める 業界用語や必須の条文のチェックなど、業務独自の内容を反映可能 評価基準の透明性 プロンプト の中に基準を明文化 することで、 ドメインエキスパートやステークホルダーも理解がしやすい 定量化が難しい基準も自然言語で入れることができる ビジネスに相応しいか、似合っているか、多様か ... などの基準を作ることが難しい内容もプロンプトが可能(精緻化した方が効果は高くなることがあります) Langfuse は最初から評価用テンプレートも用意されており、そこにさらに独自の基準を日本語で追加することができます。こうした自然言語で 半コード化された評価基盤 を「作る→回す→直す」のループに緊密に組み込み、Traceに紐づけることで、改善対象を明確にすることで、改善を具体化・高速化させることが可能になります。 「メトリクスでは不十分な評価も、LLM 使うことで “自社専属の 一次QA チーム” を構築」 ──Langfuse はその最短ルートもあわせて提供します。 まとめ|LLMOpsはLLM活用の鍵 LLMOps は、LLMをビジネスに導入し、その価値を継続的に生み出すために不可欠な運用手法です。特に、モデルプロバイダが提供する強力な基盤モデルの活用が一般的となった現在、LLMOps なしでの効果的な運用は困難と言えるでしょう。 その中でも特に、評価が改善の鍵となり、 Langfuse は世界中で使われている便利なUIや 機能を最初から備えています。ご興味がある方は、あわせてご確認ください。
- Agent Development Kit (ADK) のエージェント評価を試してみた!
最近話題の Google 製 AI エージェントフレームワーク「Agent Development Kit (ADK)」を触ってみました! Gemini モデルとの連携がしやすく、柔軟なエージェント開発が可能とのことで、期待が高まります。エージェントが自律的にツールを使うのは凄いですが、ちゃんと意図通り動くか、修正で壊れないかを確認する「評価」も重要ですよね。 そこで今回は、ADK のセットアップからエージェント作成、そしてそのエージェントを「評価」機能でテストするところまで、一通り試してみた記録をまとめます。 公式ドキュメント : 事前準備の参考記事 : ( 事前準備はこちらの記事を参考にしました ) 1. 環境セットアップ まずはローカル環境(Mac)でプロジェクトを準備します。パッケージマネージャーには uv を使用しました。 Bash # プロジェクトディレクトリ作成と移動 (Python 3.12.9 を指定) uv init -p 3.12.9 adk-work cd adk-work # ADK パッケージのインストール # (評価機能も使うため、[eval] 付きでインストールする) uv add "google-adk[eval]" google-adk[eval] とすることで、評価に必要な追加ライブラリ (pandasなど) も一緒にインストールされます。 2. エージェントプロジェクトの作成 参考記事に沿って、天気 (get_weather) と時刻 (get_current_time) を取得するツールを持つエージェント (multi_tool_agent) を作成します。 ディレクトリ・ファイル構成: Bash mkdir multi_tool_agent touch multi_tool_agent/{__init__.py,agent.py,.env} tree -a multi_tool_agent/ 実行結果: multi_tool_agent/ ├── .env ├── __init__.py └── agent.py ファイルの内容: multi_tool_agent/__init__.py : from . import agent multi_tool_agent/agent.py のコードを記述します。 import datetime from google.adk.agents import Agent from zoneinfo import ZoneInfo def get_weather(city: str) -> dict: """特定の都市の現在の天気情報を取得する。 Args: city (str): 天気情報を取得したい都市名。英語で。 Returns: dict: ステータスと結果またはエラーメッセージ。 """ if city.lower() == "new york": return { "status": "success", "report": ("ニューヨークの天気は晴れです。" "気温は25度(41°F)です。"), } else: return { "status": "error", "error_message": f"{city}の天気情報は利用できません。", } def get_current_time(city: str) -> dict: """特定の都市の現在時刻を取得する。 Args: city (str): 天気情報を取得したい都市名。英語で。 Returns: dict: ステータスと結果またはエラーメッセージ。 """ if city.lower() == "new york": tz_identifier = "America/New_York" else: return { "status": "error", "error_message": (f"{city}のタイムゾーン情報は利用できません。"), } tz = ZoneInfo(tz_identifier) now = datetime.datetime.now(tz) report = f'{city}の現在時刻は {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}です。' return {"status": "success", "report": report} root_agent = Agent( name="weather_time_agent", model="gemini-2.0-flash-exp", description="任意の都市の時刻と天気に関する質問に答えるエージェントです。", instruction="私は指定された都市の時刻や天気に関する質問に答えることができます。", tools=[get_weather, get_current_time], ) 3. モデル接続の設定 (.env ファイル) LLM (Gemini) への接続情報を .env ファイルに記述します。Google AI Studio か Vertex AI かで設定内容が異なります。 Google AI Studio: GOOGLE_GENAI_USE_VERTEXAI="False" GOOGLE_API_KEY="YOUR_API_KEY_HERE" Vertex AI: GOOGLE_CLOUD_PROJECT="your-gcp-project-id" GOOGLE_CLOUD_LOCATION="your-region" # 例: us-central1 GOOGLE_GENAI_USE_VERTEXAI="True" (Vertex AI 利用時は事前の API 有効化、gcloud auth login が必要) 今回は Vertex AI を使用しました。 4. エージェントを実行してみる (Web UIでの基本動作確認) まずはエージェントがちゃんと動くか、Web UI で確認します。プロジェクトルート (adk-work) で以下を実行。 Bash uv run adk web ブラウザで http://localhost:8000 にアクセスし、エージェント multi_tool_agent を選択します。 チャットで「ニューヨークの天気は?」などと尋ねると、エージェントがツールを使って応答してくれるはずです。右側のページで詳細な動作(LLM とのやり取り、ツール実行)も確認できます。これでエージェントが基本動作することは確認できました。 5. エージェント評価の必要性 手動での動作確認も大事ですが、エージェントが複雑になったり、修正を繰り返したりすると、「毎回同じテストを手動でやるのは大変」「意図しないところで動作が変わっていないか心配」となります。ここで ADK の 評価機能 の出番です。 ADK ドキュメントによると、LLM エージェント評価では「最終出力」だけでなく、そこに至る「軌跡(ツールの使い方など)」も重要であり、これを自動でチェックできる仕組みが提供されています。 6. 評価シナリオ (評価セット) の準備 評価のために、「お手本」となるシナリオと期待される動作を定義した 評価セットファイル (.evalset.json) を用意します。ファイル名は任意(例: multi_tool_agent_test.evalset.json)です。Web UI で対話したセッションを保存して生成することも、手動で作成することも可能です。 以下のファイルでは、期待されるツール使用と参照応答 (reference) を定義しています。 (ファイル名例: multi_tool_agent_test.evalset.json) JSON [ { "name": "test", "data": [ { "query": "おはよう!", "expected_tool_use": [], "reference": "おはようございます! お手伝いできることはありますか? " }, { "query": "ニューヨークの現在の時間は?", "expected_tool_use": [ { "tool_name": "get_current_time", "tool_input": { "city": "New York" } } ], "reference": "ニューヨークの現在時刻は...です。..." }, { "query": "ニューヨークの天気は?", "expected_tool_use": [ { "tool_name": "get_weather", "tool_input": { "city": "New York" } } ], "reference": "ニューヨークの天気は晴れです。..." } ], "initial_session": { "state": {}, "app_name": "multi_tool_agent", "user_id": "user" } } ] 7. 評価の基準 ( ADK ドキュメントより ) ADK はエージェントの実際の動作と評価セットの期待値を比較する際、以下の基準(メトリクス)とデフォルトの閾値を使用します。 tool_trajectory_avg_score : ツール使用履歴の一致度。デフォルト閾値 1.0 (完全一致)。 response_match_score : 最終応答と reference の類似度。デフォルト閾値 0.8 (ある程度似ていればOK)。 ちなみに、これらのデフォルト閾値は、必要であれば 以下のようなtest_config.json という設定ファイルを作成して各エージェントディレクトリ配下に置くことでカスタマイズすることも可能です。 { "criteria": { "tool_trajectory_avg_score": 1.0, "response_match_score": 0.8 } } 8. Web UI で評価を実行! 準備ができたので、Web UI で評価を実行します。 (もし adk web が停止していれば再起動) Web UI で multi_tool_agent を選択。 右側の「評価 (Eval)」タブを開く。 「評価セット (Eval Set)」ドロップダウンから、 自分で準備した評価セットファイル (multi_tool_agent_test)を選択。 評価ケース test が表示されるのでチェックを入れて、「Run Evaluation」ボタンをクリック! 実行後、結果が表示されます。 今回は無事「PASS」しました! また、ターミナルを見てみると詳細が出力されると思います。 ( ※注意 :応答一致 (response_match_score): 筆者が実験をしてみると、評価セットの reference に明らかに正しくない応答を設定し、さらに test_config.json で 値を明示的に指定しても、評価全体の結果は1となり「PASS」のままでした。) Agent Development Kit の評価まとめ 今回は、ADK のセットアップからエージェント作成、そして評価機能を使ったテストまでを一通り体験しました。評価セットによる自動評価は、特にエージェントのツール利用手順(軌跡)が期待通りかを確認する上で有効だと感じました (tool_trajectory_avg_score は意図通り機能しているようです)。これにより、回帰テストの一部は自動化できそうです。 一方で、 最終応答のテキスト内容 (reference) との比較 (response_match_score) については、今回試した範囲では、期待通りに最終的な評価結果 (PASS/FAIL) に影響を与えない場面がありました。 明らかに異なる応答を期待値としても、評価全体が PASS してしまうケースがあり、test_config.json で基準を明示的に設定しても結果は変わりませんでした。この挙動については、さらなる調査や ADK の今後のバージョンでの改善が必要かもしれません。 このように、現状では特に 応答内容の自動評価に関しては注意が必要 ですが、ツール利用の正確性を担保する目的など、 部分的には ADK の評価機能は開発の助けになる可能性はあります。ADK の評価機能を利用する際は、現状の挙動をよく理解・検証した上で、目的に合わせて活用するのが良さそうです。皆さんもぜひ試してみてください!
- Langfuse で LLM 評価を効率化!活用方法徹底解説
1.初めに 近年、AI 技術、特に大規模言語モデル(LLM)の進化は目覚ましく、様々な分野での活用が進んでいます。しかし、LLM をビジネスに適用する上で、その品質をどのように評価するかが大きな課題となっています。 これまでの LLM の評価は、主に「出力結果の目視確認」や「ユーザーフィードバック」に頼ってきました。この従来のアプローチには、以下のような課題があります 評価基準の曖昧さ 何をもって良い評価とするのかが評価者によって異なり、客観的な評価が困難 個人の価値観や経験によって、評価結果にばらつきが生じます 評価の多面性 正確性、簡潔性、論理的構成など、複数の観点からの評価が必要で 多角的な視点での評価が必要となり、総合的な判断が難しくなります 実装の複雑さ テストデータの準備、評価項目の設定、結果の可視化など、多くの実装工程が必要 評価用データセットの作成やプロンプトの作成に多くの工数がかかります このような課題を解決し、効率的かつ効果的な LLM 評価を実現するために、注目されているのが Langfuse です。 Langfuse は、LLM システムの開発から運用までをサポートする包括的なプラットフォームです。本記事では、特に LLM の評価機能に焦点を当て、Langfuse がどのように LLM 開発を効率化するのか、具体的な活用方法を解説します。 2. Langfuseによる評価機能 Langfuse は、これらの課題を解決するために、以下の2つの主要な評価機能を備えています。※セルフホスティングの場合はPro/Enterprise版を利用する必要あり Human Annotate: 人間の手によるラベル付けを可能にします。開発者以外のドメインエキスパートが評価する場合に特に有効です。 LLM as a Judge: LLM を評価者として活用し、評価用プロンプトに基づいて自動で評価を行います。これにより、評価の客観性と効率性を高めることができます。 Langfuse の評価機能を利用することで、評価軸を明確に定義し、客観的な評価を行うことが容易になります。また、評価結果は UI 上で可視化され、トレースと紐付けられるため、問題点を特定しやすく、効率的な改善サイクルを実現できます。 3. RAGASとLangfuseの評価アプローチの違い RAGシステムの評価フレームワークとして、RAGASは広く使用されています。RAGASは汎用的な評価フレームワークとして、検索精度や応答の関連性など、RAGシステムの基本的な性能を測定するために設計されています。しかし、実際のビジネス応用においては、以下のような制約があります RAGASの制約 事前に定義された評価指標に基づく標準的な評価 ドメイン固有の要件への対応が限定的 評価基準の詳細な調整が困難 これに対し、Langfuseは実務での活用に焦点を当てた評価プラットフォームとして、以下のような特徴があります Langfuseの特徴 ドメイン固有の評価基準を柔軟に設定可能 評価プロンプトのカスタマイズと継続的な改善 具体的な評価例 金融分野での規制要件への適合性評価 医療分野での専門用語の正確性評価 このように、RAGASとLangfuseはそれぞれ異なる用途に適しています。RAGASはRAGシステムの基本性能を標準的に評価する際に有効で、Langfuseは実際のビジネス要件に応じた詳細な評価が必要な場合に適しています。 RAGASとLangfuseの主な違い RAGAS Langfuse プロンプトを作成する必要性 必要なし 必要あり 各評価用のテンプレートはある 評価用プロンプトの可視化 Githubから確認 LangfuseのUI上で確認 評価のカスタマイズ性 ほぼなし 評価基準を作成・修正が容易に可能 実装方法 ソースコードで実装 UIで設定(別途実装も可能) 日本語での評価制度 (個人的印象) 不安定 安定するように評価用プロンプトの修正が可能 Langfuse を用いた評価の実践 データセットの作成 Langfuse では、トレースデータから評価用データセットを簡単に作成できます。UI 上で必要なトレースを選択し、「Add to dataset」ボタンをクリックするだけで、データセットとして利用できます。 また、データセット用のトレースをあらかじめ作成しておけば、より柔軟なデータセット作成が可能です。ユーザの入力だけ取得をして、データセットとして保管しておきたい場合などに有用です。 方法としては以下のような、関数を1つ作成するだけです。 例:(ユーザの入力だけほしい場合) ## python @observe() async def trace_dataset(): langfuse_context.update_current_observation(input=ユーザの入力 ,output="") テストデータセットの選定と管理 Langfuse では、作成したデータセットを「Queue」という仕組みで管理します。トレースを Annotation の Queue に入れ、ドメインエキスパートが Queue を仕分けることで、適切なテストデータを選定できます。これにより、評価に必要なデータだけを効率的に管理し、テストの精度を高めることができます。 トレースからqueueに入れる画面 Human Annotateの画面(仕分け画面) LLM as a Judge の利用方法 Langfuse の LLM as a Judge 機能を利用すると、データセットの選定も効率的に行えます。あらかじめ LLM as a Judge の設定をしておけば、トレースには自動でスコアが入力されるため、怪しい値をチェックすることで、より精度の高いデータセットを選定できます。 LLM as a Judge設定画面 LLM as a Judge設定画面(トレースの設定) テスト実行と結果の可視化 選定したデータセットを用いて、Langfuse 上でテストを実行します。テストの際には、モデルやプロンプトを自由に選択でき、複数の評価基準を設定することも可能です。テスト結果は、ダッシュボードで可視化され、各データポイントの評価スコア、入出力、トレースなどの情報を一目で確認できます。これにより、システムの改善点を効率的に特定し、迅速な改善サイクルを回すことが可能です。 プロンプト実験の設定画面 Langfuseを活用した評価サイクル 以上の機能を用いることで以下のような評価・改善サイクルが実現できます。 LLMの出力結果をトレースし、Langfuseで可視化 Annotation の Queueに入れて、ドメインエキスパートの人に出力結果を判断してもらう & LLM as a Judgeで各評価項目に対してスコアを出力させる 2で悪い結果の原因追及をして、入力をデータセットに格納(オプションで期待する出力もあると良い) プロンプトを変更する プロンプト実験を行い、前回のプロンプトの出力との違いについてLangfuse上で結果を可視化し原因の追求 5. まとめ Langfuse は、LLM システムの開発から運用までをカバーする包括的なプラットフォームです。特に評価機能においては、以下のような作業を UI 上で完結させることができます。 評価の事前準備 評価用プロンプトの作成 評価基準の定義 ドメイン固有の要件への対応 テストの効率化 トレースからの自動データセット作成 Human AnnotateとLLM as a Judgeの併用 複数の評価軸でのテスト実行 結果の可視化と改善 定量的なスコア表示 トレースを活用した原因追求 プロンプト実験による継続的な改善 現状では、Langfuseはトレースやモニタリング機能の利用がメインとなっていますが、本記事で紹介した評価機能を活用することで、LLM開発のライフサイクル全体を効率的に管理することが可能です。評価から改善までのサイクルを一つのプラットフォームで完結できる点は、開発効率を大きく向上させる要因となるでしょう。 ぜひ Langfuse を導入し、効率的なLLM開発の実現を目指してみてください。
- [LLMOps] プロンプト管理の課題
はじめに:生成AIが抱える困難とプロンプト 生成AIアプリケーションの開発は、従来のソフトウェア開発とは異なる難しさがあります。 その一つが、 生成AIの出力の不安定さ です。そしてこの不安定さに大きく関わっているのが、 プロンプト です。生成AIは、人間が与える指示、つまりプロンプトに基づいて動作しますが、プロンプトが適切でなければ、生成AIはその能力を十分に発揮できません。 しかし、 プロンプトの重要性は認識されつつも、その管理は後回しにされがち です。多くの開発現場では、プロンプトがコードの中に直接埋め込まれ、場当たり的に修正されているのが現状ではないでしょうか。(少なくとも、筆者は多くそのような現場を見聞きしています) LLMOps のプロンプト管理とは?:なぜ必要で、何が問題なのか プロンプト管理とは、生成AIへの指示(プロンプト)を体系的に作成、テスト、改善、保存、共有するプロセス全体を指します。 プロンプト管理の目的 は、主に以下の4つです。 品質向上: 生成AIの出力の品質を向上させ、安定させる。 一貫性確保: 同じプロンプトからは常に同じ品質の出力が得られるようにする。 効率化: プロンプトの作成、テスト、改善のサイクルを効率化する。 再利用性向上: 良いプロンプトをチーム内で共有し、再利用できるようにする。 これらの目的を達成するために、プロンプトを適切に管理する必要があります。 しかし、現状では以下のような問題点があります。 問題点1:コード埋め込みプロンプトの罠 開発時には、作業を優先させることに意識がいってしまい、プロンプトはプログラムコードの中に直接埋め込まれてしまいがちで、結果として以下のような問題を引き起こします。 保守性の低下: プロンプト変更のたびにアプリケーションと一緒に テスト, デプロイのパイプラインなどを回すため、とにかく手間や時間ががかかる。 再利用性の低下: 他のアプリケーションやチームメンバーがプロンプトを再利用しにくい。 可読性の低下: コードとプロンプトが混在し、コード全体の読みやすさが下がる。 バージョン管理の困難: プロンプトの変更履歴が追跡しにくく、問題発生時の原因特定が難しい。 上記のうち特に保守性の低下は致命的であり、開発,修正,テストというサイクルに無駄な工数や待ち時間などが発生してしまいます。 Prompt をコードに埋め込むとコードと同じ工程でリリースをすることになるが、その効果は特になく時間と手間だけが発生する 問題点2:Gitやデータベースでの管理の限界 プロンプトをコードから分離するためには、Gitやデータベースで管理する方法も考えられます。それらの特徴を大まかにまとめるたものが以下の表です。 プロンプト管理:データベース vs. Git 項目 データベース Git 対象ユーザー システム開発者 システム開発者 (あるいはGit作業についてトレーニングを受けた方) 利用スキル要件 DB設計・運用、SQL、加えて何らかの管理用アプリケーションが必要になるケースがある Git操作(コミット、ブランチ、マージ等) データ形式 構造化データ(プロンプト、メタデータ) 非構造化データ(主にテキスト) バージョン管理 履歴記録可能(実装依存)、差分比較は困難 履歴記録・追跡が容易、過去バージョンへ復元可、差分比較も容易 共有・コラボ 共有可能(同時アクセス、排他制御はDBによる)、専門知識必要、リアルタイム共同編集は困難 共有容易(リモートリポジトリ)、プルリクエストでレビュー可、権限管理可、ただし非技術者には難解 テスト・評価 テスト結果保存は要開発、自動評価連携は困難、プロンプトと出力結果の紐付けについても開発が必要 テスト自動化はCI/CD連携でアプリケーションと一体で実施 (プロンプト単体の評価は不可能)、自動での評価機能なし、出力結果との紐付け困難 検索性・再利用性 属性検索可、自然言語特性の完全な表現は困難 Git機能だけでは不十分(別途プロンプトライブラリ等必要) この表からわかるように、Gitとデータベースはそれぞれプロンプト管理に活用できる側面があるものの、多くの課題が残ります。 また プロンプトは本来はシステム開発者ではなく、生成AIのアウトプットの良し悪しが分かる 業務エキスパート (ドメインエキスパート) によって修正、テスト、評価をするべき にもかかわらず、両者ともシステム開発者の手により管理されることになります。 プロンプトがコードと一体化することにより、システム開発者はプロンプトの責任を持たざるを得ないが、正解が分からない悲劇 コードにプロンプトを取り込むことにより、生成AIのシステム開発者の管理スコープはプロンプトに及びます。なぜならば、変更できるのがシステム開発者だけだからです。 しかし生成AIシステムの品質を追求するためには、組織のあるべき姿として、コード管理はシステム開発者が実施し、プロンプトは生成AIに出して欲しい期待値を知っている業務エキスパートの手に委ねるべきなのです。 まとめ:プロンプト管理の課題を克服するために 生成AIアプリケーションの品質は、プロンプトの品質に大きく左右されます。しかし、プロンプトはコードに埋め込まれたり、Gitやデータベースで十分に管理されていなかったりすることが多く、様々な問題を引き起こしています。 これらの問題を解決し、生成AIのポテンシャルを最大限に引き出すためには、 プロンプト管理の仕組みをアプリケーション開発者以外でも対応できるよう整備し、プロンプト管理とテスト - 改善のプロセスを一元的に確立させることが不可欠 です。 [ 次回の記事 ] では、これらの課題を解決するための実例を「Langfuse」と、Langfuseを活用したプロンプト管理を通して詳しく解説します。
- Google CloudでLangfuse v3の構築手順(推奨設定/GKE)
はじめに GAOの遠矢です。普段はLLMアプリケーションの開発を主にしております。 このガイドでは、LangfuseというLLMOpsの基盤となるツールを Google Cloud 上で セルフホスティングする手順を紹介します。 Google Cloud 上のKubernetes (GKE) でLangfuse v3を安全かつ推奨される構成でデプロイする手順を解説します。 Langfuse v2からv3への主な変更点 V3では以下のような重要な改善が行われています アーキテクチャの最適化 キューに入れられたトレースの取り込み トレースはバッチ処理され、S3に直接保存 APIキーのキャッシュング Redisを活用した高速なAPI認証 プロンプトのキャッシュ(SDK・API) リードスルーキャッシュによる応答時間の改善 OLAPデータベース(ClickHouse)の採用 分析処理の高速化 信頼性の向上 S3/Blobストレージを活用したイベントの回復可能性 バックグラウンド移行のサポート マルチモーダルトレースのサポート コンポーネント構成 アプリケーションコンテナ(Web・Worker) ストレージコンポーネント(Postgres, ClickHouse, Redis/Valkey, S3/Blob) オプショナルなLLM API/ゲートウェイ 注記: この手順はLangfuse v3のデプロイに焦点を当てています。v2のデプロイについては、v2のドキュメントを参照してください。 注意事項: 本番環境で使用する前に、セキュリティとパフォーマンスを考慮して構成を見直すことを強く推奨します。 システム要件と構成 アーキテクチャ図 推奨構成 GKE(コンテナアプリケーション) 2つのCPUと4 GB の RAM 高可用性を実現するには、Langfuse Web コンテナのインスタンスを少なくとも 2 つ Cloud SQL(PostgreSQL) 特に指定なし Redis 1GB以上 ClickHouse: 3レプリカ構成 Cloud Storage(S3) 特に指定なし 注意事項: 今回はClickhouseをGKE上に構築する場合の手順のため、GKEノード(GCE)のマシンスペックが低いとClickhouseを構築できない可能性があるためご注意ください。 構築手順 本手順では、主にターミナルを利用して構築を行います。 構築準備 まず、Google Cloudプロジェクトの設定から始めます。 以下のコマンドでプロジェクトを設定します。 gcloud config set project [YOUR_PROJECT_ID] ネットワークインフラの構築 セキュアな環境を構築するため、専用のVPCネットワークとサブネットを作成します。 これにより、リソース間の安全な通信が可能になります。 # VPCネットワークの作成 gcloud compute networks create langfuse-network --subnet-mode=custom # サブネットの作成 gcloud compute networks subnets create langfuse-subnet \ --network=langfuse-network \ --region=asia-northeast1 \ --range=10.0.0.0/20 # VPCピアリングの設定 gcloud compute addresses create google-managed-services-range \ --global \ --purpose=VPC_PEERING \ --prefix-length=16 \ --network=langfuse-network gcloud services vpc-peerings connect \ --service=servicenetworking.googleapis.com \ --ranges=google-managed-services-range \ --network=langfuse-network # 内部通信用のファイアウォールルール gcloud compute firewall-rules create langfuse-allow-internal \ --network=langfuse-network \ --allow=tcp,udp,icmp \ --source-ranges=10.0.0.0/20 Kubernetesクラスターの構築 GKEクラスターを作成します。 本番環境では可用性を考慮して、複数のノードを配置することを推奨します。 gcloud container clusters create langfuse-cluster \ --network=langfuse-network \ --subnetwork=langfuse-subnet \ --region=asia-northeast1 \ --num-nodes=1~2 \ --machine-type=e2-standard-2 \ --enable-ip-alias # 認証設定 gcloud container clusters get-credentials langfuse-cluster --region=asia-northeast1 PostgreSQLの構築 PostgreSQLデータベースをCloud SQLで構築します。本番環境では十分なリソースと冗長性を確保することが重要です。 パスワード等は本来であれば、シークレット等で管理してください。 # PostgreSQL作成 gcloud sql instances create langfuse-postgres \ --database-version=POSTGRES_15 \ --tier=db-g1-small \ --region=asia-northeast1 \ --root-password=[YOUR_ROOT_PASSWORD] \ # 今回設定する箇所は特にないので任意で --database-flags=max_connections=100 \ --network=langfuse-network \ --no-assign-ip # データベース作成 gcloud sql databases create langfuse --instance=langfuse-postgres # ユーザの作成 gcloud sql users create langfuse --instance=langfuse-postgres --password=langfuse1234 また、プライベートIPはこの後Langfuse側で設定する必要があるのでメモしておいてください。 # プライベートIPの取得 gcloud sql instances describe langfuse-postgres \ --format="get(ipAddresses[0].ipAddress) Redisの構築 Redisをマネージドサービスである、Memorystore for Redisを利用して構築を行います。 しかし、コスト等の兼ね合いがある場合マネージドサービスを利用せずコンテナ上で構築することも可能です。 # Redisインスタンスの作成 gcloud redis instances create langfuse-redis \ --size=1 \ --region=asia-northeast1 \ --redis-version=redis_7_0 \ --network=langfuse-network \ --enable-auth \ --redis-config maxmemory-policy=noeviction Redisでは、認証用の文字列(REDIS_AUTH)、ホスト(REDIS_HOST)、ポート(REDIS_PORT)をこの後Langfuse側で設定する必要があるので、メモしておいてください # Redis認証文字列の取得 gcloud redis instances get-auth-string langfuse-redis --region=asia-northeast1 # Redisホストの取得 gcloud redis instances describe langfuse-redis \ --region=asia-northeast1 \ --format="get(host)" # Redisポートの取得 gcloud redis instances describe langfuse-redis \ --region=asia-northeast1 \ --format="get(port)" Cloud Storage (S3) の 構築 # バケットの作成 gcloud storage buckets create gs://$BUCKET_NAME \ --location=asia-northeast1 HMAC キーの作成手順 Cloud Storage > 設定 > 相互運用性タブに移動 サービスアカウント or ユーザーアカウントを選択しHMACキーを作成します。 アクセスキーとシークレットを安全に保存(これらは後でLangfuseの設定で使用) ClickHouseの 構築 今回はGKE上にClickHouseをデプロイする手法で行います。 # Helmのインストール curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash # Helmリポジトリの追加 helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update 次に以下のclickhouse-values.yamlを作成します。 shards: 1 replicaCount: 3 auth: username: default password: changeme resourcesPreset: large persistence: size: 100Gi shards: シャード数(この場合は1) replicaCount: レプリカ数(本番では3以上推奨) YAML作成後、Clickhouseのデプロイを行います。 helm install clickhouse bitnami/clickhouse \ -f clickhouse-values.yaml \ --namespace default その後以下のコマンドで、正常に起動することを確認します。 # Podの状態確認 kubectl get pods | grep clickhouse # サービスの確認 kubectl get svc -l app.kubernetes.io/name=clickhouse # ログの確認 kubectl logs clickhouse-0 # デプロイされたリソース一覧の確認 kubectl get all -l app.kubernetes.io/name=clickhouse . Kubernetes(helm)でのLangfuseのデプロイ # Langfuseリポジトリのクローン git clone https://github.com/langfuse/langfuse-k8s.git cd langfuse-k8s/charts/langfuse git checkout lfe-1348-v3-chart リポジトリをクローン後、以下の内容でlangfuse-values.yamlを作成してください。 また、その際に変数等は適宜変更してください。 langfuse-values.yaml replicaCount: 1 image: repository: langfuse/langfuse pullPolicy: Always tag: 3 imagePullSecrets: [] nameOverride: "" fullnameOverride: "" langfuse: port: 3000 nodeEnv: development next: healthcheckBasePath: "" nextauth: url: "http://localhost:3000" secret: "openssl rand -base64 32で作成" salt: "openssl rand -base64 32で作成" telemetryEnabled: true nextPublicSignUpDisabled: false enableExperimentalFeatures: true extraContainers: [] extraVolumes: [] extraInitContainers: [] extraVolumeMounts: [] web: replicas: 1 worker: replicas: 1 additionalEnv: - name: "LANGFUSE_LOG_FORMAT" value: "json" # Experimental v3 feature flags - name: "LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES" value: "true" - name: "ENCRYPTION_KEY" value: "openssl rand -hex 32で作成" - name: "LANGFUSE_ASYNC_INGESTION_PROCESSING" value: "true" - name: "LANGFUSE_ASYNC_CLICKHOUSE_INGESTION_PROCESSING" value: "true" - name: "LANGFUSE_READ_DASHBOARDS_FROM_CLICKHOUSE" value: "true" - name: "LANGFUSE_READ_FROM_POSTGRES_ONLY" value: "false" - name: "LANGFUSE_RETURN_FROM_CLICKHOUSE" value: "true" # Database connections - name: DATABASE_URL value: "postgresql://langfuse:langfuse1234@[DB_IP]:5432/langfuse" - name: "REDIS_HOST" value: "[REDIS_HOST]" - name: "REDIS_PORT" value: "[REDIS_PORT]" - name: "REDIS_AUTH" value: "[REDIS_AUTH]" - name: "CLICKHOUSE_URL" value: "http://clickhouse:8123" - name: "CLICKHOUSE_MIGRATION_URL" value: "clickhouse://clickhouse:9000" - name: "CLICKHOUSE_USER" value: "default" - name: "CLICKHOUSE_PASSWORD" value: "changeme" - name: CLICKHOUSE_CLUSTER_ENABLED value: "false" # Cloud Storage settings - name: "LANGFUSE_S3_EVENT_UPLOAD_ENABLED" value: "true" - name: "LANGFUSE_S3_EVENT_UPLOAD_BUCKET" value: "[BUCKET_NAME]" - name: "LANGFUSE_S3_EVENT_UPLOAD_REGION" value: "auto" - name: "LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID" value: "[HMAC_ACCESS_KEY]" - name: "LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY" value: "[HMAC_SECRET_ACCESS_KEY]" - name: "LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT" value: "https://storage.googleapis.com" - name: "LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE" value: "true" - name: "LANGFUSE_S3_EVENT_UPLOAD_PREFIX" value: "events/" serviceAccount: create: true annotations: {} name: "" podAnnotations: {} podSecurityContext: {} securityContext: {} service: enabled: true type: NodePort port: 3000 targetPort: 3000 ingress: enabled: false # ローカル環境では無効化 resources: {} autoscaling: enabled: false nodeSelector: {} tolerations: [] affinity: {} postgresql: deploy: false # 外部PostgreSQLを使用 auth: username: "langfuse" password: "langfuse1234" database: "langfuse" clickhouse: deploy: false # 外部Clickhouseを使用 valkey: deploy: false minio: deploy: false # 外部ストレージを使用 extraManifests: [] 主に変更する箇所は以下です。 パラメータ 作成方法/説明 nextauth.secret openssl rand -base64 32で作成 salt openssl rand -base64 32で作成 ENCRYPTION_KEY openssl rand -hex 32で作成 [DB_IP] PostgreSQLデータベースのIPアドレス [REDIS_HOST] Redisサーバーのホスト名 [REDIS_PORT] Redisサーバーのポート番号 [REDIS_AUTH] Redisの認証パスワード [BUCKET_NAME] Cloud Storageのバケット名 [HMAC_ACCESS_KEY] Cloud StorageアクセスのHMACアクセスキー [HMAC_SECRET_ACCESS_KEY] Cloud StorageアクセスのHMACシークレットキー LANGFUSE_EE_LICENSE_KEY Langfuse Enterprise プランのライセンスキー(オプション) ない場合は特に追加の必要なし 以下のコマンドでhelmでLangfuseをlangfuse-values.yamlに沿って作成します。 # Langfuseのデプロイ helm dependency update helm install langfuse . -f langfuse-values.yaml デプロイができたら、以下のコマンドでログとポッドの状態を確認します。 # podの状態確認 kubectl get pods -l app.kubernetes.io/instance=langfuse # ログの確認 kubectl logs -f deployment/langfuse-web kubectl logs -f deployment/langfuse-worker どちらとも起動することを確認したら、ポートフォワーディングをして、localhost:3000でLangfuseのログイン画面が出力されることを確認します。 ポートフォワーディングのコマンド # ポートフォワーディングの設定 kubectl port-forward svc/langfuse-web 3000:3000 その後、トレースなどを行い動作に問題がないか確認したらデプロイ完了です。 応用編 (外部IP付与 GCLB) GoogleのGlobal Load Balancerを利用して、HTTPS通信を可能にします。 まずは、Google マネージドのSSL証明書を作成します。 以下のmanaged-cert.yamlを作成します。 apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: langfuse-cert spec: domains: - YOUR_DOMAIN # 実際のドメインに変更 その後マネージド証明書の適用を行います。 # マネージド証明書の適用 kubectl apply -f managed-cert.yaml 次に外部IPアドレスを予約しておきます # 静的外部IPアドレスの予約 gcloud compute addresses create langfuse-ip --global ここで予約したIPアドレスを DNS の A レコードとして設定してください。 次に、langfuse-values.yamlを更新します。 主な変更点としては環境変数の更新・追加とIngressの追加を行います。 # 主な更新箇所のみ抜粋 langfuse: nextauth: url: "https://YOUR_DOMAIN" # 外部アクセス用のドメインに更新 additionalEnv: - name: "LANGFUSE_CSP_ENFORCE_HTTPS" value: "true" # HTTPSを強制的に使用 # 新規追加のIngress設定 ingress: enabled: true annotations: kubernetes.io/ingress.global-static-ip-name: langfuse-ip networking.gke.io/managed-certificates: langfuse-cert kubernetes.io/ingress.class: "gce" kubernetes.io/ingress.allow-http: "false" hosts: - host: YOUR_DOMAIN paths: - path: / pathType: Prefix Langfuseの更新 # Langfuseの更新 helm upgrade langfuse . -f langfuse-values.yaml 確認コマンド # 証明書の状態確認 kubectl describe managedcertificate # AtiveになったらOK # ロードバランサーの確認 kubectl get ingress # HOST名が設定したドメイン名、アドレスが langfuse-ipの値になってたらOK # GUIでGCLBが作成できるかどうかも確認 以上の設定が完了したら、https://YOUR_DOMAINにアクセスして、LangfuseUIにログインできたら成功です。 トレースなどができるか確認してみてください。 できない場合は helm unistallなどをしてください また、以下の画面はenterpriseEditionのライセンスキーの有効化を行なっているため、左上がv3.2.0 EEとなっています。 EEとなっており、Playground等の機能も画面に出力されている状態になっております。 クリーンアップ 必要に応じて、以下の手順でリソースを削除します # Langfuseの削除 helm uninstall langfuse helm uninstall clickhouse # GKEクラスターの削除 gcloud container clusters delete langfuse-cluster \ --region=asia-northeast1 \ --async # Cloud SQLインスタンスの削除 gcloud sql instances delete langfuse-postgres # Redisインスタンスの削除 gcloud redis instances delete langfuse-redis \ --region=asia-northeast1 # Cloud Storageバケットの削除 gsutil rm -r gs://$BUCKET_NAME # ファイアウォールルールの削除 gcloud compute firewall-rules delete langfuse-allow-internal # VPCピアリング接続の削除 gcloud services vpc-peerings disconnect \ --service=servicenetworking.googleapis.com \ --network=langfuse-network # 予約したIPレンジの削除 gcloud compute addresses delete google-managed-services-range \ --global # サブネットの削除 gcloud compute networks subnets delete langfuse-subnet \ --region=asia-northeast1 # VPCネットワークの削除 gcloud compute networks delete langfuse-network トラブルシューティング Redis接続エラーについて "Redis connection error: ERR unknown command 'client'"という警告は、Google CloudのMemoryStoreの制限によるものです。 この警告は表示されても、Redisとの接続自体は正常に行われています。 証明書のプロビジョニング マネージド証明書のプロビジョニングには数分から数十分かかる場合があります。 kubectl describe managedcertificate で状態を確認できます。 注意事項 すべてのパスワードとシークレットは適切に管理してください。 本番環境ではより強力なセキュリティ設定と、より多くのリソースを割り当てることを検討してください。 環境変数の値は実際の値に置き換えてください。 Langfuseの公式ドキュメントも参照し、最新の情報を確認してください。 最後に このガイドが、Google Cloud上でのLangfuse v3の安全なデプロイに役立つことを願っています。 また企業向けサポートとして、 ガオ株式会社 を通じてLangfuse ProおよびEnterpriseプランを日本円で購入し、日本語でサポートを受けることが可能です。 ご興味ある方は、contact@gao-ai.comまでご連絡ください。
- Langfuseによるプロンプト管理 (前半) - 基本 & 管理編
[ 前回の記事 ] では、プロンプト管理の重要性にくわえて、コード埋め込みやGit または データベースによる管理の課題について解説しました。今回は、それらの問題を解決すべく「Langfuse」を活用したプロンプト管理の方法を具体的に解説します。 Langfuseとは?:LLMの開発と運用に特化したオープンプラットフォーム Langfuseは、生成AIアプリケーションの開発や運用に特化したオープンソースのプラットフォームです。可視化やテストなど生成AIアプリケーションのライフサイクル全体を管理するものですが、今回は特にプロンプト管理に焦点を当ててご紹介をしていきます。 Langfuseによるプロンプト管理の主な特徴は以下のとおりです。 使いやすいUI: 直感的なインターフェースで、プロンプトの作成、編集、比較、テストが容易に行えます。 バージョン管理: 変更履歴を自動的に記録し、過去のバージョンとの比較やコピー、修正などが簡単に行えます。 詳細な分析: プロンプトのパフォーマンス(応答時間、コスト、品質スコアなど)を詳細に分析し、改善点を見つけやすくします。 柔軟な評価: LLM as a judge などによる自動評価指標に加えて、人間による評価 (Human Annotation) も組み合わせて、多角的にプロンプトを評価できます。 チームでの共有: プロンプトをチーム内で共有し、共同で作業できます。 実践!Langfuseによるプロンプト管理の具体的なステップ 前提: Prompt はLangfuse から取ってくる Langfuseを使うと、プロンプト管理はどのように変わるのでしょうか? まず前提としてアプリケーションコードに埋め込む形とは異なり、Prompt 本体は Langfuse に格納され、それをプログラム側から fetch する形となります。 アプリケーションはLangfuse に格納されているPrompt を取りに行き、適切なものを入手します。なお本番運用した際に都度取得をする必要は必ずしも無いので、TTL を設定してキャッシュする運用が現実的だと思います (デフォルト60 sec、0で即時反映)。 以下はPython のコード例です。極めてシンプルな実装が可能です。 この場合、wweという名前で管理されているPrompt をfetch してきます。 from langfuse import Langfuse # Initialize Langfuse client langfuse = Langfuse() prompt = langfuse.get_prompt("wwe") TTLを設定する場合や、特定のラベルのPrompt を取得したい場合は以下のようになります。ラベルについては後述します。 # TTL を 300に指定 prompt = langfuse.get_prompt("wwe", cache_ttl_seconds=300) # the-rock-is-cooking というラベルの Promptを取得 prompt = langfuse.get_prompt("wwe", label="the-rock-is-cooking") その他のオプションや記述例はLangfuse の公式ドキュメントに豊富な例が用意されていますので、参考にしてみてください。 URL: https://langfuse.com/docs/prompts/get-started 余談ですが、同サイトの右上にある Search 欄から、Ask AI (Cmd + k) で日本語で質問することも可能です。日本語でも精度が高いので、ぜひ使ってみてください。 さてこれから、実際のプロンプト管理を見ていきましょう。 Prompt の作成とバージョン管理 LangfuseのUI上では、直感的にプロンプトを直接作成・編集できます。 変更を加えるたびに、自動的に新しいバージョンが作成され、変更履歴が記録されます。 以下は プロンプト管理画面のサンプルです。 これは toyidea という名前のプロンプトで、右側で各バージョンを確認することができます。現在、Production に適用されているのは Version 2 のプロンプトです。 また、latest ラベルがついている Version 3 にはコメントがついており、"独自アイディアの追加プロンプト試行" とコメントがついています。併せて作業者もそれぞれ情報として付加されており、いつ誰が何のためにバージョンを変えたのかも非常に分かりやすくなっています。 ラベルについては最新のものには自動で latest がつきますが、この画像のように自分で任意の名前をつけ、前述のサンプルのように指定したものを fetch することもできます。 Version 間での詳細を比較したい場合には、GUI 上でDiff をすることもできます。相違部分がハイライトされおり、一目で差異が分かります。 またPrompt にはConfig として、以下のように任意の情報を持たせておくことができます。 モデル名, Temperature などをPrompt と一緒に取得することで、管理を一元化し、結果の整合性を維持することが期待されます。 例えばPrompt はLangfuse から持ってきても、コードの中で別のモデルを指定していると、テストしておいた結果と実際の結果は異なってしまいますが、管理をまとめることでそのような問題を防ぐことができ、コード自体もシンプルになります。 作成したプロンプト活用して、別のアプリケーションなどのために新たなプロンプトを作りたいこともあるでしょう。その際には、Duplicate 機能で任意のVersion だけ あるいはすべてのバージョンを含んでコピーを作ることができます。新たに Prompt を作る際に、どこからか Copy and Paste したり、新規で書く必要はありません。過去に作られている資産を使って作業を効率化することが可能なのです。 まとめ:Langfuseで簡単だけど効果的な プロンプト管理 他にも便利な機能がありますが、それらの紹介は別の機会に譲るとして、今回は一旦ここまでとしたいと思います。見ていただいた通り、Git でのオペレーションもSQL も不要かつ、非常に効果的な管理ができます。 本記事では、プロンプト管理の前提としてLangfuse で管理をする構成やどのように管理をされるのかという点について、いくつかの主要機能について説明をしていきました。 ぜひ参考にしていただき、プロンプトをハードコードする構成ではなく、LLM Ops を実現される一助になれば幸いです。 次回は Langfuse における実際のプロンプトの開発と評価について紹介します。 管理に加えて非常に有意義な機能を簡単に使うことができますので、ぜひご覧ください。
- Langfuseによるプロンプト管理 (後半) - プロンプト開発&実験編
[ 前回の記事 ] では、「Langfuse」を活用したプロンプト管理の方法を具体的に解説しました。Prompt をハードコードすることなく、Diff 、 Commit コメント 、Duplicate (複製) 、タグ などの機能を、直感的にエンジニアから非エンジニアまで幅広く使うことができますという内容です。まだご覧になっていない方は、ぜひチェックしてみてください。 さて今回は、Langfuseでのプロンプト開発と評価について触れていきたいと思います。 Langfuseによるプロンプトの新規作成 Langfuse にログインをしたら、左側のメニューバーから [Prompts] を選択し、右上の [+ New prompt] から新規作成を始めます。 画面右側の [+ New prompt] を選択 そして以下の新規作成ページに移りますので、必要項目を埋めるだけです。 新規作成ページ 各項目の説明は以下の通りです。 Name は Prompt に対する任意の名前で、プログラム側から指定するもの Prompt に具体的に入れたいプロンプト内容を入力します。Text か Chat を選ぶことができ、Chat を指定すると、それぞれのrole (System, Assistant, Developer, User) を指定してメッセージを入れることが可能です。Prompt の中には {{variable}} の形式で変数を埋め込め、ユーザーの入力値などを受け取って処理するために使えます。 Config は前回のブログでご紹介した通り、JSONで任意の値を入れることができるパラメーターになっております。例えば以下のようにモデル名の指定などで使うことができます。 { "model": "models/gemini-2.0-flash-001" } LabelsはデフォルトでProduction ラベルをつけるかどうかの選択です。Productionになっていると、プログラムコードでラベルを指定しない場合に選択されて使用されます。後で変更可能です。 Commit message は必須ではありませんが、Version1 以降はつけておくとチームメンバーなどに意図を伝えるために有益だと思います。 Playgroundの利用 まず新規での作り方を記載しましたが、場合によっては0から考えるのが難しいことがあると思います。そんな時に使える Playground 機能をご紹介します Playground 画面 左側のメニューから [Playground] を選択すると、Playground画面に遷移します。 基本的な使い方としては、試してみたいPrompt を [Messages] に入れ、画面右側で定義した [Model] で、モデルの種類や、各種パラメータを設定するだけ* です。また変数を入れて、右下の [Variables] に値を入れます。 例えば今回のPromptには 以下の文章が LLM の動作原理を説明する文章として正しいかどうかを判定しなさい。 {{text_input}} という記載が含まれており、この変数 text_input の値として テキストボックスに LLM は、主に「Transformer」と呼ばれる深層学習 (ディープラーニング) のアーキテクチャを基盤としています。このモデルは、大量のテキストデータ (書籍、ウェブサイト、記事など) を読み込み、単語や文の間の関係性 (文脈、意味など) を学習します。また学習した知識を基に、与えられた入力 (プロンプト) に対して、最も適切と思われる出力 (文章、回答など) を生成します。 を入れます。そしてSubmit すると、 [Output] にLLM からの回答が入っています。 この内容が気に入れば、右上の [Save as prompt] を押すと先ほどの新規作成画面に遷移し、そのまま新規Prompt にすることができます。 気に入らなければ好きなだけ修正するなり、初期化したければ [Reset playground] をするだけです。 *Model自体の登録はこの画面ではなく、メニューの [Settings] から あらかじめ設定しておく必要がありますのでご注意ください。Langfuse側からLLMモデルを利用しますので、課金されることにご注意ください。 Prompt Experiment の利用 新規作成後、LLMアプリケーションの運用においてPromptの改善が必要な場面に出くわすと思います。Prompt Experiment 利用すると変更したプロンプトに対して、リリース前に過去のユーザーのTrace をDataset にするなどして挙動が改善するかを確かめることができます。 Prompt Experiment 文字通りPrompt の実験として、対象Prompt とバージョンやモデルなどを指定し、 利用するDataset を設定します。 Datasetの指定 このDataset は0から作っておくもよいですし、Trace から直接Dataset に入れることで過去正常に動いたものがデグレしないか、不具合あったInputが改善されているかを実際に確かめていただくことができるようになります。また、LLM as a judge などと連携することで、自動で定量的な評価なども付加することが可能です。LLM as a judge については、 こちらのブログ で詳しく紹介しておりますので、是非あわせてご覧ください。(当該ブログの " テスト実行と結果の可視化" に相当する部分が本項に相当します。) なお今回ご紹介したPlayground とExperiment はSelf-hosted のOSS 版には含まれません (SaaS であれば無償のHobbyプランで使えます) のでご注意ください。 まとめ:Langfuseでプロンプト新規開発とテストを簡単に。 いかがでしたでしょうか。Langfuseを活用し、Promptの新規作成 - 管理までを簡単に実施できることがご確認いただけたと思います。本記事が効率的なLLMアプリケーションの開発とオペレーションのお役に立てれば幸いです。 本機能の具体的なユースケースや使い方のデモなどにご興味がある方は、ぜひ こちらから お気軽にお問い合わせください。
- Langfuse の Self-hosted インストールのパターンと解説
Langfuse v3 になって、「Self-hosting は良さそうだけど、結構インストール面倒なんでしょう?」という声をよく聞きます。もちろん複雑な構成を作ることも可能ではありますが、一方でLangfuse には簡単なものもふくめて幾つかのインストール方法が用意されており、利用用途や条件に合わせた選択が可能です。 この記事では、各インストールオプションおよび公式ページのリンク、使い分けについて解説します。まず簡単なケースごとのフローチャートは以下のような形になります。当てはまりそうなオプションを中心にぜひご確認ください。 インストールオプションのパターン 実際のインストールコマンドは、各オプションのリンクから公式をご参照ください。 Langfuse のインストールオプション 1. ローカルインストール Docker と docker compose を利用したローカル環境でのセットアップ方法です。 特筆すべきものはなく、非常にシンプルな手順で利用可能なもので、個人利用や簡単なテスト環境向きです。Mac やWindows でDocker をインストールしたら、docker compose upコマンド一つで起動します。特に悩むところもないです。 使用するケース 手元のアプリ開発の可視化やテスト目的で手軽にLangfuse を試してみたい このLangfuse を本番環境に使う予定はない 2. Docker Composeを使ったインストール 公式ドキュメントとしては区別されていますが、1と基本的には一緒です。ただしAWS/Google Cloud/Azure などで仮想マシン (EC2 など) をつかうことが想定されており、公式ページにはdockerパッケージの導入手順などについても記載してあります 大規模なトラフィックがなく、可用性が許容されるのであれば本番環境にも適用可能です。また一部にマネージドサービスを使うといった方法で可用性も向上できます。 使用するケース 小〜中規模のチームでの本番やステージング環境を構築したい Trace などの欠損リスクがある程度は許容できる VM の構築や管理ができる人がいる インフラ構築をシンプルに管理したい 必要なリソース 4Core 16GiB メモリなどが推奨 (それ以下でも立ち上がりはする) 100GiB ストレージ, 外部から接続できるNW設定 (Public IPなど) 本番利用に向けて、可用性を高める応用例 Object storage はVMではなくS3 / blob /GCS などに変更 プロンプト取得の可用性を高めるため、Web server のコンテナとPostgreSQL だけをマネージドサービス利用する またdocker-compose.yml を修正することで、ディスクやデータベースの接続など各種設定を変更することもできます。langfuse ディレクトリ直下にありますので必要に応じてご確認ください。 3. Dockerを使ったインストール Docker composeではなくDocker コンテナを使ってカスタマイズした構成を作るパターンです。利点は複数のコンポーネントで構成されているLangfuse をクラウドサービス側のマネージドサービスを利用して、高い可用性を保つことができることなどにあります。 PostgreSQL, Redis, Clickhouse をマネージドサービスで起動しておいて、docker コマンドの引数として指定しましょう。 使用するケース Kubernetes は使いたくないが、VM単体よりも可用性を高く保ちたい 一方でクラウドサービスのマネージドサービスを使って、手はかけたくない クラウドサービスのネットワークなどを構築・管理できる 改善したい可用性と構成例 プロンプト取得における可用性を向上させたい Web server のコンテナをECS やCloudRun で稼働 PostgreSQL をAurora や CloudSQL で稼働 Traceデータの可用性を高めたい Object Strage にS3, GCS などを活用 Clickhouse としてClickhouse Cloud などを使う、あるいはECSや GCE container optimized OS 上で動かす Async worker のコンテナをECS やCloud Run などで稼働 RedisにElasticashe や Memorystore などを活用する 最近ではTeraform, CDK, あるいはマニュアル などで比較的簡単 (あるいはほぼ自動) で構築できるようにリソースを公開しているものもあります。ご自身のケースに当てはまるかもご確認ください。 参考リンク AWS tuboneさん ( Blog ) リソース https://github.com/tubone24/langfuse-v3-terraform mazyu36さん ( Blog ) リソース https://github.com/mazyu36/langfuse-with-aws-cdk Google Cloud クラウドエース株式会社 高木さん ( Blog ) * マニュアルでのインストール手順 4. Kubernetes Helmを使ったインストール Kubernetes クラスタにHelm を使ってLangfuseを導入する方法です。可用性やスケーラビリティを確保しつつ、運用をKubernetesに任せたいケースに利用可能です。 使用するケース 比較的大規模なチームやエンタープライズ環境 高い可用性とスケーラビリティを求める Kubernetesクラスタを運用することができる なお、Langfuse 公式で Helm Chart がリリースされており、特に理由がなければこれを使うことが最初の入口として良いと思います。その上で、さらに可用性を向上させたい場合には以下のオプションなどが有益です。 Traceを格納するClickhouse自体の可用性や保守性などを高めたい コストや諸条件が合えばClickhouse Cloud など利用を検討する プロンプト取得における可用性を向上させたい PostgreSQL をAurora や CloudSQL などで稼働 以下の記事では、Langfuse をKubernetes + マネージドサービスの構成でデプロイをした構成について言及しています。 参考リンク Google Cloud GAO 遠矢 ( Blog ) 本記事がインストール方法の決定における参考になれば幸いです。 もし企業における導入サポートなどが必要でしたら、 お気軽にお問い合わせください。 https://www.gao-ai.com/contact
- [前半] ゼロからスケールへ:Langfuseのインフラストラクチャの進化 (和訳)
このBlog記事はガオ株式会社による Langfuse GmbH "From Zero to Scale: Langfuse's Infrastructure Evolution" の日本語訳 前半となります。原文は こちら をご確認ください。 ゼロからスケールへ:Langfuseの インフラストラクチャの進化 Langfuseのインフラストラクチャをシンプルなプロトタイプからスケーラブルな Observability プラットフォームへと進化させた過程を詳しくご紹介します。 Steffen Schmitz Max Deichmann オープンソースのLLM Observerbility プラットフォームであるLangfuseは、Y Combinator 2023年Winter バッチから誕生しました。 私たちは、多くのLLMアプリケーションを自分たちで構築し、デモから本番環境への移行が難しいことを実感した後、バッチメイトの数名と緊密に協力し、LLM可視化プラットフォームのv0を迅速に開発しました。 当初は、いくつかのコア機能に的を絞りました。SDKは非同期、Langfuseはトレースをベースとし、すべてのコンポーネントはオープンソースで簡単にセルフホスティングできるものでした。最初のバージョンは、NextJs、Vercel、Postgresで書かれていました。私たちは、この実験が1分あたり数万件のイベントを処理するまでに急速に進化するとは、夢にも思っていませんでした。 Langfuseがすべてのユーザーに対してスケーリングできることを確実にするという点において、私たちの最近のV3リリースは重要なマイルストーンとなりました。私たちはすでにLangfuse Cloudでこれらの変更の多くを試験的に導入しており、v3リリースではオンライン評価、非同期/キューイング取り込み、キャッシュされたプロンプトなど、セルフホスティングユーザーにもそれらを利用できるようにしました。 本記事では、Langfuseの開発中に直面したスケーリングの課題と、私たちの「仮説 - 実験 - フィードバック」のループがLangfuse v3の開発にどのように役立ったかについてご説明します。もし、私たちと一緒に同様の課題の解決に取り組みたいとお考えであれば、ベルリンで人材を募集しています! Where it all started 当初の私たちのアーキテクチャは、単一のコンテナとPostgresデータベースであり、運用とセルフホスティングは非常にシンプルでしたが、スケーリングが非常に困難な構成でした。 私たちは、アーキテクチャを再考せざるを得ないような、いくつかの重要な課題に直面しました。最も重要な課題は次の通りです。 課題 1: 耐障害性が高く、高スループットを取り込めるパイプラインの構築 目標: Ingestion API は、予測不可能な負荷パターン下でも、大量のイベントを受け入れ、一貫して低レイテンシを維持する Langfuse の可視化プラットフォームの中核は、SDK および API による効率的なイベントデータ収集に依存しています。 これらの SDK は、ユーザーのアプリケーションへのパフォーマンスへの影響を最小限に抑えるように設計されていますが、取り込みサーバーコンポーネントは、規模を拡大するにつれて、重大な課題に直面しました。 当初の課題: 2023年夏には、急激なトラフィックパターンにより、取り込みAPIのレスポンスタイムが最大50秒まで急上昇しました。 重要な要件: Ingestion API は、SDKからのイベントの円滑なフラッシングを確保するために、常に低レイテンシを維持する必要があります。そうでないと、ユーザーのアプリケーションに悪影響が及ぶ可能性があります。 課題は、大量のデータを処理することだけではありませんでした。予測不可能な負荷パターン下で信頼性を維持しながら、ユーザーのアプリケーションパフォーマンスへの影響を最小限に抑えることでした。この技術的なハードルは、トラフィックの急増をより適切に処理するための取り込みアーキテクチャを再考することを迫る、当社にとって最初の大きなスケーリングの課題となりました。 課題 2:実稼働時のワークロードに合わせたプロンプトの最適化 目標: Prompt API は常に高い可用性とパフォーマンスを維持する Langfuse の重要な機能のひとつがプロンプト管理システムであり、ユーザーは UI を通じてプロンプトを定義し、SDK を通じて取得することができます。これにより、プロンプトを変更するためにアプリケーションを再デプロイする必要がなくなります。 Trace は非同期かつノンブロッキングですが、プロンプトはLLMアプリケーションのクリティカルパスとなります。このため、一見単純な機能が複雑なパフォーマンス上の課題となりました。取り込みが集中する時間帯には、プロンプト取得の p95 レイテンシが7秒にまで上昇しました。この状況には、他の操作によるシステム負荷が重い場合でも、一貫した低レイテンシのパフォーマンスを維持できるアーキテクチャ上のソリューションが必要でした。 課題 3:高速な分析読み取り(ダッシュボード、テーブルフィルター) 目標: 大規模な観測データにも対応するダッシュボードとテーブルフィルター 当初のデータベースとしてPostgresを選択したことは、初期の段階ではうまくいきましたが、当社の最大顧客がシステムを通じてより多くのObserverbility データを送信するようになると、重大なパフォーマンスのボトルネックにぶつかりました。クエリを最適化しても、当社のダッシュボードとテーブルフィルターの操作は、企業ユーザーにとっては遅すぎました。LLMの分析データは多くの場合、大きなblobで構成されており、何百万行ものデータをスキャンする際には、行指向のストレージがディスク上で重荷となっていました。皮肉なことに、当社の分析機能を最も必要としているお客様が、最もパフォーマンスの低下を経験していました。この成長に伴う問題は、当初のアーキテクチャが迅速な開発には最適であったものの、企業規模の分析作業負荷に対応するには根本的な再考が必要であることを示していました。 課題4:簡単なセルフホスティング 目標: 簡単にセルフホスティングできるだけでなく、運用上の労力をほとんど必要とせずに拡張できること Langfuseをオープンソースプロジェクトとして構築することは、意図的な選択でした。私たちのビジョンはシンプルでした。誰もが簡単なdocker-compose upでLangfuseを利用し始めるべきであると同時に、Langfuseは同時に、毎分何百ものユーザーと何千ものLLMのやり取りがあるエンタープライズ規模の展開にも対応できなければなりません。このアプローチは、私たち自身が開発者として好むものを反映しています。私たちは、評価や展開が容易なソリューションを重視しています。 しかし、実稼働環境に耐えうるオープンソースのObserverbility プラットフォームを構築するには、特有の課題があります。 汎用性:当社のインフラは、開発者のLaptopからさまざまなクラウド事業者へのデプロイまで、多様な環境でシームレスに動作する必要があります。 オープンソースへの依存:当社はオープンソースコンポーネントのみを使用することで、無制限のセルフホスティング機能を確保することを約束しています。 ゼロタッチ操作:企業ユーザーは、メンテナンスとアップグレードの自動化を必要としています。手動操作ではエラーが発生しやすく、拡張性にも欠けます。 このシンプルさとエンタープライズ対応のバランスが、当社のアーキテクチャ上の決定を形作り、アクセスしやすく拡張性のあるソリューションの作成を後押ししました。 新しい構成要素 これらの課題に対処するために、私たちはスタックに複数のビルディングブロックを追加しました。本記事では、私たちがどのようにスタックを繰り返し改良していったかをご紹介します。 ビルディングブロック1:取り込みデータの非同期処理 同期処理から非同期処理へ 私たちは当初、APIコールごとに多数のイベントを受信し、それらを繰り返し処理し、各イベントを個別に処理するIngestionパイプラインから始めました。処理中、まず同じIDを持つ履歴行を検索し、LLMコールのプロンプトと補完をトークン化し、コストを計算し、データベース内のイベントをupsertします。しかし私たちのテレメトリを調査したところ、2つの大きなボトルネックがあることが分かりました。PostgresのIOPSの枯渇と、長い文字列をトークン化する際のCPU消費です。これらはどちらも、当社のアプリケーションの稼働時間とレイテンシに影響を及ぼすリスクです。最悪の場合、当社の取り込みAPIでEvent が失われ、HTTP 500エラーが返されることになりました。 ソリューションを検討するにあたり、単にコンテナの数を増やすだけでは効果的ではないことに気づきました。個々のユーザーが大規模なバッチジョブを実行すると、取り込みトラフィックが大幅に急増することがよくあります。その結果、ユーザーからの API トラフィックは非常に予測が難しくなり、コンテナインスタンスではこうした急増に対応するのに十分な速さでスケールすることができません。そこで最終的に、すべての取り込みトラフィックを Redis のメッセージキューにルーティングすることにしました。Kafkaとは異なり、Redisは簡単に自己ホストでき、当社の要件を満たすように拡張できます。そして次に、別のLangfuseコンテナ (Worker) が非同期でこのデータをConsumeし、レート制限を適用して、当社のデータベースの負荷とコンテナのCPU使用率を低減します。この変更により、認証と本文の形式のみを確認する軽量な取り込みエンドポイントを作成しました。このWorkerコンテナは、トークン化やデータベースへの書き込みなどのより集中的なタスクを処理します。 Clickhouseから読み込まずにClickhouseに更新を書き込む 私たちは、APIパフォーマンスを短期的に改善する必要があったため、上記のステップのみを行いました。しかし、作業はまだ終わっていませんでした。Worker コンテナがすべての処理を非同期で行っていたとしても、私たちの取り込みパイプラインのロジックを動作させるには、多くのPostgresのIOPSが引き続き必要でした。この問題についても、セルフホスティングユーザーから問い合わせがありました。同時に、私たちは読み取りクエリのAPIレイテンシを改善するという課題にも直面しており、最終的に、TraceデータをPostgresからClickhouseに移行することを決定しました。Clickhouseは、Observerbility分野において多くの新規参入者が使用しているOLAPデータベースで、Apacheライセンスが適用されており、当社の概念実証(PoC)で卓越したパフォーマンスが確認されていました。列指向のストレージレイアウトは、私たちが期待する分析クエリに適しており、大規模なバイナリ列を持つ単一行の検索でも高いパフォーマンスを発揮します。しかし、本番環境への導入は容易ではありませんでした LangfuseのSDKは、指定されたオブジェクトIDの更新をバックエンドに送信するように設計されています。Postgresにおける単一の行の読み取りと更新は高速かつ簡単ですが、 ClickHouseにおけるすべての行の更新は非常にコストのかかる操作 です。そこで私たちは更新を新しい挿入に変換し、ClickHouseのReplacingMergeTreeテーブルエンジンを使用して、最終的にバックグラウンドで行の重複を排除しています。 つまり、常に行の最新の状態を取得し、更新を適用し、それをClickhouseに書き戻す必要があるということです。 私たちはトラフィックを分析し、すべての更新の90%が10秒以内にデータベースに書き込まれることを認識しました。つまりこれは、同時実行性とデータの整合性に気を配らなければならないことを意味します。しかし、Clickhouse から行の最新の状態を取得するのは現実的ではありませんでした。Clickhouse は、クエリ結果を返す前に全てのデータが Clickhouse ノード間で同期されることを保証する、非常にコストの高い "select_sequential_consistency" 設定を使用した場合にのみ、書き込み後の読み取りの一貫性が保たれます。したがって、私たちの規模では、Clickhouse から既存のデータを読み取れる保証はありませんでした。また、同じIDに対する2つのイベントが並行して処理され、競合状態が発生する可能性もありました。 そこでこの問題を緩和するために、承認された全てのイベントを Redis にキャッシュすることにしました。そして、Worker コンテナにイベントを送信し、Worker コンテナはオブジェクト ID に関連する全てのイベントを取得して、Clickhouse から読み込む必要なしに、確実に新しい Clickhouse の行を作成します。私たちは新しい取り込みパイプラインを実装し、Postgres 取り込みパイプラインと並行してイベントの処理を開始しました。 しかし非常に大きなインスタンスを利用しても、AWS ElastiCache のネットワーク容量には限界があるという事実がすぐに判明しました。また、Redis のもう一つの欠点は、インメモリ型のアーキテクチャと、保存されたデータが一時的な性質 (ephemeral) であることです。S3 をイベントのPersistent ストレージとして導入することで、Redis には参照情報のみを保持できるようになりました。この変更により、エラーが発生した場合にイベントを再生することも可能になり、さらに驚くことに、Redis 用にイベントをシリアライズする処理が高コストだったため、Web コンテナの CPU 使用率が大幅に低下しました。Kafka の方が取り込みにはより適していたかもしれませんが、新しいマルチモーダル機能のために、Redis のキャッシュ機能と S3 を活用することで、コンポーネント数を少なく保つことを選択しました。これらの調整により、Clickhouse にデータを一貫して、かつ大規模に挿入することに成功しました。
- [後半] ゼロからスケールへ:Langfuseのインフラストラクチャの進化 (和訳)
このBlog記事はガオ株式会社による Langfuse GmbH "From Zero to Scale: Langfuse's Infrastructure Evolution" の日本語訳 後半となります。原文は こちら をご確認ください。 前半記事は こちら 。 ビルディングブロック2: キャッシュと分離型のインフラストラクチャ Clickhouseへのデータ取り込み問題を解決する一方で、プロンプト管理機能を利用するユーザーの状況も改善する必要がありました。Observerbility データ分析の結果、プロンプトAPIにはいくつかの問題があることが判明しました。具体的には、それらが大量の取り込みトラフィックがデータベースのIOPSやコンテナのCPUを枯渇させる可能性がありました。 最初に、プロンプトを取得するためのPostgresデータベースへの問い合わせを回避しようと試みました。ここで、Redisをキャッシュとして利用することの強力さと、それがもたらす影響を実感しました。プロンプトが更新されるタイミングは把握しているため、古い結果を返すリスクなく効率的にキャッシュを無効化できます。 次に、プロンプトや認証など、レイテンシーと可用性に敏感なインフラを専用のデプロイメントに分離しました。AWS ECSの特定のエンドポイントに対して、LoadBalancerルールと専用のTargetGroupを使用することで、取り込みトラフィックをアプリケーションの他の部分から隔離できます。さらに、専用ルートによって可観測性が向上するという追加のメリットも得られました。この構成はまだHelm Chartには含まれていませんが、必要であれば主要なクラウドプロバイダーやKubernetes全体でエミュレートできます。 これらの2つの変更により、プロンプトAPIのp99(99パーセンタイル)のレスポンスタイムを7秒から100ミリ秒に短縮することに成功しました。 3つ目に、SDKを更新して、ゼロレイテンシのプロンプトフェッチングを使用するようにしました。以前にAPIからプロンプトのバージョンが取得されている場合は、そのバージョンを次のLLM呼び出しに使用し、LangfuseのAPIへの呼び出しはバックグラウンドで実行します。これにより、プロンプトがユーザーのアプリケーションのクリティカルパスから取り除かれました。 ビルディングブロック3:OLAPデータベース+クエリ最適化 Langfuse V3への移行における最後の課題は、読み取りクエリを最適化し、すべてのユーザーに対して一貫して低いレイテンシーを実現することでした。この取り組みを開始した時点で、すでにPostgresと並行してClickhouseにデータを書き込んでいました。これにより、Clickhouseからのデータの保存方法と取得方法を実験することができました。何度も「これでうまくいった」と思ったものの、そのたびにさらに多くのデータが到着しました。 当初、過去1週間以内のデータに対するすべての呼び出し(単一レコードのルックアップを含む)はp99で1秒以内に完了し、1週間以上のデータについては4秒以内であれば許容できると考えていました。Datadogでの通常のトレーシングに加えて、PostgresとClickHouseの読み取りを同時に実行し、それらのレイテンシーの違いを測定するためのフレームワークを構築しました。一貫して改善された結果を確認することで、正しい方向に進んでいるという確信を得ました。 まず最初に正しく行う必要があったのは、テーブルスキーマ、パーティショニング、およびデータの並び順キーでした。これらを変更するには、テーブル全体の書き換えが必要となり、つまり、すべての更新に数日かかる可能性がありました。他のClickhouseユーザーとの会話やClickhouseのドキュメントを参照し、早い段階でprojectIdと日付を並び順キーの最初の2つの列にすることにしました。さらに、フィルタリングによく使用される列にスキップインデックスを設定して、アイテムIDも追加しました。Postgresとは異なり、Clickhouseでは効率的な行ルックアップのためのB-Treeインデックスを保持できません。常にディスクレイアウトに基づいてデータを検索する必要があります 次に最適化する必要があったのは結合処理 (Join) でした。Oberverbility データへの結合を行う際に、処理に数秒かかり、Clickhouseノードで使用可能なすべてのメモリを使い果たすことが頻繁に発生していました。Clickhouseは、結合の右側 (The right side of a join) を効果的にフィルタリングするのが苦手だということを学びました。そこで可能な限り結合を避け、Common Table Expressions (CTE) を使用して、できる限りフィルターを手動でプッシュダウンしました。場合によっては、単一のトレースやObserverbility データのルックアップで並び順キーをより有効に活用するために、タイムスタンプなどの追加情報をフロントエンドAPIの呼び出しに追加しました。 これらは私たちが想定していた課題でしたが、ここからはClickhouseの特異な性質について掘り下げていきます。まず、ReplacingMergeTree内でデータを重複排除する方法を見つける必要がありました。Clickhouseは最終的には行を重複排除しますが、挿入後数分から数時間以内に多くの重複が発生し、短期間のメトリクスやダッシュボードがほぼ使い物にならないことがわかりました。FINALキーワードを使用すると改善されましたが、クエリ実行中のリソース消費量が増加したり、スキップインデックスの最適化がまったく利用されなくなったりするという新たな問題が発生しました。書き込みタイムスタンプによる重複排除(order byとlimit by)、FINALキーワード、およびdistinct集計を組み合わせて、信頼性の高いメトリクス、テーブル、およびビューを作成しました。 スキーマ設計に多くの時間を費やしたことが、Clickhouseへの移行において大きな成果をもたらしました。プロセス全体を通してわずかな調整しか必要なく、PostgresからClickhouseへの1回のデータインポートで済みました。残りの最適化については、特定のユースケースで何がうまくいくかを予測できなかったため、迅速な反復が功を奏しました。優れた可観測性と堅牢な実験フレームワークは、反復と新しい仮説の形成に迅速なフィードバックを提供しました。昔から言われているように、「変更が難しいことについては時間をかけて考え、できる限り迅速に動く」ということが重要です。 これらにより、以前は大規模プロジェクトでの外れ値によって悪化していたフロントエンドおよびバックエンドAPI呼び出しにおけるパフォーマンスが向上しました。 V3 Architecture まとめ:Langfuse v3のアーキテクチャに施した主な変更点は以下の通りです。 Worker コンテナ:イベントを非同期に処理する S3/Blob store: ラージオブジェクトを保存するため Clickhouse: Trace, Observations, Scoreを保存する Redis/Valkey: Eventキューイングとデータキャッシュ V3構成 V2構成 (参考) 結論 (Conclusion) Langfuse v3のリリースに非常に満足しています。Langfuse Cloud ユーザーからのポジティブなフィードバック、最初の1週間でのセルフホストユーザーの高い導入率、そしてわずかな問題点リストは、プロジェクト全体を通して多くの正しい決断を下したことを示しています。新しいアイデアを迅速にテストし、明確なデータに基づいた強力な仮説に導かれることで、大きな進歩を遂げることができました。 しかし、プロジェクト中、しばしばスケジュールを見誤っていました。今後の取り組みについては、スコープを最大1か月に制限し、途中でより多くのマイルストーンを導入する予定です。さらに、Langfuseが急速に成長しているため、このプロジェクトの進行中、主要な担当者が継続的なインシデントやバグ修正の対応に手が取られることが多くありました。 私たちはデータ駆動型の文化、本番データのサブセットで実験を行うためのシンプルな方法、そしてスタック全体にわたる優れた可観測性を維持します。これらの要素は、費やした各時間の価値を最大化し、セルフホストとクラウドベースの両方の顧客を満足させ続けるのにとって重要な意味を持つものとなります。 原文: Langfuse GmbH "From Zero to Scale: Langfuse's Infrastructure Evolution" 日本語: Langfuse 日本語サイト 本ブログにおけるお問い合わせは こちら まで。





![[LLMOps] プロンプト管理の課題](https://static.wixstatic.com/media/89c202_d8d4c113a298446a9930c9159a68f5f3~mv2.png/v1/fit/w_176,h_124,q_85,usm_0.66_1.00_0.01,blur_3,enc_auto/89c202_d8d4c113a298446a9930c9159a68f5f3~mv2.png)




![[前半] ゼロからスケールへ:Langfuseのインフラストラクチャの進化 (和訳)](https://static.wixstatic.com/media/89c202_fc52200e0a20482fa12bdb0968f3091c~mv2.png/v1/fit/w_176,h_124,q_85,usm_0.66_1.00_0.01,blur_3,enc_auto/89c202_fc52200e0a20482fa12bdb0968f3091c~mv2.png)