AI에게 더 많은 장소 데이터를 주면 더 좋은 랜딩페이지가 나올 것처럼 보였다. 하지만 "현재 영업 중" 같은 값은 생성 시점에는 맞아도 정적 HTML로 저장되는 순간 위험한 정보가 된다. 그래서 이 문제는 prompt wording이 아니라 출력물의 수명과 맞지 않는 데이터를 payload에서 빼는 데이터 모델링 문제로 봤다.
요약
- 문제: AI가 만든 정적 랜딩페이지에 "현재 영업 중" 같은 생성 시점 정보가 그대로 박제될 수 있었다.
- 판단: 모델에게 "쓰지 마"라고 말하기보다, 정적 출력물의 수명과 맞지 않는 데이터는 애초에 주지 않는 편이 안전했다.
- 해결:
current_opening_hours처럼 시점에 의존하는 데이터는 final generation payload에서 제거하고, 지속 가능한 영업시간만 남겼다. - 배운 점: 정적 페이지에 넣을 데이터와 요청 시점에만 유효한 데이터는 다르게 다뤄야 한다.
상황
Place2Page는 장소 정보를 받아 정적 랜딩페이지를 만든다. 사용자가 URL을 넣으면 장소명, 주소, 사진, 리뷰, 메뉴, 영업시간 같은 데이터를 가져오고, AI가 이를 바탕으로 HTML을 생성한다.
처음에는 가능한 많은 정보를 모델에게 주는 게 좋다고 생각했다. 데이터가 많으면 더 풍부한 페이지를 만들 수 있기 때문이다.
영업시간도 마찬가지였다. 정규 영업시간뿐 아니라 현재 영업 중인지, 언제 닫는지 같은 정보가 있으면 방문 계획 섹션이 더 좋아질 것처럼 보였다.
그런데 정적 페이지라는 점을 생각하면 문제가 생긴다.
문제
생성 시점에 "현재 영업 중"이 맞았다고 해도, 그 말이 다음 날에도 맞는 것은 아니다.
예를 들어 월요일 밤에 페이지를 생성하면서 AI가 이렇게 썼다고 해보자.
현재 영업 종료 상태입니다.
이 문장은 생성 당시에는 맞을 수 있다. 하지만 이 HTML은 정적 페이지로 저장된다. 화요일 낮에 사용자가 들어와도 여전히 "현재 영업 종료"라고 보일 수 있다.
반대로 일요일 오후에 "현재 영업 중"이라고 생성된 페이지가 월요일 휴무일에도 계속 그렇게 보일 수도 있다.
이건 단순한 문구 문제가 아니다. 사용자가 방문 결정을 할 때 영향을 줄 수 있는 잘못된 정보다.
처음 생각한 가설
처음에는 프롬프트에서 "현재 상태를 쓰지 말라"고 하면 될 것 같았다.
하지만 모델 입력에 current_opening_hours 같은 데이터가 들어가 있으면, 모델은 그 정보를 중요한 사실로 본다. 특히 랜딩페이지 생성 모델은 "방문 계획에 유용한 정보를 보여줘야 한다"는 목표를 가지고 있기 때문에, 현재 영업 상태를 페이지에 넣으려고 한다.
즉, 프롬프트만으로 막기에는 약했다. 모델에게 주지 말아야 할 데이터는 애초에 payload에서 빼야 했다.
확인한 증거
문제는 Naver place fetch와 Google place fetch 양쪽에서 모두 발생할 수 있었다.
정규 영업시간은 비교적 안정적인 정보다. "월-금 10:00-21:00" 같은 문장은 페이지에 남아 있어도 괜찮다. 사용자가 직접 현재 요일과 시간을 보고 판단할 수 있기 때문이다.
하지만 "Open now", "Currently closed", "영업 종료", "곧 영업 시작" 같은 문장은 다르다. 이 정보는 요청 시각과 강하게 묶여 있다.
생성 pipeline에서 이 데이터가 final model input에 들어가면, prompt가 아무리 조심스러워도 모델이 다시 visible copy로 끌어올 가능성이 있었다.
그래서 증거를 코드와 테스트에서 같이 봤다.
generation payload 테스트에는 일부러 시점 의존 데이터가 들어간다.
{
"opening_hours": [
"영업 종료",
"10시 30분에 영업 시작",
"매일 10:30 - 20:00",
"Sunday: Closed"
],
"current_opening_hours": {
"open_now": false,
"next_open_time": "2026-05-15T10:30:00+09:00",
"next_close_time": "2026-05-15T20:00:00+09:00"
}
}그리고 기대 결과는 반대다. final model input에서는 current_opening_hours가 없어야 하고, opening_hours에는 오래 남겨도 되는 라인만 있어야 한다.
"current_opening_hours" not in payload["place_source_data"]
payload["place_source_data"]["opening_hours"] == [
"매일 10:30 - 20:00",
"Sunday: Closed"
]Naver fetcher 테스트도 같은 방향이다. 입력에는 "영업 종료", "10시 30분에 영업 시작" 같은 fetch-time status가 있지만, normalized 결과에서는 opening_hours가 비거나 정규 영업시간만 남고 current_opening_hours는 None이 된다.
커밋 단위로 봐도 이 수정은 prompt 한 줄이 아니었다. d64b0ab0 Fix static opening hours in generated pages는 prompt 파일뿐 아니라 generation_service.py, naver_place_fetcher.py, 그리고 관련 테스트를 같이 바꿨다. 이게 이 문제를 데이터 모델링 문제로 본 이유다.
해결한 방식
해결은 두 겹으로 했다.
첫째, generation payload에서 시점 의존 데이터를 제거했다. current_opening_hours처럼 현재 상태를 나타내는 필드는 final HTML 생성 입력에 넘기지 않도록 했다.
둘째, fetcher 쪽에서도 정적 snapshot에 넣을 수 있는 영업시간만 남기도록 정리했다. 현재 상태 문구가 섞여 들어오면 제거하고, 지속 가능한 정규 영업시간 라인만 남기는 식이다.
셋째, prompt contract에서도 current_opening_hours를 적극 사용하라는 문구를 제거했다. 모델에게 "있으면 써라"라고 말하는 순간 다시 같은 문제가 생길 수 있기 때문이다.
왜 데이터 모델링 문제였나
이 문제는 결국 프롬프트 문제가 아니라 데이터 모델링 문제였다.
AI에게 어떤 데이터를 줄 것인가를 정할 때 "유용해 보이는가"만 보면 안 된다. 그 데이터가 출력물의 수명과 맞는지도 봐야 한다.
정적 페이지는 생성된 뒤 오래 남는다. 그러면 입력 데이터도 오래 남아도 되는 정보여야 한다.
- 주소는 오래 남아도 된다.
- 대표 메뉴는 어느 정도 오래 남아도 된다.
- 정규 영업시간도 비교적 오래 남아도 된다.
- 하지만 현재 영업 상태는 오래 남으면 안 된다.
시간에 따라 변하는 값은 정적 HTML 안에 박는 대신, 필요하다면 runtime widget이나 외부 링크로 처리해야 한다.
배운 점
AI 생성 결과가 틀렸을 때, 자꾸 프롬프트를 먼저 의심하게 된다. 하지만 이번 문제는 prompt wording보다 payload 설계가 더 중요했다.
모델은 받은 데이터를 최대한 활용하려고 한다. 그래서 쓰면 안 되는 데이터는 "쓰지 마"라고 말하기보다 처음부터 주지 않는 편이 낫다.
정적 페이지에 들어갈 수 있는 데이터는 "생성 시점에 맞는가"가 아니라 "사용자가 나중에 봐도 여전히 덜 틀리는가"로 판단해야 한다.
다음에는 이렇게 판단한다
생성 payload를 설계할 때는 데이터가 유용해 보이는지만 보지 않는다. 그 데이터가 출력물의 수명과 맞는지도 같이 본다.
앞으로 생성 payload는 세 가지로 나눠 본다.
- 정적 페이지에 넣어도 되는 데이터
- 페이지에 넣을 수는 있지만 조심해서 표현해야 하는 데이터
- 생성 시점 이후 바로 틀릴 수 있으므로 넣으면 안 되는 데이터
AI가 잘못 쓴 문장을 고치려면, 먼저 AI가 왜 그 문장을 쓸 수 있었는지 봐야 한다. 이번 경우에는 답이 프롬프트가 아니라 payload 안에 있었다.
