가이드

AI 에이전트의 세션 간 기억: 진행 파일, 결정 로그, git과 init 스크립트

업데이트: · Skillaria.Top

AI 에이전트에게는 세션 간 기억이 없습니다. 저장소 파일에 기록되지 않은 것은 새 세션이 알지 못합니다. 그래서 AI 에이전트의 메모리는 산출물로 만듭니다. 현재 위치를 적는 PROGRESS.md, 이유와 버린 대안을 적는 DECISIONS.md, 의도를 설명하는 git 커밋, 그리고 시작과 종료 시 이것을 읽고 갱신하도록 AGENTS.md에 적은 교대 프로토콜입니다. init 스크립트는 환경을 점검하고 현재 상태를 출력합니다.

에이전트가 아무것도 기억하지 못하는 이유

모델은 실행 사이에 상태를 저장하지 않습니다. 에이전트가 여러분의 작업에 대해 '아는' 모든 것은 현재 세션의 컨텍스트 창 안에 있습니다. 읽은 파일, 명령의 출력, 여러분과의 대화입니다. 세션이 끝나거나 컨텍스트가 넘치면, 새 세션은 0에서 시작하고 디스크에 기록된 것만 봅니다.

유용한 비유가 있습니다. 매일 아침 기억이 완전히 지워진 상태로 출근하는 뛰어난 엔지니어입니다. 그는 코드를 빨리 파악하겠지만, 어제 어떤 아키텍처를 골랐는지, 왜 나머지를 버렸는지, 테스트가 지금 어떤 상태인지는 떠올리지 못합니다. 기록이 없으면 그는 15~20분을 정찰에 쓰고, 여러분이 의도적으로 버린 방식을 다시 만들어 낼 가능성이 큽니다.

그래서 AI 에이전트의 메모리는 모델의 속성이 아니라 하네스의 일부입니다. 여러분이 설계하는 파일과 규칙의 집합입니다. 좋은 소식은 벡터 데이터베이스나 특별한 서비스가 필요 없다는 것입니다. Markdown 파일 몇 개, git, 그리고 규율이면 충분합니다.

큰 컨텍스트 창이 문제를 해결하지 못하는 이유

더 큰 창을 가진 모델을 기다리면 된다고 생각하기 쉽습니다. 하지만 복잡한 작업은 어떤 창이든 채웁니다. 에이전트는 코드베이스를 읽고, 결정의 역사를 쌓고, 장황한 테스트 출력을 받고, 전체 대화를 붙들고 있습니다. 필요는 창과 함께 커집니다. 이것은 용량의 문제가 아니라 구조의 문제입니다.

두 번째 효과도 있습니다. 많은 모델은 창의 경계에 가까워질수록 서두르기 시작합니다. 검증을 건너뛰고, 올바른 해법 대신 단순한 해법을 고릅니다. Anthropic은 자사 모델에서 이 현상을 관찰했다고 설명하며, 그 정도는 모델마다 다릅니다. 한계에 가까운 긴 세션은 정보를 잃을 위험뿐 아니라 작업 품질이 떨어질 위험도 있습니다.

압축: 무엇이 남고 무엇이 사라지나

압축(compaction)은 같은 세션 안에서 공간을 확보하기 위해 대화 초반부를 짧은 요약으로 바꾸는 것입니다. Claude Code에서는 /compact 명령이 이를 수행하며, 한도에 가까워지면 자동으로도 일어납니다. 반대로 /clear는 기록을 지우고 대화를 처음부터 다시 시작합니다.

압축의 문제는 요약이 보통 '무엇'은 남기고 '왜'는 잃는다는 점입니다. 완성된 코드는 파일에 남지만, 왜 B안을 골랐는지, 왜 라이브러리를 쓰지 않았는지, 왜 최적화를 의도적으로 건너뛰었는지에 대한 추론은 몇 단어로 줄어들거나 사라집니다. 그러면 에이전트의 다음 단계는 의도적인 결정을 '개선'해 버립니다. 이유를 더 이상 보지 못하기 때문입니다.

압축초기화(새 세션)
무슨 일이 일어나나대화 초반부가 요약으로 대체됨세션이 닫히고, 새 세션이 상태 파일을 읽음
무엇이 남나압축 시 모델이 중요하다고 본 것정확히 여러분이 파일에 적은 것
경계 근처의 서두름남을 수 있음초기화됨
언제 적합한가작업이 현재 세션에 확실히 들어갈 때작업 기간이 길거나 불분명할 때

