평가는 LLM의 응답을 검증하고 품질 기준을 충족하는지 확인하는 데 도움이 되는 테스트의 한 형태입니다.
Firebase Genkit은 플러그인을 통해 서드 파티 평가 도구를 지원하며, LLM 기반 애플리케이션의 런타임 상태에 대한 통계를 제공하는 강력한 관측 가능성 기능과 함께 제공됩니다. Genkit 도구를 사용하면 중간 단계에서 입력, 출력, 정보를 비롯한 데이터를 자동으로 추출하여 LLM 응답의 엔드 투 엔드 품질을 평가하고 시스템 빌딩 블록의 성능을 파악할 수 있습니다.
평가 유형
Genkit은 다음 두 가지 유형의 평가를 지원합니다.
추론 기반 평가: 이 유형의 평가는 사전 결정된 입력 모음을 대상으로 실행되며, 해당 출력의 품질을 평가합니다.
가장 일반적인 평가 유형으로 대부분의 사용 사례에 적합합니다. 이 접근 방식은 각 평가 실행에 대해 시스템의 실제 출력을 테스트합니다.
결과를 시각적으로 검사하여 품질 평가를 수동으로 실행할 수 있습니다. 또는 평가 측정항목을 사용하여 평가를 자동화할 수 있습니다.
원시 평가: 이 유형의 평가는 추론 없이 입력의 품질을 직접 평가합니다. 이 접근 방식은 일반적으로 측정항목을 사용하는 자동 평가와 함께 사용됩니다. 평가에 필요한 모든 필드 (예:
input
,context
,output
,reference
)가 입력 데이터 세트에 있어야 합니다. 외부 소스 (예: 프로덕션 트레이스에서 수집됨)에서 가져온 데이터가 있고 수집된 데이터의 품질을 객관적으로 측정하려는 경우에 유용합니다.자세한 내용은 이 페이지의 고급 사용 섹션을 참고하세요.
이 섹션에서는 Genkit을 사용하여 추론 기반 평가를 실행하는 방법을 설명합니다.
빠른 시작
설정
- 기존 Genkit 앱을 사용하거나 [시작하기](get-started.md) 가이드를 따라 새 앱을 만듭니다.
- 다음 코드를 추가하여 평가할 간단한 RAG 애플리케이션을 정의합니다. 이 가이드에서는 항상 동일한 문서를 반환하는 더미 검색 도구를 사용합니다.
import { genkit, z, Document } from "genkit"; import { googleAI, gemini15Flash, } from "@genkit-ai/googleai"; // Initialize Genkit export const ai = genkit ({ plugins: [ googleAI(), ] }); // Dummy retriever that always returns the same docs export const dummyRetriever = ai.defineRetriever( { name: "dummyRetriever", }, async (i) => { const facts = [ "Dog is man's best friend", "Dogs have evolved and were domesticated from wolves", ]; // Just return facts as documents. return { documents: facts.map((t) => Document.fromText(t)) }; } ); // A simple question-answering flow export const qaFlow = ai.defineFlow({ name: 'qaFlow', inputSchema: z.string(), outputSchema: z.string(), }, async (query) => { const factDocs = await ai.retrieve({ retriever: dummyRetriever, query, }); const llmResponse = await ai.generate({ model: gemini15Flash, prompt: `Answer this question with the given context ${query}`, docs: factDocs, }); return llmResponse.text; } );
- (선택사항) 평가하는 동안 사용할 평가 측정항목을 애플리케이션에 추가합니다. 이 가이드에서는
genkitEval
플러그인의MALICIOUSNESS
측정항목을 사용합니다. 참고: 위 구성을 사용하려면import { genkitEval, GenkitMetric } from "@genkit-ai/evaluator"; import { gemini15Pro } from "@genkit-ai/googleai"; export const ai = genkit ({ plugins: [ ... // Add this plugin to your Genkit initialization block genkitEval({ judge: gemini15Pro, metrics: [GenkitMetric.MALICIOUSNESS], }), ] });
@genkit-ai/evaluator
패키지를 설치해야 합니다.npm install @genkit-ai/evaluator
- Genkit 애플리케이션을 시작합니다.
genkit start --
데이터 세트 만들기
흐름을 평가하는 데 사용할 예시를 정의하는 데이터 세트를 만듭니다.
http://localhost:4000
의 Dev UI로 이동하여 데이터 세트 버튼을 클릭하여 데이터 세트 페이지를 엽니다.데이터 세트 만들기 버튼을 클릭하여 데이터 세트 만들기 대화상자를 엽니다.
a. 새 데이터 세트에
datasetId
를 제공합니다. 이 가이드에서는myFactsQaDataset
을 사용합니다.b.
Flow
데이터 세트 유형을 선택합니다.c. 유효성 검사 타겟 필드는 비워두고 저장을 클릭합니다.
새 데이터 세트 페이지가 표시되고 빈 데이터 세트가 표시됩니다. 다음 단계에 따라 예시를 추가합니다.
a. 예시 추가 버튼을 클릭하여 예시 편집기 패널을 엽니다.
b.
input
필드만 필요합니다.input
필드에"Who is man's best friend?"
를 입력하고 저장을 클릭하여 데이터 세트에 예시 has를 추가합니다.c. (a) 및 (b) 단계를 몇 번 더 반복하여 예시를 추가합니다. 이 가이드에서는 데이터 세트에 다음과 같은 입력 예시를 추가합니다.
"Can I give milk to my cats?" "From which animals did dogs evolve?"
이 단계가 끝나면 데이터 세트에 위에 언급된 값이 포함된 예시가 3개 있어야 합니다.
평가 실행 및 결과 보기
흐름 평가를 시작하려면 데이터 세트 페이지에서 새 평가 실행 버튼을 클릭합니다. 평가 탭에서 새 평가를 시작할 수도 있습니다.
Flow
라디오 버튼을 선택하여 흐름을 평가합니다.평가할 대상 흐름으로
qaFlow
를 선택합니다.평가에 사용할 대상 데이터 세트로
myFactsQaDataset
를 선택합니다.(선택사항) Genkit 플러그인을 사용하여 평가자 측정항목을 설치한 경우 이 페이지에서 이러한 측정항목을 확인할 수 있습니다. 이 평가 실행에 사용할 측정항목을 선택합니다. 이는 완전히 선택사항입니다. 이 단계를 생략해도 평가 실행에서 결과가 반환되지만 연결된 측정항목은 반환되지 않습니다.
마지막으로 평가 실행을 클릭하여 평가를 시작합니다. 테스트하는 흐름에 따라 다소 시간이 걸릴 수 있습니다. 평가가 완료되면 결과를 볼 수 있는 링크가 포함된 성공 메시지가 표시됩니다. 링크를 클릭하여 평가 세부정보 페이지로 이동합니다.
이 페이지에서 원래 입력, 추출된 맥락, 측정항목 (있는 경우)을 포함한 평가 세부정보를 확인할 수 있습니다.
핵심 개념
용어
평가: 평가는 시스템 성능을 평가하는 프로세스입니다. Genkit에서 이러한 시스템은 일반적으로 흐름이나 모델과 같은 Genkit 원시입니다. 평가는 자동화되거나 수동 (인간 평가)으로 진행될 수 있습니다.
일괄 추론 추론은 흐름이나 모델에서 입력을 실행하여 상응하는 출력을 가져오는 작업입니다. 일괄 추론에는 여러 입력에 대해 동시에 추론을 실행하는 것이 포함됩니다.
측정항목 평가 측정항목은 추론에 점수를 부여하는 기준입니다. 정확성, 충실도, 악의성, 출력이 영어인지 여부 등이 여기에 해당합니다.
데이터 세트 데이터 세트는 추론 기반 평가에 사용할 예시 모음입니다. 데이터 세트는 일반적으로
input
필드와 선택적reference
필드로 구성됩니다.reference
필드는 평가의 추론 단계에 영향을 미치지 않지만 모든 평가 측정항목에 그대로 전달됩니다. Genkit에서는 Dev UI를 통해 데이터 세트를 만들 수 있습니다. Genkit에는 흐름 데이터 세트와 모델 데이터 세트라는 두 가지 유형의 데이터 세트가 있습니다.
스키마 검증
유형에 따라 개발자 UI에서 데이터 세트의 스키마 유효성 검사가 지원됩니다.
흐름 데이터 세트는 Genkit 애플리케이션의 흐름에 대해 데이터 세트의
input
및reference
필드의 유효성 검사를 지원합니다. 스키마 유효성 검사는 선택사항이며 대상 흐름에 스키마가 지정된 경우에만 적용됩니다.모델 데이터 세트에는
string
및GenerateRequest
입력 유형을 모두 지원하는 암시적 스키마가 있습니다. 문자열 유효성 검사는 간단한 텍스트 프롬프트를 평가하는 편리한 방법을 제공하는 반면GenerateRequest
는 고급 사용 사례 (예: 모델 매개변수, 메시지 기록, 도구 제공)를 위한 완전한 제어 기능을 제공합니다.GenerateRequest
의 전체 스키마는 API 참조 문서에서 확인할 수 있습니다.
지원되는 평가자
Genkit 평가자
Genkit에는 시작하는 데 도움이 되는 RAGAS에서 영감을 받은 소수의 네이티브 평가자가 포함되어 있습니다.
- 충실도: 생성된 답변이 주어진 맥락에 대해 사실적으로 일관적인지 측정합니다.
- 답변 관련성: 생성된 답변이 주어진 프롬프트와 얼마나 관련성이 있는지 평가합니다.
- 악의성: 생성된 출력이 속이거나 해를 입히거나 악용하는 의도를 가지고 있는지 측정합니다.
평가자 플러그인
Genkit은 VertexAI 플러그인을 통해 액세스할 수 있는 Vertex Rapid Evaluator와 같은 플러그인을 통해 추가 평가자를 지원합니다.
고급 사용
CLI를 사용한 평가
Genkit CLI는 평가를 실행하기 위한 풍부한 API를 제공합니다. 이는 Dev UI를 사용할 수 없는 환경 (예: CI/CD 워크플로)에서 특히 유용합니다.
Genkit CLI는 eval:flow
, eval:extractData
, eval:run
라는 세 가지 기본 평가 명령어를 제공합니다.
eval:flow
명령어
eval:flow
명령어는 입력 데이터 세트에서 추론 기반 평가를 실행합니다.
이 데이터 세트는 JSON 파일로 제공되거나 Genkit 런타임에서 기존 데이터 세트를 참조하여 제공될 수 있습니다.
# Referencing an existing dataset genkit eval:flow qaFlow --input myFactsQaDataset
# or, using a dataset from a file genkit eval:flow qaFlow --input testInputs.json
여기서 testInputs.json
는 아래와 같이 input
필드와 선택사항인 reference
필드가 포함된 객체 배열이어야 합니다.
[
{
"input": "What is the French word for Cheese?",
},
{
"input": "What green vegetable looks like cauliflower?",
"reference": "Broccoli"
}
]
흐름에 인증이 필요한 경우 --context
인수를 사용하여 지정할 수 있습니다.
genkit eval:flow qaFlow --input testInputs.json --context '{"auth": {"email_verified": true}}'
기본적으로 eval:flow
및 eval:run
명령어는 평가에 사용 가능한 모든 측정항목을 사용합니다. 구성된 평가자의 하위 집합에서 실행하려면 --evaluators
플래그를 사용하고 이름별로 평가자 목록을 쉼표로 구분하여 제공합니다.
genkit eval:flow qaFlow --input testInputs.json --evaluators=genkitEval/maliciousness,genkitEval/answer_relevancy
Dev UI(localhost:4000/evaluate
)에서 평가 실행 결과를 확인할 수 있습니다.
eval:extractData
및 eval:run
명령어
원시 평가를 지원하기 위해 Genkit은 트레이스에서 데이터를 추출하고 추출된 데이터에 평가 측정항목을 실행하는 도구를 제공합니다. 이는 예를 들어 평가에 다른 프레임워크를 사용하거나 다른 환경에서 추론을 수집하여 로컬에서 출력 품질을 테스트하는 경우에 유용합니다.
Genkit 흐름을 일괄 실행하고 실행에 고유한 라벨을 추가할 수 있으며, 이 라벨은 평가 데이터 세트를 추출하는 데 사용할 수 있습니다. 원시 평가 데이터 세트는 이전 추론을 실행하지 않고 평가 측정항목의 입력 모음입니다.
테스트 입력에 대해 흐름을 실행합니다.
genkit flow:batchRun qaFlow testInputs.json --label firstRunSimple
평가 데이터를 추출합니다.
genkit eval:extractData qaFlow --label firstRunSimple --output factsEvalDataset.json
내보낸 데이터의 형식은 앞에서 설명한 데이터 세트 형식과 다릅니다. 이는 이 데이터가 추론 단계 없이 평가 측정항목과 직접 사용되도록 하기 때문입니다. 다음은 추출된 데이터의 문법입니다.
Array<{
"testCaseId": string,
"input": any,
"output": any,
"context": any[],
"traceIds": string[],
}>;
데이터 추출기는 검색 도구를 자동으로 찾아 생성된 문서를 컨텍스트 배열에 추가합니다. eval:run
명령어를 사용하여 추출된 데이터 세트에서 평가 메트릭을 실행할 수 있습니다.
genkit eval:run factsEvalDataset.json
기본적으로 eval:run
는 구성된 모든 평가자에 대해 실행되며 eval:flow
와 마찬가지로 eval:run
의 결과는 localhost:4000/evaluate
에 있는 개발자 UI의 평가 페이지에 표시됩니다.
맞춤 추출기
Genkit은 평가를 실행하는 동안 필요한 필드(input
, output
, context
)를 추출하기 위한 합리적인 기본 로직을 제공합니다. 하지만 이러한 필드의 추출 로직을 더 세부적으로 제어해야 할 수 있습니다.
Genkit은 이를 위해 맞춤 추출기를 지원합니다. eval:extractData
및 eval:flow
명령어에 사용할 맞춤 추출기를 제공할 수 있습니다.
먼저 준비 단계로 qaFlow
예에 보조 단계를 도입합니다.
export const qaFlow = ai.defineFlow({
name: 'qaFlow',
inputSchema: z.string(),
outputSchema: z.string(),
},
async (query) => {
const factDocs = await ai.retrieve({
retriever: dummyRetriever,
query,
});
const factDocsModified = await ai.run('factModified', async () => {
// Let us use only facts that are considered silly. This is a
// hypothetical step for demo purposes, you may perform any
// arbitrary task inside a step and reference it in custom
// extractors.
//
// Assume you have a method that checks if a fact is silly
return factDocs.filter(d => isSillyFact(d.text));
});
const llmResponse = await ai.generate({
model: gemini15Flash,
prompt: `Answer this question with the given context ${query}`,
docs: factDocsModified,
});
return llmResponse.text;
}
);
그런 다음 이 흐름을 평가할 때 factModified
단계의 출력을 사용하도록 맞춤 추출기를 구성합니다.
맞춤 추출기를 구성할 tools-config 파일이 없는 경우 프로젝트 루트에 genkit-tools.conf.js
라는 파일을 추가합니다.
cd /path/to/your/genkit/app
touch genkit-tools.conf.js
도구 구성 파일에 다음 코드를 추가합니다.
module.exports = {
evaluators: [
{
actionRef: '/flow/qaFlow',
extractors: {
context: { outputOf: 'factModified' },
},
},
],
};
이 구성은 Genkit 도구의 기본 추출기를 재정의하며, 특히 이 흐름을 평가할 때 context
로 간주되는 항목을 변경합니다.
평가를 다시 실행하면 컨텍스트가 이제 factModified
단계의 출력으로 채워집니다.
genkit eval:flow qaFlow --input testInputs.json
평가 추출기는 다음과 같이 지정됩니다.
evaluators
필드는flowName
에 의해 범위가 지정된 EvaluatorConfig 객체 배열을 허용합니다.extractors
는 추출기 재정의를 지정하는 객체입니다.extractors
에서 현재 지원되는 키는[input, output, context]
입니다. 허용되는 값 유형은 다음과 같습니다.string
- 문자열로 지정된 단계 이름입니다. 이 단계의 출력은 이 키에 대해 추출됩니다.{ inputOf: string }
또는{ outputOf: string }
- 이러한 객체는 단계의 특정 채널 (입력 또는 출력)을 나타냅니다. 예를 들어{ inputOf: 'foo-step' }
은 이 키의foo-step
단계 입력을 추출합니다.(trace) => string;
- 더 유연하게 하려면 Genkit 트레이스를 수락하고any
유형 값을 반환하는 함수를 제공하고 이 함수 내에 추출 로직을 지정할 수 있습니다. 정확한 TraceData 스키마는genkit/genkit-tools/common/src/types/trace.ts
를 참고하세요.
참고: 이러한 모든 추출기의 추출된 데이터는 추출기에 해당하는 유형입니다. 예를 들어 context: { outputOf: 'foo-step' }
를 사용하고 foo-step
가 객체 배열을 반환하는 경우 추출된 컨텍스트도 객체 배열입니다.
LLM을 사용하여 테스트 데이터 합성
다음은 PDF 파일을 사용하여 잠재적 사용자 질문을 생성하는 흐름의 예입니다.
import { genkit, z } from "genkit";
import { googleAI, gemini15Flash } from "@genkit-ai/googleai";
import { chunk } from "llm-chunk"; // npm i llm-chunk
import path from "path";
import { readFile } from "fs/promises";
import pdf from "pdf-parse"; // npm i pdf-parse
const ai = genkit({ plugins: [googleAI()] });
const chunkingConfig = {
minLength: 1000, // number of minimum characters into chunk
maxLength: 2000, // number of maximum characters into chunk
splitter: "sentence", // paragraph | sentence
overlap: 100, // number of overlap chracters
delimiters: "", // regex for base split method
} as any;
async function extractText(filePath: string) {
const pdfFile = path.resolve(filePath);
const dataBuffer = await readFile(pdfFile);
const data = await pdf(dataBuffer);
return data.text;
}
export const synthesizeQuestions = ai.defineFlow(
{
name: "synthesizeQuestions",
inputSchema: z.string().describe("PDF file path"),
outputSchema: z.array(z.string()),
},
async (filePath) => {
filePath = path.resolve(filePath);
// `extractText` loads the PDF and extracts its contents as text.
const pdfTxt = await ai.run("extract-text", () => extractText(filePath));
const chunks = await ai.run("chunk-it", async () =>
chunk(pdfTxt, chunkingConfig)
);
const questions: string[] = [];
for (var i = 0; i < chunks.length; i++) {
const qResponse = await ai.generate({
model: gemini15Flash,
prompt: {
text: `Generate one question about the text below: ${chunks[i]}`,
},
});
questions.push(qResponse.text);
}
return questions;
}
);
그런 다음 이 명령어를 사용하여 데이터를 파일로 내보내고 평가에 사용할 수 있습니다.
genkit flow:run synthesizeQuestions '"my_input.pdf"' --output synthesizedQuestions.json