AI

[백엔드] 다국어 챗봇 타임존 단일 소스 LLM 컨텍스트 오염

jykim23 2026. 7. 9. 10:36
반응형

다국어 챗봇 타임존 단일 소스 settings 계산 전용 스칼라 컨텍스트

부제: 사용자 시간대를 어디에 두고, 프롬프트엔 왜 안 넣었나

다국어 챗봇이 제대로 답하려면 사용자별로 두 값이 있어야 한다.
하나는 응답 언어(language), 하나는 현지 시각(timezone)이다.
언어가 틀리면 엉뚱한 말로 답하고, 시간대가 어긋나면 "지금 몇 시"·"오늘"이 틀린다.

문제는 이 두 값이 어디에 저장되고 어떻게 프롬프트에 들어가느냐였다.

두 가지 결함

정리하다 보니 시간대에서 결함이 두 개 보였다.

첫째, 소스가 흩어져 있었다.
채팅·프롬프트는 device.timezone을 읽고, 유휴 요약 잡은 settings.timezone을 읽었다.
한쪽에만 값이 저장된 유저는 서브시스템마다 시간대가 달랐다.

둘째, 시간대 문자열이 대화에 새어 들어갔다.
프롬프트를 만들 때 device 정보를 통째로 <device> 블록에 덤프하고 있었는데,
거기에 timezone 문자열이 그대로 실렸다.
시각 계산에만 쓰려던 값이 LLM에게 텍스트로 노출돼서, 뜬금없이 대화에 영향을 줬다.

시간대의 정답 위치를 하나로

먼저 저장 위치를 정리했다.
시간대의 단일 소스는 settings.timezone 하나로 두고, device.timezone은 버렸다.
확인해 보니 그 값은 아무도 안 읽는 죽은 필드였다.

resolve_timezone(settings) 하나가 이 값을 해석하고,
기본값이 없으면 Asia/Seoul로 떨어진다.
사용자가 넣은 시간대 문자열이 이상하거나 악의적인 경로(../ 같은)여도
방어 함수에서 기본값으로 물러나게 해서, 컨텍스트를 만들다 서버가 죽지 않게 했다.

프롬프트엔 문자열로 넣지 않는다

핵심 결정은 이거였다.
시간대는 계산에만 쓰는 값이지, LLM에게 보여줄 텍스트가 아니다.

그래서 시간대를 렌더링되는 컨텍스트 블록 어디에도 넣지 않기로 했다.
경계에서 딱 한 번 스칼라 값으로 해석해서 계산 입력으로만 흘린다.
<datetime>에는 계산된 현재 시각만 찍고 시간대 문자열은 빼고,
<device>에서는 timezone 키만 제외하고 나머지(심박·페이스 같은 값)는 남겼다.

설정 dict를 통째로 프롬프트 경로에 넣지 않은 이유도 같다.
그러면 시간대 말고 다른 설정 키까지 딸려 나갈 위험이 있다.
그래서 설정을 렌더링하는 블록은 아예 만들지 않고, 필요한 시간대 하나만 뽑아 넘겼다.

기본값은 생성할 때만 채운다

언어·시간대가 비어 있으면 한국 기본값으로 채우는데,
이걸 스키마의 기본값(default)으로 두지 않고 계정 생성 시점에서만 채우게 했다.

이유가 있다.
사용자 정보 수정이 "통째로 교체" 방식이라, 필드 기본값을 "ko"로 박아 두면
수정 요청에서 언어를 빠뜨렸을 때 원래 영어 유저를 한국어로 덮어쓰는 사고가 난다.
그래서 채우는 건 생성 엔드포인트에서만 한다.

언어 자체는 분기 코드를 두지 않았다.
"무슨 언어로 답할지"는 LLM의 추론에 맡기고, 대신 프로필에 언어 신호만 실어 준다.

검증

한국 표준 유저를 복제해서 인도네시아 계정으로 바꿨다.
언어를 id, 시간대를 Asia/Jakarta로만 바꾸고 나머지는 똑같이 둔 채 비교했다.

  • 러너 타입 분석 카드가 인도네시아어로 나오고 DB에도 그렇게 저장됐다
  • 채팅에서 "지금 몇 시냐"에 "Sekarang pukul 13:55"로 자카르타 시각을 답했다. 서울(15:55)이 아니었다

시간대는 계산에만 흘러 시각은 맞고, 프롬프트에는 문자열이 안 보여 대화는 깨끗했다.

정리

  • 시간대의 단일 소스를 settings 하나로 두고, 죽은 device.timezone은 버렸다
  • 시간대는 계산 전용 스칼라로만 흘리고, 렌더링되는 컨텍스트에는 문자열로 넣지 않았다 — LLM 오염 차단
  • 설정 dict를 통째로 넘기지 않고 필요한 값 하나만 경계에서 해석해 전달했다
  • 기본값 채우기는 생성 시점에서만 — 수정이 기존 유저를 덮어쓰는 사고를 막기 위해

값이 계산에 필요한 것과 모델에게 보여줄 것은 다르다.
이 둘을 섞지 않는 것만으로 시간대 문제의 절반은 정리됐다.

반응형