[feat] solution/backend: 일정 컨셉당 2개씩, 총 10개로 확대 — 컨셉 축은 그대로 5개
This commit is contained in:
parent
ae4953cf89
commit
6fbd0904fa
@ -1,11 +1,11 @@
|
||||
"""여행 일정 프롬프트 — "1박 2일·2박 3일을 각각 5개 컨셉으로".
|
||||
"""여행 일정 프롬프트 — "1박 2일·2박 3일을 각각 5개 컨셉 × 2개씩, 총 10개로".
|
||||
|
||||
★ 왜 shared 에 두지 않나
|
||||
`shared/src/lib/section-prompts.ts` 의 단일 출처 규칙은 "사장님이 복사해 가는 프롬프트와
|
||||
서버가 도는 프롬프트가 **같은 문장**일 때" 의 규칙이다. 이 둘은 하는 일이 다르다 —
|
||||
사장님용(`canvas/dataSpec.ts`)은 "3~5개, 반나절·1박2일·2박3일 섞기" 고, 이쪽은
|
||||
"기간 고정 + 지정된 컨셉 5개" 다. 같은 문장을 두 벌 두는 게 아니므로 daily 때의 분기 사고와
|
||||
성격이 다르다. 문장 자체는 사장님용에서 가져와 변형했다.
|
||||
"기간 고정 + 지정된 컨셉 5개 × 2개" 다. 같은 문장을 두 벌 두는 게 아니므로 daily 때의 분기
|
||||
사고와 성격이 다르다. 문장 자체는 사장님용에서 가져와 변형했다.
|
||||
|
||||
★ 컨셉을 **우리가** 준다 (스파이크 2026-09-11, 스테이,머뭄)
|
||||
모델에 맡기면 2박 3일에서 5개 코스 중 **4개가 정거장 집합 100% 동일**이었다(고유 장소 13곳).
|
||||
@ -15,14 +15,22 @@
|
||||
★ 컨셉 축은 **테마**여야 한다
|
||||
'차 없이 걸어서' 를 축으로 넣었더니 '처음 온 손님(대표 명소)' 과 91% 겹쳤다 —
|
||||
원도심이 곧 도보권이라 같은 장소로 수렴한다. 제약은 축이 될 수 없다.
|
||||
|
||||
★ 10개(컨셉당 2개)로 늘렸다 (2026-09-11, 사장님 지시: "중복 허용하고 10개로")
|
||||
컨셉을 5개 더 늘려 서로 안 겹치게 짜는 대신, 기존 5개 테마 각각에서 2개씩 뽑기로 했다 —
|
||||
같은 테마 안에서의 겹침(예: 자연 풍경 코스 둘이 비슷한 종류의 장소를 쓰는 것)은 허용하고,
|
||||
**정거장 집합이 완전히 같은 것만**(규칙 7) 막는다. 장소가 둘째 코스를 못 채우면 그 컨셉은
|
||||
1개만 낸다 — 지어내지 않는다 원칙의 연장이다.
|
||||
`MAX_TOKENS` 도 12000 → 16000 으로 올렸다(완성 토큰이 코스 수에 비례해 늘어난다).
|
||||
"""
|
||||
|
||||
# 화면 탭이 되는 값이다(`ItineraryItem.duration`). 표기를 바꾸면 사장님이 적은 일정과 탭이 갈린다
|
||||
# — `canvas/dataSpec.ts` 의 options(['반나절','1박 2일','2박 3일'])와 같은 문자열이어야 한다.
|
||||
DURATIONS: tuple[str, str] = ("1박 2일", "2박 3일")
|
||||
|
||||
# 2박 3일 5코스가 completion 3,922 토큰까지 갔다(실측). 기본값 2048 로는 잘린다.
|
||||
MAX_TOKENS = 12000
|
||||
# 2박 3일 5코스가 completion 3,922 토큰까지 갔다(실측). 10개(컨셉당 2개)면 그 두 배 안팎이라
|
||||
# 여유를 넉넉히 둔다 — 기본값 2048 은 물론 12000 도 10개에서는 잘릴 수 있다.
|
||||
MAX_TOKENS = 16000
|
||||
|
||||
SYSTEM_PROMPT = (
|
||||
"너는 지역 여행 코스 플래너다. 검색으로 확인한 실제 장소만 쓰고, "
|
||||
@ -58,11 +66,15 @@ _TASK = """[업소] %(place)s
|
||||
[지역] %(region)s
|
||||
|
||||
[해야 할 일]
|
||||
[업소]에 숙박하는 손님을 위한 %(duration)s 여행 일정을 **아래 5개 컨셉으로 하나씩** 만든다.
|
||||
[업소]에 숙박하는 손님을 위한 %(duration)s 여행 일정을 **아래 5개 컨셉마다 2개씩, 총 10개** 만든다.
|
||||
|
||||
[컨셉]
|
||||
%(concepts)s
|
||||
|
||||
· 같은 컨셉 안의 두 코스도 서로 다른 일정이어야 한다 — 정거장이 겹치는 것은 괜찮지만
|
||||
(규칙 7 참고), 같은 장소를 그대로 두 번 우려내지 않는다. 컨셉에 맞는 장소가 둘째 코스를
|
||||
못 채울 만큼 모자라면 그 컨셉은 1개만 낸다 — 억지로 채우지 않는다.
|
||||
|
||||
· 모든 일정의 duration 은 "%(duration)s" 이다.
|
||||
· days 로 날짜를 나눈다.
|
||||
· 정거장은 하루에 3~5곳. 여섯 곳부터는 아무도 그대로 못 돈다.
|
||||
@ -81,7 +93,7 @@ _TASK = """[업소] %(place)s
|
||||
5. 링크를 만들지 않는다. searchQuery 에 지도 검색어만 적는다.
|
||||
6. 모든 정거장에 latitude·longitude 를 적는다.
|
||||
7. ★ 코스 둘이 **같은 정거장 집합**이면 안 된다. 순서만 바꿔 놓은 것은 같은 코스다.
|
||||
각 코스에는 다른 네 코스에 없는 정거장이 **최소 두 곳** 들어가야 한다.
|
||||
각 코스에는 다른 코스들에 없는 정거장이 **최소 두 곳** 들어가야 한다.
|
||||
컨셉에 맞는 장소가 모자라면 그 코스의 정거장을 줄인다 — 다른 코스의 장소를 빌려오지 않는다.
|
||||
8. 밤 9시를 넘기는 칸은 화면에서 빠진다 — 시각을 계산해 보고 넣는다.
|
||||
9. source.url 은 실제로 열리는 공식·기관·언론 페이지여야 한다."""
|
||||
|
||||
@ -4,6 +4,7 @@ DB 도 네트워크도 쓰지 않는 순수 단위 테스트다.
|
||||
|
||||
이 파일이 지키는 것(스파이크 2026-09-11 에서 실측으로 얻은 것들):
|
||||
- 컨셉 5개를 **우리가** 준다. 모델에 맡기면 2박 3일에서 5개 중 4개가 정거장 집합 100% 동일이 된다
|
||||
- 컨셉당 2개씩, 총 10개를 요청한다(2026-09-11, 사장님 지시: "중복 허용하고 10개로")
|
||||
- 업소 자신을 정거장에 넣지 말라고 못 박는다. 안 적으면 "스테이,머뭄" 이 정거장으로 들어온다
|
||||
- 지역명을 넣는다. 없으면 모델이 아무 도시나 고른다(story_service.region_label_of 와 같은 이유)
|
||||
"""
|
||||
@ -35,6 +36,14 @@ def test_prompt_fixes_five_concepts():
|
||||
assert concept in text
|
||||
|
||||
|
||||
def test_prompt_asks_for_ten_courses_total():
|
||||
"""검증: 컨셉당 2개씩 총 10개를 요청한다(2026-09-11: 5개 → 10개, 중복 허용).
|
||||
기대결과: 컨셉 축 자체는 그대로 5개이고, 개수만 컨셉당 2개로 늘어난다."""
|
||||
text = prompts.build_prompt("업소", "지역", "1박 2일")
|
||||
assert "5개 컨셉마다 2개씩, 총 10개" in text
|
||||
assert "같은 컨셉 안의 두 코스도 서로 다른 일정이어야 한다" in text
|
||||
|
||||
|
||||
def test_prompt_forbids_the_lodging_itself_as_a_stop():
|
||||
"""검증: 업소를 정거장에 넣지 말라는 규칙."""
|
||||
text = prompts.build_prompt("업소", "지역", "1박 2일")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user