> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-locadex-parallel-t9n-main-cs60c8p4o6ik99tylxgp3.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Weave로 AI 에이전트 평가하기

> 에이전트 워크플로와 EvaluationLogger를 사용해 Weave에서 단일 턴 및 멀티턴 AI 에이전트를 평가하고, LLM 평가자로 점수를 산정합니다.

export const GitHubLink = ({url}) => <a href={url} target="_blank" rel="noopener noreferrer" className="github-source-link">
    <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 소스 코드
  </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>
    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과 달리 에이전트는 여러 턴에 걸쳐 목표를 달성하기 위해 도구를 호출하고 그 결과에 따라 행동합니다. 따라서 단일 출력을 string 일치 방식으로 평가할 수 없습니다. 대신 트래젝터리 전반에 걸친 동작을 평가해야 합니다.

이 튜토리얼에서는 에이전트 워크플로를 사용해 Weave로 에이전트를 평가하는 방법을 설명합니다. 소규모 고객 지원 에이전트를 구축하고 계측한 후, LLM 평가자(단일 턴 및 멀티턴)를 사용해 해당 Runs에 점수를 매기고 에이전트의 두 버전을 비교합니다.

<div id="what-youll-learn">
  ## 학습할 내용
</div>

이 가이드에서는 다음 방법을 알아봅니다.

* 에이전트를 턴과 도구 Call로 이루어진 대화로 트레이스합니다.
* 각 run을 LLM 평가자로 평가합니다.
* 두 에이전트 버전을 나란히 비교합니다.
* 멀티턴 대화에서 턴을 평가합니다.
* 단일 점수를 스코어카드로 확장합니다.

Weave는 이러한 평가를 구성하고 저장하지만 에이전트를 실행하거나 격리된 환경에서 실행하지는 않으므로, 기존 에이전트 런타임을 그대로 사용할 수 있습니다.

<Note>
  이 튜토리얼에서는 에이전트가 Claude Sonnet에서 실행되고 평가자는 Claude Opus에서 실행됩니다. 평가 대상 모델보다 더 강력한 다른 모델로 평가하는 것은 좋은 평가 방법입니다.
</Note>

<div id="prerequisites">
  ## 사전 요구 사항
</div>

이 튜토리얼을 사용하려면 다음이 필요합니다.

