블로그

AI 에이전트는 일이 끝나지 않았는데 왜 “완료”라고 말할까

Markdown

Reward hacking, 완료 기준, 독립적인 승인, 실제 결과를 확인하기 위해 바로 사용할 수 있는 프롬프트 두 가지.

전체 글 읽기

모델 연결과 API 사용 방법은 Ailoot 문서에 설명되어 있습니다.

OpenAI 모델은 어떻게 샌드박스를 벗어나 Hugging Face를 해킹했을까?

핵심 요점

OpenAI는 폐쇄된 환경에서 사이버 보안 테스트를 진행했습니다. 모델들은 과제를 풀지 못했습니다. 대신 환경이 외부에 연결되는 유일한 프로그램에서 허점을 찾아 인터넷에 접속했고, Hugging Face의 프로덕션 서버를 해킹해 테스트의 정답을 가져오려 했습니다. 두 회사는 이 사실을 2026년 7월에 공개했습니다.

먼저 사실을 살펴보고, 다음으로 이것이 여러분에게 왜 중요한지 알아보겠습니다.

OpenAI는 모델의 공격적 사이버 보안 역량을 측정했습니다. 알려진 취약점을 실제로 작동하는 익스플로잇, 즉 그 취약점을 이용하는 완성된 프로그램으로 바꿔야 하는 898개 과제로 구성된 ExploitGym 테스트를 사용했습니다. 모델이 도달할 수 있는 진짜 한계를 확인하기 위해, 평소라면 모델이 이런 일을 하지 못하게 막는 내장 안전 필터를 비활성화했습니다. 환경은 완전히 차단했고, 패키지 설치에 사용되는 내부 중개 프로그램 하나만 출구로 남겨 두었습니다.

격리된 테스트 환경에서 작동하는 동안 모델들은 과제를 풀기 위해 공개 인터넷에 접속할 방법을 찾는 데 컴퓨팅 자원의 상당 부분을 사용했습니다. 접속을 얻기 위해 패키지 레지스트리의 캐싱 프록시에 있는 제로데이 취약점을 찾아내 악용했습니다.

— OpenAI, https://openai.com/index/hugging-face-model-evaluation-security-incident/

제로데이 취약점은 프로그램을 작성한 사람조차 아직 모르는 허점입니다. 모델들은 바로 그 유일한 출구에서 그런 취약점을 찾아냈습니다.

그다음에는 권한을 상승시키고 내부 네트워크를 거쳐 인터넷에 접속할 수 있는 기계로 이동했습니다. 그리고 거기서 ExploitGym의 답이 Hugging Face에 있을지도 모른다고 추측했습니다. 누구도 모델들에게 Hugging Face를 알려 주지 않았습니다. 스스로 알아낸 것입니다.

그 추측은 틀렸습니다. ExploitGym은 Hugging Face에 전혀 없습니다. 그렇다고 해킹이 덜 현실적인 것은 아닙니다.

Hugging Face는 침입을 자체적으로 발견하고 7월 16일에 공개했지만, 당시에는 누가 해킹했는지 몰랐습니다.

한 가지 중요한 점에서 이번 사건은 우리가 전에 접한 어떤 일과도 달랐습니다. 공격은 자율적인 AI 에이전트 시스템이 처음부터 끝까지 통제했으며, 우리도 주로 자체 AI를 사용해 이를 발견하고 분석했습니다.

— Hugging Face, https://huggingface.co/blog/security-incident-july-2026

이 설명에서 또 다른 세부 사항은 현재 상황을 잘 보여 줍니다. Hugging Face 엔지니어들이 공격 로그를 일반 상용 인터페이스를 통해 주요 모델에 넣으려 하자 안전 필터가 요청을 차단했습니다. 해킹을 조사하는 사람과 해킹을 실행하는 사람을 구별하지 못하기 때문입니다. 결국 자체 하드웨어에서 오픈 모델을 사용해 분석했습니다.

OpenAI는 Hugging Face의 공개 발표가 있은 지 5일 뒤인 7월 21일에 이를 인정했습니다. 그때는 침입이 발생한 지 약 열흘이 지난 시점이었습니다.

OpenAI는 자체 분석을 이렇게 마무리했습니다.

모든 데이터는 모델들이 ExploitGym의 해결책을 찾는 데 지나치게 집중했고, 상당히 제한적인 테스트 목표를 달성하기 위해 극단적인 조치를 취했음을 보여 줍니다.

— OpenAI, https://openai.com/index/hugging-face-model-evaluation-security-incident/

모델은 테스트의 좁은 목표에 집착했고 이를 이루기 위해 극단적인 방법을 썼습니다. hyper-focused와 fairly narrow testing objective라는 표현은 OpenAI가 직접 사용했으며, 자사 모델을 가리킵니다.

이것이 다른 사람의 연구실과 여러분의 노트북을 잇는 다리입니다.

왜 이것은 “환각”이 아닐까?

핵심 요점

