Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import re | |
| import yaml | |
| from openai import OpenAI | |
| # OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ | |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| # ํ๋กฌํํธ ํ ํ๋ฆฟ ๋ก๋ | |
| import os | |
| 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 f: | |
| prompt_data = yaml.safe_load(f) | |
| prompt_template = prompt_data['prompt'] | |
| def parse_jd_recommendation(content): | |
| """ | |
| AI ์๋ต์์ ์ง๋ฌด๊ธฐ์ ์ JSON์ ํ์ฑํ๋ ํจ์ | |
| """ | |
| try: | |
| print(f"ํ์ฑํ ์ปจํ ์ธ ๊ธธ์ด: {len(content)}") | |
| print(f"ํ์ฑํ ์ปจํ ์ธ ์ฒซ 200์: {repr(content[:200])}") | |
| # ํ ์คํธ ์ ์ฒ๋ฆฌ | |
| cleaned_content = content.strip() | |
| # 1. JSON ์ฝ๋ ๋ธ๋ก ์ฐพ๊ธฐ (```json ... ``` ํ์) | |
| json_patterns = [ | |
| r'```json\s*(\{.*?\})\s*```', | |
| r'```\s*(\{.*?\})\s*```', | |
| r'```json\s*(.*?)\s*```', | |
| r'```\s*(.*?)\s*```' | |
| ] | |
| for pattern in json_patterns: | |
| json_match = re.search(pattern, cleaned_content, re.DOTALL) | |
| if json_match: | |
| json_str = json_match.group(1).strip() | |
| print(f"JSON ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}") | |
| # JSON ๋ฌธ์์ด ์ ๋ฆฌ | |
| json_str = re.sub(r'\n\s*', ' ', json_str) | |
| json_str = re.sub(r',\s*}', '}', json_str) | |
| try: | |
| parsed_json = json.loads(json_str) | |
| if isinstance(parsed_json, dict) and 'recommended_jd' in parsed_json: | |
| return parsed_json['recommended_jd'] | |
| except json.JSONDecodeError as e: | |
| print(f"JSON ๋ธ๋ก ํ์ฑ ์คํจ: {e}") | |
| # 2. ์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ JSON ์ฐพ๊ธฐ | |
| brace_patterns = [ | |
| r'\{.*?\}' | |
| ] | |
| for pattern in brace_patterns: | |
| brace_match = re.search(pattern, cleaned_content, re.DOTALL) | |
| if brace_match: | |
| json_str = brace_match.group(0).strip() | |
| print(f"์ค๊ดํธ ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}") | |
| # JSON ๋ฌธ์์ด ์ ๋ฆฌ | |
| json_str = re.sub(r'\n\s*', ' ', json_str) | |
| json_str = re.sub(r',\s*}', '}', json_str) | |
| try: | |
| parsed_json = json.loads(json_str) | |
| if isinstance(parsed_json, dict) and 'recommended_jd' in parsed_json: | |
| return parsed_json['recommended_jd'] | |
| except json.JSONDecodeError as e: | |
| print(f"์ค๊ดํธ ๋ธ๋ก ํ์ฑ ์คํจ: {e}") | |
| # 3. ์ ์ฒด ํ ์คํธ๋ฅผ JSON์ผ๋ก ํ์ฑ ์๋ | |
| try: | |
| # ์ฝ๋ ๋ธ๋ก ๋ง์ปค ์ ๊ฑฐ | |
| if cleaned_content.startswith('```'): | |
| lines = cleaned_content.split('\n') | |
| start_idx = 1 if lines[0].startswith('```') else 0 | |
| end_idx = len(lines) | |
| for i in range(len(lines)-1, -1, -1): | |
| if lines[i].strip() == '```': | |
| end_idx = i | |
| break | |
| cleaned_content = '\n'.join(lines[start_idx:end_idx]) | |
| cleaned_content = cleaned_content.strip() | |
| parsed_json = json.loads(cleaned_content) | |
| if isinstance(parsed_json, dict) and 'recommended_jd' in parsed_json: | |
| return parsed_json['recommended_jd'] | |
| except json.JSONDecodeError as e: | |
| print(f"์ ์ฒด JSON ํ์ฑ ์คํจ: {e}") | |
| # 4. ์ง์ ํ ์คํธ์์ JD ๋ด์ฉ ์ถ์ถ ์๋ | |
| print("์ง์ ํ ์คํธ์์ JD ๋ด์ฉ ์ถ์ถ ์๋") | |
| # "recommended_jd" ํค์๋ ๋ค์ ๋ด์ฉ ์ฐพ๊ธฐ | |
| jd_patterns = [ | |
| r'"recommended_jd"\s*:\s*"([^"]+)"', | |
| r'recommended_jd["\s]*:\s*["\s]*([^"]+)["\s]*', | |
| r'์ง๋ฌด๊ธฐ์ ์[:\s]*([^\n]+)', | |
| ] | |
| for pattern in jd_patterns: | |
| match = re.search(pattern, cleaned_content, re.IGNORECASE) | |
| if match: | |
| jd_content = match.group(1).strip() | |
| if len(jd_content) > 10: # ์ต์ ๊ธธ์ด ์ฒดํฌ | |
| return jd_content | |
| # 5. ์ตํ์ ์๋จ: ์ ์ฒด ํ ์คํธ๋ฅผ JD๋ก ๊ฐ์ฃผ (JSON ๋ง์ปค ์ ๊ฑฐ) | |
| print("์ ์ฒด ํ ์คํธ๋ฅผ JD๋ก ๊ฐ์ฃผ") | |
| cleaned_text = re.sub(r'```[a-z]*\s*', '', cleaned_content) | |
| cleaned_text = re.sub(r'```\s*', '', cleaned_text) | |
| cleaned_text = re.sub(r'\{.*?\}', '', cleaned_text, flags=re.DOTALL) | |
| cleaned_text = cleaned_text.strip() | |
| if len(cleaned_text) > 20: | |
| return cleaned_text | |
| return "์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค." | |
| except Exception as e: | |
| print(f"JD ํ์ฑ ์ ์ฒด ์ค๋ฅ: {e}") | |
| print(f"ํ์ฑ ์คํจํ ์ปจํ ์ธ : {repr(content)}") | |
| return f"ํ์ฑ ์ค๋ฅ: {str(e)}" | |
| def generate_jd_recommendation(job_title, company_name, experience_level): | |
| """ | |
| OpenAI API๋ฅผ ์ฌ์ฉํ์ฌ ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ๋ ํจ์ | |
| """ | |
| try: | |
| if not job_title or not company_name or not experience_level: | |
| return "์ง๋ฌด, ํ์ฌ๋ช , ๊ฒฝ๋ ฅ ์์ค์ ๋ชจ๋ ์ ๋ ฅํด์ฃผ์ธ์.", "" | |
| # ํ๋กฌํํธ ์์ฑ | |
| prompt = prompt_template.format( | |
| job_title=job_title, | |
| company_name=company_name, | |
| experience_level=experience_level | |
| ) | |
| # OpenAI API ํธ์ถ | |
| response = client.chat.completions.create( | |
| model="gpt-4o", | |
| messages=[ | |
| {"role": "system", "content": "๋น์ ์ ์ฑ์ฉ ๊ณต๊ณ ์์ฑ ์ ๋ฌธ๊ฐ์ ๋๋ค. ์ ํํ JSON ํ์์ผ๋ก ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์ ๊ณตํด์ฃผ์ธ์."}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| temperature=0.3 | |
| ) | |
| content = response.choices[0].message.content | |
| print(f"=== AI ์๋ต ์๋ณธ ===") | |
| print(content) | |
| print(f"=== AI ์๋ต ๋ ===") | |
| jd_content = parse_jd_recommendation(content) | |
| if not jd_content or jd_content == "์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.": | |
| return "์ง๋ฌด๊ธฐ์ ์ ์์ฑ์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.", "" | |
| # ๊ฒฐ๊ณผ ํฌ๋งทํ | |
| result = f"""## ๐ {company_name} - {job_title} ์ง๋ฌด๊ธฐ์ ์ | |
| ### ๐ผ **์ถ์ฒ ์ง๋ฌด๊ธฐ์ ์** | |
| {jd_content} | |
| --- | |
| ### ๐ **์ง๋ฌด ์ ๋ณด ์์ฝ** | |
| **๐ข ํ์ฌ:** {company_name} | |
| **๐ผ ์ง๋ฌด:** {job_title} | |
| **๐ ๊ฒฝ๋ ฅ:** {experience_level} | |
| ### ๐ก **์์์ ์์ฑ ํ** | |
| ์ ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ค์ ์ฌํญ์ ์์์์ ๋ฐ์ํด๋ณด์ธ์: | |
| 1. **ํต์ฌ ์ ๋ฌด**: ์ธ๊ธ๋ ์ฃผ์ ์ ๋ฌด์ ๊ด๋ จ๋ ๊ฒฝํ์ด๋ ์ญ๋์ ๊ฐ์กฐ | |
| 2. **์๊ตฌ ์คํฌ**: ํ์ํ ๊ธฐ์ ์ด๋ ๋ฅ๋ ฅ์ ๋ํ ๋ณธ์ธ์ ์ค๋น๋๋ฅผ ์ดํ | |
| 3. **ํ์ฌ ํน์ฑ**: ํด๋น ํ์ฌ์ ์ฌ์ ์์ญ๊ณผ ์ฐ๊ด๋ ๊ด์ฌ์ฌ๋ ๊ฒฝํ์ ์ธ๊ธ | |
| 4. **์ฑ์ฅ ์์ง**: ์ง๋ฌด์์ ์๊ตฌํ๋ ์ฑ์ฅ ๊ฐ๋ฅ์ฑ๊ณผ ํ์ต ์์ง๋ฅผ ํํ | |
| --- | |
| *๋ณธ ์ง๋ฌด๊ธฐ์ ์๋ AI๊ฐ ์์ฑํ ๊ฒ์ผ๋ก, ์ค์ ์ฑ์ฉ๊ณต๊ณ ์ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์์์ ์์ฑ ์ ์ฐธ๊ณ ์ฉ์ผ๋ก ํ์ฉํ์ธ์.* | |
| """ | |
| return result, jd_content | |
| except Exception as e: | |
| error_msg = f"""## โ ์ค๋ฅ ๋ฐ์ | |
| ์ง๋ฌด๊ธฐ์ ์ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. | |
| **์ค๋ฅ ๋ด์ฉ:** {str(e)} | |
| ๋ค์ ์๋ํด์ฃผ์ธ์. | |
| """ | |
| return error_msg, "" |