실패를 예외가 아니라 입력으로 보기
AI 에이전트는 실패한다. 모델이 잘못 이해할 수 있고, 도구가 응답하지 않을 수 있으며, 컨텍스트가 길어져 중요한 지시를 놓칠 수 있다. 출력 형식이 계약과 맞지 않을 수도 있고, 권한 정책 때문에 작업이 중간에 멈출 수도 있다. 중요한 점은 실패 여부가 아니라 실패했을 때 시스템이 어떤 질서로 움직이느냐다.
실패 우선 설계는 비관적인 설계가 아니다. 오히려 운영 가능한 낙관주의에 가깝다. 에이전트가 대부분의 작업을 잘 처리하더라도, 하네스는 실패를 기본 경로 중 하나로 다룬다. 그래서 실패를 숨기지 않고 분류한다. 재시도할지, 중단할지, 롤백할지, 사람에게 넘길지 결정한다. 그리고 그 판단을 나중에 설명할 수 있도록 기록한다.
좋은 하네스는 에이전트에게 이렇게 말하는 시스템이다. 실패해도 된다. 단, 조용히 실패하지 말고, 같은 실패를 반복하지 말고, 위험한 방식으로 복구하려 하지 말라.

먼저 실패 유형을 분류한다
복구 전략은 실패 유형을 알아야 정할 수 있다. 모든 실패를 단순히 에러로 묶으면 하네스는 무조건 재시도하거나 무조건 중단하는 조잡한 선택만 하게 된다. 실패는 원인과 위험도에 따라 다르게 다뤄야 한다.
일반적인 실패 유형은 다음과 같다.
| 실패 유형 | 의미 | 기본 대응 |
|---|---|---|
| 타임아웃 | 모델, 도구, 외부 API가 정해진 시간 안에 응답하지 않음 | 짧은 재시도, 대체 경로, 부분 결과 저장 |
| 레이트 리밋 | 호출 횟수나 사용량 제한에 걸림 | 대기 후 재시도, 큐잉, 우선순위 조정 |
| 출력 형식 불일치 | JSON, 스키마, 필드 조건 등 입출력 계약 위반 | 형식 수정 요청, 검증기 기반 재생성 |
| 환각 | 근거 없는 사실, 없는 파일, 존재하지 않는 API를 말함 | 근거 확인, 도구 검증, 사람 검토 |
| 도구 실패 | 명령 실행 실패, 네트워크 오류, 권한 오류, 테스트 실패 | 실패 코드별 분기, 롤백 또는 중단 |
| 컨텍스트 초과 | 입력이 너무 길거나 작업 기억이 흐려짐 | 요약, 작업 분할, 체크포인트 복원 |
이 분류는 로그에도 남아야 한다. 단순히 failed라고 기록하면 나중에 개선할 수 없다. timeout인지, schema_mismatch인지, permission_denied인지 알아야 재발 방지책을 만들 수 있다.
예를 들어 출력 형식 불일치는 대개 낮은 위험의 실패다. 모델에게 검증 오류를 알려주고 다시 생성하게 하면 된다. 반면 환각은 다르다. 에이전트가 존재하지 않는 파일을 수정했다고 주장하거나, 실행하지 않은 테스트를 통과했다고 말한다면 단순 재시도보다 검증과 중단이 우선이다. 실패의 이름이 복구의 방향을 정한다.
재시도는 단계화해야 한다
많은 시스템이 실패를 만나면 재시도부터 한다. 그러나 무조건 재시도는 위험하다. 같은 프롬프트, 같은 컨텍스트, 같은 도구 상태에서 반복하면 같은 실패가 반복될 가능성이 높다. 비용만 늘고, 외부 API 제한을 더 빨리 소진하며, 때로는 데이터나 파일 상태를 더 망가뜨린다.
재시도 정책은 비용과 위험이 낮은 복구에서 높은 복구로 올라가야 한다.
첫 단계는 같은 작업을 가볍게 다시 시도하는 것이다. 일시적인 네트워크 오류, 짧은 타임아웃, 순간적인 모델 응답 실패에는 효과가 있다. 이때도 횟수 제한이 필요하다. 예를 들어 즉시 재시도 1회, 짧은 대기 후 재시도 1회처럼 제한한다.
두 번째 단계는 입력을 수정한 재시도다. 출력 형식이 틀렸다면 전체 요청을 다시 보내기보다 검증 오류만 전달한다. 컨텍스트가 너무 길다면 관련 파일만 줄여 보내거나, 이전 작업 요약을 만든 뒤 다시 시도한다. 이 단계의 핵심은 같은 실패 조건을 반복하지 않는 것이다.
세 번째 단계는 대체 경로다. 하나의 도구가 실패하면 읽기 전용 도구로 확인하거나, 더 작은 범위의 명령으로 쪼개 실행한다. 코드 수정 작업이라면 전체 테스트 대신 관련 테스트부터 실행할 수 있다. 문서 생성 작업이라면 전체 장을 다시 쓰기보다 실패한 섹션만 재생성한다.
네 번째 단계는 롤백이다. 이미 파일을 수정했거나 외부 상태를 바꿨다면 이전 체크포인트로 되돌려야 한다. 롤백은 실패 이후에 생각하는 기능이 아니라 실행 전에 준비해야 하는 기능이다. 어떤 작업을 하기 전 스냅샷을 만들고, 어떤 도구 호출이 상태를 바꾸는지 표시해야 한다.
마지막 단계는 수동 전환이다. 실패 횟수가 많거나, 위험도가 높거나, 비즈니스 영향이 큰 작업은 사람이 판단해야 한다. 사람에게 넘기는 것은 에이전트의 실패가 아니라 하네스의 성공이다. 시스템이 자신이 다룰 수 없는 상황을 알아차렸기 때문이다.
종료 경로는 실패마다 달라야 한다
하네스는 작업이 끝나는 방식을 세분화해야 한다. 완료와 실패만으로는 부족하다. 특히 에이전트 환경에서는 중단, 차단, 거부, 실패가 서로 다른 의미를 가진다.
사용자 중단은 사용자가 의도적으로 작업을 멈춘 경우다. 이때 에이전트는 추가 실행을 해서는 안 된다. 현재까지의 변경 사항, 실행한 도구, 남은 작업을 요약하고 정리 상태로 들어가야 한다. 사용자가 중단했는데도 에이전트가 복구하려고 계속 실행하면 자율성이 아니라 통제 실패다.
출력 잘림은 모델 응답이 토큰 한계나 시스템 제한으로 중간에 끊긴 경우다. 이때는 실패한 것이 아니라 미완성 상태에 가깝다. 하네스는 마지막 완전한 단락이나 구조화된 필드까지만 인정하고, 이어 쓰기 요청을 만들 수 있다. 단, 코드나 JSON처럼 닫힘 구조가 중요한 출력은 반드시 검증 후 이어야 한다.
훅 차단은 사전 정의된 검사나 정책이 실행을 막은 경우다. 예를 들어 금지된 파일 수정, 비밀키 노출 가능성, 테스트 미통과 커밋 등이 있다. 이 경우 재시도보다 원인 수정이 먼저다. 훅은 에이전트가 넘어야 할 귀찮은 장벽이 아니라 시스템의 안전벨트다.
권한 거부는 에이전트가 허용되지 않은 도구나 범위에 접근하려 한 경우다. 이때 하네스는 권한 상승을 자동으로 해서는 안 된다. 요청 이유, 필요한 권한, 예상 영향 범위를 정리해 승인 경로로 보내야 한다. 권한 거부를 단순 오류로 처리하면 에이전트가 더 우회적인 방식으로 같은 작업을 시도할 수 있다.
테스트 실패는 코드나 결과물이 요구 조건을 만족하지 못했다는 신호다. 테스트 실패는 다시 시도할 수 있지만, 같은 수정을 반복해서는 안 된다. 실패 로그를 요약하고, 원인을 가설로 분리한 뒤, 가장 작은 수정 단위로 다시 실행해야 한다. 세 번의 큰 수정 실패보다 한 번의 작은 원인 확인이 낫다.
부분 실행을 추적 가능하게 만든다
AI 에이전트의 실패가 까다로운 이유는 작업이 중간까지 실행될 수 있기 때문이다. 파일 하나는 수정됐고, 다른 파일은 수정되지 않았을 수 있다. 데이터베이스 마이그레이션은 생성됐지만 테스트는 실패했을 수 있다. 외부 API 호출은 성공했지만 후속 기록은 남지 않았을 수 있다.
이런 상태를 방치하면 다음 실행이 더 위험해진다. 에이전트는 자신이 어디까지 했는지 모르고 같은 작업을 반복한다. 사람도 어떤 변경이 의도된 것인지 알 수 없다. 그래서 하네스는 부분 실행에 대해 보상 결과와 상태 기록을 남겨야 한다.
상태 기록에는 최소한 다음 정보가 있어야 한다.
작업 ID와 요청자
시작 시점의 입력과 정책 버전
실행된 모델 호출과 도구 호출
각 도구 호출의 성공, 실패, 차단 여부
변경된 파일, 생성된 리소스, 외부 호출 결과
실패 유형과 복구 시도 횟수
현재 상태: 완료, 중단, 차단, 롤백됨, 수동 검토 필요
보상 결과란 원래 작업을 완성하지 못했을 때 남기는 정리 결과다. 예를 들어 파일 변경을 되돌렸다면 어떤 파일을 되돌렸는지 기록한다. 되돌리지 못했다면 왜 못했는지 남긴다. 테스트가 실패했다면 실패한 테스트 이름과 마지막 오류를 남긴다. 권한 때문에 멈췄다면 필요한 승인 항목을 남긴다.
중요한 것은 완벽한 복구가 아니다. 설명 가능한 복구다. 실패한 작업이라도 다음 사람이 이어받을 수 있어야 한다. 다음 에이전트 실행이 같은 상태를 오해하지 않아야 한다.
롤백은 실행 전부터 설계한다
롤백은 단순히 이전으로 되돌리는 기능이 아니다. 어떤 상태를 되돌릴 수 있고, 어떤 상태는 되돌릴 수 없는지 구분하는 설계다.
파일 수정은 비교적 롤백하기 쉽다. 변경 전 스냅샷이나 버전 관리 시스템이 있으면 된다. 하지만 외부 이메일 발송, 결제 요청, 사용자 알림, 운영 데이터 삭제는 단순 롤백이 어렵다. 이런 작업은 실행 전에 더 강한 승인과 사전 검증이 필요하다.
따라서 도구는 성격에 따라 나눠야 한다.
읽기 전용 도구: 상태를 바꾸지 않으므로 자유도가 높다.
로컬 변경 도구: 스냅샷과 diff로 복구할 수 있다.
외부 상태 변경 도구: 멱등성 키, 승인, 감사 로그가 필요하다.
되돌릴 수 없는 도구: 기본적으로 사람 승인을 요구한다.
멱등성은 같은 요청이 여러 번 실행되어도 결과가 중복되지 않게 만드는 성질이다. 예를 들어 같은 작업 ID로 외부 요청을 보내면 한 번만 처리되게 하는 방식이다. 재시도가 있는 시스템에서는 멱등성이 매우 중요하다. 재시도는 실패를 줄이지만, 멱등성이 없으면 중복 실행이라는 새 실패를 만든다.
사람에게 넘기는 임계값을 정한다
수동 전환은 기분으로 결정하면 안 된다. 하네스는 사람 검토로 전환해야 하는 기준을 명확히 가져야 한다. 대표 기준은 실패 횟수, 위험도, 비즈니스 중요도, 불확실성 점수다.
실패 횟수는 가장 단순한 기준이다. 같은 유형의 실패가 2회 또는 3회 반복되면 자동 복구를 멈춘다. 특히 같은 검증기에서 반복해서 실패한다면 더 많은 생성은 도움이 되지 않는다.
위험도는 작업이 잘못되었을 때의 피해를 뜻한다. 문서 문장 수정은 낮은 위험이다. 운영 데이터 변경, 권한 정책 수정, 결제 로직 변경은 높은 위험이다. 위험도가 높을수록 재시도 횟수는 줄이고 승인 조건은 강화해야 한다.
비즈니스 중요도는 결과가 조직이나 사용자에게 미치는 영향이다. 내부 실험 코드는 자동 복구를 넓게 허용할 수 있다. 고객에게 바로 노출되는 기능, 법적 문서, 보안 설정은 사람 검토를 빠르게 요청해야 한다.
불확실성 점수는 에이전트가 스스로 확신하지 못하는 정도를 수치화한 것이다. 근거 파일을 찾지 못했거나, 요구사항이 모호하거나, 테스트가 부족하거나, 모델 응답 간 판단이 흔들릴 때 높아진다. 이 점수는 모델의 자기 확신만 믿어서는 안 된다. 검증 실패, 검색 결과 부족, 변경 범위 증가 같은 관측 가능한 신호와 함께 계산해야 한다.
간단한 정책은 다음처럼 만들 수 있다.
| 조건 | 조치 |
|---|---|
| 낮은 위험 작업에서 형식 오류 1회 | 검증 오류를 포함해 재생성 |
| 같은 오류 3회 반복 | 자동 복구 중단, 사람 검토 |
| 권한 거부 발생 | 권한 요청 요약 후 승인 대기 |
| 운영 데이터 변경 포함 | 실행 전 승인 필수 |
| 테스트 실패 후 변경 범위 확대 | 체크포인트 생성 후 검토 요청 |
| 불확실성 높음 + 비즈니스 중요도 높음 | 자동 실행 금지 |
핵심은 에이전트가 더 열심히 시도하게 만드는 것이 아니다. 어느 지점에서 멈춰야 하는지 알게 만드는 것이다.
실패 기록은 다음 개선의 재료다
복구 전략은 한 번 정하고 끝나는 규칙이 아니다. 실패 로그가 쌓이면 하네스는 더 똑똑해져야 한다. 자주 발생하는 출력 형식 오류는 스키마 설명을 바꾸거나 예시를 추가해 줄일 수 있다. 반복되는 테스트 실패는 더 작은 체크 명령으로 앞당길 수 있다. 권한 거부가 자주 발생하면 정책이 과도하게 좁은지, 작업 분류가 잘못됐는지 점검할 수 있다.
실패 우선 설계의 목적은 실패를 없애는 것이 아니다. 실패를 작게 만들고, 빠르게 감지하고, 안전하게 멈추며, 다음 실행이 더 나아지게 만드는 것이다.
AI 에이전트는 완벽한 작업자가 아니다. 예측하기 어려운 판단 능력을 가진 실행자다. 하네스 엔지니어링은 이 실행자를 믿되, 검증 없이 방치하지 않는다. 실패를 기본값으로 두고도 시스템이 앞으로 나아가게 만드는 것, 그것이 복구 전략의 핵심이다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.