Skip to main content
코드 평가자는 데이터셋 예제와 애플리케이션의 결과 출력을 받아 하나 이상의 지표를 반환하는 함수입니다. 이러한 함수는 evaluate() / aevaluate()에 직접 전달할 수 있습니다.

기본 예제

from langsmith import evaluate

def correct(outputs: dict, reference_outputs: dict) -> bool:
    """Check if the answer exactly matches the expected answer."""
    return outputs["answer"] == reference_outputs["answer"]

def dummy_app(inputs: dict) -> dict:
    return {"answer": "hmm i'm not sure", "reasoning": "i didn't understand the question"}

results = evaluate(
    dummy_app,
    data="dataset_name",
    evaluators=[correct]
)

평가자 인자

코드 평가자 함수는 특정 인자 이름을 가져야 합니다. 다음 인자들 중 일부를 사용할 수 있습니다:
  • run: Run: 주어진 예제에 대해 애플리케이션이 생성한 전체 Run 객체입니다.
  • example: Example: 예제 입력, 출력(사용 가능한 경우), 메타데이터(사용 가능한 경우)를 포함한 전체 데이터셋 Example입니다.
  • inputs: dict: 데이터셋의 단일 예제에 해당하는 입력의 딕셔너리입니다.
  • outputs: dict: 주어진 inputs에 대해 애플리케이션이 생성한 출력의 딕셔너리입니다.
  • reference_outputs/referenceOutputs: dict: 예제와 연관된 참조 출력의 딕셔너리입니다(사용 가능한 경우).
대부분의 사용 사례에서는 inputs, outputs, reference_outputs만 필요합니다. runexample은 애플리케이션의 실제 입력과 출력 외에 추가 추적 정보나 예제 메타데이터가 필요한 경우에만 유용합니다. JS/TS를 사용할 때는 이들 모두를 단일 객체 인자의 일부로 전달해야 합니다.

평가자 출력

코드 평가자는 다음 타입 중 하나를 반환해야 합니다: Python 및 JS/TS
  • dict: {"score" | "value": ..., "key": ...} 형태의 딕셔너리를 사용하면 지표 타입(수치형은 “score”, 범주형은 “value”)과 지표 이름을 커스터마이징할 수 있습니다. 예를 들어 정수를 범주형 지표로 기록하고 싶을 때 유용합니다.
Python 전용
  • int | float | bool: 평균화, 정렬 등이 가능한 연속형 지표로 해석됩니다. 함수 이름이 지표 이름으로 사용됩니다.
  • str: 범주형 지표로 해석됩니다. 함수 이름이 지표 이름으로 사용됩니다.
  • list[dict]: 단일 함수를 사용하여 여러 지표를 반환합니다.

추가 예제

langsmith>=0.2.0 필요
from langsmith import evaluate, wrappers
from langsmith.schemas import Run, Example
from openai import AsyncOpenAI
# Assumes you've installed pydantic.
from pydantic import BaseModel

# We can still pass in Run and Example objects if we'd like
def correct_old_signature(run: Run, example: Example) -> dict:
    """Check if the answer exactly matches the expected answer."""
    return {"key": "correct", "score": run.outputs["answer"] == example.outputs["answer"]}

# Just evaluate actual outputs
def concision(outputs: dict) -> int:
    """Score how concise the answer is. 1 is the most concise, 5 is the least concise."""
    return min(len(outputs["answer"]) // 1000, 4) + 1

# Use an LLM-as-a-judge
oai_client = wrappers.wrap_openai(AsyncOpenAI())

async def valid_reasoning(inputs: dict, outputs: dict) -> bool:
    """Use an LLM to judge if the reasoning and the answer are consistent."""
    instructions = """
Given the following question, answer, and reasoning, determine if the reasoning for the
answer is logically valid and consistent with question and the answer."""

    class Response(BaseModel):
        reasoning_is_valid: bool

    msg = f"Question: {inputs['question']}\nAnswer: {outputs['answer']}\nReasoning: {outputs['reasoning']}"
    response = await oai_client.beta.chat.completions.parse(
        model="gpt-4o-mini",
        messages=[{"role": "system", "content": instructions,}, {"role": "user", "content": msg}],
        response_format=Response
    )
    return response.choices[0].message.parsed.reasoning_is_valid

def dummy_app(inputs: dict) -> dict:
    return {"answer": "hmm i'm not sure", "reasoning": "i didn't understand the question"}

results = evaluate(
    dummy_app,
    data="dataset_name",
    evaluators=[correct_old_signature, concision, valid_reasoning]
)

관련 항목


Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I