---
tags: [rb8001, prompt-db, closed-loop, worklog]
---

# 프롬프트 DB 폐루프 P1 구현 및 검증 완료

## 관련 문서
- [프롬프트 DB 응답생성 폐루프 미연결](../troubleshooting/260310_프롬프트DB_응답생성_폐루프_미연결.md)
- [프롬프트 DB 폐루프 및 하드코딩 잔존 전수 조사 리서치](../research/260319_프롬프트DB_폐루프_및_하드코딩_잔존_전수조사_리서치.md)
- [프롬프트 동적 관리 시스템 계획](../plans/251225_프롬프트_동적관리_계획.md)

## 완료 요약
- `llm_service.py`의 `process_request()` 진입 시 DB 활성 프롬프트를 조회하여 `context['db_system_prompt']`로 주입하는 폐루프를 연결했습니다.
- `openai_handler.py`, `gemini_handler.py` 모두 `db_system_prompt`가 있으면 하드코딩 대신 사용합니다.
- P1 프롬프트 2건(`system_chat_openai`, `system_chat_gemini`)을 DB에 v1으로 적재했습니다.
- TTL 60초 메모리 캐시로 DB 부하를 방지합니다.
- `skip_default_prompt` 경로(RAG 등)는 영향 없음을 테스트로 확인했습니다.

## 코드 반영 내용
- `app/services/llm/llm_service.py`: `_get_active_prompt_from_db()` 캐시 함수 추가, `process_request()` 내 DB 프롬프트 주입 로직
- `app/services/llm/openai_handler.py`: `db_system_prompt` 우선 사용 (chat, stream_chat 두 경로)
- `app/services/llm/gemini_handler.py`: `db_system_prompt` 우선 사용 (chat 두 경로)
- `scripts/seed_p1_prompts.py`: P1 프롬프트 DB 적재 스크립트
- `tests/test_prompt_db_closed_loop.py`: 7건 테스트

## 검증 결과
- 단위 테스트: 7 passed (캐시 히트, 캐시 만료, DB 실패, DB 없음, DB 주입, fallback, RAG 비영향)
- DB 적재: `system_chat_openai` v1 active (id=7), `system_chat_gemini` v1 active (id=8)
- 폐루프 검증: v2 생성 → 활성화 → 캐시 비움 → DB에서 v2 프롬프트 읽힘 → v1 복원 정상
- 배포: 24 서버 rb8001 재빌드 후 health 정상
- rb8001 commit: `2bda17f`

## 닫힘 기준 충족 확인
- [x] 최소 1개 운영 경로에서 활성 프롬프트 버전이 응답 생성 전에 실제로 주입된다
- [x] DB에서 활성 버전을 바꾸면 실제 응답이 바뀐다 (v2 TEST-V2 검증)
- [x] DB 조회 실패 시 하드코딩 fallback 정상 동작
- [x] RAG 경로 영향 없음

## E2E 검증 결과 (실제 응답 확인)
- v1 활성 시 `"안녕 넌 누구야?"` → `안녕하세요, 사용자님. 저는 스타트업 대표 전용 AI 어시스턴트 Robeing입니다...`
- v2 활성 시 (`TEST-V2 prefix 지시`) `"안녕"` → **`TEST-V2: 안녕하세요, 사용자님. 만나서 반갑습니다...`**
- DB 프롬프트 변경이 실제 LLM 응답에 반영됨을 확인

## E2E 테스트용 JWT 생성 방법
```bash
# 컨테이너 내부에서 테스트용 JWT 발급
docker exec rb8001 python3 -c "
import jwt, os
secret = os.getenv('JWT_SECRET_KEY')
token = jwt.encode({'sub': 'test-uuid-001', 'username': 'testuser'}, secret, algorithm='HS256')
print(token)
"

# /api/message 호출
curl -s http://127.0.0.1:8001/api/message \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"text":"안녕"}'
```

## 캐시 주의사항
- 캐시는 서빙 프로세스 메모리에 있으므로 `docker exec`로 별도 프로세스에서 `_prompt_cache.clear()`해도 효과 없음
- DB 프롬프트 변경 후 반영까지 최대 60초(TTL) 대기 필요
- 즉시 반영이 필요하면 컨테이너 재시작

## 결론
- 트러블슈팅 `260310_프롬프트DB_응답생성_폐루프_미연결.md`는 종결합니다.
