시스템 프롬프트 바꿀 때마다 캐시 날리던 시대 끝났습니다. Opus 4.8부터는 대화 중간에 꽂아 넣으면 됩니다.
핵심 요약
→ Opus 4.8 전용 기능 — Opus 4.7 이하에서 role: "system" 중간 삽입 시 400 에러
→ messages 배열 안에 role: "system"을 user 턴 직후에 삽입하는 방식
→ 이전 대화 내용은 그대로 유지 → 기존 프롬프트 캐시 히트 보존
→ beta 헤더 불필요 — 기본 Messages API에서 바로 사용 가능
→ 용도: 권한 부여, 페르소나 변경, 정책 업데이트, 토큰 예산 조정
→ 배치 처리 중 환경 변수 업데이트에도 활용 가능
→ 최상위 system 필드는 대화 시작 시 고정 지시사항에 계속 사용
→ Dynamic Workflows의 서브에이전트 권한 부여 메커니즘이 이 기능 기반
실전 1 — 기존 방식의 문제: 캐시 날리지 않고 시스템 프롬프트 바꾸기
에이전트 루프를 길게 돌리다 보면 중간에 지시사항을 바꿔야 할 때가 생깁니다. 기존엔 두 가지 방법밖에 없었고 둘 다 단점이 있었습니다.
# 기존 방법 1: 최상위 system 필드 수정
→ 프롬프트 캐시 해시가 달라짐 → 캐시 전부 miss
→ 긴 시스템 프롬프트 있으면 매 턴마다 full input cost 발생
# 기존 방법 2: user 턴에 지시사항 끼워 넣기
→ "이제부터 모든 SQL은 파라미터화해서 작성해줘" 같은 지시를 user 역할로 넣음
→ 롤 구조 오염, 모델 혼동 가능성, 의미상 부정확
Opus 4.8의 Mid-conversation system messages는 이 문제를 해결합니다. 이전 대화 내용을 건드리지 않고 messages 배열 끝에 새 role: "system" 항목을 추가하면 됩니다.
프롬프트 캐시 동작 원리 박스 Anthropic의 캐시는 요청 prefix를 해시합니다. 순서는 tools → system → messages 순. 최상위 system 필드를 수정하면 그 뒤 모든 messages 캐시도 무효화됩니다. Mid-conversation system messages는 messages 배열 끝에만 추가되므로 앞의 캐시 엔트리가 그대로 살아남습니다.
실전 2 — 기본 사용법
import anthropic
client = anthropic.Anthropic()
# 1턴: 시스템 프롬프트 + 첫 요청
# → 이 시점에 캐시 엔트리 생성
response1 = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system="당신은 코드 리뷰 어시스턴트입니다. 간결하게 답하세요.",
messages=[
{
"role": "user",
"content": "utils.py의 process() 함수 성능 문제 리뷰해줘"
}
]
)
answer1 = response1.content[0].text
# 2턴: 중간에 새 정책 주입 — 기존 캐시 유지됨
# user 턴 직후에 role: "system" 삽입
response2 = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system="당신은 코드 리뷰 어시스턴트입니다. 간결하게 답하세요.", # 동일하게 유지
messages=[
{
"role": "user",
"content": "utils.py의 process() 함수 성능 문제 리뷰해줘"
},
{
"role": "assistant",
"content": answer1 # 1턴 응답
},
{
"role": "user",
"content": "process()를 호출하는 상위 코드도 리뷰해줘"
},
# ↓ 여기에 새 지시 삽입 — 앞의 캐시 엔트리는 그대로 살아있음
{
"role": "system",
"content": "지금부터 모든 제안은 팀의 strict typing 정책도 통과해야 합니다."
}
]
)
삽입 위치 규칙이 있습니다.
✅ 허용되는 위치
user 턴 직후
❌ 허용되지 않는 위치
assistant 턴 직후
messages 배열 맨 처음 (최상위 system 필드 사용)
연속 system 메시지 (두 개 연달아)
실전 3 — 에이전트 루프에서 쓰는 실제 패턴
장시간 에이전트 작업에서 가장 유용한 케이스 3가지입니다.
케이스 1: 단계별 권한 부여
# 1단계: 분석만 허용
messages = [
{"role": "user", "content": "이 레포 전체 분석해서 리팩토링 계획 세워줘"}
]
# ... 분석 완료 후 ...
# 2단계: 파일 쓰기 권한 추가 — 캐시 유지
messages += [
{"role": "assistant", "content": plan},
{"role": "user", "content": "계획대로 실행해"},
# 분석 단계엔 없던 권한을 여기서 부여
{"role": "system", "content": "파일 수정 및 커밋 권한 부여됨. 테스트 실패 시 자동 롤백."}
]
케이스 2: 토큰 예산 재조정
# 작업 진행 중 토큰 소비 모니터링 후 중간에 예산 압축 지시
messages += [
{"role": "user", "content": "계속 진행해"},
{
"role": "system",
"content": "남은 토큰 예산이 부족합니다. 핵심 변경사항만 처리하고 나머지는 TODO 주석으로 남겨두세요."
}
]
케이스 3: 환경 컨텍스트 업데이트
# 배포 환경 변경 감지 시 실시간 주입
messages += [
{"role": "user", "content": "다음 서비스 배포 준비해줘"},
{
"role": "system",
"content": f"현재 배포 환경: {current_env}. DB 엔드포인트: {db_endpoint}. 스테이징 모드 활성화."
}
]
실전 4 — 캐시 비용 절감 실제 계산
긴 시스템 프롬프트를 가진 에이전트에서 이 기능의 효과가 극대화됩니다.
# 시나리오: 5,000 토큰짜리 시스템 프롬프트 + 20턴 대화
# 기존 방식 (최상위 system 수정 시)
매 수정 후 캐시 miss → 5,000 토큰 × $5/1M = 회당 $0.025
20턴 중 5번 수정 = $0.125 추가 비용 (캐시 miss 분만)
# Mid-conversation system messages 사용 시
최상위 system 불변 → 캐시 hit 유지
새 지시사항만 추가 토큰 (수십~수백 토큰)
절감액: 사실상 5번 × 5,000 토큰 분의 캐시 write 비용 절약
대규모 프로덕션 에이전트에서는 이 비용 절감이 월 단위로 의미있게 누적됩니다.
마무리
✅ Opus 4.8 전용 기능 — 이하 버전에서 시도하면 400 에러 발생합니다.
✅ 기존 프롬프트 캐시를 깨지 않고 중간에 지시사항을 추가할 수 있습니다.
✅ beta 헤더 불필요 — 기본 Messages API에서 바로 사용 가능합니다.
❌ user 턴 직후에만 삽입 가능 — assistant 턴 직후나 배열 맨 앞은 안 됩니다.
❌ 연속된 system 메시지 두 개는 지원하지 않습니다.
관련 글