LLMアプリを本番環境にリリースした後、何を監視すればいいか把握できていますか。従来のWebアプリとは異なり、LLMアプリにはAPIコスト・レイテンシ・ハルシネーション率・プロンプトの品質など、固有の指標を継続的に追う必要があります。この記事では、LLMアプリのオブザーバビリティ設計を具体的に解説します。
LLMモニタリングで追跡すべき指標
LLMアプリの監視は「コスト」「パフォーマンス」「品質」の3軸で設計します。それぞれ何を見ればいいか整理しておきましょう。
コスト指標
- 入力トークン数 / 出力トークン数(1リクエストあたり・1日あたり)
- API費用の推移(モデル・機能・ユーザーセグメント別)
- コスト異常の検知(突然のスパイクはプロンプトインジェクション等の兆候)
パフォーマンス指標
- TTFT(Time to First Token):ストリーミング開始までの時間
- 全体レイテンシ(P50・P95・P99)
- エラー率(429 Rate Limit・500 Server Error等)
品質指標
- ユーザーフィードバック(👍👎)の比率
- LLM-as-judgeによる自動品質評価スコア
- ハルシネーション検出率
- コンテキスト利用率(RAGの場合:取得ドキュメントが実際に使われているか)
Langfuseの導入
LangfuseはオープンソースのLLMオブザーバビリティプラットフォームです。セルフホスティングまたはクラウドサービスとして使えます。デコレータを一つ付けるだけでトレースが自動的に記録される点が便利です。
pip install langfuse anthropic
# .env
LANGFUSE_PUBLIC_KEY=pk-...
LANGFUSE_SECRET_KEY=sk-...
LANGFUSE_HOST=https://cloud.langfuse.com # セルフホストの場合は自前のURL
import anthropic
from langfuse import Langfuse
from langfuse.decorators import observe, langfuse_context
langfuse = Langfuse()
client = anthropic.Anthropic()
@observe() # このデコレータでLangfuseにトレースが送られる
def generate_response(user_message: str, session_id: str) -> str:
langfuse_context.update_current_trace(
session_id=session_id,
tags=["production", "chat"]
)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": user_message}]
)
text = response.content[0].text if response.content else ""
# メタデータを記録
langfuse_context.update_current_observation(
usage={
"input": response.usage.input_tokens,
"output": response.usage.output_tokens,
}
)
return text
構造化ログの実装
Langfuse等のツールを使わない場合は、構造化ログでLLMの動作を記録しましょう。JSON形式で出力すればCloudWatch LogsやDatadogで検索しやすくなります。
import json
import time
import logging
from dataclasses import dataclass, asdict
from typing import Optional
@dataclass
class LLMLog:
timestamp: str
model: str
user_id: Optional[str]
session_id: str
input_tokens: int
output_tokens: int
latency_ms: int
cost_usd: float
error: Optional[str] = None
quality_score: Optional[float] = None
logger = logging.getLogger("llm")
logger.setLevel(logging.INFO)
# JSON形式でログ出力(CloudWatch Logs・Datadogで検索しやすい)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(message)s'))
logger.addHandler(handler)
def log_llm_call(log: LLMLog):
logger.info(json.dumps(asdict(log)))
# 使用例
start = time.time()
try:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": user_message}]
)
latency = int((time.time() - start) * 1000)
# Claude Sonnet 4.6の概算コスト(実際は公式料金を参照)
input_cost = response.usage.input_tokens * 3 / 1_000_000
output_cost = response.usage.output_tokens * 15 / 1_000_000
log_llm_call(LLMLog(
timestamp=time.strftime("%Y-%m-%dT%H:%M:%SZ"),
model="claude-sonnet-4-6",
user_id=user_id,
session_id=session_id,
input_tokens=response.usage.input_tokens,
output_tokens=response.usage.output_tokens,
latency_ms=latency,
cost_usd=input_cost + output_cost,
))
except Exception as e:
log_llm_call(LLMLog(
timestamp=time.strftime("%Y-%m-%dT%H:%M:%SZ"),
model="claude-sonnet-4-6",
user_id=user_id,
session_id=session_id,
input_tokens=0,
output_tokens=0,
latency_ms=int((time.time() - start) * 1000),
cost_usd=0,
error=str(e),
))
raise
LLM-as-judgeによる品質自動評価
実は、LLMを使ってLLMの出力品質を自動評価できます。評価用の安いモデル(例:claude-haiku)を使えば、コストを抑えながら継続的な品質監視が実現します。
def evaluate_response_quality(
question: str,
context: str,
answer: str,
eval_model: str = "claude-haiku-4-5-20251001"
) -> dict:
"""回答品質を0-10のスコアで評価する"""
prompt = f"""以下のQAペアの品質を評価してください。
質問: {question}
コンテキスト: {context}
回答: {answer}
以下の観点で各10点満点で評価し、JSONで返してください:
- faithfulness: コンテキストに基づいた回答か(ハルシネーションがないか)
- relevance: 質問に的確に答えているか
- completeness: 必要な情報を網羅しているか
JSON形式のみ出力してください:
{{"faithfulness": 数値, "relevance": 数値, "completeness": 数値, "overall": 数値}}"""
response = client.messages.create(
model=eval_model,
max_tokens=256,
messages=[{"role": "user", "content": prompt}]
)
text = response.content[0].text
return json.loads(text)
アラートの設定
監視の仕上げは、異常を自動検知するアラートの設定です。次の4つを最低限設定しておきましょう。
- コストアラート:1時間のAPI費用が閾値を超えたら通知
- エラー率アラート:5分間のエラー率が5%を超えたら通知
- レイテンシアラート:P95レイテンシが10秒を超えたら通知
- 品質アラート:LLM-as-judgeのスコアが閾値を下回ったら通知
Datadog・CloudWatch・Grafana等の監視ツールのメトリクスにログを送り、アラートを設定します。
まず構造化ログとコストアラートから始めよう
LLMアプリのモニタリングはコスト・パフォーマンス・品質の3軸で設計します。Langfuseなどの専用ツールを使えばトレーシングが自動化されます。まず取り組むなら、構造化ログの出力とコスト異常・エラー率のアラート設定から始めるのが現実的です。品質監視はLLM-as-judgeで自動化することで、継続的な改善サイクルを回せます。
よくある質問
Langfuseのセルフホスティングとクラウド版の違いは?
クラウド版は無料枠(月50,000イベント)で始められ、セットアップが不要です。セルフホスティングはDockerで簡単に立ち上げられ、データを自社インフラに保持できます。機密性の高いプロンプト・ユーザーデータを扱う場合はセルフホスティングをお勧めします。
モニタリングのオーバーヘッドはLLMのレイテンシに影響しますか?
Langfuseは非同期でデータを送信するため、通常レイテンシへの影響は1ms未満です。構造化ログも同様に非同期処理することでオーバーヘッドを最小化できます。

コメント