
요즘 AI 앱을 열면 대부분 비슷한 화면이 나옵니다.
입력창이 있고, 메시지를 보내면 AI가 답합니다.
User
↓
Prompt
↓
AI
↓
Response
ChatGPT 이후 너무 익숙해진 구조입니다.
짧은 질문을 하고 바로 답을 받는다면 이 방식이 잘 맞습니다.
문제는 Agent가 실제 일을 하기 시작하면서 생깁니다.
예를 들어 이런 요청입니다.
오늘 중요한 메일을 확인하고
관련 Slack 메시지도 찾아서
해야 할 일을 정리한 다음
필요한 후속 메일까지 작성해줘.
Agent가 해야 할 일이 많습니다.
Email 확인
↓
Slack 확인
↓
Task 확인
↓
자료 분석
↓
결과 정리
↓
후속 작업 생성
몇 초가 아니라 몇 분이 걸릴 수도 있습니다.
중간에 이런 상황도 생깁니다.
Agent
"이 메일을 실제로 보내도 될까요?"
사용자의 승인이 필요합니다.
그동안 사람은 뭘 해야 할까요?
채팅창을 계속 보고 있어야 할까요?
AWS가 9월 10일 공개한 오픈소스 프로젝트 Pizza Bot은 바로 여기에서 시작합니다.
핵심 아이디어는 단순합니다.
Agent가 오래 일한다면 사용자가 채팅창에서 기다릴 이유가 없다.
그래서 Pizza Bot은 Agent UI를 Chat이 아니라 Email Inbox처럼 만들었습니다.
현재 대부분의 AI Agent UI는 기본적으로 synchronous interaction을 가정합니다.
User
↓
Request
↓
Wait
↓
Agent
↓
Response
개발 도구에서도 크게 다르지 않습니다.
Terminal에서 Agent를 실행하면 로그가 계속 올라옵니다.
Reading files...
Searching repository...
Running tests...
Fixing error...
Running tests again...
처음에는 재미있습니다.
AI가 실제로 일하는 모습이 보이기 때문입니다.
하지만 작업 시간이 길어질수록 문제가 생깁니다.
3초
10초
30초
2분
10분
30분
Agent가 정말 일을 대신해주는 것인지,
사람이 Agent가 일하는 모습을 지켜보는 것인지 애매해집니다.
AWS는 Pizza Bot 발표에서 이 상황을 상당히 직설적으로 표현했습니다.
이건 collaboration보다 babysitting에 가깝다는 것입니다.
Agent에게 일을 맡겼는데 계속 화면을 보고 있어야 한다면 자동화의 의미가 줄어듭니다.
Pizza Bot의 아이디어가 재미있는 이유는 새로운 UI를 발명하지 않았기 때문입니다.
이미 수십 년 동안 사용해온 Email의 작업 방식을 가져왔습니다.
메일을 보낼 때 이런 행동을 하지는 않습니다.
Send
↓
Outbox 열기
↓
계속 새로고침
↓
답장 기다리기
메일을 보낸 다음 다른 일을 합니다.
답장이 오면 알림을 받고 다시 확인합니다.
Pizza Bot은 Agent도 그렇게 사용해야 한다고 봅니다.
Task 전달
↓
Agent 작업 시작
↓
사용자는 다른 일
↓
완료 또는 승인 필요
↓
Inbox에 도착
즉 핵심 변화는 이것입니다.
Chat
Stay here
에서
Inbox
Come back later
로 바뀝니다.
일반적인 AI Chat에서는 Session이 중요합니다.
Chat Session
Message
Message
Message
Message
브라우저를 닫거나 Session이 끝나면 작업도 사실상 끝난다고 생각하기 쉽습니다.
Pizza Bot에서는 Thread 자체가 지속되는 작업 공간입니다.
Thread 안에는 단순 대화 내용만 있는 것이 아닙니다.
Thread
├─ Messages
├─ Agent State
├─ Tool Activity
├─ Checkpoints
├─ Attachments
└─ Approval State
가 함께 저장됩니다.
Agent가 중간까지 작업하다가 사람의 승인을 기다리는 상황도 Thread 상태에 포함됩니다.
Running
↓
Need Approval
↓
Paused
↓
User Approves
↓
Resume
↓
Completed
이 상태가 메모리에만 존재하지 않습니다.
Disk에 checkpoint가 저장됩니다.
그래서 한 시간 뒤 다시 돌아와도 작업을 이어갈 수 있습니다.
Pizza Bot의 UI는 Email Client와 비슷합니다.
중심에는 세 가지 Queue가 있습니다.
All
전체 Thread
Unread
완료됐지만
아직 확인하지 않은 작업
Action
사람의 결정이나
승인을 기다리는 작업
여기서 가장 흥미로운 것은 Action입니다.
보통 Agent UI에서는 승인을 요청하면 현재 대화 중간에 이런 메시지가 나옵니다.
Agent:
메일을 보내려고 합니다.
Approve?
문제는 사람이 그 순간 자리에 없을 수도 있다는 것입니다.
Pizza Bot에서는 Agent가 멈춘 뒤 Action Queue로 들어갑니다.
Agent
↓
Tool 실행 필요
↓
Approval Required
↓
Action Queue
사용자는 나중에 Action Queue를 열어서 판단합니다.
Approve
Edit
Reject
그리고 Agent는 그 지점부터 다시 작업을 이어갑니다.
기존 Software에서는 작업이 멈추면 보통 문제라고 생각합니다.
Running
↓
Success
or
Running
↓
Failure
하지만 Agent 시스템에서는 상태가 하나 더 필요합니다.
Running
↓
Waiting for Human
↓
Running
↓
Completed
이게 중요합니다.
AI Agent에게 모든 권한을 주면 위험하고,
모든 작업마다 승인을 요구하면 자동화가 의미 없습니다.
그래서 Agent Workflow에서는 Human-in-the-loop가 어디에 들어갈지가 중요합니다.
예를 들어 이런 식입니다.
메일 읽기
↓
자동 허용
문서 요약
↓
자동 허용
CRM 정보 조회
↓
자동 허용
CRM 수정
↓
승인 필요
외부 메일 발송
↓
승인 필요
Pizza Bot의 Skill에서는 Tool별로 이런 Approval Policy를 지정할 수 있습니다.
Agent UX가 단순 Chat UX보다 Workflow Engine에 가까워지는 이유입니다.
Approval UX에서 눈여겨볼 부분이 하나 더 있습니다.
보통 Agent 승인 UI는 이렇습니다.
Approve
Reject
하지만 실제 업무에서는 둘 사이가 필요합니다.
예를 들어 Agent가 이런 메일을 보내려고 합니다.
To: client@example.com
Meeting confirmed for 3 PM.
시간만 4시로 바꾸고 싶다고 해보겠습니다.
기존 방식이라면
Reject
↓
Agent에게 다시 설명
↓
새 결과 생성
↓
다시 승인
해야 합니다.
Pizza Bot은 edit 결정을 지원합니다.
Approve
Edit
Reject
즉 Agent가 제안한 Action 자체를 사람이 수정해서 실행할 수 있습니다.
Long-running Agent에서 꽤 중요한 UX입니다.
사람은 Agent의 결과를 처음부터 다시 만들 필요 없이 마지막 판단만 수정하면 됩니다.
Pizza Bot은 Client와 Agent Runtime을 분리합니다.
구조는 대략 이렇습니다.
Electron App ─┐
Browser ──┤
Mobile Web ──┼── HTTP ── Pizza Bot Server
Terminal ──┘
│
↓
Agent Runtime
│
┌───────────┼───────────┐
↓ ↓ ↓
SQLite Files MCP
Server가 Agent의 상태를 가지고 있습니다.
따라서 Browser를 닫거나 다른 Device로 이동해도 Server가 살아 있다면 Agent 작업은 계속됩니다.
Laptop
Task 시작
↓
Laptop 닫음
↓
Agent 계속 작업
↓
Phone
결과 확인
이런 구조가 가능합니다.
Agent가 UI 안에서 실행되는 것이 아니라 독립적인 Background Worker처럼 실행되는 것입니다.
이 부분은 모바일 앱 개발자에게 특히 흥미롭습니다.
모바일에서는 사용자가 하나의 화면을 몇 분씩 보고 있는 경우가 많지 않습니다.
예를 들어 AI 여행 앱에서 이런 작업을 요청했다고 해보겠습니다.
서울에서 오사카로
다음 주말 여행할 건데
항공편 찾아보고
호텔 비교하고
동선까지 정리해줘.
현재 Chat 방식이라면
Prompt
↓
Loading
↓
Agent working...
↓
Agent working...
↓
Result
입니다.
하지만 모바일에 더 자연스러운 구조는 이럴 수 있습니다.
Task 생성
↓
앱 닫기
↓
Agent Background Processing
↓
Push Notification
"여행 계획이 준비됐습니다."
↓
결과 확인
중간에 승인이 필요하다면
Push Notification
"호텔 예약 전에 확인이 필요합니다."
이 옵니다.
그리고 앱을 열면
Action Required
화면으로 바로 이동합니다.
Pizza Bot의 Inbox 구조와 거의 같습니다.
지금 AI App 디자인을 보면 대부분 ChatGPT를 참고합니다.
Sidebar
Conversation
Input Field
Send Button
하지만 Agent가 실제 업무를 수행하기 시작하면 더 자연스러운 UI는 이런 형태일 수 있습니다.
Tasks
────────────────────
● 코드 리뷰 완료
3분 전
● 여행 계획 완료
12분 전
! 계약서 전송 승인 필요
Action Required
○ 경쟁사 조사 중
Running
○ 매일 오전 뉴스 요약
Scheduled
Chat이라기보다
Inbox
+
Task Manager
+
Notification Center
에 가깝습니다.
여기에 Agent 상태가 붙습니다.
Queued
Running
Waiting
Completed
Failed
실제로 Agent 앱을 만든다면 Message보다 Task가 Domain Model의 중심이 될 수 있습니다.
Chat 기반 AI 앱의 상태는 비교적 단순합니다.
enum ChatState {
case idle
case generating
case completed
case failed
}
하지만 Long-running Agent를 앱에 넣는다면 상태가 훨씬 많아집니다.
개념적으로는 이런 모델이 필요할 수 있습니다.
enum AgentTaskState {
case queued
case running
case waitingForApproval
case completed
case failed
}
그리고 Task 자체가 지속돼야 합니다.
struct AgentTask: Identifiable {
let id: UUID
let title: String
let state: AgentTaskState
let createdAt: Date
}
UI도 상태별로 달라집니다.
.running
Progress UI
.waitingForApproval
Approve / Edit / Reject
.completed
Result
이렇게 보면 Agent App은 Chat UI보다 State Machine UI에 더 가깝습니다.
Long-running Agent에서 중요한 것은 모델 성능만이 아닙니다.
Agent가 30분 동안 작업한다고 생각해보겠습니다.
Step 1 완료
Step 2 완료
Step 3 완료
Step 4 실행 중
여기서 Process가 죽으면 어떻게 될까요?
처음부터 다시 실행한다면 실용성이 떨어집니다.
그래서 Agent Runtime에는 Checkpoint가 필요합니다.
Pizza Bot도 이 부분을 중요하게 다룹니다.
내부적으로 DeepAgents와 LangGraph 기반의 stateful agent runtime을 사용하며 작업 과정이 계속 checkpoint됩니다.
Task
Step 1
↓
Checkpoint
Step 2
↓
Checkpoint
Approval
↓
Checkpoint
Step 3
Agent가 멈춰도 이전 상태부터 이어갈 수 있습니다.
이제 Agent Backend를 설계할 때 Database에 저장해야 하는 것이 단순 Chat History만은 아닙니다.
Conversation
+
Task State
+
Tool Calls
+
Checkpoint
+
Approval
+
Artifact
까지 포함됩니다.
Pizza Bot은 Task를 직접 만드는 것뿐 아니라 Schedule이나 Webhook으로 시작할 수 있습니다.
예를 들어
매일 08:00
메일 확인
↓
Slack 확인
↓
오늘 중요한 일 정리
를 실행할 수 있습니다.
사용자가 Prompt를 보내지 않았습니다.
그래도 Agent는 작업합니다.
Cron
↓
Agent
↓
Result
↓
Inbox
Webhook도 비슷합니다.
GitHub PR 생성
↓
Webhook
↓
Agent Code Review
↓
Inbox
이쯤 되면 Chat이라는 UI가 더 이상 중심이 아닙니다.
Agent를 시작하는 Trigger가
User Prompt
Schedule
Webhook
Event
로 늘어나기 때문입니다.
결과를 보여주는 곳도 자연스럽게 Inbox가 됩니다.
Background Agent가 일반화되면 Notification의 의미도 바뀝니다.
지금 Notification은 주로
새 메시지
새 댓글
배송 상태
를 알려줍니다.
Agent App에서는
작업 완료
뿐 아니라
사람의 판단 필요
도 알려줘야 합니다.
예를 들면 이런 Push가 가능합니다.
AI Assistant
경쟁사 분석이 완료됐습니다.
또는
AI Assistant
고객에게 메일을 보내기 전에
승인이 필요합니다.
Notification을 누르면 해당 Task의 정확한 상태로 Deep Link됩니다.
Push
↓
Task ID
↓
Action Screen
Agent 앱에서 Notification은 부가 기능이 아니라 주요 Interaction Channel이 될 가능성이 큽니다.
Pizza Bot에서는 사용자가 이야기하는 Main Agent가 Generalist 역할을 합니다.
그리고 특정 작업은 Skill 기반 Specialist Worker에게 넘길 수 있습니다.
Main Agent
│
├─ Meeting Specialist
│
├─ Browser Specialist
│
└─ Research Specialist
각 Specialist는 별도 Instruction과 제한된 Tool 목록을 갖습니다.
예를 들어 Browser Automation Agent에는 Browser Tool만 주는 식입니다.
Browser Specialist
Allowed Tools
├─ navigate
├─ click
├─ type
└─ screenshot
CRM Agent라면
CRM Specialist
Allowed Tools
├─ readCustomer
├─ readDeal
└─ updateDeal
처럼 구성할 수 있습니다.
Agent마다 사용할 수 있는 Tool 범위를 줄이면 두 가지 장점이 있습니다.
Context ↓
Permission Surface ↓
Agent가 무엇을 할 수 있는지도 확인하기 쉬워집니다.
Pizza Bot은 새로운 Tool Extension 규격을 따로 만들지 않았습니다.
외부 Tool은 MCP로 연결합니다.
Pizza Bot
↓
MCP
↓
Calendar
Slack
CRM
Browser
GitHub
Specialist의 동작 방식은 SKILL.md로 정의할 수 있습니다.
개념적으로 보면 이런 구조입니다.
skill
├─ instructions
├─ tools
└─ approval policy
Agent가 새로운 기능을 필요로 할 때 Core Application을 계속 수정하는 방식보다,
Skill
+
MCP Server
를 추가하는 구조입니다.
최근 Agent 생태계에서 Plugin Architecture가 어느 방향으로 정리되고 있는지도 볼 수 있는 부분입니다.
Agent가 실제 업무를 하면 결국 권한 문제가 생깁니다.
Pizza Bot에서는 기본적으로 사용자의 Disk 전체에 바로 접근할 수 없습니다.
Folder 접근도 사용자가 직접 허용해야 합니다.
Folder
Read Only
or
Read + Write
MCP Tool도 마찬가지입니다.
특정 Skill에서 어떤 Tool을 사용할 수 있는지 제한할 수 있습니다.
그리고 위험한 작업에는 Approval을 붙일 수 있습니다.
Read
Auto
Write
Approval
Delete
Approval
즉 Agent Security와 Agent UX가 따로 존재하지 않습니다.
권한 정책이 UI에 그대로 나타납니다.
Action Queue가 그 대표적인 결과입니다.
Pizza Bot은 AWS의 Hosted Service가 아닙니다.
오픈소스 Community Project이고 Self-hosted 방식입니다.
Telemetry도 없으며 데이터는 기본적으로 사용자가 관리하는 환경에 저장됩니다.
Model Provider도 선택할 수 있습니다.
Anthropic
Amazon Bedrock
Google Gemini
OpenAI
OpenRouter
Ollama
Local Model도 가능합니다.
구조적으로 보면 Agent Runtime과 Model Provider가 분리돼 있습니다.
Pizza Bot
↓
Agent Runtime
↓
Provider Interface
↓
┌────────┬────────┬────────┐
Claude Gemini OpenAI Local
Agent Application이 특정 모델 하나에 종속될 필요가 없다는 의미입니다.
최근 Agent Architecture에서 계속 보이는 흐름이기도 합니다.
Model보다 Runtime과 Workflow가 위에 놓이기 시작하고 있습니다.
Pizza Bot은 갑자기 만들어진 실험 프로젝트는 아닙니다.
이전 버전은 Amazon 내부에서 사용됐고, AWS에 따르면 2,000명 이상이 사용했습니다.
활용 사례도 개발 업무에만 한정되지 않았습니다.
Meeting 준비
Follow-up
Email 작성
Slack 요약
CRM 기록
하루 업무 우선순위 정리
Web Research
같은 작업에 사용됐습니다.
즉 Pizza Bot이 해결하려는 문제는 Coding Agent만의 문제가 아닙니다.
시간이 오래 걸리는 모든 Agent Task의 Interaction 방식에 대한 실험에 가깝습니다.
그렇다고 Chat UI가 잘못됐다는 이야기는 아닙니다.
질문의 성격에 따라 다릅니다.
짧은 Interaction이라면 Chat이 훨씬 좋습니다.
이 코드 설명해줘.
이 문장 번역해줘.
Swift Actor가 뭐야?
이런 요청은
Prompt
↓
Immediate Response
가 자연스럽습니다.
반면 이런 요청은 다릅니다.
Repository 전체를 분석해서
Architecture 문제를 찾아줘.
이번 주 경쟁사 뉴스를 조사하고
보고서 만들어줘.
메일과 Slack을 확인해서
오늘 해야 할 일을 정리해줘.
이런 작업은
Task
↓
Background Work
↓
Notification
↓
Result
구조가 더 자연스럽습니다.
결국 Agent App에서는 두 가지 UI가 같이 존재할 가능성이 큽니다.
Quick Interaction
Chat
Long-running Work
Inbox / Task
최근 AI 기능을 앱에 넣을 때 가장 먼저 만드는 화면은 흔히 Chat입니다.
하지만 앞으로는 먼저 다른 질문을 해볼 필요가 있습니다.
이 작업은 몇 초 안에 끝나는가?
몇 초라면 Chat이 좋습니다.
사용자의 승인이 중간에 필요한가?
필요하다면 Task 상태 관리가 필요합니다.
앱을 닫아도 계속 실행돼야 하는가?
그렇다면 Backend Agent Runtime이 필요합니다.
Schedule이나 Event로 자동 실행되는가?
그렇다면 Chat보다 Inbox가 더 중요해집니다.
즉 UI를 결정하기 전에 Agent의 실행 모델부터 결정해야 합니다.
Pizza Bot의 아이디어를 일반적인 Agent 앱 Architecture로 바꿔보면 이런 형태입니다.
Trigger
│
┌───────────┼───────────┐
│ │ │
User Schedule Webhook
│ │ │
└───────────┼───────────┘
↓
Agent Task
↓
Agent Runtime
↓
┌────────┴────────┐
│ │
Tool Calls Specialist
│ │
└────────┬────────┘
↓
State
↓
┌────────────┼────────────┐
│ │ │
Running Action Completed
│ │
↓ ↓
Approval Unread
여기에서 Chat은 전체 시스템의 일부일 뿐입니다.
Agent Application의 중심은
Task
State
Trigger
Tool
Approval
Notification
입니다.
이 변화가 중요한 이유입니다.
iOS 앱으로 생각하면 구조가 더 명확해집니다.
사용자가 Agent Task를 생성합니다.
struct AgentTask: Identifiable, Codable {
let id: UUID
let title: String
var state: State
enum State: String, Codable {
case queued
case running
case waitingForApproval
case completed
case failed
}
}
Server에서는 Agent가 계속 작업합니다.
상태가 바뀌면 Push Notification을 보냅니다.
Server
↓
Task State Changed
↓
APNs
↓
iPhone
앱에서는 상태에 따라 다른 화면을 보여줍니다.
switch task.state {
case .running:
ProgressView()
case .waitingForApproval:
ApprovalView(task: task)
case .completed:
ResultView(task: task)
default:
EmptyView()
}
이렇게 보면 AI Agent 앱은 기존 Chat App보다 오히려
Background Job Management App
에 더 가까워집니다.
지금까지 AI는 주로 대화 상대였습니다.
Ask
↓
Answer
Agent는 조금 다릅니다.
Delegate
↓
Work
↓
Report
사람 사이에서도 이 두 방식은 다릅니다.
옆자리 동료에게 간단히 질문할 때는 바로 대화합니다.
하지만 몇 시간 걸리는 일을 맡길 때는 계속 옆에서 지켜보지 않습니다.
이거 조사해줘.
↓
다 되면 알려줘.
Agent도 실제 업무를 맡기기 시작하면 같은 UX가 필요해집니다.
그래서 Pizza Bot에서 가장 흥미로운 것은 어떤 모델을 사용하는지도, 새로운 Agent Algorithm도 아닙니다.
사용자가 Agent를 계속 보고 있지 않는다는 것을 처음부터 전제로 UI를 설계했다는 점입니다.
Chat은 AI 시대의 첫 번째 Interface였습니다.
빠르게 질문하고 빠르게 답을 받는 데는 여전히 가장 좋은 방식입니다.
하지만 Agent가
검색하고
파일을 읽고
여러 Tool을 호출하고
다른 Agent에게 일을 나누고
사람의 승인을 기다리고
몇 분 또는 몇 시간 동안 작업하고
Schedule에 따라 다시 실행되는
단계까지 오면 이야기가 달라집니다.
그런 작업을 작은 채팅창 안에서 계속 지켜보는 것은 자연스럽지 않습니다.
Pizza Bot이 제안하는 방식은 훨씬 단순합니다.
일을 맡긴다.
↓
다른 일을 한다.
↓
끝났거나
내 판단이 필요할 때
Agent가 다시 찾아온다.
결국 Long-running Agent에서 중요한 UI는 입력창이 아니라
Inbox, Task State, Approval, Notification
일 수 있습니다.
앞으로 AI 앱을 만들 때도
Chat 화면을 어떻게 만들까?
보다 먼저 물어볼 질문이 하나 생겼습니다.
이 작업을 사용자가 끝날 때까지 보고 있어야 할 이유가 있는가?
답이 아니오라면, 그 앱은 Chat보다 Inbox에 가까워지는 편이 더 자연스러울 수 있습니다.
AWS Open Source Blog — Introducing Pizza Bot, an open source inbox for AI agents that work in the background
Pizza Bot의 Inbox 중심 UI, Background Agent, Unread/Action Queue, Schedule, Webhook, Self-hosted 구조를 설명한 공식 발표입니다.
AWS Pizza Bot 공식 발표
AWS Open Source Blog
Pizza Bot을 포함해 AWS가 공개하는 Agent, MCP, Open Source 관련 후속 자료를 확인할 수 있습니다.
AWS Open Source Blog
AWS 공식 자료 기준으로 보면, Pizza Bot에서 가장 중요한 것은 새로운 AI 모델이 아니라 Agent와 사용자가 상호작용하는 방법을 바꿨다는 점입니다.
사용자가 Agent에게 작업을 맡긴 뒤 Chat 화면에서 계속 기다리는 대신 Agent는 Background에서 작업합니다.
Task 생성
↓
Background Agent
↓
작업 완료
↓
Unread
사람의 판단이 필요하면
Agent
↓
Approval Required
↓
Action
으로 이동합니다.
또한 작업은 사용자가 직접 시작하는 것뿐 아니라 Schedule이나 Webhook으로 시작할 수 있습니다.
그래서 Agent Application의 중심도
Conversation
보다
Task
State
Approval
Notification
Trigger
에 가까워집니다.
Long-running Agent를 모바일 앱이나 업무 도구에 넣는다면 Chat UI를 그대로 복제하기보다 Inbox + Task Manager + Notification 구조가 더 자연스러운 경우가 많다는 것을 보여주는 사례입니다.