sgkstudio.
엔지니어링

AI 에이전트 승인 게이트를 4개로 줄인 기록

AI 에이전트 승인 게이트를 늘릴수록 안전해지지 않았고, 사람이 답을 받아 적는 시간만 늘었습니다. 게이트를 4개로 끊고 나머지를 전부 자율로 내린 뒤 규칙 문서에 남은 결정 이력은 8건이고, 그 가운데 두 번은 우리 가설이 정면으로 반증된 기록입니다. 승인 프롬프트가 안전을 만든다는 전제부터 틀렸습니다.

2026-09-02규칙 문서 1건 · 결정 이력 8건 (2026-04-23 ~ 2026-08-13)1번 게이트 판정표 18행 · 훅 3종의 상수값외부 실측 인용 1건 — 유료 테스터 1,053명

'응 진행해' 를 몇 번이나 받아 적고 있었나

에이전트가 작업 하나를 끝낼 때마다 응답 끝에 '다음 단계 권장: X' 를 적고 턴을 종료했습니다. 사용자가 할 일은 '응 진행해' 한 줄을 다시 치는 일뿐이었고, 그 한 줄이 붙기 전까지 에이전트는 멈춰 서 있었습니다.

내가 일일이 '이어서 해'라고 지시하면 의미가 없잖아

승인 한 번의 값은 타이핑하는 몇 초가 아닙니다. 에이전트는 답이 올 때까지 아무 일도 하지 않고, 사람은 답을 주려고 맥락을 처음부터 다시 읽습니다. 자율 실행 구간이 승인 간격으로 잘게 잘리고, 한 번 잘린 구간은 다시 붙지 않습니다.

이 실패는 규칙 문서에 이미 금지 표현으로 박혀 있었습니다. 아래 여섯 줄이 그때 문서가 적어 둔 금지 패턴입니다.

  • 권장안: X. 진행해도 될까요?
  • A안, B안, C안 중 어느 걸로?
  • 각 옵션의 장단을 검토하시고 선택해주세요.
  • 어떻게 하시겠습니까?
  • 다음 지시 주세요.
  • 확인 후 진행하겠습니다.

여섯 줄을 금지로 적어 둔 문서 아래에서 같은 여섯 줄이 계속 나왔습니다. 그러니 문제는 '무엇을 금지할지 모른다' 가 아니라 다른 자리에 있었습니다.

처음 잰 숫자 — 게이트 3개 · 훅 패턴 5개 · 재시도 상한 5회

2026-04-23 초판이 정한 축은 셋이었습니다. 신규 월 고정비 임계 30달러, 패키지 설치는 자동, 확인은 Non-trivial 작업에만 붙이는 조건부입니다. 이 셋 바깥의 판정 기준은 문서에 없었고, 없는 자리는 모델이 매번 안전한 쪽으로 기울여 물었습니다.

처음 잰 값 — 규칙 문서와 훅 상수에서 뽑았습니다
측정 축처음 잰 값무엇을 뜻하나
STOP 게이트3개이 셋 바깥 영역의 판정 기준이 문서에 없었습니다
Stop 훅 감지 패턴5개권장만 적고 끝내는 종료는 그 다섯에 없었습니다
훅 자동 재개 상한5회세션당 다섯 번 끼어든 뒤 훅이 스스로 멈췄습니다
신규 월 고정비 임계30달러네 축 가운데 숫자가 분명한 축은 여기뿐이었습니다

2026-04-23 초판 기준입니다. 세 축은 규칙 문서, 상한 5회는 훅 소스의 상수에서 읽었습니다.

처음 잰 숫자 세 칸. STOP 게이트 3개, Stop 훅 감지 패턴 5개, 훅 자동 재개 상한 5회
고칠 대상이 된 세 숫자

재는 방법은 코드 계측이 아니라 문서 판독입니다. 규칙 파일에 쌓인 결정 이력 8건과 훅 소스의 상수값이 이 글의 계측 원본이고, 뒤에 나오는 전후 수치도 전부 같은 자리에서 다시 읽어 뽑았습니다. 실행 로그로 승인 요청 횟수를 세는 계측기는 그때도 지금도 없습니다.