복잡한 지표 없이 쓸 수 있는 실용 규칙이 있습니다. 작업이 컨텍스트의 약 60%를 차지했다면 코드 작성을 멈추고 인수인계를 준비하세요. 반대로 컨텍스트가 40%쯤 찼고 작업 끝이 가까우면 압축으로 충분합니다.

에이전트 메모리를 구성하는 네 가지 산출물

모델의 기억을 기대하는 대신 항해 일지를 만드세요. 네 부분으로 구성되며 각각 역할이 다릅니다.

  1. PROGRESS.md — 지금 어디에 있는가.
  2. DECISIONS.md — 왜 이렇게 했고 다르게 하지 않았는가.
  3. git 커밋 — 상태의 무료 체크포인트.
  4. AGENTS.md의 교대 프로토콜 — 근무를 시작하고 끝낼 때 무엇을 할지.

PROGRESS.md: 진행 파일

이 파일은 한 가지 질문에 답합니다. 프로젝트는 지금 어떤 상태인가. 에이전트는 세션 시작 때 가장 먼저 읽고, 떠나기 직전에 마지막으로 갱신합니다. 파일은 짧아야 하며, 계속 덧붙이기보다 다시 씁니다. 역사는 git에 있습니다.

# PROGRESS.md

## 현재 목표
상품 카탈로그 검색 (기능 search-01)

## 상태
- HEAD: 4f2a9c1
- make check: 초록, 142/142 테스트
- 완료: PostgreSQL 인덱스(tsvector), 엔드포인트 GET /search
- 검증됨: 유닛 테스트 + 검색어 3개로 curl 수동 확인

## 블로커
- 카자흐어 형태소 데이터 없음 — 결정 대기

## 다음 단계
GET /search에 페이지네이션 추가, 기준: 2페이지 테스트

인수인계에 충분한 필드가 네 개 있다는 점에 주목하세요. 커밋 해시, 통과하는 테스트의 비율, 블로커, 다음 단계입니다. 새 세션이 이 파일만으로 작업을 모호함 없이 이어 갈 수 없다면, 템플릿에 필드가 빠진 것입니다.

DECISIONS.md: 결정 로그

압축 때 사라지는 바로 그 '왜'를 보관합니다. 형식은 결정, 이유, 버린 대안과 그 이유, 제약입니다.

## 2026-03-14 — Redis에 사용자 설정 캐시
- 결정: Redis, TTL 5분, 쓰기 시 능동적 무효화.
- 이유: 모든 요청에서 읽히고, 데이터 양이 아주 작음.
- 버림: PostgreSQL의 materialized view — 변경이 너무 잦아
  유지 비용이 이익보다 큼.
- 제약: 결제 설정은 캐시하지 않음.

이 중 가장 가치 있는 줄은 '버림'입니다. 다음 세션이 이미 검토하고 버린 대안으로 결정을 '최적화'해 되돌리는 것을 막아 주기 때문입니다. 결정 로그는 진행 파일과 달리 계속 추가만 합니다. 오래된 항목은 지우지 않고, 새 항목으로 대체되었다고 표시합니다.

git 기록을 체크포인트로

커밋은 작업 중에 이미 만들어지는 버전 관리된 상태 스냅샷입니다. 에이전트는 git log와 git diff를 읽고 무엇이 바뀌었는지 복원할 수 있습니다. 기록이 메모리로 작동하려면 커밋 메시지가 diff를 다시 말하지 말고 의도를 설명해야 합니다.

# 나쁨
git commit -m "update search.py"

# 좋음
git commit -m "search: LIKE 대신 tsvector 인덱스

LIKE '%q%'는 인덱스를 쓰지 못해, 상품 20만 개에서 쿼리가 1.8초 걸렸다.
페이지네이션은 아직 없음, PROGRESS.md 참고."

초록 테스트 실행마다 작은 커밋을 자주 남기면 되돌릴 지점도 생깁니다. 세션이 엉뚱한 방향으로 가면, 반쯤 끝난 수정을 풀어내는 것보다 마지막으로 검증된 상태로 돌아가는 편이 쉽습니다.

AGENTS.md의 교대 프로토콜

에이전트가 상태 파일의 존재를 모른다면 그 파일들은 쓸모가 없습니다. 그래서 입력 지침 파일(AGENTS.md 또는 CLAUDE.md)에 짧은 프로토콜을 적습니다. 근무를 시작할 때와 끝낼 때 무엇을 할지입니다.

## 근무 시작
1. PROGRESS.md와 DECISIONS.md를 읽기.
2. .agent/feature_list.json에서 활성 작업 찾기.
3. make check를 실행해 저장소가 일관된지 확인하기.
4. '다음 단계'부터 이어 가기. 이미 결정된 것은 다시 열지 않기.

