LLM을 활용한 애플리케이션에서는 비용과 레이턴시가 과제가 될 수 있습니다.
많은 LLM API는 입력 토큰과 출력 토큰 사용량에 따라 요금이 발생합니다. 대화 기록, 긴 시스템 프롬프트, RAG로 가져온 문서를 매번 전송하면 요청 횟수 증가에 따라 비용도 누적됩니다.
같은 조건의 질문에 여러 번 답변하고 있다면, 과거 답변을 재사용할 수 있는 가능성이 있습니다. 또한, 대화 기록 전체를 매번 보내는 대신 필요한 정보만 선택하여 입력 토큰을 줄일 수 있습니다.
LLM 추론은 일반적인 캐시나 데이터베이스 조회보다 시간이 더 걸릴 수 있습니다. 특히 AI 에이전트의 경우, 하나의 요청에 대해 여러 번의 LLM 호출이나 도구 실행이 발생하여 처리 전체의 레이턴시가 누적될 수 있습니다.
재사용 가능한 답변 생성을 줄이거나 LLM에 전달하는 정보를 좁힘으로써 응답 시간을 단축할 가능성이 있습니다.
'응답 캐시(回答キャッシュ)'와 '프롬프트 캐싱(Prompt Caching)'은 둘 다 재활용을 통해 처리를 효율화하지만, 저장하는 내용과 히트 시 절약되는 처리 과정이 다릅니다.
| 응답 캐시 | Prompt Caching |
|---|
| 주로 관리하는 곳 | 애플리케이션이나 캐시 기반 시스템 |
| ... | |
| 응답 캐시에 히트하면, 애플리케이션은 저장된 답변을 반환하고 처리를 마칠 수 있습니다. 반면, Prompt Caching은 이전 답변을 돌려주는 것이 아닙니다. 공통되는 프롬프트 부분을 효율적으로 처리하여 해당 요청에 대한 답변을 다시 생성합니다. | |
본 기사에서는 응답 캐시를 중심으로 이야기하겠습니다. LLM 애플리케이션을 개발할 때, Prompt Caching은 보통 LLM 프로바이더 측의 기능으로 제공되기 때문에, 개발자가 직접 캐시 내용을 관리하는 경우는 많지 않기 때문입니다.
하지만, Prompt Caching을 의식할 필요가 없다는 의미는 아닙니다. 구현 방식은 프로바이더마다 다르지만, 많은 경우 시스템 프롬프트나 공통 참조 문서를 프롬프트의 맨 앞에 고정 배치하는 등 캐시가 효과를 보기 쉬운 형태로 입력을 설계하는 것도 가능합니다.
또한 채팅형 앱에서는 캐시에 더하여 세션 컨텍스트 관리도 토큰 절약에 도움이 됩니다. 대화 기록 전체를 매번 보내는 대신, 직전 발언이나 요약 등 답변에 필요한 정보만 프롬프트에 포함시키는 방식도 소개되었습니다.
- LLM API 호출 횟수를 줄일 수 있습니다.
- 캐시에 히트할 경우, LLM의 답변 생성을 건너뛸 수 있습니다.
- LLM 프로바이더로의 부하 집중이나 레이트 제한 영향을 완화할 수 있습니다.
다만, 챗봇 같은 AI 애플리케이션에서는 문자열이 완전히 동일한 요청인 경우는 아닐 수 있습니다. 예를 들어, 다음 질문들은 표현은 다르지만 답변은 같아도 괜찮을 예시일 것입니다.
같은 질문이라도 사용자 권한이나 참조 문서가 다르면 적절한 답변이 달라질 수 있습니다. 테넌트나 사용자의 데이터가 섞이지 않도록 캐시의 검색 범위도 분리해야 합니다.
세맨틱 캐시(Semantic Cache)는 문자열 그 자체가 아니라, 질문의 의미가 비슷한지 여부를 기준으로 과거의 답변을 찾는 방법입니다.
- 사용자 질문을 임베딩(Embedding) 모델로 벡터에 변환합니다.
- 저장된 질문 벡터를 검색합니다.
- 유사도나 검색 조건을 확인합니다.
- 재사용 가능하다고 판단되면, 저장된 답변을 반환합니다.
- 해당 답변이 없으면 LLM을 호출하고, 질문과 답변을 저장합니다.
예를 들어, 다음 질문들은 문자열로 일치하지 않습니다.
① 비밀번호를 리셋하는 방법은?
② 비밀번호를 잊어버렸을 때는 어떻게 해야 하나요?
하지만 임베딩 공간에서는 가까운 벡터가 될 가능성이 있습니다. 세맨틱 캐시를 사용하면, 두 번째 질문에 대해 첫 번째 답변을 재사용할 수 있는 경우가 있을 수 있습니다.
벡터의 유사도가 높다고 해서 답변까지 같지는 않습니다. 계약 내용, 상품, 시기, 사용자별 조건이 다른 질문에서는 잘못된 답변을 반환할 가능성이 있습니다. 유사도의 임계값은 실제 데이터로 조정하고, 이 역시 완전 일치 캐시와 마찬가지로 필요에 따라 테넌트나 카테고리 등의 조건으로 검색 대상을 좁힙니다. 업데이트 빈도가 높은 정보에는 유효 기간(TTL)이나 캐시를 무효화하는 메커니즘도 검토해야 합니다.
콜센터, 고객 지원, FAQ 챗봇 등 같은 의도의 질문이 다른 표현으로 반복되는 시스템에서는 효과가 클 수 있습니다.
세션 컨텍스트 관리(Session Context Management)는 캐시와 목적이 다릅니다. 챗봇이나 AI 에이전트가 대화를 이어가기 위해, 과거 발언에서 필요한 정보를 골라 현재 질문과 함께 LLM에 전달하는 방법입니다.
대화 기록을 매번 모두 보내면, 대화가 길어질수록 입력 토큰이 늘어납니다. 그래서 대화 기록을 저장하고, 현재 질문과 관련된 정보만 골라 컨텍스트를 구성합니다. Redis는 저장소의 한 예시입니다.
- 최근 몇 건의 메시지
- 전체 대화 또는 과거 대화 요약
- 사용자가 명시한 제약이나 선호도
- 에이전트가 실행한 도구 결과
- 필요에 따라, 과거 대화를 검색하기 위한 임베딩
예를 들어, Redis에서는 다음과 같이 대화 기록, 요약, 중요 정보를 분리하여 관리할 수 있습니다.
session:{session_id}:messages
session:{session_id}:summary
session:{session_id}:facts
LLM에 전달하는 컨텍스트는 예를 들어 다음과 같이 구성합니다.
시스템 프롬프트
+ 전체 대화 요약
+ 현재 질문과 관련된 과거 정보
...
요약이나 사용자 정보를 언제 업데이트할지, 어느 기간 보관할지도 설계가 필요합니다. 개인정보 등을 다루는 경우에는 저장하는 정보와 보존 기간을 최소한으로 해야 합니다.
이 부분은 LLM 제공사 측의 프롬프트 캐시(Prompt Cache) 히트를 고려하여 조정해야 합니다.
Redis 아티클을 통해, 완전 일치 캐시나 세맨틱 캐시에 의한 답변 재사용, 세션 컨텍스트 관리에 의한 대화 상태 관리 등이 LLM 앱의 비용이나 토큰 소비 절감에 도움이 된다는 것을 배웠습니다.
이 모든 것을 일률적으로 도입하는 것이 아니라, 캐시 히트율, 토큰 사용량, API 요금, 레이턴시 등의 지표를 확인하고, 병목 현상(Bottleneck)에 따라 적절한 메커니즘을 단계적으로 도입 및 개선해 나가는 것이 중요하다고 느꼈습니다.