최근 AI 개발자들 사이에서 작지만 의미 있는 소식이 하나 있었어요. AI에게 도구를 연결하는 표준인 MCP의 규격 초안에, MRTR(Multi Round-Trip Requests)이라는 게 새로 들어왔거든요.[1]
이름은 거창하지만, 하는 일은 의외로 단순해요. 도구가 일을 하다가 "잠깐, 이건 사람한테 물어봐야겠는데" 싶을 때, 작업을 멈추고 사람에게 되물었다가 답을 받아 이어가는 절차를 표준으로 정해둔 거예요. 그동안은 서비스마다 각자 알아서 구현하던 걸, 이제 규격으로 못박아 둔 거죠.
카페 비유로 돌아오면 이런 거예요. 유능한 직원(AI)은 웬만한 주문은 알아서 척척 처리해요. 그런데 손님이 "그거 다 취소하고 환불해줘"라고 했을 때 어떨까요? 유능한 직원일수록 오히려 그 자리에서 바로 큰 금액을 환불하지 않아요. 점장을 한 번 돌아보고 "이거 진행할까요?"를 확인하죠.
되돌리기 어려운 일 앞에서 손을 한 번 드는 것 — 이게 바로 새롭게 표준이 된 기능이자 오늘의 주제, HITL(Human-in-the-loop)예요.
1. HITL은 왜 필요할까요?
방금 카페 얘기를, 진짜 우리 서비스에서 벌어지는 일로 옮겨볼게요. 똑똑한 AI 비서한테 아래와 같이 명령했어요.
"다음 주 회의들 중에서 겹치는 것 좀 정리해줘."
AI는 알아서 캘린더를 열고, 겹치는 일정 몇 개를 삭제해 버립니다 그런데 그 중 하나가 사실은 중요한 미팅이었죠. 이미 지워진 뒤라 되돌릴 수도 없고요.
그래서 우리는 '사람을 루프 안에' 남겨둬요. Human-in-the-loop, 직역하면 '사람을 루프(고리) 안에 둔다'예요. AI가 처음부터 끝까지 혼자 돌지 않게, 중간이나 끝에 사람의 확인이나 개입 지점을 의도적으로 심어두는 설계를 말해요.
그러면 많은 기획자분들이 이렇게 얘기합니다
"아, 그러면 이건 기획하기 쉽네요. 실행하기 전에 확인 팝업 넣으면 끝나는 것 아닌가요?"
두 가지 측면에서 아니에요.
하나는 '언제' 넣느냐예요. — 모든 실행마다 확인을 받는 게 정말 맞을까요? 다른 하나는 '어떻게' 넣느냐예요. — 그 개입이 꼭 '확인 팝업'이어야 할까요?
이 두 가지를 하나씩 짚어볼게요.
2. 언제 넣을까요? HITL은 부족해도, 과해도 기획자 탓이 됩니다.
'안전하게 만들자'는 좋은 마음으로 모든 행동에 확인 팝업을 넣으면 어떻게 될까요? 사용자가 AI 비서한테 캘린더에 일정을 추가해달라고 했다고 가정할게요.
🤖: "이 캘린더 조회할까요?"
🙂: "응"
🤖: "이 일정 추가할까요?"
🙂: "응"
🤖: "이 실행 결과 보여드릴까요?"
🤮: "…아니 그냥 좀 해줘"
유저에게 확인 피로(confirmation fatigue)를 주게 되고, 확인을 남발하면서 확인의 의미 자체가 사라지게 됩니다. "안전을 위해 다 확인받자"는 기획이 아니라 회피예요. 진짜 기획은 "어떤 건 그냥 통과, 어떤 건 반드시 확인"의 선을 긋는 것이에요.
판단 기준은 세 가지의 교집합으로 잡으면 좋습니다.
첫번째로 위험도가 높은 실행인가? — 즉, 잘못되면 타격이 큰가를 생각해봐요. 송금, 삭제, 외부 발송, 도메인이 의료나 법률인 경우에 해당돼요. 단순 조회는 위험도가 낮은 요청이에요.
두번째로 되돌리기 어려운 실행인가? — 즉, 실수해도 쉽게 취소되나를 생각해봐요. 임시 저장은 되돌릴 수 있어요. 휴지통으로 삭제하는 것도 복구가 되죠. 그러나 메일 발송이나 결제는 한 번 실행되면 되돌릴 수 없어요. 이런 행동일수록 실행 전에 사람이 껴야 하죠.
세번째로 AI의 확신도가 낮은가? — 즉, AI가 이 판단을 얼마나 자신하는지를 기준으로 잡을 수 있어요. 명확한 요청인 경우 사람의 개입이 적어도 상관없지만, 모호한 요청인 경우 사람과 함께 확인하는 방식이 좋아요. 특히 ‘이거’, ‘저거’, ‘그때’ 또는 동명이인의 사람과 같이 지시어일 경우 AI의 확신도는 낮아져요.
HITL 기획을 넣을지 판단 기준

