응답 스키마의 설명란에 규칙을 적고, 점수는 태도에 맞춰 보정하기
가상 사용자 의견이 서른 개 모이면 비슷한 말과 어긋난 점수가 눈에 띄어요. JSON 스키마의 설명란을 필드별 지시문으로 쓰고, 태도와 맞지 않는 점수를 서버에서 바로잡은 방법을 정리했어요.
DropThePitch에서 페르소나 한 명은 의견을 이런 모양으로 남겨요.
- 태도: 매우 부정적부터 매우 긍정적까지 다섯 단계
- 좋았던 점
- 아쉬운 점
- 고쳤으면 하는 점
- 한 줄 요약
- 1점에서 5점 사이의 점수
형식만 정해 두면 서른 명의 의견이 비슷해지거나, 태도와 점수가 어긋나는 문제가 생길 수 있어요. 이를 줄이기 위해 스키마와 서버 코드에 넣어 둔 장치를 정리했어요.
규칙은 필드 바로 옆에
JSON 스키마의 필드에는 description을 적을 수 있어요. 보통은 필드가 무엇인지 짧게 적는 곳이지만, AI에게 스키마를 넘기면 이 설명도 함께 읽어요. 그래서 이곳을 필드별 지시문으로 썼어요.
"summary": {
"type": "string",
"description": "이 자료가 어때 보였는지에 대한 한 줄 코멘트. 60자 이내 한국어 한 문장이며 해요체로 '요'로 끝나고 합쇼체를 쓰지 않는다. attitude와 같은 온도로 가장 강하게 걸린 하나만 쓴다."
}
긴 지시문 한가운데에 "요약은 60자 이내"라고 적는 대신 요약 필드 바로 옆에 적었어요. 규칙이 그 규칙을 적용할 필드와 한자리에 있으니, 지시문을 고칠 때도 어떤 필드의 규칙인지 헷갈리지 않아요.
개수도 스키마로 정해요
좋았던 점, 아쉬운 점, 고쳤으면 하는 점은 목록이에요. 개수를 정하지 않으면 어떤 페르소나는 다섯 개를 쓰고 어떤 페르소나는 하나를 써서, 리포트에서 의견의 무게가 고르지 않아요.
"positives": {
"type": "array",
"minItems": 1,
"maxItems": 2,
"description": "내가 직접 좋다고 느낀 점. 좋게 봤으면 2개, 아니면 1개."
}
개수 범위는 스키마로 강제하고, 그 안에서 몇 개를 쓸지는 설명으로 정했어요. 좋게 본 사람은 좋은 점을 두 개, 그렇지 않은 사람은 한 개를 써요. 개수 자체가 태도를 보여주게 돼요.
모두가 하는 말은 하나까지만
의견을 서른 개 모을 때 가장 경계한 것은 같은 지적의 반복이에요. "용어가 어려워요", "숫자의 근거가 없어요", "가격이 부담돼요", "개인정보가 걱정돼요". 틀린 말은 아니지만, 서른 명 중 스무 명이 같은 말을 하면 리포트가 쓸모없어져요.
그래서 아쉬운 점의 설명에 이렇게 적었어요.
자료를 본 사람 절반이 할 법한 지적(어려운 용어, 숫자의 근거, 가격 부담, 보안이나 개인정보 설명, 연락처)은 이 목록에서 1개까지만 쓰고, 나머지는 이탈 트리거, 유료 전환 기준, 불신하는 지점, 생활 패턴, 사용 기기처럼 이 프로필에서만 나오는 반응으로 쓴다.
흔한 지적을 금지하지는 않았어요. 정말 중요한 문제일 수 있으니까요. 대신 하나까지만 허용하고, 나머지는 그 페르소나의 프로필에서만 나올 수 있는 반응으로 채우게 했어요. 프로필에 적힌 항목 이름을 그대로 써서, 어디를 보면 되는지 알려 줬어요.
엉뚱한 요구를 막아요
고쳤으면 하는 점에도 막아 둔 것이 있어요. 페르소나가 자료를 고치는 방법이 아니라 "저 같은 사람을 위한 할인을 해 주세요", "체험판을 주세요" 같은 요구를 하는 경우예요. 기획자에게 필요한 것은 자료를 어떻게 고치면 좋을지인데, 요금제 요구는 도움이 되지 않아요.
이 자료의 설명 방식, 구성, 예시 화면, 빠진 설명을 어떻게 고치면 되는지에 대한 요청 하나. negatives에 쓴 주제를 요청으로 바꿔 다시 쓰지 않는다. 나 같은 사람을 위한 요금제·할인·체험판·새 기능·다른 대상용 버전을 요구하지 않는다.
"아쉬운 점을 요청으로 바꿔 다시 쓰지 않는다"는 규칙도 넣었어요. 이게 없으면 "가격 설명이 없어요"와 "가격 설명을 넣어 주세요"가 나란히 나와서 같은 말을 두 번 하게 돼요.
점수는 태도에 맞춰 보정해요
태도와 점수를 둘 다 받는 이유가 있어요. 태도는 다섯 단계라 거칠고, 점수는 소수 한 자리라 세밀해요. 리포트에서 연령대별 평균을 낼 때는 점수가 필요해요.
그런데 둘은 따로 채워지는 값이라 어긋날 수 있어요. 태도는 "부정적"인데 점수는 3.8점이 오는 식이에요. 스키마 설명에 태도별 점수 범위를 적어 두었지만, 설명은 지시일 뿐 강제가 아니에요.
VERY_NEGATIVE 1.0~1.4, NEGATIVE 1.5~2.4, NEUTRAL 2.5~3.4, POSITIVE 3.5~4.4, VERY_POSITIVE 4.5~5.0
그래서 서버에서 한 번 더 맞춰요. 태도마다 기준 점수를 두고, 받은 점수를 그 주변 범위로 잘라요.
private static final double LOWER_MARGIN = 0.5;
private static final double UPPER_MARGIN = 0.4;
public Double adjustedScore() {
if (attitude == null) {
return score;
}
double center = attitude.getScore();
double value = score == null ? center : score;
return Math.clamp(value, center - LOWER_MARGIN, center + UPPER_MARGIN);
}
"부정적"의 기준 점수는 2점이라, 받은 점수가 1.5점에서 2.4점 사이로 들어와요. 3.8점이 오면 2.4점이 돼요. 점수가 아예 없으면 기준 점수를 써요.
어긋날 때 태도를 기준으로 삼은 이유는, 태도가 의견 글 전체와 같은 방향이기 때문이에요. 좋았던 점과 아쉬운 점의 개수, 한 줄 요약의 온도가 모두 태도를 따라가도록 설명에 적어 두었어요. 점수 하나만 다르면 점수 쪽이 틀렸을 가능성이 커요.
위아래 범위를 0.5와 0.4로 다르게 잡은 것은 범위가 겹치지 않게 하려는 것이에요. 기준 점수 2점의 범위는 1.5에서 2.4, 3점의 범위는 2.5에서 3.4라서, 점수만 보고도 태도를 알 수 있어요.
정리
- 스키마의
description은 필드별 지시문으로 쓸 수 있고, 필드 바로 옆에 있어서 더 잘 지켜져요. - 목록의 개수는 스키마로 강제하고, 그 안에서의 기준은 설명으로 정해요.
- 여러 명의 의견을 모을 때는 흔한 지적을 하나로 제한하고, 그 사람만의 반응을 요구해요.
- 서로 맞아야 하는 값은 서버에서 한 번 더 맞추고, 더 믿을 만한 쪽을 기준으로 삼아요.