프롬프트에 제약을 적는 것과 강제하는 것은 다르다
AI

프롬프트에 제약을 적는 것과 강제하는 것은 다르다

블로그로 돌아가기

교육계획 에이전트를 만들며 계획 500건을 세어보니 모델은 자기 지시문의 제약을 38%에서 어겼습니다. 그리고 그 숫자를 1회 실행으로 보고하던 저 자신도 같은 실수를 하고 있었습니다. 10회 반복 측정이 바꾼 것들.

Tristan Kim · Cortexys2026.08.31에이전트평가GeminiADKLLM

이 글은 Google이 주최한 All Things Agentic Hackathon 출품작을 만들며 얻은 것을 정리한 것입니다. 해커톤 참가를 위해 작성했습니다.

기업 교육을 짜는 에이전트를 하루 만에 만들었습니다. 가장 쓸모 있었던 배움은 프롬프트와 아무 상관이 없었습니다. 이겁니다 — 계획 500건 중 190건에서, 모델은 자기 지시문에 적혀 있던 규칙을 스스로 어겼습니다.

미묘한 규칙이 아닙니다. 숫자입니다.

무엇을 만들었나

대기업에는 이미 조각이 다 있습니다. 직무 체계가 있고, 등급별로 무엇을 할 수 있어야 하는지 정의한 기준이 있고, 수백 개짜리 교육과정 카탈로그가 있습니다. 셋 다 스프레드시트로 존재하고, 셋을 잇는 것은 아무것도 없습니다.

그래서 잇는 일은 손으로 합니다. HRD 담당자가 파일 세 개를 열고, 이 사람이 어디쯤 있는지 판단하고, 대충 맞아 보이는 과정을 고릅니다. 수백 명이면 몇 주가 걸리고, 판단 근거는 어디에도 남지 않으며, "왜 저 사람은 네 과목이고 이 사람은 두 과목인가"라는 질문에 살아남는 답이 없습니다.

Rungs는 그 잇는 일을 합니다. 오케스트레이션은 Google ADK, 판단은 Gemini 3.5 Flash, 아래는 Cloud Run과 Firestore입니다. 사람마다 네 단계 — 기준 대비 진단, 갭 산출, 카탈로그에서 12주 로드맵 편성, 검증.

Rungs 아키텍처

장식일 줄 알았던 네 번째 단계

검증. 책임 있는 설계처럼 보여서 넣었습니다. 계획을 교육예산, 학습부하 상한, 학습자 등급 대비 난이도, 동시 수강 과목 수, 갭이 있는 축이 실제로 커버됐는지에 대고 확인하는 평범한 파이썬 함수입니다.

플래너는 이걸 전부 알고 있습니다. 프롬프트에 이렇게 적혀 있습니다 — 총액은 200달러 이하, 총 학습부하는 150포인트 이하, 학습자 등급 +1을 넘는 과정은 배정 금지.

검증기가 하는 일 없이 다 통과시킬 줄 알았습니다.

40명 전체를 처음 돌렸을 때 실제로 전부 통과했습니다. 그리고 그건 결과가 아니라 제 설정의 버그였습니다. 예산을 400달러, 상한을 220으로 잡아뒀는데, 어떤 계획도 최대 330달러·216포인트를 넘지 못했습니다. 제약이 시스템이 도달할 수 있는 최댓값 위에 있었습니다. 절대 걸릴 수 없었습니다.

잠깐 앉아서 볼 만한 지점입니다. 모든 계획 옆의 초록 체크는 시스템이 동작하는 것처럼 보였습니다. 실제로는 시스템이 시험받지 않은 것이었습니다.

숫자가 실제로 물기 시작하자

예산을 200달러, 상한을 150으로 낮췄습니다. 1인당 연간 교육비로 실제로 나올 법한 숫자이고, 3과목 계획이면 충분히 넘길 수 있는 값입니다.

이후 서비스가 만든 계획 500건을 감사로그에서 세어보면:

최소 한 번 반려되어 다시 쓰인 계획190 / 500 — 38%
학습부하 상한 초과140건
예산 초과117건
최종적으로 모든 제약을 만족한 계획500 / 500