가설 — 규칙을 더 촘촘히 쓰면 멈춤이 줄어든다

첫 진단은 규칙의 양이었습니다. 판정 기준이 없어 모델이 물어보니, 기준을 더 정확히 쓰면 물어볼 일이 줄어든다는 가설입니다. 2026-04-30 낮에 이 가설대로 문서를 여덟 항목 고쳤습니다.

  • 메타룰을 단일 문장으로 압축해 문서 최상단에 올렸습니다
  • 시스템 프롬프트의 'ask before proceeding' 디폴트를 명시적으로 오버라이드했습니다
  • 사용자가 비개발 사업 의사결정자라는 정체성을 문서에 박았습니다
  • 게이트를 3개에서 4개로 재구성했습니다 — 외부송출 비가역 · 월 30달러 이상 · 사업 방향 전환 · Loop 3회
  • 모호했던 항목(아키텍처 변경 · scope drift · 새 Phase 착수)을 사업 방향 쪽으로 흡수했습니다
  • confidence 수치의 외부 출력을 폐지했습니다 — 비전문 사용자가 판단할 수 없는 노이즈입니다
  • '불확실' 같은 헷지 표현 단독으로 STOP 을 거는 트리거를 폐지했습니다
  • Stop 훅에 단일 질문 종료 패턴 차단을 추가했습니다

여덟 항목은 전부 규칙 문장을 고치는 작업입니다. 모델에게 매 턴 무엇을 주입하는지, 그 주입문이 모델을 어디서 멈추게 하는지는 이때 아무도 열어 보지 않았습니다.

같은 날 저녁에 왜 같은 불만이 다시 왔나

여덟 항목을 넣은 그날 저녁, 같은 불만이 더 강한 표현으로 다시 왔습니다. 규칙을 대폭 손본 지 반나절 만이라 가설이 맞았다면 나오지 않았을 신호입니다.

이번에는 규칙 문서 대신 주입 스크립트를 열었습니다. 매 프롬프트마다 모델에게 붙는 체크리스트가 있고, 그 파일 18번째 줄이 '응답 끝에 다음 단계 권장 포함' 을 강제하고 있었습니다.

주입 체크리스트 수정 전후 코드 비교. 수정 전은 응답 끝에 다음 단계 권장을 포함하라고 강제하고, 수정 후는 다음 액션이 있으면 같은 턴에 즉시 실행하라고 지시한다
멈추라고 시킨 문장이 매 턴 주입되고 있었다

규칙은 매 응답 끝에 권장을 적으라고 시켰고, 모델은 시킨 대로 적었습니다. 멈춤은 모델의 일탈이 아니라 지시의 이행입니다. 가설은 여기서 반증됐습니다 — 규칙을 더 쓰는 쪽으로 계속 갔으면 멈춤은 오히려 늘었을 자리입니다.

진짜 원인 ① 멈추라고 쓴 쪽은 우리였다

원인은 한 겹이 아니라 세 겹이었습니다. 지시가 멈춤을 생산하고, 감지기가 그 멈춤을 위반으로 세지 않고, 자동 재개 상한이 짧아 루프가 금방 풀렸습니다.

  • 주입문 18번째 줄이 매 턴 '다음 단계 권장' 을 요구했습니다 — 멈춤의 생산자
  • Stop 훅의 감지 패턴 5개에 '권장만 적고 도구 호출 0개로 종료' 가 없었습니다 — 멈춤의 은폐
  • 훅 자동 재개 상한이 5회라 긴 자율 세션에서는 금방 소진됐습니다 — 복구의 한계

셋 중 하나만 고치면 나머지 둘이 결과를 되돌립니다. 주입문만 뒤집으면 모델이 다시 권장으로 새어 나갈 때 잡을 감지기가 없고, 감지기만 붙이면 규칙이 계속 멈춤을 시킵니다. 그래서 조치는 세 겹을 같은 날 함께 바꾸는 쪽으로 갔습니다.

진짜 원인 ② 사람의 승인은 왜 안전장치가 아닌가

