ストーリー
Observabilityの3本柱
エージェントにおける3本柱
| 柱 | 従来のシステム | エージェントシステム |
|---|---|---|
| ログ | アプリケーションログ | LLMの入出力、ツール呼び出し、判断理由 |
| トレース | リクエストの経路追跡 | エージェントの思考→行動→観察の全経路 |
| メトリクス | レイテンシ、エラー率 | トークン使用量、ツール成功率、ステップ数 |
LangSmithによるトレース
LangSmithとは
LangSmithは、LangChain社が提供するLLMアプリケーションのObservabilityプラットフォームです。
LangSmithのトレースビュー:
[Agent Run] ─── 全体のレイテンシ: 4.2秒、トークン: 2,340
├── [LLM Call] classify_intent ── 0.8秒、tokens: 320
│ ├── Input: "注文ORD-12345の配送状況を..."
│ └── Output: "order_inquiry"
├── [Tool Call] search_orders ── 0.3秒
│ ├── Input: {order_id: "ORD-12345"}
│ └── Output: {status: "shipped", ...}
├── [Tool Call] track_shipment ── 1.2秒
│ ├── Input: {tracking: "JP1234567890"}
│ └── Output: {status: "配達中", ...}
└── [LLM Call] generate_response ── 1.9秒、tokens: 2,020
├── Input: [context + messages]
└── Output: "ご注文ORD-12345は..."
セットアップ
import os
# LangSmithの設定
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "ls_..."
os.environ["LANGCHAIN_PROJECT"] = "netshop-cs-agent"
# これだけで、LangChain/LangGraphの全呼び出しが自動トレースされる
カスタムトレースの追加
from langsmith import traceable
@traceable(name="validate_refund_request")
def validate_refund_request(order_id: str, amount: int) -> dict:
"""返金リクエストのバリデーション(カスタムトレース)"""
# この関数の入出力がLangSmithに記録される
if amount > 50000:
return {"valid": False, "reason": "返金上限超過"}
return {"valid": True}
Langfuseによるトレース
Langfuseとは
Langfuseはオープンソースのオブザーバビリティプラットフォームです。セルフホストが可能です。
from langfuse import Langfuse
from langfuse.callback import CallbackHandler
# Langfuseの設定
langfuse = Langfuse(
public_key="pk-...",
secret_key="sk-...",
host="https://cloud.langfuse.com" # またはセルフホストURL
)
# LangChain/LangGraphとの統合
langfuse_handler = CallbackHandler()
# LangGraphのinvokeにコールバックを渡す
result = app.invoke(
input_data,
config={"callbacks": [langfuse_handler]}
)
記録すべきメトリクス
エージェントの主要KPI
| メトリクス | 説明 | 監視ポイント |
|---|---|---|
| レイテンシ | ユーザー入力→最終回答の時間 | 目標: 10秒以内 |
| トークン使用量 | LLM呼び出しあたりのトークン数 | コスト管理 |
| ツール成功率 | ツール呼び出しの成功/失敗比率 | 95%以上を目標 |
| ステップ数 | タスク完了までの平均ステップ数 | 多すぎると非効率 |
| エスカレーション率 | 人間に引き継いだ割合 | 低いほどエージェントが自律的 |
| ユーザー満足度 | フィードバックスコア | CSAT目標値 |
メトリクス収集の実装
interface AgentMetrics {
runId: string;
startTime: Date;
endTime: Date;
totalLatencyMs: number;
totalTokens: number;
llmCalls: number;
toolCalls: number;
toolSuccessRate: number;
stepCount: number;
escalated: boolean;
finalStatus: "success" | "partial" | "escalated" | "error";
}
class MetricsCollector {
private metrics: Partial<AgentMetrics> = {};
startRun(runId: string): void {
this.metrics = { runId, startTime: new Date(), llmCalls: 0, toolCalls: 0 };
}
recordLLMCall(tokens: number): void {
this.metrics.llmCalls = (this.metrics.llmCalls ?? 0) + 1;
this.metrics.totalTokens = (this.metrics.totalTokens ?? 0) + tokens;
}
recordToolCall(success: boolean): void {
this.metrics.toolCalls = (this.metrics.toolCalls ?? 0) + 1;
}
endRun(status: AgentMetrics["finalStatus"]): AgentMetrics {
this.metrics.endTime = new Date();
this.metrics.totalLatencyMs =
this.metrics.endTime.getTime() - (this.metrics.startTime?.getTime() ?? 0);
this.metrics.finalStatus = status;
return this.metrics as AgentMetrics;
}
}
デバッグ手法
トレースベースのデバッグ
問題: エージェントが間違ったツールを選択している
デバッグ手順:
1. LangSmith/Langfuseでトレースを確認
2. LLM Callの入力を確認 → ツール説明文が曖昧ではないか?
3. LLMの出力を確認 → どのツールを選択したか?
4. ツールの説明文を修正してA/Bテスト
5. 修正後のトレースで改善を確認
ダッシュボード設計
| パネル | 表示内容 |
|---|---|
| リアルタイムモニター | 現在処理中のエージェント数、平均レイテンシ |
| エラーレート | 時系列のエラー率推移 |
| トークンコスト | 日次/月次のトークン使用量と推定コスト |
| ツール使用統計 | 各ツールの呼び出し回数と成功率 |
| エスカレーション | エスカレーション率と主な理由 |
まとめ
| ポイント | 内容 |
|---|---|
| Observabilityの3本柱 | ログ、トレース、メトリクスをエージェントに適用 |
| トレースツール | LangSmith(マネージド)、Langfuse(OSS/セルフホスト) |
| 主要KPI | レイテンシ、トークン使用量、ツール成功率、エスカレーション率 |
| デバッグ手法 | トレースを辿って問題の原因を特定 |
チェックリスト
- エージェントにおけるObservabilityの3本柱を理解した
- LangSmith / Langfuseによるトレースの設定方法を把握した
- エージェントの主要KPIとその監視ポイントを理解した
- トレースベースのデバッグ手法を把握した
次のステップへ
次は「エージェントテスト」を学びます。ユニットテスト、統合テスト、E2Eテストの戦略を理解しましょう。
推定読了時間: 30分