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

# Scoring overview

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

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

<Tabs>
  <Tab title="Python">
    Scorers는 평가 중 `weave.Evaluation` 객체에 전달됩니다. Weave에는 두 가지 유형의 Scorers가 있습니다:

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

    Scorers는 반드시 딕셔너리를 반환해야 하며, 여러 메트릭, 중첩된 메트릭, 그리고 추론에 대한 LLM 평가자의 텍스트처럼 숫자가 아닌 값도 반환할 수 있습니다.
  </Tab>

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

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

<Tip>
  **바로 사용할 수 있는 Scorers**
  이 가이드에서는 맞춤형 Scorer를 만드는 방법을 설명하지만, Weave에는 바로 사용할 수 있는 다양한 [기본 제공 Scorers](./builtin_scorers)와 [로컬 SLM Scorers](./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">
  ### 함수 기반 Scorers
</div>

<Tabs>
  <Tab title="Python">
    이는 딕셔너리를 반환하는 `@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">
  ## Scorers의 작동 방식
</div>

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

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

    * **입력:** Scorer가 데이터셋 행의 `"label"` 또는 `"target"` 열 같은 데이터를 사용하게 하려면, 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` 속성에 딕셔너리를 전달하세요. 이 딕셔너리는 `score` 방법의 인수 이름을 데이터셋의 열 이름에 매핑하며, 형식은 `{scorer_keyword_argument: dataset_column_name}`입니다.

    예시:

    ```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">
    Scorers는 AI 시스템의 출력과 데이터셋 행의 내용 모두에 접근할 수 있습니다.

    scorer 정의에 `datasetRow` 키워드 인수를 추가하면 데이터셋 행의 관련 열에 쉽게 접근할 수 있습니다.

    ```typescript lines theme={null}
    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 lines theme={null}
    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의 변수를 참조할 수 있습니다. 이러한 값은 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">
    평가 중에는 데이터셋의 각 행마다 scorer가 계산됩니다. 평가의 최종 점수를 제공하기 위해, 출력 반환 유형에 따라 `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">
    평가 중에는 데이터셋의 각 행마다 scorer가 계산됩니다. 최종 점수를 제공하기 위해, 출력 유형에 따라 집계하는 내부 `summarizeResults` 함수를 사용합니다.

    * 숫자 열은 평균을 계산합니다
    * 불리언 열은 개수와 비율을 계산합니다
    * 그 밖의 열 유형은 무시됩니다

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

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

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

`.call()` 사용 방법에 대한 자세한 내용은 [Calling Ops](../tracking/tracing#calling-ops#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에 여러 Scorers를 적용할 수도 있습니다:

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

    **참고:**

    * Scorer 결과는 Weave 데이터베이스에 자동으로 저장됩니다
    * 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` 함수는 입력이 모델의 예측 함수에 전달되기 전에만 변환합니다.

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

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

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

이 섹션에서는 단일 Call, 여러 Call, 그리고 특정 Scorer가 점수를 매긴 모든 Call의 점수를 분석하는 방법을 설명합니다.

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

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

단일 Call에 대한 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-docs-hivemind-launch/HbhUDAG_r2i2K_Pk/weave/guides/evaluation/img/call_scores_tab.png?fit=max&auto=format&n=HbhUDAG_r2i2K_Pk&q=85&s=4d42bc041f61f8ab78b597c2ae5ca5ec" 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의 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-docs-hivemind-launch/HbhUDAG_r2i2K_Pk/weave/guides/evaluation/img/traces_table_scores.png?fit=max&auto=format&n=HbhUDAG_r2i2K_Pk&q=85&s=a83322a5ef4fd70860fc1c0ebaa41fae" 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가 점수를 매긴 모든 Calls 분석
</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의 Scorers 탭으로 이동해 `Programmatic Scorer` 탭을 선택하세요. Scorer를 클릭해 Scorer 세부 정보 페이지를 여세요.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-docs-hivemind-launch/HbhUDAG_r2i2K_Pk/weave/guides/evaluation/img/scorer_detail_page.png?fit=max&auto=format&n=HbhUDAG_r2i2K_Pk&q=85&s=af67652705e83c0badaff1cec24e9347" 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-docs-hivemind-launch/HbhUDAG_r2i2K_Pk/weave/guides/evaluation/img/filtered_calls_to_scorer_version.png?fit=max&auto=format&n=HbhUDAG_r2i2K_Pk&q=85&s=214a0be29fb6ca62dbd7e14560bf1475" 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-docs-hivemind-launch/HbhUDAG_r2i2K_Pk/weave/guides/evaluation/img/filtered_calls_scorer_name.png?fit=max&auto=format&n=HbhUDAG_r2i2K_Pk&q=85&s=533b0eaa2fb9bec794be25f43edc4b6f" alt="Scorer 이름으로 필터링된 call" width="1919" height="946" data-path="weave/guides/evaluation/img/filtered_calls_scorer_name.png" />
</Frame>