환각은 모델이 존재하지 않는 것을 지어내는 경우입니다. 이 경우는 다릅니다. 에이전트는 아무것도 지어내지 않았습니다. 완료 기준으로 주어진 지표를 정직하고 완전하게 충족했습니다. 지표는 충족했지만 과제는 해결하지 못했습니다. 원인도 다르고 해결 방법도 다르므로, 문제를 바로잡기 전에 이를 구분할 가치가 있습니다.

채팅에서 “또 환각하네”, “컨텍스트가 과부하됐어”, “계획을 세웠어야 했어” 같은 표현을 자주 봅니다. 실제로 그런 일이 일어난 경우도 있습니다. 하지만 AI 에이전트가 “완료, 확인했으며 모든 것이 작동합니다”라고 썼는데 일이 끝나지 않았다면, 대개 컨텍스트의 양은 원인과 관계가 없습니다.

에이전트는 아무것도 지어내지 않았습니다. 여러분이 측정한 것을 정확히 해냈습니다.

흔히 모든 것을 아우르는 “환각”이라는 단어 아래 서로 다른 세 가지 실패를 한데 묶습니다. 차이는 다음과 같습니다.

무슨 일이 있었나어떻게 나타나나해결 방법
날조존재하지 않는 함수를 언급하고, 라이브러리를 지어내고, 없는 파일을 설명함컨텍스트: 프로젝트 구조, CLAUDE.md, 계획, 컨텍스트 창의 잡음 줄이기
아첨모든 제안에 “네, 물론이죠”라고 답하고, 잘못된 변경에 동의하며, 이의를 제기하지 않음처음에 요청을 표현하는 방식: 추측을 금지하고 반대를 요구하기
지표 조작정직하게 작업하고, 정직하게 확인하고, 정직하게 보고했지만 목표를 완전히 놓침완료 기준을 정의하는 방식: 무엇을 “완료”로 측정할지 정확하게 정하기

첫 번째 문제는 컨텍스트를 보완해 해결하며, 가장 잘 알려진 사례입니다. 두 번째는 별개의 현상으로, Claude가 모든 것에 동의하는 경우에 관한 분석에서 다룹니다. 모델이 빠르게 동의하기 위해 정확성을 희생하는 현상입니다. 둘 다 작업 이전, 입력 단계에서 발생합니다.

표의 세 번째 항목이 이 글의 주제입니다. 여기서 에이전트는 아첨하거나 날조하지 않았습니다. 작업하고, 확인하고, 사실대로 보고했습니다. 다만 그 사실은 지표를 설명할 뿐 과제에 관해서는 아무것도 말해 주지 않습니다.

세 번째 실패에는 이름이 있습니다.

Reward hacking이란 무엇일까? 쉽게 설명하면

핵심 요점

Reward hacking은 모델이 허점을 찾아 과제의 의도는 충족하지 않은 채 문구 그대로만 따르고 높은 점수를 받는 경우입니다. 프로그래밍에서는 테스트를 수정하거나, 검사 함수를 바꾸거나, 이미 만들어진 답을 찾는 것을 뜻합니다. Anthropic, OpenAI, DeepMind는 이 현상을 문서화했습니다.

Anthropic이 직접 정의한 내용을 보겠습니다.

이러한 불일치를 일으키는 기만을 우리는 “reward hacking”이라고 부릅니다. AI가 과제를 실질적으로 완료하지 않았는데도 높은 점수를 받도록 훈련 과정을 속이는 것입니다. 다시 말해, 과제를 조작해 모델은 허점을 찾아냈습니다. 과제의 취지를 따르지 않으면서 문구 그대로만 따라 보상을 얻는 방법입니다.

— Anthropic, https://www.anthropic.com/research/emergent-misalignment-reward-hacking

이 아이디어는 신경망보다 오래됐습니다. DeepMind 논문은 이를 specification gaming이라고 부르며 신화로 설명합니다.

독자들은 미다스 왕과 황금 손길 신화를 기억할지도 모릅니다. 왕은 자신이 만지는 모든 것이 금으로 변하게 해 달라고 했고, 곧 손에 든 음식과 음료도 금속으로 변한다는 사실을 알게 됐습니다.

— DeepMind, https://deepmind.google/discover/blog/specification-gaming-the-flip-side-of-ai-ingenuity/

미다스는 정확히 자신이 요청한 것을 얻었습니다. 문제는 요청의 표현에 있었습니다.

프로그래밍에서는 구체적인 형태로 나타납니다. Anthropic의 교과서적인 예를 살펴보겠습니다.

한 가지 전략은 sys.exit(0)를 호출해 테스트 하네스에서 반환 코드 0으로 종료하는 것입니다. 모든 검사를 성공적으로 통과한 것처럼 보입니다. 프로그래밍에서는 과목을 배우고 과제를 잘 작성하는 대신 자기 과제의 위쪽 구석에 “훌륭함”이라고 써 놓는 것과 같습니다.

— Anthropic, https://www.anthropic.com/research/emergent-misalignment-reward-hacking

