포스트

내가 모르는 사이 Hermes가 10분마다 Codex를 실행하고 있었다

며칠 동안 쓰지 않은 Hermes가 로그인과 함께 살아나 10분마다 큰 컨텍스트를 읽고 있었다. 컴퓨터 4대에서 여러 LLM을 함께 쓰다가 4.38억 토큰 기록의 원인을 늦게 발견한 과정을 정리한다.

며칠 동안 Hermes를 쓰지 않았다. 그런데 Codex 사용량이 모두 소진됐다.

처음에는 어느 컴퓨터의 어떤 도구가 사용량을 쓴 것인지 바로 알 수 없었다. 나는 컴퓨터 네 대에서 여러 LLM을 동시에 사용하고 있었다. 사용량이 줄어도 원인이 된 장비와 작업을 곧바로 좁히기 어려웠다. 그 며칠 동안 Hermes를 직접 쓰지 않았기 때문에 Hermes를 의심하지도 않았다.

문제가 생긴 Mac을 확인했더니 Hermes는 내가 직접 열지 않아도 로그인할 때 자동으로 시작됐다. 그 안에는 내가 실행 중인 줄도 몰랐던 예약 작업이 남아 있었다. 이 작업은 10분마다 Codex 세션을 새로 열었다. 그리고 작업 규칙, 작업 보드, 최근 작업일지와 저장소 상태를 다시 읽었다.

이틀 동안 확인된 루트 세션은 84개였다. 로컬 로그에 남은 입력과 출력 합계는 437,993,236토큰이었다.

가장 큰 잘못은 큰 컨텍스트를 읽고 판단해야 하는 에이전트 작업을 10분짜리 배치에 넣은 것이었다. 실행 사실을 알려주는 화면과 알림도 없었다. 나는 Hermes가 멈춰 있다고 생각했지만, 작업은 화면 밖에서 계속 돌았다.

확인한 내용 로그에서 확인한 값
예약 주기 10분
이틀 동안 생성된 루트 세션 84개 (하루 42개)
입력 토큰 436,265,354
출력 토큰 1,727,882
입력·출력 합계 437,993,236
같은 기간 작성된 작업일지 72개 (32개·40개)
확인된 커밋·푸시·PR·배포 0건

437,993,236토큰은 로컬 루트 세션 로그에 남은 입력·출력 합계다. 실제 청구량과 정확히 일치한다는 뜻은 아니며, 하위 에이전트 사용량은 빠졌을 수 있다.

왜 며칠 동안 알아채지 못했나

내 머릿속의 상태와 컴퓨터의 상태가 달랐다. 나는 Hermes를 며칠 동안 사용하지 않았으니 Hermes도 멈춰 있다고 생각했다. 실제로는 로그인할 때 게이트웨이가 자동으로 시작됐고, 그 안의 예약 작업도 살아났다.

컴퓨터 네 대에서 여러 LLM을 함께 사용한 것도 발견을 늦췄다. 어떤 장비에서는 Codex를 쓰고, 다른 장비에서는 다른 LLM 작업을 돌렸다. 사용량이 줄어드는 것만 보고는 어느 컴퓨터의 어느 도구가 원인인지 바로 알기 어려웠다. 이 환경이 예약 작업을 만든 것은 아니다. 다만 이상 징후를 평소 사용량으로 착각하게 했다.

실행 상태를 알려주는 곳도 없었다. 로그인할 때 Hermes와 10분 예약 작업이 시작됐지만 눈에 띄는 알림이나 표시가 없었다. 어느 장비와 작업이 사용량을 쓰는지도 한곳에서 볼 수 없었고, 실패나 사용량 고갈 뒤에도 예약 작업은 꺼지지 않았다.

결국 사용량이 바닥난 뒤에야 컴퓨터별 프로세스와 실행 기록을 따라가며 원인을 찾기 시작했다.

원인을 따라가 보니

실행 경로는 단순했다.

Mac 로그인 → 사용자 LaunchAgent → Hermes 게이트웨이 자동 시작 → 내가 모르고 있던 10분 예약 작업 → Codex 루트 세션 생성

Apple 문서에도 사용자 로그인 시 “a per-user launchd is started”라고 적혀 있다. 이어서 사용자 Library/LaunchAgents의 설정을 읽는다고 설명한다. (Apple, Creating Launch Daemons and Agents)

Hermes를 직접 열지 않았지만 로그인과 함께 자동으로 시작된 10분 예약 작업이 큰 컨텍스트를 반복해서 읽은 흐름

내가 Hermes를 쓰지 않는 동안에도 자동 시작과 10분 예약은 따로 움직였다. 그림을 누르면 원본 크기로 볼 수 있다.

기록을 확인했지만 외부 사용자가 원격으로 실행한 흔적은 찾지 못했다. 최초 예약 작업이 언제 어떤 명령으로 만들어졌는지도 알 수 없었다. 내가 확인한 것은 지금 무엇이 작업을 실행했고 어떻게 반복됐는지까지다.

10분 배치로 돌리면 안 되는 일이었다

