
부제: 시스템 프롬프트는 고정하고, 사용자 정보는 바뀐 부분만 다시 넣은 이유
토큰 비용을 아끼려면 프롬프트 캐싱이 중요하다.
캐시가 먹으려면 캐시되는 앞부분, 즉 시스템 프롬프트가 고정돼 있어야 한다.
문제는 사용자 정보가 매 턴 필요하다는 거였다.
왜 매 턴 사용자 정보가 필요했나
특히 "지금이 아침인지 저녁인지"를 모델이 알아야 했다.
저녁인데 오전 일정을 이야기하거나, 저녁에 아침 인사를 하면 대화가 어긋난다.
아침이면 아침 인사, 저녁이면 저녁에 맞는 응대를 하려면 시각 정보가 매 턴 들어가야 한다.
그런데 이걸 시스템 프롬프트에 넣으면 끝이다.
시각은 1분만 지나도 바뀌니, 캐시되는 앞부분이 계속 달라져 캐시가 매번 깨진다.
캐시를 살리려던 게 무너진다.
시스템 프롬프트는 건드리지 않는다
그래서 동적 정보를 시스템 프롬프트에서 빼고, 사용자 메시지 앞에 <context> 블록으로 붙였다.
시스템 프롬프트는 완전히 고정한 채, 변하는 건 전부 사용자 메시지 쪽에 실었다.
여기서부터 커졌다.
사용자 정보는 회원가입 정보에, 디바이스·커스텀 같은 추가 정보까지 여러 섹션이다.
이걸 매 턴 통째로 넣으면 이번엔 그게 토큰 낭비가 된다.
바뀐 섹션만 다시 넣는다
그래서 델타 방식으로 갔다.
전체 컨텍스트를 만들어두고, 매 턴 새로 빌드해서 이미 넣은 것과 비교한다.
바뀐 섹션만 다시 주입한다. 디바이스 정보만 바뀌었으면 <device>만 넣는 식이다.
영리했던 건 "무엇이 바뀌었나"를 판정하는 방법이었다.
소스의 수정 시각(updated_at) 같은 메타데이터를 추적하지 않았다.
대신 렌더된 텍스트 자체를 버전으로 봤다.
이번에 렌더한 결과가 지난번 넣은 것과 다르면 재주입한다.
이러면 데이터 스키마가 바뀌어도 별도 로직 없이 자동으로 맞는다.
대화 요약이 새로 생기면 이 원장을 통째로 비운다.
그럼 다음 턴에 모든 섹션이 다시 채워지고, 요약도 한 번 주입된다.
정리
- 캐시를 살리려면 시스템 프롬프트가 고정돼야 하는데, 사용자 정보(특히 시각)는 매 턴 바뀐다
- 동적 정보를 시스템 프롬프트에서 빼 사용자 메시지 앞
<context>블록으로 옮겼다 - 매 턴 전체를 넣으면 토큰 낭비 → 이미 넣은 것과 비교해 바뀐 섹션만 재주입(델타)
- "바뀜" 판정은 소스 메타가 아니라 렌더된 텍스트 자체로 — 스키마 변화에 자동으로 견고
- 요약이 생기면 원장을 비워 다음 턴에 전부 재주입
캐시를 살리려면 변하는 걸 캐시되는 자리에 두지 마라.
동적 정보는 사용자 메시지로 옮기되, 매번 전부가 아니라 바뀐 섹션만 넣는다.
무엇이 바뀌었는지는 렌더된 결과 자체로 판정하면 메타 추적 없이 튼튼하다.
'AI' 카테고리의 다른 글
| [에이전트] LLM 카드 플래그 없는 설계 환각 방지 서버 계산 (0) | 2026.08.02 |
|---|---|
| [동시성] 락 대기가 클라이언트 타임아웃보다 길면 안 되는 이유 (0) | 2026.08.02 |
| [에이전트] 무엇을 잊을지의 설계, 자주 꺼낸 기억일수록 오래 남긴다 (0) | 2026.08.01 |
| [RAG] 문서 청킹 토큰 경계 TEI tokenize 413 에러 차단 (0) | 2026.07.30 |
| [에이전트] 신경과학까지 뒤졌지만 대부분 안 썼다, 연구와 구현 사이 (0) | 2026.07.30 |