メインコンテンツへスキップ
EvaluationLogger は、Python または TypeScript のコードから評価データを直接ログに記録するための、柔軟でインクリメンタルな方法を提供します。Weave の内部データ型に関する深い知識は必要ありません。ロガーをインスタンス化し、そのメソッド(log_predictionlog_scorelog_summary)を使用して評価ステップを記録するだけです。 このアプローチは、データセット全体や基礎となるすべてのスコアラーが事前に定義されていないような、複雑なワークフローにおいて特に役立ちます。 定義済みの DatasetScorer オブジェクトのリストを必要とする標準的な Evaluation オブジェクトとは対照的に、EvaluationLogger では、個々の予測とそれに関連するスコアを、利用可能になった時点でインクリメンタルに記録できます。
より構造化された評価をお好みですか?定義済みのデータセットとスコアラーを備えた、より規範的な評価フレームワークを好む場合は、Weave の標準評価フレームワーク を参照してください。EvaluationLogger が柔軟性を提供するのに対し、標準フレームワークは構造とガイドラインを提供します。

基本的なワークフロー

  1. ロガーの初期化: EvaluationLogger のインスタンスを作成します。オプションで modeldataset に関するメタデータを提供できます。省略した場合はデフォルト値が使用されます。
    LLM 呼び出し(OpenAI など)のトークン使用量とコストを把握するには、LLM を呼び出す前に EvaluationLogger を初期化してください。 LLM を先に呼び出してから予測をログに記録した場合、トークンとコストのデータは取得されません。
  2. 予測のログ記録: システムからの各入力/出力ペアに対して log_prediction を呼び出します。
  3. スコアのログ記録: 返された ScoreLogger を使用して、予測に対する log_score を行います。1 つの予測に対して複数のスコアをサポートしています。
  4. 予測の終了: 予測のスコアをログに記録した後は、必ず finish() を呼び出して確定させてください。
  5. サマリーのログ記録: すべての予測が処理された後、log_summary を呼び出してスコアを集計し、オプションでカスタムメトリクスを追加します。
予測に対して finish() を呼び出した後は、その予測にスコアを記録することはできません。
説明したワークフローを示す Python コードについては、基本的な例 を参照してください。

基本的な例

次の例では、EvaluationLogger を使用して、既存のコード内で予測とスコアをインラインでログに記録する方法を示します。
user_model 関数が定義され、入力リストに適用されます。各例について:
  • 入力と出力が log_prediction を使用してログに記録されます。
  • 単純な正解スコア(correctness_score)が log_score 経由でログに記録されます。
  • finish() によってその予測のログ記録が完了します。 最後に、log_summary が集計メトリクスを記録し、Weave での自動スコアサマリーをトリガーします。
import weave
from openai import OpenAI
from weave import EvaluationLogger

weave.init('your-team/your-project')

# トークン追跡を確実にするため、モデルを呼び出す前に EvaluationLogger を初期化します
eval_logger = EvaluationLogger(
    model="my_model",
    dataset="my_dataset"
)

# 入力データの例(任意のデータ構造を使用できます)
eval_samples = [
    {'inputs': {'a': 1, 'b': 2}, 'expected': 3},
    {'inputs': {'a': 2, 'b': 3}, 'expected': 5},
    {'inputs': {'a': 3, 'b': 4}, 'expected': 7},
]

# OpenAI を使用したモデルロジックの例
@weave.op
def user_model(a: int, b: int) -> int:
    oai = OpenAI()
    response = oai.chat.completions.create(
        messages=[{"role": "user", "content": f"What is {a}+{b}?"}],
        model="gpt-4o-mini"
    )
    # レスポンスを何らかの方法で使用します(ここでは簡単のため a + b を返します)
    return a + b

