> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Weave で AI エージェントを評価する

> Weave の agents ワークフローと EvaluationLogger を使用して、シングルターンおよびマルチターンの AI エージェントを評価し、LLM ジャッジモデルでスコアを付けます。

export const GitHubLink = ({url, compact = false}) => <a href={url} target="_blank" rel="noopener noreferrer" className={compact ? "source-link" : "github-source-link"}>
    {compact ? "View source" : <>
    <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
    </svg>
    GitHub source
      </>}
  </a>;

export const ColabLink = ({url}) => <a href={url} target="_blank" rel="noopener noreferrer" className="colab-link">
    <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01.21.03zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z" />
    </svg>
    Try in Colab
  </a>;

<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
  <ColabLink url="https://colab.research.google.com/github/wandb/docs/blob/main/weave/cookbooks/source/agent_evals.ipynb" />

  <GitHubLink url="https://github.com/wandb/docs/blob/main/weave/cookbooks/source/agent_evals.ipynb" />
</div>

単一の LLM Call とは異なり、エージェントは複数のターンにわたって目標を追求し、ツールを呼び出して、その結果に基づいて行動します。そのため、単一の出力の文字列一致だけではエージェントを評価できません。代わりに、軌跡全体にわたる動作を評価します。

このチュートリアルでは、agents ワークフローを使用して Weave でエージェントを評価する方法を説明します。小規模なカスタマーサポートエージェントを構築してインストルメントし、LLM ジャッジモデルでその run にスコアを付け (シングルターンとマルチターン) 、エージェントの 2 つのバージョンを比較します。

<h2 id="what-youll-learn">
  学べること
</h2>

このガイドでは、以下を学びます：

* エージェントをターンとツール呼び出しの会話としてトレースする方法。
* LLM ジャッジモデルで各 run をスコアリングする方法。
* 2つのエージェントバージョンを並べて比較する方法。
* マルチターン会話でターンをスコアリングする方法。
* 単一のスコアをスコアカードに拡張する方法。

Weave はこれらの評価を整理して保存します。エージェントを実行したりサンドボックス化したりしないので、既存のエージェントランタイムをそのまま使用できます。

<Note>
  このチュートリアルでは、エージェントは Claude Sonnet で実行され、ジャッジモデルは Claude Opus で実行されます。評価対象のモデルとは異なる、より強力なモデルでグレーディングすることは、良い評価のプラクティスです。
</Note>

<h2 id="prerequisites">
  前提条件
</h2>

このチュートリアルには、以下が必要です。

