익명 체험 상담
상담 내용 대화 저장 고지 및 저장 기능 설정 토글
rerank 방식을 LLM → Ko-Bert 로 변경
성경 구절 검색 후 구절을 활용하여 llm 이 최종 답변 생성 하도록 수정
→ 기본 로컬 LLM / 사용자가 OPENAI_API_KEY를 UI 에서 입력하면 자신의 OPENAI API LLM 을 호출(키가 없으면 기본 로컬 LLM 호출)
→ 전반적인 테스트 결과 정상적이면 클라우드 이관을 통해 앱배포 준비를 해볼 것!
** OpenAI API KEY 를 일단 내 KEY 로 적용(서버 키로 사용)
⇒ 사용자가 개인의 OpenAI API Key를 사용하고 싶으면 설정 탭에서 설정하도록!
0) 공통 목표: “서버가 최종 집행자”로 만들기
프론트가 store_messages를 보내도 서버가 마지막으로 검증/강제해야 합니다.
“익명 체험”에서는 무조건 false (프론트가 true 보내도 무시)
“로그인 사용자”는 서버 DB에 저장된 유저 설정값을 우선 적용 (클라이언트 토글만 믿지 않기)
이때, 턴과 TTL 은 Redis 가 관리하도록 개발
1) 익명 체험 상담 기능 (Anonymous Trial)
1-1. 백엔드: conversation 모델에 “모드”와 “TTL/턴 제한” 추가
Conversation 메타에 최소 필드 3개만 추가하면 운영이 쉬워집니다.
conversation_id: UUID
mode: "anonymous" | "authenticated"
store_messages: bool (익명은 항상 false)
expires_at: datetime (예: now + 2h)
turn_limit: int (예: 10)
turn_count: int (서버에서 증가)
DB 테이블로 만들지 않아도 됩니다. 익명은 메모리/Redis에만 둬도 OK.
저장 위치(추천)
Redis(권장): TTL 자동 삭제가 깔끔함
없다면 서버 메모리(Map) + 주기적 청소(하지만 멀티 인스턴스에서 꼬일 수 있음)
1-2. 백엔드: POST /v1/chat/conversations 로직 수정
프론트에서 store_messages를 보내더라도 서버가 모드에 따라 강제합니다.
규칙
요청이 익명이면
store_messages = false 강제
expires_at = now + TTL
turn_limit = N
turn_count = 0
요청이 로그인 사용자면
store_messages = (유저 설정값)으로 최종 결정
(프론트 payload는 참고만 하거나 무시하는 게 더 안전)
1-3. 백엔드: 메시지 처리 API에서 “턴 제한/TTL” 강제
메시지 저장/응답 전에 체크:
expires_at < now 이면
410 Gone (또는 401) + “세션이 만료되었습니다”
turn_count >= turn_limit 이면
429 (또는 403) + “체험 턴이 종료되었습니다”
통과하면:
turn_count += 1
store.add_message(...) 호출 (이미 구현된 분기 로직 그대로 사용)
포인트: turn_count 증가도 서버가 해야 남용/조작을 막습니다.
1-4. 프론트: 익명 체험 UI 필수 요소 3개
“익명 체험: 저장되지 않음” 고정 배지
“남은 턴 표시: 3/10”
제한 도달 시 화면:
로그인 유도 버튼 (강요 느낌 X)
“저장 옵션은 로그인 후 설정에서 선택 가능” 안내
2) 최초 실행 시 “대화 저장 고지 + 설정 가능” 구현
여기서 중요한 건: (1) 최초 실행 고지와 **(2) 저장 토글(설정)**을 “서로 다른 개념”으로 분리하는 겁니다.
최초 실행 고지: “당신은 선택할 수 있다”를 명확히 알리는 UI
실제 저장 여부: 서버 정책에 의해 집행되는 store_messages
2-1. 프론트: 최초 실행 여부 체크 & 로컬 저장
저장 키 (예시)
has_seen_privacy_notice: true
chat_storage_consent: true|false ← 사용자가 선택한 “기본값”
Web: localStorage
RN: AsyncStorage 또는 가능하면 SecureStore
2-2. 프론트: 최초 실행 모달/화면 구성(권장 3줄)
익명 체험: “대화는 저장되지 않고 앱을 닫으면 사라집니다”
로그인 사용자: “대화 저장은 설정에서 켠 경우에만 저장됩니다”
안전: “위기 표현이 감지되면 상담이 제한되고 도움 안내가 제공될 수 있습니다”
버튼 2개:
[동의하고 시작] → chat_storage_consent = true
[저장하지 않고 사용] → chat_storage_consent = false
마지막에:
“언제든 설정에서 변경 가능” 짧게 표시
2-3. 서버 연동: 최초 선택값을 “바로 저장”하지 말고 이렇게 처리
당신이 말한 대로 로컬에만 저장하는 방향은 좋아요(특히 익명/비로그인 구간).
다만 “로그인 사용자”가 등장하는 순간, 서버에서 최종 설정값을 보장해야 토글 신뢰성 문제가 사라집니다.
추천 방식(현실적인 타협)
최초 실행 선택은 로컬에만 저장 OK
사용자가 로그인한 순간:
프론트가 서버에 “내 기본값을 서버 설정으로 반영할래?”를 1회 요청
서버는 user_settings.store_messages_default에 저장
이후부터는 서버 설정이 기준
즉,
익명/비로그인: 로컬 기준
로그인 이후: 서버 기준 (정합성/법적 방어력↑)
3) UI “대화 저장” 설정 모달 추가 (ON/OFF)
3-1. 서버: 사용자 설정 저장 테이블(또는 기존 settings)에 필드 추가
예: user_settings
user_id
store_messages: boolean (기본 false)
updated_at
핵심: 매 메시지 저장 전에 서버가 이 값을 조회해 최종 결정.
3-2. API 추가 (권장)
GET /v1/users/me/settings
현재 store_messages 상태 반환
PATCH /v1/users/me/settings
{ "store_messages": true|false }
중요 규칙
익명: 이 API 접근 불가(401)
로그인만 가능
3-3. 프론트: 설정 토글 UI + “변경 확인 모달”
설정 화면에 토글 하나:
“대화 저장”
토글을 ON으로 바꾸는 순간 모달 1회 띄우기(정책적으로 강함):
모달 내용(핵심만):
저장되는 것: “대화 내용(질문/답변)”
목적: “상담 품질 제공/이력 제공(또는 기능 목적)”
철회: “언제든 OFF 가능”
삭제: “삭제 경로(설정/문의)를 제공” (당장 기능 없으면 운영정책이라도)
버튼:
[동의하고 저장 켜기]
[취소]
OFF는 모달 없이 바로 적용해도 괜찮습니다(법적으로 더 안전).
3-4. “설정 OFF → 즉시 효력” 구현 (추천 방식)
가장 깔끔한 구현은 이거예요:
사용자가 OFF로 바꾸는 순간:
서버에 PATCH로 store_messages=false
프론트는 현재 대화방 종료
새 conversation 생성 시 store_messages=false로 시작
즉,
기존 대화방은 (이미 저장되고 있었다면) 그대로 남을 수 있음(실무에서 흔함)
새 대화부터 저장이 멈춤 (즉시 효력)
추가 옵션(선택):
“기존 대화도 삭제” 버튼은 별도 기능으로 분리(나중에)
4) “정책이 진짜”가 되게 만드는 운영/로그 설정 체크리스트 (필수)
익명/비저장 모드에서 절대 하면 안 되는 것:
Reverse proxy access log에 request body 기록
앱/서버 debug 로그에 prompt/response 출력
Sentry/APM에 request body 자동 첨부
LLM 벤더 tracing에 prompt 저장
최소한 이것만은 바로 점검하세요:
(서버) request logging 미들웨어가 body 찍는지
(Sentry) send_default_pii, before_send에서 message 제거
(Nginx) log_format에 $request_body 같은 변수 쓰는지
5) 당신이 “바로 수정”할 수 있게 오늘 할 일 순서
서버: 익명 모드 강제 규칙 추가
익명은 store_messages=false 강제
TTL + turn_limit + turn_count 체크
프론트: 최초 실행 고지 화면 + 로컬 저장
has_seen_privacy_notice
chat_storage_consent
서버: 사용자 설정 API 2개 추가
GET/PATCH settings
프론트: 설정 토글 + ON 전 확인 모달
OFF 즉시 적용 + 새 conversation 생성
운영 설정: 로그/에러/트레이싱에서 본문 제거