ClOr

ClOr

백엔드 실무 트러블슈팅과 AI 에이전트 구조 분석을 기록합니다.

Claude Code 해부학 (완결)

51만 줄 소스코드를 19편에 걸쳐 분석한 완결 시리즈

전체 시리즈 보기 →

백엔드 트러블슈팅

실무에서 겪은 장애와 해결 과정 기록

전체 시리즈 보기 →

최신 글

article thumbnail

Claude Code 소스코드 유출에서 가장 많이 참조된 피처 플래그가 있다. 150회 이상 등장하는 KAIROS. 그리스어로 "적절한 순간"이라는 뜻이다.

KAIROS는 Claude Code를 항상 켜져 있는 자율 에이전트로 바꾸는 미출시 기능이다. 터미널을 닫아도 돌아가고, 밤새 메모리를 정리하고, PR이 올라오면 알아서 반응한다. Boris Cherny(Claude Code 책임자)가 Substack 댓글에서 "현재 테스팅 중이며 곧 출시될 기능"이라고 언급한 바 있다.

기존 AI 코딩 도구는 전부 리액티브다. 시키면 한다. KAIROS는 프로액티브다. 스스로 할 일을 찾는다.

이 글에서는 KAIROS의 핵심 메커니즘 — Tick Engine, SleepTool, autoDream, 전용 도구 — 을 소스코드 기반으로 해부한다.

목차

  • Tick Engine — 스스로 깨어나는 심장박동
  • SleepTool — 자는 것도 전략이다
  • 15초 블로킹 버짓
  • 터미널 포커스 인식
  • 전용 도구 5가지
  • autoDream — 밤새 메모리를 정리하는 4단계
    • 3-Gate 트리거
    • 4단계 Dream Cycle
  • Append-Only 로그 — 지울 수 없는 기록
  • Daemon Mode와의 관계
  • 다른 백그라운드 에이전트와 비교
  • 요약

Tick Engine — 스스로 깨어나는 심장박동

KAIROS의 핵심은 Tick Engine이다. 일반 Claude Code는 사용자 입력을 기다린다. KAIROS는 기다리지 않는다.

메시지 큐가 비면, setTimeout(0)으로 <tick> 메시지를 스스로 주입한다.

const scheduleProactiveTick = feature('PROACTIVE') || feature('KAIROS')
  ? () => {
      setTimeout(() => {
        if (!proactiveModule?.isProactiveActive() || 
            proactiveModule.isProactivePaused() || inputClosed) return
        const tickContent = 
          `<${TICK_TAG}>${new Date().toLocaleTimeString()}</${TICK_TAG}>`
        enqueue({ 
          mode: 'prompt', value: tickContent, 
          priority: 'later', isMeta: true 
        })
        void run()
      }, 0)
    }
  : undefined

핵심 설계가 몇 가지 보인다.

zero-delay timer. setTimeout(0)이라 이벤트 루프에 양보한다. 사용자가 메시지를 보내면 그게 먼저 처리되고, tick은 뒤로 밀린다. 자율 행동이 사용자 입력을 절대 선점하지 않는다.

시간 정보 포함. tick에 사용자 로컬 시간이 들어간다. "새벽 3시에 CI 감시를 시작할까?"같은 timezone-aware 판단이 가능하다.

모델의 해석. 모델은 tick을 "너 깨어있어, 지금 뭐 할 거야?"라는 프롬프트로 받아들인다. 대화 히스토리를 보고 CI 감시, 실행 중인 명령, 미해결 스레드 등 할 일이 있으면 tool call로 응답한다.

SleepTool — 자는 것도 전략이다

할 일이 없으면? 모델은 반드시 SleepTool을 호출해야 한다.

시스템 프롬프트에 이런 지시가 있다:

"If you have nothing useful to do on a tick, you MUST call Sleep. Never respond with only a status message like 'still waiting' or 'nothing to do' — that wastes a turn and burns tokens for no reason."

"아직 기다리는 중입니다" 같은 응답은 금지다. API 콜 1회 비용만 날리니까.

여기서 재밌는 트레이드오프가 나온다.

상황 결과
너무 자주 깨면 API 콜 비용 누적
너무 오래 자면 프롬프트 캐시 만료 (5분), 재구축 비용 발생

소스코드에 따르면 프롬프트 캐시는 약 5분 비활성 후 만료되는 것으로 설계되어 있다. 캐시가 날아가면 다음 wake-up에서 전체 컨텍스트를 다시 로드해야 한다. 그래서 KAIROS는 모델에게 직접 이 비용을 밸런싱하라고 시킨다. 얼마나 자주 깨고 얼마나 오래 잘지를 AI가 판단한다.

