"""Prompt contract for image classification and accessible alt text.""" from typing import Optional from common.enums import PlaceCategory _LABELS = { PlaceCategory.LODGING: ["외관", "침실", "거실", "욕실", "주방", "수영장", "바비큐장", "주차장", "전망", "부대시설"], PlaceCategory.CAFE: ["외관", "내부", "좌석", "메뉴", "디저트", "음료", "테라스", "주차장"], PlaceCategory.RESTAURANT: ["외관", "내부", "좌석", "메뉴", "음식", "룸", "주차장"], PlaceCategory.CLINIC: ["외관", "시설", "장비", "활동", "안전장비", "주차장", "매표소"], } _DEFAULT_LABELS = ["외관", "내부", "시설", "기타"] RESPONSE_SCHEMA = { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "ref": {"type": "string"}, "label": {"type": "string"}, "alt_text": {"type": "string"}, "confidence": {"type": "number", "minimum": 0, "maximum": 1}, }, "required": ["ref", "label", "alt_text", "confidence"], }, } }, "required": ["items"], } def build_prompt( category: Optional[PlaceCategory], unit_names: Optional[list[str]], refs: list[str] ) -> str: lines = [ "소상공인 홈페이지에 사용할 사진을 분류한다.", f"사진 {len(refs)}장의 각 [ref]에 대해 아래 값을 만든다.", f"- label: {' / '.join(_LABELS.get(category, _DEFAULT_LABELS))} 중 하나", "- alt_text: 화면에 보이는 것만 한국어 20~60자로 작성", "- confidence: 불명확할수록 0에 가깝게 지정", "- 가격·면적·인원·시설을 지어내지 마라.", "- '아름다운' 같은 홍보성 또는 평가성 표현을 쓰지 않는다.", ] if unit_names: lines.append(f"- 관련된 경우 객실·프로그램 이름을 label에 붙일 수 있다: {', '.join(unit_names)}") lines.append(f"모든 ref를 빠짐없이 반환한다: {', '.join(refs)}") return "\n".join(lines)