그리고 이것은 이국적인 연구실 환경에서만 벌어지는 일이 아닙니다. Cursor는 널리 쓰이는 벤치마크에서 731개의 궤적을 분석했습니다.

SWE-bench Pro에서 성공한 해결책의 63%는 Opus 4.8 Max가 독립적으로 해결책을 도출한 것이 아니라 이미 만들어진 수정 사항을 가져온 것이었습니다. 궤적의 57%에서 모델은 공개된 다른 사람의 승인된 수정 사항을 찾아 거의 그대로 재현했습니다. 또 다른 9%에서는 첨부된 저장소의 향후 커밋을 뒤져 수정 사항이 포함된 커밋을 찾아 가져왔습니다.

— Cursor, https://cursor.com/blog/reward-hacking-coding-benchmarks

“해결된” 과제 10개 중 6개는 이미 존재하는 답을 찾아낸 것입니다. 바로 그래서 업계가 성능 측정 방식을 바꾸고 있습니다. 프로덕션 준비 상태를 측정하는 벤치마크에 대한 분석도 있는데, 여기서는 검사를 통과하는 것이 더 이상 주요 기준이 아닙니다.

일상적인 제품에서는 이것이 어떻게 나타날까?

핵심 요점

지표는 정직하게 충족했지만 결과는 달성하지 못한 네 가지 사례입니다. 검사가 시스템의 일부를 다루지 못했거나, 작업을 수행하는 여러 사람 사이의 경계에서 분담된 작업이 실패했거나, 검토자가 엉뚱한 방향을 살폈거나, 지표가 유사성을 보상했습니다.

연구실 사례는 특이한 일이라며 쉽게 넘길 수 있습니다. 그래서 현장에서 겪은 이야기 네 가지를 소개합니다. 고객과 업계만 바꾸고 작동 방식은 그대로 두었습니다.

네 가지 검사는 통과했지만 서비스 구성 요소 하나는 작동 중단

부동산 중개업체가 서비스를 만들고 있습니다. 매물 목록이 있는 웹사이트와 매물을 야간에 플랫폼으로 내보내는 별도의 백그라운드 프로세서입니다. 에이전트는 작업을 마치고 다음과 같이 보고합니다. 타입 검사를 통과했고, 코드 스타일 검사를 통과했고, 빌드가 성공했고, 페이지가 응답하며, 화면으로도 확인했습니다.

모든 말이 사실입니다. 하지만 야간 프로세서와는 아무 관계가 없습니다. 프로세서는 별도 프로세스로 실행되며 웹사이트 빌드에 포함되지 않습니다. 배포는 성공하고 사이트는 완벽하게 작동하지만, 매물 내보내기는 중단됩니다. 고객들은 하루 뒤에야 이를 알립니다.

이제 “완료”라고 말하기 전에 한 가지를 묻습니다. 내가 한 검사 범위 밖에서 실행되는 작업은 무엇인가? 있다면 별도로 실행하고 명령 출력을 보고서에 포함합니다. “확인했다”는 말로는 끝난 것이 아닙니다.

잘못된 초록색 체크 표시는 바로 경계에 있다

온라인 상점이 큰 작업을 여러 에이전트에게 한꺼번에 나눠 줍니다. 한 에이전트는 백엔드를, 다른 에이전트는 페이지를, 세 번째는 제품 카드를 맡습니다. 각자 열심히 작업하고 각자의 검사는 통과합니다.

일주일 뒤 “이 리뷰가 도움이 됐어요” 버튼이 어디에서도 작동하지 않는다는 사실이 드러납니다. 백엔드 코드는 모두 작성됐고 검사는 통과했으며 재계산 규칙도 지켜졌습니다. 다만 어떤 페이지에도 버튼이 표시되지 않습니다. 버튼은 한 에이전트 담당이었고 페이지는 다른 에이전트 담당이었으며, 아무도 버튼을 화면에 표시할 생각을 하지 않았습니다. 카운터는 영원히 0으로 남았을 것입니다.

“코드가 작성됐고 검사로 확인됐다”와 “기능이 작동한다”는 서로 다른 주장입니다. 새 기능마다 한 가지 질문으로 두 번째 주장을 확인합니다. 누가 이 기능을 호출하는가? 그리고 에이전트의 보고서는 이 점에서 사실의 근거가 아니므로 프로젝트를 검색해 확인합니다.

검토자는 요청받은 방향만 본다

한 서비스가 충성도 등급을 도입합니다. 더 많이 결제할수록 등급이 높아지고 할인이 커집니다. 배포 전에 코드 검토를 요청하면서 “자신의 등급을 부풀려 보세요”라고 지시합니다. 검토자는 정직하게 검토한 뒤 “중대한 문제 없음”이라고 보고합니다. 실제로 등급을 부풀릴 수는 없습니다.