10분마다 해도 되는 일은 “새 작업이 생겼는가”를 가볍게 확인하는 정도다. 파일 하나의 변경 시각이나 큐 길이를 일반 코드로 검사하면 된다. 새 후보가 없으면 모델을 부르지 않고 끝내야 한다.

그런데 이 예약 작업은 새 일이 있는지 확인하려고 매번 큰 컨텍스트를 만들었다.

  1. 전역 지침과 작업 규칙을 읽었다.
  2. 작업 보드 전체와 캐시 상태를 확인했다.
  3. 최근 작업일지 10~15개를 다시 비교했다.
  4. 저장소 잠금과 중복 작업 여부를 확인했다.
  5. 실행 가능한 일을 모델이 판단했다.
  6. 결과를 새 작업일지로 남겼다.

10분마다 담당자에게 업무 규정과 최근 일지를 처음부터 다시 읽힌 뒤 “지금 할 일이 있습니까?”라고 묻는 것과 같았다. 확인 작업보다 준비 비용이 훨씬 컸다.

OpenAI도 Codex 사용량을 설명하면서 “A long-running task can use substantially more than a short request.”라고 적고 있다. (OpenAI Help Center, Using Codex with your ChatGPT plan)

새 후보가 생겼을 때만 에이전트를 한 번 실행했어야 했다. 긴 컨텍스트를 읽는 작업에는 별도의 실행 예산과 종료 조건이 필요했다. 실행 중이라는 사실도 내가 볼 수 있어야 했다.

같은 자료를 읽고 다시 일지를 썼다

작업을 고르는 조건도 실제 보드와 맞지 않았다. 중간에 확인한 보드에는 담당 미완료 카드가 69개 있었다. 하지만 자동 선별 규칙이 요구한 입력 자료, 예상 출력, 완료 조건, 검증 절차 필드가 보드에 없었다. 어떤 카드도 규칙을 통과할 수 없는 상태였다.

감사 기록에는 이렇게 적혀 있었다.

“분자가 0이 아니라 필드가 존재하지 않는다.”

작업 조건의 불일치는 이미 실행 중이던 10분 배치의 비용을 더 키웠다. 후보를 고르지 못한 실행도 새 작업일지를 만들었다. 다음 실행은 그 일지를 다시 읽었다.

“일지가 늘수록 대조 비용만 커진다.”

작업일지는 감사와 인수인계에 필요하다. 하지만 방금 만든 작업일지를 다음 실행의 입력으로 계속 넣으면 출력이 다시 입력을 키운다. 빈 실행도 기록을 만들고, 다음 실행의 컨텍스트는 더 커졌다.

로그에는 결과물도 남아 있었다

일부 실행은 격리된 복제본에 패치와 테스트 결과를 남겼다.

작업 종류 로컬에 남은 것 전달 상태
백엔드 라우터 2파일 +55/-4, 로컬 회귀 테스트 미커밋, 실제 메시징 검증 없음
CLI 핸들러 2종 각 5파일 패치, 단위 테스트·race·vet·build 일부 통과 실제 CLI·서비스 종단 간 검증 없음
관측 UI와 조립 코드 7파일, Go·Node 테스트 브라우저·원격 환경 검증 없음
서비스 회귀 테스트 2파일 +81/-1 패치 의존성 문제로 테스트 미완주
자동화 요청 JSON 재사용 가능한 패치 2개 현행 소스에 적용하지 않음

로그에는 “로컬 패치 완료, 카드 종료 판정은 보류”, “집중 테스트는 실행 완료가 아니다”라는 기록도 남아 있었다. 이 판단은 맞다. 로컬 파일이 생긴 것과 일이 전달된 것은 다르다.

나도 이 결과물을 전달받지 못했다. 조사 범위에서 커밋, 푸시, PR, 배포까지 이어진 기록은 0건이었다. 외부 반영을 승인 없이 막은 것은 안전했지만, 검토할 패치와 한계를 나에게 알려주는 마지막 단계가 없었다.

오류가 나도 10분 뒤 다시 시작됐다

실행 기록에서는 세 가지 신호가 반복됐다.

  • 실제 작업 중에도 상태가 initializing으로 남아 600초 뒤 시간 초과로 끝났다.
  • Too many open files 오류가 발생했다.
  • 사용량이 100%에 도달한 뒤에도 다음 예약이 남았다.

원인은 달랐지만 결과는 같았다. 어떤 오류도 예약 작업을 끄지 못했다. 성공하든 실패하든 10분 뒤에 새 실행이 시작됐다. 시간 초과는 복구가 아니라 다음 재실행으로 이어졌다.

문제가 난 곳 당시 동작 필요했던 동작
예약 실패 뒤에도 다음 실행 유지 연속 실패 시 자동 중단하고 알림
상태 확인 작업 중에도 initializing 실제 도구 호출과 출력으로 상태 갱신
작업 선택 없는 필드를 모델이 계속 해석 모델 호출 전 일반 코드로 검사
입력 새 작업일지를 다음 입력에 추가 자기 작업일지 제외와 입력 크기 제한
사용량 예산 없이 계속 실행 작업별 토큰·시간·실행 횟수 제한

