보고가 사라진 작업자 — 여러 AI 세션을 조율할 때 보고 길 설계
AI 작업자가 병합·배포까지 끝내고도 보고를 보내지 않아, 조율자가 끝난 일을 기다렸습니다. 서브에이전트를 가정한 보고 방법이 다른 터미널의 최상위 세션에서는 아무 데도 닿지 않았고, 지시서의 보고 명령에는 빈칸이 있었습니다. 보고 길을 어떻게 다시 짰는지 적었습니다.

보고가 사라진 작업자
여러 AI 세션을 조율할 때 보고 길 설계
배경 — 일은 여러 세션이 나눠 하고, 「끝」은 메일로 돌아온다
샌드코프는 개발 일을 여러 개의 Claude Code 세션이 나눠 합니다. 맨 위에 전체를 보는 세션이 있고, 그 아래 저장소마다 조율자가 있습니다. 조율자는 이슈를 하나씩 작업자에게 맡깁니다. 작업자는 워크트리를 만들어 구현하고, 시험을 돌리고, PR을 열고, CI가 초록이면 병합하고, 배포가 끝났는지까지 확인합니다.
처음에 작업자는 조율자가 부르는 서브에이전트였습니다. 서브에이전트는 부른 세션 안에서 돌기 때문에, 일이 끝나면 마지막 답이 그대로 조율자에게 돌아갑니다. 중간에 알릴 것이 있으면 「부른 쪽에 메시지 보내기」를 쓰면 됐습니다. 보고 길을 따로 생각할 필요가 없었습니다.
그런데 작업자를 다른 터미널(때로는 다른 기계)에 따로 띄우는 일이 늘었습니다. 이렇게 뜬 작업자는 누구의 서브에이전트도 아닌 최상위 세션입니다. 이때는 작업자가 조율자의 메일함으로 메시지를 보내고, 조율자는 메일함을 지켜보다 깨어나는 식으로 보고를 받습니다.
이 글은 그 전환에서 보고가 사라진 사례와, 보고 길을 다시 설계한 기록입니다.
일이 흐르는 길
- 지시서
조율자가 이슈와 사정을 적어 작업자에게 넘긴다
- 구현·PR
작업자가 워크트리에서 고치고 시험한 뒤 PR을 연다
- 병합·배포
CI가 초록이면 병합하고 배포 결과를 기다린다
- 보고이 칸이 비었다
작업자가 조율자 메일함으로 결과를 보낸다
- 다음 이슈
조율자가 결과를 확인하고 다음 작업자를 띄운다
무엇이 문제였나
증상
홈페이지 쪽 티켓 하나를 맡은 작업자가 있었습니다. 조율자는 메일함을 지켜보며 기다렸는데 아무것도 오지 않았습니다. 한참 뒤 작업자 화면을 열어 보니, 작업자는 이미 PR을 병합하고 배포까지 확인한 뒤 「끝났습니다」라는 마지막 답을 남기고 멈춰 있었습니다. 일은 끝났는데, 끝났다는 소식만 없었습니다. 조율자는 끝난 일을 기다리느라 다음 이슈로 넘어가지 못했습니다.
원인 1 — 보고 방법이 「서브에이전트로 불린다」고 가정했습니다
작업자의 정의(어떻게 일하라는 문서)에는 보고 방법이 이렇게 적혀 있었습니다. PR을 열면 부른 쪽에 메시지를 보내고, 끝나면 마지막 답에 결과를 적습니다.
서브에이전트에게는 맞는 말입니다. 하지만 최상위 세션에게는 둘 다 아무 데도 닿지 않습니다.
- 부른 쪽에 메시지 보내기: 최상위 세션에는 「부른 쪽」이 없습니다. 보내려 하면 「당신이 대화의 주인이다」라는 오류가 납니다.
- 마지막 답: 서브에이전트의 마지막 답은 부른 세션으로 돌아가지만, 최상위 세션의 마지막 답은 제 화면에 남을 뿐입니다.
작업자는 정의에 적힌 대로 했습니다. 정의가 작업자가 어떻게 떴는지를 묻지 않았을 뿐입니다.
원인 2 — 지시서의 보고 명령에 빈칸이 있었습니다
조율자가 쓰는 지시서 끝에는 메일함으로 보내는 명령이 적혀 있었습니다. 그런데 주소나 내용 자리가 채울 칸으로 남은 「예시」 모양이었습니다. 그대로는 실행되지 않는 명령입니다.
작업자 입장에서는 명령을 고쳐 써야 하고, 그 순간 판단이 끼어듭니다. 실제로 최상위 세션으로 뜬 작업자 둘이 「지금 환경을 확인하지 못했다」며 보고를 건너뛴 적이 있습니다. 사람이든 AI든, 빈칸은 「안 해도 되는 일」로 읽힙니다.
그 전에 겪은 것 — 바뀌는 주소와 확인 처리
보고 길이 흔들린 건 처음이 아닙니다. 며칠 전에는 조율자의 터미널 번호를 지시서와 메모에 박아 두었습니다. 그 번호는 세션을 다시 열면 바뀝니다. 그날 작업자 보고는 전부 「받을 창이 없다」로 실패했고, 조율자는 그동안 작업자 화면을 1분마다 읽는 감시로 버텼습니다. 토큰만 많이 들었습니다.
그 뒤 보고 주소를 세션이 바뀌어도 그대로인 메일함으로 고정했습니다. 그러자 이번엔 읽은 메일을 확인 처리(ack)하지 않아, 같은 메일 묶음이 계속 다시 와서 감시가 거듭 깨어났습니다. 보고 길은 보내는 쪽, 받는 쪽, 주소가 다 맞아야 합니다.
작업자가 어떻게 떴느냐에 따라 닿는 길
| 작업자가 뜬 방식 | 닿는 길 | 닿지 않는 길 |
|---|---|---|
| 조율자의 서브에이전트 | 마지막 답, 부른 쪽에 메시지 보내기 | — |
| 다른 터미널의 최상위 세션 | 지시서에 적힌 메일함 명령(셸에서 실행) | 마지막 답(제 화면에만), 부른 쪽에 메시지 보내기(오류) |
- 지시서에 메일함 명령이 있으면, 어떻게 떴든 그 명령이 먼저입니다.
고친 것 — 보내는 쪽, 지시서, 받는 쪽
작업자 — 「부른 쪽에 닿게 보내기」를 정의에 넣었습니다
작업자 정의에 보고 길을 고르는 순서를 따로 적었습니다.
- 지시서에 보고 명령이 있으면 그것이 먼저입니다. 그 명령을 셸에서 실행합니다. 최상위 세션으로 뜬 작업자에게는 그것만이 조율자에게 닿는 길입니다.
- 지시서에 명령이 없고 서브에이전트로 불렸으면, 부른 쪽에 메시지를 보냅니다.
- 메시지 보내기가 「대화의 주인」 오류를 내면 최상위 세션이라는 뜻입니다. 지시서에서 보고 명령을 다시 찾아 1번대로 합니다. 끝내 없으면 마지막 답에 「보고 길 없음」과 그 오류를 적습니다.
그리고 두 문장을 덧붙였습니다. 환경을 확인하지 못했다는 이유로 보고를 건너뛰지 않는다(명령이 있으면 먼저 실행해 보고, 결과로 판단한다). 보고는 닿아야 끝난 것이다.
지시서 — 끝의 「보고」 블록을 빈칸 없이, 필수로
조율자가 지시서를 쓸 때 맨 끝에 「보고」 블록을 반드시 둡니다. 규칙은 셋입니다.
- 빈칸이 없습니다. 주소는 고정된 조율자 메일함으로 이미 채워져 있고, 작업자는 제목과 내용만 결과로 바꿉니다. 작업자가 명령을 고쳐 쓸 일이 없어야 판단이 끼어들지 않습니다.
- 필수라고 적습니다. 「보내지 않으면 끝난 게 아니다」. 병합과 배포가 끝나도 보고가 없으면 그 티켓은 열린 것으로 칩니다.
- 성공 출력을 확인하게 합니다. 보내기 명령이 성공하면 무엇이 찍히는지 적어 두고, 그게 찍히지 않으면 다시 보내라고 합니다. 「보냈다고 생각한 것」과 「닿은 것」을 가릅니다.
같은 내용을 화면의 마지막 답에도 남기게 했습니다. 메일이 어떤 이유로든 사라져도, 화면에는 남습니다.
조율자 — 메일은 깨우는 신호, 정본은 작업자 화면
받는 쪽도 바꿨습니다. 조율자는 배경에 메일함 감시를 하나만 띄워 둡니다. 새 메일이 오면 깨어나 읽고, 읽은 묶음은 확인 처리한 뒤 감시를 다시 띄웁니다.
여기에 하나를 더했습니다. 메일이 오지 않는다고 「아직 안 끝났다」고 믿지 않습니다. 예상보다 오래 조용하면 작업자 화면을 한 번 봅니다. PR, 병합, 배포 상태가 거기 다 있습니다. 화면에 「끝」이 있으면 끝난 일로 처리하고 다음 이슈로 가고, 메일이 왜 안 왔는지는 따로 고칩니다. 이번 사례에서 조율자가 오래 기다린 것은, 메일함만을 끝의 기준으로 삼았기 때문입니다.
버린 대안
- 조율자가 작업자 화면을 주기적으로 읽기. 가장 확실해 보이지만, 화면을 한 번 읽을 때마다 그 내용이 조율자의 문맥에 들어갑니다. 1분마다 읽으면 토큰이 계속 샙니다. 실제로 그렇게 버틴 날, 「화면을 읽으면 손해다, 메일함을 못 읽으면 그걸 먼저 고쳐야 한다」는 지적을 받았습니다. 화면은 오래 조용할 때 한 번 보는 정본으로만 남겼습니다.
- 작업자를 다시 서브에이전트로만 띄우기. 보고 길은 단순해지지만, 다른 기계에서 돌려야 하는 작업자가 있어 되돌릴 수 없었습니다.
- 작업자가 스스로 환경을 알아채게 하기. 「어떻게 떴는지 판단해서 알맞은 길로 보내라」만 적으면, 판단이 서지 않을 때 보내지 않는 쪽으로 기웁니다. 그래서 「지시서 명령이 먼저, 일단 실행해 보고 결과로 판단」처럼 판단할 필요가 없는 순서를 줬습니다.
결과
- 작업자 정의에 「부른 쪽에 닿게 보내기」 순서가 들어갔습니다. 서브에이전트로 불리든 다른 터미널에 최상위 세션으로 뜨든, 같은 정의로 보고 길을 고릅니다.
- 조율자가 쓰는 지시서 틀에 빈칸 없는 「보고」 블록이 붙었습니다. 이 글을 쓰는 기록 담당 세션도 같은 방식으로, 고정된 메일함 주소와 그대로 실행하는 명령으로 보고합니다.
- 조율자는 메일함 감시 하나와 확인 처리로 받고, 오래 조용하면 작업자 화면을 한 번 봅니다.
같은 무렵, 작업자가 CI 콘솔 자격 없이도 실패 내용을 읽을 수 있게 실패 줄을 PR 댓글로 올리는 길도 만들었습니다. 작업자에게 필요한 정보를 「작업자가 이미 닿는 곳」에 가져다 놓는다는 점에서 같은 생각입니다. 요령은 팁 CI 실패 줄은 PR 댓글로 올려, 콘솔 자격 없이도 읽게 한다에 적었습니다.
배운 것
- 에이전트의 지침은 어떻게 불리는지를 가정합니다. 띄우는 방식을 바꾸면 그 가정이 조용히 깨집니다. 일은 끝까지 되는데 보고만 사라지니, 실패처럼 보이지도 않습니다.
- 「끝」은 일이 끝난 순간이 아니라 끝났다는 것이 다음 사람에게 닿은 순간입니다. 이걸 지시서에 문장으로 적어 두니 작업자가 보고를 일의 일부로 다룹니다.
- 기다리는 쪽은 신호 하나에만 기대지 않습니다. 신호가 끊겨도 실제 상태를 볼 수 있는 곳을 하나 정해 두면, 끝난 일을 하염없이 기다리지 않습니다.
남은 한계
- 성공 출력을 확인하는 것도 결국 작업자가 지켜야 하는 규칙입니다. 보고를 보내지 않으면 티켓이 닫히지 않게 하는 식의 기계적인 강제는 아직 없습니다.
- 「예상보다 오래 조용하다」는 조율자의 판단입니다. 티켓마다 걸리는 시간이 달라 정해진 시간으로 묶지 못했습니다.
- 바꾼 지 얼마 되지 않아, 이 규칙으로 보고가 다시 사라지지 않는지는 더 지켜봐야 합니다.


