from typing import Dict, Any
def build_webtest_prompt(npc_id: str, npc_location: str, player_utt: str) -> str:
# 웹 테스트에서는 최소 필드만 채운 pre dict 생성
pre = {
"tags": {
"npc_id": npc_id,
"location": npc_location,
"quest_stage": "",
"relationship": "",
"trust": "",
"npc_mood": "",
"player_reputation": "",
"style": ""
},
"player_state": {},
"rag_main_docs": [], # 웹 테스트에서는 RAG 문서 없음
"context": [], # 대화 히스토리 없음
"player_utterance": player_utt
}
# session_id는 웹 테스트에서는 의미 없으니 빈 값
return build_main_prompt(pre, session_id="", npc_id=npc_id)
def build_main_prompt(pre: Dict[str, Any], session_id: str, npc_id: str) -> str:
tags = pre.get("tags", {})
ps = pre.get("player_state", {})
rag_docs = pre.get("rag_main_docs", [])
# RAG 문서 분리
lore_text = ""
desc_text = ""
for doc in rag_docs:
if "LORE:" in doc:
lore_text += doc + "\n"
elif "DESCRIPTION:" in doc:
desc_text += doc + "\n"
else:
# fallback: type 기반 분리 가능
if "lore" in doc.lower():
lore_text += doc + "\n"
elif "description" in doc.lower():
desc_text += doc + "\n"
prompt = [
"",
f"NPC_ID={tags.get('npc_id','')}",
f"NPC_LOCATION={tags.get('location','')}",
"TAGS:",
f" quest_stage={tags.get('quest_stage','')}",
f" relationship={tags.get('relationship','')}",
f" trust={tags.get('trust','')}",
f" npc_mood={tags.get('npc_mood','')}",
f" player_reputation={tags.get('player_reputation','')}",
f" style={tags.get('style','')}",
"",
"",
f"LORE: {lore_text.strip() or '(없음)'}",
f"DESCRIPTION: {desc_text.strip() or '(없음)'}",
"",
""
]
if ps.get("items"):
prompt.append(f"items={','.join(ps['items'])}")
if ps.get("actions"):
prompt.append(f"actions={','.join(ps['actions'])}")
if ps.get("position"):
prompt.append(f"position={ps['position']}")
prompt.append("")
prompt.append("")
for h in pre.get("context", []):
prompt.append(f"{h['role']}: {h['text']}")
prompt.append("")
prompt.append(f"{pre.get('player_utterance','').rstrip()}")
prompt.append("")
prompt.append("")
return "\n".join(prompt)