Jev의 자신감 없는 답변은 채택하지 않기: confidence 임계값에 대한 논의
요약
기술 기사에서는 보안 뉴스 분류 정확도를 높이기 위해 프롬프트 개선보다 '질문 분리'와 '자신감 임계값(confidence threshold)'을 활용하는 것이 더 효과적임을 제시합니다. 특히, 낮은 confidence 값으로 인해 잘못된 답변을 걸러내는 방식이 높은 정확도를 유지하면서도 누락되는 올바른 사례를 최소화할 수 있음을 보여줍니다.
핵심 포인트
- 프롬프트 개선보다 질문 분리 및 코드 측 폐기가 더 효과적입니다.
- 자신감 임계값(confidence threshold) 설정은 오류 방지에 매우 유용합니다.
- 임계값을 통해 잘못된 답변을 걸러내면서도 올바른 사례를 포기하는 위험을 최소화할 수 있습니다.
지난 글에서는 보안 뉴스 기사를 도도부현(都道府県)별로 분류하는 처리를 문자열 일치 방식에서 Jev로 대체하기로 결정한 내용을 작성했습니다.
이번에는 실제 운영 환경에 도입하기 전에 분류 정확도를 높이기 위해 시도했던 개선 사항에 대해 이야기하겠습니다.
먼저 결론부터 말씀드리자면, 프롬프트(prompt)를 고안하는 것보다 질문을 분리하고, 자신감이 없는 답변은 코드 측에서 폐기하는 것이 더 효과적이었습니다.
최근 200건의 기사를 대상으로 구 방식(문자열 일치)과 Jev를 비교한 결과입니다.
| 판정 | 건수 |
|---|---|
| 양측 모두 '해당 없음' | 163 |
| ... | |
| Jev는 기사에 도도부현이 적혀 있지 않아도 피해 조직의 본사 소재지를 추론하여 분류할 수 있다는 것을 알게 되었습니다. |
차이점 11건은 Jev가 전승(全勝)했지만, 양측 모두 '해당 없음'으로 답한 163건은 차이점에 포함되지 않기 때문에 아직 확신할 수 없습니다. 그래서 Claude Code의 제안에 따라 163건 중 20건을 무작위로 뽑아 확인했습니다.
-
'해당 없음'이 올바름: 12건 (해외 제품의 취약점, JPCERT의 Weekly Report, 경찰청의 전국 대상 주의 환기 등)
-
본사 소재지에서 추정 가능했으나 양측 모두 '해당 없음': 7건
- 산포식품(佐賀県), 베네핏 원(東京都), 타임즈 모빌리티(東京都), 라신반(東京都), 와시ントン 호텔(愛知県), ApplyNow(東京都), PhotoGoods(大阪府)
-
판단이 갈림: 1건
-
일본 우편(본사는 東京都이나 전국 대상 서비스)
20건 중 7건을 놓쳤기 때문에, 단순히 비율을 적용하면 163건 중 50건 이상이 누락되었을 가능성이 있습니다.
궁금했던 점은 Jev의 본사 추정에서 일관성이 없다는 것입니다. 게이오 전철(京王電鉄)이나 세이부 전철(西武鉄道)은 본사 소재지를 답했지만, 타임즈 모빌리티나 베네핏 원은 답변하지 않았습니다. 이전 프롬프트는
from typesafe_sdk import Choice, TypeSafeClient
질문 1: 본문에 쓰인 지명만으로 판단한다 (지식에 의한 추측은 허용하지 않음)
SITE_INSTRUCTIONS = (
...
site
과 hq의 원본 답변(raw answer)과 confidence를 저장해 두면, 임계값(threshold)을 변경하여 재평가할 때 Jev를 다시 호출할 필요가 없습니다.
| 결정적 요소 | 건수 |
|---|---|
| 거점 (본문 지명) | 27 |
| ... | |
| 거점에서 결정된 27건은 눈으로 확인한 범위에서는 모두 올바르게 분류되었습니다. 타카라즈카 시립 병원은 거점으로 효고현에 분류되었습니다. 야마구치 도쿄 이과대학의 훈련 기사는 거점이 야마구치현이고, 본사는 '사건 관련 기사가 아니므로' 해당 없음으로 질문을 분리하는 효과가 있었습니다. |
본사에서 결정된 31건 역시 30건이 올바르게 분류되었습니다. 오류로 보이는 것은 Gyazo → 도쿄도 (confidence 0.69, 공개한 Helpfeel의 본사는 교토부)의 1건뿐입니다.
흥미로웠던 점은 confidence가 0.5 미만이라서 버린 23건이었습니다. 시도 1에서 나왔던 오류들이 대부분 여기에 있었습니다. 23건 중 13건은 Jev의 답변이 잘못되었습니다.
| 기사 | Jev의 답변 | confidence | 실제 본사 |
|---|---|---|---|
| 원자력기구 | 후지마현 | 0.24 | 이바라키현 |
| ... | |||
| 반면, 타임즈카(기사 4건분), 라신반, 로트제약, 니치레이, 스코어・재팬 등 정확한데 버려진 것도 10건 있었습니다 (confidence 0.23~0.49). |
즉, 임계값 0.5로 인해 올바른 답변을 10건 포기하고, 오류를 13건 방지할 수 있었던 것입니다.
버린 23건을 confidence별로 나누어 보면, 더욱 명확한 경향이 나타납니다.
| confidence | 올바름 | 오류 |
|---|---|
| 0.4 이상 0.5 미만 | 8건 | 3건 |
| 0.4 미만 | 2건 | 10건 |
0.4 미만은 대부분 오류였으므로, 버리고 정답이었습니다. 반면, 0.4~0.5는 올바른 답변 쪽이 더 많았기 때문에, 임계값을 0.4로 낮추면 오류를 3건 늘리는 대신 올바른 답변을 8건 얻을 수 있습니다.
틀릴 바에는 대답하지 않는 것이 낫다고 생각하여, 현재는 임계값 0.5로 운영하고 있습니다.
임계값을 코드 측에 두었다는 점에는 또 다른 장점이 있습니다. 프롬프트가 바뀌면 Jev의 답변 자체가 변하기 때문에, 시도 1처럼 어디가 어떻게 바뀔지는 직접 테스트해 봐야 알 수 없습니다. 반면, 임계값은 코드의 숫자 하나만 바꾸면 되기 때문에, Jev의 답변은 변하지 않습니다. 실제 운영에서는 Jev의 원본 답변과 confidence를 DB에 저장하고 있으므로, 0.4로 낮추면 어느 기사에 어떤 현이 붙을지 미리 계산할 수 있습니다.
※임계값 미만으로 버린 23건은 공식 정보로 본사 소재지를 확인했습니다. 그 외의 본사 소재지의 정오 여부는 일부를 제외하고 필자와 Claude의 지식으로 판단한 것입니다. 공급망(위탁처・제휴처)에서의 사건은 기사의 중심이 된 기업의 본사를 정답으로 했습니다.
타임즈카 기사는 5건이 있었고, Jev의 답변은 모두 도쿄도였지만, confidence는 기사마다 달랐으며, 임계값을 넘은 것은 1건뿐이었습니다.
| confidence | 본문에서 회사가 쓰인 방식 |
|---|---|
| 0.51 | 「동성공개 프라임 상장 기업의 Park24 주식회사는… 연결 자회사인 타임즈모빌리티…」 |
| ... | |
| confidence는 회사 그 자체가 아니라 기사의 작성 방식에 따라 변하는 것 같습니다. 임계값 근처의 회사는 같은 사건이라도 기사에 따라 지도에 실리거나 안 실리기도 합니다. 이것 또한 '잘못된 현을 넣기보다는 누락하는 것이 낫다'는 생각으로 허용하게 되었습니다. |
실제 운영에 투입하기 전에 비용도 검증했습니다. TypeSafe 공식 cookbook(Parallel questions)에는 '질문을 한 번의 호출로 모으면 12.2배 저렴하다'는 예시가 실려 있습니다. 그렇다면, 여러 기사를 한 번의 요청으로 모으면 저렴해지지 않을까 생각했습니다.
그런데 Claude에게 상담한 결과, 예상은 정반대였습니다. 이유는 다음과 같습니다.
- cookbook에서 저렴해지는 이유는, 하나의 문서(state)에 여러 질문을 하기 때문에 문서 토큰을 한 번만 지불하면 되기 때문입니다. 기사를 묶어서 처리할 경우, 기사별로 다른 것을 물어보기 때문에 질문은 기사 수만큼 필요하게 됩니다 (
site_0,hq_0,site_1,hq_1, …). 문서와 질문의 총합은 변하지 않으므로 거의 저렴해지지 않습니다. 게다가 옆 기사에 영향을 받아 정확도가 떨어지거나, 한 번의 실패로 여러 기사를 분류할 수 없게 될 걱정도 있습니다.
글쓴이의 생각과 Claude의 예상 중 어느 것이 맞는지 실제로 검증해 보았습니다.
최근 20개 기사를 다음 방식으로 분류하여 비교했습니다. 질문 문구는 시도 2와 동일합니다.
| 방식 | 내용 |
|---|---|
| single | 1기사당 1요청 (site / hq의 두 가지 질문). 비교 기준 |
| ... | |
| 방식 | 요청 |
| single | 20 |
| ... |
-
input은 13~15% 감소했습니다 (기사당 약 200 토큰). 요청마다 발생하는 고정 비용을 묶어서 처리한 기사들로 분산시킬 수 있었던 것 같습니다. output은 변하지 않았습니다.
-
output은 기사당 약 920 토큰으로 큰 편입니다. 47개 도도부현 + 해당 없음의 확률을 두 가지 질문에 대한 만큼 모두 반환하기 때문인 것으로 보입니다.
-
공식 cookbook 코드에서는 output 단가를 0으로 설정했습니다. output이 무료라면, 과금되는 것은 input뿐이므로, 묶어서 처리했을 때 절약은 **input의 13~15%**입니다. - 애초에 기사당 비용 자체가 매우 작아서, 신규 기사가 하루 50건 들어와도 월 $0.1 정도 예상됩니다.
-
single과 single-2는 답이 완전히 일치했고, confidence 차이도 평균 0.015였습니다.
Jev는 동일한 입력이라면 거의 같은 답변을 반환합니다. - 반면, 묶어서 처리할 경우에는 본사(hq)의 답변이 20건 중 4건 바뀌었고, confidence 차이도 평균 0.080.11로 실행별 변동 폭이 57배가 되었습니다.
묶어서 처리하는 것 자체가 답을 바꾸고 있습니다.- 원자력기구: 이바라키현 (0.25, 정확) → 후쿠시마현 (0.10~0.18, 오류) -
베네핏 원: 해당 없음 (0.65) → 도쿄도 (0.46~0.47)
-
confidence도 전반적으로 하락했습니다 (세이코마트 0.98 → 0.64, 이에플러스 0.77 → 0.54). 임계값 0.5로 보면, 타임즈카(0.50 → 0.32)나 라신반(0.51 → 0.31~0.41)은 채택되지 않게 되었습니다.
결과는 거의 Claude의 예상과 같았습니다. 묶어서 처리해도 과금 대상인 input은 1315%밖에 줄지 않고, 그 대신 옆 기사의 영향으로 답변이나 confidence가 바뀌어 버립니다. 한 번의 실패로 여러 기사를 분류할 수 없게 될 위험도 있습니다. 1요청당 시간(0.230.34초)도 거의 비슷했습니다.
비용을 줄이려면, 묶는 것보다 다음 두 가지가 더 효과적입니다.
- 신규 기사만 분류하기 (저장된 기사를 매번 재분류하지 않기)
- 도도부현과 무관한 소스를 대상에서 제외하기 (취약점 정보가 중심인 JVN과 JPCERT)
이 방식들로 수집 처리를 (AWS Lambda, TypeScript)에 통합했습니다.
- TypeSafe의 JavaScript SDK를 사용하여, 시도 2와 동일한 두 가지 질문을 1기사당 1요청으로 합니다.
- Jev 호출에 실패할 경우, 기존 방식인 문자열 일치로 전환하여 수집 자체는 중단하지 않습니다.
- 판정 근거(어떤 질문으로 결정되었는지, 답변, confidence, 임계값)를 DB에 저장합니다.
- 신규 기사만 분류하고, JVN과 JPCERT는 분류하지 않습니다.
도입 후 처음 들어온 신규 기사 12건 중, 현이 붙은 4건(이케가미통신 ×2 → 도쿄도, 아이노카제와야마철도 → 도야마현, 니혼대학 → 도쿄도)은 모두 정확했고, 이들 모두 기존 방식에서는 현이 붙지 않던 기사였습니다.
- 프롬프트에 우선순위를 작성하는 것만으로는 '모르는 회사라도 그럴듯하게 답변한다', '알고 있는 회사인데도 답변하지 않는다' 문제가 해결되지 않았습니다.
질문을 하나의 판단으로 나누고, 우선순위와 confidence 임계값을 코드 측에서 갖게 하자, 많은 오류를 걸러낼 수 있었습니다. 다만, 이 임계값은 정답의 일부까지 포기하는 거래이기도 합니다. 어떤 종류의 실수가 더 곤란한지(오류)에 따라 용도에 맞춰 결정하는 것이 중요했습니다.
임계값이 적절한지는 버린 답변들의 정오를 공식 정보로 확인해 봐야만 정확히 알 수 있었습니다 (추측만으로 판단했을 때는, 정답이 이렇게 많이 포함되는 것(0.4~0.5)을 깨닫지 못했습니다).
아티클을 모아서 한 번에 물어봐도 가격은 크게 내려가지 않았고, 답변도 바뀌었습니다.
AI의 답변을 그대로 사용하는 것이 아니라, '자신이 없을 때는 답변하지 않는다'라는 메커니즘을 코드 측에서 구현할 수 있다는 점이 Jev가 흥미로운 부분이라고 느꼈습니다.
길어졌지만 끝까지 읽어주셔서 감사합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기