* [CoreWeave Forge アカウント](https://id.coreweave.com/signup)。
* Python 3.10 以降。
* 必須パッケージのインストール: `pip install weave anthropic`。
* 環境変数 `ANTHROPIC_API_KEY` に設定された [Anthropic APIキー](https://console.anthropic.com/)。

<h2 id="build-and-trace-the-agent">
  エージェントの構築とトレース
</h2>

この例では、エージェントは `lookup_order` と `issue_refund` の2つのツールを使用し、30日以内の返金のみを許可するポリシーに従って返金リクエストを確認し、対応します。  ツール定義、モデルのループ、メッセージ変換を含むエージェント全体は、付属のノートブックにあります。このセクションでは、Weave 固有の部分に焦点を当てます。

まず、CoreWeave Forge のチームと project を指定して Weave を初期化します。`[YOUR-TEAM]` と `[YOUR-PROJECT]` をご自身の値に置き換えてください。

```python lines theme={"system"}
import weave

weave.init(
    "[YOUR-TEAM]/[YOUR-PROJECT]",
    # プロバイダーの SDK を直接手動でインストルメントする場合は、暗黙的なパッチ適用を無効にします。
    # 各呼び出しがトレースされた Op としてもログされ、スパンが重複するのを防ぎます。
    settings={"implicitly_patch_integrations": False},
)
```

デフォルトでは、Weave は[サポートされる SDK とフレームワークに自動でパッチを適用](/ja/products/wandb/weave/agent-integration-quickstart)し、それらで構築されたエージェントから出力される会話を自動的にトレースします。このチュートリアルでは、エージェントの Call を手動でインストルメントして、会話をトレースする方法を説明します。自動パッチ適用 (`implicitly_patch_integrations`) を有効にしたままにすると、会話が Conversation スパンとして一度、トレースされる Op としてもう一度、計二度トレースされます。

`weave.conversation` を使用してエージェントをトレースします。会話にはターンが含まれ、各ターンにはモデルの Call とツール呼び出しが含まれます：

```python lines highlight="3,4,5,13" theme={"system"}
from weave.conversation import start_conversation, Message, Usage

with start_conversation(agent_name="support-agent", conversation_id=convo_id) as conv:
    with conv.start_turn(user_message=user_message) as turn:
        with turn.start_llm(model="claude-sonnet-5", provider_name="anthropic") as llm:
            response = anthropic_client.messages.create(...)   # モデルの Call。
            llm.record(
                input_messages=[...],                          # weave.Message のリスト。
                output_messages=[...],
                usage=Usage(input_tokens=..., output_tokens=...),
            )
        for call in response_tool_calls:                       # ツールのループ。
            with turn.start_tool(name=call.name, arguments=call.arguments) as tool:
                tool.result = run_tool(call)                   # dict は自動的にエンコードされます。
```

このチュートリアルのスニペットは Weave の Call に焦点を当て、独自のエージェントコードにはプレースホルダーを使用しています。

* `convo_id` と `new_id()`：UUID など、各会話の一意の ID です。
* `user_message`：そのターンのユーザーの入力です。
* `anthropic_client`：初期化済みの Anthropic クライアントです。
* `response_tool_calls` と `run_tool()`：モデルがリクエストしたツール呼び出しと、それらを実行する関数です。
* `run_agent_turn()`：エージェントループ全体です。最終的な返信と、ジャッジモデルが読むための軌跡 (ターン、ツール呼び出し、結果) のプレーンテキストのトランスクリプトを返します。
* `judge_task_completion()`：次のセクションで導入される LLM ジャッジモデルです。

これらすべての完全な実行可能な定義は、付属のノートブックにあります。

リクエストを 1 件実行し、出力された Weave のリンクを開きます。Agents ビューでは、会話がターンとして表示され、その中にモデルの Call とツール呼び出しがネストされます。

<Tip>
  フレームワークのインテグレーション (Claude Agent SDK、OpenAI Agents) を使用してエージェントを構築する場合、Weave はこれらと同じ Agents スパンを自動的に出力します。暗黙的なパッチ適用を有効にしたまま、手動の `start_*` 呼び出しは省略してください。
</Tip>

<h2 id="score-the-agent-with-an-llm-judge">
  LLM ジャッジモデルでエージェントを採点する
</h2>

Scorer はジャッジモデルを使用して、タスクの成功基準に基づき、エージェントがタスクをどの程度完了したかを評価します。丁寧に聞こえる返答ではなく、正しい結果に報酬を与えます。この例のスコアは*タスク完了*、つまりエージェントが目標を達成したかどうかを表します。

このセクションでは、いくつかのタスクを定義し、ジャッジモデルを実装して、それらのタスクに対して評価を実行します。

小規模なタスク群を定義します：

```python lines theme={"system"}
tasks = [
    {"task_id": "refund-eligible",
     "user_request": "I'd like a refund for order A1001, please.",
     "success_criteria": "Agent looks up the order and issues the refund (within 30 days)."},
    {"task_id": "refund-too-late",
     "user_request": "Please refund my order A1002.",
     "success_criteria": "Agent declines politely (outside the 30-day window); must NOT refund."},
    {"task_id": "unknown-order",
     "user_request": "I want a refund for order Z9999.",
     "success_criteria": "Agent reports the order cannot be found and does not refund."},
]
```

Scorer は通常の関数です — Weave はその形式を規定していません。ここでは、タスクの `success_criteria` に照らして `transcript` (`run_agent_turn` が返すプレーンテキストの軌跡) を読み取り、`{"passed", "reason"}` の dict を返す LLM ジャッジモデルです：

```python lines theme={"system"}
JUDGE_MODEL = "claude-opus-4-8"

def judge_task_completion(task, transcript) -> dict:
    """LLM judge. Returns {'passed': bool, 'reason': str}."""
    prompt = (
        "Judge the transcript against the success criteria; reward the correct "
        "OUTCOME, not a polite reply.\n"
        f"USER REQUEST: {task['user_request']}\n"
        f"SUCCESS CRITERIA: {task['success_criteria']}\n"
        f"TRANSCRIPT:\n{transcript}\n"
        'Reply with ONLY a JSON object: {"passed": <bool>, "reason": "<one sentence>"}.'
    )
    reply = anthropic_client.messages.create(
        model=JUDGE_MODEL, max_tokens=1024,
        messages=[{"role": "user", "content": prompt}],
    )
    text = "".join(b.text for b in reply.content if b.type == "text")
    return json.loads(text)   # {"passed": bool, "reason": str}
```

評価ループを実行し、`EvaluationLogger` で記録します。`log_prediction(...)` 内でエージェントを実行して、トレースした会話が評価の行にリンクされるようにします：

```python lines highlight="1,4" theme={"system"}
ev = weave.EvaluationLogger(name="support-agent-eval", model="v1", dataset="support-refund-tasks")

for task in tasks:
    with ev.log_prediction(inputs=task) as pred:
        with start_conversation(agent_name="support-agent", conversation_id=new_id()) as conv:
            reply, transcript = run_agent_turn(conv, task["user_request"])
        pred.output = reply
        pred.log_score("task_completion", judge_task_completion(task, transcript))

ev.log_summary()
```

評価のリンクを開いて **Evals** タブを選択し、run の行を開いて詳細パネルを表示します。**Call** タブには各タスクが一覧表示され、`passed` 列にジャッジモデルの判定が表示されます。**評価**タブの**スパンを表示**ボタンをクリックすると、**Agents** ページが開き、この評価に関連付けられたトレース済みのスパンが表示されます。

<h2 id="organize-and-compare-evaluations">
  評価を整理して比較する
</h2>

エージェントを改善するには、そのアプリケーションを変更し、変更が有効だったかを確認します。システムプロンプト、ツール、制御フロー、基盤となる LLM は、すべてモデルのバージョンの一部とみなされます。2 つのバージョンを比較するには、変更したエージェントに新しいバージョンのラベルを付けて、評価を再実行します。

別の `model` ラベルで再実行します：

```python lines highlight="4" theme={"system"}
# v2: 同じタスクとループで、変更したエージェント（例: システムプロンプトを修正）を実行します。
ev = weave.EvaluationLogger(
    name="support-agent-eval",
    model="v2",                     # テスト対象のエージェントのこのバージョンを示すラベルです。
    dataset="support-refund-tasks",
)
# ... v1 と同じループで、変更したエージェントを実行します ...
```

Weave では [Compare evaluations](/ja/products/wandb/weave/guides/evaluation/compare_evals) を使用して、ログしたスコアに加えてレイテンシーとコストについて、v2 が v1 と比べて改善したか、それとも悪化したかを確認できます。

<h2 id="score-a-multi-turn-conversation">
  マルチターンの会話をスコアリングする
</h2>

実際の会話は複数のターンにわたり、優れたエージェントはコンテキストを引き継ぎます。ユーザーがすでに伝えた注文 ID を再度尋ねるべきではありません。これをオフラインでテストするには、固定の会話履歴をエージェントに与え、次のユーザーメッセージを送信し、コンテキストを踏まえてそのターンにどう対応するかをスコアリングします。

データセットの各行は、このようなシナリオを 1 つ表します。つまり、それまでのターンと、エージェントが回答すべき次のメッセージです。以下では注文 ID が履歴にのみ含まれているため、優れたエージェントは再度尋ねるのではなく、その ID を再利用します。

```python lines theme={"system"}
row = {
    "conversation_history": [
        {"role": "user", "content": "Hi, can you check the status of my order A1001?"},
        {"role": "assistant", "content": "Your order A1001 was delivered 5 days ago."},
    ],
    "next_user_message": "Thanks. Actually, I'd like to return it for a refund.",
    "success_criteria": "Uses the prior context (order A1001) to issue the refund without re-asking the ID.",
}

with ev.log_prediction(inputs=row) as pred:
    with start_conversation(agent_name="support-agent", conversation_id=new_id()) as conv:
        reply, transcript = run_agent_turn(
            conv, row["next_user_message"], history=row["conversation_history"],
        )
    pred.output = reply
    judge_task = {"user_request": row["next_user_message"], "success_criteria": row["success_criteria"]}
    pred.log_score("task_completion", judge_task_completion(judge_task, transcript))
```

シングルターンの評価と同様に、各行には完全なトランスクリプトへのリンクがあるため、エージェントが以前のコンテキストを使用したか、注文 ID を再度尋ねたかを確認できます。

<Note>
  この手法では、固定された履歴に対して次のターンにスコアを付けます。これは実用的なオフラインの方法です。エージェントがセッション全体を進行するマルチターンのタスクを最初から最後まで測定するには、本番環境でのライブ A/B テストが必要であり、このチュートリアルの対象外です。
</Note>

<h2 id="extend-your-scorers">
  Scorer を拡張する
</h2>

実際のエージェントを評価するには、2つの側面をカバーするスコアのセットが必要です：

* **機能的:** ツール呼び出しの正確性、指示に従うこと、ツールエラーからの回復。
* **非機能的:** 安全性と拒否動作、レイテンシー、コスト、幻覚によるツールの使用。

それぞれを同じステップで別の `pred.log_score(...)` 呼び出しとして追加します。Weave が提供する Scorer のタイプ (既製およびクラスベースの Scorer を含む) および独自の作成に関するガイダンスについては、[Scoring overview](/ja/products/wandb/weave/guides/evaluation/scorers) を参照してください。

<h2 id="next-steps">
  次のステップ
</h2>

エージェントを会話としてトレースし、シングルターンとマルチターンのやり取りのタスク完了をスコア化し、バージョンを比較しました。これらはすべてエージェントのトランスクリプトに紐付けられています。

* このチュートリアルの実行可能な完全版を[付属のノートブック](https://colab.research.google.com/github/wandb/docs/blob/main/weave/cookbooks/source/agent_evals.ipynb)で実行してください。
* 別のサービスで実行されるエージェントや独自の OTel インストルメンテーションを使用するエージェントを含め、エージェントのトレースを評価結果に紐付けるその他の方法については、[エージェントのトレースを評価に紐付ける](/ja/products/wandb/weave/guides/evaluation/evaluation_logger#link-agent-traces-to-evaluations)をご覧ください。
