Documentation Index
Fetch the complete documentation index at: https://wb-21fd5541-john-wbdocs-2044-rename-serverless-products.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
_Evaluation 기반 LLM 애플리케이션 개발_은 일관되고 엄선된 예시를 사용해 동작을 체계적으로 측정함으로써 LLM 애플리케이션을 지속적으로 개선할 수 있도록 도와줍니다.
Weave에서 워크플로의 핵심은 _Evaluation 객체_이며, 다음을 정의합니다:Evaluation을 정의하고 나면, 이를 Model 객체나 LLM 애플리케이션 로직을 포함한 맞춤형 함수에 대해 실행할 수 있습니다. .evaluate()를 호출할 때마다 _평가 run_이 시작됩니다. Evaluation 객체를 설계도라고 생각하면, 각 run은 해당 설정에서 애플리케이션이 얼마나 잘 동작하는지를 측정한 결과라고 볼 수 있습니다. Weave에서 워크플로의 핵심은 _Evaluation 객체_이며, 다음을 정의합니다:Evaluation을 정의하고 나면, 이를 weave.op으로 래핑된 모든 함수에 대해 실행할 수 있습니다. .evaluate()를 호출할 때마다 _평가 run_이 시작됩니다. Evaluation 객체를 설계도라고 생각하면, 각 run은 해당 설정에서 애플리케이션이 얼마나 잘 동작하는지를 측정한 결과라고 볼 수 있습니다.TypeScript SDK는 함수 기반 모델과 scorer를 사용합니다. 클래스 기반 Model 및 Scorer 유형은 아직 TypeScript에서 사용할 수 없습니다.
평가를 시작하려면 다음 step을 완료하세요:
Evaluation 객체 생성
- 예시 테스트 데이터셋 정의
- 채점 함수 정의
- 평가할 모델 또는 함수 정의
- 평가 실행
전체 평가 코드 샘플은 여기에서 확인할 수 있습니다. 저장된 뷰 및 명령형 평가과 같은 고급 평가 기능에 대해서도 자세히 알아볼 수 있습니다.
Evaluation 객체를 만드는 것은 평가 설정을 구성하는 첫 번째 step입니다. Evaluation은 예제 데이터, 점수 산정 로직, 그리고 선택적 전처리로 구성됩니다. 이후 이를 사용해 하나 이상의 평가를 실행합니다.
Weave는 각 예제를 애플리케이션에 전달한 뒤 여러 맞춤형 점수 함수로 출력 결과를 평가합니다. 이렇게 하면 애플리케이션의 성능을 확인할 수 있는 뷰와, 개별 출력과 점수를 자세히 살펴볼 수 있는 풍부한 UI를 활용할 수 있습니다.
평가 흐름에서는 맞춤 설정할 수 있는 이름이 두 가지 있습니다:Evaluation 객체 이름 지정
Evaluation 객체 자체의 이름을 지정하려면 Evaluation 클래스에 evaluation_name 매개변수를 전달하세요. 이 이름은 코드와 UI 목록에서 Evaluation을 파악하는 데 도움이 됩니다.evaluation = Evaluation(
dataset=examples, scorers=[match_score1], evaluation_name="My Evaluation"
)
개별 평가 run 이름 지정
특정 평가 run(evaluate() 호출)의 이름을 지정하려면 display_name이 포함된 __weave 딕셔너리를 사용하세요. 그러면 해당 run에 대해 UI에 표시되는 이름이 달라집니다.evaluation = Evaluation(
dataset=examples, scorers=[match_score1]
)
evaluation.evaluate(model, __weave={"display_name": "My Evaluation Run"})
Evaluation 객체의 이름을 지정하려면 Evaluation 생성자에 id 매개변수를 전달하세요. 이 이름은 코드와 UI 목록에서 Evaluation을 파악하는 데 도움이 됩니다.const evaluation = new weave.Evaluation({
id: 'my-evaluation',
dataset: dataset,
scorers: [matchScore],
});
먼저, 평가할 예제 모음이 포함된 Dataset 객체 또는 예제 목록을 정의합니다. 이러한 예제는 보통 테스트하려는 실패 케이스이며, 테스트 주도 개발(TDD)의 단위 테스트와 비슷합니다.
다음 예제는 딕셔너리 목록으로 정의한 데이터셋을 보여줍니다:examples = [
{"question": "What is the capital of France?", "expected": "Paris"},
{"question": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
{"question": "What is the square root of 64?", "expected": "8"},
]
다음 예제는 row 배열을 포함한 Dataset 객체로 정의한 데이터셋을 보여줍니다:const dataset = new weave.Dataset({
id: 'my-dataset',
rows: [
{question: 'What is the capital of France?', expected: 'Paris'},
{question: 'Who wrote "To Kill a Mockingbird"?', expected: 'Harper Lee'},
{question: 'What is the square root of 64?', expected: '8'},
],
});
그런 다음 하나 이상의 채점 함수를 만듭니다. 이 함수들은 Dataset의 각 예제에 점수를 매기는 데 사용됩니다.
각 채점 함수에는 output 매개변수가 있어야 하며, 점수를 담은 딕셔너리를 반환해야 합니다. 필요하다면 예제의 다른 입력도 포함할 수 있습니다.채점 함수에는 output 키워드 인자가 필요하지만, 나머지 인자는 사용자가 정의하며 데이터셋 예제에서 가져옵니다. 인자 이름을 기준으로 딕셔너리 키를 매칭해 필요한 키만 사용합니다.scorer가 output 인자를 기대하는데 전달받지 못한다면, 레거시 model_output 키를 사용하고 있는지 확인하세요. 이를 해결하려면 scorer 함수에서 output을 키워드 인수로 사용하도록 업데이트하세요.
다음 예제 scorer 함수 match_score1는 채점에 examples 딕셔너리의 expected 값을 사용합니다.import weave
# 예제를 수집합니다
examples = [
{"question": "What is the capital of France?", "expected": "Paris"},
{"question": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
{"question": "What is the square root of 64?", "expected": "8"},
]
# 맞춤형 채점 함수를 정의합니다
@weave.op()
def match_score1(expected: str, output: dict) -> dict:
# 여기에서 모델 출력에 점수를 매기는 로직을 정의합니다
return {'match': expected == output['generated_text']}
(선택) 맞춤형 Scorer 클래스를 정의합니다
일부 애플리케이션에서는 맞춤형 Scorer 클래스를 만들고 싶을 수 있습니다. 예를 들어 특정 매개변수(예: chat model, prompt), 각 행에 대한 특정 채점 방식, 그리고 집계 점수의 특정 계산 방식을 갖춘 표준화된 LLMJudge 클래스를 만들 수 있습니다.자세한 내용은 RAG 애플리케이션의 모델 기반 Evaluation에서 Scorer 클래스를 정의하는 튜토리얼을 참조하세요. 각 채점 함수는 weave.op로 래핑되며, modelOutput 및 datasetRow 속성이 있는 객체를 받습니다.다음 예제 scorer 함수 matchScore는 모델 출력을 데이터셋 행의 expected 값과 비교합니다.import * as weave from "weave"
// 예제를 데이터셋으로 수집합니다
const dataset = new weave.Dataset({
id: "my-dataset",
rows: [
{ question: "What is the capital of France?", expected: "Paris" },
{ question: 'Who wrote "To Kill a Mockingbird"?', expected: "Harper Lee" },
{ question: "What is the square root of 64?", expected: "8" }
]
})
// 맞춤형 채점 함수를 정의합니다
const matchScore = weave.op(
({ modelOutput, datasetRow }) => {
return { match: modelOutput === datasetRow.expected }
},
{ name: "matchScore" }
)
클래스 기반 Scorer 유형은 아직 TypeScript에서 사용할 수 없습니다. weave.op로 래핑한 함수 기반 scorer를 사용하세요.
Model을 평가하려면 Evaluation으로 .evaluate()를 호출하세요. Models는 실험해 보고 Weave에서 캡처하려는 매개변수가 있을 때 사용합니다.from weave import Model, Evaluation
import asyncio
class MyModel(Model):
prompt: str
@weave.op()
def predict(self, question: str):
# 여기에 LLM 호출을 추가하고 출력을 반환합니다
return {'generated_text': 'Hello, ' + self.prompt}
model = MyModel(prompt='World')
evaluation = Evaluation(
dataset=examples, scorers=[match_score1]
)
weave.init('intro-example') # Weave로 결과 추적 시작
asyncio.run(evaluation.evaluate(model))
이 코드는 각 예제에 대해 predict를 실행하고, 각 채점 함수로 출력에 점수를 매깁니다.(선택 사항) 평가할 함수 정의하기
또는 @weave.op()로 추적되는 맞춤형 함수를 평가할 수도 있습니다.@weave.op
def function_to_evaluate(question: str):
# 여기에 LLM 호출을 추가하고 출력을 반환합니다
return {'generated_text': 'some response'}
asyncio.run(evaluation.evaluate(function_to_evaluate))
TypeScript에서는 weave.op으로 래핑한 함수를 평가합니다. 이 함수는 데이터셋 행을 받아 모델 출력을 반환합니다.import * as weave from "weave"
// Weave 초기화
await weave.init("intro-example")
// 평가할 함수 정의
const myModel = weave.op(
async ({ question }) => {
// 여기에 LLM 호출을 추가하고 출력을 반환합니다
return "Paris"
},
{ name: "myModel" }
)
// 평가 생성
const evaluation = new weave.Evaluation({
id: "my-evaluation",
dataset: dataset,
scorers: [matchScore]
})
// 평가 실행
const results = await evaluation.evaluate({ model: myModel })
이 코드는 각 예제에 대해 myModel을 실행하고, 각 채점 함수로 출력에 점수를 매깁니다.
평가를 실행하려면 Evaluation 객체에서 .evaluate()를 호출합니다.
evaluation이라는 Evaluation 객체와 평가할 model이라는 Model 객체가 있다고 가정하면, 다음 코드는 평가 run을 생성합니다.asyncio.run(evaluation.evaluate(model))
(선택) 여러 번 실행
각 예제를 여러 번 실행하려면 Evaluation 객체에서 trials 파라미터를 설정할 수 있습니다.evaluation = Evaluation(
dataset=examples,
scorers=[match_score],
trials=3
)
evaluation이라는 Evaluation 객체와 myModel이라는 모델 함수가 있다고 가정하면, 다음 코드는 평가를 실행합니다.const results = await evaluation.evaluate({model: myModel});
(선택) 여러 번 실행
각 예제를 여러 번 실행하려면 evaluate()를 호출할 때 nTrials 파라미터를 설정할 수 있습니다.const results = await evaluation.evaluate({
model: myModel,
nTrials: 3,
});
이 run에서는 각 예제가 모델에 세 번 전달되며, 각 run은 독립적으로 점수가 매겨지고 Weave에 개별적으로 표시됩니다.
다음 코드 샘플은 처음부터 끝까지 전체 평가 run 과정을 보여줍니다. examples 딕셔너리는 prompt 값이 주어졌을 때 MyModel을 평가하는 데 match_score1 및 match_score2 Scorer 함수에서 사용되며, 맞춤형 함수 function_to_evaluate를 평가할 때도 사용됩니다. Model과 함수에 대한 평가는 모두 asyncio.run(evaluation.evaluate())로 호출합니다.from weave import Evaluation, Model
import weave
import asyncio
weave.init('intro-example')
examples = [
{"question": "What is the capital of France?", "expected": "Paris"},
{"question": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
{"question": "What is the square root of 64?", "expected": "8"},
]
@weave.op()
def match_score1(expected: str, output: dict) -> dict:
return {'match': expected == output['generated_text']}
@weave.op()
def match_score2(expected: dict, output: dict) -> dict:
return {'match': expected == output['generated_text']}
class MyModel(Model):
prompt: str
@weave.op()
def predict(self, question: str):
# 여기에서 LLM 호출을 추가하고 출력을 반환합니다
return {'generated_text': 'Hello, ' + question + self.prompt}
model = MyModel(prompt='World')
evaluation = Evaluation(dataset=examples, scorers=[match_score1, match_score2])
asyncio.run(evaluation.evaluate(model))
@weave.op()
def function_to_evaluate(question: str):
# 여기에서 LLM 호출을 추가하고 출력을 반환합니다
return {'generated_text': 'some response' + question}
asyncio.run(evaluation.evaluate(function_to_evaluate("What is the capitol of France?")))
다음 코드 샘플은 처음부터 끝까지 전체 평가 run 과정을 보여줍니다. 데이터셋 행은 myModel을 평가하는 데 matchScore Scorer 함수에서 사용됩니다.import * as weave from "weave"
// Weave를 초기화합니다
await weave.init("intro-example")
// 예제를 데이터셋으로 모읍니다
const dataset = new weave.Dataset({
id: "my-dataset",
rows: [
{ question: "What is the capital of France?", expected: "Paris" },
{ question: 'Who wrote "To Kill a Mockingbird"?', expected: "Harper Lee" },
{ question: "What is the square root of 64?", expected: "8" }
]
})
// Scorer 함수를 정의합니다
const matchScore = weave.op(
({ modelOutput, datasetRow }) => {
return { match: modelOutput === datasetRow.expected }
},
{ name: "matchScore" }
)
// 평가할 함수를 정의합니다
const myModel = weave.op(
async ({ question }) => {
// 여기에서 LLM 호출을 추가하고 출력을 반환합니다
return "Paris"
},
{ name: "myModel" }
)
// 평가를 생성하고 실행합니다
const evaluation = new weave.Evaluation({
id: "my-evaluation",
dataset: dataset,
scorers: [matchScore]
})
const results = await evaluation.evaluate({ model: myModel })
console.log("Evaluation results:", results)
preprocess_model_input 함수는 입력이 모델의 예측 함수에 전달되기 전에만 적용됩니다. scorer 함수는 전처리가 적용되지 않은 원본 데이터셋 예제를 항상 전달받습니다.
preprocess_model_input 매개변수를 사용하면 데이터셋 예제가 평가 함수에 전달되기 전에 변환할 수 있습니다. 다음과 같은 경우에 유용합니다.
- 모델이 기대하는 입력에 맞게 필드 이름 바꾸기
- 데이터를 올바른 형식으로 변환하기
- 필드 추가 또는 제거하기
- 각 예제에 대해 추가 데이터 불러오기
다음은 preprocess_model_input를 사용해 필드 이름을 바꾸는 방법을 보여주는 간단한 예제입니다.import weave
from weave import Evaluation
import asyncio
# 데이터셋에는 "input_text"가 있지만 모델은 "question"을 기대합니다
examples = [
{"input_text": "What is the capital of France?", "expected": "Paris"},
{"input_text": "Who wrote 'To Kill a Mockingbird'?", "expected": "Harper Lee"},
{"input_text": "What is the square root of 64?", "expected": "8"},
]
@weave.op()
def preprocess_example(example):
# input_text를 question으로 이름 변경
return {
"question": example["input_text"]
}
@weave.op()
def match_score(expected: str, output: dict) -> dict:
return {'match': expected == output['generated_text']}
@weave.op()
def function_to_evaluate(question: str):
return {'generated_text': f'Answer to: {question}'}
# 전처리를 포함한 평가 생성
evaluation = Evaluation(
dataset=examples,
scorers=[match_score],
preprocess_model_input=preprocess_example
)
# 평가 실행
weave.init('preprocessing-example')
asyncio.run(evaluation.evaluate(function_to_evaluate))
이 예제에서는 데이터셋에 input_text 필드가 있는 예제가 들어 있지만, 평가 함수는 question 매개변수를 기대합니다. preprocess_example 함수는 필드 이름을 바꿔 각 예제를 변환하므로 평가가 올바르게 작동할 수 있습니다.전처리 함수는 다음과 같이 동작합니다.
- 데이터셋에서 원본 예제를 받습니다
- 모델이 기대하는 필드가 포함된 딕셔너리를 반환합니다
- 각 예제가 평가 함수에 전달되기 전에 적용됩니다
이는 모델이 기대하는 필드 이름이나 구조와 다른 외부 데이터셋으로 작업할 때 특히 유용합니다.TypeScript에서는 Evaluation 객체의 columnMapping을 사용해 데이터셋 컬럼 이름을 scorer가 기대하는 이름에 매핑할 수 있습니다. 데이터셋의 필드 이름이 scorer 함수가 기대하는 이름과 다를 때 유용합니다.다음 예제는 expectedOutputTimesTwo 컬럼을 expected 컬럼에 매핑합니다.const myScorer = weave.op(
({ modelOutput, datasetRow }) => {
return modelOutput * 2 === datasetRow.expectedOutputTimesTwo
},
{ name: "myScorer" }
)
const evaluation = new weave.Evaluation({
id: "my-evaluation",
dataset: [{ expected: 2 }],
scorers: [myScorer],
columnMapping: { expectedOutputTimesTwo: "expected" }
})
preprocess_model_input 매개변수는 아직 TypeScript에서 사용할 수 없습니다. 데이터셋 필드를 scorer가 기대하는 형식에 맞추려면 columnMapping을 사용하세요.
평가에서 HuggingFace 데이터셋 사용하기
서드파티 서비스 및 라이브러리와의 인테그레이션을 지속적으로 개선하고 있습니다.더 원활한 인테그레이션을 제공하기 위해 작업하는 동안, 현재는 Weave 평가에서 HuggingFace Datasets를 사용하기 위한 임시 우회 방법으로 preprocess_model_input을 사용할 수 있습니다.현재 방법은 평가에서 HuggingFace 데이터셋 사용 cookbook을 참조하세요. 이 기능은 현재 TypeScript에서 사용할 수 없습니다.
Evals 테이블의 설정, 필터, 정렬을 _저장된 뷰_로 저장해 선호하는 설정에 빠르게 접근할 수 있습니다. 저장된 뷰는 UI와 Python SDK에서 설정하고 사용할 수 있습니다. 자세한 내용은 저장된 뷰를 참조하세요.
명령형 평가 (EvaluationLogger)
더 유연한 평가 프레임워크를 선호한다면 Weave의 EvaluationLogger를 확인해 보세요. EvaluationLogger는 Python과 TypeScript 모두에서 사용할 수 있으며, 복잡한 워크플로에 더 유연하게 대응할 수 있습니다. 반면 표준 평가 프레임워크는 더 체계적인 구조와 가이드를 제공합니다.