fix lyric

insta
Dohyun Lim 2026-01-13 17:27:30 +09:00
parent 3f75b6d61d
commit 1acd8846ab
5 changed files with 38 additions and 42 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -197,7 +197,7 @@ async def crawling(request_body: CrawlingRequest):
step3_4_start = time.perf_counter()
print(f"[crawling] Step 3-4: 응답 파싱 시작 - facility_info: {scraper.facility_info}")
parsed = await chatgpt_service.parse_marketing_analysis(
raw_response, facility_info=scraper.facility_info
raw_response
)
marketing_analysis = MarketingAnalysis(**parsed)
step3_4_elapsed = (time.perf_counter() - step3_4_start) * 1000

View File

@ -149,7 +149,6 @@ async def get_lyric_by_task_id(
task_id=lyric.task_id,
project_id=lyric.project_id,
status=lyric.status,
lyric_prompt=lyric.lyric_prompt,
lyric_result=lyric.lyric_result,
created_at=lyric.created_at,
)

View File

@ -140,7 +140,6 @@ class LyricDetailResponse(BaseModel):
"task_id": "0694b716-dbff-7219-8000-d08cb5fce431",
"project_id": 1,
"status": "completed",
"lyric_prompt": "고객명: 스테이 머뭄, 지역: 군산...",
"lyric_result": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서\n여유로운 하루를 보내며\n추억을 만들어가요",
"created_at": "2024-01-15T12:00:00",
}
@ -151,7 +150,6 @@ class LyricDetailResponse(BaseModel):
task_id: str = Field(..., description="작업 고유 식별자")
project_id: int = Field(..., description="프로젝트 ID")
status: str = Field(..., description="처리 상태")
lyric_prompt: str = Field(..., description="가사 생성 프롬프트")
lyric_result: Optional[str] = Field(None, description="생성된 가사")
created_at: Optional[datetime] = Field(None, description="생성 일시")

View File