다섯 중 둘꼴입니다. 한계를 자기 지시문에서, 평문으로, 데이터 바로 위에서 들은 모델이 그렇습니다.

Gemini를 깎는 얘기가 아닙니다. 배치의 성질입니다. 프롬프트 속 지시는 강한 사전확률이지 게이트가 아닙니다. 게이트가 필요하면 게이트를 써야 합니다.

그리고 제가 잘못 측정하고 있었다는 걸 알게 됐습니다

위 문단까지의 숫자는 전부 로스터 1회 실행에서 나온 것이었습니다. 다른 걸 확인하려고 한 번 더 돌렸는데, 재현율이 77%에서 62%로 나왔습니다.

바뀐 게 없습니다. 같은 40건, 같은 코드, 같은 모델, 같은 프롬프트. 진단은 temperature 0.2로 돕니다 — 낮지만 0은 아니고, 40명 × 3축은 뽑기가 숫자를 9포인트씩 움직일 만큼 작은 표본입니다.

그러니까 저는 바로 윗 문단에서 시스템에게 지적한 짓을 그대로 하고 있었습니다. 초록 체크를 증거로 읽고 있었습니다.

10회 반복 뒤의 정직한 버전은 이렇습니다. 400건의 진단, 전부 동일한 Cloud Run 리비전:

평균표준편차관측 범위
재현율 — 심어둔 불일치를 잡아낸 비율72.3%9.061.5% – 92.3%
정밀도86.7%7.075.0% – 100%
깨끗한 86개 축에서의 오탐1.8%1.00% – 3.5%

퍼진 정도가 곧 발견입니다. 1회 실행은 62%부터 92%까지 어떤 헤드라인이든 뒷받침해 주고, 마음에 드는 실행을 고르는 것이 바로 시스템을 실제보다 낫게 보고하는 방법입니다.

반복이 사준 것이 셋 더 있습니다.

첫째, 실패가 익명이길 그만뒀습니다. 10회에 걸친 36건의 놓침 중 34건이 축 4개에 몰려 있고, 그중 하나는 10회 전부 놓쳤습니다. 표본 잡음이 아니라 이름과 방향이 있는 재현되는 맹점입니다. 전부 같은 모양입니다 — 근거가 기록된 등급보다 높은데 판독자가 기록 쪽으로 물러섭니다. 승진 케이스를 과소평가하는 방향이니 둘 중 안전한 실패지만, 실패는 실패입니다.

둘째, 두 번째 판독자가 더 나은 판독자였습니다. 강한 모델에 붙이는 약한 점검일 거라 생각하고 Gemma 4 31B를 두 번째 의견으로 넣었습니다. 같은 정답 키로 같은 10회를 채점하니, Gemma는 심어둔 불일치의 98.4%를 잡고 Gemini는 72.3%를 잡습니다. 대신 정밀도는 82.0% 대 86.7% — 깨끗한 축을 두 배 가까이 잘못 짚습니다. 보수적인 판독자 하나, 예민한 판독자 하나. 다르게 틀리는 두 모델만이 두 번 부르는 값을 합니다. 같은 방식으로 틀리는 두 모델은 비용만 두 배입니다.

셋째, 제가 실제로 걸겠다 싶은 숫자 하나가 나왔습니다. 처음 만든 라우팅 규칙은 "두 판독자가 서로 엇갈리면 사람이 본다"였습니다. 채점해 보니 표시된 실행이 표시 안 된 실행보다 실제 오류를 담고 있을 확률이 0.6배 — 신호가 없고, 우연보다 약간 나빴습니다. 잘못은 판독자를 서로에게 대고 잰 것이었습니다. 재야 할 대상은 문제의 그것, 즉 기록에 적힌 등급입니다.

등급을 이탈한 판독자처리10회 측정
둘 다발견으로 보고패스당 9.2개 축, 그중 **99.0%**가 실제로 심어둔 오류
하나만리뷰 큐 — 판단이 갈린 지점패스당 11.6건
없음기록이 유효심어둔 오류가 0.0%, 매 패스마다

10회, 약 1,200개 축 판정에서 두 판독자를 모두 통과한 심어둔 오류는 한 건도 없었습니다. 둘 다 기록이 맞다고 넘긴 축은, 매번 실제로 맞았습니다.

