|
import re, json, ast
|
|
from langchain_core.prompts import PromptTemplate
|
|
from langchain_core.output_parsers import StrOutputParser
|
|
from langchain_upstage import ChatUpstage
|
|
|
|
def generate_character_creation_questions(world_summary, language="korean"):
|
|
llm = ChatUpstage()
|
|
questions_prompt_template = PromptTemplate.from_template(
|
|
"""
|
|
Based on the following novel context, generate five simple questions that a player should answer to help create a deeply personalized character for a fantasy RPG.
|
|
The questions should explore different aspects of a potential characterβs personality, background, and capabilities.
|
|
For users who are not used to the story I want you to give several choices in the question.
|
|
Write five questions in Korean(νκΈ).
|
|
Your response should be python list with strings consist of questions.
|
|
---
|
|
Novel Context: {Context}
|
|
---
|
|
Format: ['λΉμ μ ...? (λ΅λ³μ μμ: ...): ', ...]
|
|
---
|
|
Questions:
|
|
"""
|
|
)
|
|
questions_chain = questions_prompt_template | llm | StrOutputParser()
|
|
|
|
default_questions = [
|
|
"λΉμ μ μΊλ¦ν° μ΄λ¦μ 무μμΈκ°μ? (μν°λ‘ μ€ν΅ν μ μλμΌλ‘ μ΄λ¦μ΄ μμ±λ©λλ€): ",
|
|
"λΉμ μ μΊλ¦ν°μ μ±λ³μ 무μμΈκ°μ? (μν°λ‘ μ€ν΅ν μ μλμΌλ‘ μ±λ³μ΄ μ νλ©λλ€): ",
|
|
"λΉμ μ μΊλ¦ν°λ λͺμ΄μΈκ°μ? (μν°λ‘ μ€ν΅ν μ μλμΌλ‘ λμ΄κ° μ νλ©λλ€): ",
|
|
]
|
|
while(True):
|
|
try:
|
|
questions = questions_chain.invoke({ "Context": world_summary })
|
|
questions_list = ast.literal_eval(questions)
|
|
questions_list = [question.replace('[', '').replace(']', '') for question in questions_list]
|
|
return default_questions + questions_list
|
|
except:
|
|
continue
|
|
|
|
|
|
|
|
def create_character_profile(questions, language="korean"):
|
|
llm = ChatUpstage()
|
|
character_creation_prompt_template = PromptTemplate.from_template(
|
|
"""
|
|
Using the answers provided below, create a detailed character profile for a fantasy tabletop RPG.
|
|
The character should reflect the given attributes. Please ensure to use the specified field names and format in your output consistently.
|
|
Consider Player's answers as the input and generate a character profile based on the given context.
|
|
When player's answer is not given, please use a appropriate value for corresponding fields made by yourself.
|
|
|
|
**Output should strictly follow this format:**
|
|
|
|
- name: "character name"
|
|
- gender: "Male" or "Female"
|
|
- age: age on integer
|
|
- race: "character race"
|
|
- job: "character job"
|
|
- stamina: integer between [1, 100]
|
|
- intelligence: integer between [1, 100]
|
|
- combat_power: integer between [1, 100]
|
|
- agility: integer between [1, 100]
|
|
- background: "character background"
|
|
|
|
**Player Answers:**
|
|
qna:
|
|
{qna}
|
|
---
|
|
Please write the output in English.
|
|
"""
|
|
)
|
|
character_creation_chain = character_creation_prompt_template | llm | StrOutputParser()
|
|
answers = []
|
|
for i, question in enumerate(questions):
|
|
print(f"Question {i+1}: {question}")
|
|
answers.append(input("Your answer: "))
|
|
qna = [f"Q: {questions[i]}\nA: {answers[i]}" for i in range(len(questions))]
|
|
character_description = character_creation_chain.invoke({ "qna": qna, "Language": language})
|
|
return character_description
|
|
|
|
def parse_character_data_to_json(text):
|
|
fields = {
|
|
'name': r"- name: (.*)",
|
|
'gender': r"- gender: (.*)",
|
|
'age': r"- age: (\d+)",
|
|
'race': r"- race: (.*)",
|
|
'job': r"- job: (.*)",
|
|
'background': r"- background: (.*)"
|
|
}
|
|
param_fields = {
|
|
'stamina': r"- stamina: (\d+)",
|
|
'intelligence': r"- intelligence: (\d+)",
|
|
'combat_power': r"- combat_power: (\d+)",
|
|
'agility': r"- agility: (\d+)"
|
|
}
|
|
character_dict = {}
|
|
params_dict = {}
|
|
for key, pattern in fields.items():
|
|
match = re.search(pattern, text)
|
|
if match:
|
|
character_dict[key] = match.group(1)
|
|
for key, pattern in param_fields.items():
|
|
match = re.search(pattern, text)
|
|
if match:
|
|
params_dict[key] = int(match.group(1))
|
|
character_dict['params'] = params_dict
|
|
|
|
return character_dict
|
|
|
|
def main():
|
|
with open("/Users/hyunkoolee/upstage_kai_llm/llm_dnd/harrypotter_scenario/world_summary.txt", "r", encoding="utf-8") as file:
|
|
world_summary = file.read()
|
|
|
|
|
|
questions = generate_character_creation_questions(world_summary)
|
|
character_description = create_character_profile(questions)
|
|
character_json = parse_character_data_to_json(character_description)
|
|
print(character_json)
|
|
|
|
if __name__ == "__main__":
|
|
main() |