Thesis
Hermes Joe는 실행자가 아니라 판단 계층(control plane)이고, Slack은 감사 가능한 운영 표면이다.
1. 모든 것이 Hermes로 들어오지만 Hermes가 모든 것을 실행하지 않는다
먼저 등장인물을 정리하자. Hermes는 운영이 모이는 에이전트 시스템이고, Joe는 그 안에서 Slack으로 대화하는 에이전트다. Joon은 지시하는 사람, 즉 나다.
밖에서 보면 이 구조는 “도구가 많은 챗봇”처럼 보일 수 있다. Slack에서 Joon이 지시하고, Joe가 답하고, Codex나 Happy가 작업하고, Kanban에 상태가 남고, Sentry와 Grafana가 알림을 보낸다. 그러나 이 구조의 핵심은 도구의 수가 아니다. 판단과 실행을 분리하는 control plane이다.
Joe의 역할은 실행자가 아니라 판단 계층이다. 요구사항을 완료 기준으로 바꾸고, 어떤 lane이 맞는지 정하고, 필요한 skill과 기억 계층을 불러오고, 작업자에게 실행을 넘기고, 원천 증거로 결과를 검증한다. 직접 shell을 잡고 해결하는 경우도 있다. 그때도 핵심은 변하지 않는다. “무엇이 완료인가”를 정의하고 “무엇으로 증명되는가”를 확인하는 일이다.
이 분리는 에이전트 운영의 안전장치다. 실행자가 판단자까지 겸하면 자기 보고가 곧 완료가 된다. 반대로 control plane이 있으면 실행자는 작업하고, Joe는 증거를 보고, Slack은 그 판단의 감사 표면이 된다.
2. Slack thread는 감사 단위다
Slack은 이 구조의 가장 바깥쪽 운영 표면이다. 그러나 일반적인 챗봇 대화창과는 다르다. Slack thread는 작업의 작은 감사 단위다. 요청, 판단, 실행 위임, 실패, 재시도, 최종 증거가 같은 흐름에 남아야 한다.
예를 들어 Sentry 사건이 올라오면 중요한 것은 “알림이 왔다”가 아니다. 그 알림에서 어떤 issue가 생겼는지, Joe가 어떤 추가 근거를 봤는지, Kanban 작업이 생겼는지, Codex lane이 실행됐는지, 최종적으로 어떤 commit·test·log로 닫혔는지가 한 스레드에서 이어져야 한다. Voice Memory도 마찬가지다. 녹음 요약이 올라오고 Joon이 코멘트를 달면, 그 스레드는 후처리 루프의 입력 표면이 된다.
스레드를 감사 단위로 보면, cross-posting과 정상 상태 소음이 위험해진다. 같은 사건이 여러 채널에 흩어지면 원인과 결론이 분리된다. 정상이라는 메시지가 계속 올라오면 정작 중요한 실패가 묻힌다. Slack 운영 표면의 품질은 메시지 수가 아니라 스레드의 추적 가능성으로 판단한다.
3. Joe judgment layer의 일
Joe는 모든 도구를 다루는 슈퍼 실행자가 아니다. Joe의 일은 judgment layer로 정리할 수 있다.
| 판단 영역 | Joe가 하는 일 | Joe가 하지 말아야 할 일 |
|---|---|---|
| 요구사항 해석 | Joon의 지시를 완료 기준과 제약으로 바꾼다 | 애매한 목표를 마음대로 확장하지 않는다 |
| lane 선택 | Codex, Happy, Kanban, 직접 검증 중 맞는 경로를 고른다 | 모든 일을 한 대화 턴에서 억지로 처리하지 않는다 |
| 근거 수집 | diff, test, log, dashboard, thread를 본다 | 작업자 자기 보고만 믿지 않는다 |
| 승인 경계 | 배포, DB, secret, 광고 변경을 사람 결정으로 올린다 | 되돌리기 어려운 변경을 독단 실행하지 않는다 |
| 최종 보고 | “다 했다”가 아니라 “무엇으로 증명된다”를 말한다 | 성공 분위기만 만들지 않는다 |
이 레이어가 없으면 에이전트 시스템은 빠르게 느슨해진다. 작업자가 성공이라고 말하면 성공이 되고, webhook이 200을 반환하면 연결된 것으로 착각하고, secret 값이 보이면 권한이 충분하다고 오해한다. Joe는 이런 착각을 끊고 운영 증거로 되돌리는 역할을 한다.
4. Memory, Skills, Session Search, Hindsight를 섞지 않는다
Control plane에는 기억이 필요하다. 그러나 기억을 하나의 저장소처럼 뭉뚱그리면 금방 오염된다. Hermes 구조에서는 기억 계층을 구분한다.
flowchart LR Current["현재 Slack/Hermes 대화"] Current --> Memory["Hermes Memory<br/>작고 안정적인 포인터"] Current --> Skills["Skills / Runbooks<br/>반복 가능한 절차"] Current --> Sessions["Session Search<br/>과거 대화와 결정"] Current --> Hindsight["Hindsight<br/>의미 기반 근거 색인"] Current --> Work["작업 산출물<br/>Git · Kanban · 로그 · 문서"] Hindsight --> Work
Memory에는 오래 남을 선호, 안전 경계, 안정적인 진입점만 들어간다. Skills에는 절차가 들어간다. Session Search는 과거 대화와 결정을 찾는다. Hindsight는 의미 기반 검색으로 원천 산출물을 가리키는 포인터 역할을 한다. 작업 로그, 일회성 PR 번호, 완료 보고, 임시 상태를 Memory에 욱여넣으면 미래의 판단이 오염된다.
Joe가 control plane으로 안정적으로 작동하려면 “무엇을 기억할지”만큼 “무엇을 기억하지 않을지”가 중요하다. 모든 것을 기억하는 에이전트는 똑똑해지는 게 아니라 오래된 근거에 끌려다닌다.
5. Approval boundary는 자동화의 적이 아니다
승인 경계는 자동화를 느리게 만드는 장치가 아니라 자동화를 믿을 수 있게 만드는 장치다. Hermes/Joe의 운영에서 명시 승인 없이 넘지 않는 경계는 분명하다. 운영 배포, DB 변경, 비밀값 출력, 실제 광고 예산·캠페인 변경, 파괴적 인프라 작업은 사람이 결정한다.
이 경계가 있다고 해서 에이전트가 쓸모없어지는 것은 아니다. 오히려 역할이 또렷해진다. Joe는 상태를 확인하고, 위험을 설명하고, 선택지를 좁히고, 되돌림 방법과 증거를 제시한 뒤 사람에게 결정을 올린다. 결정 전까지 가능한 읽기, 분석, 초안 작성, 테스트, 재현, 영향 범위 추정은 자동화할 수 있다.
좋은 control plane은 “모두 자동 실행”을 목표로 하지 않는다. 읽기와 판단과 실행과 승인을 분리한다. 이 분리 덕분에 에이전트가 더 많은 일을 안전하게 맡을 수 있다.
6. Pitfall: Slack을 채팅창으로만 쓰면 증거가 사라진다
가장 흔한 실패는 Slack을 질문과 답변의 장소로만 쓰는 것이다. “이거 해줘”, “완료했다”, “고마워”가 흘러가고 끝난다. 이러면 나중에 사건을 복기할 수 없다. 어떤 파일이 바뀌었는지, 테스트는 무엇이었는지, 실패한 webhook은 어떤 payload였는지, 누가 어떤 결정을 했는지를 다시 찾기 어렵다.
반대 방향의 실패도 있다. 모든 것을 Slack에 올리는 것이다. 정상 heartbeat, 잡다한 cron 성공, 의미 없는 OK 메시지가 쌓이면 사람은 채널을 무시하게 된다. 그러다 진짜 실패도 함께 묻힌다. Slack이 운영 표면이 되려면 메시지는 적고, 스레드는 깊고, 증거는 한 흐름에 남아야 한다.
Slack thread를 감사 단위로 쓰는 순간, 에이전트의 언어도 바뀐다. “완료”가 아니라 “변경점은 이것이고, 테스트는 이것이며, 남은 위험은 이것이다”가 된다. 이 차이가 control plane의 품질을 만든다.
7. Control plane spec block
control_plane: Hermes Joe
primary_surface: Slack thread
role:
- interpret_request
- select_execution_lane
- call_skills_and_memory_layers
- delegate_execution
- verify_primary_evidence
- report_decision_or_result
execution_lanes:
- Codex CLI lane
- Happy lane
- Hermes Kanban worker
- direct read-only diagnostics
memory_layers:
memory: stable preferences, safety boundaries, entry points
skills: reusable procedures and runbooks
session_search: previous conversations and decisions
hindsight: semantic index and source pointers
approval_boundaries:
- production deployment
- database mutation
- secret value disclosure
- real ad budget or campaign change
- destructive infrastructure action
evidence_required:
- diff_or_artifact
- test_or_check_output
- log_or_dashboard_reference
- slack_thread_summary
이 spec은 구현 코드가 아니라 운영 계약이다. Joe가 무엇을 판단하고, 무엇을 위임하고, 무엇을 증거로 요구하며, 어디서 멈춰야 하는지를 한눈에 보여준다.
8. 운영 규칙
- Slack thread를 작업과 사건의 감사 단위로 사용한다.
- Joe는 실행자가 아니라 요구사항 해석, lane 선택, 검증, 승인 경계 판단을 맡는다.
- 작업자 자기 보고는 검토 시작 신호이지 완료 증거가 아니다.
- Memory에는 안정적인 포인터만 넣고, 절차는 Skills, 과거 대화는 Session Search, 의미 기반 근거는 Hindsight로 분리한다.
- 정상 상태는 Slack에 반복 게시하지 않는다.
- 위험한 변경은 에이전트가 분석과 제안까지만 하고, 사람 승인 전에는 넘지 않는다.
- 최종 보고는 “무엇을 했다”보다 “무엇으로 증명된다”를 중심으로 쓴다.
다음 글 제안
다음 글은 /writing/observable-surface/event-driven-agent-ops/로 이어진다. Control plane이 어디서 판단하는지를 정했다면, 다음 문제는 언제 에이전트를 깨울 것인가다. 계속 확인하는 운영을 버리고 사건 기반으로 바꾸는 방법을 다룬다.