
여러 AI 에이전트를 병행 실행할 때 병목이 되는 것은 인간, herdr의 해답
요약
여러 AI 에이전트를 병렬로 실행할 때 발생하는 인간의 주의력 병목 문제를 해결하기 위한 터미널 다중화 도구 herdr를 소개합니다. herdr는 에이전트의 상태를 실시간으로 추적하여 사용자가 대기 중인 에이전트를 즉시 파악할 수 있도록 돕습니다.
핵심 포인트
- 에이전트 상태(blocked, working, completed)를 사이드바에 표시하여 가시성 확보
- Rust 기반의 단일 바이너리로 제공되며 tmux/zellij와 유사한 세션 관리 지원
- 에이전트 간 상호작용을 위한 CLI 및 JSON 기반 소켓 API 제공
- 인간의 역할을 구현자에서 에이전트 교통정리자로 전환하는 UI 설계
코딩 에이전트를 4개, 각각 다른 페인(pane)에서 실행하고 있다고 가정해 보자. 사양 변경을 위한 리팩터링(refactor) 1개, 테스트 작성 1개, 로그 조사 1개, 의존성 업데이트 1개. 잠시 눈을 떼고 Slack에 답장을 보낸 뒤 돌아오면, 화면 앞에서 한 가지 의문이 떠오른다. "지금 어떤 녀석이 내 답변을 기다리며 멈춰 있지?". 결국 당신은 페인을 순서대로 스크롤하며 Do you want to proceed? (y/n) 상태로 굳어 있는 녀석을 찾아야 한다.
AI를 병렬로 돌릴수록 병목이 되는 것은 계산 자원이 아니라 인간의 주의력(attention)이다. 이 점을 정면으로 설계에 반영한 것이 7월 GitHub 트렌드에 올라온 herdr이다. 제작자는 ogulcancelik이며, Rust로 제작된 단일 바이너리 형태로, 최신 버전은 v0.7.5(2026-07-21)이다. 일본어 소개는 아직 거의 없으므로, 1차 소스를 대조하여 요점을 정리해 둔다.
herdr 자체는 "터미널 다중화 도구(multiplexer)"를 표방한다. 페인을 분할하고, 세션을 디태치(detach)하여 나중에 다시 어태치(reattach)할 수 있다. SSH를 통해서도 유지되며, 터미널을 닫아도 계속 실행된다. 여기까지는 tmux나 zellij와 동일하며, 공식 문서에서도 "detach/reattach 방식은 tmux/zellij와 같은 유파"라고 인정하고 있다. 마우스 조작을 일급 시민(first-class)으로 취급하여 키 바인딩(keybind)을 외우지 않아도 시작할 수 있다는 점은 UX의 장점이지만, 본질은 아니다.
본질은 herdr가 화면의 내용을 "단순히 바이트 열이 흐르는 터미널"이 아니라, 상태를 가진 **에이전트(agent)**로 취급한다는 점에 있다. README에 따르면, 각 에이전트의 상태를 blocked(입력 대기 중 멈춤) / working(처리 중) / completed(완료)로 구분하여 사이드바에 표시한다. 서두의 "어떤 녀석이 기다리고 있지?"라는 질문에 스크롤이 아닌 목록으로 답해주는 것이다. 인간의 역할이 "구현하는 사람"에서 "여러 에이전트의 교통정리를 하는 사람"으로 옮겨가는 흐름에 UI를 맞추고 있다.
도입은 용도에 따라 선택할 수 있다. 로컬 macOS/Linux라면 원라이너(one-liner)가 빠르다.
# 설치 (둘 중 하나)
curl -fsSL https://herdr.dev/install.sh | sh
brew install herdr
...
실행 후에는 tmux 방식의 프리픽스 키(prefix key, 기본값은 ctrl+b)에 이어 q를 눌러 디태치하고, herdr를 재실행하면 원래 세션으로 돌아간다. claude나 codex는 이름으로 감지할 수 있으며, herdr integration install claude와 같이 통합을 설치할 수 있다(agent guide에서 확인 가능).
tmux에도 스크립트용 인터페이스는 있다. send-keys로 키 입력을 흘려보낼 수도 있다. 그렇다면 herdr의 무엇이 새로운가? 차이점은 에이전트를 조작하기 위한 CLI/소켓 API가 처음부터 준비되어 있다는 점에 있다. 리포지토리의 SKILL.md에는 에이전트 스스로가 다른 에이전트를 실행하여 지시를 내리기 위한 일련의 명령어가 나열되어 있다.
# 옆에 새로운 페인을 만들고, 그곳에서 에이전트를 실행한다
herdr pane split --current --direction right --cwd "$PWD" --no-focus
herdr agent start reviewer --kind <type> --pane <id>
...
응답은 모두 JSON으로 반환되며, w1:p1(워크스페이스 수식된 페인 ID)과 같은 식별자를 다음 조작에 재사용한다. 여기서 유용하게 쓰이는 것이 agent wait --until blocked이다. tmux에서 같은 일을 하려고 하면, 페인의 출력을 직접 폴링(polling)하여 "입력 대기 중인 것으로 보이는 문자열"을 정규 표현식으로 잡아내는 수동적인 모니터링 루프를 작성해야 한다. herdr는 "에이전트가 현재 어떤 상태인가"를 API의 일급 개념으로 다루고 있기 때문에, 대기(wait)를 명령어 한 줄로 표현할 수 있다. 오케스트레이터(orchestrator) 역할을 하는 에이전트가 리뷰 담당, 테스트 담당 서브 에이전트를 깨우고, 각각이 멈출 때까지 기다렸다가 다음 단계로 진행하는 재귀적인 구성을 자연스럽게 작성할 수 있다.
이 부분은 냉정하게 살펴볼 필요가 있다. blocked 여부 판정은 결국 각 에이전트 CLI의 화면 출력을 관찰하여 "입력 대기 중인 것 같다"라고 추측하는 방식이다. 즉, 감지는 본질적으로 휴리스틱(heuristic)이며, 에이전트 측의 CLI가 표시 형식을 바꾸면 오작동할 가능성이 있다.
그러한 취약성은 herdr 자신의 변경 이력에 흔적으로 남아 있다. v0.7.5에서는 래퍼(wrapper)를 통해 작동하는 에이전트라도 화면을 올바르게 감지할 수 있도록 macOS에서 HERDR_AGENT=<agent>라는 전경 프로세스(foreground process) 힌트를 수용하게 되었으며, agent prompt 대기는 상태 변화가 5초간 없으면 무한정 기다리지 않고 agent_prompt_stalled를 반환하도록 변경되었다. 이 두 가지 모두 "상태를 순순히 다 읽어내지 못하는 경우가 있다"는 점의 반증이다. 프로덕션(production)에서 무인 운용으로 전환하기 전에, 자신이 사용하는 에이전트에서 wait --until blocked가 정말로 신뢰할 수 있는지 직접 확인해 볼 가치가 있다.
또 다른 한 가지, 운영자로서 걸리는 점은 권한의 확장성이다. 에이전트가 페인(pain)을 할당하고, 다른 에이전트를 실행하며, 프롬프트(prompt)까지 보낼 수 있다는 것은 처리량(throughput)과 동시에 "폭주했을 때의 피해 범위"도 곱절로 넓어진다는 것을 의미한다. 에이전트의 스킬에 악의적인 코드가 섞일 리스크나 샌드박스화(sandboxing) 논의와 맞닿아 있는 문제로, herdr agent start를 무인 루프에 포함시킨다면 그 앞단에 승인이나 격리 계층을 두는 것을 전제로 고려해야 한다.
혼자서 하나의 에이전트와 페어를 이루고 있는 동안에는 tmux를 쓰든 zellij를 쓰든 어려움이 없다. herdr가 진가를 발휘하는 시점은 3개, 5개로 에이전트를 병행 실행하기 시작하여, "어떤 에이전트가 나를 기다리고 있는가"를 찾는 것 자체가 병목(bottleneck)이 되었을 때다. 그 단계에 도달한 사람에게 상태 표시 사이드바와 agent wait는 현재 직접 만든 스크립트로 메우고 있는 빈틈 그 자체를 채워준다.
반대로, 아직 수동으로 하나씩 돌리고 있는 단계라면 억지로 추가할 도구는 아니다. 도입 비용은 낮기 때문에(단일 바이너리, 1줄 설치), 병렬 운용으로 발을 들일 타이밍에 떠올리면 된다. 우선 herdr를 실행하여 claude를 하나 띄워보고, herdr agent list가 무엇을 반환하는지 살펴보는 것만으로도 충분하다. 이곳이 수동 폴링(polling)을 졸업하는 라인이 될 수 있을지, 당분간 직접 사용하며 판단해 보고 싶다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기