## 근무 종료
1. make check를 실행하고, 초록 상태를 커밋하기.
2. PROGRESS.md 갱신: HEAD, 테스트, 블로커, 다음 단계.
3. 새 결정을 DECISIONS.md에 추가하기.
4. 작업 트리에 끝나지 않은 것을 남기지 않기.

프로토콜은 짧게 유지하는 것이 좋습니다. 입력 지침 파일에 몇 줄이면 충분하며, 별도의 긴 문서일 필요는 없습니다.

Init 스크립트: 세션 시작 가속하기

에이전트가 그림을 손으로 맞추지 않도록, 환경을 점검하고 상태를 출력하는 스크립트를 하나 주세요. 스크립트는 멱등해야 합니다. 몇 번을 돌려도 괜찮아야 하며, 마지막에 준비 완료를 분명히 알리는 메시지를 출력해야 합니다.

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

echo "== 1. 환경 =="
command -v uv >/dev/null || { echo "FAIL: uv가 설치되지 않음"; exit 1; }
uv sync --frozen

echo "== 2. 저장소 =="
if [ -n "$(git status --porcelain)" ]; then
  echo "WARN: 작업 트리가 지저분함"
else
  echo "OK: 깨끗함"
fi
echo "HEAD: $(git log -1 --oneline)"

echo "== 3. 검사 =="
make check

echo "== 4. 상태 =="
cat PROGRESS.md

echo "작업 준비 완료"

그러면 시작 프로토콜에는 'scripts/init.sh를 실행하라'는 한 줄이면 충분합니다. Claude Code에서는 세션 시작 이벤트(SessionStart)에 훅을 걸어 이 실행을 자동화할 수 있습니다. 훅이 없더라도 에이전트는 파일의 지침에 따라 스크립트를 실행합니다.

에이전트 메모리에 무엇을 넣고 무엇을 뺄까

가장 흔한 실수는 메모리를 잡동사니 창고로 만드는 것입니다. 에이전트가 시작할 때 읽는 모든 줄은 컨텍스트 공간을 차지하고, 쓸모없는 것은 중요한 것을 흐립니다.

넣기넣지 않기
현재 목표와 다음 단계에이전트가 직접 읽을 수 있는 코드 설명
이유와 버린 대안이 있는 결정대화 전체 기록과 명령 출력
커밋 해시와 테스트 상태의존성 목록 — 패키지 매니페스트에 이미 있음
블로커와 열린 질문'아주 잘 됐고 모두 작동함'처럼 검증 방법이 없는 말
막다른 길: 무엇을 시도했고 왜 실패했는지비밀 값, 토큰, 비밀번호
인수 기준이 있는 작업이미 닫힌 작업에 대한 오래된 메모

수명에 따라서도 나누세요. 프로젝트 규칙은 드물게 바뀌고 모든 작업에 적용되므로 입력 지침 파일에 둡니다. 상태는 세션마다 바뀌므로 진행 파일에 둡니다. 둘을 섞으면 입력 지침 파일이 금방 낡은 메모로 부풀어 오릅니다.

첫 세션: 초기화를 별도 단계로

첫 세션이 혼란에 빠졌다면 세션 간 메모리도 도움이 되지 않습니다. 전형적인 장면은 이렇습니다. 빈 저장소에 '검색 추가해 줘'라고 적었는데, 30분 뒤 테스트 프레임워크가 잘못 설정되어 있고 마이그레이션 형식도 맞지 않는다는 것이 드러납니다. 검색은 생겼지만 기반이 비뚤어져 있습니다.

이유는 구현과 초기화가 서로 다른 것을 최적화하기 때문입니다. 구현은 이번 세션에서 완성되는 기능의 수를 최적화하고, 초기화는 이후 모든 세션의 속도와 신뢰성을 최적화합니다. 에이전트는 눈에 보이는 결과, 즉 코드 쪽으로 기웁니다. 그래서 초기화는 네 가지 조건으로 된 명확한 완료 기준을 가진 별도 세션으로 떼어 내세요.

  • 실행되기: 깨끗한 클론에서 make setup과 make dev가 작동함.
  • 검증되기: make test가 있고, 실제로 통과하는 테스트가 최소 하나 있음.
  • 진행이 보이기: 상태 파일이 존재하고 읽을 수 있음.
  • 이어받기: 인수 기준이 있는 작업 목록이 있음.

