대화 시나리오 테스트 케이스를 YAML로 관리하는 최소 예제
요약
본 글은 대화 시나리오 테스트 케이스를 YAML 형식으로 관리하고 검증하는 방법을 제시합니다. 질문(input), 응답(response), 기대 조건(expected condition)을 하나의 케이스에 기록하여, 나중에 조건을 변경해도 일관된 재검사가 가능하게 합니다. Node.js와 Ajv 라이브러리를 사용하여 구조적 유효성뿐만 아니라 문자열 포함/제외 여부까지 검사하는 최소 예제를 소개합니다.
핵심 포인트
- 대화 시나리오를 YAML로 관리하여 테스트 케이스의 일관성을 확보할 수 있습니다.
- Node.js와 Ajv 라이브러리를 활용해 구조적 유효성 및 문자열 조건을 검증합니다.
- 테스트는 AI 모델 호출 없이, 미리 작성된 합성 응답을 대상으로 합니다.
- 필수 키 누락이나 기대 조건 불만족 시 테스트 실패(FAIL)를 명확히 알 수 있습니다.
이 글은 Pogee의 편집 기획으로, 생성 AI를 사용하여 작성되었습니다. YAML, 설정 항목, 질문, 응답은 모두 독립적인 가상의 교재입니다. Pogee 내부 테스트 형식, 비공개 API, 실제 대화 로그는 사용하지 않았습니다. 게재된 코드는 로컬에서 실행 확인했습니다.
대화 시나리오를 확인할 때, 질문만 메모해 두면 무엇을 충족해야 합격인지 나중에 알 수 없게 됩니다. 입력(input), 확인할 응답(response), 기대하는 조건(expected condition)을 같은 케이스에 남겨두면, 조건을 변경했을 때도 동일한 검사를 재실행할 수 있습니다. 여기서는 YAML에 3개의 합성 케이스를 작성하고, Node.js로 구조와 문자열 조건을 검사합니다.
이전에는 JSON Schema로 캐릭터 설정의 구조를 확인했습니다. 이번에는 설정에서 한 단계 나아가 대화 테스트 기록을 다룹니다. 다만 AI 모델에 연결하지 않고, 미리 작성한 응답을 검사하는 최소 예제에 국한합니다. Pogee의 대화 성능을 측정한 결과가 아닙니다.
YAML이 읽히는지, 필요한 필드가 있는지, 응답이 조건을 충족하는지는 별도의 판정입니다. 예를 들어 reply가 누락되었다면 테스트 데이터의 미비점입니다. reply는 있더라도, 밤 시간대의 장면에서 기대했던 '안녕하세요'가 없다면, 이 예시에서 정의한 문자열 조건에는 불합격합니다.
그림 1: 합성 응답 3건을 검사하는 흐름과 실행 결과. AI 지원으로 작성된 설명 그림이며, Pogee의 제품 화면이나 실제 대화 테스트 결과가 아닙니다.
실행 확인은 Node.js v25.2.1, yaml 2.8.1, Ajv 8.18.0으로 진행했습니다. 빈 작업 디렉터리에서 다음을 실행하고, 이어지는 2개의 파일을 저장합니다. 샘플 코드는 CommonJS이므로 .cjs를 사용합니다.
npm init -y
npm install --save-exact [email protected] [email protected]
node check-scenarios.cjs scenarios.yaml
밤의 도서관 안내원을 가정한 가상의 예시입니다. reply는 이 교재용으로 고정된 합성 샘플이며, 모델을 호출하여 얻은 답변이 아닙니다. 마지막 greeting_regression만 기대했던 인삿말과 다른 응답을 넣었습니다. input은 실시 조건을 남기기 위한 기록이며, 이 스크립트에서 모델로 전송하는 처리는 없습니다.
version: 1
cases:
- id: evening_greeting
...
must_include는 모든 문자열이 포함되어야 함을, must_not_include는 어떤 문자열도 포함되어서는 안 됨을 의미합니다. 예시의 '전화번호'는 검사 방법을 보여주기 위한 단어이며, 이 검사만으로 개인 정보의 취득이나 누설을 포괄적으로 탐지할 수 있다는 의미가 아닙니다.
const fs = require('node:fs');
const YAML = require('yaml');
const Ajv = require('ajv');
...
Ajv에서는 필수 키, 타입, 빈 cases, 알 수 없는 키를 검사합니다. 케이스 ID의 중복은 Set으로 별도 확인합니다. YAML의 같은 매핑 내에서 키가 중복된 경우라면 yaml 파서에서 오류가 발생합니다. must_include와 must_not_include 배열은 비어 있어도 되지만, 둘 다 비어 있다면 응답 내용의 조건은 아무것도 검사하지 않습니다.
evening_greeting: PASS
unknown_fact: PASS
greeting_regression: FAIL
...
이 실행의 종료 코드는 1입니다. greeting_regression은 구조적으로 올바른 YAML이지만, reply에 '안녕하세요'가 없기 때문에 FAIL이 됩니다. 의도적인 실패 케이스이므로, 기사의 코드를 그대로 실행했을 때 종료 코드 1이 되는 것은 예상대로입니다.
마지막 reply를 '안녕하세요. 어떤 책을 찾으시나요?'로 수정하면, 이 케이스의 문자열 조건도 충족합니다. 검사 코드는 전체 합격 시 0, 응답 조건 실패 시 1, YAML 파싱이나 데이터 구조 미비 시 2를 반환합니다. 다른 합성 입력으로 정상 종료 0, expect 누락, 케이스 ID 중복, YAML 키 중복에 의한 종료 2도 확인했습니다.
includes는 부분 문자열의 일치입니다. 예를 들어 '안녕하세요라고 말할 필요는 없습니다'에도 '안녕하세요'가 포함됩니다. 반대로 '오늘밤은'과 같은 표기 차이는 일치하지 않습니다. 인사말의 자연스러움, 문맥에 맞는 의미, 설정의 일관성, 안전성까지 자동으로 판단한 것은 아닙니다.
실제 생성 응답을 검사하는 단계에서는 입력과 출력 외에도 실행 일시, 모델 식별 정보, 생성 조건, 케이스 버전 등을 기록하면 비교의 전제를 추적하기 용이합니다. 실제 로그를 사용하는 경우, 공개해도 되는 내용인지 별도로 확인해야 합니다. 이 교재에는 실존 사용자의 입력이나 비공개 데이터는 포함되어 있지 않습니다.
먼저 YAML을 팀원들이 읽을 수 있는 케이스 모음으로 만들고, 기계로 확인할 수 있는 단순 조건과 사람이 의미를 판단하는 관점을 분리합니다. 이런 형태라면 실패했을 때 '데이터의 부재'와 '응답에 대한 기대 불일치'를 구분할 수 있습니다.
AI 캐릭터의 프로필과 대화를 구상하는 배경으로는 Pogee의 공개 가이드도 참고할 수 있습니다. 본 기사의 필드나 검사 코드는 해당 가이드로부터 내부 구성을 추정한 것이 아닙니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기