에이전트가 '완료했습니다'라고 말하는 순간, 그 말을 믿어도 되는가. 이 질문은 이론이 아니다. 현장에서 이미 답이 나오고 있고, 그 답은 불편하다.
Nick Meinhold는 Claude Code 세션 훅으로 구동되는 AI 에이전트의 GitHub 이슈 백로그를 직접 감사했다. 결과는 11개 오픈 태스크 중 3개가 유령이었다—이미 완료된 작업이 완료로 기록되지 않은 채 세션마다 복원되며 살아있는 작업처럼 순환하고 있었다. 단 한 번의 감사에서 27% 유령율. 작은 숫자처럼 보이지만, 이게 우연이 아니라는 점이 핵심이다.
구조적 이유는 명확하다. 생성 신호는 자동이고, 완료 신호는 선택적이다. 에이전트가 작업을 시작할 때는 이슈 생성이 작업 수행과 결합되어 있어 반드시 실행된다. 그런데 작업이 끝났을 때 이슈를 닫는 것은 별도의 부기 행위다—세션이 끝나거나, 다음 작업으로 주의가 이동하거나, 사람이 '잘했어요'라고 말하는 그 순간에 발생해야 하는, 그러나 아무것도 다운스트림에 의존하지 않는 단계. 그래서 건너뛰어진다. 쓰기 편향(write-bias)이 만드는 루프다—상태를 기록하는 것보다 상태를 주장하는 것이 훨씬 쉽기 때문에 시스템은 조용히 stale 정보로 채워진다.
이 문제의 해결책으로 Meinhold가 제시한 것은 단순하다. 자기보고를 믿지 말고 현실을 확인하라. 이메일을 보냈는지 확인하려면 발신 폴더의 실제 스레드를 본다. 캘린더 초대가 나갔는지는 캘린더 이벤트 자체를 본다. 시크릿 디렉터리가 제거됐는지는 git 트리를 직접 읽는다. 태스크 트래커가 '완료'라고 해도 현실이 '아직'이면, 현실이 이긴다. 에이전트의 기억이 아니라 다운스트림 아티팩트가 사실의 소재지다.
그런데 에이전트가 완료 신호를 누락하는 것만이 문제가 아니다. 완료했다고 기록한 것 자체가 근본 원인을 해결하지 않은 임시방편일 때도 있다. 음성 변환 앱 개발 중 발생한 세 가지 버그를 분석한 Orca Forge의 사례 연구는 AI 코딩 에이전트가 '지금 당장 작동하는 수정'을 얼마나 빠르게, 얼마나 설득력 있게 제안하는지를 보여준다. try-catch로 에러를 삼키고, 특정 값을 하드코딩으로 회피하고, 휴리스틱 키워드로 정밀도를 위장하는 것들—모두 에이전트가 속도감 있게 내놓을 수 있는 해법이다.
이 사례 연구에서 실제 근본 원인을 찾아낸 방법은 증상이 무엇에 비례하는지 측정하는 것이었다. 음성이 느리게 재생되는 버그는 짧은 오디오에서는 발생하지 않고 길수록 심각해졌다—131초 녹음이 4배 느리게 재생됐다. 샘플링 레이트 불일치였다면 길이와 무관하게 고정 비율로 느렸을 것이다. '길이에 비례해 악화된다'는 패턴은 Whisper 인코더의 30초 한계라는 한 지점으로 직접 수렴했다. 타임스트레치로 출력을 강제 조정하는 것은 증상 제거다. 30초 청크로 분할해 피처 추출 단계를 올바르게 고치는 것이 근본 원인 해결이다. AI 에이전트가 제안하는 빠른 수정이 설득력 있을수록, '왜 작동하는지 한 문장으로 설명할 수 있는가'라는 질문을 명시적으로 강제해야 한다.
실운용 레이어에서의 신뢰성 문제는 한 단계 더 있다. Labyrinth Analytics가 20개 Claude 에이전트를 launchd로 스케줄링해 3개월간 운용한 유지보수 로그는, 에이전트 신뢰성 문제가 에이전트 자체뿐 아니라 인프라 레이어의 암묵적 가정에서도 발생한다는 것을 보여준다. launchd는 정확한 시작 시각을 보장하지 않는다. 시스템 부하가 있으면 지연이 쌓이고, 20개 에이전트가 같은 슬롯에서 출발하면 SQLite 파일에 동시 쓰기 충돌이 발생한다. 세션이 비정상 종료되면 트랜잭션이 열린 채로 남고, 다음 에이전트가 잠금 해제를 기다리며 플릿 전체가 멈춘다.
이 로그에서 가장 주목할 지점은 턴 예산 관리 원칙이다. '계측이 집행보다 먼저여야 한다'—어떤 작업 유형이 얼마나 긴지 실제 데이터 없이 상한을 설정하면, 정당한 작업을 자르거나 의도치 않게 문을 열어두게 된다. 에이전트가 스스로 보고하는 완료 상태뿐 아니라, 에이전트를 둘러싼 인프라가 암묵적으로 전제하는 보장들—정확한 스케줄, 환경 변수 상속, 정상 종료 핸들링—도 모두 설계의 대상이지 당연한 전제가 아니다.
세 사례를 관통하는 패턴을 정리하면 이렇다. 에이전트는 의도를 신뢰성 있게 선언하지만, 완료를 신뢰성 있게 기록하지 않는다. 완료했다고 기록하더라도 그것이 근본 원인을 해결한 결과인지 증상을 가린 결과인지는 기록만으로 알 수 없다. 그리고 에이전트를 돌리는 인프라 자체가 암묵적 실패 모드를 품고 있다. 이 세 층위의 불신뢰성은 각각 다른 설계 응답을 요구한다.
팀이 지금 설계해야 할 것은 다음 세 가지 구조다. 첫째, 완료 신호를 생성 신호처럼 자동화하거나, 자기보고 대신 다운스트림 아티팩트를 정기적으로 대조하는 조정 루프를 파이프라인에 넣어라. 에이전트의 기억이 아니라 실제 시스템 상태가 사실의 소재지다. 둘째, 에이전트가 제안하는 수정에 '왜 작동하는가'를 설명하도록 요구하는 프롬프트 원칙을 팀 표준으로 박아라. 설명할 수 없는 수정은 증상 제거일 가능성이 높다. 셋째, 에이전트를 돌리는 스케줄러와 데이터 레이어의 암묵적 보장을 명시적 설계로 전환하라—타이밍, 잠금, 환경 변수, 비정상 종료 핸들링은 기본값을 신뢰하는 영역이 아니다.
에이전트가 더 빠르고 더 많은 작업을 수행할수록, 팀이 설계하지 않은 검증 공백은 더 빠르게 채워진다—유령 작업으로, 임시방편 수정으로, 조용한 플릿 중단으로. 에이전트를 신뢰하는 것과 에이전트의 출력을 검증하는 구조를 갖추는 것은 다른 일이다. 그리고 지금 시점에서 팀이 투자해야 할 곳은 명확히 후자다.