# サンプルを反復処理し、予測してログに記録します
for sample in eval_samples:
    inputs = sample["inputs"]
    model_output = user_model(**inputs) # 入力を kwargs として渡します

    # 予測の入力と出力をログに記録します
    pred_logger = eval_logger.log_prediction(
        inputs=inputs,
        output=model_output
    )

    # この予測のスコアを計算してログに記録します
    expected = sample["expected"]
    correctness_score = model_output == expected
    pred_logger.log_score(
        scorer="correctness", # スコアラーのシンプルな文字列名
        score=correctness_score
    )

    # この特定の予測のログ記録を終了します
    pred_logger.finish()

# 評価全体の最終サマリーをログに記録します。
# Weave は上記でログに記録された 'correctness' スコアを自動的に集計します。
summary_stats = {"subjective_overall_score": 0.8}
eval_logger.log_summary(summary_stats)

print("Evaluation logging complete. View results in the Weave UI.")

高度な使用法

EvaluationLogger は、より複雑な評価シナリオに対応するために、基本的なワークフローを超えた柔軟なパターンを提供します。このセクションでは、自動リソース管理のためのコンテキストマネージャーの使用、モデル実行とログ記録の分離、リッチメディアデータの処理、複数のモデル評価の並列比較などの高度なテクニックについて説明します。

コンテキストマネージャーの使用

EvaluationLogger は、予測とスコアの両方でコンテキストマネージャー(with ステートメント)をサポートしています。これにより、コードがよりクリーンになり、リソースの自動クリーンアップが可能になり、LLM 判定の呼び出しなどのネストされた操作の追跡が改善されます。 この文脈で with ステートメントを使用すると、以下の利点があります:
  • コンテキストを抜けるときに finish() が自動的に呼び出される
  • ネストされた LLM 呼び出しのトークン/コスト追跡が改善される
  • 予測コンテキスト内でのモデル実行後に出力を設定できる
import openai
import weave

weave.init("nested-evaluation-example")
oai = openai.OpenAI()

# ロガーの初期化
ev = weave.EvaluationLogger(
    model="gpt-4o-mini",
    dataset="joke_dataset"
)

user_prompt = "Tell me a joke"

# 予測にコンテキストマネージャーを使用 - finish() を呼び出す必要はありません
with ev.log_prediction(inputs={"user_prompt": user_prompt}) as pred:
    # コンテキスト内でモデル呼び出しを行います
    result = oai.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": user_prompt}],
    )

    # モデル呼び出し後に出力を設定します
    pred.output = result.choices[0].message.content

    # シンプルなスコアをログに記録します
    pred.log_score("correctness", 1.0)
    pred.log_score("ambiguity", 0.3)
    
    # LLM 判定が必要なスコアにはネストされたコンテキストマネージャーを使用します
    with pred.log_score("llm_judge") as score:
        judge_result = oai.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": "Rate how funny the joke is from 1-5"},
                {"role": "user", "content": pred.output},
            ],
        )
        # 計算後にスコア値を設定します
        score.value = judge_result.choices[0].message.content

# 'with' ブロックを抜けるときに finish() が自動的に呼び出されます

ev.log_summary({"avg_score": 1.0})
このパターンにより、すべてのネストされた操作が追跡され、親の予測に帰属することが保証され、Weave UI で正確なトークン使用量とコストデータが得られます。

ログ記録の前に出力を取得する

最初にモデルの出力を計算し、後で予測とスコアを個別にログに記録することができます。これにより、評価ロジックとログ記録ロジックをより適切に分離できます。
# トークン追跡を確実にするため、モデルを呼び出す前に EvaluationLogger を初期化します
ev = EvaluationLogger(
    model="example_model",
    dataset="example_dataset"
)

# モデル出力(例:OpenAI 呼び出し)は、トークン追跡のためにロガー初期化後に行う必要があります
outputs = [your_output_generator(**inputs) for inputs in your_dataset]
preds = [ev.log_prediction(inputs, output) for inputs, output in zip(your_dataset, outputs)]
for pred, output in zip(preds, outputs):
    pred.log_score(scorer="greater_than_5_scorer", score=output > 5)
    pred.log_score(scorer="greater_than_7_scorer", score=output > 7)
    pred.finish()