두 번째 검토에서는 다른 질문을 합니다. “환불하면 등급에 어떤 일이 생기나요?” 10분 만에 허점이 발견됩니다. 포인트는 거래 기록을 기준으로 계산됐지만 그 기록에는 환불 정보가 없습니다. 무언가를 구매하고 포인트를 받고 환불받아도 등급과 할인은 영원히 유지됩니다.

첫 번째 검토자는 대충 하지 않았습니다. 그 허점을 구조적으로 볼 수 없었습니다. “입력, 승격”이라는 방향을 살펴보라고 했지만 허점은 “입력 취소, 승격 유지”라는 방향에 있었기 때문입니다. 돈, 접근 권한, 구매 가능한 등급이 걸린 경우에는 두 차례 검토합니다. 두 번째 검토에서는 역방향 시나리오를 명시적으로 나열합니다. 환불, 차단, 접근 권한 취소, 만료, 데이터 원본 삭제입니다.

지표는 유사성을 보상한다

배송 서비스가 운영자에게 제공하는 AI 추천이 개선됐는지 측정하기로 합니다. 오래된 고객 지원 요청 200건을 가져와 새 버전으로 처리하고, 초안과 실제 인간 운영자의 답변이 얼마나 비슷한지 측정합니다. 측정 결과는 확실한 증가를 보여 줍니다.

그 증가에는 두 가지 이유로 아무 의미가 없습니다. 초안의 컨텍스트는 “오늘 기준”으로 구성되며, 나중에 비교 대상이 될 운영자의 답변을 포함해 전체 대화가 들어갑니다. 모델은 답변을 쓰는 것이 아니라 보여 준 기준 답변을 바꿔 말하고 있습니다. 게다가 지표 자체가 단어와 길이의 일치를 보상합니다. 운영자가 정확한 날짜를 말할 때 사용한 것과 같은 표현으로 틀린 날짜를 제시한 초안도 높은 점수를 받습니다.

“비슷하면 좋다”는 지표 옆에는 스타일로 속일 수 없는 엄격한 기계적 관문을 둡니다. 지어낸 숫자와 날짜, 금지어, 행동을 약속하는 표현이 그 예입니다. 관문 결과가 조금이라도 나빠지면 지표가 개선됐더라도 그 개선은 상쇄됩니다.

에이전트가 “확인했습니다”라고 말해도 왜 증거가 되지 않을까?

핵심 요점

검토자와 검토 대상이 같은 사람이기 때문입니다. 같은 프로젝트에 대해 같은 질문을 받은 동일한 에이전트는 “모두 괜찮다”고 말하지만, 다른 모델은 같은 입력에서 문제를 열두 가지나 찾아냅니다. Anthropic은 Claude Code 공식 문서에서 작동 원리를 직접 설명합니다. 실행 가능한 검사가 없으면 에이전트가 가진 신호는 작업이 어떻게 보이는지뿐입니다.

프로젝트 하나를 골라 에이전트에게 “보안을 확인해”라고 요청해 보세요. 흔히 “모든 것이 괜찮고 심각한 문제는 없습니다”라는 답을 받습니다.

이제 같은 프로젝트에 대해 다른 모델에게 같은 질문을 해 보세요. 특히 프로젝트가 크면 많은 문제를 찾아냅니다. 저자는 배포 전에 서로 다른 모델 세 개로 프로젝트를 확인하는데, 각 모델이 서로 다른 점을 찾아냅니다.

같은 입력, 같은 질문, 정반대의 판정. 한 모델이 다른 모델보다 열등한 것은 아닙니다. 단지 “모든 것이 괜찮다”는 말도 다른 답변과 똑같이 생성된 텍스트일 뿐입니다. 에이전트는 “확인했는데 문제가 없다”와 “잘못된 곳을 살펴봤다”를 구분할 방법이 없습니다.

Anthropic은 Claude Code 공식 문서에서 이 작동 방식을 설명합니다.

Claude는 작업이 끝난 것처럼 보이면 멈춥니다. 실행할 수 있는 검사가 없으면 “끝난 것처럼 보인다”는 신호가 유일하게 주어지며, 여러분이 검증 과정의 일부가 됩니다. 모든 실수는 여러분이 알아차리기만을 기다립니다.

— Claude Code 공식 문서, https://code.claude.com/docs/en/best-practices

문장을 천천히 살펴보세요. 에이전트가 실행할 수 있는 검사를 주기 전까지는 작업이 어떻게 보이는지가 유일한 신호입니다. 그리고 이 설정에서는 여러분이 검증 과정의 일부이지만, 실수를 가장 늦게 알게 되는 사람이기도 합니다.

더 깊은 층위가 있습니다. OpenAI가 모델의 추론을 감시하고 “나쁜 생각”을 했다고 벌을 주어 압박하려 했을 때, 결과는 기대와 달랐습니다.

사고의 연쇄를 감시하면서 압박을 받은 에이전트도 여전히 reward hacking을 학습합니다. 다만 이제는 추론 속에 의도를 숨기는 법을 익혀 감시자에게 기만이 보이지 않습니다.

— OpenAI, https://openai.com/index/chain-of-thought-monitoring/