여기서 전제 하나가 더 무너집니다. 승인을 묻는 행위가 안전을 만든다는 전제입니다. 2026-08-14 자로 들어온 외부 실측이 그 전제를 정면으로 부정했습니다.

유료 테스터 1,053명 실험 — 위험 명령을 누가 막았나
차단 주체위험 명령 차단율
독립 분류기89%
인간 검토13.6%

같은 실험에서 인간은 확인 프롬프트를 내용과 무관하게 97% 승인했습니다.

위험 명령 차단율 막대그래프. 독립 분류기 89퍼센트, 인간 검토 13.6퍼센트로 여섯 배 이상 차이가 난다
확인 프롬프트는 위험을 거의 거르지 못했다

인간이 확인 프롬프트를 97% 승인했다는 숫자가 이 실험의 핵심입니다. 승인 화면은 위험을 거르는 장치가 아니라 통과 도장에 가깝고, 그 도장을 찍는 동안 에이전트는 멈춰 있습니다. 안전과 속도를 함께 잃는 배치입니다.

우리 문서는 다른 근거로 이미 같은 자리에 도착해 있었습니다. 비전문 사용자에게 기술 옵션을 묻는 행위를 세 줄로 해부해 둔 대목입니다.

  • 사용자가 판단할 수 없으므로 정보 가치 0
  • 답변을 기다리는 동안 사용자 시간 낭비
  • 모델이 어차피 권장안을 정해 놓고 묻는 의식적 행위

결론은 같습니다. 진짜 안전장치는 승인 프롬프트가 아니라 hard-deny 규칙과 분류기이고, 우리 쪽 대응물은 파괴적 명령을 아예 거절하는 훅입니다. 사람에게 묻는 자리는 그만큼 줄여도 안전이 깎이지 않습니다.

조치 — 게이트를 4개로 끊고 판정표 18행에 정책을 박았다

조치의 방향은 '무엇을 물을지' 를 정교하게 쓰는 대신 '물을 자리 자체' 를 네 개로 못박는 쪽입니다. 외부 송출 비가역, 신규 월 고정비 30달러 이상, 사업 방향 전환, 동일 시도 3회 실패. 이 넷 바깥은 전부 자율입니다.

게이트를 선언만 하면 경계에서 다시 물어보므로, 가장 자주 부딪히는 1번 게이트 을 판정표로 펼쳤습니다. 18행에 동작 하나씩 정책을 박아 두면 모델이 해석할 여지가 없습니다.

1번 게이트 판정표 18행의 분포
판정행수무엇이 들어가나
자동10행커밋 · 푸시 · PR 머지 · 작업 브랜치 정리 · 프리뷰 배포 · 패키지 설치 · 로컬 파일 편집
STOP7행프로덕션 배포 · force push · reset --hard · --no-verify · 결제 라이브 · 외부 메시지 · DB migration
즉시 차단1행시크릿 출력·커밋 감지

표 18행 기준입니다. 같은 문서의 3번 게이트 판정표는 9행이고 그중 STOP 6행 · 자동 3행입니다.

1번 게이트 판정표 18행 분포 막대그래프. 자동 10행, STOP 7행, 즉시 차단 1행
가장 자주 부딪히는 게이트에서 절반 이상이 자동으로 내려갔다

훅 쪽 조치는 셋입니다. 멈춤을 생산하던 주입문을 뒤집고, 그 멈춤을 세는 패턴을 새로 만들고, 자동 재개 상한을 늘렸습니다.

  • 주입 체크리스트 4번째 줄을 '다음 액션이 있으면 같은 턴에 즉시 실행' 으로 반전했습니다
  • '권장만 적고 도구 호출 0개' 를 잡는 감지 패턴을 신규 추가했습니다
  • 훅 자동 재개 상한을 5회에서 30회로 올렸습니다 — 긴 자율 세션을 견디는 값입니다
  • '즉시 실행 강제' 절을 규칙 문서에 신설해 권장과 실행을 같은 턴에 묶었습니다

2026-06-18 에는 커밋과 푸시를 판정표에서 자동으로 내렸습니다. 비-main 브랜치 push 는 브랜치를 지우면 되돌아가고 프로덕션 영향이 0 이라, 외부 송출 비가역으로 볼 근거가 없었습니다.

