Langfuse、金融サービス向けLLM・AIエージェントのデプロイゲート構築を提案
本文の状態
日本語全文を表示中
詳細モードで約24分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Langfuse Engineering
Langfuse Engineering は、世界有数の銀行との協業を通じて、LLM や AI エージェントの金融サービス向けデプロイメントゲートを自動化するパイプラインを構築し、手動検証の非効率性を解消した。
AI深層分析を開く2026年8月4日 14:02
AI深層分析
キーポイント
金融規制における迅速な対応の必要性
従来の信用モデル向けに設計された数ヶ月単位の承認プロセスは、プロンプトやツールの頻繁に変更される LLM システムには適合せず、手動検証では追いつかないという課題が指摘されている。
自動化されたデプロイメントゲートの構築
Langfuse のデータセット、実験機能、および公開 API を活用し、LLM システムを金銭的データセットに対して実行し、ドメイン固有の評価器でスコアリングして自動的な PASS/FAIL 判定を行うパイプラインを実装した。
監査証跡の完全な記録と可視化
各ランの実行結果、トレース、スコア、およびその背後にあるプロンプトバージョンを Langfuse に保存し、レビュー担当者がいつでも検証可能な状態を維持することで、モデルリスク管理プロセスを強化している。
実例に基づく失敗の防止
Claude Sonnet を使用した 150 項目の FinanceBench ランで数値精度閾値(85%)を下回った際、デプロイ前にアラートが発令され、クライアントへの誤報告という重大インシデントを未然に防ぐ事例を示している。
手動プロセスの非効率性
金融機関の既存モデルリスク管理は手動証拠作成に数週間を要し、LLM の迅速な変化に対応できない。
重要な引用
Caught here, this costs nothing: a number turns red on a dashboard and someone investigates before the release.
Financial institutions and organizations in other regulated industries need a reliable way to establish whether the output of an LLM system can be trusted.
By the time a manual approval lands, the system it tested has often already changed.
Caught after deployment, it means a client received a wrong number in a 10-K summary, and in financial services that is a reportable incident rather than an engineering bug.
編集コメントを表示
編集コメント
この記事は、LLM の実運用におけるリスク管理の難しさを具体的な数値事例で浮き彫りにしており、単なる技術紹介を超えた実践的な知見を提供している。金融業界のような厳格な規制下での AI 導入において、自動化された検証プロセスが不可欠であるという示唆は非常に価値が高い。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
2026 年 7 月 15 日
金融サービス分野における LLM(大規模言語モデル)や AI エージェントのデプロイメントに、自動的な合格・不合格のゲート(閾値)を設けるために、Langfuse のデータセット、実験機能、およびパブリック API をどのように活用したかについて解説します。

