목차
- 에이전트 관련 사고는 실제로 얼마나 흔할까요?
- 에이전트가 사람을 필요로 할 때 실제로 무슨 일이 벌어질까요?
- 어떤 에이전트 이벤트가 전화를 받을 자격이 있을까요?
- 에이전트 승인 게이트를 전화로 연결하는 방법
- 1단계 — 막힌 에이전트를 위한 전화 채널 만들기
- 2단계 — 승인 분기에서 Webhook 발사하기
- 3단계 — 에이전트가 라이브러리가 아니라 CLI일 때는 훅 사용하기
- 4단계 — 이메일로만 알리는 에이전트 붙잡기
- 5단계 — 진짜 차단만 울리도록 조건 추가하기
- 6단계 — 방해 금지를 켠 채로 테스트하기
- 이렇게 하면 더 시끄러운 종으로 알림 피로를 되풀이하는 것 아닌가요?
- Echobell이 하지 않는 일
- FAQ
- 전화를 받은 상태에서 바로 에이전트 작업을 승인할 수 있나요?
- 어떤 프레임워크 이벤트가 Webhook을 트리거해야 하나요?
- CI에서 돌아가는 헤드리스 에이전트에서도 동작하나요?
- MCP elicitation은 구체적으로 어떤가요?
- 알림에 에이전트 출력을 담아도 안전한가요?
- 팀 전체가 같은 에이전트 알림을 받을 수 있나요?
- iOS 전용인가요?
- WebhookMCP 방식과는 무엇이 다른가요?
- 관련 글
2026년에 출시된 자율 에이전트 프레임워크에는 모두 같은 구멍이 있습니다. 에이전트는 사람 없이 몇 시간씩 실행되다가 혼자서는 수행할 수 없는 작업을 만나 멈춰 섭니다. 그리고 그다음에는 아무 일도 일어나지 않습니다. 실행이 실패하지도, 재시도되지도 않습니다. 직렬화된 상태 객체를 쥔 채 메모리에 앉아, 자기를 기다리는 존재가 있다는 사실을 전혀 모르는 사람을 기다릴 뿐입니다. 이 가이드에서는 에이전트의 “사람이 필요하다”는 순간을 Echobell로 울리는 전화로 바꿔 이 공백을 메우는 방법을 설명합니다.
이 공백은 특정 제품의 버그가 아니라 구조적인 문제입니다. OpenAI의 에이전트 문서는 승인 흐름을 정확하게 설명합니다. 도구에 승인이 필요하면 “승인하거나 거부할 때까지 실행이 일시 중지”되고, 결과로 interruptions와 재개 가능한 state가 반환되며, 검토에 시간이 걸릴 수 있다면 그 상태를 직렬화해 저장했다가 나중에 재개하라고 안내합니다(OpenAI, Agents SDK 가이드). 이 흐름 어디에도 사람에게 가닿는 부분은 없습니다. 승인자에게 알리는 일은 전적으로 여러분의 몫입니다.
그사이 실행 시간은 점점 길어지고 있습니다. AWS는 자사의 프런티어 에이전트가 “개입 없이 몇 시간 또는 며칠 동안 작동”할 수 있다고 설명합니다(About Amazon). 2026년 8월 4일에 출시된 Kiro Crew는 이를 더 분명하게 말합니다. “마이그레이션을 시작해 두면 회의 중이거나 잠든 사이에도 체크포인트와 재시도를 거치며 계속 진행됩니다.” 그러면서 동시에 “도구 요청에는 승인이 필요할 수 있다”고 덧붙입니다(Kiro). 두 문장은 동시에 참입니다. 에이전트는 여러분이 잠든 사이에 일하고, 에이전트는 여러분이 잠든 사이에 멈춥니다.
에이전트 관련 사고는 실제로 얼마나 흔할까요?
대부분의 기업이 한 번은 겪었을 만큼 흔하며, 대부분은 에이전트를 감독 없이 돌리지 않습니다. Cloud Security Alliance가 Token Security의 의뢰로 2026년 1월에 IT·보안 전문가 418명을 대상으로 실시한 설문에서, 조직의 65%가 지난 1년 동안 AI 에이전트와 관련된 사고를 최소 한 건 겪었다고 답했습니다. 그중 61%는 데이터 노출, 43%는 운영 중단, 35%는 금전적 손실을 동반했습니다(CSA 보도자료, 보고서).
알림 설계에서 정말 중요한 것은 같은 설문의 거버넌스 수치입니다. 완전 자율 에이전트를 운영하는 곳은 13%뿐입니다. 53%는 위험이 낮은 작업에서만 에이전트가 자율적으로 행동하게 하고 위험이 큰 작업은 사람이 검토하며, 24%는 대부분의 작업에 사람을 개입시킵니다. 82%는 지난 1년 동안 자사 환경에서 섀도 AI 에이전트를 발견했습니다.
이 숫자는 겁주기 위한 통계가 아니라 운영상의 사실로 읽어야 합니다. 조직의 약 4분의 3이 에이전트에 멈춤 지점을 의도적으로 심어 두었습니다. 그 멈춤 하나하나가 기계가 사람 때문에 막혀 있는 순간입니다. 그 사람이 다음 날 아침 9시에야 알아차린다면, 밤새 일할 수 있다는 에이전트의 능력은 아무 가치도 없었던 셈입니다.
에이전트가 사람을 필요로 할 때 실제로 무슨 일이 벌어질까요?
조용히 기다리며, 알리는 일은 모든 프레임워크가 여러분에게 넘깁니다. 방식은 저마다 다르지만 결과는 같습니다.
| 스택 | 동작 방식 | 사람에게 전달되는 것 |
|---|---|---|
| OpenAI Agents SDK | 도구의 needsApproval이 실행을 일시 중지하고 interruptions와 재개 가능한 state를 반환합니다 | 없음 — 인터럽션을 어떻게 처리할지는 여러분의 애플리케이션이 결정합니다 |
| MCP 서버 | elicitation/create가 도구 호출 도중 사용자에게 입력을 요청하고 accept, decline, cancel 중 하나를 반환합니다 | MCP 클라이언트가 그려 주는 UI — 무인 실행에서는 아무도 그것을 보지 않습니다 |
| Claude Code | agent_needs_input, agent_completed 등의 매처 값과 함께 Notification 훅이 실행됩니다 | 그 훅을 연결해 둔 대상이 무엇이든 그것 |
| Kiro Crew | 도구 요청에 승인이 필요할 수 있고, 활동은 검토용으로 기록됩니다 | Activity 화면 — 열어 본다면 |
Model Context Protocol은 이 점을 명세 수준에서 못 박아 둡니다. Elicitation은 서버가 실행 도중 사람에게 무언가를 물을 수 있도록 존재하며, 현재 리비전(2026-07-28)은 서버가 “elicitation 요청이 항상 성공한다고 가정해서는 안 되며” 거부, 취소, 클라이언트 실패를 처리해야 한다고 경고합니다(MCP 명세). 프로토콜은 질문을 표준화합니다. 하지만 사람의 주의를 끄는 일은 표준화하지 않으며, 표준화할 수도 없습니다.
바로 여기에 기회가 있습니다. 에이전트 스택의 모든 계층에는 잘 설계된 멈춤 지점이 있습니다. 그러나 그중 어느 것에도 전화번호는 없습니다.
어떤 에이전트 이벤트가 전화를 받을 자격이 있을까요?
두 가지뿐이며, 나머지에 대해서는 냉정해야 합니다. 전화는 희소한 자원입니다. 잠든 사람이 정말로 병목인 곳에만 쓰세요.
- 승인 없이는 진행할 수 없는 실행에서 승인이 막힌 경우. 에이전트는 멈춰 있고 시간은 흐르며, 아무리 기다려도 해결되지 않습니다. 가장 전형적인 사례입니다.
- 장시간 무인 실행이 최종적으로 실패한 경우. 두 시간째에 죽어 버린 여섯 시간짜리 마이그레이션은 되돌릴 수 없는 여섯 시간이며, 여러분은 두 시간째에 그 사실을 알고 싶을 것입니다.
그 밖의 모든 것은 더 조용한 채널에 두어야 합니다. “작업이 성공적으로 완료되었습니다”는 일반 푸시입니다. “에이전트가 예산의 80%를 사용했습니다”는 기껏해야 긴급 알림입니다. “에이전트가 시작되었습니다”는 알림이라고 할 수도 없습니다. Echobell의 세 가지 알림 유형, 즉 일반·긴급·전화는 정확히 이 분류를 위해 존재하며, 에이전트 이벤트를 여기에 어떻게 대응시킬지가 이 글에서 가장 중요한 설계 결정입니다. 이미 알림 양과 씨름하고 있다면, 울리는 채널을 추가하기 전에 알림 피로 해결하기를 먼저 읽어 보세요.
에이전트 승인 게이트를 전화로 연결하는 방법
Echobell은 Webhook이나 이메일을 전화로 바꿉니다. 가족에게서 걸려 온 전화처럼 iOS 집중 모드와 방해 금지를 뚫고 실제로 울리고 진동하는 전화입니다(iOS 집중 모드 우회하기 참고). Echobell은 멈춰 선 에이전트와 그 에이전트를 다시 움직일 수 있는 사람 사이에 자리합니다.
1단계 — 막힌 에이전트를 위한 전화 채널 만들기
앱에서 채널을 만들고 알림 유형을 전화로 설정하세요. “에이전트 차단 — 승인 필요”처럼 오해의 여지가 없는 이름을 붙이고, 다른 용도로는 절대 쓰지 마세요. 채널 상세 화면에서 Webhook URL을 복사합니다. https://hook.echobell.one/t/<channel-token> 형태입니다. 이 URL은 비밀로 다루세요. 이것을 가진 사람은 누구나 여러분의 휴대폰을 울릴 수 있습니다(Webhook 가이드).
잠금 화면에서 바로 행동에 옮길 수 있도록 제목과 본문 템플릿을 설정하세요.
Title: 에이전트 차단: {{agent}}
Body: {{project}}의 {{action}} 대기 중 — {{time}} UTC부터
{{time}}을 비롯한 시스템 시간 변수는 따로 보내지 않아도 항상 UTC로 사용할 수 있습니다.
2단계 — 승인 분기에서 Webhook 발사하기
인터럽션을 반환하는 SDK라면 어느 것에서든 이 멈춤은 코드상의 평범한 분기 하나입니다. 실행을 보류하기 전에 채널 URL로 요청을 보내세요.
let result = await run(agent, input, { stream: false });
if (result.interruptions?.length) {
await fetch(process.env.ECHOBELL_BLOCKED_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
agent: agent.name,
action: result.interruptions[0].rawItem.name,
project: process.env.PROJECT_NAME,
externalLink: `https://ops.example.com/runs/${runId}`,
}),
});
await saveState(runId, result.state); // 직렬화한 뒤 승인이 끝나면 재개
}
특수 변수 externalLink는 알림 기록에서 클릭 가능한 링크가 됩니다. 덕분에 전화를 받은 사람은 실행을 찾아 헤매지 않고 곧바로 해당 실행으로 이동할 수 있습니다.
3단계 — 에이전트가 라이브러리가 아니라 CLI일 때는 훅 사용하기
Claude Code는 Notification 훅을 제공하며, 이 훅의 매처는 agent_needs_input과 agent_completed를 포함한 알림 유형으로 필터링합니다. 훅 핸들러로는 셸 명령이나 직접적인 HTTP 요청을 쓸 수 있습니다(훅 레퍼런스). command 핸들러를 쓰면 페이로드의 형태를 직접 정할 수 있는데, Echobell은 여러분이 보낸 JSON 키를 그대로 렌더링하므로 이 점이 중요합니다.
{
"hooks": {
"Notification": [
{
"matcher": "agent_needs_input",
"hooks": [
{
"type": "command",
"command": "jq -c '{agent: \"claude-code\", action: .message, project: .cwd}' | curl -sS -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_BLOCKED_URL\""
}
]
}
]
}
}
command 핸들러에서는 훅 입력이 stdin으로 JSON 형태로 들어오며, session_id, cwd, hook_event_name, permission_mode 같은 필드를 담고 있습니다. http 핸들러 유형은 스크립트 없이 같은 JSON을 URL로 그대로 보내 주므로 솔깃하지만, 응답이 훅 출력 문서일 것을 기대합니다. Echobell의 응답은 그런 문서가 아닙니다. 자신의 환경에서 http가 원하는 대로 동작하는지 직접 확인한 것이 아니라면 command를 쓰세요.
4단계 — 이메일로만 알리는 에이전트 붙잡기
적지 않은 에이전트 플랫폼과 예약 실행 서비스, 사내 도구가 오직 이메일로만 상황을 보고합니다. Echobell 채널은 저마다 전용 주소를 가질 수 있으므로, 전달 규칙 하나면 그 메일이 전화로 바뀝니다(이메일 트리거, 이메일을 전화로 설정하기). 이메일 트리거는 from, to, subject, text, html을 템플릿 변수로 제공하므로, 직접 파싱하지 않고도 제목 줄을 기준으로 조건을 만들 수 있습니다.
5단계 — 진짜 차단만 울리도록 조건 추가하기
모든 에이전트 이벤트마다 울리는 채널은 더 이상 전화가 아니라 배경 소음입니다. Echobell의 조건은 템플릿과 동일한 표현식 문법으로 변수 값을 걸러 내므로, 예를 들어 다음과 같이 요구할 수 있습니다.
blocking == true && risk == "high"
그 기준에 못 미치는 것은 모두 별도의 긴급 채널로 보내세요. 쓸모 있는 목표치를 하나 들면, 전화 채널은 많아야 일주일에 서너 번 울려야 합니다. 그보다 자주 울린다면 에이전트의 자율성 경계가 잘못 그어진 것이고, 어떤 알림 설정으로도 그 문제는 해결되지 않습니다.
6단계 — 방해 금지를 켠 채로 테스트하기
실제로 알림을 받게 될 휴대폰에서 방해 금지를 켜 둔 상태로 curl을 사용해 채널을 트리거해 보세요.
curl -X POST https://hook.echobell.one/t/<channel-token> \
-H "Content-Type: application/json" \
-d '{"agent":"test","action":"deploy to prod","project":"demo","blocking":true,"risk":"high"}'
앱에서 실패한 전화 재시도를 켜 두면 집중 모드에 막힌 전화가 다시 시도됩니다. 테스트해 보지 않은 에스컬레이션 경로는 그저 가정일 뿐입니다.
이렇게 하면 더 시끄러운 종으로 알림 피로를 되풀이하는 것 아닌가요?
5단계를 건너뛴다면 그렇습니다. 이 실패 양상은 실제로 존재하며 짚고 넘어갈 가치가 있습니다. 에이전트는 서버보다 훨씬 많은 이벤트를 만들어 냅니다. 모든 도구 호출, 모든 체크포인트, 모든 재시도가 이벤트입니다. 그리고 그 전부를 눈에 띄는 어딘가로 흘려보내고 싶은 유혹은 강합니다.
실제로 통하는 원칙은 이렇습니다. 전화는 사람이 잠들어 있다는 사실만이 에이전트와 진전 사이를 가로막는 유일한 장애물인 이벤트에만 허용합니다. 이는 “에이전트가 한 중요한 일”보다 훨씬 작은 집합입니다. 전화를 받은 사람이 그 뒤 90초 동안 무엇을 할지 한 문장으로 설명할 수 없다면, 그 이벤트는 전화를 받을 자격이 없습니다.
기준을 높게 유지해야 할 보안상의 이유도 있습니다. 같은 CSA 설문에서 조직들은 행동의 위험도(63%)와 사람의 승인(53%)을 주된 거버넌스 신호로 꼽았습니다. 이 신호는 사람의 승인이 실제로 신속하게 이루어질 때에만 의미가 있습니다. 늘 여덟 시간씩 늦게 응답되는 승인 게이트는 모두에게 게이트를 더 넓히라고 가르칩니다. 완전 자율 13%가 잘못된 이유로 조용히 기본값이 되는 경로가 바로 이것입니다.
Echobell이 하지 않는 일
에이전트 인프라는 과장된 주장을 끌어들이기 마련이므로, 여기서는 정확해야 합니다.
Echobell이 하는 일: Webhook이나 이메일을 울리는 전화, 긴급 알림, 일반 푸시로 바꾸는 것. 조건으로 걸러 내는 것. 템플릿으로 맥락을 표현하는 것. 같은 트리거를 공유 팀 채널로 전달해 구독자마다 자신에게 맞는 긴급도를 고르게 하는 것.
Echobell이 하지 않는 일:
- 승인 처리. Echobell은 승인 UI가 아니며 에이전트의 상태와는 아무 연결도 없습니다. 휴대폰을 울릴 뿐이고, 승인하거나 거부하려면 여전히 노트북이나 대시보드, 터미널을 열어야 합니다. “승인하려면 1번을 누르세요” 같은 기능은 없습니다.
- 실행 재개. 에이전트 상태를 직렬화하고 복원하는 일은 여러분이 쓰는 프레임워크의 몫입니다. Echobell은 그 상태를 전혀 건드리지 않습니다.
- 에스컬레이션 정책, 확인 응답, 온콜 로테이션 제공. “5분 안에 아무도 받지 않으면 다음 사람에게 전화”하는 기능은 없습니다. 채널 구독자에게 전화를 걸 뿐입니다. 예약된 교대 근무와 확인 응답 추적이 필요하다면 인시던트 관리 플랫폼이 필요합니다. 그런 종류의 도구는 Opsgenie 대안 비교를 참고하세요.
- 에이전트 보안. 여기 있는 어떤 내용도 섀도 에이전트나 지나치게 넓은 도구 권한, CSA 보고서가 지적한 폐기 절차의 공백을 해결해 주지 않습니다. 사람이 더 빨리 알아차리게 만드는 것은 느린 대응에 대한 완화책이지, 잘못된 아키텍처에 대한 해법이 아닙니다.
- 전달 보장. 전화는 푸시 인프라와 네트워크, 충전된 휴대폰에 달려 있습니다. 기다리는 시간을 줄여 주는 계층으로 여기되, 절대적으로 의존할 수 있는 통제 수단으로 보지는 마세요.
솔직하게 말하면, 어떤 앱이 휴대폰을 울리든 에이전트의 자율성 경계는 달라지지 않습니다. 전화가 바꾸는 것은 에이전트가 멈춘 시점과 사람이 그것을 알아차리는 시점 사이의 시간입니다. 그리고 밤새 돌리는 실행에서는 바로 그 시간이 밤새 돌리는 일의 가치 전부입니다.
FAQ
전화를 받은 상태에서 바로 에이전트 작업을 승인할 수 있나요?
아니요. Echobell은 알림 내용과 클릭 가능한 링크를 담은 전화를 전달할 뿐, 에이전트로 되돌아가는 대화형 응답 경로는 없습니다. 현실적인 방식은 이렇습니다. 전화가 여러분을 깨우고, externalLink가 실행 대시보드나 승인 엔드포인트로 데려다주며, 결정은 그곳에서 내립니다. 응답만으로 승인하는 기능이 필요하다면 그 엔드포인트는 직접 만들어야 합니다. Echobell은 깨우는 절반만 담당합니다.
어떤 프레임워크 이벤트가 Webhook을 트리거해야 하나요?
실행이 더 이상 진행될 수 없는 이벤트입니다. OpenAI Agents SDK에서는 비어 있지 않은 interruptions 배열입니다. MCP에서는 클라이언트가 사람 없이 답할 수 없는 elicitation/create 요청입니다. Claude Code에서는 agent_needs_input 매처를 붙인 Notification 훅입니다. 완료 이벤트는 전화 채널이 아니라 일반 채널이나 긴급 채널에 두어야 합니다.
CI에서 돌아가는 헤드리스 에이전트에서도 동작하나요?
네, 그리고 아무도 터미널을 지켜보지 않기 때문에 그곳에서 가장 큰 값어치를 합니다. curl을 실행할 수 있는 CI 단계라면 어디서든 채널을 트리거할 수 있습니다. 모든 잡이 아니라 긴 잡의 실패 분기에서만 보내세요. 그러지 않으면 파이프라인이 여러분이 가진 것 중 가장 시끄러운 존재가 됩니다.
MCP elicitation은 구체적으로 어떤가요?
Elicitation은 사용자가 곁에 있는 클라이언트가 프롬프트를 그려 주는 상황을 전제로 설계되었습니다. 무인 실행에서는 그것을 보여 줄 사람이 없고, 명세는 서버에게 응답이 온다고 가정하지 말고 거부와 취소를 처리하라고 명시적으로 지시합니다. 합리적인 방식은 MCP 클라이언트 래퍼가 자율적으로 답할 수 없는 elicitation 요청을 받았을 때 Echobell Webhook을 발사하고, 그다음에는 여러분의 정책에 따라 실행을 보류하거나 취소하는 것입니다.
알림에 에이전트 출력을 담아도 안전한가요?
가능한 한 적게 보내세요. 에이전트의 실제 출력보다 식별자와 링크를 우선하세요. externalLink로, 그런 내용을 담도록 만들어진 시스템의 실행 기록을 가리키면 됩니다. Echobell은 알림 내용과 기록을 여러분의 기기에만 저장하고 서버에는 계정과 채널, 구독 정보만 둡니다(프라이버시 모델). 데이터 최소화에는 유리하지만, 필요 이상으로 많이 보내도 된다는 뜻은 아닙니다.
팀 전체가 같은 에이전트 알림을 받을 수 있나요?
네. 채널을 공유하면 모든 구독자가 트리거를 받고, 각자 자신의 알림 유형을 고릅니다. 흔한 구성은 이렇습니다. 에이전트를 담당하는 엔지니어는 전화로 구독하고, 나머지 팀원은 긴급으로 구독합니다.
iOS 전용인가요?
아니요. Echobell은 iOS에서, 그리고 Google Play를 통해 Android에서도 쓸 수 있습니다(Android 출시 소식 참고). 전화형 알림의 동작은 플랫폼마다 다르므로, 온콜 담당자가 실제로 들고 다니는 기기에서 테스트하세요.
WebhookMCP 방식과는 무엇이 다른가요?
WebhookMCP는 작업이 끝났을 때 모델이 스스로 호출할 수 있는 도구를 제공합니다. 유용하지만, 에이전트가 알리기로 판단해야만 동작합니다. 이 글에서 소개한 방식은 여러분의 코드나 프레임워크 훅에서 직접 발사되므로, 에이전트가 막혔든 혼란에 빠졌든 죽어 버렸든 상관없이 동작합니다. 둘 다 쓰세요. 하나는 “완료”를 위해, 다른 하나는 “차단”을 위해.