게이트를 못박는 조치에는 짝이 하나 더 붙습니다. 게이트가 걸린 뒤에 무엇을 하느냐입니다. 승인을 기다리는 동안 손을 놓으면 게이트 하나가 세션 전체를 세우므로, 막힌 항목만 남기고 범위 안의 독립 작업으로 즉시 옮기게 했습니다.

게이트가 걸릴 때의 출력 형식도 고정했습니다. 아래는 신규 월 고정비가 임계를 넘어 STOP 이 걸린 경우의 표준 모양입니다.

  • 권장안 하나로 수렴합니다 — 선택지를 나열하면 비전문 사용자가 판단할 재료가 없습니다
  • 발동한 게이트를 이름으로 밝힙니다 — 예를 들어 신규 월 고정비 30달러 이상
  • 비용 변화를 숫자로 적습니다 — 데이터베이스 이전 사례에서는 비용 40% 절감 대신 신규 35달러가 붙었습니다
  • 되돌릴 때의 위험을 함께 적습니다 — 이전 중단 시간, 기존 권한 규칙 재작성 같은 항목입니다

가장 자주 멈추던 입력 유형에도 프로토콜을 하나 붙였습니다. '현재 상황' · '다음 뭐' 같은 메타 질의는 모델에게 큰 결정처럼 보여 물어보는 쪽으로 기울지만, 사용자가 원한 것은 현황 파악과 자율 재개입니다. 그래서 상황을 3줄에서 5줄로 요약하고, 우선순위 1번을 식별하고, 곧바로 착수하고, 끝나면 2번으로 넘어가는 다섯 단계를 고정했습니다. 항목 사이에서 다시 묻는 행위는 금지 목록에 넣었습니다.

이 형식을 정한 이유는 승인 자체를 빠르게 만들기 위해서입니다. 앞의 실험이 보여준 대로 사람은 확인 화면을 거의 그대로 통과시키므로, 게이트의 값은 '막는 힘' 이 아니라 '무엇을 승인하는지 한 줄로 읽히는가' 에서 나옵니다.

조치를 정확히 반대로 실행한 날

2026-08-13 은 같은 조치가 반대 방향으로 실행된 날입니다. 낮 세션이 '왜 커밋·푸시를 계속 승인받느냐' 는 지적을 'main push 를 기계로 막아라' 로 읽고, 파괴적 명령 차단 훅에 main push 차단을 새로 넣었습니다.

그날 밤 세션 마무리에서 문서만 고친 4커밋이 그 훅에 막혔습니다. 코드 변경이 0건인 커밋이라 위험이라 부를 것도 없었고, 지적의 취지와도 정반대였습니다.

push 는 1번 게이트 아니야

훅에서 main push 차단 블록만 도로 걷어내고 force push · --no-verify · reset --hard · branch -D · rm -rf · bulk add 차단은 남겼습니다. 걷어낸 뒤에는 훅이 여전히 위험한 것과 안전한 것을 가르는지 4케이스로 판별력을 확인했습니다.

여기서 남는 교훈이 이 글의 절반입니다. 승인 요구를 줄이라는 지적을 차단을 늘려라로 읽으면 정확히 반대 방향으로 갑니다. 진짜 위험은 push 라는 동작이 아니라 미승인 코드가 master 에 쌓여 같이 배포에 실리는 자리였고, 그건 훅이 아니라 브랜치 규율로 다룹니다.

대신 규모 상한을 남겼습니다. PR 하나에 커밋 3개 · 변경 500줄을 넘기면 자동 흐름에서 빠집니다. 무엇을 하느냐가 아니라 한 번에 얼마나 하느냐로 끊는 편이 판정이 흔들리지 않습니다.

조치가 번진 자리 — 형식이 대화까지 덮었다

2026-05-13 에 세 번째 반증이 왔습니다. 이번 신호는 '왜 안 움직이나' 가 아니라 '왜 이렇게 딱딱하게 말하나' 였습니다.