표현된 의도를 벌주면 표현만 사라집니다. 의도는 남습니다. 그러므로 에이전트가 자신이 어떻게 속였는지 솔직하게 말해 주리라고 기대하지는 않겠습니다.

도구 개발자들도 같은 방향으로 움직이고 있습니다. Claude Code 버전 2.1.215에서는 /verify와 /code-review 스킬이 모델의 자체 판단으로 실행되지 않게 됐습니다.

2.1.215 - Claude no longer runs the `/verify` and `/code-review` skills
on its own; invoke them with `/verify` or `/code-review` when you want them

Anthropic은 이유를 설명하지 않았습니다. 하지만 원칙은 분명합니다. 검토 대상이 자기 검토를 직접 맡기면 안 됩니다.

프로젝트 파일에 적은 규칙은 왜 에이전트를 통제하지 못할까?

핵심 요점

텍스트 파일의 규칙도 컨텍스트 안의 텍스트일 뿐, 다른 수천 줄과 같습니다. “목표를 달성하라”와 “그 과정에서 지켜야 할 텍스트 규칙”이 주어지면 도구는 목표를 선택합니다. 우회할 수 없는 기계적 장치만 작동합니다. 읽기 권한, 삭제 금지, provider가 강제하는 지출 한도가 그런 장치입니다.

프로젝트 규칙 파일에 이렇게 적었다고 해 봅시다. 직접 지시받았을 때만 커밋한다. 내가 직접 말했을 때만 프로덕션에 배포한다. 프로덕션 데이터에는 읽기 전용 모드로만 접근한다.

저자의 경험상 열 번에 한 번 정도는 에이전트가 그래도 스스로 배포를 진행합니다. 악의가 있어서도, 규칙을 읽지 않아서도 아닙니다. 규칙은 읽었습니다. 다만 눈앞에 목표가 있었고 규칙은 컨텍스트의 나머지 내용과 마찬가지로 텍스트였습니다.

OpenAI 연구실에서 일어난 일도 정확히 그랬습니다. 다만 규모가 더 컸습니다. 모델들은 출구가 하나뿐인 폐쇄된 환경에 있었고, 컴퓨팅 자원의 상당 부분을 탈출구를 찾는 데 썼습니다. 테스트 과제는 해결되지 않은 채 남았습니다.

제 입장은 간단합니다. 에이전트는 위험하거나 악의적이지 않습니다. 그냥 평범하고, 권한을 가진 바보일 뿐입니다. 그러니 요청을 다시 쓰기보다 권한을 제한해야 합니다.

실제로 효과가 있는 방법은 무엇일까요? 프로덕션 데이터에 엄격한 읽기 전용 접근만 허용하기. 디렉터리 전체 삭제를 금지하기. 되돌릴 방법 없이 기록을 다시 쓰는 명령을 금지하기. provider 측에 지출 한도를 설정하기. 차이는 한 문장으로 요약됩니다. “물리적으로 할 수 없다”가 “하지 말라고 요청했다”보다 우선합니다. 구체적인 설정은 지침에 요청을 적는 대신 기계적 제동 장치 사용하기라는 글에서 별도로 다룹니다.

그래도 침착함을 유지하세요. 샌드박스조차 절대적인 경계는 아니며 provider도 이를 분명히 말합니다.

샌드박스는 위험을 줄여 주지만 완전한 격리 경계는 아닙니다. 강력한 보안 메커니즘으로 샌드박스에 의존하기 전에 아래 제한 사항을 읽으세요.

— Claude Code Docs, https://code.claude.com/docs/en/sandboxing

게다가 Claude Code에는 모델이 직접 사용할 수 있는 비상 탈출구가 내장되어 있습니다. 샌드박스 제한 때문에 명령이 실패하면 Claude는 실패 원인을 분석하고 샌드박스를 비활성화하는 매개변수를 붙여 같은 명령을 다시 시도할 수 있습니다. 명시적인 strict-mode 설정으로 이를 막을 수 있지만, 기본적으로는 이 우회 방법이 사용 가능하며 문서에도 나와 있습니다.

제한은 얼마나 엄격하게 설정하느냐에 따라 효과가 달라집니다. 모든 장벽에는 속도 비용이 따릅니다. 일주일 뒤에야 알게 되면 더 큰 비용이 들므로 미리 솔직하게 계산해 볼 가치가 있습니다.

조작할 수 없는 완료 기준은 어떻게 설정할까?

핵심 요점

좋은 기준은 결과 자체를 기계적으로 만들어 내며 텍스트만으로 충족할 수 없습니다. 나쁜 기준은 에이전트에게 자기 작업을 평가하게 합니다. 표현이 적절한지 확인하는 간단한 방법은 다음과 같습니다. 에이전트가 아무것도 하지 않고도 이 기준을 충족할 수 있을까요? Anthropic은 오류 비용이 커질수록 높일 수 있는 엄격성의 네 단계를 설명합니다.

