33차시. Modular RAG 최적화
퀴즈 2 — 통과한 답만 담는 캐시 만들기
질문의 앞뒤 공백을 없애고 소문자로 바꾼 것을 키로 쓰는 캐시를 만드세요. grade가 pass인 결과만 저장하고, 저장한 지 ttl초가 지난 항목은 쓰지 않습니다.
빈칸 코드에서 시작합니다.
def ask_with_cache(question, cache, run, now, ttl=3600):
pass결과 보기 (예시 풀이)
import hashlib
# 질문을 정리한 뒤 해시로 바꿔 캐시 키로 씁니다.
def _key(question):
return hashlib.md5(question.strip().lower().encode()).hexdigest()
# run: 실제 파이프라인을 대신하는 함수, now: 현재 시각(초)
def ask_with_cache(question, cache, run, now, ttl=3600):
k = _key(question)
hit = cache.get(k)
# 저장한 지 ttl초가 안 지났으면 저장된 결과를 복사해 돌려줍니다.
if hit and now - hit["at"] < ttl:
result = dict(hit["result"])
result["cached"] = True
return result
# 캐시에 없거나 너무 오래됐으면 파이프라인을 실제로 돌립니다.
result = run(question)
# 검증을 통과한 답만 저장합니다. 실패 안내가 계속 재사용되면 안 되기 때문입니다.
if result.get("grade") == "pass":
cache[k] = {"result": result, "at": now}
return result
# 파이프라인을 몇 번 돌렸는지 세는 가짜 실행 함수입니다.
runs = []
def fake_run(question):
runs.append(question)
if "환불" in question:
return {"answer": "환불은 7일 이내입니다.", "grade": "pass"}
return {"answer": "자료를 찾지 못했습니다.", "grade": "giveup"}
cache = {}
# 1) 처음 묻는 질문은 파이프라인을 돌립니다.
print(ask_with_cache("환불은 며칠 이내인가요?", cache, fake_run, now=0))
# 2) 공백과 대소문자만 다른 같은 질문은 캐시에서 바로 나와야 합니다.
print(ask_with_cache(" 환불은 며칠 이내인가요? ", cache, fake_run, now=10))
# 3) 실패한 답은 저장하지 않으므로 두 번 물으면 두 번 다 실행됩니다.
ask_with_cache("대표이사가 누구인가요?", cache, fake_run, now=20)
ask_with_cache("대표이사가 누구인가요?", cache, fake_run, now=30)
# 4) ttl(3600초)이 지나면 다시 실행합니다.
print(ask_with_cache("환불은 며칠 이내인가요?", cache, fake_run, now=4000))
print("파이프라인 실행 횟수:", len(runs))
print("캐시에 저장된 항목 수:", len(cache))
실행 결과
{'answer': '환불은 7일 이내입니다.', 'grade': 'pass'}
{'answer': '환불은 7일 이내입니다.', 'grade': 'pass', 'cached': True}
{'answer': '환불은 7일 이내입니다.', 'grade': 'pass'}
파이프라인 실행 횟수: 4
캐시에 저장된 항목 수: 1채점 기준: 실패한 답을 저장하거나 ttl이 지난 항목을 그대로 돌려주면 오답이다.