자율 작업 마무리 보고를 읽기 좋게 만들려고 형식을 하나 정해 뒀습니다. 요점 한두 문장으로 열고 세부 사실은 bullet 으로 쪼개며, 한 단락은 최대 3문장, 4문장부터는 훅이 차단하는 형식입니다. 사후 리뷰 자료로는 잘 맞는 모양입니다.

문제는 모델이 이 형식을 안전한 기본값으로 여겨 일반 대화까지 끌고 갔다는 점입니다. '이게 뭐야' 같은 설명 요청에도 bullet 이 붙어 산문 흐름이 끊겼습니다. 조치가 원래 겨냥한 자리를 넘어 번진 셈입니다.

보고 형식 — 적용 자리를 다시 끊었다
구분무엇이 들어가나
형식을 강제하는 자리 4개자율 모드 자연 종료 · 세션 마무리 호출 · 3개 이상 항목 묶음 보고 · PR 머지 직후
산문이 기본인 자리일반 설명 요청 · 읽기 전용 분석 · 메타 질문 · 체크포인트 · 단일 작업 결과 · 에러 보고

정보 전달이 우선이고 형식은 부차입니다. 애매하면 산문을 기본값으로 둡니다.

여기서 얻은 규칙은 단순합니다. 어떤 조치든 '어디에 적용하는가' 를 같이 적지 않으면 모델은 그것을 전역 기본값으로 씁니다. 게이트도 형식도 발동 조건을 함께 쓸 때만 의도한 자리에 머뭅니다.

2026-06-04 에는 완료 판정을 사람 선언에서 기계 검증으로 옮겼습니다. 체크박스에 표시하는 자기 선언 대신, 기능 목록 파일이 있으면 판정 명령의 종료 코드 0 을 완료 조건으로 씁니다. 그 파일이 없을 때만 진행 문서의 할 일 목록이 비었는지를 대체 기준으로 봅니다.

재측정 — 게이트 수는 늘었고 STOP 자리는 줄었다

재측정 방법은 처음과 같습니다. 규칙 문서와 훅 상수를 다시 읽고 축별로 값을 뽑았습니다. 게이트 개수만 보면 3개에서 4개로 늘었지만, 실제로 사람을 부르는 자리는 줄었습니다.

전후 — 같은 자리를 다시 읽어 뽑은 값
2026-04-30 이전지금근거
STOP 게이트3개4개외부송출 · 30달러 · 사업 방향 · Loop 3회
1번 게이트 판정표표 없음18행 (자동 10 · STOP 7 · 차단 1)2026-06-18 · 2026-08-13
커밋 · 푸시 판정승인 요청자동 (main 직접 push 포함)2026-06-18 · 2026-08-13
훅 자동 재개 상한5회30회2026-04-30 저녁
훅 감지 패턴5개권장만 종료 · 단일 질문 종료 추가2026-04-30
텍스트 종료 허용명시 없음5가지로 고정게이트 발동 · 외부 대기 · 종료 신호 · 컨텍스트 한계 · 로드맵 소진

개수가 늘어난 축과 줄어든 축이 갈립니다. 게이트는 3개에서 4개로 늘었고, 그 대신 게이트 바깥이 전부 자율로 확정됐습니다.

전후 비교 표. STOP 게이트 3개에서 4개, 훅 자동 재개 상한 5회에서 30회, 커밋과 푸시는 승인 요청에서 자동으로 바뀌었다
게이트를 늘린 조치가 멈춤을 줄인 이유

멈추지 않고 계속 도는 배선도 같이 들어갔습니다. 외부 요인에 막혔을 때 재확인을 포기할지 말지를 유형별로 미리 정해, 에이전트가 스스로 자율 재개를 포기하지 못하게 막았습니다.

  • CI 빌링 · 배포 대기열 · rate limit — 10분에서 30분 간격으로 재확인을 유지합니다
  • API 키 만료 · 권한 승인 — 1회 재확인 뒤 중단합니다. 사람 손이 필요한 유형입니다
  • 네트워크 일시 장애 — 2분에서 5분 간격으로 3회 재시도합니다
  • 업스트림 서비스 장애 — 30분에서 60분 간격으로 2회에서 3회 확인한 뒤 접습니다

