[fix] solution/backend: 히어로 아래 한 줄이 소개문 세 문장을 이고 있었다
`narrative.summary` 는 계약이 "요약 **한 문장**"이라 적어 둔 자리인데(shared/site-payload.ts) 첫 **문단**을 통째로 넣고 있었다. 그 값은 두 곳으로 나간다 — 히어로 아래 한 줄과 meta description. 그래서 히어로가 세 문장을 이고 서고(실측 2026-09-10), 검색 결과에서는 설명이 중간에 잘렸다. - site_payload._first_sentence: 첫 문장만 뗀다. **문장을 새로 생성하지 않는다** — 있는 글에서 자를 뿐이다(요약을 또 생성하면 근거 검사를 한 번 더 통과해야 한다). 숫자 사이의 점은 자르지 않는다(1.5km) — 뒤가 숫자면 문장 끝이 아니다. ★ 곁에서 확인한 것 — 생성기가 만든 meta_description 이 **버려지고 있다.** copy_service 는 소개문과 함께 50~120자짜리 메타 요약을 만들지만, 업종 스키마에 `meta_description` 필드가 없어서 "allow_llm 이 아닌 필드" 로 조용히 건너뛴다 (lodging.json 의 allow_llm 은 intro·room_intro 둘뿐). 지금은 첫 문장으로 대신하지만, 스키마에 자리를 만들면 생성기가 쓴 요약이 그대로 meta description 이 된다 — 별건이다. 검증: 재발행 후 히어로 한 문장 · meta description 동일. test_snapshot 통과 (site_theme 의 섹션표 parity 4건 실패는 이 변경 전 기준선과 같다).
This commit is contained in:
parent
868127a69a
commit
c8cf704217
@ -163,6 +163,21 @@ _DEFAULT_THEME = {
|
|||||||
|
|
||||||
|
|
||||||
# ── 값 변환 헬퍼 ──────────────────────────────────────────────────────────
|
# ── 값 변환 헬퍼 ──────────────────────────────────────────────────────────
|
||||||
|
def _first_sentence(text: str) -> str:
|
||||||
|
"""첫 문장. 마침표가 없으면 통째로 돌려준다.
|
||||||
|
|
||||||
|
★ 왜 필요한가: 히어로 아래 한 줄과 meta description 이 같은 값을 쓴다. 둘 다 **한 문장**
|
||||||
|
자리라, 문단이 들어가면 히어로는 세 줄로 부풀고 검색 결과에서는 뒤가 잘린다.
|
||||||
|
★ 마침표 뒤에 공백이 없어도 자른다("…입니다.일본식" 같은 생성물이 실제로 온다).
|
||||||
|
다만 숫자 사이의 점(1.5km)은 자르지 않는다 — 뒤가 숫자면 문장 끝이 아니다.
|
||||||
|
"""
|
||||||
|
import re as _re
|
||||||
|
|
||||||
|
match = _re.search(r"[.!?](?![0-9])", text or "")
|
||||||
|
return text[: match.end()].strip() if match else (text or "").strip()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _get(row, key, default=None):
|
def _get(row, key, default=None):
|
||||||
"""ORM 행이든 dict 든 같은 방식으로 읽는다(테스트가 가짜 행을 넣기 쉬우라고)."""
|
"""ORM 행이든 dict 든 같은 방식으로 읽는다(테스트가 가짜 행을 넣기 쉬우라고)."""
|
||||||
if isinstance(row, dict):
|
if isinstance(row, dict):
|
||||||
@ -805,8 +820,12 @@ def to_site_payload(place, snapshot: dict, site, version, links) -> dict:
|
|||||||
paragraphs = [p.strip() for p in intro.split("\n") if p.strip()] if intro else []
|
paragraphs = [p.strip() for p in intro.split("\n") if p.strip()] if intro else []
|
||||||
narrative = {
|
narrative = {
|
||||||
"about": paragraphs,
|
"about": paragraphs,
|
||||||
# 요약은 첫 문단을 그대로 쓴다(요약문을 새로 생성하지 않는다).
|
# ★ 요약은 **첫 문장**이다. 문단이 아니다.
|
||||||
"summary": paragraphs[0] if paragraphs else None,
|
# 계약이 "요약 한 문장"이라 적어 뒀는데(shared/site-payload.ts) 첫 문단을 통째로
|
||||||
|
# 넣고 있었다. 그 값은 두 곳으로 나간다 — 히어로 아래 한 줄과 meta description.
|
||||||
|
# 문단이 들어가면 히어로가 세 문장을 이고 서고(실측 2026-09-10), meta description 은
|
||||||
|
# 검색 결과에서 잘린다. 문장을 새로 생성하지는 않는다 — 있는 글의 첫 문장을 뗄 뿐이다.
|
||||||
|
"summary": _first_sentence(paragraphs[0]) if paragraphs else None,
|
||||||
}
|
}
|
||||||
|
|
||||||
theme_spec = _DEFAULT_THEME.get(category) or _DEFAULT_THEME[PlaceCategory.LODGING.value]
|
theme_spec = _DEFAULT_THEME.get(category) or _DEFAULT_THEME[PlaceCategory.LODGING.value]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user