

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 모범 사례
<a name="semantic-caching-best-practices"></a>

## 캐시할 수 있는 데이터 선택
<a name="semantic-caching-bp-choosing-data"></a>

시맨틱 캐싱은 응답이 비교적 안정적인 반복 쿼리에 적합한 반면, 실시간 또는 매우 동적인 응답은 캐싱에 적합하지 않은 경우가 많습니다.

기존 애플리케이션 컨텍스트(예: 제품 ID, 범주, 리전 또는 사용자 세그먼트)에서 파생된 태그 및 숫자 필터를 사용하여 캐싱에 적합한 쿼리 및 응답을 결정하고 캐시 적중의 관련성을 개선합니다.

## 유사성 임계값 튜닝
<a name="semantic-caching-bp-threshold"></a>

유사성 임계값은 캐시 적중률과 응답 품질 간의 균형을 제어합니다. 사용 사례에 맞게 비용 절감과 정확성의 균형을 맞추는 임계값을 선택합니다.


| Threshold | 적중률 | 품질 위험 | 최적의 용도 | 
| --- | --- | --- | --- | 
| 0.95(엄격) | 낮음(\~25%) | 매우 낮음 | 의료, 법률, 금융 애플리케이션 | 
| 0.90(중간) | 중간(\~55%) | 낮음 | 일반 챗봇 | 
| 0.80(균형) | 높음(\~75%) | 낮음-중간 | FAQ 봇, IT 지원 | 
| 0.75(릴랙싱됨) | 매우 높음(\~90%) | 중간 | 대용량 반복 쿼리 | 

**중요**  
더 높은 임계값(0.90\~0.95)으로 시작하고 정확도를 모니터링하면서 점진적으로 낮춥니다. A/B 테스트를 사용하여 워크로드에 가장 적합한 균형을 찾습니다.

## 독립 실행형 쿼리와 대화 비교
<a name="semantic-caching-bp-standalone-vs-conversations"></a>
+ **독립 실행형 쿼리의 경우** - 사용자 쿼리 텍스트에 직접 의미 체계 캐싱을 적용합니다.
+ **멀티턴 대화의 경우** - 먼저 대화 메모리를 사용하여 현재 턴에 응답하는 데 필요한 주요 사실과 최근 메시지를 검색합니다. 그런 다음 전체 원시 대화를 포함하는 대신 현재 사용자 메시지와 검색된 컨텍스트의 조합에 의미 체계 캐싱을 적용합니다.

## 캐시 무효화 기간 설정
<a name="semantic-caching-bp-ttl"></a>

TTL을 사용하여 캐시 누락 시 재생성되기 전에 캐시된 응답이 제공되는 기간을 제어할 수 있습니다.


| 데이터 유형 | 권장 TTL | 이론적 근거 | 
| --- | --- | --- | 
| 정적 사실(문서, 정책) | 24시간 | 팩트가 자주 변경되지 않음 | 
| 제품 정보 | 12\~24시간 | 대부분의 카탈로그에서 매일 업데이트됨 | 
| 일반 어시스턴트 응답 | 1\~4시간 | 신선도와 적중률의 균형 | 
| 실시간 데이터(가격, 인벤토리) | 5\~15분 | 데이터가 자주 변경됨 | 
| 대화 컨텍스트 | 30 분 | 세션 범위, 단기 | 

```
# Set TTL with random jitter to spread out cache invalidations
import random

base_ttl = 82800  # ~23 hours
jitter = random.randint(0, 3600)  # Up to 1 hour of jitter
valkey_client.expire(cache_key, base_ttl + jitter)
```

**작은 정보**  
애플리케이션 사용 사례 및 데이터 또는 모델 출력 변경 빈도와 일치하는 TTLs을 설정합니다. TTLs 길수록 캐시 적중률이 증가하지만 오래된 답변의 위험이 높아집니다. TTLs 짧을수록 응답이 더 최신 상태로 유지되지만 캐시 적중률은 낮으며 더 많은 LLM 추론이 필요합니다.

## 모니터링 및 비용 추적
<a name="semantic-caching-bp-monitoring"></a>

캐시 성능 지표를 추적하여 시간 경과에 따라 의미 체계 캐시를 최적화합니다.

```
def record_cache_event(valkey_client, event_type: str):
    """Track cache hits and misses using atomic counters."""
    valkey_client.incr(f"cache:metrics:{event_type}")

    # Also track hourly for time-series analysis
    from datetime import datetime
    hour_key = datetime.now().strftime("%Y%m%d%H")
    counter_key = f"cache:metrics:{event_type}:{hour_key}"
    valkey_client.incr(counter_key)
    valkey_client.expire(counter_key, 86400 * 7)  # Keep 7 days

def get_cache_stats(valkey_client) -> dict:
    """Get current cache performance metrics."""
    hits = int(valkey_client.get("cache:metrics:hit") or 0)
    misses = int(valkey_client.get("cache:metrics:miss") or 0)
    total = hits + misses
    hit_rate = hits / total if total > 0 else 0

    avg_cost_per_call = 0.015  # Example: ~$0.015 per LLM call
    savings = hits * avg_cost_per_call

    return {
        "total_requests": total,
        "hits": hits,
        "misses": misses,
        "hit_rate": round(hit_rate, 3),
        "estimated_savings_usd": round(savings, 2),
    }
```

## 메모리 관리
<a name="semantic-caching-bp-memory"></a>
+ **최대 정책 설정 **- 클러스터가 메모리 제한`maxmemory-policy allkeys-lru`에 도달하면 least-recently-used 캐시 항목을 자동으로 제거하도록 ElastiCache 클러스터에서를 구성합니다.
+ **용량 계획** - 각 캐시 항목에는 일반적으로 약 4\~6KB(임베딩 차원 × 4바이트 \+ 쿼리 텍스트 \+ 응답 텍스트)가 필요합니다. 1GB ElastiCache 인스턴스는 약 170,000개의 캐시된 항목을 저장할 수 있습니다.
+ **오래된 데이터에 캐시 무효화 사용 **- 기본 데이터가 변경될 때 텍스트 검색을 사용하여 관련 캐시 항목을 찾고 무효화합니다.

  ```
  def invalidate_by_topic(valkey_client, topic_keyword: str):
      """Remove cached entries matching a topic after a data update."""
      results = valkey_client.execute_command(
          "FT.SEARCH", "semantic_cache",
          f"@query:{topic_keyword}",
          "NOCONTENT",  # Only return keys, not fields
      )
  
      if results[0] > 0:
          keys = results[1:]
          for key in keys:
              valkey_client.delete(key)
          print(f"Invalidated {len(keys)} cached entries for '{topic_keyword}'")
  ```