15초 블로킹 버짓

KAIROS가 돌아가는 동안 명령이 15초 이상 걸리면?

const ASSISTANT_BLOCKING_BUDGET_MS = 15_000

if (feature('KAIROS') && getKairosActive() && isMainThread && 
    !isBackgroundTasksDisabled && run_in_background !== true) {
  setTimeout(() => {
    if (shellCommand.status === 'running' && 
        backgroundShellId === undefined) {
      assistantAutoBackgrounded = true
      startBackgrounding(/* ... */)
    }
  }, ASSISTANT_BLOCKING_BUDGET_MS).unref()
}

자동으로 백그라운드로 넘긴다. .unref()가 붙어서 이 타이머가 Node 프로세스를 살려두지도 않는다. 사용자 워크플로우를 절대 차단하지 않겠다는 설계다.

터미널 포커스 인식

KAIROS는 터미널이 포커스 상태인지도 안다.

상태 행동
비포커스 독립적 결정 최대화. 되돌릴 수 없는 작업만 일시중지
포커스 협업 증가. 주요 커밋 전에 옵션 제시

사용자가 터미널을 보고 있으면 "이거 커밋할까요?" 물어보고, 안 보고 있으면 알아서 처리하되 위험한 건 멈춘다.

전용 도구 5가지

일반 Claude Code에는 없는 KAIROS 전용 도구다.

도구 기능
PushNotification 터미널을 닫아도 모바일로 알림 전송
SendUserFile 생성한 파일을 사용자에게 직접 전달
SubscribePR GitHub PR을 실시간 웹훅으로 모니터링
SleepTool 지정 시간 동안 데몬 일시중지
BriefTool 사용자 대면 출력 전용 채널

BriefTool이 특히 흥미롭다. 모든 사용자 대면 출력이 이걸 통해서 나간다. status 필드에 "normal"(사용자 발의)과 "proactive"(자율 업데이트) 구분이 있다.

렌더링도 3단계다:

  • Brief-only: BriefTool + 사용자 입력만 표시
  • Default: BriefTool 호출 시 중복 텍스트 삭제
  • Transcript (ctrl+o): 필터 없는 전체 표시

백그라운드에서 뭘 하는지 궁금하면 ctrl+o로 전체 로그를 볼 수 있다.

autoDream — 밤새 메모리를 정리하는 4단계

KAIROS의 가장 인상적인 부분이다. UC Berkeley의 "Sleep-time Compute" 논문(arXiv:2504.13171)에 이론적 기반을 둔다. 유휴 시간에 미리 연산하면 테스트 타임 컴퓨트를 5배 절감하고, 정확도를 최대 18% 올릴 수 있다는 연구다.

3-Gate 트리거

autoDream은 아무 때나 돌지 않는다. 세 조건이 동시에 충족되어야 한다.

Gate 조건 기본값
Time 마지막 dream 이후 경과 시간 24시간
Session 누적 세션 수 5개
Lock 배타적 파일 잠금 PID 기반

24시간 이내거나, 세션이 5개 미만이면 실행하지 않는다. Lock은 두 dream이 동시에 돌지 않게 막는다.

4단계 Dream Cycle

Phase 1: Orient (방향 잡기)

메모리 디렉토리를 스캔한다. MEMORY.md 인덱스를 읽고, 기존 토픽 파일을 확인해서 중복을 방지한다.

Phase 2: Gather Signal (신호 수집)

우선순위 순서대로 3가지 소스에서 수집한다:

  1. 일별 append-only 로그 (logs/YYYY/MM/YYYY-MM-DD.md)
  2. 현재 코드베이스와 모순되는 기존 메모리
  3. JSONL 세션 트랜스크립트에 대한 타겟 grep 검색

전체 읽기는 금지다. 사용자 교정, 선호도 변경, 중요 결정, 반복 패턴만 포착한다.

Phase 3: Consolidate (통합)

새 신호를 기존 토픽에 병합한다. 핵심 규칙이 있다: 상대 날짜를 절대 날짜로 변환한다. "어제 Redis 쓰기로 함" → "2026-03-15 Redis 쓰기로 결정". 모순된 사실은 삭제하고, 삭제된 파일을 참조하는 디버깅 노트도 제거한다.

Phase 4: Prune & Index (정리)