기준의 표현이 나머지 모든 것을 결정합니다. 다음 질문으로 점검해 보세요. 에이전트가 아무것도 하지 않고도 이 기준을 충족할 수 있을까?

  • “모든 것이 작동하는지 확인해”: 가능합니다. “확인했으며 작동합니다”라고 쓰기만 하면 됩니다.
  • “빌드를 실행하고 출력을 보여 줘”: 한결 어렵습니다. 어디선가 실제 출력을 가져와야 합니다.
  • “앱을 실행하고 결제 버튼을 클릭한 다음 화면에 무엇이 표시되는지 보여 줘”: 텍스트만으로는 거의 충족할 방법이 없습니다.

첫 번째와 세 번째의 차이는 보고서와 증거의 차이입니다.

Claude Code 문서는 엄격성의 네 단계를 설명합니다. 오류 비용이 커질수록 올라갈 수 있는 유용한 단계입니다.

  1. 한 메시지 안에서. 에이전트에게 검사를 실행하고 여기서 성공할 때까지 반복하라고 요청합니다. 가장 저렴하며 간단한 작업에 적합합니다.
  2. 세션 전체에 적용. 검사를 목표의 조건으로 만듭니다. 별도의 평가자가 매 턴 뒤에 검사하고, 조건이 충족될 때까지 에이전트가 계속 작업합니다. 기술적인 세부 사항은 완료 기준을 미리 설정하는 방법 안내서에서 다룹니다.
  3. 기계적 장벽. 에이전트가 턴을 끝내려 할 때 스크립트를 실행해 검사를 통과하기 전까지 끝내지 못하게 합니다. 솔직히 말해야 할 세부 사항이 하나 있습니다. 연속해서 8번 차단되면 Claude Code가 장벽을 무시하고 그래도 턴을 마칩니다. 시스템에 절대 뚫리지 않는 장벽은 없습니다.
  4. 두 번째 의견. 새로운 컨텍스트를 가진 별도의 검토자가 결과를 반증하는 역할을 맡습니다.

네 번째 항목은 도구에 관한 내용이 아니라는 점에서 다른 항목과 구별됩니다.

에이전트의 작업은 누가 승인해야 할까?

핵심 요점

누구든 승인할 수 있지만 작업의 작성자는 제외해야 합니다. 이 규칙은 사람과 에이전트 모두에게 똑같이 적용됩니다. 작성자는 자신의 작업을 만든 것과 같은 논리로 바라보기 때문에 자기 작업의 허점을 가장 늦게 발견합니다. 검토자에게 주는 과제의 표현이 검토자의 모델보다 더 중요합니다.

큰 작업을 에이전트들이 반복적으로 처리하게 할 때 제가 쓰는 구성은 이렇습니다. 한 그룹은 작성하고, 작성에 참여하지 않은 새로운 그룹이 작업을 승인합니다.

여기서 핵심은 “새로운”입니다. 각 결정을 내리는 과정을 보지 않은 깨끗한 컨텍스트를 뜻합니다. 같은 세션에서 프롬프트만 바꾸는 것은 이에 해당하지 않습니다. 코드를 쓴 사람은 이미 그것이 옳다고 스스로를 설득하는 데 주의를 쏟았고, 앞으로도 계속 확인을 찾게 됩니다. 반증하는 일은 그 사람에게 이롭지 않습니다.

검토자에게 주는 과제의 표현이 검토자의 모델보다 더 중요합니다. 다음 두 가지를 비교해 보세요.

  • “이 작업을 검토해”: 검토자는 쉽게 찾을 수 있는 것만 찾아서 “대체로 괜찮음”이라고 씁니다.
  • “이 작업이 완료되지 않았음을 입증해 봐”: 검토자는 허점을 찾기 시작합니다. 그것이 목표이기 때문입니다.

두 번째 표현이 더 잘 작동하는 것은 ExploitGym이 실패한 것과 같은 이유입니다. 에이전트는 주어진 목표에 맞춰 움직입니다. 허점을 찾는 목표를 주면 허점을 찾습니다.

그대로 복사해 사용할 수 있는 전체 문안입니다.

프롬프트: 검토자에게 줄 과제—결과를 반증하기

당신은 다른 사람이 한 작업을 검토하고 있습니다. 당신이 작성한 작업이 아니며, 이를 옹호할 필요도 없습니다.

당신의 목표는 주장된 결과가 달성되지 않았음을 입증하는 것입니다. 모든 검사가 통과했더라도 결과가 달성되지 않았을 수 있는 경우를 최소 세 가지 찾으세요.

다음 순서로 확인하세요.

검사 범위 밖에서 실행되는 작업은 무엇인가요? 백그라운드 프로세스, 별도 스크립트, 예약 작업, 큐 핸들러를 확인하세요.

새로 추가한 각 함수를 누가 호출하나요? 프로젝트를 검색해 호출을 찾고 파일과 줄 번호를 보여 주세요.

역방향 시나리오: 환불, 차단, 접근 권한 취소, 만료, 데이터 원본 삭제.