Doneyli De Jesus
ある一つの数値が、実行結果を赤く染めました。81.3%です。
Claude Sonnet を用いた 150 項目の FinanceBench(金融ベンチマーク)テストを完了した直後でした。数値精度に関するゲートの閾値は 85% に設定されていたため、今回の実行は不合格となりました。
この段階で検知できればコストは発生しません。ダッシュボード上で数値が赤く表示され、リリース前に担当者が調査に乗り出すからです。しかし、もしデプロイ後に発見されていれば、クライアントは 10-K(年次報告書)の要約において誤った数値を受け取ることになります。金融サービス業界では、これは単なるエンジニアリング上のバグではなく、報告義務のあるインシデントとして扱われます。
金融機関や他の規制産業に属する組織にとって、LLM システムの出力を信頼できるかどうかを判断するための確実な手段が必要です。本プロジェクトは、世界有数の大手銀行 5 行の一つとの共同作業から生まれました。同社のモデルリスク管理プロセスでは、何らかのプロダクション環境への展開前に必ず証拠書類が必要とされていました。具体的には、テスト結果、レビュー承認書、およびドキュメントです。
しかし、これらの証拠を人手で作成するには数週間もの時間を要し、そのプロセス自体は年に 2 回しか変更されない従来の信用モデル向けに設計されたものでした。一方、LLM システムははるかに速いペースで変化します。プロンプトが更新され、モデルが差し替えられ、ツールや検索ロジックも進化していくからです。手動での承認が下りた頃には、テスト対象となったシステム自体はすでに変わってしまっていることがほとんどです。
ここでは、検証プロセスを自動化したスクリプトを紹介します。本記事で解説するパイプラインは、LLM システム(プロンプト付きのモデルまたは多段階エージェント)に対して、金融分野に特化した「正解データセット」を実行させます。すべての出力結果は、ドメイン固有の評価器によって採点され、最終的に「合格/不合格」という判定が下されます。
この判定に至るまでの全プロセス——各実行のトレース、スコア、プロンプトバージョンなど——はすべて Langfuse に保存されます。これにより、レビュー担当者は詳細を検証することが可能になります。関連するコードは、langfuse-llm-certification-finance リポジトリで公開されています。本記事執筆時に使用したソースの状態に固定されており、以下のコミットを確認できます:source state used for this post。
なお、リポジトリ名やデータセット名、および後述のスクリーンショットに登場する「certification(認証)」という用語について補足します。これは開発プロセス内で私たちが内部で使っていた名称であり、本パイプラインが何らかの公式な証明書を発行するものではありません。このパイプラインはあくまで、レビュー可能な証拠を生成するための「デプロイメントゲート」です。規制当局による承認、独立した検証、法的審査、そして責任ある人間の最終承認は、すべて人間が行うべき事項として残されます。
合格/不合格判定の仕組み
- 審査済みの不具合のリリース抑制
- Langfuse 上の正解データセット管理
- 実験実行:モデル、プロンプトのバリエーション、またはエージェント
- プロンプト管理:バージョン管理されたプロンプト
- 評価器:決定論的アルゴリズムと LLM-as-a-judge の併用
- ランレベルでのゲート制御
- ポータル機能・エクスポート・CI エクジットコードの連携
- 本番環境のトレース記録
- アノテーションキュー:人間のレビュー待ち状態
本パイプラインは、Langfuse の 4 つの機能——datasets、experiments、prompt management、annotation queues——を基盤とした Python スクリプト群です。テスト対象となるすべての要素は、同じループを通じて処理されます。
各ランの実行先(ターゲット)は、ベースラインとして機能しモデル比較の基準となる「プロンプト付きモデル」、または審査委員会が実際に目を通すシステムである 3 つの登録済みエージェントのいずれかです。登録されているエージェントは 10k-analyst、sentiment-triage、advisory-draft の 3 つです。
各ランでは、ターゲットの出力を「ゴールデンデータセット」上で評価し、ランレベルのゲートがそのスコアを単一の PASS または FAIL に変換します。判定結果は、レビュー担当者が利用するポータルに表示され、エビデンスパッケージとしてエクスポートされるほか、CI の終了コードとしても返されます。
本稿では、このループを左から右へと順を追って解説していきます。なお、本パイプラインでは 3 つのデータセットを使用します。
| データセット | ソース | 項目数 | テスト内容 | ゲート |
|---|---|---|---|---|
| FinanceBench | PatronusAI/financebench | 150 | SEC 提出書類からの金融 Q&A:数値抽出と推論 | モデルのベースラインおよび 10k-analyst エージェント |
| Financial PhraseBank | ChanceFocus/en-fpb | ~4,850 | 金融ニュースの感情分類 | モデルのベースラインおよび sentiment-triage エージェント |
| Advisory Adversarial | リポジトリに同梱 | 10 | ドラフトを禁止された表現へと誘発する顧客向け更新ブリーフ | advisory-draft エージェント |
これら 3 つはすべて Langfuse の データセット に読み込まれ、各項目には入力(質問またはテキスト)、期待される出力(正解またはラベル)、そしてメタデータ(ソース、質問タイプ、推論タイプ)が含まれています。
from langfuse import Langfuse
from datasets import load_dataset
langfuse = Langfuse()
ds = load_dataset("PatronusAI/financebench", split="train")
for item in ds:
langfuse.create_dataset_item(
dataset_name="certification/financebench-v1",
input={
"question": item["question"],
"company": item.get("company", ""),
"evidence": [ev.get("evidence_text", "") for ev in item.get("evidence", [])],
},
expected_output={
"answer": item["answer"],
"justification": item.get("justification", ""),
},
metadata={
"question_type": item.get("question_type", ""),
"question_reasoning": item.get("question_reasoning", ""),
"source": "PatronusAI/financebench",
},
)question_reasoning フィールドには、各回答がどのように導き出されるべきかのプロセスが記録されています。以下のエージェントセクションでは、このフィールドを正解(グランドトゥルース)として用い、エージェントが適切な手順で回答に到達したかどうかを検証します。
プロのヒント: すべてのデータセットは 2 つのサイズで読み込むようにしてください。セットアップスクリプトの --sample フラグを使用すると、10 件のサンプルからなるバージョン(例:certification/financebench-sample)が作成されます。これは数分でエンドツーエンドの実行が可能であり、ライブデモや評価器・プロンプトの反復開発時に利用しています。
正式なゲート評価は、完全なセット(certification/financebench-v1)に対して実行されます。タスク、評価者、閾値はいずれのサイズでも同一であるため設定のズレはなく、レビュー証拠として認められるのは完全なランのみです。
`dataset.run_experiment()` は、タスクを期待します。これはデータセットの1項目を受け取り、スコアリング対象となる出力を返す関数です。当社のタスクは、評価対象のモデルにその項目を送信します。SEC 提出書類からの証拠抜粋を含む FinanceBench の項目については、ソース文書をプロンプト内のコンテキストとして組み込み、RAG パイプラインをシミュレートします:
def create_certification_task(model, endpoint, api_key):
def task(*, item, **kwargs):
inp = item.input if hasattr(item, "input") else item.get("input", {})
question = inp.get("question", inp.get("text", ""))
evidence = inp.get("evidence", [])
if evidence and any(evidence):
context = "\n\n".join(
f"--- Source Document Excerpt {i} ---\n{ev}"
for i, ev in enumerate(evidence, 1) if ev
)
prompt = (
f"You are a financial analyst. Answer the question using ONLY the "
f"provided source document excerpts. Be precise with numbers.\n\n"
f"{context}\n\n--- Question ---\n{question}"
)
else:
prompt = question
return call_model(prompt, model, endpoint, api_key)
return taskこのスニペットに含まれるアナリストの指示は、あくまでフォールバック(代替手段)です。
このリポジトリは、Langfuse プロンプト管理 からテンプレート名で取得するため、実行ごとにどのプロンプトバージョンを使用したかが記録されます。数ヶ月後に結果に疑問が生じた場合でも、正確な文言が証拠として残ります。
このタスクは run_experiment() 関数に渡され、ここでは並行処理、トレーシング、評価を一度の呼び出しで処理します:
from langfuse import get_client
langfuse = get_client()
dataset = langfuse.get_dataset("certification/financebench-v1")
result = dataset.run_experiment(
name="financebench-v1",
run_name="claude-sonnet-4-6-20260715",
task=create_certification_task(model, endpoint, api_key),
evaluators=[
numerical_accuracy_evaluator,
exact_match_evaluator,
regulatory_compliance_evaluator,
response_completeness_evaluator,
groundedness_evaluator,
],
run_evaluators=[
average_score_evaluator("numerical_accuracy"),
average_score_evaluator("groundedness"),
certification_gate("numerical_accuracy", threshold=0.85),
],
max_concurrency=5,
)すべてのモデル呼び出しは Langfuse で追跡され、評価者によってスコアリングされます。同じデータセットを複数のモデルで実行すれば、Langfuse UI 上で項目別・スコア別に並列比較が可能になります。
このパイプラインでは、異なる失敗パターンを検出するために 2 種類の評価器を組み合わせています。5 つの決定論的評価器(高速・低コスト・再現性あり):
- 数値精度: 出力から数値を抽出し、期待される答えと 5% の許容誤差で比較します。通貨記号、カンマ、パーセント表記、丸め方の違いにも対応しています。
- 完全一致: 出力に期待される答えがそのまま含まれているかを確認します。
- 感情分類: 出力内の感情ラベルを、Financial PhraseBank の正解ラベルと比較します。これは単純な文字列比較であり、判定モデルは使用しません。
- 規制遵守: 「確約された収益」や「リスクフリー投資」といった禁止用語が出力に含まれていないかスキャンします。
「レスポンスの完全性」スコアは、回答の長さや構造化されたフォーマットを評価します。名前の通り構造をチェックするものですが、内容が質問に答えているかどうかは、後述する判定モデル(judge)が担当します。
LLM-as-a-judge 方式の評価者が一人います。この評価者は、決定論的なチェックでは見逃す可能性のある「根拠の妥当性」groundedness という次元をカバーします。判定モデルは、質問、出典となる証拠、そしてモデルの回答を受け取り、金融監査人の評価基準に従って、その回答が証拠によって裏付けられているかをスコアリングします。このスコアには判定者の推論理由も併記され、トレース情報として記録されます。
例えば、計算ステップで失敗した際に架空の数値を補填して回答を膨らませたケースなどを、この手法は検出できます。
10 項目からなる FinanceBench サンプルからの実行例を見ると、なぜ両方の評価が必要なのかよく分かります。Claude Haiku は数値精度で 60%、根拠の妥当性では 97% を記録しました。間違った数値であればどちらのケースでもモデルは実用できませんが、この二つのスコアを組み合わせることで、失敗の原因を特定できます。Haiku は証拠を忠実に読み取っていましたが、数値推論においてのみ失敗していました。解決策として必要なのは、検索設定の変更ではなく、計算ツールの導入か、より強力なモデルの採用です。こうした詳細な分析こそが、モデルリスクレビュー担当者がレポートから得るべき情報なのです。
すべての評価者は同じ Langfuse のシグネチャに従います。以下は、リポジトリから要約した数値精度の評価結果です:
from langfuse import Evaluation
def numerical_accuracy_evaluator(*, output, expected_output, **kwargs):
answer = expected_output.get("answer", "")
expected_nums = _extract_numbers(answer)
if not expected_nums:
# Not a numerical question: fall back to string containment
matched = answer.strip().lower()[:20] in str(output).strip().lower()
return Evaluation(name="numerical_accuracy", value=1.0 if matched else 0.0)
matched, detail = _numbers_match(expected_nums, _extract_numbers(str(output)))
return Evaluation(
name="numerical_accuracy",
value=1.0 if matched else 0.0,
comment=detail,
)アイテムレベルの評価器に加えて、certification_gate という名前のランレベル評価器がバイナリ判定(合格/不合格)を出力します。ランレベル評価器はすべてのアイテム結果のリストを受け取るため、関連するスコアをラン全体で平均化し、閾値と比較します。
def certification_gate(score_name, threshold=0.85):
def evaluator(*, item_results, **kwargs):
values = [
ev.value
for result in item_results
for ev in result.evaluations
if ev.name == score_name and ev.value is not None
]
avg = sum(values) / len(values) if values else 0.0
passed = avg >= threshold
return Evaluation(
name="certification_result",
value=1.0 if passed else 0.0,
comment=f"{'PASSED' if passed else 'FAILED'}: avg {score_name}={avg:.1%} (threshold={threshold:.0%})",
)
return evaluator完了したランは、レビュー可能な証拠パッケージとして Markdown、JSON、または CSV 形式でエクスポートできます。
python setup_datasets.py --dataset financebench --sample
python run_certification.py --dataset certification/financebench-sample --model claude-sonnet-4-6
python export_results.py --dataset certification/financebench-sample --format markdown上記のモデルレベルのランはベースラインに過ぎません。これらは「どのモデルを基盤とするか」「モデルの差し替えによって何かが後退していないか」といった問いに答えるものです。実際のデプロイ判断は、より大きな文脈で行われます。誰しもが単に Claude Sonnet をデプロイするわけではなく、それを基盤とした 10-K 分析アシスタントをデプロイします。このアシスタントは計画を立て、証拠を検索し、計算ツールを呼び出し、回答を組み立てます。そのため、パイプラインではエージェントを第一級のターゲットとして登録し、モデルと同じデータセット、評価器、ゲートを通じて実行します。
エージェントにおいては 2 つの変化があります。まず、各エージェントはデータセットのアイテムごとに多段階タスクとして実行され、各ステップにネストされたスパンが 1 つずつ付与されます。これにより、レビュー担当者は Langfuse の任意のアイテムを開き、エージェントがどのツールを呼び出し、どのような結果を得たかを確認できます。以下は calculate ステップを選択した 10k-analyst アイテムの例です。ツールの呼び出し入力と返却値がトレース内に明確に表示されています:
第二に、単一の精度閾値ではなく、各エージェントには独自の多次元ゲートが設けられています。すべての次元で同時に合格しなければ、実行は失敗となります。
| エージェント | ステップ (スパン) | ゲート(すべての次元で合格すること) |
|---|---|---|
10k-analyst | plan → retrieve-evidence → calculate → compose | accuracy ≥ 85%, groundedness ≥ 80%, compliance = 100%, tool use ≥ 90% |
sentiment-triage | classify → rationale → route | sentiment accuracy ≥ 85%, compliance = 100%, tool use = 100% |
advisory-draft | analyze → draft → compliance-self-check | groundedness ≥ 80%, compliance = 100%, completeness ≥ 70%, tool use = 100% |
python run_usecase_certification.py --list
python run_usecase_certification.py --use-case 10k-analyst \
--dataset certification/financebench-sample --queue-failuresこれらの次元のうち、2 つは特に注意深く見る必要があります。
ツール軌跡(tool trajectory)は評価の基準です。 tool_use_correctness 評価器は、データセット内の question_reasoning メタデータを利用して、数値に関する質問が電卓ツールの使用を通じて回答されたかを確認します。計算せずに正しい比率を推測したエージェントは、答え自体は「正解」と判定されますが、その軌跡は「不正」としてマークされ、評価に失敗します。
コンプライアンス(法令遵守)では 100% が求められます。 advisory-draft の場合、禁止されたフレーズが一つでも含まれると、実行全体が不合格となります。このゲートが機能していることを証明するために、上記の表にある「Advisory Adversarial データセット」をリポジトリに含めています。これは 10 件の顧客向け更新ブリーフで構成され、そのうち 3 件はコンプライアンス要件を満たし、残りの 7 件はそれぞれ、コンプライアンス担当者が即座に認識する異なる失敗モード(確約された利益や機密性の高い非公開情報の示唆など)を誘発するように設計されています。2 つの公的ベンチマークとは異なり、このセットは手作業でキュレーションされ、継続的な成長を意図しています。本記事末尾にあるフィードバックループにより、レビュー済みの本番環境での失敗事例がここに追加されていきます。
モデル承認に関わる担当者がトレース(実行ログ)を読み込むことはありません。リスク管理部門や事業責任者は、1 つの画面で以下の 3 つの質問に答えられるものを求めています。「何が合格したのか」「どのデータセットに対して評価されたのか」「最後にチェックしたのはいつか」。リポジトリには、これらを正確に可視化する「Certification Portal(認証ポータル)」が含まれています。これは FastAPI バックエンド上で動作するシンプルな React ダッシュボードで、すべてのモデル、プロンプトのバリアント、およびエージェントについて、最新の判定結果をステータステーブルとして表示します。
画面に表示されるすべての数値は、Langfuse の パブリック REST API(データセット、ラン、トレース、スコア)からリアルタイムで取得されています。各行は、真実の源となる Langfuse 内の対応するトレースへ直接リンクしています。
各行は実行ビューへのリンクを持っており、そこでは判断基準の背後にある評価者のスコア(平均値、最小値、最大値、および各次元ごとのパス率)が表示されます。PASS/FAIL バッジはランレベルのゲートスコアに基づいています。しきい値タイルには主要メトリックのバー(今回は 85%)が表示され、エージェントの各次元ごとしきい値は、上記の表からゲート評価器自体内で適用されています。
さらにワンクリックでアイテム別ビューへ移動できます。ここではデータセットの各項目がすべての次元でスコアリングされており、それぞれの項目は Langfuse 内の対応するトレースにリンクしています。ある項目が数値精度チェックで失敗した場合、そのトレースを開いてエージェントの動作を確認します。
ゲート実行は繰り返し行われるため、各データセットには実行履歴が保持されます。これは敵対的データセット上の advisory-draft エージェントの例です。クリーンなパスに挟まれた一時的な失敗(ディップ)は、意図的に誘発されたランがゲートを通過しなかったことを示しています。
ポータルは、型安全な Python SDK を介して公開 API 経由で全データを取得します。一方、集計データやデータウェアハウス向けのワークフローには Metrics API やスケジュールされたエクスポートが利用されます。Langfuse が唯一の信頼できる情報源(ソース・オブ・トゥルース)であり、ポータルは承認判断を下す人々に向けたドメイン特化型のビューです。
一度きりのゲートは単なるスナップショットに過ぎません。証拠を最新の状態に保つために、2 つのフィードバックループが機能しています。1 つ目は、本番環境での障害がゴールデンデータセットへフィードバックされること、2 つ目はプロンプトの変更がゲートを通過して反映されることです。
本番環境はゴールデンデータセットを強化します。 モニタリングスクリプトが生きたトレースのコンプライアンスと完全性をスコアリングし、違反事項を Langfuse の 注釈キュー へ転送して人的レビューの対象とします。具体的な例として、本番環境で生成されたドラフトが基金を「安全な賭け」と表現した場合、モニタリングがそのフレーズを検知し、トレースがレビューキューに格納されます。その後、レビュアーがスコアを付け、本来記述すべき内容も記録します。
検証された失敗事例は、新しい項目として「ゴールデンデータセット」に昇格させることができます。レビュアーが正解を提示するため、パイプラインが疑わしい出力をそのまま正解としてコピーすることはありません。次の実行では、発見された生産環境での失敗を正確に回帰テストします。
データセットが成長するとスコアの解釈も変わるため、昇格は自動化ではなく、意図的なレビュアーの行為です。また、各実行でどの項目にスコアをつけたかを記録するため、過去の結果も追跡可能です。スコアの推移は、同じデータセットの状態で行われた実行間でのみ比較されます。
プロンプトの変更はゲートを再実行します。 Langfuse の GitHub 連携 を使えば、プロンプトが変更された際にリポジトリイベントをトリガーできます。このリポジトリでは、連携とシークレットを設定した上で、プロンプトを production ラベルに昇格させると、GitHub Actions ワークフローが起動し、影響を受けるゲートを厳格な終了コードで実行します。
新しいプロンプトバージョンのスコアが閾値を下回った場合、ゲートは失敗し、ワークフローも失敗してリリースがブロックされます。レビュアーが確認するまで、この状態は解除されません。
このパイプラインはエンジニアリングインフラストラクチャに過ぎず、それ単体でシステムをコンプライアンス適合させるものではありません。どの要件が特定のシステムに適用されるかは、機関や管轄区域、そして各フレームワークがそのシステムをどのように分類するかによって異なります。
主要なフレームワーク全体を通じて共通するエンジニアリング上の要件は一つです。それは、デプロイ前の文書化されたテスト、完全なログの記録、文書化された人的レビュー、そしてリリース後の継続的なモニタリングです。このパイプラインが生成するのはまさにその証拠となります。
| フレームワーク | 要約 | パイプラインが支援できる箇所 |
|---|---|---|
| Fed SR 26-2 / OCC 2026-13 | 米国モデルリスクガイドラインの改訂。生成 AI および自律型 AI は明確に対象外とされているが、銀行には適切な統制をもってこれらを管理するよう指示されている | その検証および監視のパターンは、このような内部 LLM ゲートの設計上の参考となる |
| PRA SS1/23 | 銀行向けの UK モデルリスク原則。AI および ML 技術(ガバナンス、検証、継続的監視)を網羅 | バージョン管理されたゲートは、検証および再検証の証拠として機能する |
| EU AI Act | 信用力評価などの高リスク用途におけるログ記録、人的監督、市場導入後の監視 | ログ記録用のトレース、文書化された人的レビュー用の注釈キュー、市場導入後プロセスの監視 |
| DORA | EU 金融機関向けの ICT およびサードパーティリスク管理 | モデル API の可用性、劣化、およびインシデントに関する運用上の証拠 |
| NIST AI RMF | 任意のフレームワーク:展開前の文書化されたテストおよび使用時の監視 | Measure 用のデータセット、評価器、ゲート、実行履歴;Manage 用のレビューキュー |
同機関は、従来の運用を継続します。つまり、適用性の判断、ポリシーの策定、独立した検証、承認プロセス、そして法的コンプライアンスです。
- カスタムデータセット: FinanceBench を自社の「正解 Q&A ペア」に置き換えます。設定スクリプトは、入力・期待出力・メタデータフィールドを含む任意の JSON ファイルを受け付けます。
- ドメイン固有の評価器: 専門用語や書式要件、規制制約に対するチェックを追加できます。
- プロンプトのバリエーション: 特殊なシステムプロンプトで同一モデルを実行し、ベースラインと比較します。当社のテストでは、金融専門家向けのシステムプロンプトを採用したことで、Claude Sonnet の FinanceBench サンプルにおける数値精度が 90% から 100% に向上しました。両方の結果は、上記のポータル画面スクリーンショットで確認できます。
- 独自のエージェント: プロンプトバリエーションがプロンプトのみを変更するのに対し、エージェントにはステップとツールが追加されます。ステップとゲート閾値を登録すれば、組み込みの 3 つと同様にネストされたトレーシングや多次元ゲートの恩恵を受けられます。
- CI/CD の統合: pytest ゲートおよび GitHub Actions ワークフローは、ゲート実行が失敗した場合にビルドを停止します。これにより、モデルとプロンプトの承認がデプロイパイプラインの一部となります。
オフラインテスト用のサンプルデータと CI ワークフローを含む完全なコードは、langfuse-llm-certification-finance リポジトリにあります。このリポジトリを構築した理由は、LLM システムの進化スピードに対して手動での証拠収集が追いつかないからです。承認に数週間かかるケースも珍しくなく、その頃にはすでにテスト対象となったプロンプトやモデル自体が置き換えられてしまっています。一方、スクリプトで自動化されたゲートを使えば、何らかの変更があった際に毎回数分で同じ証拠を生成できます。
このページは役立ちましたか?
原文を表示
July 15, 2026
How we used Langfuse datasets, experiments, and the public API to build automated pass/fail deployment gates for LLMs and AI agents in financial services.

