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

# 점수화 개요

> Weave Scorer로 AI 출력을 평가하고 평가 메트릭을 반환합니다

Weave에서 Scorer는 AI 출력을 평가하고 평가 메트릭을 반환합니다. Scorer는 AI의 출력을 받아 분석한 뒤 결과를 담은 사전을 반환합니다. 필요에 따라 입력 데이터를 참조로 사용할 수 있으며, 평가에 대한 설명이나 추론 같은 추가 정보도 함께 반환할 수 있습니다.

이 가이드는 AI 시스템 출력의 품질을 측정하려는 개발자를 위한 것입니다. Scorer가 Weave 평가에서 어떤 역할을 하는지, 직접 Scorer를 구축하는 방법, 개별 Call에 Scorer를 적용하는 방법, 그리고 결과 점수를 분석하는 방법을 설명합니다.

<Tabs>
  <Tab title="Python">
    평가 중에 `weave.Evaluation` 객체에 Scorer를 전달하세요. Weave는 두 가지 유형의 Scorer를 지원합니다:

    1. **함수 기반 Scorer:** `@weave.op`으로 데코레이트된 Python 함수입니다.
    2. **클래스 기반 Scorer:** 더 복잡한 평가를 위해 `weave.Scorer`를 상속하는 Python 클래스입니다.

    Scorer는 반드시 사전을 반환해야 하며, 여러 메트릭, 중첩된 메트릭, 그리고 추론에 대한 LLM 평가자의 텍스트 같은 비수치 값도 반환할 수 있습니다.
  </Tab>

  <Tab title="TypeScript">
    Scorer는 평가 중에 `weave.Evaluation` 객체에 전달하는 특수한 op입니다.
  </Tab>
</Tabs>

<div id="create-your-own-scorers">
  ## 나만의 Scorer 만들기
</div>

맞춤형 Scorer를 사용하면 기본 제공 Scorer로는 다루지 못하는, 사용 사례별 평가 기준을 인코딩할 수 있습니다. 다음 섹션에서는 Scorer를 정의하는 두 가지 방법, 즉 함수로 정의하는 방법과 더 복잡한 로직을 위해 클래스로 정의하는 방법을 설명합니다.

