Agent 장시간 작업은 왜 진행률을 보고해야 하는가
← 전체 목차 · 이전: MCP Tasks와 "도구 호출을 걸어놓고 기다리기"는 도대체 무엇이 다른가 · 다음: 컨텍스트 압축에서 잃어서는 안 되는 것
진행률 보고는 프런트엔드 애니메이션도 아니고 단지 "사용자 경험이 좋아서"도 아니다. 그것은 Agent 통제 가능성의 입구다. 장시간 작업을 상태·소요 시간·에러·산출물을 가진 관찰 가능한 단계로 쪼개어 외부에 노출해야 비로소 관측성, 중도 개입(일시정지/재시도/스킵/롤백/사람 전환), 이상 복구를 논할 수 있다. 진행률 보고는 Agent 통제 가능성의 입구다.
작업을 "관찰 가능한 단계"로 쪼개기
- 요구 이해
- 자료 검색
- 시스템 호출
- 결과 생성
- 확인 대기
반드시 기록해야 할 필드
| 필드 | 용도 |
|---|
| 상태 | 사용자는 진행 상황을 보고, 시스템은 흐름을 제어 |
| 시작 시각 | 병목 지점 특정 |
| 종료 시각 | 병목 지점 특정 |
| 소요 | 성능과 타임아웃 판정 |
| 에러 정보 | 실패 위치를 정확히 특정 |
멈췄을 때 "로딩 중"만 표시해서는 안 된다 — 이상은 분류 가능해야 한다 (이것이 곧 관측성의 가치다)
| 이상 유형 | 의미 |
|---|
| 모델 타임아웃 | LLM 측이 제한 시간 내에 반환하지 않음 |
| 도구 타임아웃 | 도구/함수 호출이 반환하지 않음 |
| 권한 실패 | 인증/인가 미통과 |
| 외부 서비스 불가 | 다운스트림 시스템 다운 또는 도달 불가 |
반면 경고
- 가짜 진행률을 보고하지 말 것
- 진행률에도 권한과 마스킹을 적용할 것
정리
Agent 장시간 작업은 실시간으로 진행률을 보고해야 한다. 경험을 개선할 뿐 아니라 작업 통제, 이상 복구, 관측성을 뒷받침하기 때문이다. 작업을 여러 관찰 가능한 단계로 쪼개고 각 단계마다 상태, 소요, 에러, 산출물을 기록한다. 프런트엔드가 표시하는 것은 마스킹된 진짜 진행률이며, 백엔드는 이 상태들로 취소, 재시도, 일시정지, 확인, 사람 전환을 지원한다. 어떤 단계가 실패하면 시스템은 실패 위치를 설명할 수 있어야지 "일반 실패" 하나만 주면 안 된다.
핵심 통찰
- 진행률은 "제어면"이지 "표시면"이 아니다 — 대부분의 사람이 진행률 보고를 프런트엔드 경험으로 분류하지만, 이것은 시스템 통제 가능성에 속한다. 판단 기준은 간단하다. 진행률이 UI에만 공급되고 백엔드는 같은 상태를 가져오지 못한다면 그것은 장식일 뿐이고, 백엔드도 이 상태에 의존해 취소/재시도/롤백을 한다면 그것이 제어면이다.
- 관측성의 전제는 "열거 가능한 단계"다 — 쪼개지지 않은 블랙박스 장시간 작업에는 본질적으로 관측성이 없다. 먼저 작업 분해를 해야 상태 보고가 가능하고, 그래야 개입 지점이 가능하다. 순서를 뒤집으면 안 된다.
- 이상은 반드시 분류해야 하며, 그러지 않으면 예외 처리가 없는 것과 같다 — "로딩 중"과 "실패"는 같은 부류의 오류다. 완전히 다른 네 가지 장애(모델 타임아웃/도구 타임아웃/권한 실패/다운스트림 불가)를 행동 불가능한 신호 하나로 압축한다. 행동 가능성 = 이것을 근거로 다음 동작을 고를 수 있는가.
- 무상태 = 블랙박스 = 전부 다시 하기 — 중간 상태가 없으면 사용자의 유일한 교정 수단은 처음부터 다시 돌리는 것이며, 비용은 작업 길이에 비례해 커진다. 중간 상태의 진짜 가치는 "다시 하기"의 입도를 작업 전체에서 단일 단계로 낮추는 것이다.
- 가짜 진행률은 기술 부채이며 신뢰를 역습한다 — "심층 사고 중" 같은 실제 이벤트와 디커플링된 문구는 단기적으로는 똑똑해 보이지만, 장기적으로는 사용자가 진행률로 개입 여부를 판단할 수 없게 만들어 진행률 신호의 정보량을 0으로 만든다.
- 진행률은 외부로 나가는 데이터 채널이므로 데이터 채널의 기준으로 거버넌스해야 한다 — 많은 팀이 반환 결과에는 권한과 마스킹을 적용하면서, 진행률 문구가 똑같이 계약명, 고객명, 견적을 경계 밖으로 내보낸다는 것을 잊는다. 시스템 밖으로 나가는 모든 문자열은 마스킹을 거쳐야 한다.
엔지니어링 실전 Tips
- 2분을 설계 레드라인으로 삼을 것: 경험값은 "십수 초는 수용 가능, 2분 무반응이면 반드시 문제"다. P95가 십수 초를 넘는 Agent 실행 경로라면 타임아웃 컴플레인을 기다리지 말고 진행률 보고를 올려야 한다.
- 진행률 보고는 멱등이어야 하고 단계 ID를 가져야 한다: 사용자의 반복 클릭은 필연적 행동이므로, 프런트는 작업 ID + 단계 순번으로 중복을 제거해 중복 제출이 작업 상태를 망가뜨리지 않게 해야 한다.
- 상태 필드는 한 번에 제대로 설계할 것: 상태 / 시작 시각 / 종료 시각 / 소요 / 에러 / 산출물, 여섯 필드 중 하나만 빠져도 나중에 재시도나 롤백을 만들 때 데이터 구조를 다시 손봐야 한다.
- "산출물(artifact)" 필드를 빠뜨리기 쉽다: 이것이 "스킵"과 "롤백"을 구현할 수 있는 전제다. 단계별 산출물이 없으면 롤백은 시작점으로밖에 갈 수 없다.
- 타임아웃은 계층별로 설정할 것: 모델 타임아웃과 도구 타임아웃은 서로 다른 두 예산이며, 전역 타임아웃 하나를 공용하면 이상 분류가 무효화된다.
- 마스킹은 서버 출구에 두고 프런트엔드에 두지 말 것: 프런트 마스킹은 데이터가 이미 나갔다는 뜻이며 패킷을 잡으면 보인다.
- 실패 정보에 위치 좌표를 붙일 것:
문서 파싱 ✓ → 엔티티 추출 ✗ TimeoutError → 요약 생성 (미실행) 같은 3단 형식이 어떤 에러 코드보다도 트러블슈팅 시간을 줄여준다.
- 진행률 입도는 개입 지점 기준으로 나누고 코드 모듈 기준으로 나누지 말 것: 사용자나 시스템이 "중단/재실행"할 수 있는 경계만이 진행 단계가 될 가치가 있으며, 그렇지 않으면 무의미한 상태 노이즈만 대량 생산된다.