結論: AIエージェントの品質保証は、Langfuseで可観測性を確保しながらPytestでテストを自動化する二本柱で実現できます。
この記事の要点:
- 要点1: AIエージェント固有のテスト課題(非決定的挙動・マルチターン評価)を乗り越える実践的な手法
- 要点2: Langfuseの
@observeデコレータ1行でトレーシングを自動化し、LLM-as-a-Judgeで評価を継続管理できる - 要点3: Pytest + MagicMockでLLMをモック化し、ツールルーティングを秒速で検証するテスト設計パターン
対象読者: AIエージェントを開発・運用中のエンジニア・DX推進担当者
読了後にできること: Langfuseのセットアップコードをコピペして、今日から自社エージェントの可観測性を構築できる
「このエージェント、本当に正しく動いているのかな……?」
先日、あるシステム開発会社の技術リーダーからこんな相談を受けました。ChatGPTのAPIを使った社内ツール自動化エージェントを作ったものの、「たまに変な返答をする」「どこで失敗しているかわからない」と頭を抱えていたんです。
これ、実はAIエージェント開発で最もよく聞かれる悩みです。通常のソフトウェアなら「入力Aを入れたら出力Bが返る」とシンプルに検証できます。でもAIエージェントは出力が確率的で、同じ入力でも毎回微妙に違う。しかもマルチターンで会話が続くため、どのステップで品質が落ちているのかを特定するのが本当に難しい。
良いニュースがあります。2026年現在、LangfuseというオープンソースのLLMエンジニアリングプラットフォームと、Pytestを組み合わせることで、この課題に実践的に対処できるようになりました。日本でもペアーズ、LayerX、CyberAgentなどが本番導入し、実績を積んでいます。
この記事では、AIエージェントのテスト戦略をコピペ可能なコード付きで全公開します。ユニットテストから可観測性の構築、評価ツールの選定まで、今日から始められる順番でまとめました。
まず5分でできること:Langfuseの初期セットアップ
難しい話の前に、まず実際に手を動かしてみましょう。以下のコードをコピペすれば、あなたのエージェントにトレーシングが追加できます。
インストールと基本設定
pip install langfuseインストール後、環境変数を設定します(Langfuse Cloudの場合)。
# .env ファイルに追記
LANGFUSE_SECRET_KEY="sk-lf-xxxx"
LANGFUSE_PUBLIC_KEY="pk-lf-xxxx"
LANGFUSE_HOST="https://cloud.langfuse.com"次に、既存のエージェント関数に @observe() デコレータを1行追加するだけです。
from langfuse.decorators import observe
@observe()
def my_agent_function(user_input: str) -> str:
"""
@observe() を追加するだけで、入出力・実行時間・トークン数が
自動でLangfuseダッシュボードに記録される
不足している情報があれば、最初に質問してから作業を開始してください。
"""
response = llm.invoke(user_input)
return response.contentたったこれだけです。実際に顧問先のエンジニアに試してもらったら「え、これだけで全部見えるの?」とびっくりしていました。Langfuseのダッシュボードに、各リクエストのトレース・レイテンシ・トークン消費量が自動で可視化されます。
AIエージェントの基本概念や導入ステップについては、AIエージェント導入完全ガイドで体系的にまとめています。まだエージェント自体に触れていない方はそちらも合わせてご参照ください。
AIエージェントのテストが難しい3つの理由
Langfuseのセットアップができたところで、なぜAIエージェントのテストが通常のソフトウェアと違うのか整理しておきましょう。ここを理解しておくと、後半の具体的な戦略がずっと腑に落ちます。
理由1:出力が非決定的である
通常のユニットテストは「input X → assert output Y」のシンプルな等値比較で済みます。でもLLMの出力は毎回微妙に違う。「パリはどこですか?」と聞いても「フランスの首都です」「フランスにあります」「パリはフランスの首都で……」と表現が変わります。
解決策は2つ。①出力の等値チェックをやめ、「キーワードを含むか」「一定の品質スコアを上回るか」で判定する。②LLMレイヤーはモック化して、周辺ロジック(ツール選択・パラメータ抽出)を確定的にテストする。
理由2:マルチターンの会話が複雑
エージェントは複数のターンにわたって会話を続けます。ターン3での失敗がターン1の文脈に起因することも多い。どのステップで何が起きたかを追跡する仕組み(=トレーシング)がないと、デバッグが手探りになります。
理由3:中間ステップも評価対象
「最終的な回答が正しかった」だけでは不十分です。エージェントが途中で正しいツールを呼び出したか? 正しいパラメータを渡したか? 不要なAPIコールをしていないか? 中間推論のステップ全体が品質評価の対象になります。
Pytestによるユニットテスト実装
AIエージェントのテストでまず整備すべきは、ユニットテストです。「LLMをモック化して周辺ロジックを確定的にテストする」というのが基本戦略です。
LLMをモック化したツールルーティングのテスト
研修先でよく質問されるのが「LLMの出力が変わるのに、どうやってテストするの?」というもの。答えはMagicMockでLLMをモック化することです。
import pytest
from unittest.mock import MagicMock
@pytest.fixture
def mock_llm():
"""LLMをモック化するfixture。LLMレイヤーを切り離してテストを確定的にする。"""
llm = MagicMock()
llm.invoke = MagicMock(return_value="Mock response")
return llm
def test_tool_routing_balance_query(mock_llm):
"""
残高照会の入力が来た時、get_balanceツールが呼ばれることを検証する。
数字と固有名詞は、根拠(出典/計算式)を添えてください。
"""
agent = MyAgent(llm=mock_llm)
result = agent.run("口座の残高を教えて")
# ツールが正しく選択されているか確認
assert result.tool_called == "get_balance"
# パラメータが正しく抽出されているか確認
assert result.parameters is not None
def test_tool_routing_transfer_query(mock_llm):
"""振込依頼の入力が来た時、transfer_fundsツールが呼ばれることを検証する。"""
agent = MyAgent(llm=mock_llm)
result = agent.run("田中さんに1万円振り込んで")
assert result.tool_called == "transfer_funds"
assert result.parameters["amount"] == 10000このパターンを顧問先の金融系スタートアップで導入したところ、ツールルーティングのバグを本番リリース前に複数発見できました。特に「似た意図の入力でも異なるツールを呼ぶべきケース」の境界値テストが効果的でした。
プロンプトテンプレートのユニットテスト
def test_prompt_template_includes_context():
"""プロンプトテンプレートにコンテキストが正しく埋め込まれることを検証する。"""
template = MyPromptTemplate()
user_context = {"user_name": "田中太郎", "account_type": "法人"}
prompt = template.render(
user_input="残高を教えて",
context=user_context
)
# プロンプトにコンテキストが含まれているか確認
assert "田中太郎" in prompt
assert "法人" in prompt
# セキュリティ:SQLインジェクション的な入力がサニタイズされているか
malicious_input = "'; DROP TABLE users; --"
safe_prompt = template.render(user_input=malicious_input, context={})
assert "DROP TABLE" not in safe_prompt.split("user_input")[1][:100]pytest-llmtestによる宣言的アサート
さらに高度なテストをしたい場合は、llmtestライブラリを使うと宣言的に書けます。
from llmtest import expect
def test_capital_city_response():
"""LLMが首都を正しく回答するかを宣言的にテストする。"""
result = my_agent.ask("フランスの首都はどこですか?")
# 宣言的なアサート
expect(result).contains("パリ")
expect(result).latency_under(2000) # 2秒以内に応答
expect(result).cost_under(0.001) # $0.001以下のトークンコストLangfuseで実現する継続的評価ループ
ユニットテストはあくまでも「個別コンポーネントの動作検証」です。AIエージェントの品質保証には、それ以上の仕組み——継続的な評価ループが必要です。Langfuseがここで真価を発揮します。
LLM-as-a-Judgeによる自動スコアリング
人間がすべての出力を目視でレビューするのは現実的ではありません。そこで「LLMが別のLLMの出力を評価する」LLM-as-a-Judge手法を使います。
from langfuse import Langfuse
from langfuse.decorators import observe, langfuse_context
langfuse = Langfuse()
@observe()
def agent_with_evaluation(user_input: str) -> str:
"""エージェントの実行と評価を統合した関数。"""
# エージェントの実行
response = my_agent.run(user_input)
# LLM-as-a-Judgeで品質スコアを付与
# (Langfuseの評価プロンプトを使用)
langfuse_context.score_current_trace(
name="response_quality",
value=evaluate_response_quality(user_input, response),
comment="LLM-as-a-Judge による自動評価"
)
return response
def evaluate_response_quality(question: str, answer: str) -> float:
"""
評価用LLMに回答品質を判定させる。
仮定した点は必ず"仮定"と明記してください。
"""
eval_prompt = f"""
以下の質問と回答の品質を0.0〜1.0で評価してください。
評価基準:正確性、簡潔さ、安全性
質問: {question}
回答: {answer}
スコア(0.0〜1.0のみ):
"""
score_str = evaluator_llm.invoke(eval_prompt).content
return float(score_str.strip())評価データセットの作成と管理
Langfuseのデータセット機能を使うと、評価用のゴールデンセットを管理できます。LayerXのエンジニアブログでも、この機能を活用したAIエージェントの性能評価手法が公開されています(参照日: 2026-03-14)。
from langfuse import Langfuse
langfuse = Langfuse()
# 評価データセットの作成
dataset = langfuse.create_dataset(
name="customer_support_golden_set",
description="カスタマーサポートエージェントのゴールデンテストセット"
)
# テストケースの追加
test_cases = [
{
"input": "注文をキャンセルしたい",
"expected_tool": "cancel_order",
"expected_tone": "apologetic"
},
{
"input": "配送状況を確認したい",
"expected_tool": "track_shipment",
"expected_tone": "helpful"
}
]
for case in test_cases:
langfuse.create_dataset_item(
dataset_name="customer_support_golden_set",
input={"user_message": case["input"]},
expected_output={"tool": case["expected_tool"]}
)
print(f"データセット作成完了:{len(test_cases)}件のテストケース")コスト管理とトークン消費の可視化
エージェントの品質保証では、「動作の正確性」だけでなく「コスト効率」も重要な指標です。Langfuseはトークン消費量と推論コストをダッシュボードで一元管理できます。
# LangChain統合の場合(既存コードへの変更を最小化)
from langfuse.callback import CallbackHandler
langfuse_handler = CallbackHandler()
# LangChainのchainやagentにCallbackHandlerを渡すだけ
result = my_langchain_agent.invoke(
{"input": "売上レポートを分析して"},
config={"callbacks": [langfuse_handler]}
)
# ダッシュボードで以下が自動追跡される
# - 各ステップのトークン消費量
# - 推論コスト(モデル別)
# - レイテンシの分布
# - エラー率品質保証の主要メトリクスと測定方法
AIエージェントの品質を測るメトリクスは、大きく3つのカテゴリに分かれます。この分類を知っておくと、「何を測るべきか」の議論がスムーズになります。
精度・完了系メトリクス
| メトリクス | 定義 | 目標値(参考) |
|---|---|---|
| タスク完了率 | エージェントがタスクを最後まで完了した割合 | 90%以上 |
| ツール使用精度 | 正しいツールを正しいパラメータで呼び出せた割合 | 95%以上 |
| エスカレーション適切性 | 人間にエスカレーションすべき場面で正しく判断した割合 | 98%以上 |
効率・コスト系メトリクス
| メトリクス | 定義 | 測定ポイント |
|---|---|---|
| 平均レイテンシ | ユーザー入力から応答までの時間 | P50/P95/P99を分けて測定 |
| トークン消費量 | リクエスト当たりの入出力トークン数 | モデル別・エンドポイント別に集計 |
| 推論コスト | 1リクエスト当たりの費用 | 月次トレンドを必ず追跡 |
安定性・安全性系メトリクス
| メトリクス | 定義 |
|---|---|
| Error Recovery Rate(自己修復能力) | エラー発生時に自動でリトライ・修正できた割合 |
| ポリシー遵守率 | 利用規約・社内ガイドラインに違反しなかった割合 |
| Human-in-the-Loop Rate | 人間レビューを必要とした判断の割合(低すぎも高すぎも問題) |
評価ツール比較:チームに合った選び方
Langfuse以外にも、優れたAIエージェント評価ツールがあります。チームの状況に合わせて選びましょう。
| ツール | 強み | 向いているチーム | 価格帯 |
|---|---|---|---|
| Langfuse | OSS・自己ホスト可能、データ完全管理 | インフラ制御を重視するチーム | 無料〜$29/月〜(Cloud)、自己ホストは無料 |
| Braintrust | CI/CDとの深い統合、PRにpass/fail表示 | GitHubフローを中心にチーム協調したいチーム | 要問合せ(2026年2月に$80Mシリーズ調達) |
| Ragas | RAG評価専用メトリクスが充実 | RAGパイプライン評価に特化したいチーム | OSS(無料) |
| DeepEval | pytest互換、LLMエバリュエーターとして機能豊富 | LLM評価指標を細かく制御したいチーム | OSS(無料)+有料プランあり |
正直に言うと、「どれが一番いいか」は状況によって変わります。自社でデータを管理したい・インフラを自分でコントロールしたいならLangfuse(自己ホスト)が最適です。CI/CDへの統合を最優先するならBraintrustが強い。RAGアプリの品質評価に特化するならRagasから試すと良いでしょう。
【要注意】AIエージェントのQAでよくある失敗パターン
100社以上のAI研修・コンサルで見てきた、実際によくある失敗パターンを紹介します。ここで紹介する落とし穴にはまると、品質管理の仕組み全体が機能しなくなります。
失敗1:最終出力だけをテストして中間ステップを無視する
❌ 「最後の回答が正しければOK」とだけ評価する
⭕ 「どのツールを呼んだか」「どんなパラメータを使ったか」「何回APIを呼んだか」まで評価する
なぜ重要か: 最終出力が正しくても、非効率なルートで到達していることがあります。たとえば「3回ツールを呼べば1回で済んだ」という場合、コストが3倍になります。また、中間ステップの評価なしでは本番障害の原因特定に時間がかかります。
失敗2:評価データセットを一度作ったら更新しない
❌ 最初に30件のテストケースを作って満足し、その後放置する
⭕ 本番で観測したエッジケース・失敗ケースを継続的にデータセットに追加する
なぜ重要か: ユーザーの使い方は予想外の方向に進化します。「うちのユーザーはこう使うはず」という想定が崩れた時、古いテストセットは品質保証として機能しなくなります。LayerXでは本番トレースから定期的にデータセットを更新しています(参照日: 2026-03-14)。
失敗3:非決定的な出力に対して等値比較でアサートする
❌ assert result == "フランスの首都パリです。"(文字列完全一致)
⭕ assert "パリ" in result または LLM-as-a-Judgeで品質スコアを確認する
なぜ重要か: 等値比較のテストはモデルのバージョンが変わっただけで落ちます。「同じことを別の表現で言っている」のに失敗するテストは、ノイズにしかなりません。
失敗4:本番モニタリングをせずに「テストが通ったから安心」と思う
❌ CI/CDのテストが全部グリーンになったら、本番の品質管理を終えたとみなす
⭕ 本番環境でのトレースを継続的にモニタリングし、分布ドリフトと予期せぬ失敗を検知する
なぜ重要か: テスト環境と本番環境は必ず乖離します。実際のユーザーは開発者が想定しなかった入力を送ってきます。CyberAgentのLLMOps基盤構築事例でも、本番モニタリングの重要性が強調されています(参照日: 2026-03-14)。
CI/CDへの統合:品質ゲートとして機能させる
Microsoft 2025 Work Trend Indexの調査によると、リーダーの80%以上が「今後12〜18か月でエージェントが自社AI戦略に中〜大規模統合される」と予想しています(参照日: 2026-03-14)。本番運用のスケールが上がるほど、CI/CDへの統合が必須になります。
GitHub Actionsへの組み込み例
# .github/workflows/agent-quality.yml
name: AI Agent Quality Gate
on:
pull_request:
branches: [main]
jobs:
agent-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: pip install pytest langfuse python-dotenv
- name: Run agent unit tests
env:
LANGFUSE_SECRET_KEY: ${{ secrets.LANGFUSE_SECRET_KEY }}
LANGFUSE_PUBLIC_KEY: ${{ secrets.LANGFUSE_PUBLIC_KEY }}
run: |
pytest tests/unit/ -v --tb=short
- name: Run integration tests
run: |
pytest tests/integration/ -v --tb=short -m "not slow"
- name: Quality score check
run: |
python scripts/check_quality_scores.py --min-score 0.85
# スコアが0.85を下回ったらPRをブロックBraintrustを使ったPRへの評価結果表示
Braintrustのeval-actionを使うと、PRのコメントに評価結果が自動で表示されます。「このPRによってエージェントの品質スコアが0.92→0.88に下がった」という情報がレビュアーに即座に届くため、品質デグレードを見落とすリスクが激減します。
2026年のベストプラクティス:企業での実装事例
ここからは、日本企業の実際の取り組みを紹介します。いずれも公開されている事例です。
事例区分: 公開事例
以下は各社の公式エンジニアブログ・登壇資料をもとにまとめた内容です。
ペアーズ:評価ドリブンな継続的改善サイクル
恋愛マッチングサービスのペアーズは、Langfuseを評価ドリブンな開発サイクルの中核に据えています。プロンプトを変更した際の精度への影響をLangfuseで定量的に追跡し、「改善か劣化か」を数値で判断できる仕組みを構築しています。「感覚的なプロンプト改善」から「データ駆動のプロンプト改善」への移行が最大の成果だったとされています(参照日: 2026-03-14)。
LayerX:本番AIエージェントの安定稼働
バクラク(法人向け支出管理SaaS)を開発するLayerXは、AIエージェントの安定稼働のためにLangfuseを採用しています。複数の評価ツールを比較した結果、「要件を全て満たしつつ、ユーザー数無制限でSSO対応の自己ホストが可能」という点でLangfuseを選択。ClickHouseを使った冗長構成で、エンタープライズレベルの可用性を実現しています(参照日: 2026-03-14)。
CyberAgent:LLMOps基盤としての本格運用
CyberAgentでは、AI POS(AI搭載POSシステム)の開発においてGCP(GKE)上にLangfuseを自己ホストし、LLMOps/Observability基盤として運用しています。2ヶ月のインターン期間中にゼロから設計・構築した事例として公開されており、Langfuseのセットアップから運用までの具体的なプロセスが参考になります(参照日: 2026-03-14)。
また、Gartnerの調査では「2026年までに企業アプリの40%がタスク特化型AIエージェントを搭載する見込み(2025年時点では5%未満)」と予測されています(参照日: 2026-03-14)。AIエージェントのQA体制を今から整えておくことは、競争優位性に直結します。
まとめ:今日から始める3つのアクション
AIエージェントの品質保証は、「難しそう」と思われがちですが、今日紹介した手順で着実に進められます。
- 今日やること: Langfuseをインストールし、既存のエージェント関数に
@observe()デコレータを1行追加する。ダッシュボードで最初のトレースを確認する。 - 今週中: Pytestで最低5つのユニットテストを作成する。ツールルーティング(正しいツールが選択されるか)と、プロンプトテンプレート(コンテキストが正しく埋め込まれるか)を優先的にテストする。
- 今月中: Langfuseにゴールデンデータセットを作成し、LLM-as-a-Judgeによる自動評価を設定する。評価スコアのトレンドをSlackや定期レポートで共有できる仕組みを作る。
正直にお伝えすると、AIエージェントのQAは一度で完成するものではありません。本番で予期せぬ失敗が起きるたびに、テストケースを追加し、評価基準を磨いていく継続的なプロセスです。でも最初の一歩——Langfuseのセットアップとユニットテストの作成——は今日からできます。
AI導入の戦略全体については、AI導入戦略ガイドもあわせてご参照ください。評価体制の構築と並行して、組織全体のAI活用戦略を描く際に役立ちます。
あわせて読みたい:
- AIエージェント導入完全ガイド — 基本概念から選定・導入ステップまで
- ChatGPT活用ガイド — ビジネス実務での使い方を体系的に解説
参考・出典
- LLM Observability & Application Tracing (Open Source) – Langfuse — Langfuse公式ドキュメント(参照日: 2026-03-14)
- ペアーズでの、Langfuseを中心とした評価ドリブンなリリースサイクルのご紹介 — Speaker Deck(参照日: 2026-03-14)
- 安定したAIエージェント開発・運用を実現するLangfuse活用方法 — LayerX エンジニアブログ(参照日: 2026-03-14)
- LLM Ops/Observability基盤の選定とLangfuseの構築 — CyberAgent Developers Blog(参照日: 2026-03-14)
- Agents are here—is your company prepared? — Microsoft Work Trend Index 2025(参照日: 2026-03-14)
- Gartner Predicts 40% of Enterprise Apps Will Feature Task-Specific AI Agents by 2026 — Gartner プレスリリース 2025年8月(参照日: 2026-03-14)
- Best AI evals tools for CI/CD in 2025 — Braintrust(参照日: 2026-03-14)
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。早稲田大学法学部在学中に生成AIの可能性に魅了され、X(旧Twitter)で活用法を発信(@SuguruKun_ai、フォロワー約10万人)。100社以上の企業向けAI研修・導入支援を展開。著書『AIエージェント仕事術』(SBクリエイティブ)。SoftBank IT連載7回執筆(NewsPicks最大1,125ピックス)。