새 프로젝트를 자주 시작한다면 저장소 템플릿을 만들어 두세요. Makefile, 테스트 프레임워크, AGENTS.md 뼈대, .agent/ 폴더, scripts/init.sh, 린터, CI를 넣습니다. 그러면 초기화는 해당 프로젝트만의 특수한 부분으로 줄어듭니다.

메모리가 작동하는지 확인하기

가장 정직한 지표는 새 세션을 시작한 뒤 의미 있는 코드 변경을 하기까지 걸리는 시간입니다. 산출물이 없으면 보통 15~20분의 정찰이 걸리고, 좋은 인수인계가 있으면 2~3분입니다. 한 번 전후를 재 보면, 이 규율이 값어치를 하는지 알 수 있습니다.

두 번째 방법은 콜드 스타트 테스트입니다. 새 세션을 열고 '계속하세요'라고 쓴 뒤 다섯 가지를 물어보세요. 현재 목표는 무엇인가, 테스트는 어떤 상태인가, 핵심 주제에서 어떤 결정이 내려졌고 왜인가, 무엇이 막고 있는가, 다음 단계는 무엇인가. 에이전트가 추측 없이 파일에서 다섯 가지 모두에 답하면 메모리가 제대로 구성된 것입니다. 확신이 없는 답마다 템플릿에 빠진 필드가 하나씩 있다는 뜻입니다.

흔한 실수

  • 진행 파일이 계속 늘어나기만 함. 한 달이면 수백 줄의 역사가 쌓입니다. 현재 상태에 맞게 다시 쓰고, 역사는 git에 두세요.
  • '버림' 줄이 없음. 버린 대안이 없는 결정 로그는 같은 논쟁이 반복되는 것을 막지 못합니다.
  • 에이전트가 상태를 '눈대중으로' 갱신함. 어떻게 검증했는지 적으세요. 명령과 결과를 쓰고, '모두 작동함'이라고 쓰지 마세요.
  • 컨텍스트 한계에서 인수인계. 창의 경계에서 에이전트는 이미 서두릅니다. 인수인계는 약 60%에서 미리 시작하세요.
  • 종료 시 작업 트리가 지저분함. 커밋되지 않은 반쯤 끝난 수정은 다음 세션을 헷갈리게 합니다.

정리

AI 에이전트의 세션 간 메모리는 모델이 아니라 파일 위에 세워집니다. PROGRESS.md는 현재 상태를 담고, DECISIONS.md는 이유와 버린 대안을 담고, git 커밋은 의도를 설명하는 체크포인트이며, AGENTS.md의 교대 프로토콜은 이 모든 것을 읽고 갱신하게 만듭니다. Init 스크립트는 시작을 명령 하나로 줄이고, 콜드 스타트 테스트는 기록이 충분한지 보여 줍니다. 에이전트의 작업 일지와 bootstrap 계약은 강의에서 실제 사례로 자세히 다룹니다.

자주 묻는 질문

에이전트에게 무언가를 기억해 달라고 부탁하면 되나요?

에이전트는 다음 세션이 읽는 파일에 적은 것만 기억합니다. Claude Code에는 메모리 파일과 CLAUDE.md가 있지만, 특정 작업의 상태에는 저장소 안의 명시적인 진행 파일이 더 확실합니다.

PROGRESS.md와 CHANGELOG는 무엇이 다른가요?

CHANGELOG는 사용자를 위해 버전별 변경을 기록합니다. PROGRESS.md는 다음 에이전트 세션을 위한 현재 작업 상태를 기록하며, 상태가 바뀔 때마다 다시 씁니다.

한 저장소에서 일하는 코딩 에이전트에도 벡터 데이터베이스가 필요한가요?

보통 필요하지 않습니다. 작업 상태는 짧은 파일 몇 개에 들어가고, 에이전트는 코드를 직접 읽습니다. 벡터 검색은 대량의 외부 문서를 뒤질 때 의미가 있습니다.

상태 파일을 git에 커밋해야 하나요?

네. 그래야 어느 세션이나 팀의 누구든 상태에 접근할 수 있고, 변경 이력도 남습니다. 개인 메모나 비밀 값이 들어 있는 것은 예외입니다.

에이전트가 끝에 PROGRESS.md 갱신을 잊으면 어떻게 하나요?

갱신을 종료 프로토콜의 완료 기준에 포함하고, 파일의 HEAD가 현재 커밋과 같은지 비교하는 훅이나 스크립트로 기계적으로 확인하세요.

영상으로 이 주제 배우기

이 주제는 “Harness Engineering: инженерия надёжности AI-агентов” 강의에서 실습과 함께 자세히 다룹니다.

강의로 이동