ev.log_summary()

リッチメディアのログ記録

入力、出力、スコアには、画像、動画、音声、構造化テーブルなどのリッチメディアを含めることができます。log_prediction または log_score メソッドに辞書やメディアオブジェクトを渡すだけです。
import io
import wave
import struct
from PIL import Image
import random
from typing import Any
import weave

def generate_random_audio_wave_read(duration=2, sample_rate=44100):
    n_samples = duration * sample_rate
    amplitude = 32767  # 16ビット最大振幅

    buffer = io.BytesIO()

    # wave データをバッファに書き込む
    with wave.open(buffer, 'wb') as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)  # 16ビット
        wf.setframerate(sample_rate)

        for _ in range(n_samples):
            sample = random.randint(-amplitude, amplitude)
            wf.writeframes(struct.pack('<h', sample))

    # バッファを最初から読み取れるように巻き戻す
    buffer.seek(0)

    # Wave_read オブジェクトを返す
    return wave.open(buffer, 'rb')

rich_media_dataset = [
    {
        'image': Image.new(
            "RGB",
            (100, 100),
            color=(
                random.randint(0, 255),
                random.randint(0, 255),
                random.randint(0, 255),
            ),
        ),
        "audio": generate_random_audio_wave_read(),
    }
    for _ in range(5)
]

@weave.op
def your_output_generator(image: Image.Image, audio) -> dict[str, Any]:
    return {
        "result": random.randint(0, 10),
        "image": image,
        "audio": audio,
    }

ev = EvaluationLogger(model="example_model", dataset="example_dataset")

for inputs in rich_media_dataset:
    output = your_output_generator(**inputs)
    pred = ev.log_prediction(inputs, output)
    pred.log_score(scorer="greater_than_5_scorer", score=output["result"] > 5)
    pred.log_score(scorer="greater_than_7_scorer", score=output["result"] > 7)

ev.log_summary()

複数の評価をログに記録して比較する

EvaluationLogger を使用すると、複数の評価をログに記録して比較できます。
  1. 下記のサンプルコードを実行します。
  2. Weave UI で、Evals タブに移動します。
  3. 比較したい評価(evals)を選択します。
  4. Compare ボタンをクリックします。比較ビューでは、以下のことができます。
    • 追加または削除する評価の選択
    • 表示または非表示にするメトリクスの選択
    • 特定の例をページ送りして、同じデータセットの同じ入力に対して異なるモデルがどのように機能したかを確認
    比較の詳細については、Comparisons を参照してください。
import weave

models = [
    "model1",
    "model2",
     {"name": "model3", "metadata": {"coolness": 9001}}
]

for model in models:
    # トークンをキャプチャするため、モデルを呼び出す前に EvalLogger を初期化する必要があります
    ev = EvaluationLogger(
        name="comparison-eval",
        model=model, 
        dataset="example_dataset",
        scorers=["greater_than_3_scorer", "greater_than_5_scorer", "greater_than_7_scorer"],
        eval_attributes={"experiment_id": "exp_123"}
    )
    for inputs in your_dataset:
        output = your_output_generator(**inputs)
        pred = ev.log_prediction(inputs=inputs, output=output)
        pred.log_score(scorer="greater_than_3_scorer", score=output > 3)
        pred.log_score(scorer="greater_than_5_scorer", score=output > 5)
        pred.log_score(scorer="greater_than_7_scorer", score=output > 7)
        pred.finish()

    ev.log_summary()
Evals タブ
比較ビュー

使用上のヒント

  • 各予測の直後に速やかに finish() を呼び出してください。
  • log_summary を使用して、単一の予測に関連付けられていないメトリクス(例:全体のレイテンシ)をキャプチャします。
  • リッチメディアのログ記録は定性分析に最適です。