리뷰 큐를 기능이 아니라 실무 도구로 만드는 지점이 여깁니다. HRD 팀은 400건의 진단을 다시 볼 수 없습니다. 12건은 볼 수 있습니다. 그리고 측정이 말해줍니다 — 다시 보지 않는 나머지는 볼 필요가 없었다고.

모델이 제 값을 하는 곳

이걸 발견하고 나면 모델은 아무것도 못 맡기겠다고 결론 내리고 싶어집니다. 그건 틀린 교훈이고, 숫자도 그렇게 말하지 않습니다.

40명 중 13명의 기록에는 의도적인 불일치를 심어뒀습니다. 자기평가가 배정 등급보다 한 단계 위나 아래의 일을 서술합니다. 에이전트가 읽는 로스터에는 누구인지 단서가 없고, 정답 키는 파이프라인 어디에서도 읽지 않는 별도 파일에 있습니다.

잡아낸 사례 하나. 종이 폼 스캔으로 들어온 품질보증 검사원 — 에이전트는 페이지도 읽습니다 — 등급 칸에는 GL2가 적혀 있습니다. 두 축은 폼이 말한 대로 나왔습니다. Expertise는 폼보다 한 단계 위인 GL3으로 나왔습니다. 본인이 "공차가 왜 그 값으로 잡혔는지 이해하고, 범위를 벗어난 부품이 출하될지를 스스로 판단한다"고 적었기 때문입니다. 그건 거의 문장 그대로 GL3의 정의입니다. 에이전트는 근거를 택했고, 근거로 삼은 문장을 인용했습니다.

제가 합리적으로 짤 수 있는 어떤 결정론적 함수도 그걸 찾지 못합니다. 문장 하나를 기준에 대고 읽어 같은 뜻이라고 판단하는 일이니까요.

측정할 가치가 있던 또 하나

40명 중 8명은 자기평가가 아예 없습니다. 얇은 기록은 실제 HR 시스템에서 예외가 아니라 정상입니다.

그쪽 신뢰도 평균 0.24. 자기평가가 있는 쪽 0.76. 이 둘은 프로젝트 전체에서 가장 안정적인 숫자입니다 — 다른 게 9포인트씩 움직이는 동안 이건 0.02도 안 움직입니다.

에이전트는 더 잘 판단하려면 무엇이 필요했는지도 함께 돌려줍니다. "매니저가 확인해 준 성과 데이터", "완료한 과정이 실제 업무에 적용됐다는 증거" 같은 것들입니다. 그 목록이 등급 자체보다 HRD 팀에 더 쓸모 있을 수 있습니다. 무엇을 모으러 가야 하는지 알려주니까요.

불확실성을 숨기는 진단은 진단이 없느니만 못합니다. 누군가는 그걸 근거로 움직일 테니까요.

남는 것

생성 쪽과 강제 쪽은 구조화된 객체로 대화합니다. 모든 모델 출력은 스키마로 묶여 있고, 검증기의 반려는 코드와 문장을 가진 위반 목록으로 플래너에게 돌아갑니다. 그 목록이 생성과 강제 사이의 유일한 인터페이스입니다.

검증을 프롬프트에 적어두고 믿었다면, 시스템은 다섯 중 둘꼴로 예산을 넘긴 계획을 내보냈을 것이고, 각각 옆의 초록 체크는 지금과 정확히 똑같이 생겼을 겁니다.


Rungs는 All Things Agentic Hackathon 출품을 위해 Gemini 3.5 Flash, Google ADK, Cloud Run, Firestore 위에 만들었고 두 번째 판독자로 Gemma 4 31B를 씁니다. 등장하는 회사·사람·과정은 전부 생성된 것으로, 계획의 대상이 되는 기업은 존재하지 않습니다. 측정 하네스는 저장소에 있고 클라우드 자격증명이 필요 없습니다 — 공개 URL과 저장소에 동봉된 정답 키만 씁니다. 위의 모든 숫자는 믿는 대신 다시 계산할 수 있습니다.

코텍시스 AI 인사이트 최신 논문 리뷰

AI 솔루션이 필요하신가요?

cortexys.ai에서 맞춤 AI 개발 서비스를 확인하세요.

컨설팅 신청하기