<Tip>
  **바로 사용할 수 있는 Scorer**
  이 가이드에서는 맞춤형 Scorer를 만드는 방법을 설명하지만, Weave에는 바로 사용할 수 있는 다양한 [기본 제공 Scorer](./builtin_scorers)와 [로컬 SLM Scorer](./weave_local_scorers)가 포함되어 있습니다. 예를 들면 다음과 같습니다.

  * [환각 감지](./builtin_scorers#hallucinationfreescorer)
  * [요약 품질](./builtin_scorers#summarizationscorer)
  * [임베딩 유사도](./builtin_scorers#embeddingsimilarityscorer)
  * [유해성 감지(로컬)](./weave_local_scorers#weavetoxicityscorerv1)
  * [컨텍스트 관련성 평가(로컬)](./weave_local_scorers#weavecontextrelevancescorerv1)
</Tip>

<div id="function-based-scorers">
  ### 함수 기반 Scorer
</div>

<Tabs>
  <Tab title="Python">
    함수 기반 Scorer는 딕셔너리를 반환하는 `@weave.op` 데코레이터가 적용된 함수입니다. 다음과 같은 간단한 평가에 적합합니다.

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

    @weave.op
    def evaluate_uppercase(text: str) -> dict:
        return {"text_is_uppercase": text.isupper()}

    my_eval = weave.Evaluation(
        dataset=[{"text": "HELLO WORLD"}],
        scorers=[evaluate_uppercase]
    )
    ```

    평가를 실행하면 `evaluate_uppercase`가 텍스트가 모두 대문자인지 확인합니다.
  </Tab>

  <Tab title="TypeScript">
    이는 `modelOutput`과 선택적으로 `datasetRow`를 포함하는 객체를 인자로 받는 `weave.op`로 래핑된 함수입니다. 다음 예시와 같은 간단한 평가에 적합합니다.

    ```typescript lines theme={null}
    import * as weave from 'weave'

    const evaluateUppercase = weave.op(
        ({modelOutput}) => modelOutput.toUpperCase() === modelOutput,
        {name: 'textIsUppercase'}
    );

    const myEval = new weave.Evaluation({
        dataset: [{text: 'HELLO WORLD'}],
        scorers: [evaluateUppercase],
    })
    ```
  </Tab>
</Tabs>

<div id="class-based-scorers">
  ### 클래스 기반 Scorers
</div>

<Tabs>
  <Tab title="Python">
    더 고급 평가가 필요하거나, 특히 추가적인 Scorer 메타데이터를 추적해야 하거나 LLM 평가기에 서로 다른 프롬프트를 사용해 보거나 여러 함수 call을 수행해야 하는 경우 `Scorer` 클래스를 사용하세요.

    **요구 사항:**

    1. `weave.Scorer`를 상속합니다.
    2. `@weave.op`로 데코레이션된 `score` 방법을 정의합니다.
    3. `score` 방법은 딕셔너리를 반환해야 합니다.

    예시:

    ```python lines {7} theme={null}
    import weave
    from openai import OpenAI
    from weave import Scorer

    llm_client = OpenAI()

    class SummarizationScorer(Scorer):
        model_id: str = "gpt-4o"
        system_prompt: str = "Evaluate whether the summary is good."

        @weave.op
        def some_complicated_preprocessing(self, text: str) -> str:
            processed_text = "Original text: \n" + text + "\n"
            return processed_text

        @weave.op
        def call_llm(self, summary: str, processed_text: str) -> dict:
            res = llm_client.chat.completions.create(
                messages=[
                    {"role": "system", "content": self.system_prompt},
                    {"role": "user", "content": (
                        f"Analyze how good the summary is compared to the original text."
                        f"Summary: {summary}\n{processed_text}"
                    )}])
            return {"summary_quality": res}

        @weave.op
        def score(self, output: str, text: str) -> dict:
            """요약 품질을 평가합니다.

            인수:
                output: AI 시스템이 생성한 요약
                text: 요약할 원문
            """
            processed_text = self.some_complicated_preprocessing(text)
            eval_result = self.call_llm(summary=output, processed_text=processed_text)
            return {"summary_quality": eval_result}

    evaluation = weave.Evaluation(
        dataset=[{"text": "The quick brown fox jumps over the lazy dog."}],
        scorers=[summarization_scorer])
    ```

    이 클래스는 요약을 원문과 비교해 품질을 평가합니다.
  </Tab>

  <Tab title="TypeScript">
    ```plaintext theme={null}
    이 기능은 아직 TypeScript에서 사용할 수 없습니다.
    ```
  </Tab>
</Tabs>

<div id="how-scorers-work">
  ## Scorer의 작동 방식
</div>

이 섹션에서는 Scorer가 평가로부터 데이터를 받는 방식, 데이터셋 열을 Scorer 인수에 매핑하는 방법, 점수화 프롬프트에서 op 변수를 참조하는 방법, 그리고 Weave가 각 행의 점수를 최종 결과로 요약하는 방식을 설명합니다.

<div id="scorer-keyword-arguments">
  ### Scorer 키워드 인수
</div>

<Tabs>
  <Tab title="Python">
    Scorer는 AI 시스템의 출력과 데이터셋 행의 입력 데이터 모두에 액세스할 수 있습니다.

    * **입력:** `label` 또는 `target` 열처럼 데이터셋 행의 데이터를 Scorer에서 사용하려면, Scorer 정의에 `label` 또는 `target` 키워드 인수를 추가하세요.

    예를 들어 데이터셋의 `label`이라는 열을 사용하려는 경우, Scorer 함수(또는 `score` 클래스 메서드)의 파라미터 목록은 다음과 같습니다.

    ```python lines theme={null}
    @weave.op
    def my_custom_scorer(output: str, label: int) -> dict:
        ...
    ```

    Weave `Evaluation`이 실행되면 AI 시스템의 출력이 `output` 파라미터로 전달됩니다. 또한 `Evaluation`은 추가 Scorer 인수 이름을 데이터셋 열 이름과 자동으로 매칭하려고 시도합니다. Scorer 인수나 데이터셋 열을 맞춤화하기 어렵다면 열 매핑을 사용할 수 있습니다. 다음 섹션을 참조하세요.

    * **출력:** AI 시스템의 출력에 액세스하려면 Scorer 함수의 시그니처에 `output` 파라미터를 포함하세요.

    ### `column_map`으로 열 이름 매핑하기

    경우에 따라 `score` 메서드의 인수 이름이 데이터셋의 열 이름과 일치하지 않을 수 있습니다. 이럴 때 `column_map`을 사용하면 됩니다.

    클래스 기반 Scorer를 사용하는 경우, Scorer 클래스를 초기화할 때 `Scorer`의 `column_map` 속성에 딕셔너리를 전달하세요. 이 딕셔너리는 `{scorer_keyword_argument: dataset_column_name}` 형식으로 `score` 메서드의 인수 이름을 데이터셋의 열 이름에 매핑합니다.

    예시:

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

    # 요약할 뉴스 아티클 데이터셋
    dataset = [
        {"news_article": "The news today was great...", "date": "2030-04-20", "source": "Bright Sky Network"},
        ...
    ]

    # Scorer 클래스
    class SummarizationScorer(Scorer):

        @weave.op
        def score(self, output, text) -> dict:
            """
                output: LLM 요약 시스템의 출력 요약
                text: 요약할 텍스트
            """
            ...  # 요약의 품질을 평가합니다

    # `text` 인수를 `news_article` 데이터 열에 매핑하는 열 매핑으로 Scorer를 생성합니다
    scorer = SummarizationScorer(column_map={"text" : "news_article"})
    ```

    이제 `score` 메서드의 `text` 인수는 `news_article` 데이터셋 열의 데이터를 받습니다.

    **참고:**

    * 열을 매핑하는 또 다른 동일한 방법은 `Scorer`를 서브클래싱하고 `score` 메서드를 오버로드해 열을 명시적으로 매핑하는 것입니다.

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

    class MySummarizationScorer(SummarizationScorer):

        @weave.op
        def score(self, output: str, news_article: str) -> dict:  # 유형 힌트 추가됨
            # score 메서드를 오버로드하고 열을 수동으로 매핑합니다
            return super().score(output=output, text=news_article)
    ```
  </Tab>

  <Tab title="TypeScript">
    Scorer는 AI 시스템의 출력과 데이터셋 행의 내용 모두에 액세스할 수 있습니다.

    Scorer 정의에 `datasetRow` 키워드 인수를 추가하면 데이터셋 행의 관련 열에 액세스할 수 있습니다.

    ```typescript twoslash lines theme={null}
    // @noErrors
    const myScorer = weave.op(
        ({modelOutput, datasetRow}) => {
            return modelOutput * 2 === datasetRow.expectedOutputTimesTwo;
        },
        {name: 'myScorer'}
    );
    ```

    ### `columnMapping`으로 열 이름 매핑하기

    <Warning>
      TypeScript에서는 이 기능이 개별 Scorer가 아니라 `Evaluation` 객체에 있습니다.
    </Warning>

    경우에 따라 `datasetRow`의 키가 Scorer의 이름 지정 방식과 정확히 일치하지 않더라도 의미상으로는 유사할 수 있습니다. 이 경우 `Evaluation`의 `columnMapping` 옵션을 사용해 열을 매핑할 수 있습니다.

    매핑은 항상 Scorer의 관점에서 이루어지며, 즉 `{scorer_key: dataset_column_name}` 형식입니다.

    예시:

    ```typescript twoslash lines theme={null}
    // @noErrors
    const myScorer = weave.op(
        ({modelOutput, datasetRow}) => {
            return modelOutput * 2 === datasetRow.expectedOutputTimesTwo;
        },
        {name: 'myScorer'}
    );

    const myEval = new weave.Evaluation({
        dataset: [{expected: 2}],
        scorers: [myScorer],
        columnMapping: {expectedOutputTimesTwo: 'expected'}
    });
    ```
  </Tab>
</Tabs>

<div id="access-variables-from-your-ops-in-scoring-prompts">
  ### 스코어링 프롬프트에서 ops의 변수에 액세스하기
</div>

LLM-as-a-judge scorer의 스코어링 프롬프트에서는 op의 변수를 참조할 수 있습니다. Weave는 scorer가 실행될 때 이러한 값을 자동으로 추출합니다.

예를 들어 다음과 같은 함수가 있을 때:

```python theme={null}
@weave.op
def summarize_article(article: str, max_length: int) -> str:
    # 요약 로직을 여기에 작성하세요
    return summary
```

다음 변수를 사용할 수 있습니다:

| Variable       | 설명                    |
| -------------- | --------------------- |
| `{article}`    | 입력 인수 `article`의 값    |
| `{max_length}` | 입력 인수 `max_length`의 값 |
| `{inputs}`     | 모든 입력 인수의 JSON 딕셔너리   |
| `{output}`     | op의 반환 결과             |

예시 채점 프롬프트:

```text theme={null}
이 요약의 품질을 평가하세요.

원본 기사: {article}
요약: {output}
요청된 최대 길이: {max_length}

다음 기준에 따라 1-10점 척도로 요약을 평가하세요:
- 정확성: 기사를 정확하게 나타내고 있는가?
- 완전성: 핵심 사항을 다루고 있는가?
- 간결성: 적절히 간결한가?

평점과 근거가 포함된 JSON 객체를 반환하세요.
```

<div id="final-summarization-of-the-scorer">
  ### scorer의 최종 요약
</div>

<Tabs>
  <Tab title="Python">
    평가 중에는 Weave가 데이터셋의 각 행마다 scorer를 계산합니다. 평가의 최종 점수를 제공하기 위해, Weave는 출력의 반환 유형에 따라 `auto_summarize`를 실행합니다.

    `Scorer` 클래스의 `summarize` 방법을 재정의해 최종 점수를 계산하는 자신만의 방법을 제공할 수 있습니다. `summarize` 함수는 다음을 받습니다.

    * 단일 파라미터 `score_rows`: 딕셔너리 목록이며, 각 딕셔너리에는 데이터셋의 단일 행에 대해 `score` 방법이 반환한 점수가 들어 있습니다.
    * 요약된 점수가 담긴 딕셔너리를 반환합니다.

    **왜 유용할까요**

    데이터셋의 점수 최종값을 결정하기 전에 모든 행의 점수를 먼저 계산해야 할 때 유용합니다.

    ```python lines theme={null}
    class MyBinaryScorer(Scorer):
        """
        전체 출력이 대상과 일치하면 True를 반환하고, 그렇지 않으면 False를 반환합니다
        """

        @weave.op
        def score(self, output, target):
            return {"match": output == target}

        def summarize(self, score_rows: list) -> dict:
            full_match = all(row["match"] for row in score_rows)
            return {"full_match": full_match}
    ```

    > 이 예제에서는 기본 `auto_summarize`가 True의 개수와 비율을 반환합니다.

    자세한 내용은 [CorrectnessLLMJudge](/ko/weave/tutorial-rag#optional-defining-a-scorer-class)의 구현을 참조하세요.
  </Tab>

  <Tab title="TypeScript">
    평가 중에는 Weave가 데이터셋의 각 행마다 scorer를 계산합니다. 최종 점수를 제공하기 위해, Weave는 출력 유형에 따라 집계하는 내부 `summarizeResults` 함수를 사용합니다.

    Weave는 맞춤형 요약을 지원하지 않습니다.
  </Tab>
</Tabs>

<div id="apply-scorers-to-a-call">
  ### Call에 Scorer 적용하기
</div>

`weave.Evaluation`의 일부로 Scorer를 실행하는 것 외에도, 개별 call에 직접 적용할 수 있습니다. 이는 프로덕션 트래픽을 score하거나 특정 op 호출에 Evaluation 메트릭을 연결하려는 경우에 유용합니다.

Weave op에 Scorer를 적용하려면 오퍼레이션의 결과와 tracking 정보에 모두 접근할 수 있는 `.call()` 메서드를 사용하세요. 이렇게 하면 Scorer 결과를 Weave 데이터베이스의 특정 call과 연결할 수 있습니다.

`.call()` 메서드 사용에 대한 자세한 내용은 [Calling Ops](../tracking/tracing#getting-a-handle-to-the-call-object-during-execution) 가이드를 참조하세요.

<Tabs>
  <Tab title="Python">
    다음은 기본 예제입니다:

    ```python lines theme={null}
    # result와 Call 객체를 모두 조회
    result, call = generate_text.call("Say hello")

    # Scorer 적용
    score = await call.apply_scorer(MyScorer())
    ```

    동일한 call에 여러 Scorer를 적용할 수도 있습니다:

    ```python lines theme={null}
    # 여러 Scorer를 병렬로 적용
    await asyncio.gather(
        call.apply_scorer(quality_scorer),
        call.apply_scorer(toxicity_scorer)
    )
    ```

    **참고:**

    * Weave는 Scorer 결과를 데이터베이스에 자동으로 저장합니다.
    * Scorer는 메인 오퍼레이션이 완료된 후 비동기적으로 실행됩니다.
    * UI에서 Scorer 결과를 확인하거나 API를 통해 쿼리할 수 있습니다.

    프로덕션 모범 사례와 전체 예제를 포함해 guardrail 또는 monitor로 Scorer를 사용하는 방법에 대한 자세한 내용은 [Guardrails and Monitors guide](./monitors)를 참조하세요.
  </Tab>

  <Tab title="TypeScript">
    ```plaintext theme={null}
    이 기능은 아직 TypeScript에서 사용할 수 없습니다.
    ```
  </Tab>
</Tabs>

<div id="use-preprocess_model_input">
  ### `preprocess_model_input` 사용
</div>

평가 중 데이터셋 예제가 모델에 전달되기 전에 수정하려면 `preprocess_model_input` 매개변수를 사용할 수 있습니다.

<Important>
  `preprocess_model_input` 함수는 Weave가 입력을 모델의 예측 함수에 전달하기 전에만 변환합니다.

  scorer 함수는 전처리가 적용되지 않은 원래 데이터셋 예제를 항상 받습니다.
</Important>

사용 방법과 예시는 [평가 전에 `preprocess_model_input`을 사용해 데이터셋 행 형식 지정하기](../core-types/evaluations#using-preprocess_model_input-to-format-dataset-rows-before-evaluating)를 참조하세요.

<div id="score-analysis">
  ## 점수 분석
</div>

Scorer가 실행된 후에는 모델 동작을 이해하거나 버전을 비교하기 위해 Scorer가 생성한 점수를 확인해야 하는 경우가 많습니다. 다음 섹션에서는 API와 Weave UI를 모두 사용하여 단일 Call, 여러 Call, 그리고 특정 Scorer가 점수를 매긴 모든 Call의 점수를 분석하는 방법을 설명합니다.

<div id="analyze-a-single-calls-scores">
  ### 단일 Call의 점수 분석하기
</div>

<div id="single-call-api">
  #### 단일 Call API
</div>

단일 Call을 조회하려면 `get_call` 방법을 사용하세요.

```python lines theme={null}
client = weave.init("my-project")

# 단일 Call 조회
call = client.get_call("call-uuid-here")

# 점수가 포함된 Call의 피드백 조회
feedback = list(call.feedback)
```

<div id="single-call-ui">
  #### 단일 Call UI
</div>

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541/6UHHO9Wn0FEtNKHz/weave/guides/evaluation/img/call_scores_tab.png?fit=max&auto=format&n=6UHHO9Wn0FEtNKHz&q=85&s=bb4b36ef3cd9f29a7fa1396844ece2f0" alt="Call 점수 탭" width="4112" height="2328" data-path="weave/guides/evaluation/img/call_scores_tab.png" />
</Frame>

개별 Call의 점수는 Call details panel의 **점수** 탭에 표시됩니다.

<div id="analyze-multiple-calls-scores">
  ### 여러 Call의 점수 분석하기
</div>

<div id="multiple-calls-api">
  #### 여러 Call API
</div>

여러 Call을 조회하려면 `get_calls` 방법을 사용하세요.

```python lines theme={null}
client = weave.init("my-project")

# 여러 Call 조회 - 원하는 필터를 사용하고 피드백 포함
calls = client.get_calls(..., include_feedback=True)

# Call을 반복하며 점수가 포함된 피드백에 액세스
for call in calls:
    feedback = list(call.feedback)
```

<div id="multiple-calls-ui">
  #### 여러 Call UI
</div>

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541/IuXGrpyeFw4WzHgb/weave/guides/evaluation/img/traces_table_scores.png?fit=max&auto=format&n=IuXGrpyeFw4WzHgb&q=85&s=a6af79d893cf7b5ad8cfa6165e965626" alt="여러 Call 탭" width="4112" height="2328" data-path="weave/guides/evaluation/img/traces_table_scores.png" />
</Frame>

트레이스 테이블의 **점수** 열에 여러 Call의 점수가 표시됩니다.

<div id="analyze-all-calls-scored-by-a-specific-scorer">
  ### 특정 Scorer가 점수를 매긴 모든 Call 분석하기
</div>

<div id="all-calls-by-scorer-api">
  #### Scorer별 모든 Call API
</div>

특정 Scorer로 점수가 매겨진 모든 Call을 조회하려면 `get_calls` 방법을 사용하세요.

```python lines theme={null}
client = weave.init("my-project")

# Scorer의 모든 버전에서 점수가 매겨진 Call을 가져오려면 Scorer 이름(일반적으로 클래스 이름)을 사용하세요.
calls = client.get_calls(scored_by=["MyScorer"], include_feedback=True)

# 특정 버전의 Scorer에서 점수가 매겨진 Call을 가져오려면 전체 ref를 사용하세요.
# Ref는 Scorer 객체에서 가져오거나 UI를 통해 확인할 수 있습니다.
calls = client.get_calls(scored_by=[myScorer.ref.uri()], include_feedback=True)

# Call을 순회하며 점수가 포함된 피드백에 액세스합니다.
for call in calls:
    feedback = list(call.feedback)
```

<div id="all-calls-by-scorer-ui">
  #### Scorer UI에서 Scorer별 모든 call 보기
</div>

마지막으로, Scorer가 점수를 매긴 모든 call을 보려면 UI의 **Scorer** 탭으로 이동해 **Programmatic Scorer** 탭을 선택하세요. Scorer를 클릭해 Scorer 세부 정보 페이지를 여세요.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541/IuXGrpyeFw4WzHgb/weave/guides/evaluation/img/scorer_detail_page.png?fit=max&auto=format&n=IuXGrpyeFw4WzHgb&q=85&s=b7423ba46a06fe72e862c9845d7f915a" alt="Scorer 세부 정보 페이지" width="1919" height="946" data-path="weave/guides/evaluation/img/scorer_detail_page.png" />
</Frame>

다음으로, **Scores** 아래의 **View Traces** 버튼을 클릭해 Scorer가 점수를 매긴 모든 call을 확인하세요.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541/IuXGrpyeFw4WzHgb/weave/guides/evaluation/img/filtered_calls_to_scorer_version.png?fit=max&auto=format&n=IuXGrpyeFw4WzHgb&q=85&s=7f2db1dc932187fdb28fc8839b2b18c7" alt="Scorer 버전으로 필터링된 call" width="1919" height="946" data-path="weave/guides/evaluation/img/filtered_calls_to_scorer_version.png" />
</Frame>

기본적으로 선택한 Scorer 버전으로 필터링됩니다. 버전 필터를 제거하면 해당 Scorer의 모든 버전이 점수를 매긴 모든 call을 볼 수 있습니다.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541/IuXGrpyeFw4WzHgb/weave/guides/evaluation/img/filtered_calls_scorer_name.png?fit=max&auto=format&n=IuXGrpyeFw4WzHgb&q=85&s=62b13bd1438232a3d037ba74aec259b5" alt="Scorer 이름으로 필터링된 call" width="1919" height="946" data-path="weave/guides/evaluation/img/filtered_calls_scorer_name.png" />
</Frame>
