ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

Datadog LLM Observability で custom evaluation を使ってみた

こんにちは!本記事は、Datadog の LLM Observability 機能において、custom evaluation を利用して独自の評価指標を送信した例を紹介します。

この記事は Datadog Advent Calendar 2024 10日目の記事です。

LLM Observability 概要

LLM Observability は、Datadog が提供する LLM(Large Language Model)アプリケーションの観測機能です。
OpenAI や Azure OpenAI、Anthropic といった様々な LLM プロバイダに対するプロンプト・レスポンスを可視化・分析できます。
これにより、LLM に関する以下のような観点での観測が容易になります:

  • LLM への入力(prompt)と出力(response)のトレース化
  • トークン使用量、応答時間、成功・失敗ステータスの可視化
  • ダッシュボード上での総合的な分析

Datadog LLM Observability 概要ページ

さらに、Datadog LLM Observability では、evaluation(評価)を送信することで、モデルの回答が正しいかどうか、ビジネスロジック的に望ましい回答になっているかなどの独自指標を可視化できます。

custom evaluation とは

custom evaluation とは、LLM の応答結果を独自基準で評価するための仕組みです。
例えば、LLM が出した回答が正解か不正解か、あるいは特定の条件を満たすかどうかを、自分たちで定義したロジックで判定し、その結果を Datadog に送信することで、後からダッシュボード上で分析・可視化できます。

Python SDK であれば利用は簡単ですが、Application が Python でない場合は API 経由で直接 JSON を POST することで評価メトリクスを送信可能です。

docs.datadoghq.com

TypeScript での実装例(抜粋と解説)

以下は、TypeScript から Datadog LLM Observability に独自の評価メトリクスを送信する例の一部抜粋です。

// custom evaluation metric を送信する関数例
export async function submitEvalMetric(
  spanId: string,       // LLM要請に対応するスパンID
  traceId: string,      // トレースID
  timestamp_ms: number, // 評価を行う時刻(ミリ秒)
  evalResponse: string, // "1" なら正解、"0" なら不正解などの独自評価値
  DATADOG_API_KEY: string,
) {
  // "1" -> "true", "0" -> "false" といった形で評価値を変換
  const categorical_value = evalResponse === "1" ? "true" : "false";

  // Datadog へ送信する JSON ボディ
  // metric_type="categorical" とすることで分類メトリクスとして送信
  // label="Answered" は評価対象の指標名
  const body = {
    data: {
      type: "evaluation_metric",
      attributes: {
        metrics: [
          {
            span_id: spanId,
            trace_id: traceId,
            ml_app: "your-llm-app",         // モニタリング中のアプリ名
            timestamp_ms: timestamp_ms,
            metric_type: "categorical",
            label: "Answered",
            categorical_value: categorical_value,
          },
        ],
      },
    },
  };

  const res = await fetch(
    "https://api.datadoghq.com/api/intake/llm-obs/v1/eval-metric",
    {
      method: "POST",
      headers: {
        "DD-API-KEY": DATADOG_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    },
  );

  if (res.status !== 202) {
    const responseBody = await res.text();
    console.error(
      `Failed to send evaluation metric to Datadog. status:${res.status} body:${responseBody}`,
    );
  } else {
    console.log(`Successfully sent evaluation metric to Datadog. status:${res.status}`);
  }
}

ポイント解説

metric_type に "categorical" を指定すると、true/false だったり、ラベル分けによる評価が行えます。 今回は label フィールドで「Answered」という指標名をつけ、回答できたかの True / False を送信しました。

metric_type は他に score もあり、この場合 score_value で number を送信できます。

なお、この 0 or 1 を判定するのに LLM as a Judge を利用しており、LLM によって「質問に回答できているか?」を評価させたものを submit しています。

    // Evaluation
    // TODO: Structured Output を使ってみたい
    // ref: https://techcommunity.microsoft.com/t5/ai-azure-ai-services-blog/introducing-gpt-4o-2024-08-06-api-with-structured-outputs-on/ba-p/4232684
    const evalMessages: Message[] = [
      {
        role: "system",
        content:
          "あなたは質問と回答のセットを評価します。質問に対して回答できているかを判断してください。回答できていない場合は 0、回答できている場合は 1 を返してください。",
      },
      { role: "user", content: `質問: ${content} 回答: ${originalAnswer}` },
    ];
    const evalRes = await evaluateRequest(
      env,
      evalMessages,
      traceId,
      evalSpanId,
      spanId,
    );

スクリーンショット例

今回はとある RAG を利用した Bot で利用しました。このように Answered(名前微妙ですね...)という指標が categorical で TRUE / FALSE で送られています。

感想

API が用意されているので、Python 以外でも送ることができました。

このように簡単に利用できるので、LLM Application を使う場合は最初から入れておくと良いでしょう。モデルを変更した場合の評価もできますし、他のアプリケーション同様 Datadog 上でモニタリングが可能になります。metrics として扱えるのでアラート設定も可能です。 ぜひ使ってみてください。