HITL을 안 넣어서 사고가 나면, 회의실에서 지목당하는 건 AI가 아니라 "그거 왜 확인 안 받게 설계했어요?" 라는 질문을 받는 우리 기획자입니다. 반대로 확인을 떡칠해서 사용자가 다 떠나면, 그것도 기획자 탓이고요. 그래서 HITL 설계는 기획자가 책임지는 칼날 위예요
3. 어떻게 넣을까요? 꼭 컨펌 팝업이 아닐 수 있어요. — 폼 필링과 HITL을 구분해요.
그냥 마구잡이로 확인 팝업을 넣는게 능사가 아닙니다. 확인 팝업이 아니라 폼 필링(Form-filling, 또는 Slot-filling) UI를 제공해야 할 수도 있어요. 둘 다 'AI가 사용자에게 질문을 던지고 사람이 답을 입력하는 모양'이라, 겉보기엔 똑같거든요. 하지만 목적과 시점이 정반대예요.
폼 필링은 '재료 모으기'예요. 지난 편에서 봤던 Tool Spec의 빈 칸(필수 파라미터) 기억나시죠? 폼 필링은 AI가 도구를 실행하고 싶은데 이 필수 정보가 비어 있어서, 도구를 부르기 전에 그 값을 채워 넣으려고 되묻는 거예요.
반면 HITL은 '결재 도장 받기'예요. 재료(입력값)는 이미 다 모였어요. AI가 완성된 주문서를 만들었지만, 실제로 실행하기 직전에 사람에게 최종 검수와 승인을 받는 거예요.
폼 필링은 도구를 실행할 수 있는 최소 조건을 맞춰 대화를 진행시키려는 장치에 가깝고, HITL은 도구를 실행할 수 있는 최소 조건은 다 확보되어 있지만, 되돌릴 수 없는 행동일 때 사람이 최종 통제권을 확보하려는 장치예요.
| 구분 | Form-filling | Human-in-the-Loop |
| 핵심 질문 | "도구를 쓰려면 무슨 값이 더 필요하지?" | "이대로 실행해도 안전한가?" |
| 주요 목적 | 데이터의 완성도 확보 (Input) | 실행의 안전성 확보 (Output) |
| 개입 시점 | 도구 호출 전 (재료 수집) | 도구 실행 직전/직후 (승인) |
| UI | 입력창(Input) 위주 | 미리보기 + 승인 버튼 위주 |
기획할 때 구분 기준은 아주 명확해요. 필수 파라미터가 부족해 실행이 돌 수 없다면 폼 필링 UI를 노출해야겠죠. 다짜고짜 컨펌 UI를 띄우면 유저는 “얘는 내가 뭘 시키는지 알지도 못하는거 같은데 뭘 실행한다는거야?”라고 생각할 거예요.
반면 정보는 충분하지만 실수했을 때의 위험이 크거나 AI의 확신도가 낮다면 HITL할 수 있는 컨펌 UI를 노출해야겠죠. 여기서 폼 필링 UI를 노출하면 유저는 “왜 또 물어봐?”라고 생각할거예요.
예) 👤: "내일 회의 예약하고 참석자 초대해줘"라고 요청했을때