Doneyli De Jesus
One number turned the run red: 81.3%.
We had just finished a 150-item FinanceBench run with Claude Sonnet. The gate for numerical accuracy was set at 85%, so the run failed.
Caught here, this costs nothing: a number turns red on a dashboard and someone investigates before the release. Caught after deployment, it means a client received a wrong number in a 10-K summary, and in financial services that is a reportable incident rather than an engineering bug.
Financial institutions and organizations in other regulated industries need a reliable way to establish whether the output of an LLM system can be trusted. This project came out of our work with one of the five largest banks in the world. Their model risk management process already required evidence before anything reached production: test results, review sign-offs, documentation. Producing that evidence by hand took weeks, and the process was designed for credit models that changed twice a year. LLM systems change much faster, because prompts get promoted, models get swapped, and tools and retrieval logic evolve. By the time a manual approval lands, the system it tested has often already changed.
So we scripted the evidence. The pipeline in this post runs an LLM system, either a model with a prompt or a full multi-step agent, against golden financial datasets, scores every output with domain-specific evaluators, and produces a PASS/FAIL verdict. Every run, trace, score, and prompt version behind that verdict is stored in Langfuse, where a reviewer can inspect it. The code is available in the langfuse-llm-certification-finance repository, pinned here to the source state used for this post.
A note on the word certification, which appears in the repository name, the dataset names, and the screenshots below: it is the internal name we used for this process while building it, and nothing here issues a certificate. The pipeline is a deployment gate that produces reviewable evidence. Regulatory approval, independent validation, legal review, and accountable human sign-off stay with people.
PASS / FAIL
promote reviewed failures
Golden datasets**in Langfuse
Experiment run
model, prompt variant, or agent
Prompt management
versioned prompts
Evaluators
deterministic + LLM-as-a-judge
Run-level gate
Portal · exports · CI exit code
Production traces
Annotation queue
human review
- The pipeline is a set of Python scripts built on four Langfuse features: datasets, experiments, prompt management, and annotation queues.
Everything under test goes through the same loop. The target of a run is either a model with a prompt, which serves as a baseline and for model comparisons, or one of three registered agents, which are the systems a review board would actually look at: 10k-analyst, sentiment-triage, and advisory-draft. Each run scores the target's outputs on a golden dataset, and a run-level gate turns the scores into a single PASS or FAIL. The verdicts surface in a reviewer-facing portal, in exported evidence packages, and as CI exit codes. The rest of this post walks the loop from left to right.
The pipeline uses three datasets:
| Dataset | Source | Items | What it tests | Gates |
|---|---|---|---|---|
| FinanceBench | PatronusAI/financebench | 150 | Financial Q&A from SEC filings: numerical extraction and reasoning | Model baselines and the 10k-analyst agent |
| Financial PhraseBank | ChanceFocus/en-fpb | ~4,850 | Sentiment classification of financial news | Model baselines and the sentiment-triage agent |
| Advisory Adversarial | ships with the repository | 10 | Client-update briefs that tempt a draft into prohibited phrasing | The advisory-draft agent |
All three are loaded into Langfuse as datasets, with each item containing an input (the question or text), an expected output (the correct answer or label), and metadata (source, question type, reasoning type):
from langfuse import Langfuse
from datasets import load_dataset
langfuse = Langfuse()
ds = load_dataset("PatronusAI/financebench", split="train")
for item in ds:
langfuse.create_dataset_item(
dataset_name="certification/financebench-v1",
input={
"question": item["question"],
"company": item.get("company", ""),
"evidence": [ev.get("evidence_text", "") for ev in item.get("evidence", [])],
},
expected_output={
"answer": item["answer"],
"justification": item.get("justification", ""),
},
metadata={
"question_type": item.get("question_type", ""),
"question_reasoning": item.get("question_reasoning", ""),
"source": "PatronusAI/financebench",
},
)The question_reasoning field records how each answer should be derived. The agent section below uses it as ground truth for checking whether an agent reached its answer the right way.
Pro tip: load every dataset in two sizes. The setup script's --sample
flag creates 10-item versions (certification/financebench-sample) that run
end to end in a couple of minutes; we use those in live demos and while
iterating on evaluators and prompts. Formal gate runs are scored against the
full set (certification/financebench-v1). The task, evaluators, and
thresholds are identical for both sizes, so there is no configuration drift,
and only full runs count as review evidence.
dataset.run_experiment() expects a task: a function that receives one dataset item and returns the output to be scored. Our task sends the item to the model under test. For FinanceBench items that include evidence excerpts from SEC filings, it puts the source documents into the prompt as context, simulating a RAG pipeline:
def create_certification_task(model, endpoint, api_key):
def task(*, item, **kwargs):
inp = item.input if hasattr(item, "input") else item.get("input", {})
question = inp.get("question", inp.get("text", ""))
evidence = inp.get("evidence", [])
if evidence and any(evidence):
context = "\n\n".join(
f"--- Source Document Excerpt {i} ---\n{ev}"
for i, ev in enumerate(evidence, 1) if ev
)
prompt = (
f"You are a financial analyst. Answer the question using ONLY the "
f"provided source document excerpts. Be precise with numbers.\n\n"
f"{context}\n\n--- Question ---\n{question}"
)
else:
prompt = question
return call_model(prompt, model, endpoint, api_key)
return taskThe analyst instructions in this snippet are only a fallback. The repository fetches the template from Langfuse prompt management by name, so every run records which prompt version it ran against. When a result is questioned months later, the exact wording is part of the evidence.
The task is passed to run_experiment(), which handles concurrency, tracing, and evaluation in one call:
from langfuse import get_client
langfuse = get_client()
dataset = langfuse.get_dataset("certification/financebench-v1")
result = dataset.run_experiment(
name="financebench-v1",
run_name="claude-sonnet-4-6-20260715",
task=create_certification_task(model, endpoint, api_key),
evaluators=[
numerical_accuracy_evaluator,
exact_match_evaluator,
regulatory_compliance_evaluator,
response_completeness_evaluator,
groundedness_evaluator,
],
run_evaluators=[
average_score_evaluator("numerical_accuracy"),
average_score_evaluator("groundedness"),
certification_gate("numerical_accuracy", threshold=0.85),
],
max_concurrency=5,
)Every model call is traced in Langfuse and scored by the evaluators. Running the same dataset against multiple models gives a side-by-side comparison in the Langfuse UI, per item and per score:
The pipeline mixes two kinds of evaluators because they catch different failure modes.
Five deterministic evaluators (fast, cheap, reproducible):
Numerical accuracy extracts numbers from the output and compares them to the expected answer with a 5% tolerance, handling currency symbols, commas, percentages, and rounding differences.
- Exact match checks whether the expected answer appears verbatim in the output.
- Sentiment classification compares the sentiment label in the output to the ground-truth label from Financial PhraseBank. This is a plain string comparison; no judge model is involved.
- Regulatory compliance scans outputs for prohibited phrases like "guaranteed returns" or "risk-free investment."
- Response completeness scores response length and structural formatting. Despite the name it checks structure; whether the content answers the question is covered by the judge below.
One LLM-as-a-judge evaluator** covers the dimension the deterministic checks cannot see: groundedness. The judge model receives the question, the source evidence, and the model's answer, and scores whether the answer is supported by the evidence, following a financial-auditor rubric. The score lands on the trace with the judge's reasoning attached. Here it catches an answer that padded a failed calculator step with invented figures:
An example run from the 10-item FinanceBench sample shows why both kinds are needed. Claude Haiku scored 60% on numerical accuracy and 97% on groundedness. Wrong numbers make the model unusable either way, but the pair of scores locates the failure: Haiku reads the evidence faithfully and fails specifically at numerical reasoning. The fix is a calculator tool or a stronger model rather than a different retrieval setup, and that level of nuance is what a model risk reviewer needs from a report.
All evaluators follow the same Langfuse signature. Here is numerical accuracy, condensed from the repository:
from langfuse import Evaluation
def numerical_accuracy_evaluator(*, output, expected_output, **kwargs):
answer = expected_output.get("answer", "")
expected_nums = _extract_numbers(answer)
if not expected_nums:
# Not a numerical question: fall back to string containment
matched = answer.strip().lower()[:20] in str(output).strip().lower()
return Evaluation(name="numerical_accuracy", value=1.0 if matched else 0.0)
matched, detail = _numbers_match(expected_nums, _extract_numbers(str(output)))
return Evaluation(
name="numerical_accuracy",
value=1.0 if matched else 0.0,
comment=detail,
)On top of the item-level evaluators, a run-level evaluator named certification_gate produces the binary verdict. Run-level evaluators receive the full list of item results, so the gate averages the relevant score across the run and compares it to the threshold:
def certification_gate(score_name, threshold=0.85):
def evaluator(*, item_results, **kwargs):
values = [
ev.value
for result in item_results
for ev in result.evaluations
if ev.name == score_name and ev.value is not None
]
avg = sum(values) / len(values) if values else 0.0
passed = avg >= threshold
return Evaluation(
name="certification_result",
value=1.0 if passed else 0.0,
comment=f"{'PASSED' if passed else 'FAILED'}: avg {score_name}={avg:.1%} (threshold={threshold:.0%})",
)
return evaluatorA finished run can be exported as a review-ready evidence package in Markdown, JSON, or CSV:
python setup_datasets.py --dataset financebench --sample
python run_certification.py --dataset certification/financebench-sample --model claude-sonnet-4-6
python export_results.py --dataset certification/financebench-sample --format markdownThe model-level runs above are baselines. They answer questions like "which model do we build on" and "did the model swap regress anything." The deployment decision is made on something larger: nobody deploys Claude Sonnet, they deploy the 10-K analysis assistant built on it, and that assistant plans, retrieves evidence, calls a calculator tool, and composes an answer. The pipeline therefore registers agents as first-class targets and runs them through the same datasets, evaluators, and gate as the models.
Two things change for agents. First, each agent runs as a multi-step task per dataset item, with one nested span per step, so a reviewer can open any item in Langfuse and see which tool the agent invoked and what it returned. Here is a 10k-analyst item with the calculate step selected — the tool call's input and its returned value are right there in the trace:
Second, instead of a single accuracy threshold, each agent has its own multi-dimensional gate: every dimension must pass at once or the run fails.
| Agent | Steps (spans) | Gate (all dimensions must pass) |
|---|---|---|
10k-analyst | plan → retrieve-evidence → calculate → compose | accuracy ≥ 85%, groundedness ≥ 80%, compliance = 100%, tool use ≥ 90% |
sentiment-triage | classify → rationale → route | sentiment accuracy ≥ 85%, compliance = 100%, tool use = 100% |
advisory-draft | analyze → draft → compliance-self-check | groundedness ≥ 80%, compliance = 100%, completeness ≥ 70%, tool use = 100% |
python run_usecase_certification.py --list
python run_usecase_certification.py --use-case 10k-analyst \
--dataset certification/financebench-sample --queue-failuresTwo of these dimensions deserve a closer look.
Tool trajectory is an evaluation dimension. The tool_use_correctness evaluator uses the dataset's question_reasoning metadata to check that numerical questions were answered through the calculator tool. An agent that guesses the right ratio without computing it gets the answer marked correct and the trajectory marked wrong, and the trajectory fails it.
Compliance requires 100%. For advisory-draft, a single prohibited phrase fails the entire run. To prove that this gate does its job, the repository ships the Advisory Adversarial dataset from the table above: ten client-update briefs, three compliant controls and seven that each tempt a distinct failure mode a compliance officer would recognize, from guaranteed profits to a hint of material non-public information. Unlike the two public benchmarks, this set is curated by hand and designed to grow: the feedback loop at the end of this post promotes reviewed production failures into it.
The people who approve models do not read traces. Risk officers and business owners want one screen that answers three questions: what passed, against which dataset, and when it was last checked. The repository ships the Certification Portal, a small React dashboard on a FastAPI backend, that renders exactly that: a status table with the latest verdict for every model, prompt variant, and agent.
Every number on that screen is fetched live from Langfuse's public REST API (datasets, runs, traces, scores), and every row deep-links back to the underlying traces in Langfuse as the source of truth.
Each row links to its run view, which shows the evaluator scores behind the verdict: mean, min, max, and pass rate for every dimension. The PASS/FAIL badge comes from the run-level gate score. The threshold tile shows the primary metric's bar (85% here), while an agent's per-dimension thresholds from the table above are enforced inside the gate evaluator itself:
One more click reaches the per-item view: every dataset item scored across all dimensions, each linking to its trace in Langfuse. When an item misses the numerical-accuracy check, you open its trace and read what the agent did:
Because gate runs repeat, each dataset keeps a run history. This is the advisory-draft agent on the adversarial dataset; the dips are the deliberately tempted runs failing the gate between clean passes:
The portal reads everything through the public API via the typed Python SDK; the Metrics API and scheduled exports cover aggregate and warehouse workflows. Langfuse stays the source of truth, and the portal is a domain-specific view for the people making the approval decision.
A gate that runs once is a snapshot. Two feedback loops keep the evidence current: production failures flow back into the golden datasets, and prompt changes flow back through the gate.
Production feeds the golden datasets. A monitoring script scores live traces for compliance and completeness and routes violations to a Langfuse annotation queue for human review. A concrete example: a draft generated in production calls a fund "a safe bet." The monitor flags the phrase, the trace lands in the review queue, and a reviewer scores it and records what the draft should have said.
The reviewed failure can then be promoted into the golden dataset as a new item. The reviewer supplies the correct answer; the pipeline never copies the suspect output as ground truth. The next run then regression-tests exactly the failure production found. Growing a dataset changes what its scores mean, so promotions are deliberate reviewer actions rather than automation, and because every run records which items it scored, older results stay traceable. Score trends are only compared between runs on the same dataset state.
Prompt changes re-run the gate. Langfuse's GitHub integration can dispatch a repository event whenever a prompt changes. In this repository, once the integration and repository secrets are configured, promoting a prompt to the production label triggers a GitHub Actions workflow that runs the affected gate with a strict exit code. If the new prompt version scores below a threshold, the gate fails, the workflow fails, and the release is blocked until a reviewer looks at it.
This pipeline is engineering infrastructure; it does not make anything compliant by itself. What applies to a given system depends on the institution, the jurisdiction, and how each framework classifies that system. Across the major frameworks, though, the recurring engineering requirement is the same: documented testing before deployment, complete logs, documented human review, and monitoring that continues after release. That is the evidence this pipeline produces.
| Framework | In short | Where the pipeline can help |
|---|---|---|
| Fed SR 26-2 / OCC 2026-13 | Revised US model risk guidance. Generative and agentic AI are explicitly out of scope, but banks are told to govern them with appropriate controls | Its validation and monitoring patterns are a design reference for an internal LLM gate like this one |
| PRA SS1/23 | UK model risk principles for banks, covering AI and ML techniques: governance, validation, ongoing monitoring | Versioned gate runs as validation and revalidation evidence |
| EU AI Act | Logging, human oversight, and post-market monitoring for high-risk uses such as creditworthiness assessment | Traces for logging, annotation queues for documented human review, monitoring for the post-market process |
| DORA | ICT and third-party risk management for EU financial entities | Operational evidence on model API availability, degradation, and incidents |
| NIST AI RMF | Voluntary framework: documented testing before deployment and monitoring in use | Datasets, evaluators, gates, and run history for Measure; review queues for Manage |
The institution keeps what it always kept: applicability decisions, policy, independent challenge, approvals, and legal compliance.
- Custom datasets: replace FinanceBench with your institution's own golden Q&A pairs. The setup script accepts any JSON file with input, expected output, and metadata fields.
- Domain-specific evaluators: add checks for your terminology, formatting requirements, or regulatory constraints.
- Prompt variants: run the same model under a specialized system prompt and compare it to the baseline. In our runs, a finance-expert system prompt lifted Claude Sonnet from 90% to 100% numerical accuracy on the FinanceBench sample; both rows are visible in the portal screenshot above.
- Your own agents: where a prompt variant changes only the prompt, an agent adds steps and tools. Register one with its steps and gate thresholds, and it gets the same nested tracing and multi-dimensional gate as the built-in three.
- CI/CD integration: a pytest gate and the GitHub Actions workflows fail your build when a gate run fails, so model and prompt approvals become part of the deployment pipeline.
The full code, including sample data for offline testing and the CI workflows, is in the langfuse-llm-certification-finance repository. We built it because manual evidence could not keep up with the pace of LLM systems: a weeks-long approval often lands after the prompt or model it tested has been replaced. A scripted gate produces the same evidence in minutes, every time something changes.
Was this page helpful?
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み