CPN 한국어 자습서 · Claude Certified Developer — Foundations Prep
2-8 · 에이전트 메모리
Choosing the right scope for state that survives sessions
앞 절에서 만든 에이전트는 한 세션 안에서는 정확하게 동작합니다. 다만 그 세션이 끝나면 아무것도 기억하지 못합니다. 메모리 범위(memory scope)는 다음 세션이 시작될 때 에이전트가 무엇을 알고 있을지, 그리고 그 기억을 이어 가는 데 비용이 얼마나 드는지를 정하는 설계 기준입니다. 이 레슨에서는 네 가지 메모리 패턴과 고르는 기준, 그리고 매 세션에 싣지 않고도 지시문을 재사용하는 Skill까지 살펴봅니다.
이 장에서 배우는 것What you'll learn
약 13분메모리 범위가 정하는 것 — 다음 세션 시작 때 에이전트가 아는 것
네 가지 패턴 비교 — 인컨텍스트 · 외부 저장소 · 요약 · 무상태
이 선택이 설계 단계의 몫인 이유 — 리팩터링 시점과의 비용 차이
Skill — 요청과 맞을 때만 불려 오는 재사용 지시문
Skill · CLAUDE.md · 인컨텍스트 지시문의 컨텍스트 비용 비교
4번째 세션에서 컨텍스트 창이 가득 찬 사고 기록
메모리 범위 외에도, 이 목표 아래에는 몇 가지 에이전트 설계 패턴이 함께 묶여 있습니다. 모두 이 모듈 앞부분에서 이미 한 번씩 만들어 본 것들입니다.
메모리 범위는 새 세션이 시작될 때 에이전트가 무엇을 아는지를 정합니다. 이 선택이 어긋나면 두 가지 방식으로 실패하는데, 두 실패는 서로 반대 방향에 있습니다.
MEMORY SCOPE × 4 — 네 가지 범위 비교표
| 범위 | 무엇이 남나 | 비용 | 언제 쓰나 | 무엇을 잃나 |
|---|---|---|---|---|
| 인컨텍스트 | 상태가 진행 중인 대화 안에 살아 있고, 한 세션 안에서는 턴을 넘겨 유지된다. | 따로 읽어 오는 부담은 없지만, 대화가 길어질수록 토큰 비용이 늘어난다. | 필요한 상태가 전부 컨텍스트 창에 들어가고, 재시작을 넘겨 이어질 것이 없는 짧은 세션. | 세션이 끝나면 전부. 대화를 비우는 명령이나 새 세션이 상태를 지운다. |
| 외부 저장소 | 상태를 데이터베이스에 기록해 두고, 세션 시작 시점이나 필요할 때 다시 읽는다. | 호출마다 읽어 오는 지연이 붙고, 읽기·쓰기 로직을 직접 구현하는 부담이 생긴다. | 세션을 넘어 남아야 하는 상태, 사용자 사이를 오가는 상태, 여러 에이전트 인스턴스가 공유하는 상태. | 남기는 쪽에서는 없다. 비용은 호출마다의 지연과 계속되는 구현 복잡도로 나타난다. |
| 요약 메모리 | 이전 대화를 압축한 요약본을 만들어 다음 세션 시작에 넣어 준다. | 전체 기록을 다시 싣는 것보다 세션당 토큰 비용은 낮지만, 요약 단계에서 원본에 있던 세부가 빠진다. | 대화가 끝나기 전에 전체 기록이 컨텍스트 예산을 넘길 만큼 길게 이어지는 대화형 에이전트. | 요약기가 남기지 않은 세부 전부. 에이전트는 요약 프롬프트가 남기기로 한 것만 본다. |
| 무상태 | 아무것도. 세션마다 독립적이다. | 읽어 올 것도 저장할 것도 없어서 부담이 전혀 없다. | 일을 마치면 종료하는 작업 실행형 에이전트, 세션마다 완전히 독립인 파이프라인. | 이전 컨텍스트 전부. 후속 작업이 이전 세션의 무언가에 의존하면 닿을 방법이 없다. |
인컨텍스트는 머릿속 기억, 외부 저장소는 수첩, 요약 메모리는 요점 정리, 무상태는 매번 백지에서 시작하는 것에 가깝습니다. 과제가 어느 쪽을 요구하는지부터 확인하면 고르기 쉬워집니다.
에이전트가 이전 대화를 어떻게 기억할지는 설계 단계에서 정할 문제입니다. 프로덕션 리팩터링으로 미루면 같은 결정이 훨씬 비싸지는 경우가 많습니다.
여러 날에 걸쳐 같은 사용자를 돕는 에이전트라면 세션 사이에 상태를 이어 갈 필요가 있습니다. 요약본이나 전체 기록을 모델의 컨텍스트 창 밖에 저장해 두면, 다음 세션이 그것을 읽어 올 수 있습니다. 반대로 작업 하나를 받아 마치고 종료하는 에이전트는 되돌아볼 이전 세션 자체가 없으니 무상태로 동작합니다.
기본 경로는 처음에는 합리적으로 보입니다. 전체 대화 기록을 messages 배열에 쌓아 두고 매 API 호출에 함께 보내면 프로토타입은 동작합니다. 한동안은 계속 잘 되는 것처럼 보이기도 합니다. 문제는 더 들어간 뒤에 시작됩니다. 턴이 더해질수록 토큰 비용이 늘고, 컨텍스트 창이 차면서 지연이 길어지고, 긴 세션이 결국 한도에 걸리면 에이전트가 응답을 멈춥니다.
그 시점이 되면 리팩터링이 필요해집니다. 대화 상태를 진행 중인 컨텍스트에서 꺼내 외부 저장소로 옮기고, 턴마다 필요한 것만 넣는 구조로 바꾸는 일입니다. 리팩터링 자체는 기계적인 작업입니다. 코드 몇백 줄과 팀이 이미 쓰고 있는 데이터베이스면 됩니다. 비싼 것은 시점입니다. 이 작업은 보통 프로덕션 압박 속에서, 이미 진행 중인 마감과 함께 이뤄집니다. 메모리 구조를 고치는 데 쓰는 시간만큼, 에이전트가 다음에 맡을 일은 그만큼 미뤄집니다. 같은 결정을 설계 단계에서 내리면 비용이 적게 들고, 리팩터링이 필요해진 시점에는 훨씬 비싸집니다.
세 가지 경우로 정리해 보겠습니다. 각 접근이 잘 맞는 조건, 따라오는 부담, 그리고 잘못된 선택으로 이끄는 경우가 많은 가정입니다.
HANDLES WELL · ADDS COST · DIFFERENT APPROACH — 세 가지 판단
| 잘 맞는 경우 | 설계 시점에 메모리 범위가 과제와 맞을 때입니다. 세션을 넘어 대화를 이어 가는 에이전트에는 외부 저장소를, 작업마다 자기 완결이면 무상태를, 세션이 짧고 재시작을 넘길 필요가 없으면 인컨텍스트를 씁니다. |
|---|---|
| 비용·복잡도가 붙는 경우 | 외부 저장소에는 읽어 오는 지연과 읽기·쓰기 로직이 따라옵니다. 요약 메모리는 잘 짜인 요약 프롬프트가 전제인데, 그것이 없으면 압축할 때마다 과제에 중요한 상태가 빠져나갑니다. 어느 쪽도 공짜가 아니니, 비용을 견주어 본 뒤에 고르는 것이 좋습니다. |
| 다른 접근이 필요한 경우 | 창이 충분히 클 것이라는 가정만 믿고 모든 상태를 인컨텍스트에 두는 경우입니다. 매 호출에 전체 컨텍스트가 실려 가니 턴이 더해질수록 토큰 비용이 늘어납니다. 캐싱이나 압축(compaction) 없이 세션이 길어지면, 초반 몇 턴만 재 봤을 때의 예상보다 비용이 빠르게 쌓입니다. 인컨텍스트로 확정하기 전에 실제 세션 토큰 사용량을 창 한도와 비교해 보는 것부터 시작합니다. |
위 표는 에이전트가 세션 사이에 상태를 어떻게 이어 가는지를 다뤘습니다. 비슷해 보이지만 다른 문제가 하나 더 있습니다. 반복해서 쓰는 지시문을, 매 세션에 밀어 넣는 비용을 치르지 않고 여러 과제에 걸쳐 재사용하는 방법입니다. 그 자리를 맡는 패턴이 Skill입니다.
Skill은 특정 유형의 과제를 처리하는 방법을 Claude에게 한 번만 가르쳐 두는 재사용 마크다운 파일입니다. 요청이 Skill의 설명과 맞으면 Claude가 자동으로 불러옵니다. 지시문은 필요해질 때까지 디스크에 머물러 있고, 모든 대화에 상주하지 않습니다.
Skill은 정해진 디렉터리 안의 SKILL.md 파일에 담깁니다. 파일은 두 부분으로 나뉩니다. 이름과 설명을 적는 프런트매터frontmatter — 파일 맨 위에 이름·설명 같은 메타데이터를 적는 블록. 블록, 그리고 그 아래의 지시문입니다. 매칭 기준은 설명입니다. 요청을 보내면 Claude는 사용할 수 있는 모든 Skill의 이름과 설명을 읽고 메시지와 비교한 뒤, 맞는 것이 있을 때만 전체 지시문을 불러옵니다. 지금 요청과 관련이 없는 지시문은 컨텍스트 창에 아예 들어오지 않습니다.
앞의 메모리 패턴들과 대비되는 지점이 바로 여기입니다. 인컨텍스트 메모리는 항상 실려 있고 턴마다 늘어납니다. CLAUDE.md는 Claude Code를 어디에서 실행하는지에 따라 동작이 다릅니다. Claude Code CLI에서는 어떤 과제를 하고 있든 CLAUDE.md 파일이 모든 세션에 불려 들어갑니다. Agent SDK에서는 CLAUDE.md를 포함한 파일 시스템 설정을 불러올지를 settingSources 설정이 정합니다. 기본값에 기대기보다는 의도한 소스를 명시적으로 지정하고, 빌드 시점에 Agent SDK 레퍼런스에서 현재 기본 동작을 확인해 두는 것이 좋습니다. 반면 Skill은 두 환경 모두에서, 과제가 요구할 때만 불려 들어갑니다. 매 세션이 아니라 특정 유형의 반복 과제에 적용되는 지시문이라면, Skill이 두 대안보다 부담이 적은 패턴입니다.
SKILL · CLAUDE.MD · IN-CONTEXT — 패턴별 비용 비교
| 패턴 | 언제 불려 오나 | 컨텍스트 비용 | 잘 맞는 곳 |
|---|---|---|---|
| Skill | 요청이 Skill의 설명과 맞을 때, 그때그때. | 낮다. 시작 시점에는 이름과 설명만 실리고, 전체 내용은 매칭될 때만 실린다. | 필요 없는 세션까지 무겁게 만들면 안 되는 과제 특화 지식. 도메인 특화 출력 형식, 전문 리뷰 체크리스트, 전체가 아니라 일부 과제에 적용되는 워크플로. |
| CLAUDE.md | 모든 세션에, 조건 없이. | 과제와 무관하게 세션당 고정 비용. | 모든 작업에 적용되는 상시 프로젝트 표준. 팀이 합의한 코딩 컨벤션, 프로젝트가 요구하는 출력 형식 규칙, 코드베이스 전체에 걸친 제약. |
| 인컨텍스트 지시문 | 그 세션의 모든 턴에. | 세션 길이에 따라 늘어나고, 세션이 끝나면 남지 않는다. | 전체 기록이 창에 들어가고 남길 것이 없는 짧은 세션. 일회성 탐색 작업, 대화 하나로 끝나는 과제. |
Skill이 푸는 것은 상태가 아니라 일하는 방법의 재사용입니다. 기억을 남기는 장치가 아니라, 반복 과제의 처리법을 필요할 때만 꺼내 쓰는 장치입니다.
지금 시점의 제공 범위도 확인해 둘 필요가 있습니다. Skill은 Messages API에서도 쓸 수 있지만, 이 연동은 베타이고 설정 방식이 Claude Code나 Agent SDK 경로와 다릅니다. API 요청에 베타 헤더 두 개가 필요합니다 — code-execution-2025-08-25와 skills-2025-10-02. 이 경로로 호출된 Skill은 호출한 애플리케이션의 환경이 아니라 코드 실행 컨테이너 안에서 동작하는데, Skill이 기댈 수 있는 도구와 파일 시스템 접근이 그만큼 달라집니다.
베타 헤더에는 버전이 붙어 있고, 기능이 정식 제공으로 옮겨 가면서 값이 바뀝니다. 이 구성을 프로덕션에 넣기 전에는 Anthropic API 문서에서 헤더 값이 지금도 유효한지, 기능이 정식 제공에 도달했는지, 코드 실행 컨테이너가 여전히 실행 경로인지 확인해 보는 것이 좋습니다.
제약이 하나 있습니다. 서브에이전트는 부모 세션의 Skill을 자동으로 물려받지 않습니다. 작업을 서브에이전트에 위임하면, 서브에이전트는 깨끗한 컨텍스트에서 시작합니다. Skill과 대화 기록은 넘어가지 않지만 권한 컨텍스트는 부모 세션에서 물려받는다는 점도 같이 기억해 둘 만합니다. 위임 시점에 권한 범위는 초기화되지 않습니다. 서브에이전트에 Skill이 필요하면, 그 Skill을 서브에이전트 설정에 명시적으로 등록합니다. 특정 지시문에 의존하는 작업을 서브에이전트에 맡기도록 설계하고 있다면, 그 지시문이 부모에서 넘어온다고 가정하기보다 서브에이전트 쪽에 등록돼 있는지부터 확인해 볼 필요가 있습니다.
개발 중에는 에이전트가 완벽하게 동작합니다. 하나의 긴 연속 세션으로 실행하고 있어서 컨텍스트 창이 차지 않고, 인컨텍스트 메모리가 모든 것을 담아 주기 때문입니다. 그런데 프로덕션은 여러 날에 걸쳐, 턴이 더 쌓이는 짧은 세션 여러 개로 운영됩니다. 그리고 4번째 세션에서 창이 가득 찹니다.
실제 사후 분석 사례입니다. 진행 중인 에스컬레이션escalation — 일반 창구에서 해결되지 않아 상위 담당자에게 넘어간 사례. 사례를 다루는 지원 엔지니어를 돕는 에이전트가 있었습니다. 개발 단계에서는 10~15턴짜리 연속 세션으로 실행했고, 인컨텍스트 상태가 전체 기록을 문제없이 담았습니다. 개발자는 세션당 토큰 사용량을 재 보지 않은 채 배포했습니다.
프로덕션에서는 세션 하나하나는 더 짧았지만, 상태가 세션을 넘어 계속 쌓였습니다. 4번째 세션이 되자, 컨텍스트에 주입된 기록이 도구 호출을 하나도 처리하기 전에 이미 40,000 토큰을 넘었습니다. 시스템 프롬프트와 등록된 도구 스키마까지 더하면, 세션의 첫 생산적인 턴이 시작되기도 전에 컨텍스트 예산에서 45,000 토큰 이상이 소비된 상태였습니다. 세션이 진행되며 도구 호출이 쌓이자 남은 예산은 분석을 마치기 전에 바닥났고, 에이전트는 불완전한 결과를 돌려주기 시작했습니다. 겉으로 보이는 증상만으로는 메모리 구조 문제가 아니라 도구 선택 실패처럼 읽히는 상황이었습니다.
고치는 작업 자체는 외부 저장소로 옮기는 한 시간짜리 리팩터링이었습니다. 쌓인 세션 기록을 진행 중인 컨텍스트에서 꺼내 데이터베이스에 저장하고, 세션 시작 시점에 관련 있는 부분만 넣어 주는 구조입니다. 다만 프로덕션 압박 속의 리팩터링은 설계 시점에 했을 때보다 훨씬 오래 걸렸습니다. 저장 계층, 읽어 오는 로직, 세션 관리 전부, 첫 배포 전에 내릴 수 있었던 결정이었습니다.
원문의 점검 과제는 세 가지 에이전트 사례를 알맞은 메모리 범위와 짝짓는 매칭형입니다. 여기서는 사례별 객관식으로 바꿔 풀어 봅니다. 사례마다 맞는 범위는 하나입니다. 정답을 먼저 떠올려 본 뒤 골라 보세요. 맞히면 설명이 나옵니다.
Q1고객 지원 에이전트가 2주 동안 매일 이어지는 체크인에서 같은 사용자를 돕습니다. 세션마다 이전 세션이 끝난 지점에서 이어서 시작합니다. 어느 범위가 맞을까요?
인컨텍스트 상태는 세션이 끝나면 초기화되기 때문에, 다음 날의 에이전트에게는 전날 체크인 기록이 없습니다. 세션마다 첫 상담처럼 시작하게 되고, 사용자는 자기 상황을 처음부터 다시 설명하게 됩니다. 세션을 넘어 이어지는 관계에는 외부 저장소가 맞습니다.
Q2문서 포매터가 파일을 받아 변환을 적용하고, 결과를 반환한 뒤 종료합니다. 작업마다 완전히 독립입니다. 어느 범위가 맞을까요?
이어질 것이 없는 작업에 외부 저장소를 붙이면 읽기·쓰기 호출만 더해집니다. 동작이 깨지지는 않지만, 다시 쓸 일이 없는 상태를 위해 실행마다 지연과 구현 비용을 치르게 됩니다. 작업이 자기 완결이면 무상태가 맞습니다.
Q3코딩 어시스턴트가 개발자와 몇 시간짜리 세션을 함께 진행합니다. 세션이 끝난 뒤에는 이어지지 않습니다. 어느 범위가 맞을까요?
개발자가 로그오프하면 끝나는 세션에 외부 저장소는 불필요한 부담입니다. 요약 메모리 층을 두면, 개발자가 같은 세션 뒷부분에서 다시 참조할 코드 수준의 세부가 압축 과정에서 빠져나갑니다. 한 세션 안에서 끝나는 작업에는 인컨텍스트가 맞습니다.
다음 장은 모듈 2의 누적 디버그 과제입니다. 지금까지 배운 것으로 문제를 찾아내고(Identify) 고치는(Fix) 실습으로 이어집니다. → 2-9 · 누적 디버그 과제
전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 38개 레슨을 끝까지 읽을 수 있습니다.
이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.