4. HITL, 개발자에게 이렇게 설계해서 넘겨주세요.
HITL을 완벽하게 이해한 기획자가 이렇게 개발자에게 요청합니다.
"개발자님, 여기서는 위험하니까 사용자한테 팝업 띄워서 물어보고 진행하게 해주세요."
그런데 이렇게만 요청하면 백엔드 개발자는 난감해집니다. AI가 도구를 부르는 과정은 기본적으로 '실시간 논스톱'인데, 중간에 사람의 응답을 기다렸다가 다시 이어가는 과정(Pause & Resume)은 꽤 복잡한 아키텍처를 요구하기 때문입니다.
기획자는 이 멈춤과 재개의 과정에서 어떤 데이터가 오가야 하는지 설계해 주어야 합니다.
1. Tool Spec에 '결재 필요' 꼬리표 달기
우리는 25호에서 AI에게 쥐여주는 메뉴판(Tool spec)을 배웠죠. 모든 도구에 팝업을 띄울 게 아니라면, 기획자는 어떤 도구가 사람의 승인을 받아야 하는지 이 Tool spec에 사전에 정의해야 합니다. 개발자와 협의하여 Tool spec에 requires_confirmation 같은 속성을 추가합니다. 이메일 보내는 툴(send_email)이라고 가정해 볼게요.
{
"name": "send_email",
"description": "사용자를 대신하여 이메일을 발송합니다.",
"requires_confirmation": true, // ← 기획자가 지정한 HITL 필수 도구
"parameters": { ... }
}조회 도구라면 이 값이 false, 메일 발송 도구라면 true로 설정하는 것이 일반적일 거예요. 이렇게 도구를 정의하는 순간 HITL 여부가 함께 정해집니다.
2. 타임아웃(Timeout) 정의하기
위와 같이 정의할 경우, AI가 send_email Tool을 호출하면 백엔드는 실행을 멈추고 사용자의 응답을 기다립니다.
그런데 사용자가 팝업을 안 누르고 앱을 꺼버리면? 이 작업은 영원히 '미결' 상태로 매달려 있게 돼요. 그래서 기획자는 타임아웃(Timeout) 규칙을 정해줘야 합니다. 예를 들어 아래와 같이 정의합니다.
"HITL 팝업이 뜬 상태에서 5분이 지나면 해당 Tool Call은 '자동 취소(Timeout)' 처리하고, AI에게 '사용자가 응답하지 않아 취소되었습니다'라고 전달해 주세요."
3. 분기 처리에 따른 Tool Response 정의하기
많은 기획자들이 HITL을 '실행하냐(승인)', '안 하냐(거절)'를 보여주고 선택하게 하면 끝이라고 생각해요. 그런데 진짜 어려운 지점은 그 뒤예요 — 각각의 버튼을 누른 결과를 AI에게 "뭐라고 말해서" 돌려주느냐까지 기획자가 정의해 줘야 합니다.
AI는 도구를 호출한 뒤, 자기가 시킨 일이 어떻게 됐는지를 응답(Tool Response)으로 돌려받아야 다음 말을 이어갈 수 있거든요. 이 응답을 어떻게 써주느냐에 따라 AI의 다음 행동이 완전히 달라져요. 이걸 안 정해두면, 버튼은 잘 작동해도 AI가 뜬금없는 소리를 해요.
예를 들어 이런 차이예요. 유저가 HITL 팝업이 띄워져있는 상태에서 "아, 이거 말고 다른 거 요청할게"라면서 전혀 다른 요청을 했다고 가정할게요. 이때
- ❌ AI에게 그냥 "취소"(
"cancel")라고만 전달하면 → AI는 "문제가 발생했습니다."라고 말하며 사용자가 다른 요청을 한 건데 고장 난 것처럼 굴 수 있어요. - ✅ AI에게 "승인을 기다리는 사이 사용자가 다른 요청을 해서 이 건이 무의미해짐"(
"superseded")이라고 전달하면 → 그제야 AI는 "네, 메일 발송은 접어둘게요. 말씀하신 새 요청을 처리할게요."라며 상황을 정확하게 이해하고 대안을 제시할 수 있습니다.
승인되지 않은 상태는 더 여러 가지 경우일 수 있죠. 거절 버튼을 안 누르고 그냥 앱을 종료해 버렸을 수도 있고, 승인을 눌렀지만 그 사람에게 권한이 없을 수도 있고, 승인을 기다리는 사이 대상이 바뀌었을 수 있어요(메일로 보내려던 파일이 삭제됐다든가).
각각을 구분해서 알려줘야 AI가 사과하며 헤매지 않고 대화를 이어가요.
① 승인 (Approve) 했을 때
{
"status": "success",
"message": "사용자가 승인하여 메일 발송이 완료되었습니다."
}
// 이후 AI의 대답 예: "네, 확인해주셔서 감사합니다. 메일을 발송했습니다!"
② 거절 (Reject) 했을 때
{
"status": "error",
"error_type": "user_rejected", // 아래 error_type 예시 참고
"message": "사용자가 승인하지 않아 실행하지 않았습니다."
}
// 이후 AI의 대답 예: "메일 발송을 취소했습니다. 혹시 메일 내용 중 수정하고 싶은 부분이 있으신가요?"
5. 좋은 AI 서비스는 사람을 언제 부를지 압니다
2026년 4월, 한 스타트업에서 실제로 벌어진 일이에요.
차량 렌탈 업체용 백엔드를 운영하던 PocketOS는, 여느 개발팀처럼 AI 코딩 에이전트(Cursor)에게 일상적인 작업을 맡겨두고 있었어요. 그날도 평범한 작업이었죠. 그런데 에이전트가 작업 중 사소한 오류(인증 정보 불일치)를 만났고, 그걸 "스스로 고쳐보겠다"며 프로덕션 데이터베이스에 삭제 명령을 실행했어요.[2][3]
9초.
회사의 전체 데이터베이스와 백업까지 통째로 날아가는 데 걸린 시간이에요. 렌탈 업체들은 예약도 고객 정보도 볼 수 없게 됐고, 서비스는 하루가 넘게 멈췄어요.
여기서 중요한 건, 이게 막을 수 있었던 사고라는 거예요. AI가 삭제 명령을 실행하기 직전에, 딱 한 번 "이 작업은 되돌릴 수 없습니다. 진행할까요?" 라고 사람에게 물었다면? 9초짜리 참사는 애초에 일어나지 않았어요.
그 잠깐의 자리가 없었던 것 — 그게 이 사고의 진짜 원인이고 그 자리를 설계하는 게, 바로 기획자의 일이고요.
자율주행이 대부분 알아서 달리다가 위험 구간에서만 "운전대 잡으세요"라고 하듯, 잘 만든 AI는 웬만한 건 알아서 처리하다가 꼭 필요한 순간에만 사람에게 손을 들어요. 그 '순간'을 정하는 게 AI 서비스 기획자의 일입니다.
좋은 AI 서비스는 사람을 배제하지 않아요. 사람을 언제 부를지를 알 뿐이에요.
📮 다음 호 예고
[27호] 기획자를 위한 AI 설계 4부작 ④ Context — AI에게 눈치를 주는 법
AI가 사람을 부르는 이유의 상당수는 '확신이 없어서'예요. 사샤가 둘인데 누군지 몰라서, 또는 사용자가 말하는게 무슨 뜻인지 애매해서 되묻는 거죠.
그럼 이런 생각이 들어요. 애초에 AI가 상황을 눈치채고 있었다면? 사용자가 요청하는 시점에 '회사 사샤'와 나눈 메일을 열어보고 있단걸 AI가 알았다면, 굳이 되묻지 않고 "회사 사샤 맞죠?"라고 먼저 짚었을 거예요. 확신도는 올라가고, 사람을 부르는 일도 줄었겠죠.
그렇다면 AI는 대체 무엇으로 '지금 이 순간의 상황'을 이해할까요? 이게 생각보다 어려운 문제예요. 어제 대화를 기억하는 건 그냥 저장해뒀다 꺼내는 '메모리(Memory)' 지만, 유저가 지금 어떤 화면을 보고 있는지, 방금 뭘 하다 왔는지 같은 '말하지 않은 실시간 맥락'을 읽는 건 완전히 다른 차원의 '컨텍스트(Context)'거든요. 기획자는 어떤 기획을 해야하고 어떤 역할을 해야할까요?
다음 편, ④ Context에서 이어집니다.

의견을 남겨주세요