LLM에게 일을 요청하는 것은 어렵다. 하지만 결과를 검증하는 일은 더 어렵다.
AI 에이전트에게 일을 맡기면 마지막 문장은 대개 비슷하다. “수정했습니다”, “테스트를 통과했습니다”, “배포했습니다.” 문장은 분명하지만, 무엇이 실제로 확인됐는지는 분명하지 않다.
답변에 코드가 있다는 것과 파일이 바뀐 것은 다르다. 파일이 바뀐 것과 기능이 동작하는 것도 다르다. 로컬에서 동작하는 것과 사용자가 실제 화면에서 목적을 달성하는 것, 업로드 명령이 성공한 것과 공개된 결과가 남은 것도 각각 다른 주장이다.
요청의 작은 흔들림은 이 차이를 더 크게 만든다. 경첩에서 몇 도 어긋난 선은 멀리 뻗을수록 끝점이 크게 벗어난다. 이것은 정량 법칙이 아니라 작업을 이해하기 위한 비유다. 모호한 단어 하나가 계획, 도구 선택, 파일 변경, 배포를 차례로 지나면 처음보다 큰 결과 차이가 될 수 있다. 그래서 검증은 마지막에 덧붙이는 절차가 아니라, 요청을 검증 가능한 문장으로 바꾸는 순간부터 시작한다.
이번 세션 감사에서는 489개 대화에서 1,012개 글감 후보를 정리했다. 이것은 실패율을 측정한 연구가 아니다. 다만 코드, 표, UI, 배포, 모델 평가처럼 서로 다른 작업을 가로질러 에이전트의 완료 보고와 사람이 확인할 수 있는 결과를 분리해야 한다는 문제가 하나의 독립 주제로 반복해서 연결됐다.
이 글의 결론은 다음과 같다.
완료는 에이전트가 “끝났다”고 말하는 순간이 아니다. 사용자가 원한 결과가 실제로 만들어졌고, 그 결과를 사용자가 쓰는 화면이나 최종 저장소에서 다시 확인할 수 있어야 완료다. 다만 모든 작업을 끝까지 검증할 필요는 없다. 필요한 증거의 높이는 실패의 영향과 되돌리기 난이도가 정한다. 검증을 더 검증하는 일도 새로운 정보를 주는 지점까지만 해야 한다.
완료를 먼저 검증 가능한 문장으로 바꾼다
“사이트를 고쳤다”처럼 넓은 문장은 검증하기 어렵다. 에이전트가 일을 시작하기 전에 완료 조건을 다음 여섯 칸으로 바꾸면 확인할 대상이 선명해진다.
의도한 결과: 사용자가 무엇을 할 수 있어야 하는가
진입점: 사용자는 어디에서 시작하는가
필요한 변화: 어떤 파일·데이터·외부 상태가 바뀌어야 하는가
판정 권위: 최종 결과를 어느 화면·저장소·원장에서 확인할 것인가
판정 이유: 왜 이 증거면 완료를 받아들일 수 있는가
미확인 범위: 이번 작업에서 확인하지 않을 것은 무엇인가
아 다르고 어 다르다. 모든 맞춤법 실수가 같은 위험을 갖는 것은 아니지만, 파일 경로의 한 글자, 부정어 하나, 단위나 계정 이름의 오타는 다른 작업을 만든다. 이런 의미 오타는 사소한 흠으로 넘길 일이 아니다. 요청에는 명령만 쓰지 않고 사유와 판정 기준을 함께 적는 편이 낫다. 이유를 알아야 에이전트도 여러 가능한 해석 가운데 무엇을 지켜야 하는지 판단할 수 있고, 검수자도 결과가 달라졌을 때 단순 차이인지 의도 이탈인지 가를 수 있다.
이 구분은 오래된 시스템 공학의 질문과도 맞닿아 있다. NASA의 검증·확인 지침은 명세를 충족했는지 확인하는 일과, 시스템이 사용자와 임무의 목적을 충족하는지 확인하는 일을 구분한다. 또 전체 흐름 검증에는 실제 또는 대표 입력과 운영 시나리오가 필요하다고 설명한다. 물론 우주 시스템의 절차를 작은 개인 프로젝트에 그대로 옮길 필요는 없다. 중요한 것은 “요구한 모양인가”와 “의도한 일을 할 수 있는가”가 다른 질문이라는 점이다. NASA Product Verification
예를 들어 “게시글을 올렸다”는 말을 파일 생성으로만 판정하면 부족하다. 독자가 목록에서 글을 찾아 공개 URL로 열 수 있어야 하고, 본문과 이미지가 보이며, 게시 상태를 소비하는 색인도 같은 결과를 반영해야 한다. 반대로 요청이 “초고 파일만 만들어 달라”였다면 공개 URL은 완료 조건에 들어가지 않는다. 증거의 높이는 작업의 이름이 아니라 받아들이려는 주장에 맞춰야 한다.
0번 완료 주장과 여섯 증거 수준
아래 사다리는 표준이 아니라 여러 작업에서 재사용하기 위해 이 글이 제안하는 실무 프레임이다. 엄격한 우열표도 아니다. 정확한 계산식 하나에는 단위 테스트가 가장 직접적인 증거일 수 있고, 사용자가 목적을 달성했는지에는 대표 사용자 흐름이 더 직접적이다. 위로 갈수록 실제 운영 조건에 가까워지는 현실성과 결과를 말한 주체로부터 독립된 판정 권위가 대체로 커진다고 읽는 편이 정확하다.
0. 말했다
에이전트의 완료 요약은 무엇을 하려고 했고 무엇을 수행했다고 인식하는지 알려 준다. 다음 검증을 시작하기에는 유용하다. 그러나 결과 그 자체는 아니다. 자연스러운 설명, 긴 변경 목록, “모든 테스트 통과”라는 문구도 아직 자기 보고다.
1. 남았다
요청한 산출물과 변경 흔적이 실제로 존재하는지 본다. 파일 경로, diff, 생성 시점, 버전, 행 수 같은 정체성을 확인한다. 이 단계는 답변에만 있고 파일에는 없는 코드를 잡는다. 다만 비슷한 이름의 다른 파일이나 오래된 빌드 결과를 확인하면 거짓 확신을 얻을 수 있다.
2. 맞았다
구조, schema, type, 정적 규칙, 불변조건이 맞는지 확인한다. parse나 lint, 필수 필드 검사는 실행 전에 잡을 수 있는 오류를 빠르게 찾는다. 계산표라면 행 합계와 전체 합계가 보존되는지처럼 결과가 반드시 지켜야 할 계약도 여기에 들어간다. 직접 눈으로 판정할 수 있는 좁고 가역적인 문구 수정은 이 단계의 사람 검토만으로 충분할 수도 있다.
3. 돌아갔다
단위·통합 테스트, build 실행, 대표 입력 같은 제한된 동작 검사를 실행한다. 여기에서도 각 검사가 증명하는 범위를 나눠야 한다. 단위 테스트는 정한 입력과 계약을, 통합 테스트는 선택한 경계를, build 실행은 생성 가능성을 보여 준다. 어느 하나도 자동으로 사용자 성공을 뜻하지 않는다.
실행 기반 benchmark도 test oracle이 약하면 틀린 결과를 통과시킬 수 있다. 한 SWE-bench 후속 분석은 특정 agent와 benchmark에서 테스트를 통과한 patch 가운데 실제 issue 해결이 불완전한 사례를 보고했다. 이 수치를 자동 테스트 일반의 실패율로 확대할 수는 없다. 다만 테스트 통과는 테스트가 물은 질문에 대한 답이라는 경계는 분명히 보여 준다.
4. 사용했다
대표 사용자가 의도한 진입점에서 핵심 흐름을 끝까지 통과하는지 본다. UI라면 열기, 입력, 저장, 재접속까지 이어질 수 있다. 정적 사이트라면 목록에서 글을 찾아 본문과 이미지를 여는 흐름이 될 수 있다. 화면 한 장이 보기 좋다는 것과 버튼을 눌러 목적을 달성하는 것은 다르다.
Anthropic의 agent 평가 지침도 transcript와 최종 환경 상태를 구분한다. 예를 들어 예약 agent가 예약했다고 말한 기록과 실제 예약 원장에 항목이 생긴 결과는 별개다. computer-use agent는 실제 또는 sandbox 환경에서 작업을 수행하게 한 뒤 URL, 화면 상태, 파일, 설정, 데이터베이스 같은 결과를 검사할 수 있다. Demystifying evals for AI agents
5. 바뀌었다
저장, 전송, 게시, 권한 변경, 캐시 무효화처럼 요청한 외부 효과나 영속 상태가 실제로 생겼는지 확인한다. 명령의 exit code가 0이라는 사실은 명령이 오류 없이 끝났다는 증거일 수 있지만, 원하는 소비자까지 변화가 전달됐다는 증거는 아니다. HTTP 표준에서도 202 Accepted는 요청을 받아들였다는 뜻이지 처리가 끝났다는 뜻이 아니다. 실제로 수행되지 않을 가능성까지 남는다. RFC 9110
6. 다시 읽었다
마지막으로 결과를 판정할 권위 있는 시스템에서 상태를 재조회한다. 공개 글이라면 실제 URL, 예약이라면 예약 원장, 데이터 변경이라면 최종 저장소가 여기에 해당한다. 가능하면 사용자가 보게 될 경로를 그대로 사용한다.
readback도 자동으로 진실이 되지는 않는다. cache, replica, 잘못된 계정, 다른 환경, 이전 배포를 읽을 수 있다. 그래서 판정 권위, 환경·버전 같은 정체성, 최신성 조건, 확인한 범위와 시점을 함께 남겨야 한다. 권위는 데이터베이스라는 제품 종류가 아니라 이번 완료 주장을 최종 판정하도록 합의한 대상과 그 정체성에서 나온다.
기계로 판정할 수 있는 것은 먼저 기계에 맡긴다
검증 수단을 고를 때는 무엇이 더 지능적으로 보이는지가 아니라, 같은 조건에서 같은 판정을 반복할 수 있는지를 먼저 본다.
정확한 문자열, 스키마, 타입, 합계, 해시, 링크 수, 이미지 크기, 화면 넘침처럼 조건을 분명히 적을 수 있는 항목은 파서와 스크립트, 테스트가 맡는 편이 낫다. 빠르고 반복 가능하며, 어디에서 실패했는지도 비교적 분명하다. LLM은 요구가 서로 충돌하는지, 글에서 빠진 논점은 없는지, 화면에 수상한 부분이 보이는지처럼 규칙만으로 전부 표현하기 어려운 대상을 넓게 살피는 데 유용하다. 사람은 사용 가치와 위험, 브랜드 맥락, 받아들일 수 있는 잔여 오차를 판정한다.
적어도 지금 내가 택하는 운영 원칙은 단순하다. 픽셀 수나 화면 넘침처럼 기계적으로 판정할 수 있는 것은 비전 모델에게 묻기 전에 측정한다. 비전 모델은 넓은 화면을 훑고 의심할 지점을 찾는 보조 검수자로 쓰되, “괜찮아 보인다”는 한 문장에 최종 판정을 맡기지 않는다. 모델 성능이 앞으로 얼마나 빨리 좋아질지는 별도 문제다. 당분간도 재현 가능한 검사가 있는 자리를 확률적 판정으로 바꾸지 않는 편이 안전하다.
테스트와 실제 흐름은 경쟁 관계가 아니다
이 사다리는 “자동 테스트보다 사람이 화면을 보는 편이 낫다”는 주장이 아니다. 서로 다른 검증 수단은 서로 다른 오류를 잡는다.
- code grader는 schema, 계산, 명확한 pass/fail처럼 반복 가능한 계약에 강하다.
- model grader는 열린 글이나 시각 결과를 넓게 볼 수 있지만, rubric과 사람 기준으로 계속 교정해야 한다.
- 사람은 맥락과 사용 가치를 판단할 수 있지만 느리고 일관성이 흔들릴 수 있다.
- 대표 사용자 흐름은 통합된 결과를 보지만 드문 경계 조건을 모두 탐색하기 어렵다.
Anthropic의 실무 지침은 agent 평가에 코드, 모델, 사람 grader를 조합하고 outcome과 transcript 가운데 적합한 대상을 보라고 권한다. NIST의 AI Risk Management Framework도 하나의 측정값을 만능으로 두기보다, 위험 맥락에 맞는 정량·정성 측정이 어떤 고유한 정보를 주는지 고려하라고 한다. NIST AI RMF Core
테스트 포트폴리오와 증거 사다리도 구분해야 한다. Google의 testing guidance는 작은 테스트의 속도·진단 가능성과 큰 테스트의 현실성 사이에 trade-off가 있음을 강조한다. 핵심 사용자 여정은 많이 만드는 것이 아니라, 중요한 사용자 목표와 그 목표까지의 행동을 대표하도록 고른다. SMURF: Beyond the Test Pyramid, How Much Testing is Enough?
문제는 검사를 많이 하는가가 아니다. 낮은 층의 검사가 실제 수행 경로를 우회하거나, fixture와 mock이 확인해야 할 모델·권한·저장을 대신하면서도 전체 능력을 증명했다고 말할 때 생긴다. 반대로 실제 서비스에서만 검증하면 비용과 안전, 재현성이 나빠질 수 있다. 실제 경로의 의미를 보존하는 대표 환경과 최종 readback을 적절히 나누는 편이 낫다.
LLM 검토는 UI와 UX를 대신하지 않는다
LLM이 화면 캡처를 보고 잘린 글자나 어색한 간격을 찾을 수는 있다. 브라우저를 조작해 정해 둔 흐름을 재현할 수도 있다. 그래도 그것만으로 사용자가 제품을 이해하고 목적을 달성했다는 결론을 내릴 수는 없다.
UI 검증에는 실제 문자열, 화면 너비, 입력 장치, 초점, 로딩과 오류 상태가 포함된다. UX 검증에는 사용자가 어디서 망설였는지, 기대와 실제 반응이 맞았는지, 목표를 끝낼 수 있었는지가 포함된다. 전자는 일부를 자동화할 수 있고 모델이 보조할 수도 있다. 후자는 대표 사용자 흐름과 제품 판단을 함께 봐야 한다. 화면을 설명한 모델의 문장은 사용 경험 그 자체가 아니다.
따라서 “모델이 화면을 확인했다”는 보고에는 무엇을 측정했고, 어떤 흐름을 실제로 실행했으며, 어느 부분을 사람이 보지 않았는지가 따라붙어야 한다. LLM 검토는 UI·UX 검증의 빈칸을 찾을 수 있지만 그 빈칸을 저절로 메우지는 못한다.
어디까지 올라가야 할까
모든 작은 수정에 가장 높은 단계의 readback을 요구하면 검증이 작업보다 비싸진다. 이 반론은 맞다. 충분한 증거의 높이는 다음 두 질문으로 정할 수 있다.
- 실패했을 때 누구에게 어떤 영향이 생기는가?
- 결과가 틀렸을 때 얼마나 쉽게 되돌리고 다시 확인할 수 있는가?
| 영향과 가역성 | 예시 | 권장하는 최소 증거 |
|---|---|---|
| 영향이 낮고 되돌리기 쉬움 | 탐색용 문구, 버릴 prototype | 산출물 확인과 작은 검사, 사람의 빠른 검토 |
| 영향이 높지만 되돌리기 쉬움 | 많은 사용자가 보는 UI 변경 | 관련 자동 검사와 대표 사용자 흐름, regression 확인 |
| 영향은 낮아도 되돌리기 어려움 | 영구 URL 변경, 외부로 전달되는 파일 | 외부 효과와 실제 소비자 경로의 readback |
| 영향이 높고 되돌리기 어려움 | 삭제, 권한, 비용, 개인정보 변경 | 별도 승인, 복구 준비, 외부 효과, 권위 있는 readback |
이 표도 표준이나 보증이 아니라 검증 예산을 고르는 heuristic이다. 고위험 도메인의 법적·안전상 요구사항이나 전문 감사를 대신하지 않는다. NIST AI RMF Core 역시 가장 중요한 위험부터 측정 방법을 선택하고, 측정하지 못한 부분을 문서화하도록 제안한다.
증거 사다리도 새로운 점수판이 될 수 있다
파일을 만들고, 보이는 테스트를 통과하고, 유리한 화면을 캡처하고, 오래된 cache의 URL을 한 번 여는 방식으로도 모든 칸을 채울 수 있다. 그러면 증거의 수는 늘지만 사용자의 실제 목적에는 가까워지지 않는다. 약한 테스트가 불완전한 구현을 통과시키는 문제와, 시스템이 의도적으로 평가 기준만 최적화하는 문제도 구분해야 한다.
사다리의 목적은 높은 번호를 얻는 것이 아니다. 다음 검사를 추가하기 전에 세 가지를 묻는다.
- 아직 다루지 않은 구체적 실패 가능성이 있는가?
- 그 실패의 영향이 크며, 새 검사가 기존 증거와 다른 정보를 주는가?
- 지금 멈춰도 남은 불확실성을 말하고 문제를 탐지·복구할 수 있는가?
새로운 중대한 실패 가능성을 줄이지 못하는 검사는 추가하지 않아도 된다. 반대로 외부 공개, 데이터, 권한, 비용처럼 늦게 발견할수록 피해와 복구 비용이 커지는 작업에는 독립된 증거를 더 붙인다.
검증의 검증을 어디서 멈출까
검증기도 틀릴 수 있다. 그렇다고 같은 결과를 또 다른 LLM에게 묻고, 그 답을 다시 제3의 LLM에게 맡기면 비용만 늘고 독립성은 생기지 않을 수 있다. 검증기를 믿을 수 있는 범위를 좁게 정하는 편이 낫다.
- 기계 검증기에는 입력, 판정 규칙, 실패 코드가 포함된 작은 계약을 둔다.
- 검증기를 만들거나 바꿀 때는 반드시 통과해야 할 사례와 반드시 실패해야 할 사례를 함께 실행한다.
- 안정된 검증기는 매 작업마다 처음부터 다시 증명하지 않고, 버전과 적용 범위를 기록한다.
- 다음 검사는 앞선 검사와 다른 실패 모드를 겨냥하고, 그 결과가 승인·수정·중단 결정 가운데 하나를 바꿀 때만 추가한다.
이렇게 하면 검증의 검증은 무한 재귀가 아니라 범위가 정해진 교정이 된다. 좁고 결정적인 속성은 검증된 기계 검사로 닫고, 열린 판단은 서로 다른 근거를 가진 모델이나 사람에게 넘긴다. 그래도 남는 불확실성은 숨기지 말고 acceptance record에 적는다.
작업 종류로 바꾸면 다음처럼 읽을 수 있다.
- 조사·요약: 출처 연결, 핵심 질문 coverage, 반론과 미확인 범위를 확인한다.
- 파일 수정: 정확한 diff와 관련 검사부터 보고, 그 파일을 소비하는 생성물이 있다면 소비자도 확인한다.
- UI: 실제 문자열과 대표 입력으로 핵심 흐름을 확인하고, 필요한 경우 mobile과 desktop을 나눠 본다.
- 게시·전송: 외부 효과가 생겼는지 확인한 뒤 실제 사용자 경로에서 다시 읽는다.
- 삭제·권한·비용: 실행 전 대상을 다시 특정하고, 승인과 복구 수단을 준비하며, 실행 뒤 권위 원본을 재조회한다.
다음 사람에게는 로그 전체보다 작은 증거 묶음을 남긴다
긴 채팅과 원시 로그를 전부 넘겨도 다음 사람은 완료를 재구성하기 어렵다. 검증 결과 자체도 사용자가 확인하기 편해야 한다. 필요한 것은 결론을 바꿀 수 있는 항목만 담은 작은 acceptance record다.
완료 주장:
판정: 통과 / 실패 / 일부 확인
제외 범위:
산출물·배포 identity:
실행한 검사와 결과:
대표 사용자 흐름:
최종 readback과 시점:
확인하지 못한 부분:
잔여 위험과 복구 방법:
사용자가 열어 볼 증거:
다음 행동:
첫 화면에는 판정, 직접 열 수 있는 결과, 미확인 범위, 다음 행동만 둔다. 변경 내역, 화면 캡처, 테스트 보고서 같은 증거는 바로 열 수 있게 연결하고, 긴 원시 로그는 부록이나 비공개 운영 기록으로 내린다. 민감한 입력, 내부 경로, 자격 증명을 사용자용 기록에 복사할 필요도 없다. 나중에 통과 결과를 재현할 수 있을 정도의 정체성과 결과만 남기고, 공개할 기록과 비공개 운영 기록을 분리한다.
검증할 권한이나 환경이 없다면 그것도 정확히 적는다. “로컬 build까지 확인했고 실제 공개 URL은 확인하지 못했다”는 보고는 불완전하지만 정직하다. 확인하지 않은 외부 효과를 추론해 “완료”라고 부르는 것보다 다음 행동을 훨씬 선명하게 만든다.
완료 보고를 불신하는 것이 목적은 아니다
에이전트의 완료 메시지는 작업을 넘겨받는 좋은 출발점이다. 문제는 그 메시지 하나에 파일 존재, 테스트, 사용자 성공, 외부 변화, 최종 상태를 모두 압축해 버리는 데 있다. 요청보다 검증이 더 어렵게 느껴지는 이유도 여기에 있다. 요청은 한 번 말하면 되지만, 완료를 받아들이려면 서로 다른 주장을 서로 다른 증거로 풀어야 한다.
완료를 잘 확인하는 사람은 모든 작업을 의심하며 최고 단계까지 올라가지 않는다. 먼저 받아들이려는 주장을 작게 쓰고 그 이유를 붙인다. 그 주장을 판정할 권위를 정하고, 기계가 정확히 판정할 수 있는 부분은 기계에 맡기며, 위험에 맞는 최소 증거를 고른다. 도달하지 못한 층은 실패를 숨기는 대신 미확인 범위로 남긴다. 다음 검사가 새로운 정보를 주지 않는다면 거기서 멈춘다.
다음 작업을 시킬 때는 한 문장만 먼저 덧붙여 볼 수 있다.
이 작업은 무엇이 어디에서 다시 확인되면 완료인가?
그 질문이 “완료했습니다”를 실제로 받아들일 수 있는 결과로 바꾸는 시작점이다.
관련 글: LLM Wiki를 잘 쓰는 사람은 무엇을 저장하지 않을지 먼저 정한다
AI disclosure
Researched and drafted with OpenAI Codex using GPT‑5.6 Sol (xhigh reasoning). Editorial review and final approval by Yioo.
