Vercel의 AI SDK와 Vitest로 LLM Eval 작성하기: 실전 가이드
2025-04-03 23:15:40Vercel의 AI SDK와 Vitest로 LLM Eval 작성하기
기업 환경에서 데이터베이스의 성능과 안정성은 필수적입니다. 특히, PostgreSQL과 같은 대규모 데이터베이스를 관리할 때 그 중요성은 더욱 두드러집니다. 최근 Xata에서 출시한 오픈 소스 AI 에이전트인 Xata Agent는 이러한 문제를 해결하기 위한 강력한 도구입니다. 이 글에서는 Xata Agent의 성능을 지속적으로 평가하기 위해 사용된 Vercel의 AI SDK와 Vitest를 기반으로 한 Eval 작성 방법을 소개합니다.
Xata Agent란?
Xata Agent는 PostgreSQL 데이터베이스의 문제를 진단하고 최적화 방법을 제안하는 AI 기반의 오픈 소스 에이전트입니다. 데이터베이스를 운용하다 보면, 종종 성능 이슈나 최적화 기회가 발생합니다. 이때 Xata Agent는 데이터베이스의 상태를 분석하고, 문제점을 파악하며 실시간으로 최적화 방안을 제시합니다. 자세히 알아보기
Eval의 중요성
Xata Agent와 같은 애플리케이션은 LLM(Large Language Model)을 활용해 특정 기능을 수행합니다. 그러나 LLM은 내부 작동이 불명확한 '블랙 박스'입니다. 쉽게 말해, 같은 입력에 대해서도 결과가 어떻게 나올지 확실히 알 수 없는 경우가 많습니다. 이를 정확히 평가하기 위해 Eval이 필요합니다.
Eval은 시스템 테스트와 유사하지만, LLM의 불확실성에 특별히 초점을 맞춘 일종의 통합 테스트입니다. Xata Agent의 다양한 프롬프트와 도구 호출이 제대로 작동하는지 검증하기 위해 Eval을 실행합니다.
Eval 실행 결과
Eval을 실행하면 각 테스트 케이스에 대한 결과를 포함하는 디렉토리가 생성됩니다. 결과 디렉토리에는 실행 결과 파일과 디버깅을 위한 '추적' 정보가 포함되어 있습니다. 이러한 파일들은 Xata Agent의 성능을 평가하는 데 필요한 모든 정보를 포함하는 완전한 응답 객체를 제공합니다.
./eval-run-output/
├── evalResults.json
├── eval_id_1
│ ├── evalResult.json
│ ├── human.txt
│ ├── judgeResponse.txt
│ └── response.json
├── eval_id_2
│ ├── evalResult.json
│ ├── human.txt
│ ├── judgeResponse.txt
│ └── response.json
Vercel AI SDK 사용하기
Eval을 수행하기 위해 우리는 Vercel의 AI SDK를 이용해 다양한 모델과 도구 호출을 실행합니다. 이들 응답 객체는 최종 텍스트 응답, 도구 호출 및 모델의 중간 '생각' 과정을 포함하며, 이를 통해 Xata Agent의 성능을 평가할 수 있습니다. 그런 다음 인간이 쉽게 읽을 수 있는 형식으로 변환합니다.
예시
System Prompt:
You are an AI assistant expert in PostgreSQL and database administration.
Your name is Xata Agent.
--------
User Prompt: What tables do I have in my db?
--------
Step: 1
I'll help you get an overview of the tables in your database. I'll use the getTablesAndInstanceInfo tool to retrieve this information.
getTablesAndInstanceInfo with args: {}
Tool Result:
Here are the tables, their sizes, and usage counts:
[{"name":"dogs","schema":"public","rows":150,"size":"24 kB","seqScans":45,"idxScans":120,"nTupIns":200,"nTupUpd":50,"nTupDel":10}]
...
사용자 정의 UI 구축
우리 팀은 모든 출력을 확인하고 특정 Eval 실행에서 어떤 일이 발생했는지 빠르게 디버깅할 수 있도록 맞춤 UI를 제작했습니다.
Vitest를 이용한 Eval 실행
Vitest는 TypeScript 환경에서 인기 있는 테스트 프레임워크입니다. 우리가 원하는 폴더 구조를 만들기 위해 Vitest의 몇 가지 기능을 활용했습니다.
Eval 실행 ID 획득
Eval 테스트의 각 실행에 대해 일관성 있는 ID를 얻기 위해 Vitest의 globalSetup에서 TEST_RUN_ID 환경 변수를 설정합니다.
import { randomUUID } from 'crypto';
export default async function globalSetup() {
process.env.TEST_RUN_ID = randomUUID();
}
이 ID는 다음과 같이 Eval 실행 폴더에 참조됩니다: path.join('/tmp/eval-runs/', process.env.TEST_RUN_ID)
개별 Eval ID 획득
각각의 개별 Eval 테스트 케이스에 대한 ID 획득은 조금 복잡합니다. LLM 호출은 시간이 걸리기 때문에 Vitest 테스트를 병렬로 실행해야 하며, 이는 describe.concurrent를 통해 가능합니다. 그러나 테스트 이름이 올바르게 지정되었는지 확인하기 위해 테스트의 expect 변수를 로컬 복사본으로 사용해야 합니다.
새로운 Reporter와 Eval 결과 결합
Vitest의 리포터를 활용해 테스트 실행 중 또는 후에 코드를 실행할 수 있습니다. 우리는 개별 Eval의 결과를 중앙 서버에 업로드하거나, 로컬 파일 시스템에 저장하여 추후 참고할 수 있습니다.
결론
Vercel의 AI SDK와 Vitest는 TypeScript에서 Eval을 실행하는 데 매우 유용한 도구입니다. 특히 Xata Agent와 같은 데이터베이스 관리 도구의 성능을 평가하고, 개선점을 찾아내는 데 큰 도움이 될 것입니다. 팀의 안정성과 효율성을 높이고 싶다면, 이 방법을 고려해 보십시오.
유용한 링크
이 글이 PostgreSQL과 같은 대규모 데이터베이스의 관리 및 최적화에 관심 있는 분들께 도움이 되길 바랍니다.