본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 30. 20:51

Claude를 자율 에이전트(Autonomous Agent)로 실행하는 방법: 루프, 메모리, 스케줄 및 가드레일

요약

Claude를 자율 에이전트로 운영하기 위한 루프, 메모리, 스케줄, 가드레일의 4가지 핵심 요소를 다룹니다. 각 실행이 독립적인 컨텍스트를 갖는 한계를 극복하기 위해 디스크 기반의 메모리 재구성 패턴과 샌드박스 환경을 통한 안전한 실행 방법을 제시합니다.

핵심 포인트

  • 자율 에이전트는 상태 읽기, 결정, 행동, 기록의 루프 구조를 가짐
  • 메모리 관리는 매 실행 시 디스크에서 상태를 로드하여 컨텍스트를 재구성하는 것이 핵심
  • cron이나 작업 러너를 활용한 주기적 스케줄링이 상시 가동 프로세스보다 효율적
  • 샌드박스 및 도구 허용 목록을 통해 에이전트의 폭주를 막는 가드레일 필수

대부분의 사람들은 한 번에 하나의 프롬프트(Prompt)로 Claude를 사용합니다. 하지만 흥미로운 영역은 무인(unattended) 운영입니다. 즉, 정해진 스케줄에 따라 깨어나서 지난번의 노트를 읽고, 도구(Tools)를 사용하여 실제 작업을 수행하며, 배운 내용을 기록한 뒤, 사용자가 돌보지 않아도 며칠 또는 몇 주 동안 다시 잠드는 에이전트입니다.

우리는 프로덕션 환경에서 Claude를 이런 방식으로 실행합니다. 즉, 샌드박스 컨테이너(Sandboxed container) 내부에서 작동하는 장기 실행 에이전트(Long-lived agent)로 운영합니다. 따라서 이 가이드는 단순한 사고 실험이 아니라 실제로 유효한 패턴을 다룹니다. 이 가이드는 모든 자율적인 Claude 설정에 필요한 네 가지 요소인 루프(Loop), 메모리(Memory), 스케줄(Schedule), 그리고 **가드레일(Guardrails)**을 다룹니다.

요약 (TL;DR)

  • 자율 에이전트는 하나의 **루프(Loop)**입니다: 상태 읽기 → 결정 → 도구로 행동 → 상태 기록 → 반복.
  • 메모리(Memory)가 가장 어려운 부분입니다. 각 세션은 새로 시작되므로, 에이전트는 상태를 디스크(또는 저장소)에 영구적으로 저장하고 매 실행 시작 시 _컨텍스트를 재구성(Reconstruct context)_해야 합니다. 메모리가 없다면 같은 행동을 반복하는 기억상실증 환자와 같습니다.
  • cron, systemd 타이머 또는 작업 러너(Job runner)를 사용하여 **스케줄을 지정(Schedule it)**하세요. 짧은 주기의 스케줄링된 실행이 하나의 거대한 상시 가동 프로세스보다 낫습니다.
  • 가드레일(Guardrails)은 타협할 수 없는 요소입니다: 샌드박스, 허용 목록(Allow-listed) 도구, 강제 중단 조건, 그리고 에이전트가 느낌(Vibes)이 아닌 현실을 보고하도록 하는 "허위 사실 생성 금지(No fabrication)" 규칙이 필요합니다.

핵심 루프 (The core loop)

유행어를 걷어내고 보면, 자율 에이전트는 중간에 두뇌가 있는 while 루프와 같습니다:

loop:
  1. RECONSTRUCT  — 지난 실행으로부터 메모리/상태 로드
  2. ORIENT       — 목표는 무엇인가, 이미 완료된 것은 무엇인가, 다음 단계는 무엇인가
...

여러분은 Claude Code CLI를 헤드리스(Headless) 모드로 사용하거나 Anthropic SDK를 사용하여 이를 구동할 수 있습니다. 헤드리스 CLI는 마찰이 가장 적은 옵션입니다. 하나의 명령으로 도구가 이미 연결된 상태에서 전체적인 추론-행동-관찰(Reason-act-observe) 사이클을 수행할 수 있습니다:

claude -p "$(cat ./agent/task.md)" \
  --output-format json \
  --max-turns 40 \
...

-p는 단일 비대화형 프롬프트를 실행하며, --max-turns는 도구 사용 왕복(Round-trips) 횟수를 제한합니다(기본적인 폭주 방지책). JSON 출력은 스크립트가 다음 단계를 위해 파싱할 수 있는 데이터를 제공합니다.

메모리 (Memory): "건망증 환자"가 아닌 "자율적"인 존재로 만드는 요소

여기에 함정이 있습니다. 각 에이전트 호출은 **새로운 컨텍스트 윈도우 (fresh context window)**입니다. 어제의 실행 결과 중 그 어떤 것도 자동으로 이어지지 않습니다. 메모리 문제를 해결하지 않으면, 당신의 "자율 에이전트 (autonomous agent)"는 동일한 사실을 다시 발견하고, 동일한 작업을 반복하며, 당신이 이미 내린 결정을 다시 내리게 됩니다.