@ -70,13 +70,19 @@ Analyze the following internally to inform lyrics creation:
- Main target audience appeal
- Nearby famous places or regional characteristics
2. Keywords to Incorporate (use language-appropriate trendy expressions):
- Korean: 인스타 감성, 사진같은 하루, 힐링, 여행, 감성 숙소
- English: Instagram vibes, picture-perfect day, healing, travel, getaway
- Chinese: 网红打卡, 治愈系, 旅行, 度假, 拍照圣地
- Japanese: インスタ映え, 写真のような一日, 癒し, 旅行, 絶景
- Thai: กสวย, ลใจ, เทยว, ายร, วสวย
- Vietnamese: check-in đẹp, healing, du lịch, nghỉ dưỡng, view đẹp
2. Keywords Selection:
<<CRITICAL: Use ONLY the keywords for {language}. DO NOT transliterate or use keywords from other languages.>>
Select keywords based on {language}:
- IF Korean: 인스타 감성, 사진같은 하루, 힐링, 여행, 감성 숙소
- IF English: Instagram vibes, picture-perfect day, healing, travel, getaway
- IF Chinese: 网红打卡, 治愈系, 旅行, 度假, 拍照圣地
- IF Japanese: インスタ映え, 写真のような一日, 癒し, 旅行, 絶景
- IF Thai: กสวย, ลใจ, เทยว, ายร, วสวย
- IF Vietnamese: check-in đẹp, healing, du lịch, nghỉ dưỡng, view đẹp
<<FORBIDDEN: Never transliterate keywords from other languages (e.g., "왕홍다카", "인스타바에", "티팍수아이" are WRONG)>>
3. Structure:
- Length: For 1-minute video (approximately 8-12 lines)
@ -112,15 +118,15 @@ ALL OUTPUT MUST BE 100% WRITTEN IN {language} - NO EXCEPTIONS
- Follow the exact format below
[OUTPUT FORMAT - SUCCESS]
---
[Lyrics ENTIRELY in {language} here - no other language characters allowed]
---
[OUTPUT FORMAT - FAILURE]
If you cannot generate lyrics due to insufficient information, invalid input, or any other reason:
---
ERROR: [Brief reason for failure in English]
---
""".strip()
# fmt: on
@ -160,10 +166,18 @@ Provide comprehensive marketing analysis including:
- Return as JSON with key "tags"
- **MUST be written in Korean (한국어)**
2. Facilities
- Based on the business name and region details, identify 5 likely facilities/amenities
- Consider typical facilities for accommodations in the given region
- Examples: 바베큐장, 수영장, 주차장, 와이파이, 주방, 테라스, 정원, etc.
- Return as JSON with key "facilities"
- **MUST be written in Korean (한국어)**
[CRITICAL LANGUAGE REQUIREMENT - ABSOLUTE RULE]
ALL OUTPUT MUST BE WRITTEN IN KOREAN (한국어)
- Analysis sections: Korean only
- Tags: Korean only
- Facilities: Korean only
- This is a NON-NEGOTIABLE requirement
- Any output in English or other languages is considered a FAILURE
- Violation of this rule invalidates the entire response
@ -195,7 +209,8 @@ ALL OUTPUT MUST BE WRITTEN IN KOREAN (한국어)
## JSON Data
```json
{{
"tags": ["태그1", "태그2", "태그3", "태그4", "태그5"]
"tags": ["태그1", "태그2", "태그3", "태그4", "태그5"],
"facilities": ["부대시설1", "부대시설2", "부대시설3", "부대시설4", "부대시설5"]
}}
```
---
@ -315,16 +330,18 @@ class ChatgptService:
텍스트를 분석하여 핵심 내용을 항목별로 구분하여 500 이내로 요약해주세요.
[OUTPUT REQUIREMENTS]
- 5 항목으로 구분: 타겟 고객, 핵심 차별점, 지역 특성, 시즌별 포인트, 추천 키워드
- 5 항목으로 구분: 타겟 고객, 핵심 차별점, 지역 특성, 시즌별 포인트
- 항목은 줄바꿈으로 구분
- 500 이내로 요약
- 내용의 누락이 있어서는 안된다
- 문장이 자연스러워야 한다
- 핵심 정보만 간결하게 포함
- 한국어로 작성
- 특수문자 사용 금지 (괄호, 슬래시, 하이픈, 물결표 제외)
- 쉼표와 마침표만 사용하여 자연스러운 문장으로 작성
[OUTPUT FORMAT - 반드시 아래 형식 준수]
---
타겟 고객
[대상 고객층을 자연스러운 문장으로 설명]
@ -336,11 +353,11 @@ class ChatgptService:
시즌별 포인트
[계절별 매력 포인트를 자연스러운 문장으로 설명]
추천 키워드
[마케팅에 활용할 키워드를 쉼표로 구분하여 나열]
---
"""
# 추천 키워드
# [마케팅에 활용할 키워드를 쉼표로 구분하여 나열]
result = await self.generate(prompt=prompt)
@ -352,15 +369,9 @@ class ChatgptService:
return result
async def parse_marketing_analysis(
self, raw_response: str, facility_info: str | None = None
) -> dict:
async def parse_marketing_analysis(self, raw_response: str) -> dict:
"""ChatGPT 마케팅 분석 응답을 파싱하고 요약하여 딕셔너리로 반환
Args:
raw_response: ChatGPT 마케팅 분석 응답 원문
facility_info: 크롤링에서 가져온 편의시설 정보 문자열
Returns:
dict: {"report": str, "tags": list[str], "facilities": list[str]}
"""
@ -374,7 +385,7 @@ class ChatgptService:
try:
json_data = json.loads(json_match.group(1))
tags = json_data.get("tags", [])
print(f"[parse_marketing_analysis] GPT 응답에서 tags 파싱 완료: {tags}")
facilities = json_data.get("facilities", [])
# JSON 블록을 제외한 리포트 부분 추출
report = raw_response[: json_match.start()].strip()
# --- 구분자 제거
@ -383,22 +394,10 @@ class ChatgptService:
if report.endswith("---"):
report = report[:-3].strip()
except json.JSONDecodeError:
print("[parse_marketing_analysis] JSON 파싱 실패")
pass
# 크롤링에서 가져온 facility_info로 facilities 설정
print(f"[parse_marketing_analysis] 크롤링 facility_info 원본: {facility_info}")
if facility_info:
# 쉼표로 구분된 편의시설 문자열을 리스트로 변환
facilities = [f.strip() for f in facility_info.split(",") if f.strip()]
print(f"[parse_marketing_analysis] facility_info 파싱 결과: {facilities}")
else:
facilities = ["등록된 정보 없음"]
print("[parse_marketing_analysis] facility_info 없음 - '등록된 정보 없음' 설정")
# 리포트 내용을 500자로 요약
if report:
report = await self.summarize_marketing(report)
print(f"[parse_marketing_analysis] 최종 facilities: {facilities}")
return {"report": report, "tags": tags, "facilities": facilities}