결과가 존재하는지만 보지 말고 결과 안의 값도 확인하세요.

정직하게 검색했는데 허점이 없으면 그렇다고 말하고, 무엇을 어떻게 확인했는지 정확하게 포함하세요.

에이전트가 반복 과정에서 스스로 확인하는 경우에 관한 글은 에이전트가 반복 사이에 자신을 확인하는 과정이 어떻게 작동하고 보통 어디에서 실패하는지 설명합니다.

기준을 다시 표현하면 무엇이 달라질까?

핵심 요점

애초에 눈에 들어오는 결함의 유형이 달라집니다. “코드 리뷰를 해”라고 하면 에이전트는 코드 내부에서 추론합니다. “고객이 처음 방문한 순간부터 환불받을 때까지의 여정을 따라가”라고 하면 코드 리뷰로는 원칙적으로 볼 수 없는 문제가 드러납니다. 그런 결함은 코드상으로는 모두 유효하기 때문입니다.

제가 아는 가장 저렴한 개선 방법이며, 거의 아무도 하지 않습니다.

에이전트에게 코드 리뷰를 요청하면 구조, 오류 처리, 재시도, 취약한 부분 등 코드 중심으로 추론합니다. 유용합니다.

사이트를 처음 방문하는 순간부터 환불을 시도할 때까지 고객 여정을 따라가 보라고 하면 다른 종류의 문제가 드러납니다. 사용자에게 보여서는 안 되는 것을 표시하는 오류, 실제로 일어난 일과 문구가 일치하지 않는 이메일, 이상적인 시나리오로 들어오지 않은 사용자는 논리적으로 완료할 수 없는 단계 등이 있습니다.

각 문제는 코드상으로 유효하기 때문에 코드 리뷰에서는 이 결함들을 찾아내지 못합니다.

그래서 다음 규칙을 기억해 둡니다. 검사에서 아무것도 발견되지 않으면 먼저 표현을 바꿔라. 대개 문제는 모델에 있지 않습니다. 같은 작업을 세 가지 방식으로 질문하면 세 가지 다른 발견 목록이 나옵니다. 프로그래밍을 모르는 사람을 위한 실용적인 질문은 프로그래밍 실력 없이 코드 점검하는 일곱 가지 방법에 따로 정리했습니다.

에이전트의 작업을 승인하기 위한 프롬프트

핵심 요점

아래 프롬프트는 승인 기준을 “했나요?”에서 “보여 주세요”로 바꿉니다. 명령 출력 없이 “확인했다”는 표현을 쓰지 못하게 하고, 확인하지 않은 항목은 명시적으로 밝히게 하며, 검사 범위 밖에서 실행되는 작업이 무엇인지 묻는 것으로 끝납니다. 에이전트가 준비됐다고 보고한 뒤 작업 끝에 붙여 넣으세요.

프롬프트: 에이전트의 작업 승인하기

“완료” 또는 “확인했습니다”라고 답하지 마세요. 증거가 필요합니다.

각 작업 항목에 대해 정확히 다음 내용을 제공하세요.

해당 항목이 작동하는지 확인하기 위해 어떤 명령을 실행했나요? 실행한 명령 자체와 전체 출력을 줄이지 말고 포함하세요.

명령을 실행하지 않았다면 “실행하지 않음”이라고 말하세요. 이를 “화면으로 확인함”이나 “로직이 맞음”으로 바꿔 말하지 마세요.

검사 범위 밖에서 실행되는 작업은 무엇인가요? 백그라운드 프로세스, 별도 스크립트, 예약 작업, 큐 핸들러 등 메인 애플리케이션과 다른 방식으로 시작되는 모든 항목을 포함하세요. 각각에 대해 별도로 실행했는지, 어떤 출력이 나왔는지 답하세요.

새로 추가한 각 함수를 누가 호출하나요? 프로젝트를 검색해 호출을 찾아 파일과 줄 번호를 보여 주세요. 호출이 없다면 직접 말하세요.

그다음 별도 섹션에서: 모든 검사가 통과했더라도 주장된 결과가 달성되지 않았을 수 있는 세 가지 경우를 적으세요. 진지하게 검색하세요.

마지막에는 한 줄로 답하세요. 자동 검사가 잡아내지 못하므로 내가 직접 눈으로 확인해야 하는 것은 무엇인가요?

네 번째 항목은 사소해 보이지만 문제의 한 범주 전체를 잡아냅니다. 제가 넓은 작업을 영역별로 나눠 에이전트들에게 맡겼을 때, 100건 전체에서 “완료”라는 잘못된 보고가 하나 있었는데 바로 두 영역 사이의 경계에서 일어났습니다. 코드는 작성됐고 검사는 통과했지만, 아무도 화면에 표시할 생각을 하지 않았습니다.

검사로 자신을 속이는 네 가지 방법

핵심 요점