효과적인 패턴은 다음과 같습니다: 메모리는 디스크에 저장되며, 에이전트의 매 실행 시 첫 번째 작업은 이를 읽는 것입니다.

단순하고 지속 가능한 레이아웃:

agent/
  MEMORY.md        # 지속적인 사실, 결정 사항, "이 사항들은 다시 논쟁하지 말 것"
  state.json       # 구조화된 현재 상태 (완료된 작업, 대기 중인 작업)
...

그런 다음 프롬프트의 첫 번째 지침으로 재구성(reconstruction)을 설정하십시오:

# task.md
다른 무엇을 하기 전에:
1. agent/MEMORY.md와 agent/state.json을 읽으십시오.
...

메모리가 부패하는 것을 방지하는 두 가지 원칙:

  • 하나의 사실에는 하나의 저장소만. 모든 결정/결과는 단 하나의 정식(canonical) 장소를 가져야 합니다. 동일한 사실을 다섯 개의 파일에 흩뿌려 놓으면 파일 간의 정보가 불일치하는 것이 보장됩니다.
  • 단순한 행동이 아닌 _결정(decisions)_을 기록하십시오. "Y 때문에 접근 방식 X를 중단함"은 "명령어 Z를 실행함"보다 훨씬 가치가 높습니다. 이는 에이전트가 다음 실행 시 이미 해결된 문제를 다시 논쟁하는 것을 방지합니다.

더 큰 규모의 설정에서는 동일한 아이디어를 벡터 스토어 (vector store)나 에이전트가 의미론적으로 검색할 수 있는 노트 인덱스로 확장할 수 있습니다. 하지만 단순한 마크다운 (markdown) 파일만으로도 놀라울 정도로 멀리 갈 수 있으며 디버깅도 용이합니다.

스케줄링 (Scheduling): 항상 켜두는 것보다 cron이 낫다

하나의 무한 프로세스를 실행할 수도 있지만, 이는 취약합니다. 충돌(crash)이 발생하면 모든 것을 잃게 되고, 오래 지속된 컨텍스트는 표류(drift)하게 됩니다. 견고한 패턴은 **디스크로부터 상태를 재구성하는 여러 번의 짧은 예약 실행 (scheduled runs)**입니다.

매시간 에이전트를 실행하는 cron 항목:

# minute hour * * *  — 매시 정각
0 * * * * cd /opt/agent && ./run.sh >> /opt/agent/log/cron.log 2>&1

...여기서 run.sh는 루프 본문입니다:

#!/usr/bin/env bash
set -euo pipefail

...

systemd가 있는 시스템에서는 cron보다 타이머 (timer)가 더 관찰 가능합니다 (systemctl status, 로깅, 그리고 쉬운 활성화/비활성화 가능):

# /etc/systemd/system/claude-agent.timer
[Unit]
Description=Run the Claude agent hourly
...

각 실행은 독립적이며 디스크에서 상태 (state)를 읽어오기 때문에, 단 한 번의 실행 실패는 해롭지 않습니다. 다음 실행이 현재 상태에서 작업을 이어갑니다.

도구 사용 (Tool use): 손을 부여하되, 최소한으로 유지하라

말만 할 수 있는 에이전트는 챗봇 (chatbot)입니다.
_행동_할 수 있는 에이전트에게는 도구 (tools)가 필요합니다. 셸 (shell), HTTP, 파일 입출력 (file I/O), 혹은 데이터베이스 클라이언트 (database client) 등이 필요할 수 있습니다. Claude Code는 파일 편집, 셸, 검색 기능을 기본적으로 제공하며, MCP (Model Context Protocol) 서버를 통해 사용자 정의 기능(검색 인덱스, 내부 API, 배포 훅 등)을 추가하여 확장할 수 있습니다.

도구 목록보다 더 중요한 원칙은 다음과 같습니다: 업무를 완수하는 데 필요한 최소한의 도구만 노출하고, 안전한 도구들만 허용 목록 (allow-list)에 포함하십시오. 그래야 에이전트가 git status 같은 명령에서 권한 승인을 위해 멈춰 서지 않으면서도, 파괴적인 작업에 대해서는 통제 (gated)를 받을 수 있습니다.

# 읽기 전용 / 안전한 명령을 사전 승인합니다. 그 외의 모든 것은 여전히 프롬프트(prompt)를 띄우거나 거부됩니다.
claude -p "$(cat task.md)" \
  --allowedTools "Bash(git status),Bash(npm test),Read,Grep" \
...

가드레일 (Guardrails): 대부분의 자율 설정이 실패하는 지점

