ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AI 에이전트에게 자율권을 얼마나 줄 것인가 - HITL Policy 설계
    IT 2026. 3. 14. 23:00

    AI가 일을 대신 해준다면서, 왜 이렇게 자꾸 물어보는 거야?

    AI 에이전트 도구를 쓰다 보면 이런 경험 해보셨을 겁니다.

    "파일 읽어도 될까요?"
    "이 명령어 실행해도 될까요?"
    "이 검색을 수행해도 될까요?"

    한두 번이야 괜찮죠. 그런데 작업 하나에 10번, 20번씩 물어보면 어떨까요? AI한테 일을 시킨 건데, 결국 내가 계속 "응, 해" 버튼을 눌러야 합니다. 이러면 자동화가 아니라 반자동화도 아닌, 그냥 승인 버튼 노가다입니다.

    이 문제의 핵심에 HITL(Human-in-the-Loop)이라는 개념이 있습니다. AI 에이전트가 자율적으로 작업하되, 적절한 순간에 사람의 판단을 받는 구조인데요. 여기서 "적절한 순간"을 잘 정의하는 것이 바로 HITL Policy입니다.

    HITL Policy란?

    HITL Policy는 AI 에이전트의 모든 행동을 세 가지로 분류하는 규칙입니다:

    구분 의미 예시
    Allow 묻지 않고 바로 실행 파일 읽기, git status, 검색
    Deny 절대 실행하지 않음 rm -rf, force push, 데이터 삭제
    Ask 사람에게 확인 후 실행 프로세스 종료, 서비스 재시작

    이 세 가지를 어떻게 설정하느냐에 따라, AI 에이전트와의 협업 경험이 완전히 달라집니다.

    잘못된 기본값: 모든 게 Ask

    대부분의 AI 에이전트 도구는 안전 우선으로 설계됩니다. 그래서 기본 설정은 "잘 모르겠으면 물어보기"입니다. 이게 틀린 건 아닌데, 문제는 시간이 지날수록 이런 일이 벌어진다는 겁니다:

    # 실제로 쌓이는 허용 목록 (60개 이상...)
    "Bash(curl -s \"https://api.example.com/endpoint\" | python3 -m json.tool)"
    "Bash(tail -5 /tmp/app/app-2026-03-14.log | python3 -c \"import sys,json; ...\")"
    "Bash(cat /path/to/config.json | python3 -m json.tool 2>/dev/null | head -60)"
    # ... 비슷한 명령어가 60줄 넘게 계속됨
    

    무슨 일이 벌어진 걸까요? 매번 "허용" 버튼을 누를 때마다, 정확히 그 명령어 한 줄만 허용 목록에 추가된 겁니다. curl로 API를 호출하는 건 같은 종류의 작업인데, URL이 조금만 바뀌어도 또 물어봅니다. 파라미터 하나 다르면 또 물어봅니다.

    이건 마치 회사에서 "복사기 사용 허가"를 문서 한 장마다 받는 것과 같습니다. "복사기를 쓸 수 있는 사람"으로 한 번 등록하면 될 일을요.

    해결: 카테고리 기반 Allow 설계

    핵심은 개별 명령어가 아니라 카테고리로 허용하는 것입니다. 와일드카드(*) 패턴을 활용합니다.

    Before: 명령어 하나하나 허용 (60개+)

    {
      "permissions": {
        "allow": [
          "Bash(curl -s \"https://api.example.com/v1/status\" | python3 -m json.tool)",
          "Bash(curl -s \"https://api.example.com/v1/updates\" | head -30)",
          "Bash(curl -s \"https://api.example.com/v1/info\" | python3 -m json.tool)",
          "Bash(tail -5 /tmp/app/app.log | python3 -c \"...\")",
          "Bash(cat ~/.config/app/config.json | python3 -m json.tool | head -60)",
          // ... 55개 더
        ]
      }
    }

    After: 카테고리별 와일드카드 (정리된 구조)

    {
      "permissions": {
        "allow": [
          // --- 버전 관리 ---
          "Bash(git *)",
    
          // --- 개발 도구 ---
          "Bash(python3 *)",
          "Bash(node *)",
          "Bash(npm *)",
          "Bash(pip install *)",
    
          // --- 시스템 정보 (읽기 전용) ---
          "Bash(ls *)",
          "Bash(cat *)",
          "Bash(find *)",
          "Bash(nvidia-smi *)",
          "Bash(who *)",
    
          // --- 네트워크/API ---
          "Bash(curl *)",
    
          // --- 파일 조작 (생성/이동) ---
          "Bash(mkdir *)",
          "Bash(cp *)",
          "Bash(mv *)",
          "Bash(touch *)",
    
          // --- 웹 검색 ---
          "WebSearch",
          "WebFetch"
        ],
        "deny": [
          // --- 절대 금지 (비가역적 작업) ---
          "Bash(rm -rf *)",
          "Bash(git reset --hard*)",
          "Bash(git push --force*)",
          "Bash(git push -f *)",
          "Bash(git clean -f*)"
        ]
      }
    }

    어디서 설정하나요?

    이 설정은 AI 코딩 에이전트의 설정 파일에서 관리합니다. 예를 들어, 프로젝트 루트의 .claude/settings.local.json 파일에 permissions 객체를 정의하면 됩니다. 이 파일은 git에 커밋되지 않는 로컬 설정이므로, 개인 환경에 맞게 자유롭게 조정할 수 있습니다.

    // .claude/settings.local.json
    {
      "permissions": {
        "allow": [ "Bash(git *)", "Bash(python3 *)", ... ],
        "deny":  [ "Bash(rm -rf *)", "Bash(git push --force*)", ... ]
      }
    }

    팀 전체에 공유할 정책이라면 .claude/settings.json에 넣고 git에 커밋하면 됩니다. 개인 설정은 settings.local.json, 팀 설정은 settings.json으로 분리하는 것이 권장됩니다.

    3단계 분류 기준: 이렇게 나눠보세요

    어떤 작업을 allow/deny/ask로 분류할지 판단하는 기준은 두 가지 축으로 정리할 수 있습니다:

      되돌릴 수 있음 되돌릴 수 없음
    로컬 영향 ✅ Allow
    파일 읽기, git status, 검색
    ⚠️ Ask
    프로세스 종료, 서비스 재시작
    외부 영향 ⚠️ Ask
    git push, PR 생성, 메시지 전송
    🚫 Deny
    force push, 데이터 삭제, rm -rf

    이 2x2 매트릭스가 판단의 출발점입니다:

    • 로컬 + 되돌릴 수 있음 → Allow. 파일 읽기, 검색, git diff 같은 건 아무리 해도 해가 없습니다.
    • 로컬 + 되돌릴 수 없음 → Ask. 프로세스를 죽이거나 설정을 바꾸는 건 로컬이지만 실수하면 복구가 어렵습니다.
    • 외부 + 되돌릴 수 있음 → Ask. git push는 되돌릴 수 있지만, 다른 사람에게 영향을 줍니다.
    • 외부 + 되돌릴 수 없음 → Deny. force push로 히스토리를 날리면 팀 전체가 피해를 봅니다.

    실제 적용 후 체감 변화

    정리 전후를 비교하면:

      정리 전 정리 후
    허용 규칙 수 62개 (specific) ~50개 (wildcard)
    커버 범위 허용한 정확한 명령만 카테고리 전체
    새 작업 시 Ask 빈도 거의 매번 거의 없음
    위험 작업 보호 없음 (allow만 있었음) Deny 5개로 명시적 차단

    특히 deny 규칙이 없었다는 점이 중요합니다. 이전에는 "허용한 것만 실행" 방식이었는데, 실수로 위험한 명령을 승인할 수도 있었습니다. 이제는 rm -rfgit push --force는 아무리 허용 버튼을 눌러도 실행되지 않습니다.

    자신만의 HITL Policy 만들기

    환경에 따라 정책이 달라져야 합니다. 아래를 참고해보세요:

    개인 개발 서버 (나만 쓰는 환경)

    • Allow를 넉넉하게. 실수해도 나만 피해봄
    • Deny는 정말 위험한 것만 (rm -rf, force push)
    • Ask는 최소화

    팀 프로젝트

    • Allow는 읽기 전용 위주
    • git push, PR 생성 등은 Ask
    • main 브랜치 force push, DB 변경 등은 Deny

    프로덕션 환경

    • Allow는 최소한으로 (조회만)
    • 대부분 Ask
    • Deny 목록을 넉넉하게

    정리하며

    AI 에이전트와 협업할 때 가장 중요한 건 "얼마나 똑똑한가"가 아니라 "얼마나 매끄럽게 협업하는가"입니다. HITL Policy는 그 매끄러움을 만드는 핵심 설정입니다.

    자율주행차에 비유하면, Level 5(완전 자율)를 바로 달성할 순 없지만, Level 2(부분 자동)에서 머무를 필요도 없습니다. Allow/Deny/Ask를 잘 조절해서 나에게 맞는 자율 수준을 찾아가는 것. 그게 AI 에이전트 시대의 진짜 스킬입니다.

    오늘 한 번, 여러분의 AI 도구 권한 설정을 열어보세요. 60줄짜리 허용 목록이 쌓여 있다면, 정리할 타이밍입니다.


    이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.

Designed by Tistory.