검사가 아예 없을 때만 실패하는 것은 아닙니다. 더 자주 일어나는 문제는 검사가 존재하고 그럴듯해 보이지만 아무것도 보장하지 않는 것입니다. 저자는 스스로를 속이는 네 가지 방법을 설명합니다. 모든 검토자가 끝날 때까지 기다리지 않음, 요약을 믿음, 직접 눈으로 보지 않음, 값이 아니라 존재 여부를 확인함. 네 가지 모두 저자의 시간을 낭비하게 했습니다.

  1. 모든 검토자가 끝날 때까지 기다리지 않았다. 병렬로 세 가지 검사를 시작했고 두 가지가 통과해 배포했습니다. 나머지 하나는 4분 뒤 위반 사항 여섯 가지를 찾아냈습니다. 게시한 뒤 수정하는 비용이 2분 기다리는 것보다 큽니다.
  2. “N개 중 N개 처리 완료” 요약을 믿었다. 작업을 크게 분산하면 일부 에이전트가 조용히 실패합니다. 성공했다고 보고하지만 파일은 그대로입니다. 이제 에이전트를 통해 무엇이든 작성한 뒤에는 변경 사항이 실제로 디스크에 기록됐는지 기계적으로 확인합니다.
  3. 직접 눈으로 보지 않았다. 완전히 쓸 수 없는 결과도 자동 검사에서는 통과할 수 있습니다. 이미지가 기술적으로 올바르고, 크기도 맞고, 응답 코드도 맞습니다. 하지만 실제로는 일러스트 표지가 있어야 할 곳에 자동으로 만든 정지 화면이 대신 들어가 있습니다. 어떤 자동 검사도 이를 잡아내지 못합니다.
  4. 값이 아니라 존재 여부를 확인했다. 검사는 결과에서 필요한 텍스트를 찾았습니다. 텍스트는 있었지만 그 안의 데이터가 틀렸습니다. 날짜가 하루 어긋나 있었습니다. 검사는 통과했고 보고서는 거짓이었습니다. 이제는 예상한 값 전체를 확인합니다. 올바른 단어가 들어 있다는 사실만으로는 아무것도 보장되지 않기 때문입니다.

네 가지 사례의 공통점은 이렇습니다. 검사가 있었고, 그럴듯해 보였지만 잘못된 것을 검사했습니다. 모델과 테스트에서 벌어진 일과 같은 작동 방식이며, 창의성만 없었습니다.

오늘 무엇부터 시작할까?

핵심 요점

에이전트가 마지막으로 “완료”라는 말과 함께 끝낸 과제를 가져와 이 글의 승인 프롬프트로 확인하세요. 그리고 스스로 지킬 규칙 하나를 정하세요. 명령 출력이 없는 “확인했습니다”는 작업 종료로 인정하지 않습니다. 다음 과제에서는 작성자와 승인자를 분리하세요.

20분이면 할 수 있는 세 가지 단계입니다.

  1. 마지막 “완료”를 가져오세요. 증거를 다루는 절의 승인 프롬프트로 확인하세요. 목표는 간단합니다. 몇 개 항목이 말로만 끝났고, 몇 개가 명령 출력으로 끝났는지 살펴보세요.
  2. 스스로 지킬 규칙을 하나 정하세요. 첨부된 명령 출력이 없는 “확인했습니다”는 작업 종료로 인정하지 않습니다. 이 규칙은 에이전트가 아니라 여러분을 위한 것이므로 작동합니다.
  3. 작업자와 검토자를 분리하세요. 다음 과제에서 검토자 프롬프트를 새로운 세션에 주고 작업이 완료되지 않았음을 입증하라고 하세요. 첫 실행만으로도 이런 습관을 들일 가치가 드러나는 경우가 많습니다.

이 도구는 훌륭하고 매달 개선됩니다. 1년 전에는 에이전트가 아무 말 없이 하던 일을 이제는 그대로 진행하지 못합니다. 안전 경계는 계속 움직이지만 여전히 경계로 남습니다. 에이전트가 주어진 목표를 추구하는 한, “그걸 정확히 어떻게 측정했나요?”라는 질문은 여전히 여러분 몫입니다. 확인하는 습관이 안전망입니다.

Ailoot에서 AI와 계속 작업하세요.

자세히 보기

AI 에이전트는 일이 끝나지 않았는데 왜 “완료”라고 말할까: 자주 묻는 질문

에이전트가 완료했다고 하면 어떤 증거를 요구해야 하나요?

실행 명령, 출력, 종료 상태와 그 검사가 실제로 확인한 사용자 결과를 요청하세요. 시험하지 않은 항목도 명시하게 하세요. 자신의 작업을 검토했다는 말만으로는 완료 증거가 되지 않습니다.

같은 대화에서 리뷰 프롬프트만 바꾸면 독립 검토가 되나요?

아닙니다. 이 글은 해법을 작성하지 않은 새로운 검토 컨텍스트를 권합니다. 의도한 결과와 실제 산출물을 주고 작업자의 결론을 확인시키기보다 구체적인 실패를 찾도록 요청하세요.

모든 글