|
|
from openai import OpenAI |
|
|
from dotenv import load_dotenv |
|
|
import yaml |
|
|
import os |
|
|
import json |
|
|
import re |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) |
|
|
|
|
|
|
|
|
try: |
|
|
current_dir = os.path.dirname(os.path.abspath(__file__)) |
|
|
prompt_path = os.path.join(current_dir, 'prompt.yaml') |
|
|
with open(prompt_path, "r", encoding='utf-8') as file: |
|
|
prompt = yaml.safe_load(file)["prompt"] |
|
|
except Exception as e: |
|
|
print(f"Warning: prompt.yaml λ‘λ μ€ν¨. κΈ°λ³Έ ν둬ννΈλ₯Ό μ¬μ©ν©λλ€. μ€λ₯: {e}") |
|
|
prompt = "Question: {question}\nJD: {jd}\nCompany: {company_name}\nExperience: {experience_level}\nGenerate a guide based on this information in markdown table format." |
|
|
|
|
|
|
|
|
def parse_json_from_response(text: str) -> dict | None: |
|
|
""" |
|
|
Markdown μ½λ λΈλ‘ μμ ν¬ν¨λ μ μλ JSON λ¬Έμμ΄μ μΆμΆνκ³ νμ±ν©λλ€. |
|
|
|
|
|
Deprecated: μ΄ ν¨μλ JSON νμ±μ©μ΄λ―λ‘ guide generationμμλ λ μ΄μ μ¬μ©λμ§ μμ΅λλ€. |
|
|
|
|
|
Args: |
|
|
text (str): LLMμ΄ λ°νν μ 체 ν
μ€νΈ μλ΅. |
|
|
|
|
|
Returns: |
|
|
dict | None: νμ±λ λμ
λ리 κ°μ²΄, λλ μ€ν¨ μ None. |
|
|
""" |
|
|
if not text: |
|
|
return None |
|
|
|
|
|
|
|
|
match = re.search(r"```(?:json)?\s*([\s\S]*?)\s*```", text) |
|
|
if match: |
|
|
json_str = match.group(1) |
|
|
else: |
|
|
|
|
|
json_str = text |
|
|
|
|
|
try: |
|
|
return json.loads(json_str) |
|
|
except json.JSONDecodeError: |
|
|
|
|
|
start_index = json_str.find('{') |
|
|
end_index = json_str.rfind('}') |
|
|
if start_index != -1 and end_index != -1 and start_index < end_index: |
|
|
potential_json = json_str[start_index:end_index+1] |
|
|
try: |
|
|
return json.loads(potential_json) |
|
|
except json.JSONDecodeError: |
|
|
pass |
|
|
|
|
|
return None |
|
|
|
|
|
def parse_markdown_table_from_response(text: str) -> str: |
|
|
""" |
|
|
LLM μλ΅μμ λ§ν¬λ€μ΄ ν
μ΄λΈμ μΆμΆνμ¬ λ°νν©λλ€. |
|
|
|
|
|
Args: |
|
|
text (str): LLMμ΄ λ°νν μ 체 ν
μ€νΈ μλ΅. |
|
|
|
|
|
Returns: |
|
|
str: μΆμΆλ λ§ν¬λ€μ΄ ν
μ΄λΈ λ¬Έμμ΄, μ€ν¨ μ μ 체 ν
μ€νΈ λ°ν |
|
|
""" |
|
|
if not text: |
|
|
return "" |
|
|
|
|
|
|
|
|
markdown_match = re.search(r"```(?:markdown)?\s*([\s\S]*?)\s*```", text) |
|
|
if markdown_match: |
|
|
return markdown_match.group(1).strip() |
|
|
|
|
|
|
|
|
lines = text.split('\n') |
|
|
table_lines = [] |
|
|
in_table = False |
|
|
|
|
|
for line in lines: |
|
|
line = line.strip() |
|
|
if '|' in line and ('λ¨κ³' in line or '---' in line or 'β ' in line): |
|
|
in_table = True |
|
|
table_lines.append(line) |
|
|
elif in_table and '|' in line: |
|
|
table_lines.append(line) |
|
|
elif in_table and not line: |
|
|
|
|
|
break |
|
|
|
|
|
if table_lines: |
|
|
return '\n'.join(table_lines) |
|
|
|
|
|
|
|
|
return text.strip() |
|
|
|
|
|
def generate_guide(question, jd, company_name, experience_level): |
|
|
""" |
|
|
μκΈ°μκ°μ λ¬Έν κ°μ΄λλ₯Ό μμ±νκ³ , λ§ν¬λ€μ΄ ν
μ΄λΈκ³Ό μ 체 μλ΅ κ°μ²΄λ₯Ό λ°ννλ ν¨μ |
|
|
""" |
|
|
try: |
|
|
response = client.chat.completions.create( |
|
|
model="gpt-4o-mini", |
|
|
messages=[{"role": "user", "content": prompt.format(question=question, jd=jd, company_name=company_name, experience_level=experience_level)}], |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
guide_content = parse_markdown_table_from_response(response.choices[0].message.content) |
|
|
|
|
|
|
|
|
guide_dict = {"guide": guide_content} |
|
|
return guide_dict, response |
|
|
|
|
|
except Exception as e: |
|
|
print(f"κ°μ΄λ μμ± λλ νμ± μ€ μ€λ₯ λ°μ: {e}") |
|
|
return {"error": f"Failed to generate or parse guide: {str(e)}", "guide": ""}, None |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
example_input = { |
|
|
"question": "μΌμ±μ μλ₯Ό μ§μν μ΄μ μ μ
μ¬ ν μ΄λ£¨κ³ μΆμ κΏμ κΈ°μ νμμ€.", |
|
|
"jd": "μΌμ±μ μλ μΈκ³μ μΈ κΈ°μ κΈ°μ
μΌλ‘, λ€μν λΆμΌμμ μ λμ μΈ κΈ°μ μ κ°λ°νκ³ μμ΅λλ€. νλ‘ νΈμλ κ°λ°μλ‘ μ
μ¬νλ©΄ λ€μν νλ‘μ νΈμ μ°Έμ¬νλ©°, μ΅μ κΈ°μ μ μ μ©νμ¬ μ¬μ©μ κ²½νμ κ°μ ν μ μμ΅λλ€.", |
|
|
"company_name": "μΌμ±μ μ", |
|
|
"experience_level": "μ μ
" |
|
|
} |
|
|
guide_dict, _ = generate_guide(**example_input) |
|
|
print("Guide content:") |
|
|
print(guide_dict.get("guide", "No guide generated")) |