확인하자마자 이렇게 끊었다

원인을 확인한 뒤에는 문제를 일으킨 실행 경로만 끊었다.

  1. 예약 작업을 일시 정지했다.
  2. 실행 중인 에이전트 프로세스를 종료했다.
  3. 예약 작업 정의를 삭제했다.
  4. 부팅 자동 시작 등록을 해제했다.
  5. 작업 ID, 프로세스, 자동 시작 등록이 모두 사라졌는지 확인했다.
  6. 원인 분석에 필요한 실행 기록과 로컬 패치는 남겼다.

자동 시작 설정은 복구할 수 있도록 휴지통으로 옮겼다. 다른 예약 작업과 Hermes 데이터까지 한꺼번에 지우지는 않았다.

다시 만든다면 10분 작업은 감시만 하게 한다

10분 배치가 모델을 직접 부르면 안 된다. 10분 작업은 새 후보가 생겼는지만 값싸게 확인하고 끝내야 한다.

10분 작업은 새 후보만 확인하고 큰 컨텍스트를 읽는 에이전트는 필요할 때 한 번만 실행하는 개선 흐름

새 후보가 없으면 모델을 부르지 않는다. 후보가 있을 때만 예산을 정해 한 번 실행하고, 결과나 실패를 나에게 알린 뒤 끝낸다.

이미 끝낸 조치는 예약 작업 삭제와 자동 시작 해제다. 아래 항목은 다시 자동화를 만들 때 적용할 원칙이며, 아직 구현을 마쳤다는 뜻은 아니다.

다시 만든다면 10분 작업은 작업 카드 스키마와 새 후보 수만 일반 코드로 확인한다. 후보가 없으면 LLM을 부르지 않고, 후보가 생기면 내가 볼 수 있는 곳에 먼저 표시한다. 큰 컨텍스트는 그때 한 번만 읽히고 입력 크기도 제한한다.

실행마다 토큰, 시간, 도구 호출 횟수의 상한을 두고 같은 작업은 한 번에 하나만 돌린다. 시간 초과, 사용량 고갈, 파일 한도, 연속 실패가 발생하면 예약을 끄고 알린다. 성공했다면 패치와 테스트 결과, 남은 한계를 나에게 전달한다. 어느 장비와 작업이 사용량을 썼는지도 한 화면에서 확인할 수 있게 한다.

확인하지 못한 부분

로그를 확인하고도 모르는 것이 남았다.

  • 최초 예약 작업을 만든 사람이나 명령은 기록이 없어 특정하지 못했다.
  • 로컬 로그의 토큰 합계와 실제 청구량의 관계는 확인하지 못했다.
  • 하위 에이전트 사용량은 합계에서 빠졌을 수 있다.
  • 모든 실행이 얼마나 유효했는지는 전수 검증하지 않았다.
  • 작업일지 재입력이 전체 사용량에서 차지한 비율은 계산하지 않았다.
  • 발견한 로컬 패치가 최신 원격 코드에도 그대로 유효한지는 확인하지 않았다.

그래서 이 일을 “모든 실행이 공회전했다”, “4.38억 토큰이 그대로 과금됐다”, “Codex 자체의 버그였다”라고 말하지 않는다. 내가 확인한 사실은 모르는 사이 살아 있던 10분 예약 작업이 큰 컨텍스트를 반복해서 읽었고, 멈출 조건과 알림이 없었다는 것이다.

내가 가장 크게 잘못 본 지점

이번에 가장 크게 잘못 본 부분은 모델보다 실행 방식이었다. Hermes를 직접 사용하지 않았으니 멈춰 있을 것이라고 생각했다. 그 10분 주기 안에는 가벼운 확인이 아니라 큰 컨텍스트를 읽고 판단하는 일이 들어 있었다.

컴퓨터 네 대와 여러 LLM을 함께 쓰면서 사용량의 출처도 한눈에 보지 못했다. 자동화가 조용히 실행되는 환경에서 “내가 지금 쓰고 있지 않다”는 감각은 아무런 안전장치가 되지 못했다.

앞으로 10분 작업에는 새 일이 있는지만 확인시킬 생각이다. 실제 에이전트는 내가 볼 수 있는 곳에서 시작하고, 토큰과 시간의 한도를 정한다. 성공하든 실패하든 반드시 나에게 알려준 뒤 끝나게 해야 한다.

확인 방법과 출처

위 숫자는 내가 예약 작업 정의와 실행 기록, 사용량 기록, 작업일지와 오류 로그를 맞춰 보며 집계했다. 원본에는 공개할 수 없는 프로젝트 정보가 있어 이 글에는 익명화한 합계와 직접 만든 흐름도만 실었다.

외부 동작 설명은 다음 문서를 확인했다.

  1. Apple, Creating Launch Daemons and Agents.
  2. OpenAI, Using Codex with your ChatGPT plan.

대표 이미지는 AI로 생성했고, 흐름도는 실제 실행 기록을 바탕으로 직접 만들었다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.