MEMORY.md200줄 이하, 25KB 이하로 유지한다. 항목당 150자 이하 한 줄 설명. 오래된 포인터는 제거하고, 상세 내용은 토픽 파일로 강등한다.

실제 성능은? 커뮤니티 테스트에서 913개 세션을 약 8~9분에 통합한 사례가 보고됐다.

안전장치도 철저하다. autoDream은 bash 읽기 전용 접근만 허용되고, 쓰기는 ~/.claude/projects/<project>/memory/에만 가능하다. 소스 코드, 설정, 테스트 파일은 건드리지 않는다.

Append-Only 로그 — 지울 수 없는 기록

KAIROS의 세션은 영속적이다. 로그는 logs/YYYY/MM/YYYY-MM-DD.md 경로에 날짜별로 쌓인다.

시스템 프롬프트에 이런 지시가 있다:

"Do not rewrite or reorganize the log — it is append-only. A separate nightly process distills these logs into MEMORY.md and topic files."

에이전트가 자신의 히스토리를 조용히 삭제할 수 없다. 데이터베이스의 Write-Ahead Log와 같은 패턴이다. 감사 추적이 보장된다.

야간에 별도의 /dream 프로세스가 이 로그를 토픽 파일과 MEMORY.md로 증류한다. 로그는 원본 그대로 남는다.

Daemon Mode와의 관계

KAIROS는 Daemon Mode의 진화형이다.

claude --bg <prompt>          # 백그라운드 세션 생성
claude daemon ps              # 백그라운드 세션 목록
claude daemon logs <id>       # 세션 출력 보기
claude daemon attach <id>     # 세션 재연결
claude daemon kill <id>       # 세션 종료

Daemon Mode는 이미 BG_SESSIONS 플래그로 백그라운드 실행을 지원한다. tmux에서 터미널을 닫아도 세션이 유지된다.

KAIROS는 이 위에 Tick Engine + SleepTool + 프로액티브 행동을 올린 것이다.

Daemon Mode KAIROS
실행 수동 (claude --bg) 자율 (tick loop)
행동 시킨 것만 함 스스로 판단
수면 없음 SleepTool로 비용 최적화
메모리 세션 단위 4계층 + autoDream
알림 없음 모바일 푸시

Feature flag 관계도 명확하다. feature('KAIROS')는 영속 세션 전체를 게이트하고, feature('PROACTIVE')는 기본 tick loop를 활성화한다. 두 플래그 모두 true여야 완전한 기능이 동작한다.

다른 백그라운드 에이전트와 비교

KAIROS를 OpenAI Codex, Devin과 비교하면 핵심 차이가 드러난다.

KAIROS Codex Devin
실행 환경 로컬 터미널 데몬 클라우드 우선 클라우드 자율
행동 모델 프로액티브 (스스로 판단) 리액티브 (작업 할당) 리액티브 (작업 할당)
메모리 4계층 + autoDream 세션 기반 세션 기반
알림 모바일 푸시 웹 UI Slack/웹
항상 켜짐 O (데몬 모드) X X
PR 모니터링 O (SubscribePR) X 제한적
비용 최적화 SleepTool + 캐시 밸런싱 고정 비용 사용 시간 기반

핵심: Codex와 Devin은 "작업을 할당하면 실행"하는 리액티브 모델이다. KAIROS는 스스로 할 일을 찾아 실행하는 프로액티브 모델이다.

로컬 실행이라는 점도 중요하다. 코드가 클라우드로 올라가지 않는다. 대신 항상 켜져 있으려면 머신이 켜져 있어야 한다는 제약이 있다.

요약

  • KAIROS는 Claude Code를 항상 켜져 있는 자율 에이전트로 바꾸는 미출시 기능이다
  • Tick Engine이 매 순간 "지금 할 일이 있나?" 확인하고, 없으면 SleepTool로 비용을 아낀다
  • autoDream은 24시간 + 5세션 조건 충족 시 4단계로 메모리를 정리한다 — 913개 세션을 8분에 통합
  • Append-only 로그로 에이전트가 자기 기록을 삭제할 수 없다
  • PushNotification, SubscribePR 등 전용 도구 5가지로 터미널 밖에서도 동작한다
  • Codex/Devin이 리액티브라면, KAIROS는 프로액티브 — 시키지 않아도 일한다

관련글:

profile

ClOr

@ClOr

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

ClOr · 백엔드 트러블슈팅과 AI 에이전트 구조 분석을 기록합니다.