가드레일 없는 자율성은 대담한 것이 아니라, 리스크 (liability)입니다. 그 자리를 차지할 만한 가치가 있는 네 가지 요소는 다음과 같습니다:

  1. 전체를 샌드박스(Sandbox)화 하세요. 에이전트를 읽기 전용 루트(read-only root), 작업 디렉토리만 마운트된 상태, 그리고 기본 거부(default-deny) 네트워크(모델 API와 사용자의 레지스트리만 허용 목록에 추가)를 갖춘 컨테이너에서 실행하세요. 자율성을 부여할 계획이라면, 그 영향 범위(blast radius)가 사용자의 기기가 아닌 컨테이너 내로 한정되는 곳에서 수행해야 합니다. (Claude Code의 샌드박스화에 관한 별도의 글에서 이 과정에 대한 전체 가이드를 작성했습니다.)

  2. 강제 중단 조건(Hard stop conditions). 턴 수 제한(--max-turns), 실제 경과 시간(wall-clock time)

자율 에이전트(Autonomous Agent)의 진정한 매력은 사용자가 지켜보고 있지 않아도 스스로 실행된다는 점입니다. 하지만 바로 그 점 때문에 토큰 비용이 조용히 불어날 수 있습니다. 사용자가 인지하지 못하는 사이에 수십 번의 스케줄된 실행이 이루어지고, 각 실행마다 거대한 재구성된 컨텍스트(reconstructed context)와 캐시 미스(cache misses)가 발생하기 때문입니다. Claude Code는 JSONL 세션 로그를 로컬(~/.claude/projects/)에 기록하므로, 사후에 비용을 감사(audit)할 수 있습니다. 저희는 이러한 로그를 세션별, 모델별, 일별 비용 내역으로 변환해 주는 오픈 소스 CLI인 **tokenscope**를 구축했습니다. 여기에는 대부분의 예상치 못한 비용을 유발하는 '캐시 생성(cache-creation) 대 캐시 읽기(cache-read)'의 분리 내역도 포함됩니다. 관리되지 않는 상태로 실행되는 모든 작업에 대해, npx tokenscope는 가장 저렴한 보험이 될 것입니다. 이 도구는 읽기 전용(read-only)이며 오프라인으로 작동하므로, 샌드박스(sandboxed) 환경에 즉시 통합할 수 있습니다.

FAQ

Claude를 "자율적"으로 만들기 위한 최소 요건은 무엇인가요?
루프(헤드리스 모드(headless mode)로 Claude를 호출하는 스크립트), 에이전트가 가장 먼저 읽고 가장 마지막에 쓰는 메모리 파일, 그리고 이를 실행할 스케줄러(cron 또는 systemd)가 필요합니다. 그게 전부입니다. 나머지는 모두 고도화 과정입니다.

에이전트는 실행 사이의 정보를 어떻게 기억하나요?
자동으로는 기억하지 못합니다. 각 실행은 새로운 컨텍스트(fresh context)입니다. 상태를 디스크에 저장(markdown + JSON, 또는 저장소)하고, 매 실행 시 "메모리를 읽으라"는 명령을 첫 번째 지침으로 전달해야 합니다. 메모리는 토글(toggle)하는 기능이 아니라, 사용자가 부여하는 규율(discipline)입니다.

Cron을 사용해야 하나요, 아니면 항상 켜져 있는 프로세스를 사용해야 하나요?
짧은 주기로 스케줄링된 여러 번의 실행을 권장합니다. 이러한 방식은 충돌에 강하고(실행 실패가 무해함), 컨텍스트 드리프트(context drift)를 방지하며, 관찰하기가 더 쉽습니다. 항상 켜져 있는 방식은 진정으로 이벤트 기반(event-driven)인 작업에만 남겨두되, 그 경우에도 디스크에 체크포인트(checkpoint)를 생성하도록 하세요.

에이전트가 무한히 실행되거나 경로를 이탈하는 것을 어떻게 막나요?
강력한 제한(Hard caps: --max-turns, 시간 제한, 예산), 영향 범위(blast radius)를 제한할 수 있는 샌드박스(sandbox), 안전한 도구의 허용 목록(allow-list), 그리고 현실을 보고하도록 하는 허구 금지 규칙(no-fabrication rule)이 필요합니다. 가드레일(Guardrails)이 우선이며, 자율성(autonomy)은 그다음입니다.

내 내부 API와 도구들을 사용할 수 있나요?
네 — Claude가 가리키는 MCP (Model Context Protocol) 서버를 통해 가능하며, 샌드박스(sandbox) 내의 shell/HTTP를 통해서도 가능합니다. 필요한 최소한의 도구만 노출하고, 안전한 도구들만 허용 목록(allow-list)에 추가하세요.

이 글은 Claude Code의 토큰 비용을 추적하기 위한 오픈 소스 CLI인 tokenscope를 개발한 팀이 작성했습니다. 저희는 샌드박스 컨테이너 내에서 장기 실행되는 자율 에이전트(autonomous agent)로서 Claude를 운영하고 있으며, 위에서 언급한 루프(loop), 메모리(memory), 가드레일(guardrail) 패턴을 매일 사용하고 있습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0