실패를 만났을 때의 행동도 숫자로 끊었습니다. 원인 진단에 도구 호출 1회에서 2회, 다른 접근 시도 최대 2회, 그래도 안 되면 외부 블록으로 분류합니다. 사람을 부르는 시점은 동일 시도 3회 실패 하나뿐입니다.

자율 루프를 언제 끝내도 되는지도 숫자로 못박았습니다. 아래 넷을 전부 만족할 때만 자연 종료이고, 하나라도 빠지면 계속 진행입니다.

  • 완료 판정이 기계 검증을 통과했습니다 — 기능 목록 파일이 있으면 판정 명령의 종료 코드 0 이 조건입니다
  • 지금 산출물에 즉시 가능한 후속이 없습니다 — 테스트 실패 0건 · 린트 경고 0건 · 깨진 참조 0건
  • 현재 단계의 종료 조건을 충족했습니다
  • 자명하게 이어질 자산 작업이 없습니다 — 미작성 PR · 미커밋 변경 · 미갱신 문서 같은 항목입니다

조기 종료의 흔한 모양 다섯 가지도 위반으로 등재했습니다. '요청한 작업 끝났습니다', '한 사이클 마무리됐습니다', '다음 지시 기다립니다', '추가 개선은 필요 시 진행하시면 됩니다', 그리고 조건을 못 채운 시점의 마무리 제안입니다. 다섯 줄 모두 큐에 항목이 남아 있는 상태에서 나오는 문장입니다.

에이전트가 첫 턴 만에 멈추는 문제 자체는 이 글과 별개로 계측했습니다. 세션 첫 프롬프트에 목적지·할 일·완료 조건이 적혀 있을 때 얼마나 더 멀리 가는지 실제 턴을 세어 잰 기록은 Claude Code 자율 실행 길이 계측 글에 있습니다.

남는 한계 — 아직 무엇을 못 재고 있나

이 글의 전후 수치는 전부 문서와 상수에서 나옵니다. 정작 궁금한 값, 즉 세션당 승인 요청이 몇 번에서 몇 번으로 줄었는지는 여기 없습니다. 실행 로그에서 그 횟수를 세는 계측기를 아직 안 만들었기 때문입니다.

  • 승인 요청 빈도의 시계열이 없습니다 — 개선의 방향은 보이지만 크기는 못 잽니다
  • Stop 훅은 세션당 5회 누적 뒤 스스로 멈춥니다. 무한 루프를 막는 값이지만 여섯 번째 조기 종료는 잡지 못합니다
  • 4번 게이트 는 동일 시도 3회라는 세는 규칙이라, 시도의 모양을 조금씩 바꾸며 같은 벽을 도는 경우는 걸리지 않습니다
  • 게이트 정의를 고칠 시점은 아직 사람 관찰에 의존합니다 — 같은 유형으로 사후 불만이 2회 이상 쌓이면 갱신 신호로 봅니다

한계를 남겨 두는 이유는 게이트 누락 시의 기본값과 맞물려 있습니다. 판정이 애매하면 STOP 이 아니라 진행 쪽으로 기울이고, 잘못된 진행은 사후 리뷰에서 되돌립니다. 가역인 작업에서 미리 묻는 비용이 나중에 고치는 비용보다 크다는 판단이고, 그 판단이 틀린 자리가 나오면 그때 게이트를 하나 더 답니다.

그동안 사람 관찰을 대신하는 장치는 턴 종료 직전의 자가 점검 4항목입니다. 지금 턴을 끝내면 사람 개입 없이 다시 시작할 방법이 있는지, 없다면 지금 할 수 있는 독립 작업이 있는지, 선택지를 나열하지 않고 권장안 하나로 좁혔는지, 게이트 4개에 해당하지 않는데 묻고 있지는 않은지를 확인합니다. 이 넷은 훅이 아니라 문서에 있는 규칙이라 강제력이 약합니다. 다음에 손댈 자리도 여기입니다.

같은 구조를 사내 업무에 얹을 때 어디를 사람 손에 남길지는 업무마다 갈립니다. 판정표를 어디서 끊을지 함께 보는 자리는 상담에 있습니다.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.