* [W\&B 계정](https://wandb.ai/signup)
* Python 3.10 이상
* 필수 패키지: `pip install weave anthropic`
* `ANTHROPIC_API_KEY` 환경 변수로 설정한 [Anthropic API 키](https://console.anthropic.com/)

<div id="build-and-trace-the-agent">
  ## 에이전트 구축 및 트레이싱
</div>

이 예시에서 에이전트는 `lookup_order`와 `issue_refund`라는 두 도구를 사용해 30일 이내의 환불만 허용하는 정책에 따라 환불 요청을 검토하고 응답합니다. 도구 정의, 모델 루프, 메시지 변환을 포함한 전체 에이전트는 함께 제공되는 노트북에 있습니다. 이 섹션에서는 Weave 관련 부분에 중점을 둡니다.

먼저 W\&B 팀과 프로젝트를 사용하여 Weave를 초기화합니다. `[YOUR-TEAM]` 및 `[YOUR-PROJECT]`를 자신의 값으로 바꾸세요:

```python lines theme={null}
import weave

weave.init(
    "[YOUR-TEAM]/[YOUR-PROJECT]",
    # 순수 공급자 SDK를 직접 instrumenting하는 경우: 암시적 patching을 끄면
    # 각 call이 traced Op로도 기록되어 span이 중복되는 것을 방지할 수 있습니다.
    settings={"implicitly_patch_integrations": False},
)
```

기본적으로 Weave는 [지원되는 SDK 및 프레임워크를 자동으로 패치](/ko/weave/agent-integration-quickstart)하고, 이를 기반으로 구축된 에이전트에서 생성되는 대화를 자동으로 트레이스합니다. 이 튜토리얼에서는 에이전트의 Call을 수동으로 계측하여 대화를 트레이스하는 방법을 안내합니다. 자동 패치(`implicitly_patch_integrations`)를 켜 두면 대화가 두 번 트레이스됩니다. 한 번은 Conversation span으로, 또 한 번은 트레이스된 Op로 기록됩니다.

`weave.conversation`을 사용해 에이전트를 트레이스합니다. 대화는 여러 턴으로 구성되며, 각 턴에는 모델 Call과 모든 도구 Call이 포함됩니다:

```python lines highlight="3,4,5,13" theme={null}
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()`: 모델이 요청한 도구 Call과 이를 실행하는 함수입니다.
* `run_agent_turn()`: 전체 에이전트 루프입니다. 최종 응답과 평가자가 읽을 수 있도록 트래젝터리(턴, 도구 Call, 결과)를 일반 텍스트로 기록한 내용을 반환합니다.
* `judge_task_completion()`: 다음 섹션에서 도입하는 LLM 평가자입니다.

이 모든 항목의 완전하고 실행 가능한 정의는 함께 제공되는 노트북에 있습니다.

요청을 하나 실행한 후 출력된 Weave 링크를 여세요. Agents 뷰에서는 대화가 하나의 턴으로 표시되며, 그 안에 모델 Call과 도구 Call이 중첩됩니다.

<Tip>
  프레임워크 인테그레이션(Claude Agent SDK, OpenAI Agents)으로 에이전트를 구축하는 경우, Weave는 동일한 Agents span을 자동으로 생성합니다. 암시적 패칭을 켜 둔 상태로 수동 `start_*` Call은 건너뛰세요.
</Tip>

<div id="score-the-agent-with-an-llm-judge">
  ## LLM 평가자로 에이전트 점수 매기기
</div>

평가 모델을 사용해 Scorer는 작업의 성공 기준을 바탕으로 에이전트가 작업을 얼마나 잘 완료했는지 평가합니다. 정중하게 들리는 응답이 아니라 올바른 결과에 점수를 부여합니다. 이 예시의 점수는 *작업 완료*입니다. 즉, 에이전트가 목표를 달성했는지를 평가합니다.

이 섹션에서는 몇 가지 작업을 정의하고, 평가자를 작성한 다음, 해당 작업에 대해 평가를 실행합니다.

작은 작업 모음을 정의합니다:

```python lines theme={null}
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는 그 형태를 규정하지 않습니다. 여기서는 `transcript`(`run_agent_turn`이 반환하는 일반 텍스트 트래젝터리)를 작업의 `success_criteria`에 따라 평가하고 `{"passed", "reason"}` 딕셔너리를 반환하는 LLM 평가자입니다:

```python lines theme={null}
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={null}
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` 열과 함께 각 작업이 나열됩니다. **Evaluation** 탭의 **View spans** 버튼을 클릭하면 이 평가에 연결된 트레이스 span이 표시된 **Agents** 페이지가 열립니다.

<div id="organize-and-compare-evaluations">
  ## 평가 구성 및 비교
</div>

애플리케이션을 변경하고 변경 사항이 개선에 도움이 되었는지 확인하여 에이전트를 개선할 수 있습니다. system 프롬프트, 도구, 제어 흐름, 기반 LLM은 모두 모델 버전의 일부로 간주됩니다. 두 버전을 비교하려면 변경된 에이전트에서 평가를 다시 실행하고 새 버전으로 레이블을 지정하세요.

다른 `model` 레이블로 다시 실행하세요:

```python lines highlight="4" theme={null}
# v2: 동일한 작업과 루프에서 변경된 에이전트(예: 수정된 system 프롬프트)를 실행합니다.
ev = weave.EvaluationLogger(
    name="support-agent-eval",
    model="v2",                     # 테스트 대상 에이전트의 해당 version을 나타내는 레이블입니다.
    dataset="support-refund-tasks",
)
# ... v1과 동일한 루프에서 변경된 에이전트를 실행합니다 ...
```

Weave에서는 [평가 비교](/ko/weave/guides/evaluation/compare_evals)를 통해 로깅한 점수, 지연 시간, 비용을 기준으로 v2가 v1보다 개선되었는지 또는 성능이 저하되었는지 확인할 수 있습니다.

<div id="score-a-multi-turn-conversation">
  ## 여러 턴으로 이루어진 대화 점수 매기기
</div>

실제 대화는 여러 턴에 걸쳐 진행되며, 유능한 에이전트는 문맥을 이어갑니다. 사용자가 이미 제공한 주문 ID를 다시 묻지 않아야 합니다. 이를 오프라인에서 테스트하려면 고정된 대화 이력으로 에이전트에 정보를 제공하고, 다음 사용자 메시지를 전송한 후 해당 턴을 문맥에 맞게 어떻게 처리하는지 점수를 매기세요.

각 데이터셋 행은 이전 턴과 에이전트가 답변해야 하는 다음 메시지로 구성된 하나의 시나리오입니다. 아래 예에서는 주문 ID가 이력에만 나타나므로, 좋은 에이전트는 다시 묻지 않고 이를 재사용합니다:

```python lines theme={null}
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>
  이 방식은 고정된 이력을 기준으로 다음 턴을 평가하는 실용적인 오프라인 방법입니다. 에이전트가 전체 Session을 주도하는 멀티턴 작업 전체를 엔드 투 엔드로 측정하려면 프로덕션 환경에서 실시간 A/B 테스트가 필요하며, 이는 이 튜토리얼의 범위를 벗어납니다.
</Note>

<div id="extend-your-scorers">
  ## Scorer 확장
</div>

실제 에이전트를 평가하려면 다음 두 가지 측면을 포괄하는 점수 집합이 필요합니다.

* **기능적:** 도구 호출의 정확성, 지침 준수, 도구 오류로부터의 복구
* **비기능적:** 안전성 및 거부 동작, 지연 시간, 비용, 환각에 따른 도구 사용

같은 단계에서 각각을 `pred.log_score(...)` 호출로 추가하세요. Weave에서 제공하는 사전 구축된 Scorer 및 클래스 기반 Scorer를 비롯한 Scorer 유형과 자체 Scorer 작성 방법은 [점수화 개요](/ko/weave/guides/evaluation/scorers)를 참조하세요.

<div id="next-steps">
  ## 다음 단계
</div>

에이전트를 대화로 트레이스하고, 단일 턴 및 멀티턴 상호작용의 작업 완료 여부를 평가했으며, 에이전트 전사본에 연결된 버전을 비교했습니다.

* [함께 제공되는 노트북](https://colab.research.google.com/github/wandb/docs/blob/main/weave/cookbooks/source/agent_evals.ipynb)에서 이 튜토리얼의 전체 실행 가능 버전을 실행하세요.
* 별도 서비스에서 실행되거나 자체 OTel 계측을 사용하는 에이전트를 포함해, 에이전트 트레이스를 평가 결과에 연결하는 다른 방법은 [에이전트 트레이스를 평가에 연결](/ko/weave/guides/evaluation/evaluation_logger#link-agent-traces-to-evaluations)에서 알아보세요.
