Spaces:
Sleeping
Sleeping
- commonly-asked-question/.gradio/certificate.pem +31 -0
- commonly-asked-question/__pycache__/llm_functions.cpython-312.pyc +0 -0
- commonly-asked-question/eval.json +93 -0
- commonly-asked-question/llm_functions.py +251 -0
- commonly-asked-question/main.py +351 -0
- commonly-asked-question/prompt.yaml +43 -0
- company-size-classification/.gradio/certificate.pem +31 -0
- company-size-classification/__pycache__/llm_functions.cpython-312.pyc +0 -0
- company-size-classification/eval.json +48 -0
- company-size-classification/llm_functions.py +110 -0
- company-size-classification/main.py +228 -0
- company-size-classification/prompt.yaml +85 -0
- industry-classification/.gradio/certificate.pem +31 -0
- industry-classification/__pycache__/llm_functions.cpython-312.pyc +0 -0
- industry-classification/eval.json +256 -0
- industry-classification/llm_functions.py +271 -0
- industry-classification/main.py +305 -0
- industry-classification/prompt.yaml +128 -0
- jasoseo-context-report/.gradio/certificate.pem +31 -0
- jasoseo-context-report/__pycache__/llm_functions.cpython-312.pyc +0 -0
- jasoseo-context-report/eval.json +123 -0
- jasoseo-context-report/llm_functions.py +282 -0
- jasoseo-context-report/main.py +314 -0
- jasoseo-context-report/prompt.yaml +96 -0
- jd-recommendation/__pycache__/llm_functions.cpython-312.pyc +0 -0
- jd-recommendation/eval.json +117 -0
- jd-recommendation/llm_functions.py +205 -0
- jd-recommendation/main.py +329 -0
- jd-recommendation/prompt.yaml +69 -0
- jd-recommendation/propmt.yaml +0 -0
- main.py +474 -0
- question-recommendation/.gradio/certificate.pem +31 -0
- question-recommendation/__pycache__/llm_functions.cpython-312.pyc +0 -0
- question-recommendation/eval.json +67 -0
- question-recommendation/llm_functions.py +116 -0
- question-recommendation/main.py +190 -0
- question-recommendation/prompt.yaml +34 -0
- requirements.txt +6 -0
commonly-asked-question/.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
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
|
| 31 |
+
-----END CERTIFICATE-----
|
commonly-asked-question/__pycache__/llm_functions.cpython-312.pyc
ADDED
|
Binary file (9.86 kB). View file
|
|
|
commonly-asked-question/eval.json
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"sample_question_generation_eval": {
|
| 3 |
+
"task_definition": {
|
| 4 |
+
"description": "Based on the user's input (company, job, experience level) and a predefined list of common interview questions, select and refine 3 sample questions that are most relevant to the user's situation.",
|
| 5 |
+
"input": {
|
| 6 |
+
"job_title": "string",
|
| 7 |
+
"company_name": "string",
|
| 8 |
+
"experience_level": "์ ์
| ๊ฒฝ๋ ฅ | ์ธํด | ๊ธฐํ",
|
| 9 |
+
"common_questions": ["string", "..."]
|
| 10 |
+
},
|
| 11 |
+
"output": {
|
| 12 |
+
"sample_questions": ["string", "string", "string"]
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
"examples": [
|
| 16 |
+
{
|
| 17 |
+
"input": {
|
| 18 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 19 |
+
"company_name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)",
|
| 20 |
+
"experience_level": "์ ์
",
|
| 21 |
+
"common_questions": ["์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์", "์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "๊ฐ์ฅ ๋์ ์ ์ธ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์", "์
์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์"]
|
| 22 |
+
},
|
| 23 |
+
"output": {
|
| 24 |
+
"sample_questions": [
|
| 25 |
+
"์๋ง์ ํํ
ํฌ ๊ธฐ์
์ค ์ 'ํ ์ค'์ ์ง์ํ์
จ๋์?",
|
| 26 |
+
"๊ฐ๋ฐ์๋ก์ ๊ฐ์ฅ ํฌ๊ฒ ์ฑ์ฅํ๋ ๊ธฐ์ ์ ๋์ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์?",
|
| 27 |
+
"๋ณธ์ธ์ด ํ ์ค์ ๊ธฐ์ ๋ฌธํ(์์จ๊ณผ ์ฑ
์, ๋์ ๋๋ฃ ์ ๋ขฐ ๋ฑ)์ ์ ๋ง๋๋ค๊ณ ์๊ฐํ๋ ์ด์ ๋ฅผ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ์๊ฐํด ์ฃผ์ธ์."
|
| 28 |
+
]
|
| 29 |
+
}
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"input": {
|
| 33 |
+
"job_title": "์ํ๋ง์ผํ
",
|
| 34 |
+
"company_name": "CJ์ ์ผ์ ๋น",
|
| 35 |
+
"experience_level": "๊ฒฝ๋ ฅ",
|
| 36 |
+
"common_questions": ["์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์", "์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "๋ณธ์ธ์ ๊ฐ์ ์ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ณต ๊ฒฝํ์ ๋งํด์ฃผ์ธ์"]
|
| 37 |
+
},
|
| 38 |
+
"output": {
|
| 39 |
+
"sample_questions": [
|
| 40 |
+
"CJ์ ์ผ์ ๋น์ ์ฌ๋ฌ ๋ธ๋๋ ์ค ํน๋ณํ ๊ธฐ์ฌํ๊ณ ์ถ์ ๋ธ๋๋์ ๊ทธ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?",
|
| 41 |
+
"์ฑ๊ณต์ ์ผ๋ก ์ด๋์๋ ๋ง์ผํ
์บ ํ์ธ ์ค, ๋ณธ์ธ์ ์ญํ ๊ณผ ์ฑ๊ณผ๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ์ค๋ช
ํด์ฃผ์ธ์.",
|
| 42 |
+
"์ต๊ทผ ์ํ์
๊ณ ํธ๋ ๋(HMR, ํฌ์ํ๋ ์ ๋ฑ)์ ์ฐ๊ด์ง์ด ์
์ฌ ํ ์ด๋ค ๋ง์ผํ
์ ํผ์น๊ณ ์ถ์ผ์ ๊ฐ์?"
|
| 43 |
+
]
|
| 44 |
+
}
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
"input": {
|
| 48 |
+
"job_title": "A&R",
|
| 49 |
+
"company_name": "ํ์ด๋ธ",
|
| 50 |
+
"experience_level": "์ธํด",
|
| 51 |
+
"common_questions": ["์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ฒฉ์ ์ฅ๋จ์ ์ ๋งํด์ฃผ์ธ์", "์
์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์", "๋ง์ง๋ง์ผ๋ก ํ๊ณ ์ถ์ ๋ง์?"]
|
| 52 |
+
},
|
| 53 |
+
"output": {
|
| 54 |
+
"sample_questions": [
|
| 55 |
+
"ํ์ด๋ธ์ ์์
/์ํฐ์คํธ๊ฐ ๋ณธ์ธ์๊ฒ ์ด๋ค ์๋ฏธ์ธ์ง, ๊ทธ๋ฆฌ๊ณ A&R ์ง๋ฌด์ ์ ์ง์ํ๋์ง ์ฐ๊ฒฐ์ง์ด ์ค๋ช
ํด์ฃผ์ธ์.",
|
| 56 |
+
"A&R ์ง๋ฌด์ ํ์ํ ์ญ๋ ์ค ๋ณธ์ธ์ด ๊ฐ์ฅ ์์ ์๋ ๊ฒ๊ณผ ๋ณด์ํ๊ณ ์ถ์ ์ ์ ๋ฌด์์ธ๊ฐ์?",
|
| 57 |
+
"์ธํด์ผ๋ก์ ํ์ด๋ธ์์ ๊ฐ์ฅ ๋ฐฐ์ฐ๊ณ ์ถ์ ์ ์ ๋ฌด์์ด๋ฉฐ, ์ด๋ป๊ฒ ํ์ ๊ธฐ์ฌํ๊ณ ์ถ๋์?"
|
| 58 |
+
]
|
| 59 |
+
}
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"input": {
|
| 63 |
+
"job_title": "๊ฒฝ์๊ธฐํ",
|
| 64 |
+
"company_name": "ํ๋๊ฑด์ค",
|
| 65 |
+
"experience_level": "์ ์
",
|
| 66 |
+
"common_questions": ["์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "์ฑ์ฅ ๊ณผ์ ์ ๋งํด์ฃผ์ธ์", "๊ฐ์ฅ ํ๋ค์๋ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์", "์กด๊ฒฝํ๋ ์ธ๋ฌผ์ ๋๊ตฌ์ธ๊ฐ์"]
|
| 67 |
+
},
|
| 68 |
+
"output": {
|
| 69 |
+
"sample_questions": [
|
| 70 |
+
"๊ฑด์ค ์ฐ์
์ ํน์ฑ์ ๊ณ ๋ คํ์ฌ ํ๋๊ฑด์ค์ ์ง์ํ ๋๊ธฐ๋ฅผ ๋ง์ํด์ฃผ์ธ์.",
|
| 71 |
+
"ํ ํ๋ก์ ํธ์์ ๊ฐ๋ฑ์ ํด๊ฒฐํ๊ฑฐ๋ ์ด๋ ค์ด ๋ชฉํ๋ฅผ ๋ฌ์ฑํ๋ ๊ฒฝํ์ด ์๋ค๋ฉด ๊ตฌ์ฒด์ ์ผ๋ก ์ค๋ช
ํด์ฃผ์ธ์.",
|
| 72 |
+
"๊ฒฝ์๊ธฐํ ์ง๋ฌด ๋ด๋น์๋ก์ ํ๋๊ฑด์ค์ ๋ฏธ๋ ์ฑ์ฅ์ ์ด๋ป๊ฒ ๊ธฐ์ฌํ๊ณ ์ถ์ผ์ ๊ฐ์?"
|
| 73 |
+
]
|
| 74 |
+
}
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"input": {
|
| 78 |
+
"job_title": "ํด์ธ์์
",
|
| 79 |
+
"company_name": "์ผ์ฑ์ ์",
|
| 80 |
+
"experience_level": "๊ฒฝ๋ ฅ",
|
| 81 |
+
"common_questions": ["๊ฒฝ๋ ฅ ์์ฃผ๋ก ์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์", "์ด์ง ์ฌ์ ๊ฐ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ณต ๊ฒฝํ์ ๋งํด์ฃผ์ธ์", "์คํจ ๊ฒฝํ์ ๋งํด์ฃผ์ธ์"]
|
| 82 |
+
},
|
| 83 |
+
"output": {
|
| 84 |
+
"sample_questions": [
|
| 85 |
+
"๊ฐ์ฅ ์ฑ๊ณต์ ์ด์๋ ํด์ธ ์์ฃผ/์์
๊ฒฝํ๊ณผ ๊ทธ ๊ณผ์ ์์ ๋ณธ์ธ์ ํต์ฌ์ ์ธ ์ญํ ์ ๋ฌด์์ด์๋์?",
|
| 86 |
+
"์ผ์ฑ์ ์์ ๋ฐ๋์ฒด/๊ฐ์ ์ฌ์
๋ถ ์ค ๋ณธ์ธ์ ์ ๋ฌธ์ฑ์ ๊ฐ์ฅ ์ ๋ฐํํ ์ ์๋ ๋ถ์ผ๋ ์ด๋๋ผ๊ณ ์๊ฐํ๋ฉฐ, ๊ทธ ์ด์ ๋ ๋ฌด์์
๋๊น?",
|
| 87 |
+
"ํด์ธ ๊ณ ๊ฐ๊ณผ์ ๋ฌธํ์ ์ฐจ์ด๋ ์ด๋ ค์ด ํ์ ์ํฉ์ ๊ทน๋ณตํ๋ ์ฌ๋ก๊ฐ ์๋ค๋ฉด ๋ง์ํด์ฃผ์ธ์."
|
| 88 |
+
]
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
]
|
| 92 |
+
}
|
| 93 |
+
}
|
commonly-asked-question/llm_functions.py
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import re
|
| 4 |
+
import yaml
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
|
| 7 |
+
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
| 8 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 9 |
+
|
| 10 |
+
# ํ๋กฌํํธ ํ
ํ๋ฆฟ ๋ก๋
|
| 11 |
+
import os
|
| 12 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 13 |
+
prompt_path = os.path.join(current_dir, 'prompt.yaml')
|
| 14 |
+
with open(prompt_path, 'r', encoding='utf-8') as f:
|
| 15 |
+
prompt_data = yaml.safe_load(f)
|
| 16 |
+
prompt_template = prompt_data['prompt']
|
| 17 |
+
|
| 18 |
+
def parse_prediction(content):
|
| 19 |
+
"""
|
| 20 |
+
AI ์๋ต์์ JSON ํ์์ ๋ฉด์ ์ง๋ฌธ์ ํ์ฑํ๋ ํจ์
|
| 21 |
+
"""
|
| 22 |
+
try:
|
| 23 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ๊ธธ์ด: {len(content)}")
|
| 24 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ์ฒซ 200์: {repr(content[:200])}")
|
| 25 |
+
|
| 26 |
+
# ํ
์คํธ ์ ์ฒ๋ฆฌ - ๋ถํ์ํ ๊ณต๋ฐฑ๊ณผ ํน์๋ฌธ์ ์ ๊ฑฐ
|
| 27 |
+
cleaned_content = content.strip()
|
| 28 |
+
|
| 29 |
+
# 1. JSON ์ฝ๋ ๋ธ๋ก ์ฐพ๊ธฐ (```json ... ``` ํ์)
|
| 30 |
+
json_patterns = [
|
| 31 |
+
r'```json\s*(\{.*?\})\s*```',
|
| 32 |
+
r'```\s*(\{.*?\})\s*```',
|
| 33 |
+
r'```json\s*(.*?)\s*```',
|
| 34 |
+
r'```\s*(.*?)\s*```'
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
for pattern in json_patterns:
|
| 38 |
+
json_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 39 |
+
if json_match:
|
| 40 |
+
json_str = json_match.group(1).strip()
|
| 41 |
+
print(f"JSON ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 42 |
+
|
| 43 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 44 |
+
json_str = re.sub(r'\n\s*', ' ', json_str) # ์ค๋ฐ๊ฟ๊ณผ ๊ณต๋ฐฑ ์ ๋ฆฌ
|
| 45 |
+
json_str = re.sub(r',\s*}', '}', json_str) # ๋ง์ง๋ง ์ฝค๋ง ์ ๊ฑฐ
|
| 46 |
+
json_str = re.sub(r',\s*]', ']', json_str) # ๋ฐฐ์ด ๋ง์ง๋ง ์ฝค๋ง ์ ๊ฑฐ
|
| 47 |
+
|
| 48 |
+
try:
|
| 49 |
+
parsed_json = json.loads(json_str)
|
| 50 |
+
if 'sample_questions' in parsed_json:
|
| 51 |
+
return parsed_json['sample_questions']
|
| 52 |
+
except json.JSONDecodeError as e:
|
| 53 |
+
print(f"JSON ๋ธ๋ก ํ์ฑ ์คํจ: {e}")
|
| 54 |
+
print(f"์คํจํ JSON: {repr(json_str)}")
|
| 55 |
+
|
| 56 |
+
# 2. ์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ ์ ์ฒด JSON ์ฐพ๊ธฐ
|
| 57 |
+
brace_patterns = [
|
| 58 |
+
r'\{[^{}]*"sample_questions"[^{}]*\[[^\]]*\][^{}]*\}',
|
| 59 |
+
r'\{.*?"sample_questions".*?\[.*?\].*?\}'
|
| 60 |
+
]
|
| 61 |
+
|
| 62 |
+
for pattern in brace_patterns:
|
| 63 |
+
brace_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 64 |
+
if brace_match:
|
| 65 |
+
json_str = brace_match.group(0).strip()
|
| 66 |
+
print(f"์ค๊ดํธ JSON ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 67 |
+
|
| 68 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 69 |
+
json_str = re.sub(r'\n\s*', ' ', json_str)
|
| 70 |
+
json_str = re.sub(r',\s*}', '}', json_str)
|
| 71 |
+
json_str = re.sub(r',\s*]', ']', json_str)
|
| 72 |
+
|
| 73 |
+
try:
|
| 74 |
+
parsed_json = json.loads(json_str)
|
| 75 |
+
if 'sample_questions' in parsed_json:
|
| 76 |
+
return parsed_json['sample_questions']
|
| 77 |
+
except json.JSONDecodeError as e:
|
| 78 |
+
print(f"์ค๊ดํธ JSON ํ์ฑ ์คํจ: {e}")
|
| 79 |
+
|
| 80 |
+
# 3. sample_questions ๋ฐฐ์ด๋ง ์ง์ ์ฐพ๊ธฐ
|
| 81 |
+
array_patterns = [
|
| 82 |
+
r'"sample_questions"\s*:\s*\[(.*?)\]',
|
| 83 |
+
r'sample_questions\s*:\s*\[(.*?)\]'
|
| 84 |
+
]
|
| 85 |
+
|
| 86 |
+
for pattern in array_patterns:
|
| 87 |
+
array_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 88 |
+
if array_match:
|
| 89 |
+
array_content = array_match.group(1).strip()
|
| 90 |
+
print(f"๋ฐฐ์ด ๋ด์ฉ ๋ฐ๊ฒฌ: {repr(array_content[:100])}")
|
| 91 |
+
|
| 92 |
+
# ๋ฐฐ์ด ๋ด์ฉ์์ ๋ฌธ์์ด ์ถ์ถ
|
| 93 |
+
questions = []
|
| 94 |
+
# ๋ฐ์ดํ๋ก ๋๋ฌ์ธ์ธ ๋ฌธ์์ด๋ค ์ฐพ๊ธฐ
|
| 95 |
+
question_matches = re.findall(r'"([^"]+)"', array_content)
|
| 96 |
+
for q in question_matches:
|
| 97 |
+
if len(q.strip()) > 10: # ์๋ฏธ์๋ ๊ธธ์ด์ ์ง๋ฌธ๋ง
|
| 98 |
+
questions.append(q.strip())
|
| 99 |
+
|
| 100 |
+
if questions:
|
| 101 |
+
return questions
|
| 102 |
+
|
| 103 |
+
# 4. ์ ์ฒด ํ
์คํธ๋ฅผ JSON์ผ๋ก ํ์ฑ ์๋
|
| 104 |
+
try:
|
| 105 |
+
# ์ฝ๋ ๋ธ๋ก ๋ง์ปค ์ ๊ฑฐ
|
| 106 |
+
if cleaned_content.startswith('```'):
|
| 107 |
+
lines = cleaned_content.split('\n')
|
| 108 |
+
start_idx = 1 if lines[0].startswith('```') else 0
|
| 109 |
+
end_idx = len(lines)
|
| 110 |
+
for i in range(len(lines)-1, -1, -1):
|
| 111 |
+
if lines[i].strip() == '```':
|
| 112 |
+
end_idx = i
|
| 113 |
+
break
|
| 114 |
+
cleaned_content = '\n'.join(lines[start_idx:end_idx])
|
| 115 |
+
|
| 116 |
+
cleaned_content = cleaned_content.strip()
|
| 117 |
+
parsed_json = json.loads(cleaned_content)
|
| 118 |
+
if 'sample_questions' in parsed_json:
|
| 119 |
+
return parsed_json['sample_questions']
|
| 120 |
+
except json.JSONDecodeError as e:
|
| 121 |
+
print(f"์ ์ฒด JSON ํ์ฑ ์คํจ: {e}")
|
| 122 |
+
|
| 123 |
+
# 5. ์ตํ์ ์๋จ: ํจํด ๋งค์นญ์ผ๋ก ์ง๋ฌธ ์ถ์ถ
|
| 124 |
+
print("ํจํด ๋งค์นญ์ผ๋ก ์ง๋ฌธ ์ถ์ถ ์๋")
|
| 125 |
+
questions = []
|
| 126 |
+
|
| 127 |
+
# ๋ค์ํ ํจํด์ผ๋ก ์ง๋ฌธ ์ฐพ๊ธฐ
|
| 128 |
+
patterns = [
|
| 129 |
+
r'"([^"]{20,}[?])"', # ๋ฐ์ดํ ์์ ๋ฌผ์ํ๋ก ๋๋๋ ๊ธด ๋ฌธ์ฅ
|
| 130 |
+
r'"([^"]{20,})"', # ๋ฐ์ดํ ์์ ๊ธด ๋ฌธ์ฅ
|
| 131 |
+
r'[1-9]\.\s*([^"\n]{20,}[?])', # ๋ฒํธ. ์ง๋ฌธ ํํ
|
| 132 |
+
r'[1-9]\.\s*([^"\n]{20,})', # ๋ฒํธ. ๋ฌธ์ฅ ํํ
|
| 133 |
+
]
|
| 134 |
+
|
| 135 |
+
for pattern in patterns:
|
| 136 |
+
matches = re.findall(pattern, cleaned_content)
|
| 137 |
+
for match in matches:
|
| 138 |
+
question = match.strip()
|
| 139 |
+
if len(question) > 15 and question not in questions:
|
| 140 |
+
questions.append(question)
|
| 141 |
+
if len(questions) >= 5: # ์ต๋ 5๊ฐ
|
| 142 |
+
break
|
| 143 |
+
if questions:
|
| 144 |
+
break
|
| 145 |
+
|
| 146 |
+
return questions[:5] if questions else []
|
| 147 |
+
|
| 148 |
+
except Exception as e:
|
| 149 |
+
print(f"JSON ํ์ฑ ์ ์ฒด ์ค๋ฅ: {e}")
|
| 150 |
+
print(f"ํ์ฑ ์คํจํ ์ปจํ
์ธ : {repr(content)}")
|
| 151 |
+
return []
|
| 152 |
+
|
| 153 |
+
def generate_interview_questions(company_name, job_title, experience_level, selected_questions, num_questions=3):
|
| 154 |
+
"""
|
| 155 |
+
OpenAI API๋ฅผ ์ฌ์ฉํ์ฌ ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ ์์ฑํ๋ ํจ์
|
| 156 |
+
"""
|
| 157 |
+
# try:
|
| 158 |
+
if True:
|
| 159 |
+
if not company_name or not job_title or not experience_level or not selected_questions:
|
| 160 |
+
return "๋ชจ๋ ํ๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.", []
|
| 161 |
+
|
| 162 |
+
# ์ ํ๋ ์ง๋ฌธ๋ค์ ๋ฆฌ์คํธ๋ก ๋ณํ
|
| 163 |
+
if isinstance(selected_questions, str):
|
| 164 |
+
common_questions = [q.strip() for q in selected_questions.split(',')]
|
| 165 |
+
else:
|
| 166 |
+
common_questions = selected_questions
|
| 167 |
+
|
| 168 |
+
# ํ๋กฌํํธ ์์ฑ
|
| 169 |
+
prompt = prompt_template.format(
|
| 170 |
+
company_name=company_name,
|
| 171 |
+
job_title=job_title,
|
| 172 |
+
experience_level=experience_level,
|
| 173 |
+
common_questions=common_questions,
|
| 174 |
+
num_questions=num_questions
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
print(prompt)
|
| 178 |
+
# OpenAI Responses API ํธ์ถ (Web Search Preview ์ฌ์ฉ)
|
| 179 |
+
response = client.responses.create(
|
| 180 |
+
model="gpt-4o",
|
| 181 |
+
tools=[{
|
| 182 |
+
"type": "web_search_preview",
|
| 183 |
+
"search_context_size": "high",
|
| 184 |
+
}],
|
| 185 |
+
input=f"๋น์ ์ ๋ฉด์ ์ง๋ฌธ ์์ฑ ์ ๋ฌธ๊ฐ์
๋๋ค. ์น ๊ฒ์์ ํตํด ์ต์ ๊ธฐ์
์ ๋ณด์ ์ฑ์ฉ ๋ํฅ์ ํ์ธํ๊ณ ์ฃผ์ด์ง ์กฐ๊ฑด์ ๋ง๋ ๊ตฌ์ฒด์ ์ด๊ณ ์ค์ฉ์ ์ธ ๋ฉด์ ์ง๋ฌธ์ ์์ฑํด์ฃผ์ธ์.\n\n{prompt}"
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
content = response.output_text
|
| 189 |
+
print(f"=== AI ์๋ต ์๋ณธ ===")
|
| 190 |
+
print(content)
|
| 191 |
+
print(f"=== ์ ์ฒด ์๋ต ๊ฐ์ฒด ===")
|
| 192 |
+
print(response)
|
| 193 |
+
|
| 194 |
+
# ์น ๊ฒ์ ์ฐธ๊ณ ๋งํฌ ์ถ๋ ฅ
|
| 195 |
+
if hasattr(response, 'web_search_results') and response.web_search_results:
|
| 196 |
+
print(f"=== ์ฐธ๊ณ ํ ์น ๊ฒ์ ๋งํฌ ===")
|
| 197 |
+
for i, result in enumerate(response.web_search_results, 1):
|
| 198 |
+
if hasattr(result, 'url'):
|
| 199 |
+
print(f"{i}. {result.url}")
|
| 200 |
+
elif hasattr(result, 'link'):
|
| 201 |
+
print(f"{i}. {result.link}")
|
| 202 |
+
|
| 203 |
+
print(f"=== AI ์๋ต ๋ ===")
|
| 204 |
+
questions = parse_prediction(content)
|
| 205 |
+
|
| 206 |
+
if not questions:
|
| 207 |
+
return "์ง๋ฌธ ์์ฑ์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.", []
|
| 208 |
+
|
| 209 |
+
# ๊ฒฐ๊ณผ ํฌ๋งทํ
|
| 210 |
+
result = f"""## ๐ฏ {company_name} - {job_title} ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ
|
| 211 |
+
|
| 212 |
+
### ๐ **์์ฑ๋ ์ง๋ฌธ๋ค**
|
| 213 |
+
|
| 214 |
+
"""
|
| 215 |
+
for i, question in enumerate(questions, 1):
|
| 216 |
+
result += f"**{i}.** {question}\n\n"
|
| 217 |
+
|
| 218 |
+
result += f"""
|
| 219 |
+
---
|
| 220 |
+
**๐ ์
๋ ฅ ์ ๋ณด:**
|
| 221 |
+
- ํ์ฌ: {company_name}
|
| 222 |
+
- ์ง๋ฌด: {job_title}
|
| 223 |
+
- ๊ฒฝ๋ ฅ: {experience_level}
|
| 224 |
+
- ์์ฑ๋ ์ง๋ฌธ ์: {len(questions)}๊ฐ (์์ฒญ: {num_questions}๊ฐ)
|
| 225 |
+
- ์ฐธ๊ณ ์ง๋ฌธ ์: {len(common_questions)}๊ฐ
|
| 226 |
+
|
| 227 |
+
*๋ณธ ์ง๋ฌธ๋ค์ AI๊ฐ ์์ฑํ ๊ฒ์ผ๋ก, ์ค์ ๋ฉด์ ๊ณผ ๋ค๋ฅผ ์ ์์ต๋๋ค.*
|
| 228 |
+
"""
|
| 229 |
+
|
| 230 |
+
return result, questions
|
| 231 |
+
|
| 232 |
+
# except Exception as e:
|
| 233 |
+
# error_msg = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 234 |
+
|
| 235 |
+
# ์ง๋ฌธ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 236 |
+
|
| 237 |
+
# **์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 238 |
+
|
| 239 |
+
# ๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 240 |
+
# """
|
| 241 |
+
# return error_msg, []
|
| 242 |
+
|
| 243 |
+
if __name__ == "__main__":
|
| 244 |
+
company_name = "ํ ์ค"
|
| 245 |
+
job_title = "๋ฐฑ์๋ ๊ฐ๋ฐ"
|
| 246 |
+
experience_level = "์ ์
"
|
| 247 |
+
selected_questions = "์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์, ์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์, ๊ฐ์ฅ ๋์ ์ ์ธ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์, ์
์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์"
|
| 248 |
+
num_questions = 3
|
| 249 |
+
result, questions = generate_interview_questions(company_name, job_title, experience_level, selected_questions, num_questions)
|
| 250 |
+
print(result)
|
| 251 |
+
print(questions)
|
commonly-asked-question/main.py
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from llm_functions import generate_interview_questions
|
| 3 |
+
|
| 4 |
+
# LLM ๊ด๋ จ ํจ์๋ค์ llm_functions.py๋ก ์ด๋๋จ
|
| 5 |
+
|
| 6 |
+
# ์์ ๋ฐ์ดํฐ
|
| 7 |
+
example_companies = ["์ผ์ฑ์ ์", "ํ ์ค", "์นด์นด์ค", "๋ค์ด๋ฒ", "LG์ ์", "ํ๋์๋์ฐจ", "CJ์ ์ผ์ ๋น", "ํ์ด๋ธ", "์ฟ ํก", "๋ฐฐ๋ฌ์๋ฏผ์กฑ"]
|
| 8 |
+
example_jobs = ["๋ฐฑ์๋ ๊ฐ๋ฐ", "ํ๋ก ํธ์๋ ๊ฐ๋ฐ", "๋ฐ์ดํฐ ์ฌ์ด์ธํฐ์คํธ", "๋ง์ผํ
", "์์
", "๊ธฐํ", "๋์์ธ", "HR", "์ฌ๋ฌด", "A&R"]
|
| 9 |
+
experience_levels = ["์ ์
", "๊ฒฝ๋ ฅ", "์ธํด", "๊ธฐํ"]
|
| 10 |
+
common_questions_list = [
|
| 11 |
+
"์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์",
|
| 12 |
+
"์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์",
|
| 13 |
+
"๋ณธ์ธ์ ๊ฐ์ ์ ๋ฌด์์ธ๊ฐ์",
|
| 14 |
+
"๊ฐ์ฅ ๋์ ์ ์ธ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์",
|
| 15 |
+
"์ฑ๊ณต ๊ฒฝํ์ ๋งํด์ฃผ์ธ์",
|
| 16 |
+
"์คํจ ๊ฒฝํ์ ๋งํด์ฃผ์ธ์",
|
| 17 |
+
"์
์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์",
|
| 18 |
+
"์ฑ๊ฒฉ์ ์ฅ๋จ์ ์ ๋งํด์ฃผ์ธ์",
|
| 19 |
+
"์กด๊ฒฝํ๋ ์ธ๋ฌผ์ ๋๊ตฌ์ธ๊ฐ์",
|
| 20 |
+
"๋ง์ง๋ง์ผ๋ก ํ๊ณ ์ถ์ ๋ง์?"
|
| 21 |
+
]
|
| 22 |
+
|
| 23 |
+
# generate_interview_questions ํจ์๋ llm_functions.py๋ก ์ด๋๋จ
|
| 24 |
+
|
| 25 |
+
def create_question_cards(questions):
|
| 26 |
+
"""
|
| 27 |
+
์์ฑ๋ ์ง๋ฌธ๋ค์ ์นด๋ ํํ๋ก ํ์ํ๋ HTML ์์ฑ
|
| 28 |
+
"""
|
| 29 |
+
if not questions:
|
| 30 |
+
return "<div style='text-align: center; color: #6B7280; padding: 20px;'>์ง๋ฌธ์ ์์ฑํด์ฃผ์ธ์</div>"
|
| 31 |
+
|
| 32 |
+
cards_html = "<div style='display: flex; flex-direction: column; gap: 15px;'>"
|
| 33 |
+
|
| 34 |
+
colors = ["#EBF8FF", "#ECFDF5", "#FEF2F2", "#F5F3FF", "#FFF7ED"]
|
| 35 |
+
border_colors = ["#1E40AF", "#059669", "#DC2626", "#7C3AED", "#EA580C"]
|
| 36 |
+
|
| 37 |
+
for i, question in enumerate(questions):
|
| 38 |
+
color = colors[i % len(colors)]
|
| 39 |
+
border_color = border_colors[i % len(border_colors)]
|
| 40 |
+
|
| 41 |
+
cards_html += f"""
|
| 42 |
+
<div style="
|
| 43 |
+
background-color: {color};
|
| 44 |
+
border: 2px solid {border_color};
|
| 45 |
+
border-radius: 12px;
|
| 46 |
+
padding: 20px;
|
| 47 |
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
| 48 |
+
">
|
| 49 |
+
<div style="
|
| 50 |
+
font-weight: bold;
|
| 51 |
+
color: {border_color};
|
| 52 |
+
font-size: 16px;
|
| 53 |
+
margin-bottom: 10px;
|
| 54 |
+
">์ง๋ฌธ {i+1}</div>
|
| 55 |
+
<div style="
|
| 56 |
+
color: #374151;
|
| 57 |
+
font-size: 15px;
|
| 58 |
+
line-height: 1.5;
|
| 59 |
+
">{question}</div>
|
| 60 |
+
</div>
|
| 61 |
+
"""
|
| 62 |
+
|
| 63 |
+
cards_html += "</div>"
|
| 64 |
+
return cards_html
|
| 65 |
+
|
| 66 |
+
def process_question_generation(company_name, job_title, experience_level, selected_questions, num_questions):
|
| 67 |
+
"""
|
| 68 |
+
์ง๋ฌธ ์์ฑ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๊ณ UI์ ํ์ํ ํํ๋ก ๋ณํํ๋ ํจ์
|
| 69 |
+
"""
|
| 70 |
+
try:
|
| 71 |
+
content, questions = generate_interview_questions(company_name, job_title, experience_level, selected_questions, num_questions)
|
| 72 |
+
question_cards = create_question_cards(questions)
|
| 73 |
+
return content, question_cards
|
| 74 |
+
except Exception as e:
|
| 75 |
+
error_content = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 76 |
+
|
| 77 |
+
์ง๋ฌธ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 78 |
+
|
| 79 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 80 |
+
|
| 81 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 82 |
+
"""
|
| 83 |
+
error_cards = create_question_cards([])
|
| 84 |
+
return error_content, error_cards
|
| 85 |
+
|
| 86 |
+
# ์ ์ญ ์ํ ๊ด๋ฆฌ
|
| 87 |
+
class AppState:
|
| 88 |
+
def __init__(self):
|
| 89 |
+
self.companies = ["ํ ์ค", "๋ค์ด๋ฒ", "์นด์นด์ค", "์ผ์ฑ์ ์", "LG์ ์", "ํ๋์๋์ฐจ", "SKํ์ด๋์ค", "CJ์ ์ผ์ ๋น", "ํ์ด๋ธ", "ํ๋๊ฑด์ค"]
|
| 90 |
+
self.jobs = ["๋ฐฑ์๋ ๊ฐ๋ฐ์", "ํ๋ก ํธ์๋ ๊ฐ๋ฐ์", "๋ฐ์ดํฐ ์ฌ์ด์ธํฐ์คํธ", "๋ง์ผํ
", "์์
", "๊ธฐํ", "๋์์ด๋", "A&R", "ํด์ธ์์
", "์ฌ์
๊ธฐํ"]
|
| 91 |
+
self.questions = common_questions_list.copy()
|
| 92 |
+
|
| 93 |
+
app_state = AppState()
|
| 94 |
+
|
| 95 |
+
# ๋ ์ด์ ์ฌ์ฉํ์ง ์๋ ํจ์๋ค ์ ๊ฑฐ๋จ
|
| 96 |
+
|
| 97 |
+
def add_company(new_company):
|
| 98 |
+
"""์ ํ์ฌ ์ถ๊ฐ"""
|
| 99 |
+
if new_company and new_company.strip() and new_company.strip() not in app_state.companies:
|
| 100 |
+
app_state.companies.append(new_company.strip())
|
| 101 |
+
return gr.Dropdown.update(choices=app_state.companies), ""
|
| 102 |
+
return gr.Dropdown.update(), ""
|
| 103 |
+
|
| 104 |
+
def add_job(new_job):
|
| 105 |
+
"""์ ์ง๋ฌด ์ถ๊ฐ"""
|
| 106 |
+
if new_job and new_job.strip() and new_job.strip() not in app_state.jobs:
|
| 107 |
+
app_state.jobs.append(new_job.strip())
|
| 108 |
+
return gr.Dropdown.update(choices=app_state.jobs), ""
|
| 109 |
+
return gr.Dropdown.update(), ""
|
| 110 |
+
|
| 111 |
+
def add_question(new_question):
|
| 112 |
+
"""์ ์ผ๋ฐ ์ง๋ฌธ ์ถ๊ฐ"""
|
| 113 |
+
if new_question and new_question.strip() and new_question.strip() not in app_state.questions:
|
| 114 |
+
app_state.questions.append(new_question.strip())
|
| 115 |
+
return gr.CheckboxGroup.update(choices=app_state.questions), ""
|
| 116 |
+
|
| 117 |
+
def create_interface():
|
| 118 |
+
"""
|
| 119 |
+
Gradio ์ธํฐํ์ด์ค ์์ฑ
|
| 120 |
+
"""
|
| 121 |
+
with gr.Blocks(
|
| 122 |
+
title="๐ฏ AI ๋ฉด์ ์ง๋ฌธ ์์ฑ๊ธฐ",
|
| 123 |
+
theme=gr.themes.Soft(),
|
| 124 |
+
css="""
|
| 125 |
+
.main-header {
|
| 126 |
+
text-align: center;
|
| 127 |
+
padding: 20px;
|
| 128 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 129 |
+
color: white;
|
| 130 |
+
border-radius: 10px;
|
| 131 |
+
margin-bottom: 20px;
|
| 132 |
+
}
|
| 133 |
+
.input-section {
|
| 134 |
+
background-color: #f8f9fa;
|
| 135 |
+
padding: 20px;
|
| 136 |
+
border-radius: 8px;
|
| 137 |
+
margin: 10px 0;
|
| 138 |
+
}
|
| 139 |
+
.example-section {
|
| 140 |
+
background-color: #f0f9ff;
|
| 141 |
+
padding: 15px;
|
| 142 |
+
border-radius: 8px;
|
| 143 |
+
margin: 10px 0;
|
| 144 |
+
}
|
| 145 |
+
"""
|
| 146 |
+
) as demo:
|
| 147 |
+
|
| 148 |
+
# ํค๋
|
| 149 |
+
gr.HTML("""
|
| 150 |
+
<div class="main-header">
|
| 151 |
+
<h1>๐ฏ AI ๋ฉด์ ์ง๋ฌธ ์์ฑ๊ธฐ</h1>
|
| 152 |
+
<p>ํ์ฌ์ ์ง๋ฌด์ ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ AI๊ฐ ์์ฑํด๋๋ฆฝ๋๋ค</p>
|
| 153 |
+
</div>
|
| 154 |
+
""")
|
| 155 |
+
|
| 156 |
+
# ์ค๋ช
|
| 157 |
+
gr.Markdown("""
|
| 158 |
+
### ๐ **์ฌ์ฉ ๋ฐฉ๋ฒ**
|
| 159 |
+
1. **ํ์ฌ๋ช
**: ์ง์ํ๊ณ ์ ํ๋ ํ์ฌ๋ฅผ ์
๋ ฅํ์ธ์
|
| 160 |
+
2. **์ง๋ฌด**: ์ง์ ์ง๋ฌด๋ฅผ ์
๋ ฅํ์ธ์
|
| 161 |
+
3. **๊ฒฝ๋ ฅ ์์ค**: ๋ณธ์ธ์ ๊ฒฝ๋ ฅ ์์ค์ ์ ํํ์ธ์
|
| 162 |
+
4. **์ผ๋ฐ ์ง๋ฌธ**: ์ฐธ๊ณ ํ ์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ๋ค์ ์ ํํ์ธ์
|
| 163 |
+
5. **์์ฑ**: '์ง๋ฌธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ฌ ๋ง์ถคํ ์ง๋ฌธ์ ๋ฐ์๋ณด์ธ์
|
| 164 |
+
|
| 165 |
+
โจ **ํน์ง**: ํ์ฌ์ ํน์ฑ, ์ง๋ฌด ์๊ตฌ์ฌํญ, ๊ฒฝ๋ ฅ ์์ค์ ๋ชจ๋ ๊ณ ๋ คํ ๊ตฌ์ฒด์ ์ด๊ณ ํ์ค์ ์ธ ์ง๋ฌธ์ ์์ฑํฉ๋๋ค.
|
| 166 |
+
""")
|
| 167 |
+
|
| 168 |
+
with gr.Row():
|
| 169 |
+
with gr.Column(scale=2):
|
| 170 |
+
# ์
๋ ฅ ์น์
|
| 171 |
+
gr.HTML('<div class="input-section">')
|
| 172 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 173 |
+
|
| 174 |
+
with gr.Row():
|
| 175 |
+
company_input = gr.Textbox(
|
| 176 |
+
label="๐ข ํ์ฌ๋ช
",
|
| 177 |
+
placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ",
|
| 178 |
+
value="",
|
| 179 |
+
scale=2,
|
| 180 |
+
elem_id="company_input"
|
| 181 |
+
)
|
| 182 |
+
|
| 183 |
+
job_input = gr.Textbox(
|
| 184 |
+
label="๐ผ ์ง๋ฌด",
|
| 185 |
+
placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ง์ผํ
, ๊ธฐํ ๋ฑ",
|
| 186 |
+
value="",
|
| 187 |
+
scale=2,
|
| 188 |
+
elem_id="job_input"
|
| 189 |
+
)
|
| 190 |
+
|
| 191 |
+
with gr.Row():
|
| 192 |
+
experience_input = gr.Dropdown(
|
| 193 |
+
label="๐ ๊ฒฝ๋ ฅ ์์ค",
|
| 194 |
+
choices=experience_levels,
|
| 195 |
+
value="์ ์
",
|
| 196 |
+
interactive=True,
|
| 197 |
+
scale=2
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
num_questions_input = gr.Dropdown(
|
| 201 |
+
label="๐ข ์ง๋ฌธ ๊ฐ์",
|
| 202 |
+
choices=[1, 2, 3, 4, 5],
|
| 203 |
+
value=3,
|
| 204 |
+
interactive=True,
|
| 205 |
+
scale=1
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
+
common_questions_input = gr.CheckboxGroup(
|
| 209 |
+
label="๐ ์ฐธ๊ณ ํ ์ผ๋ฐ ๋ฉด์ ์ง๋ฌธ (3-5๊ฐ ์ ํ ๊ถ์ฅ)",
|
| 210 |
+
choices=common_questions_list,
|
| 211 |
+
value=common_questions_list[:4],
|
| 212 |
+
interactive=True
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
generate_btn = gr.Button(
|
| 216 |
+
"๐ฏ ๋ง์ถคํ ์ง๋ฌธ ์์ฑ",
|
| 217 |
+
variant="primary",
|
| 218 |
+
size="lg"
|
| 219 |
+
)
|
| 220 |
+
gr.HTML('</div>')
|
| 221 |
+
|
| 222 |
+
with gr.Column(scale=1):
|
| 223 |
+
# ์์ ๋ฐ ๊ฐ์ด๋
|
| 224 |
+
gr.HTML('<div class="example-section">')
|
| 225 |
+
|
| 226 |
+
# ์ฌ์ฉ์ ์ ์ ํ์ฌ ์ถ๊ฐ
|
| 227 |
+
gr.Markdown("### ๐ข **ํ์ฌ ๊ด๋ฆฌ**")
|
| 228 |
+
with gr.Row():
|
| 229 |
+
new_company_input = gr.Textbox(
|
| 230 |
+
label="์ ํ์ฌ ์ถ๊ฐ",
|
| 231 |
+
placeholder="ํ์ฌ๋ช
์
๋ ฅ",
|
| 232 |
+
scale=2
|
| 233 |
+
)
|
| 234 |
+
add_company_btn = gr.Button("์ถ๊ฐ", size="sm", scale=1)
|
| 235 |
+
|
| 236 |
+
# ์์ ํ์ฌ ๋๋กญ๋ค์ด
|
| 237 |
+
company_dropdown = gr.Dropdown(
|
| 238 |
+
label="์์ ํ์ฌ ์ ํ",
|
| 239 |
+
choices=app_state.companies,
|
| 240 |
+
value=None,
|
| 241 |
+
interactive=True
|
| 242 |
+
)
|
| 243 |
+
|
| 244 |
+
# ์ฌ์ฉ์ ์ ์ ์ง๋ฌด ์ถ๊ฐ
|
| 245 |
+
gr.Markdown("### ๐ผ **์ง๋ฌด ๊ด๋ฆฌ**")
|
| 246 |
+
with gr.Row():
|
| 247 |
+
new_job_input = gr.Textbox(
|
| 248 |
+
label="์ ์ง๋ฌด ์ถ๊ฐ",
|
| 249 |
+
placeholder="์ง๋ฌด๋ช
์
๋ ฅ",
|
| 250 |
+
scale=2
|
| 251 |
+
)
|
| 252 |
+
add_job_btn = gr.Button("์ถ๊ฐ", size="sm", scale=1)
|
| 253 |
+
|
| 254 |
+
# ์์ ์ง๋ฌด ๋๋กญ๋ค์ด
|
| 255 |
+
job_dropdown = gr.Dropdown(
|
| 256 |
+
label="์์ ์ง๋ฌด ์ ํ",
|
| 257 |
+
choices=app_state.jobs,
|
| 258 |
+
value=None,
|
| 259 |
+
interactive=True
|
| 260 |
+
)
|
| 261 |
+
|
| 262 |
+
# ์ฌ์ฉ์ ์ ์ ์ผ๋ฐ ์ง๋ฌธ ์ถ๊ฐ
|
| 263 |
+
gr.Markdown("### ๐ **์ผ๋ฐ ์ง๋ฌธ ๊ด๋ฆฌ**")
|
| 264 |
+
with gr.Row():
|
| 265 |
+
new_question_input = gr.Textbox(
|
| 266 |
+
label="์ ์ผ๋ฐ ์ง๋ฌธ ์ถ๊ฐ",
|
| 267 |
+
placeholder="์ง๋ฌธ ๋ด์ฉ ์
๋ ฅ",
|
| 268 |
+
scale=2
|
| 269 |
+
)
|
| 270 |
+
add_question_btn = gr.Button("์ถ๊ฐ", size="sm", scale=1)
|
| 271 |
+
|
| 272 |
+
gr.HTML('</div>')
|
| 273 |
+
|
| 274 |
+
# ๊ฒฐ๊ณผ ์ถ๋ ฅ ์น์
|
| 275 |
+
with gr.Row():
|
| 276 |
+
with gr.Column(scale=2):
|
| 277 |
+
gr.Markdown("### ๐ **์์ฑ ๊ฒฐ๊ณผ**")
|
| 278 |
+
result_output = gr.Markdown(
|
| 279 |
+
value="๊ธฐ๋ณธ ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ '๋ง์ถคํ ์ง๋ฌธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.",
|
| 280 |
+
elem_classes=["result-output"]
|
| 281 |
+
)
|
| 282 |
+
|
| 283 |
+
with gr.Column(scale=1):
|
| 284 |
+
gr.Markdown("### ๐ฏ **์ง๋ฌธ ์นด๋**")
|
| 285 |
+
question_cards = gr.HTML(
|
| 286 |
+
value="<div style='text-align: center; color: #6B7280; padding: 20px;'>์ง๋ฌธ์ ์์ฑํด์ฃผ์ธ์</div>",
|
| 287 |
+
elem_classes=["question-cards"]
|
| 288 |
+
)
|
| 289 |
+
|
| 290 |
+
# ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ฐ๊ฒฐ
|
| 291 |
+
add_company_btn.click(
|
| 292 |
+
fn=add_company,
|
| 293 |
+
inputs=[new_company_input],
|
| 294 |
+
outputs=[company_dropdown, new_company_input]
|
| 295 |
+
)
|
| 296 |
+
|
| 297 |
+
add_job_btn.click(
|
| 298 |
+
fn=add_job,
|
| 299 |
+
inputs=[new_job_input],
|
| 300 |
+
outputs=[job_dropdown, new_job_input]
|
| 301 |
+
)
|
| 302 |
+
|
| 303 |
+
add_question_btn.click(
|
| 304 |
+
fn=add_question,
|
| 305 |
+
inputs=[new_question_input],
|
| 306 |
+
outputs=[common_questions_input, new_question_input]
|
| 307 |
+
)
|
| 308 |
+
|
| 309 |
+
# ๋๋กญ๋ค์ด ์ ํ ์ ์
๋ ฅ ํ๋์ ์๋ ์
๋ ฅ
|
| 310 |
+
company_dropdown.change(
|
| 311 |
+
fn=lambda x: x if x else "",
|
| 312 |
+
inputs=[company_dropdown],
|
| 313 |
+
outputs=[company_input]
|
| 314 |
+
)
|
| 315 |
+
|
| 316 |
+
job_dropdown.change(
|
| 317 |
+
fn=lambda x: x if x else "",
|
| 318 |
+
inputs=[job_dropdown],
|
| 319 |
+
outputs=[job_input]
|
| 320 |
+
)
|
| 321 |
+
|
| 322 |
+
# ์์ฑ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
| 323 |
+
generate_btn.click(
|
| 324 |
+
fn=process_question_generation,
|
| 325 |
+
inputs=[company_input, job_input, experience_input, common_questions_input, num_questions_input],
|
| 326 |
+
outputs=[result_output, question_cards],
|
| 327 |
+
api_name="generate_questions"
|
| 328 |
+
)
|
| 329 |
+
|
| 330 |
+
# ํธํฐ
|
| 331 |
+
gr.Markdown("""
|
| 332 |
+
---
|
| 333 |
+
**๐ก ์์ฑ๋ ์ง๋ฌธ ํ์ฉ ํ**:
|
| 334 |
+
- ๊ฐ ์ง๋ฌธ์ ๋ํด STAR(Situation, Task, Action, Result) ๊ธฐ๋ฒ์ผ๋ก ๋ต๋ณ์ ์ค๋นํด๋ณด์ธ์
|
| 335 |
+
- ํ์ฌ์ ์ง๋ฌด์ ๋ํ ์ฌ์ ์กฐ์ฌ๋ฅผ ๋ฐํ์ผ๋ก ๊ตฌ์ฒด์ ์ธ ์ฌ๋ก๋ฅผ ์ค๋นํ์ธ์
|
| 336 |
+
- ์์ฑ๋ ์ง๋ฌธ์ ๋ฐํ์ผ๋ก ์ถ๊ฐ ์ง๋ฌธ๋ค๋ ์์ํด๋ณด์ธ์
|
| 337 |
+
|
| 338 |
+
๐ค **Powered by**: OpenAI GPT-4o with Web Search
|
| 339 |
+
""")
|
| 340 |
+
|
| 341 |
+
return demo
|
| 342 |
+
|
| 343 |
+
if __name__ == "__main__":
|
| 344 |
+
# Gradio ์ฑ ์คํ
|
| 345 |
+
demo = create_interface()
|
| 346 |
+
demo.launch(
|
| 347 |
+
server_name="0.0.0.0",
|
| 348 |
+
# server_port=7864,
|
| 349 |
+
share=True,
|
| 350 |
+
show_error=True
|
| 351 |
+
)
|
commonly-asked-question/prompt.yaml
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
prompt: |
|
| 2 |
+
๋น์ ์ ์ฌ์ฉ์์ ์ํฉ์ ๋ง์ถฐ ๋ฉด์ ์์ ์ง๋ฌธ์ ์์ฑํด์ฃผ๋ ์ ๋ฌธ AI ์ปจ์คํดํธ์
๋๋ค.
|
| 3 |
+
์ฌ์ฉ์๊ฐ ์ ๊ณตํ๋ [์
๋ ฅ ์ ๋ณด]์ [์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ๋ฆฌ์คํธ]๋ฅผ ๋ฐํ์ผ๋ก, ํด๋น ๊ธฐ์
๊ณผ ์ง๋ฌด, ๊ฒฝ๋ ฅ ์์ค์ ๊ฐ์ฅ ์ ํฉํ ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ ์์ฑํด์ผ ํฉ๋๋ค.
|
| 4 |
+
|
| 5 |
+
### ์ง์นจ
|
| 6 |
+
1. **์น ๊ฒ์ ํ์ฉ:** ํ์ฌ๋ช
์ ๊ฒ์ํ์ฌ ์ต์ ๊ธฐ์
์ ๋ณด, ์ฌ์
ํํฉ, ์ฑ์ฉ ๋ํฅ, ๋ฉด์ ํ๊ธฐ, ๊ธฐ์
๋ฌธํ ๋ฑ์ ํ์ธํฉ๋๋ค.
|
| 7 |
+
2. **์ํฉ ๋ฐ์:** ๊ฒ์๋ ๊ธฐ์
์ ํน์ฑ(์
์ข
, ๋ฌธํ, ์ต๊ทผ ์ด์ ๋ฑ)๊ณผ ์ง๋ฌด์ ํต์ฌ ์ญ๋, ๊ฒฝ๋ ฅ ์์ค(์ ์
/๊ฒฝ๋ ฅ/์ธํด)์ ๋ชจ๋ ๊ณ ๋ คํ์ฌ ์ง๋ฌธ์ ์์ฑํฉ๋๋ค.
|
| 8 |
+
3. **์ง๋ฌธ ๊ตฌ์ฒดํ:** "์ง์ ๋๊ธฐ"์ ๊ฐ์ด ๋๋ฌด ์ผ๋ฐ์ ์ธ ์ง๋ฌธ์ ํผํ๊ณ , ๊ฒ์๋ ์ ๋ณด๋ฅผ ํ์ฉํ์ฌ ํจ์ฌ ๋ ๊ตฌ์ฒด์ ์ด๊ณ ๊น์ด ์๋ ์ง๋ฌธ์ผ๋ก ๋ง๋ค์ด์ผ ํฉ๋๋ค.
|
| 9 |
+
4. **๋ค์ํ ์ธก๋ฉด ํ๊ฐ:** ์์ฑ๋ ์ง๋ฌธ๋ค์ ์ง์์์ ์ง๋ฌด ์ญ๋, ์ปฌ์ฒํ(์กฐ์ง ์ ํฉ์ฑ), ์ฑ์ฅ ๊ฐ๋ฅ์ฑ ๋ฑ ๋ค์ํ ์ธก๋ฉด์ ์ข
ํฉ์ ์ผ๋ก ํ๊ฐํ ์ ์๋๋ก ๊ตฌ์ฑํฉ๋๋ค.
|
| 10 |
+
5. **์ฐฝ์์ ์ด์ง๋ง ํ์ค์ ์ธ ์ง๋ฌธ:** ๋๋ฌด ํฉ๋นํ๊ฑฐ๋ ํ์ค๊ณผ ๋๋จ์ด์ง ์ง๋ฌธ์ด ์๋, ์ค์ ๋ฉด์ ์์ ๋์ฌ ๋ฒํ ํ์ค์ ์ธ ์ง๋ฌธ์ ์์ฑํฉ๋๋ค.
|
| 11 |
+
|
| 12 |
+
### ์
๋ ฅ ์ ๋ณด
|
| 13 |
+
- **ํ์ฌ๋ช
:** {company_name}
|
| 14 |
+
- **์ง๋ฌด:** {job_title}
|
| 15 |
+
- **๊ฒฝ๋ ฅ ์์ค:** {experience_level}
|
| 16 |
+
- **์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ๋ฆฌ์คํธ:** {common_questions}
|
| 17 |
+
|
| 18 |
+
### ์ถ๋ ฅ ํ์
|
| 19 |
+
- ๋ฐ๋์ {num_questions}๊ฐ์ ์ง๋ฌธ์ ์์ฑํด์ผ ํฉ๋๋ค.
|
| 20 |
+
- ๊ฐ ์ง๋ฌธ์ JSON ํ์์ `sample_questions` ๋ฐฐ์ด์ ํฌํจ๋์ด์ผ ํฉ๋๋ค.
|
| 21 |
+
- ๋ฐ๋์ ์๋ ์์์ ์ ํํ ๊ฐ์ JSON ํ์์ผ๋ก๋ง ์๋ตํ์ธ์.
|
| 22 |
+
- ๋ค๋ฅธ ํ
์คํธ, ์ค๋ช
, ์ฃผ์์ ์ ๋ ํฌํจํ์ง ๋ง์ธ์.
|
| 23 |
+
- JSON ํ์์ด ์ฌ๋ฐ๋ฅธ์ง ํ์ธํ์ธ์ (์ฝค๋ง, ๋ฐ์ดํ, ์ค๊ดํธ ๋ฑ).
|
| 24 |
+
|
| 25 |
+
### ์์
|
| 26 |
+
[์
๋ ฅ]
|
| 27 |
+
- ํ์ฌ๋ช
: ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)
|
| 28 |
+
- ์ง๋ฌด: ๋ฐฑ์๋ ๊ฐ๋ฐ
|
| 29 |
+
- ๊ฒฝ๋ ฅ ์์ค: ์ ์
|
| 30 |
+
- ์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ๋ฆฌ์คํธ: ["์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์", "์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "๊ฐ์ฅ ๋์ ์ ์ธ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์", "์
์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์"]
|
| 31 |
+
|
| 32 |
+
[์ถ๋ ฅ]
|
| 33 |
+
```json
|
| 34 |
+
{{
|
| 35 |
+
"sample_questions": [
|
| 36 |
+
"์๋ง์ ํํ
ํฌ ๊ธฐ์
์ค ์ 'ํ ์ค'์ ์ง์ํ์
จ๋์?",
|
| 37 |
+
"๊ฐ๋ฐ์๋ก์ ๊ฐ์ฅ ํฌ๊ฒ ์ฑ์ฅํ๋ ๊ธฐ์ ์ ๋์ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์?",
|
| 38 |
+
"๋ณธ์ธ์ด ํ ์ค์ ๊ธฐ์ ๋ฌธํ(์์จ๊ณผ ์ฑ
์, ๋์ ๋๋ฃ ์ ๋ขฐ ๋ฑ)์ ์ ๋ง๋๋ค๊ณ ์๊ฐํ๋ ์ด์ ๋ฅผ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ์๊ฐํด ์ฃผ์ธ์."
|
| 39 |
+
]
|
| 40 |
+
}}
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
์ด์ ๋ค์ ์
๋ ฅ์ ๋ํ ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ ์ JSON ํ์์ผ๋ก๋ง ์์ฑํด์ฃผ์ธ์. ๋ค๋ฅธ ํ
์คํธ๋ ํฌํจํ์ง ๋ง์ธ์.
|
company-size-classification/.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
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
|
| 31 |
+
-----END CERTIFICATE-----
|
company-size-classification/__pycache__/llm_functions.cpython-312.pyc
ADDED
|
Binary file (4.2 kB). View file
|
|
|
company-size-classification/eval.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"company_size_classification": {
|
| 3 |
+
"enum": [
|
| 4 |
+
"๋๊ธฐ์
",
|
| 5 |
+
"์ค๊ฒฌ๊ธฐ์
",
|
| 6 |
+
"์ค์๊ธฐ์
",
|
| 7 |
+
"์คํํธ์
",
|
| 8 |
+
"์ธ๊ตญ๊ณ๊ธฐ์
",
|
| 9 |
+
"๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
",
|
| 10 |
+
"๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ",
|
| 11 |
+
"๊ธ์ต์
"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
"examples": [
|
| 15 |
+
{
|
| 16 |
+
"input": "์ผ์ฑ์ ์",
|
| 17 |
+
"output": "๋๊ธฐ์
"
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"input": "LG์ ์",
|
| 21 |
+
"output": "๋๊ธฐ์
"
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"input": "์นด์นด์ค",
|
| 25 |
+
"output": "์ค๊ฒฌ๊ธฐ์
"
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"input": "์ฟ ํก",
|
| 29 |
+
"output": "์คํํธ์
"
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"input": "JP๋ชจ๊ฑด",
|
| 33 |
+
"output": "์ธ๊ตญ๊ณ๊ธฐ์
"
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
"input": "์์ธ์์ฒญ",
|
| 37 |
+
"output": "๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
"
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"input": "ํ๊ตญ๋ ๋ํฌ๋ก์ค",
|
| 41 |
+
"output": "๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ"
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"input": "์ ํ์ํ",
|
| 45 |
+
"output": "๊ธ์ต์
"
|
| 46 |
+
}
|
| 47 |
+
]
|
| 48 |
+
}
|
company-size-classification/llm_functions.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import openai
|
| 2 |
+
import yaml
|
| 3 |
+
import re
|
| 4 |
+
|
| 5 |
+
# OpenAI client ์ด๊ธฐํ
|
| 6 |
+
client = openai.OpenAI()
|
| 7 |
+
|
| 8 |
+
# ํ๋กฌํํธ ํ
ํ๋ฆฟ ๋ก๋
|
| 9 |
+
import os
|
| 10 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 11 |
+
prompt_path = os.path.join(current_dir, 'prompt.yaml')
|
| 12 |
+
with open(prompt_path, 'r', encoding='utf-8') as f:
|
| 13 |
+
prompt_data = yaml.safe_load(f)
|
| 14 |
+
prompt_template = prompt_data['prompt']
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def parse_prediction(content):
|
| 18 |
+
"""
|
| 19 |
+
AI ์๋ต์์ ๊ธฐ์
๊ท๋ชจ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ํ์ฑํ๋ ํจ์
|
| 20 |
+
"""
|
| 21 |
+
predicted_category = "๋ถ๋ฅ ๋ถ๊ฐ"
|
| 22 |
+
|
| 23 |
+
# ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ: ```<๊ธฐ์
๊ท๋ชจ>``` ํ์์์ ํ์ฑ
|
| 24 |
+
category_match = re.search(r'```<([^>]+)>```', content)
|
| 25 |
+
if category_match:
|
| 26 |
+
predicted_category = category_match.group(1)
|
| 27 |
+
else:
|
| 28 |
+
# ๋ฐฑ์
: ๊ธฐ์กด ๋ฐฉ์์ผ๋ก ์นดํ
๊ณ ๋ฆฌ ์ฐพ๊ธฐ
|
| 29 |
+
categories = ["๋๊ธฐ์
", "์ค๊ฒฌ๊ธฐ์
", "์ค์๊ธฐ์
", "์คํํธ์
", "์ธ๊ตญ๊ณ๊ธฐ์
", "๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
", "๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ", "๊ธ์ต์
"]
|
| 30 |
+
for category in categories:
|
| 31 |
+
if category in content:
|
| 32 |
+
predicted_category = category
|
| 33 |
+
break
|
| 34 |
+
|
| 35 |
+
return predicted_category
|
| 36 |
+
|
| 37 |
+
def analyze_company_size(company_name):
|
| 38 |
+
"""
|
| 39 |
+
OpenAI Search API๋ฅผ ์ฌ์ฉํ์ฌ ๊ธฐ์
๊ท๋ชจ๋ฅผ ์์ธกํ๋ ํจ์
|
| 40 |
+
"""
|
| 41 |
+
try:
|
| 42 |
+
# OpenAI Search API๋ฅผ ์ฌ์ฉํ ํ์ฌ ์ ๋ณด ๊ฒ์
|
| 43 |
+
search_response = client.responses.create(
|
| 44 |
+
model="gpt-4o",
|
| 45 |
+
tools=[
|
| 46 |
+
{
|
| 47 |
+
"type": "web_search_preview",
|
| 48 |
+
"search_context_size": "low",
|
| 49 |
+
}
|
| 50 |
+
],
|
| 51 |
+
input= prompt_template.format(company_name=company_name)
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
# ์๋ต์์ ์ค์ ๋ฉ์์ง ์ฐพ๊ธฐ (์น ๊ฒ์ ํธ์ถ๊ณผ ๋ถ๋ฆฌ)
|
| 55 |
+
print(search_response)
|
| 56 |
+
message_output = None
|
| 57 |
+
for output in search_response.output:
|
| 58 |
+
if hasattr(output, 'content') and output.type == 'message':
|
| 59 |
+
message_output = output
|
| 60 |
+
break
|
| 61 |
+
|
| 62 |
+
if message_output is None:
|
| 63 |
+
raise Exception("์๋ต์์ ๋ฉ์์ง ๋ด์ฉ์ ์ฐพ์ ์ ์์ต๋๋ค.")
|
| 64 |
+
|
| 65 |
+
# ์๋ต์์ ๋ด์ฉ๊ณผ URL ์ถ์ถ
|
| 66 |
+
content = message_output.content[0].text
|
| 67 |
+
|
| 68 |
+
# URL ์ธ์ฉ ์ ๋ณด ์ถ์ถ
|
| 69 |
+
citations = []
|
| 70 |
+
if hasattr(message_output.content[0], 'annotations') and message_output.content[0].annotations:
|
| 71 |
+
for annotation in message_output.content[0].annotations:
|
| 72 |
+
if hasattr(annotation, 'url_citation'):
|
| 73 |
+
citations.append({
|
| 74 |
+
'title': annotation.url_citation.title,
|
| 75 |
+
'url': annotation.url_citation.url
|
| 76 |
+
})
|
| 77 |
+
|
| 78 |
+
# ๊ธฐ์
๊ท๋ชจ ์นดํ
๊ณ ๋ฆฌ ์ถ์ถ
|
| 79 |
+
predicted_category = parse_prediction(content)
|
| 80 |
+
|
| 81 |
+
# ์ฐธ์กฐ URL ํ์ํ
|
| 82 |
+
reference_text = ""
|
| 83 |
+
if citations:
|
| 84 |
+
reference_text = "\n\n๐ **์ฐธ๊ณ ์๋ฃ:**\n"
|
| 85 |
+
for i, citation in enumerate(citations, 1):
|
| 86 |
+
reference_text += f"{i}. [{citation['title']}]({citation['url']})\n"
|
| 87 |
+
|
| 88 |
+
# ์ต์ข
๊ฒฐ๊ณผ ํ์ํ (์นดํ
๊ณ ๋ฆฌ์ ๋ถ์ ๋ด์ฉ ๋ถ๋ฆฌ ๋ฐํ)
|
| 89 |
+
result_content = f"""## ๐ข {company_name} ๊ธฐ์
๊ท๋ชจ ๋ถ์ ๊ฒฐ๊ณผ
|
| 90 |
+
|
| 91 |
+
{content}
|
| 92 |
+
|
| 93 |
+
{reference_text}
|
| 94 |
+
|
| 95 |
+
---
|
| 96 |
+
*๋ณธ ๋ถ์์ OpenAI Search API๋ฅผ ํตํด ์์ง๋ ์ต์ ์น ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ํ๋์์ต๋๋ค.*
|
| 97 |
+
"""
|
| 98 |
+
|
| 99 |
+
return result_content, predicted_category
|
| 100 |
+
|
| 101 |
+
except Exception as e:
|
| 102 |
+
error_msg = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 103 |
+
|
| 104 |
+
์ฃ์กํฉ๋๋ค. {company_name}์ ๊ธฐ์
๊ท๋ชจ ๋ถ์ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 105 |
+
|
| 106 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 107 |
+
|
| 108 |
+
๋ค์ ์๋ํด์ฃผ์๊ฑฐ๋ ๋ค๋ฅธ ๊ธฐ์
๋ช
์ ์
๋ ฅํด์ฃผ์ธ์.
|
| 109 |
+
"""
|
| 110 |
+
return error_msg, "์ค๋ฅ ๋ฐ์"
|
company-size-classification/main.py
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from llm_functions import analyze_company_size
|
| 3 |
+
|
| 4 |
+
# LLM ๊ด๋ จ ํจ์๋ค์ llm_functions.py๋ก ์ด๋๋จ
|
| 5 |
+
|
| 6 |
+
example_company_name = ["์ผ์ฑ์ ์", "ํ๋์๋์ฐจ", "LG์ ์", "SKํ์ด๋์ค", "ํฌ์ค์ฝํ๋ฉ์ค", "ํํ", "๋กฏ๋ฐ์ผ๋ฏธ์นผ", "CJ์ ์ผ์ ๋น", "๋์ฐ์๋๋น๋ฆฌํฐ", "KT", "์
ํธ๋ฆฌ์จํฌ์ค์ผ์ด", "์์ค์ํ์์ด", "ํ๋ฆผ์ง์ฃผ", "์ด๋
น์ค์ฒจ๋จ์์ฌ", "์ฝ์จ์ด", "ํ์์ผ๋ฏธ์นผ", "๋ดํฐ์", "์์ฝํ๋ก์์ด์น์", "๋ค์ฐ๊ธฐ์ ", "์ ๋ฅ์ ", "์ค์คํ
์ํ๋ํธ", "๋น์ธ ๋ก์
", "๋ฐ๋ํ๋๋", "์จ์์ด์์ค", "์์ด์ผ์ค", "์ด๋ฃจ๋ค", "๋๋
ธ์ ์์ฌ", "์๋ฉ์ด๋๋งฅ์ค", "์์ด์น์์ฌ์ด์ธ์ค", "๋๋ค์ด์ณํ๋ฉ์ค", "ํผ์์ค์ผ์ด", "๋ดํ์ํ๋ผ์ฆ๋ง", "์ง๋์ค", "์์ตIPS", "์ง์์ด์ด๋
ธ๋ฒ ์ด์
", "๋คผ์ด๋", "์ผ๋๋ฒ๋", "์ง๋ฐฉ", "๋ฆฌ๋", "๋ฒ์ฆ๋น", "๋น๊ทผ๋ง์ผ", "์ปฌ๋ฆฌ", "์์ฑ ", "๋ฃจ๋", "ํ๋ผ๋คํ๋ฆฌ์", "ํฌ๋ํํค ๋ฒค์ฒ์ค", "๋ฑ
ํฌ์๋ฌ๋", "์งํ ", "ํธ๋ ๋ฐ๋ฆฌ", "๋ฉ์คํ๋ ์"]
|
| 7 |
+
|
| 8 |
+
# analyze_company_size ํจ์๋ llm_functions.py๋ก ์ด๋๋จ
|
| 9 |
+
|
| 10 |
+
def get_category_button_style(category):
|
| 11 |
+
"""
|
| 12 |
+
์นดํ
๊ณ ๋ฆฌ๋ณ ์๊น๊ณผ ์คํ์ผ์ ๋ฐํํ๋ ํจ์
|
| 13 |
+
"""
|
| 14 |
+
category_styles = {
|
| 15 |
+
"๋๊ธฐ์
": {"color": "#1E40AF", "bg_color": "#EBF8FF", "emoji": "๐ข"},
|
| 16 |
+
"์ค๊ฒฌ๊ธฐ์
": {"color": "#059669", "bg_color": "#ECFDF5", "emoji": "๐ญ"},
|
| 17 |
+
"์ค์๊ธฐ์
": {"color": "#DC2626", "bg_color": "#FEF2F2", "emoji": "๐ช"},
|
| 18 |
+
"์คํํธ์
": {"color": "#7C3AED", "bg_color": "#F5F3FF", "emoji": "๐"},
|
| 19 |
+
"์ธ๊ตญ๊ณ๊ธฐ์
": {"color": "#EA580C", "bg_color": "#FFF7ED", "emoji": "๐"},
|
| 20 |
+
"๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
": {"color": "#0F766E", "bg_color": "#F0FDFA", "emoji": "๐๏ธ"},
|
| 21 |
+
"๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ": {"color": "#BE185D", "bg_color": "#FDF2F8", "emoji": "๐ค"},
|
| 22 |
+
"๊ธ์ต์
": {"color": "#7C2D12", "bg_color": "#FEF7ED", "emoji": "๐ฆ"},
|
| 23 |
+
"๋ถ๋ฅ ๋ถ๊ฐ": {"color": "#6B7280", "bg_color": "#F9FAFB", "emoji": "โ"},
|
| 24 |
+
"์ค๋ฅ ๋ฐ์": {"color": "#B91C1C", "bg_color": "#FEF2F2", "emoji": "โ ๏ธ"}
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
return category_styles.get(category, category_styles["๋ถ๋ฅ ๋ถ๊ฐ"])
|
| 28 |
+
|
| 29 |
+
def create_category_html(category):
|
| 30 |
+
"""
|
| 31 |
+
์นดํ
๊ณ ๋ฆฌ๋ฅผ ์ํ HTML ๋ฒํผ์ ์์ฑํ๋ ํจ์
|
| 32 |
+
"""
|
| 33 |
+
style = get_category_button_style(category)
|
| 34 |
+
|
| 35 |
+
html = f"""
|
| 36 |
+
<div style="text-align: center; padding: 10px;">
|
| 37 |
+
<div style="
|
| 38 |
+
background-color: {style['bg_color']};
|
| 39 |
+
border: 2px solid {style['color']};
|
| 40 |
+
border-radius: 15px;
|
| 41 |
+
padding: 15px 20px;
|
| 42 |
+
margin: 10px 0;
|
| 43 |
+
font-weight: bold;
|
| 44 |
+
font-size: 16px;
|
| 45 |
+
color: {style['color']};
|
| 46 |
+
text-align: center;
|
| 47 |
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
| 48 |
+
">
|
| 49 |
+
<div style="font-size: 24px; margin-bottom: 5px;">{style['emoji']}</div>
|
| 50 |
+
<div>{category}</div>
|
| 51 |
+
</div>
|
| 52 |
+
</div>
|
| 53 |
+
"""
|
| 54 |
+
return html
|
| 55 |
+
|
| 56 |
+
def process_analysis_result(company_name):
|
| 57 |
+
"""
|
| 58 |
+
๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๊ณ UI์ ํ์ํ ํํ๋ก ๋ณํํ๋ ํจ์
|
| 59 |
+
"""
|
| 60 |
+
try:
|
| 61 |
+
content, category = analyze_company_size(company_name)
|
| 62 |
+
category_html = create_category_html(category)
|
| 63 |
+
return content, category_html
|
| 64 |
+
except Exception as e:
|
| 65 |
+
error_content = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 66 |
+
|
| 67 |
+
์ฃ์กํฉ๋๋ค. {company_name}์ ๊ธฐ์
๊ท๋ชจ ๋ถ์ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 68 |
+
|
| 69 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 70 |
+
|
| 71 |
+
๋ค์ ์๋ํด์ฃผ์๊ฑฐ๋ ๋ค๋ฅธ ๊ธฐ์
๋ช
์ ์
๋ ฅํด์ฃผ์ธ์.
|
| 72 |
+
"""
|
| 73 |
+
error_html = create_category_html("์ค๋ฅ ๋ฐ์")
|
| 74 |
+
return error_content, error_html
|
| 75 |
+
|
| 76 |
+
def create_interface():
|
| 77 |
+
"""
|
| 78 |
+
Gradio ์ธํฐํ์ด์ค ์์ฑ
|
| 79 |
+
"""
|
| 80 |
+
with gr.Blocks(
|
| 81 |
+
title="๐ข AI ๊ธฐ์
๊ท๋ชจ ์์ธก๊ธฐ",
|
| 82 |
+
theme=gr.themes.Soft(),
|
| 83 |
+
css="""
|
| 84 |
+
.main-header {
|
| 85 |
+
text-align: center;
|
| 86 |
+
padding: 20px;
|
| 87 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 88 |
+
color: white;
|
| 89 |
+
border-radius: 10px;
|
| 90 |
+
margin-bottom: 20px;
|
| 91 |
+
}
|
| 92 |
+
.example-section {
|
| 93 |
+
background-color: #f8f9fa;
|
| 94 |
+
padding: 15px;
|
| 95 |
+
border-radius: 8px;
|
| 96 |
+
margin: 10px 0;
|
| 97 |
+
}
|
| 98 |
+
"""
|
| 99 |
+
) as demo:
|
| 100 |
+
|
| 101 |
+
# ํค๋
|
| 102 |
+
gr.HTML("""
|
| 103 |
+
<div class="main-header">
|
| 104 |
+
<h1>๐ข AI ๊ธฐ์
๊ท๋ชจ ์์ธก๊ธฐ</h1>
|
| 105 |
+
<p>OpenAI Search API๋ฅผ ํ์ฉํ ์ค์๊ฐ ๊ธฐ์
์ ๋ณด ๋ถ์</p>
|
| 106 |
+
</div>
|
| 107 |
+
""")
|
| 108 |
+
|
| 109 |
+
# ์ค๋ช
|
| 110 |
+
gr.Markdown("""
|
| 111 |
+
### ๐ **์ฌ์ฉ ๋ฐฉ๋ฒ**
|
| 112 |
+
1. **์ง์ ์
๋ ฅ**: ๋ถ์ํ๊ณ ์ถ์ ๊ธฐ์
๋ช
์ ์
๋ ฅ์ฐฝ์ ์ง์ ์์ฑ
|
| 113 |
+
2. **์์ ์ ํ**: ์๋ ์์ ๊ธฐ์
์ค ํ๋๋ฅผ ํด๋ฆญํ์ฌ ์๋ ์
๋ ฅ
|
| 114 |
+
3. **๋ถ์ ์คํ**: '๊ธฐ์
๊ท๋ชจ ๋ถ์' ๋ฒํผ์ ํด๋ฆญํ์ฌ ๊ฒฐ๊ณผ ํ์ธ
|
| 115 |
+
|
| 116 |
+
โจ **ํน์ง**: ์ต์ ์น ์ ๋ณด๋ฅผ ์ค์๊ฐ์ผ๋ก ๊ฒ์ํ์ฌ ์ ํํ ๊ธฐ์
๊ท๋ชจ๋ฅผ ๋ถ๋ฅํฉ๋๋ค.
|
| 117 |
+
""")
|
| 118 |
+
|
| 119 |
+
with gr.Row():
|
| 120 |
+
with gr.Column(scale=2):
|
| 121 |
+
# ์
๋ ฅ ์น์
|
| 122 |
+
company_input = gr.Textbox(
|
| 123 |
+
label="๐ข ๊ธฐ์
๋ช
์
๋ ฅ",
|
| 124 |
+
placeholder="๋ถ์ํ๊ณ ์ถ์ ๊ธฐ์
๋ช
์ ์
๋ ฅํ์ธ์ (์: ์ผ์ฑ์ ์, ์นด์นด์ค, ๋ฐฐ๋ฌ์๋ฏผ์กฑ ๋ฑ)",
|
| 125 |
+
value="",
|
| 126 |
+
lines=1
|
| 127 |
+
)
|
| 128 |
+
|
| 129 |
+
analyze_btn = gr.Button(
|
| 130 |
+
"๐ ๊ธฐ์
๊ท๋ชจ ๋ถ์",
|
| 131 |
+
variant="primary",
|
| 132 |
+
size="lg"
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
+
with gr.Column(scale=1):
|
| 136 |
+
# ์ ๋ณด ๋ฐ์ค
|
| 137 |
+
gr.Markdown("""
|
| 138 |
+
### โน๏ธ **๋ถ๋ฅ ๊ธฐ์ค**
|
| 139 |
+
- **๋๊ธฐ์
**: ๋งค์ถ 1์กฐ์ ์ด์
|
| 140 |
+
- **์ค๊ฒฌ๊ธฐ์
**: ๋งค์ถ 1000์ต-1์กฐ์
|
| 141 |
+
- **์ค์๊ธฐ์
**: ๋งค์ถ 1000์ต์ ๋ฏธ๋ง
|
| 142 |
+
- **์คํํธ์
**: ์ค๋ฆฝ 10๋
์ด๋ด
|
| 143 |
+
- **์ธ๊ตญ๊ณ๊ธฐ์
**: ํด์ธ ๋ณธ์ฌ ๊ธฐ์
|
| 144 |
+
- **๊ณต๊ณต๊ธฐ๊ด**: ์ ๋ถ ์ถ์/์ถ์ฐ
|
| 145 |
+
- **๋น์๋ฆฌ๋จ์ฒด**: ๋น์๋ฆฌ ๋ชฉ์
|
| 146 |
+
- **๊ธ์ต์
**: ๊ธ์ต ์๋น์ค์
|
| 147 |
+
""")
|
| 148 |
+
|
| 149 |
+
# ์์ ๊ธฐ์
์น์
|
| 150 |
+
gr.HTML('<div class="example-section">')
|
| 151 |
+
gr.Markdown("### ๐ผ **์์ ๊ธฐ์
์ ํ** (ํด๋ฆญํ๋ฉด ์๋ ์
๋ ฅ๋ฉ๋๋ค)")
|
| 152 |
+
|
| 153 |
+
# ์์ ๋ฒํผ๋ค์ ํ๋ณ๋ก ๋ฐฐ์น
|
| 154 |
+
example_rows = [example_company_name[i:i+10] for i in range(0, len(example_company_name), 10)]
|
| 155 |
+
|
| 156 |
+
for row in example_rows:
|
| 157 |
+
with gr.Row():
|
| 158 |
+
for company in row:
|
| 159 |
+
example_btn = gr.Button(
|
| 160 |
+
company,
|
| 161 |
+
size="sm",
|
| 162 |
+
variant="secondary",
|
| 163 |
+
scale=1
|
| 164 |
+
)
|
| 165 |
+
example_btn.click(
|
| 166 |
+
fn=lambda x=company: x,
|
| 167 |
+
outputs=company_input
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
+
gr.HTML('</div>')
|
| 171 |
+
|
| 172 |
+
# ๊ฒฐ๊ณผ ์ถ๋ ฅ ์น์
|
| 173 |
+
with gr.Row():
|
| 174 |
+
with gr.Column(scale=3):
|
| 175 |
+
gr.Markdown("### ๐ **๋ถ์ ๊ฒฐ๊ณผ**")
|
| 176 |
+
result_output = gr.Markdown(
|
| 177 |
+
label="๋ถ์ ๊ฒฐ๊ณผ",
|
| 178 |
+
value="๊ธฐ์
๋ช
์ ์
๋ ฅํ๊ณ '๊ธฐ์
๊ท๋ชจ ๋ถ์' ๋ฒํผ์ ํด๋ฆญํ์ธ์.",
|
| 179 |
+
elem_classes=["result-output"]
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
with gr.Column(scale=1):
|
| 183 |
+
gr.Markdown("### ๐ **๋ถ๋ฅ ๊ฒฐ๊ณผ**")
|
| 184 |
+
# ์นดํ
๊ณ ๋ฆฌ ํ์์ฉ HTML ์ปดํฌ๋ํธ
|
| 185 |
+
category_display = gr.HTML(
|
| 186 |
+
value="""<div style="text-align: center; padding: 20px;">
|
| 187 |
+
<div style="color: #6B7280; font-size: 14px;">๋ถ์์ ์คํํด์ฃผ์ธ์</div>
|
| 188 |
+
</div>""",
|
| 189 |
+
elem_classes=["category-display"]
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
+
# ๋ถ์ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
| 193 |
+
analyze_btn.click(
|
| 194 |
+
fn=process_analysis_result,
|
| 195 |
+
inputs=[company_input],
|
| 196 |
+
outputs=[result_output, category_display],
|
| 197 |
+
api_name="analyze_company"
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
# ์ํฐํค๋ก๋ ๋ถ์ ์คํ ๊ฐ๋ฅ
|
| 201 |
+
company_input.submit(
|
| 202 |
+
fn=process_analysis_result,
|
| 203 |
+
inputs=[company_input],
|
| 204 |
+
outputs=[result_output, category_display]
|
| 205 |
+
)
|
| 206 |
+
|
| 207 |
+
# ํธํฐ
|
| 208 |
+
gr.Markdown("""
|
| 209 |
+
---
|
| 210 |
+
**๐ก ํ**:
|
| 211 |
+
- ํ๊ตญ ๊ธฐ์
๋ช
๋ฟ๋ง ์๋๋ผ ๊ธ๋ก๋ฒ ๊ธฐ์
๋ ๋ถ์ ๊ฐ๋ฅํฉ๋๋ค
|
| 212 |
+
- ๋ถ์ ๊ฒฐ๊ณผ์๋ ์ค์๊ฐ ์น ๊ฒ์์ ํตํ ์ต์ ์ ๋ณด๊ฐ ๋ฐ์๋ฉ๋๋ค
|
| 213 |
+
- ์ฐธ๊ณ ์๋ฃ ๋งํฌ๋ฅผ ํตํด ์์ธ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค
|
| 214 |
+
|
| 215 |
+
๐ **Powered by**: OpenAI Search API (gpt-4o-mini-search-preview)
|
| 216 |
+
""")
|
| 217 |
+
|
| 218 |
+
return demo
|
| 219 |
+
|
| 220 |
+
if __name__ == "__main__":
|
| 221 |
+
# Gradio ์ฑ ์คํ
|
| 222 |
+
demo = create_interface()
|
| 223 |
+
demo.launch(
|
| 224 |
+
server_name="0.0.0.0",
|
| 225 |
+
server_port=7859,
|
| 226 |
+
share=True,
|
| 227 |
+
show_error=True
|
| 228 |
+
)
|
company-size-classification/prompt.yaml
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
prompt_simple: |
|
| 2 |
+
๋น์ ์ ํ๊ตญ ๊ธฐ์
์ ๊ท๋ชจ๋ฅผ ๋ถ์ํ๋ ์ ๋ฌธ๊ฐ์
๋๋ค. ์ฃผ์ด์ง ๊ธฐ์
์ ๊ท๋ชจ๋ฅผ ๋ค์ ์นดํ
๊ณ ๋ฆฌ ์ค ํ๋๋ก ๋ถ๋ฅํด์ฃผ์ธ์.
|
| 3 |
+
๋ต๋ณ์ ๋ฐ๋์ ์๋ ์นดํ
๊ณ ๋ฆฌ ์ค ํ๋๋ง ํฌํจํด์ผ ํ๋ฉฐ, ๋ค๋ฅธ ์ค๋ช
์ ํฌํจํ์ง ๋ง์ธ์.
|
| 4 |
+
|
| 5 |
+
### ๊ธฐ์
๊ท๋ชจ ๋ถ๋ฅ ๊ธฐ์ค
|
| 6 |
+
- ๋๊ธฐ์
: ๋๊ท๋ชจ ๊ณ์ด์ฌ, ๋งค์ถ 1์กฐ์ ์ด์, ์ง์ 1๋ง๋ช
์ด์
|
| 7 |
+
- ์ค๊ฒฌ๊ธฐ์
: ๋งค์ถ 1000์ต-1์กฐ์, ์ง์ 300๋ช
-1๋ง๋ช
|
| 8 |
+
- ์ค์๊ธฐ์
: ๋งค์ถ 1000์ต์ ๋ฏธ๋ง, ์ง์ 300๋ช
๋ฏธ๋ง
|
| 9 |
+
- ์คํํธ์
: ์ค๋ฆฝ 10๋
์ด๋ด, ๋น ๋ฅธ ์ฑ์ฅ ๋จ๊ณ
|
| 10 |
+
- ์ธ๊ตญ๊ณ๊ธฐ์
: ํด์ธ ๋ณธ์ฌ๋ฅผ ๋ ๊ธฐ์
์ ํ๊ตญ ์ง์ฌ
|
| 11 |
+
- ๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
: ์ ๋ถ ์ถ์/์ถ์ฐ ๊ธฐ๊ด
|
| 12 |
+
- ๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ: ๋น์๋ฆฌ ๋ชฉ์ ์กฐ์ง
|
| 13 |
+
- ๊ธ์ต์
: ์ํ, ๋ณดํ, ์ฆ๊ถ ๋ฑ ๊ธ์ต ์๋น์ค
|
| 14 |
+
|
| 15 |
+
### ์์
|
| 16 |
+
[์์ 1]
|
| 17 |
+
๊ธฐ์
์ด๋ฆ: ์ผ์ฑ์ ์
|
| 18 |
+
๊ธฐ์
๊ท๋ชจ: ๋๊ธฐ์
|
| 19 |
+
|
| 20 |
+
[Example 2]
|
| 21 |
+
๊ธฐ์
์ด๋ฆ: LG์ ์
|
| 22 |
+
๊ธฐ์
๊ท๋ชจ: ๋๊ธฐ์
|
| 23 |
+
|
| 24 |
+
[Example 3]
|
| 25 |
+
๊ธฐ์
์ด๋ฆ: ์นด์นด์ค
|
| 26 |
+
๊ธฐ์
๊ท๋ชจ: ์ค๊ฒฌ๊ธฐ์
|
| 27 |
+
|
| 28 |
+
[Example 4]
|
| 29 |
+
๊ธฐ์
์ด๋ฆ: ์ฟ ํก
|
| 30 |
+
๊ธฐ์
๊ท๋ชจ: ์คํํธ์
|
| 31 |
+
|
| 32 |
+
[Example 5]
|
| 33 |
+
๊ธฐ์
์ด๋ฆ: JP๋ชจ๊ฑด
|
| 34 |
+
๊ธฐ์
๊ท๋ชจ: ์ธ๊ตญ๊ณ๊ธฐ์
|
| 35 |
+
|
| 36 |
+
[Example 6]
|
| 37 |
+
๊ธฐ์
์ด๋ฆ: ์์ธ์์ฒญ
|
| 38 |
+
๊ธฐ์
๊ท๋ชจ: ๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
|
| 39 |
+
|
| 40 |
+
[Example 7]
|
| 41 |
+
๊ธฐ์
์ด๋ฆ: ํ๊ตญ๋ ๋ํฌ๋ก์ค
|
| 42 |
+
๊ธฐ์
๊ท๋ชจ: ๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ
|
| 43 |
+
|
| 44 |
+
[Example 8]
|
| 45 |
+
๊ธฐ์
์ด๋ฆ: ์ ํ์ํ
|
| 46 |
+
๊ธฐ์
๊ท๋ชจ: ๊ธ์ต์
|
| 47 |
+
|
| 48 |
+
### Input
|
| 49 |
+
๊ธฐ์
์ด๋ฆ: {company_name}
|
| 50 |
+
๊ธฐ์
๊ท๋ชจ:
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
prompt: |
|
| 55 |
+
๋น์ ์ ํ๊ตญ ๊ธฐ์
์ ๊ท๋ชจ๋ฅผ ๋ถ์ํ๋ ์ ๋ฌธ๊ฐ์
๋๋ค. ์น ๊ฒ์์ ํตํด ์ป์ ์ต์ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ๊ธฐ์
์ ๊ท๋ชจ๋ฅผ ์ ํํ ๋ถ๋ฅํ๊ณ ์์ธํ ๋ถ์์ ์ ๊ณตํด์ฃผ์ธ์.
|
| 56 |
+
|
| 57 |
+
### ๊ธฐ์
๊ท๋ชจ ๋ถ๋ฅ ๊ธฐ์ค
|
| 58 |
+
- ๋๊ธฐ์
: ๋๊ท๋ชจ ๊ณ์ด์ฌ, ๋งค์ถ 1์กฐ์ ์ด์, ์ง์ 1๋ง๋ช
์ด์
|
| 59 |
+
- ์ค๊ฒฌ๊ธฐ์
: ๋งค์ถ 1000์ต-1์กฐ์, ์ง์ 300๋ช
-1๋ง๋ช
|
| 60 |
+
- ์ค์๊ธฐ์
: ๋งค์ถ 1000์ต์ ๋ฏธ๋ง, ์ง์ 300๋ช
๋ฏธ๋ง
|
| 61 |
+
- ์คํํธ์
: ์ค๋ฆฝ 10๋
์ด๋ด, ๋น ๋ฅธ ์ฑ์ฅ ๋จ๊ณ
|
| 62 |
+
- ์ธ๊ตญ๊ณ๊ธฐ์
: ํด์ธ ๋ณธ์ฌ๋ฅผ ๋ ๊ธฐ์
์ ํ๊ตญ ์ง์ฌ
|
| 63 |
+
- ๊ณต๊ณต๊ธฐ๊ด ๋ฐ ๊ณต๊ธฐ์
: ์ ๋ถ ์ถ์/์ถ์ฐ ๊ธฐ๊ด
|
| 64 |
+
- ๋น์๋ฆฌ๋จ์ฒด ๋ฐ ํํ์ฌ๋จ: ๋น์๋ฆฌ ๋ชฉ์ ์กฐ์ง
|
| 65 |
+
- ๊ธ์ต์
: ์ํ, ๋ณดํ, ์ฆ๊ถ ๋ฑ ๊ธ์ต ์๋น์ค
|
| 66 |
+
- ๋ถ๋ฅ๋ถ๊ฐ: ์ถฉ๋ถํ ์ ๋ณด๊ฐ ์์ด ๋ถ๋ฅ๊ฐ ์ด๋ ค์ด ๊ฒฝ์ถฉ
|
| 67 |
+
|
| 68 |
+
### ๋ต๋ณ ํ์
|
| 69 |
+
๋ค์ ํ์์ผ๋ก ์์ธํ ๋ถ์์ ์ ๊ณตํด์ฃผ์ธ์:
|
| 70 |
+
|
| 71 |
+
**๊ธฐ์
๊ฐ์:**
|
| 72 |
+
- ํด๋น ๊ธฐ์
์ ๋ํ ๊ฐ๋จํ ์๊ฐ (3-4์ค)
|
| 73 |
+
|
| 74 |
+
**๊ธฐ์
๊ท๋ชจ ๋ถ๋ฅ:** [์ 8๊ฐ ์นดํ
๊ณ ๋ฆฌ ์ค ํ๋]
|
| 75 |
+
|
| 76 |
+
**๋ถ๋ฅ ๊ทผ๊ฑฐ:**
|
| 77 |
+
- ๋งค์ถ ๊ท๋ชจ: (๊ตฌ์ฒด์ ์์น ํฌํจ)
|
| 78 |
+
- ์ง์ ์: (๊ตฌ์ฒด์ ์์น ํฌํจ)
|
| 79 |
+
- ์
์ข
/์ฌ์
์์ญ:
|
| 80 |
+
- ๊ธฐํ ํน์ง:
|
| 81 |
+
|
| 82 |
+
### ๋ถ์ ๋์ ๊ธฐ์
|
| 83 |
+
๊ธฐ์
์ด๋ฆ: {company_name}
|
| 84 |
+
|
| 85 |
+
์ ํ์์ ๋ฐ๋ผ ์์ธํ ๋ถ์์ ์ ๊ณตํด์ฃผ์ธ์. ๋ถ๋ฅ ์นดํ
๊ณ ๋ฆฌ๋ ๋ฐ๋์ ๋ต๋ณ ๋ง์ง๋ง์ ```<๊ธฐ์
๊ท๋ชจ>``` ํ์์ผ๋ก ํ์ํด์ฃผ์ธ์. ๋ถ๋ฅ ์นดํ
๊ณ ๋ฆฌ๋ ๋ฐ๋์ ๋ต๋ณ ๋ง์ง๋ง์ ```<๊ธฐ์
๊ท๋ชจ>``` ํ์์ผ๋ก ํ์ํด์ฃผ์ธ์ ("<" ์ ">" ๊ธฐํธ ํฌํจ).
|
industry-classification/.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
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
|
| 31 |
+
-----END CERTIFICATE-----
|
industry-classification/__pycache__/llm_functions.cpython-312.pyc
ADDED
|
Binary file (11.2 kB). View file
|
|
|
industry-classification/eval.json
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"industryCategories": [
|
| 3 |
+
{
|
| 4 |
+
"id": "it-platform-game",
|
| 5 |
+
"name": "IT ยท ํ๋ซํผ ยท ๊ฒ์",
|
| 6 |
+
"isPrimary": true,
|
| 7 |
+
"tags": [
|
| 8 |
+
{ "tagId": "platform-portal", "tagName": "#ํ๋ซํผ/ํฌํธ" },
|
| 9 |
+
{ "tagId": "e-commerce", "tagName": "#์ด์ปค๋จธ์ค" },
|
| 10 |
+
{ "tagId": "game", "tagName": "#๊ฒ์" },
|
| 11 |
+
{ "tagId": "it-solution-si", "tagName": "#IT์๋ฃจ์
/SI" },
|
| 12 |
+
{ "tagId": "o2o-vertical", "tagName": "#O2O/๋ฒํฐ์ปฌ" },
|
| 13 |
+
{ "tagId": "ai-data", "tagName": "#AI/๋ฐ์ดํฐ" },
|
| 14 |
+
{ "tagId": "cloud-saas", "tagName": "#ํด๋ผ์ฐ๋/SaaS" },
|
| 15 |
+
{ "tagId": "fintech", "tagName": "#ํํ
ํฌ" }
|
| 16 |
+
]
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"id": "manufacturing-hardware",
|
| 20 |
+
"name": "์ ์กฐ ยท ํ๋์จ์ด",
|
| 21 |
+
"isPrimary": true,
|
| 22 |
+
"tags": [
|
| 23 |
+
{ "tagId": "semiconductor", "tagName": "#๋ฐ๋์ฒด" },
|
| 24 |
+
{ "tagId": "electronics-home", "tagName": "#๊ฐ์ /์ ์์ ํ" },
|
| 25 |
+
{ "tagId": "automotive-mobility", "tagName": "#์๋์ฐจ/๋ชจ๋น๋ฆฌํฐ" },
|
| 26 |
+
{ "tagId": "battery", "tagName": "#2์ฐจ์ ์ง" },
|
| 27 |
+
{ "tagId": "display", "tagName": "#๋์คํ๋ ์ด" },
|
| 28 |
+
{ "tagId": "heavy-industry-shipbuilding", "tagName": "#์ค๊ณต์
/์กฐ์ " },
|
| 29 |
+
{ "tagId": "steel-metal", "tagName": "#์ฒ ๊ฐ/๊ธ์" }
|
| 30 |
+
]
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"id": "finance",
|
| 34 |
+
"name": "๊ธ์ต",
|
| 35 |
+
"isPrimary": true,
|
| 36 |
+
"tags": [
|
| 37 |
+
{ "tagId": "bank", "tagName": "#์ํ" },
|
| 38 |
+
{ "tagId": "securities", "tagName": "#์ฆ๊ถ" },
|
| 39 |
+
{ "tagId": "insurance", "tagName": "#๋ณดํ" },
|
| 40 |
+
{ "tagId": "card", "tagName": "#์นด๋" },
|
| 41 |
+
{ "tagId": "asset-management", "tagName": "#์์ฐ์ด์ฉ" }
|
| 42 |
+
]
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"id": "retail-fmcg-life",
|
| 46 |
+
"name": "์ ํต ยท ์๋น์ฌ ยท ์ํ",
|
| 47 |
+
"isPrimary": true,
|
| 48 |
+
"tags": [
|
| 49 |
+
{ "tagId": "dept-store-mart", "tagName": "#๋ฐฑํ์ /๋งํธ" },
|
| 50 |
+
{ "tagId": "convenience-store", "tagName": "#ํธ์์ " },
|
| 51 |
+
{ "tagId": "fmcg-beverage", "tagName": "#FMCG/์์๋ฃ" },
|
| 52 |
+
{ "tagId": "fashion-beauty", "tagName": "#ํจ์
/๋ทฐํฐ" },
|
| 53 |
+
{ "tagId": "duty-free", "tagName": "#๋ฉด์ธ์ " }
|
| 54 |
+
]
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"id": "bio-pharma-medical",
|
| 58 |
+
"name": "๋ฐ์ด์ค ยท ์ ์ฝ ยท ์๋ฃ",
|
| 59 |
+
"isPrimary": true,
|
| 60 |
+
"tags": [
|
| 61 |
+
{ "tagId": "pharma-new-drug", "tagName": "#์ ์ฝ/์ ์ฝ๊ฐ๋ฐ" },
|
| 62 |
+
{ "tagId": "bio-cmo", "tagName": "#๋ฐ์ด์ค/CMO" },
|
| 63 |
+
{ "tagId": "medical-device", "tagName": "#์๋ฃ๊ธฐ๊ธฐ" },
|
| 64 |
+
{ "tagId": "digital-healthcare", "tagName": "#๋์งํธํฌ์ค์ผ์ด" }
|
| 65 |
+
]
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"id": "media-contents-ad",
|
| 69 |
+
"name": "๋ฏธ๋์ด ยท ์ฝํ
์ธ ยท ๊ด๊ณ ",
|
| 70 |
+
"isPrimary": true,
|
| 71 |
+
"tags": [
|
| 72 |
+
{ "tagId": "entertainment", "tagName": "#์ํฐํ
์ธ๋จผํธ" },
|
| 73 |
+
{ "tagId": "contents-video", "tagName": "#์ฝํ
์ธ /์์์ ์" },
|
| 74 |
+
{ "tagId": "ad-agency", "tagName": "#๊ด๊ณ ๋ํ์ฌ" },
|
| 75 |
+
{ "tagId": "webtoon-webnovel", "tagName": "#์นํฐ/์น์์ค" },
|
| 76 |
+
{ "tagId": "broadcasting-press", "tagName": "#๋ฐฉ์ก/์ธ๋ก " }
|
| 77 |
+
]
|
| 78 |
+
},
|
| 79 |
+
{
|
| 80 |
+
"id": "construction-realestate",
|
| 81 |
+
"name": "๊ฑด์ค ยท ๋ถ๋์ฐ",
|
| 82 |
+
"isPrimary": true,
|
| 83 |
+
"tags": [
|
| 84 |
+
{ "tagId": "construction-engineering", "tagName": "#๊ฑด์ค/์์ง๋์ด๋ง" },
|
| 85 |
+
{ "tagId": "realestate-development", "tagName": "#๋ถ๋์ฐ๊ฐ๋ฐ" },
|
| 86 |
+
{ "tagId": "plant", "tagName": "#ํ๋ํธ" },
|
| 87 |
+
{ "tagId": "interior", "tagName": "#์ธํ
๋ฆฌ์ด" }
|
| 88 |
+
]
|
| 89 |
+
},
|
| 90 |
+
{
|
| 91 |
+
"id": "public-corp",
|
| 92 |
+
"name": "๊ณต๊ธฐ์
ยท ๊ณต๊ณต๊ธฐ๊ด",
|
| 93 |
+
"isPrimary": true,
|
| 94 |
+
"tags": [
|
| 95 |
+
{ "tagId": "public-soc", "tagName": "#SOC (๊ณตํญ,๋๋ก,์ฒ ๋)" },
|
| 96 |
+
{ "tagId": "public-energy", "tagName": "#์๋์ง ๊ณต๊ธฐ์
" },
|
| 97 |
+
{ "tagId": "public-finance", "tagName": "#๊ธ์ต ๊ณต๊ธฐ์
" },
|
| 98 |
+
{ "tagId": "public-admin", "tagName": "#์ผ๋ฐํ์ " }
|
| 99 |
+
]
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"id": "materials-parts-equipment",
|
| 103 |
+
"name": "์์ฌ ยท ๋ถํ ยท ์ฅ๋น (์๋ถ์ฅ)",
|
| 104 |
+
"isPrimary": false,
|
| 105 |
+
"tags": [
|
| 106 |
+
{ "tagId": "mpe-semiconductor", "tagName": "#๋ฐ๋์ฒด ์๋ถ์ฅ" },
|
| 107 |
+
{ "tagId": "mpe-display", "tagName": "#๋์คํ๋ ์ด ์๋ถ์ฅ" },
|
| 108 |
+
{ "tagId": "mpe-battery", "tagName": "#2์ฐจ์ ์ง ์๋ถ์ฅ" },
|
| 109 |
+
{ "tagId": "auto-parts", "tagName": "#์๋์ฐจ ๋ถํ" },
|
| 110 |
+
{ "tagId": "chemical-materials", "tagName": "#ํํ/์์ฌ" }
|
| 111 |
+
]
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
"id": "hospitality-travel-airline",
|
| 115 |
+
"name": "ํธํ
ยท ์ฌํ ยท ํญ๊ณต",
|
| 116 |
+
"isPrimary": false,
|
| 117 |
+
"tags": [
|
| 118 |
+
{ "tagId": "hotel", "tagName": "#ํธํ
" },
|
| 119 |
+
{ "tagId": "travel-agency", "tagName": "#์ฌํ์ฌ" },
|
| 120 |
+
{ "tagId": "airline", "tagName": "#ํญ๊ณต์ฌ" },
|
| 121 |
+
{ "tagId": "leisure-resort", "tagName": "#๋ ์ /๋ฆฌ์กฐํธ" }
|
| 122 |
+
]
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"id": "professional-services",
|
| 126 |
+
"name": "์ ๋ฌธ ์๋น์ค",
|
| 127 |
+
"isPrimary": false,
|
| 128 |
+
"tags": [
|
| 129 |
+
{ "tagId": "consulting", "tagName": "#์ปจ์คํ
" },
|
| 130 |
+
{ "tagId": "accounting-tax", "tagName": "#ํ๊ณ/์ธ๋ฌด" },
|
| 131 |
+
{ "tagId": "law-firm", "tagName": "#๋ฒ๋ฅ (๋กํ)" },
|
| 132 |
+
{ "tagId": "market-research", "tagName": "#๋ฆฌ์์น" }
|
| 133 |
+
]
|
| 134 |
+
},
|
| 135 |
+
{
|
| 136 |
+
"id": "transportation-logistics",
|
| 137 |
+
"name": "์ด์ก ยท ๋ฌผ๋ฅ",
|
| 138 |
+
"isPrimary": false,
|
| 139 |
+
"tags": [
|
| 140 |
+
{ "tagId": "logistics-delivery", "tagName": "#๋ฌผ๋ฅ/ํ๋ฐฐ" },
|
| 141 |
+
{ "tagId": "shipping", "tagName": "#ํด์ด" },
|
| 142 |
+
{ "tagId": "forwarding", "tagName": "#ํฌ์๋ฉ" },
|
| 143 |
+
{ "tagId": "land-transport", "tagName": "#์ก์์ด์ก" }
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"id": "education",
|
| 148 |
+
"name": "๊ต์ก",
|
| 149 |
+
"isPrimary": false,
|
| 150 |
+
"tags": [
|
| 151 |
+
{ "tagId": "edutech", "tagName": "#์๋ํ
ํฌ" },
|
| 152 |
+
{ "tagId": "private-academy", "tagName": "#์
์/๋ณด์ตํ์" },
|
| 153 |
+
{ "tagId": "edu-publishing", "tagName": "#๊ต์ก์ถํ" },
|
| 154 |
+
{ "tagId": "language-edu", "tagName": "#์ธ๊ตญ์ด๊ต์ก" }
|
| 155 |
+
]
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"id": "nonprofit-social-enterprise",
|
| 159 |
+
"name": "๋น์๋ฆฌ ยท ์ฌํ์ ๊ธฐ์
",
|
| 160 |
+
"isPrimary": false,
|
| 161 |
+
"tags": [
|
| 162 |
+
{ "tagId": "ngo-npo", "tagName": "#NGO/NPO" },
|
| 163 |
+
{ "tagId": "social-enterprise", "tagName": "#์ฌํ์ ๊ธฐ์
" },
|
| 164 |
+
{ "tagId": "foundation", "tagName": "#์ฌ๋จ" }
|
| 165 |
+
]
|
| 166 |
+
}
|
| 167 |
+
],
|
| 168 |
+
"industry_classification_eval": {
|
| 169 |
+
"task_definition": {
|
| 170 |
+
"description": "Classify the company's industry based on job title and company name. The output must be an array containing one or more relevant 'tagId's from the provided industry list.",
|
| 171 |
+
"input": {
|
| 172 |
+
"job_title": "string",
|
| 173 |
+
"company_name": "string"
|
| 174 |
+
},
|
| 175 |
+
"output": {
|
| 176 |
+
"type": "array",
|
| 177 |
+
"items": {
|
| 178 |
+
"type": "string",
|
| 179 |
+
"description": "A valid tagId from the industryCategories list."
|
| 180 |
+
}
|
| 181 |
+
}
|
| 182 |
+
},
|
| 183 |
+
"examples": [
|
| 184 |
+
{
|
| 185 |
+
"input": {
|
| 186 |
+
"job_title": "๊ฒฝ์๊ธฐํ",
|
| 187 |
+
"company_name": "์ผ์ฑ์ ์"
|
| 188 |
+
},
|
| 189 |
+
"output": ["semiconductor", "electronics-home"]
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"input": {
|
| 193 |
+
"job_title": "๊ฒฝ์๊ธฐํ",
|
| 194 |
+
"company_name": "์ ํ์ํ"
|
| 195 |
+
},
|
| 196 |
+
"output": ["bank"]
|
| 197 |
+
},
|
| 198 |
+
{
|
| 199 |
+
"input": {
|
| 200 |
+
"job_title": "์จ๋ผ์ธ๋ง์ผํ
",
|
| 201 |
+
"company_name": "์ฟ ํก"
|
| 202 |
+
},
|
| 203 |
+
"output": ["e-commerce", "platform-portal"]
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"input": {
|
| 207 |
+
"job_title": "์จ๋ผ์ธ๋ง์ผํ
",
|
| 208 |
+
"company_name": "์๋ชจ๋ ํผ์ํฝ"
|
| 209 |
+
},
|
| 210 |
+
"output": ["fashion-beauty", "fmcg-beverage"]
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"input": {
|
| 214 |
+
"job_title": "HRM(์ธ์ฌ์ด์)",
|
| 215 |
+
"company_name": "ํ๋๊ฑด์ค"
|
| 216 |
+
},
|
| 217 |
+
"output": ["construction-engineering"]
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"input": {
|
| 221 |
+
"job_title": "HRM(์ธ์ฌ์ด์)",
|
| 222 |
+
"company_name": "ํ์ด๋ธ"
|
| 223 |
+
},
|
| 224 |
+
"output": ["entertainment"]
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"input": {
|
| 228 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 229 |
+
"company_name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)"
|
| 230 |
+
},
|
| 231 |
+
"output": ["fintech", "platform-portal"]
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"input": {
|
| 235 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 236 |
+
"company_name": "๋ฅ์จ"
|
| 237 |
+
},
|
| 238 |
+
"output": ["game"]
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"input": {
|
| 242 |
+
"job_title": "ํด์ธ์์
",
|
| 243 |
+
"company_name": "์ผ์ฑ๋ฐ์ด์ค๋ก์ง์ค"
|
| 244 |
+
},
|
| 245 |
+
"output": ["bio-cmo", "pharma-new-drug"]
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"input": {
|
| 249 |
+
"job_title": "ํด์ธ์์
",
|
| 250 |
+
"company_name": "HMM (์์ด์น์ ์ )"
|
| 251 |
+
},
|
| 252 |
+
"output": ["shipping"]
|
| 253 |
+
}
|
| 254 |
+
]
|
| 255 |
+
}
|
| 256 |
+
}
|
industry-classification/llm_functions.py
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import re
|
| 4 |
+
import yaml
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
|
| 7 |
+
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
| 8 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 9 |
+
|
| 10 |
+
# ํ๋กฌํํธ ํ
ํ๋ฆฟ ๋ก๋
|
| 11 |
+
import os
|
| 12 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 13 |
+
prompt_path = os.path.join(current_dir, 'prompt.yaml')
|
| 14 |
+
with open(prompt_path, 'r', encoding='utf-8') as f:
|
| 15 |
+
prompt_data = yaml.safe_load(f)
|
| 16 |
+
prompt_template = prompt_data['prompt']
|
| 17 |
+
|
| 18 |
+
def parse_industry_tags(content):
|
| 19 |
+
"""
|
| 20 |
+
AI ์๋ต์์ ์ฐ์
ํ๊ทธ ๋ฐฐ์ด์ ํ์ฑํ๋ ํจ์
|
| 21 |
+
"""
|
| 22 |
+
try:
|
| 23 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ๊ธธ์ด: {len(content)}")
|
| 24 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ์ฒซ 200์: {repr(content[:200])}")
|
| 25 |
+
|
| 26 |
+
# ํ
์คํธ ์ ์ฒ๋ฆฌ
|
| 27 |
+
cleaned_content = content.strip()
|
| 28 |
+
|
| 29 |
+
# 1. JSON ์ฝ๋ ๋ธ๋ก ์ฐพ๊ธฐ (```json ... ``` ํ์)
|
| 30 |
+
json_patterns = [
|
| 31 |
+
r'```json\s*(\[.*?\])\s*```',
|
| 32 |
+
r'```\s*(\[.*?\])\s*```',
|
| 33 |
+
r'```json\s*(.*?)\s*```',
|
| 34 |
+
r'```\s*(.*?)\s*```'
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
for pattern in json_patterns:
|
| 38 |
+
json_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 39 |
+
if json_match:
|
| 40 |
+
json_str = json_match.group(1).strip()
|
| 41 |
+
print(f"JSON ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 42 |
+
|
| 43 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 44 |
+
json_str = re.sub(r'\n\s*', ' ', json_str)
|
| 45 |
+
json_str = re.sub(r',\s*]', ']', json_str)
|
| 46 |
+
|
| 47 |
+
try:
|
| 48 |
+
parsed_json = json.loads(json_str)
|
| 49 |
+
if isinstance(parsed_json, list):
|
| 50 |
+
return parsed_json
|
| 51 |
+
except json.JSONDecodeError as e:
|
| 52 |
+
print(f"JSON ๋ธ๋ก ํ์ฑ ์คํจ: {e}")
|
| 53 |
+
|
| 54 |
+
# 2. ๋๊ดํธ๋ก ๋๋ฌ์ธ์ธ ๋ฐฐ์ด ์ฐพ๊ธฐ
|
| 55 |
+
array_patterns = [
|
| 56 |
+
r'\[(.*?)\]'
|
| 57 |
+
]
|
| 58 |
+
|
| 59 |
+
for pattern in array_patterns:
|
| 60 |
+
array_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 61 |
+
if array_match:
|
| 62 |
+
array_content = array_match.group(1).strip()
|
| 63 |
+
print(f"๋ฐฐ์ด ๋ด์ฉ ๋ฐ๊ฒฌ: {repr(array_content[:100])}")
|
| 64 |
+
|
| 65 |
+
# ๋ฐฐ์ด ๋ด์ฉ์์ ๋ฌธ์์ด ์ถ์ถ
|
| 66 |
+
tags = []
|
| 67 |
+
# ๋ฐ์ดํ๋ก ๋๋ฌ์ธ์ธ ๋ฌธ์์ด๋ค ์ฐพ๊ธฐ
|
| 68 |
+
tag_matches = re.findall(r'"([^"]+)"', array_content)
|
| 69 |
+
for tag in tag_matches:
|
| 70 |
+
if tag.strip():
|
| 71 |
+
tags.append(tag.strip())
|
| 72 |
+
|
| 73 |
+
if tags:
|
| 74 |
+
return tags
|
| 75 |
+
|
| 76 |
+
# 3. ์ ์ฒด ํ
์คํธ๋ฅผ JSON์ผ๋ก ํ์ฑ ์๋
|
| 77 |
+
try:
|
| 78 |
+
# ์ฝ๋ ๋ธ๋ก ๋ง์ปค ์ ๊ฑฐ
|
| 79 |
+
if cleaned_content.startswith('```'):
|
| 80 |
+
lines = cleaned_content.split('\n')
|
| 81 |
+
start_idx = 1 if lines[0].startswith('```') else 0
|
| 82 |
+
end_idx = len(lines)
|
| 83 |
+
for i in range(len(lines)-1, -1, -1):
|
| 84 |
+
if lines[i].strip() == '```':
|
| 85 |
+
end_idx = i
|
| 86 |
+
break
|
| 87 |
+
cleaned_content = '\n'.join(lines[start_idx:end_idx])
|
| 88 |
+
|
| 89 |
+
cleaned_content = cleaned_content.strip()
|
| 90 |
+
parsed_json = json.loads(cleaned_content)
|
| 91 |
+
if isinstance(parsed_json, list):
|
| 92 |
+
return parsed_json
|
| 93 |
+
except json.JSONDecodeError as e:
|
| 94 |
+
print(f"์ ์ฒด JSON ํ์ฑ ์คํจ: {e}")
|
| 95 |
+
|
| 96 |
+
# 4. ์ตํ์ ์๋จ: ํจํด ๋งค์นญ์ผ๋ก ํ๊ทธ ์ถ์ถ
|
| 97 |
+
print("ํจํด ๋งค์นญ์ผ๋ก ํ๊ทธ ์ถ์ถ ์๋")
|
| 98 |
+
tags = []
|
| 99 |
+
|
| 100 |
+
# ๋ค์ํ ํจํด์ผ๋ก ํ๊ทธ ์ฐพ๊ธฐ
|
| 101 |
+
patterns = [
|
| 102 |
+
r'"([a-z-]+)"', # ๋ฐ์ดํ ์์ ํ๊ทธ ํํ
|
| 103 |
+
r'([a-z-]+)', # ๋จ์ ํ๊ทธ ํํ
|
| 104 |
+
]
|
| 105 |
+
|
| 106 |
+
for pattern in patterns:
|
| 107 |
+
matches = re.findall(pattern, cleaned_content)
|
| 108 |
+
for match in matches:
|
| 109 |
+
tag = match.strip()
|
| 110 |
+
if len(tag) > 2 and '-' in tag and tag not in tags:
|
| 111 |
+
tags.append(tag)
|
| 112 |
+
if len(tags) >= 5: # ์ต๋ 5๊ฐ
|
| 113 |
+
break
|
| 114 |
+
if tags:
|
| 115 |
+
break
|
| 116 |
+
|
| 117 |
+
return tags[:5] if tags else []
|
| 118 |
+
|
| 119 |
+
except Exception as e:
|
| 120 |
+
print(f"ํ๊ทธ ํ์ฑ ์ ์ฒด ์ค๋ฅ: {e}")
|
| 121 |
+
print(f"ํ์ฑ ์คํจํ ์ปจํ
์ธ : {repr(content)}")
|
| 122 |
+
return []
|
| 123 |
+
|
| 124 |
+
def classify_industry(job_title, company_name):
|
| 125 |
+
"""
|
| 126 |
+
OpenAI API๋ฅผ ์ฌ์ฉํ์ฌ ๊ธฐ์
์ ์ฐ์
์ ๋ถ๋ฅํ๋ ํจ์
|
| 127 |
+
"""
|
| 128 |
+
try:
|
| 129 |
+
if not job_title or not company_name:
|
| 130 |
+
return "์ง๋ฌด์ ํ์ฌ๋ช
์ ๋ชจ๋ ์
๋ ฅํด์ฃผ์ธ์.", []
|
| 131 |
+
|
| 132 |
+
# ํ๋กฌํํธ ์์ฑ
|
| 133 |
+
prompt = prompt_template.format(
|
| 134 |
+
job_title=job_title,
|
| 135 |
+
company_name=company_name
|
| 136 |
+
)
|
| 137 |
+
|
| 138 |
+
# OpenAI Responses API ํธ์ถ (Web Search Preview ์ฌ๏ฟฝ๏ฟฝ๏ฟฝ)
|
| 139 |
+
response = client.responses.create(
|
| 140 |
+
model="gpt-4o",
|
| 141 |
+
tools=[{
|
| 142 |
+
"type": "web_search_preview",
|
| 143 |
+
"search_context_size": "high",
|
| 144 |
+
}],
|
| 145 |
+
input=f"๋น์ ์ ๊ธฐ์
์ฐ์
๋ถ๋ฅ ์ ๋ฌธ๊ฐ์
๋๋ค. ์น ๊ฒ์์ ํตํด ์ต์ ์ ๋ณด๋ฅผ ํ์ธํ๊ณ ์ ํํ ์ฐ์
ํ๊ทธ๋ฅผ JSON ๋ฐฐ์ด ํ์์ผ๋ก ๋ฐํํด์ฃผ์ธ์.\n\n{prompt}"
|
| 146 |
+
)
|
| 147 |
+
|
| 148 |
+
content = response.output_text
|
| 149 |
+
print(f"=== AI ์๋ต ์๋ณธ ===")
|
| 150 |
+
print(content)
|
| 151 |
+
print(f"=== ์ ์ฒด ์๋ต ๊ฐ์ฒด ===")
|
| 152 |
+
print(response)
|
| 153 |
+
|
| 154 |
+
# ์น ๊ฒ์ ์ฐธ๊ณ ๋งํฌ ์ถ๋ ฅ
|
| 155 |
+
if hasattr(response, 'web_search_results') and response.web_search_results:
|
| 156 |
+
print(f"=== ์ฐธ๊ณ ํ ์น ๊ฒ์ ๋งํฌ ===")
|
| 157 |
+
for i, result in enumerate(response.web_search_results, 1):
|
| 158 |
+
if hasattr(result, 'url'):
|
| 159 |
+
print(f"{i}. {result.url}")
|
| 160 |
+
elif hasattr(result, 'link'):
|
| 161 |
+
print(f"{i}. {result.link}")
|
| 162 |
+
|
| 163 |
+
print(f"=== AI ์๋ต ๋ ===")
|
| 164 |
+
|
| 165 |
+
tags = parse_industry_tags(content)
|
| 166 |
+
|
| 167 |
+
if not tags:
|
| 168 |
+
return "์ฐ์
๋ถ๋ฅ์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.", []
|
| 169 |
+
|
| 170 |
+
# ํ๊ทธ๋ช
๋งคํ (ํ์์ฉ)
|
| 171 |
+
tag_mapping = {
|
| 172 |
+
"platform-portal": "ํ๋ซํผ/ํฌํธ",
|
| 173 |
+
"e-commerce": "์ด์ปค๋จธ์ค",
|
| 174 |
+
"game": "๊ฒ์",
|
| 175 |
+
"it-solution-si": "IT์๋ฃจ์
/SI",
|
| 176 |
+
"o2o-vertical": "O2O/๋ฒํฐ์ปฌ",
|
| 177 |
+
"ai-data": "AI/๋ฐ์ดํฐ",
|
| 178 |
+
"cloud-saas": "ํด๋ผ์ฐ๋/SaaS",
|
| 179 |
+
"fintech": "ํํ
ํฌ",
|
| 180 |
+
"semiconductor": "๋ฐ๋์ฒด",
|
| 181 |
+
"electronics-home": "๊ฐ์ /์ ์์ ํ",
|
| 182 |
+
"automotive-mobility": "์๋์ฐจ/๋ชจ๋น๋ฆฌํฐ",
|
| 183 |
+
"battery": "2์ฐจ์ ์ง",
|
| 184 |
+
"display": "๋์คํ๋ ์ด",
|
| 185 |
+
"heavy-industry-shipbuilding": "์ค๊ณต์
/์กฐ์ ",
|
| 186 |
+
"steel-metal": "์ฒ ๊ฐ/๊ธ์",
|
| 187 |
+
"bank": "์ํ",
|
| 188 |
+
"securities": "์ฆ๊ถ",
|
| 189 |
+
"insurance": "๋ณดํ",
|
| 190 |
+
"card": "์นด๋",
|
| 191 |
+
"asset-management": "์์ฐ์ด์ฉ",
|
| 192 |
+
"dept-store-mart": "๋ฐฑํ์ /๋งํธ",
|
| 193 |
+
"convenience-store": "ํธ์์ ",
|
| 194 |
+
"fmcg-beverage": "FMCG/์์๋ฃ",
|
| 195 |
+
"fashion-beauty": "ํจ์
/๋ทฐํฐ",
|
| 196 |
+
"duty-free": "๋ฉด์ธ์ ",
|
| 197 |
+
"pharma-new-drug": "์ ์ฝ/์ ์ฝ๊ฐ๋ฐ",
|
| 198 |
+
"bio-cmo": "๋ฐ์ด์ค/CMO",
|
| 199 |
+
"medical-device": "์๋ฃ๊ธฐ๊ธฐ",
|
| 200 |
+
"digital-healthcare": "๋์งํธํฌ์ค์ผ์ด",
|
| 201 |
+
"entertainment": "์ํฐํ
์ธ๋จผํธ",
|
| 202 |
+
"contents-video": "์ฝํ
์ธ /์์์ ์",
|
| 203 |
+
"ad-agency": "๊ด๊ณ ๋ํ์ฌ",
|
| 204 |
+
"webtoon-webnovel": "์นํฐ/์น์์ค",
|
| 205 |
+
"broadcasting-press": "๋ฐฉ์ก/์ธ๋ก ",
|
| 206 |
+
"construction-engineering": "๊ฑด์ค/์์ง๋์ด๋ง",
|
| 207 |
+
"realestate-development": "๋ถ๋์ฐ๊ฐ๋ฐ",
|
| 208 |
+
"plant": "ํ๋ํธ",
|
| 209 |
+
"interior": "์ธํ
๋ฆฌ์ด",
|
| 210 |
+
"public-soc": "SOC (๊ณตํญ,๋๋ก,์ฒ ๋)",
|
| 211 |
+
"public-energy": "์๋์ง ๊ณต๊ธฐ์
",
|
| 212 |
+
"public-finance": "๊ธ์ต ๊ณต๊ธฐ์
",
|
| 213 |
+
"public-admin": "์ผ๋ฐํ์ ",
|
| 214 |
+
"mpe-semiconductor": "๋ฐ๋์ฒด ์๋ถ์ฅ",
|
| 215 |
+
"mpe-display": "๋์คํ๋ ์ด ์๋ถ์ฅ",
|
| 216 |
+
"mpe-battery": "2์ฐจ์ ์ง ์๋ถ์ฅ",
|
| 217 |
+
"auto-parts": "์๋์ฐจ ๋ถํ",
|
| 218 |
+
"chemical-materials": "ํํ/์์ฌ",
|
| 219 |
+
"hotel": "ํธํ
",
|
| 220 |
+
"travel-agency": "์ฌํ์ฌ",
|
| 221 |
+
"airline": "ํญ๊ณต์ฌ",
|
| 222 |
+
"leisure-resort": "๋ ์ /๋ฆฌ์กฐํธ",
|
| 223 |
+
"consulting": "์ปจ์คํ
",
|
| 224 |
+
"accounting-tax": "ํ๊ณ/์ธ๋ฌด",
|
| 225 |
+
"law-firm": "๋ฒ๋ฅ (๋กํ)",
|
| 226 |
+
"market-research": "๋ฆฌ์์น",
|
| 227 |
+
"logistics-delivery": "๋ฌผ๋ฅ/ํ๋ฐฐ",
|
| 228 |
+
"shipping": "ํด์ด",
|
| 229 |
+
"forwarding": "ํฌ์๋ฉ",
|
| 230 |
+
"land-transport": "์ก์์ด์ก",
|
| 231 |
+
"edutech": "์๋ํ
ํฌ",
|
| 232 |
+
"private-academy": "์
์/๋ณด์ตํ์",
|
| 233 |
+
"edu-publishing": "๊ต์ก์ถํ",
|
| 234 |
+
"language-edu": "์ธ๊ตญ์ด๊ต์ก",
|
| 235 |
+
"ngo-npo": "NGO/NPO",
|
| 236 |
+
"social-enterprise": "์ฌํ์ ๊ธฐ์
",
|
| 237 |
+
"foundation": "์ฌ๋จ"
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
# ๊ฒฐ๊ณผ ํฌ๋งทํ
|
| 241 |
+
result = f"""## ๐ข {company_name} - {job_title} ์ฐ์
๋ถ๋ฅ ๊ฒฐ๊ณผ
|
| 242 |
+
|
| 243 |
+
### ๐ท๏ธ **๋ถ๋ฅ๋ ์ฐ์
ํ๊ทธ**
|
| 244 |
+
|
| 245 |
+
"""
|
| 246 |
+
for i, tag in enumerate(tags, 1):
|
| 247 |
+
tag_name = tag_mapping.get(tag, tag)
|
| 248 |
+
result += f"**{i}.** #{tag_name} (`{tag}`)\n\n"
|
| 249 |
+
|
| 250 |
+
result += f"""
|
| 251 |
+
---
|
| 252 |
+
**๐ ์
๋ ฅ ์ ๋ณด:**
|
| 253 |
+
- ํ์ฌ: {company_name}
|
| 254 |
+
- ์ง๋ฌด: {job_title}
|
| 255 |
+
- ๋ถ๋ฅ๋ ํ๊ทธ ์: {len(tags)}๊ฐ
|
| 256 |
+
|
| 257 |
+
*๋ณธ ๋ถ๋ฅ๋ AI๊ฐ ์ํํ ๊ฒ์ผ๋ก, ์ค์ ์ ๋ค๋ฅผ ์ ์์ต๋๋ค.*
|
| 258 |
+
"""
|
| 259 |
+
|
| 260 |
+
return result, tags
|
| 261 |
+
|
| 262 |
+
except Exception as e:
|
| 263 |
+
error_msg = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 264 |
+
|
| 265 |
+
์ฐ์
๋ถ๋ฅ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 266 |
+
|
| 267 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 268 |
+
|
| 269 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 270 |
+
"""
|
| 271 |
+
return error_msg, []
|
industry-classification/main.py
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from llm_functions import classify_industry
|
| 3 |
+
|
| 4 |
+
# ์์ ๋ฐ์ดํฐ
|
| 5 |
+
example_companies = ["์ผ์ฑ์ ์", "์ ํ์ํ", "์ฟ ํก", "์๋ชจ๋ ํผ์ํฝ", "ํ๋๊ฑด์ค", "ํ์ด๋ธ", "ํ ์ค", "๋ฅ์จ", "์ผ์ฑ๋ฐ์ด์ค๋ก์ง์ค", "HMM"]
|
| 6 |
+
example_jobs = ["๊ฒฝ์๊ธฐํ", "์จ๋ผ์ธ๋ง์ผํ
", "HRM(์ธ์ฌ์ด์)", "๋ฐฑ์๋ ๊ฐ๋ฐ", "ํด์ธ์์
", "๋ฐ์ดํฐ ๋ถ์", "์์
", "๋ง์ผํ
", "๊ธฐํ", "๊ฐ๋ฐ"]
|
| 7 |
+
|
| 8 |
+
def create_tag_cards(tags):
|
| 9 |
+
"""
|
| 10 |
+
๋ถ๋ฅ๋ ํ๊ทธ๋ค์ ์นด๋ ํํ๋ก ํ์ํ๋ HTML ์์ฑ
|
| 11 |
+
"""
|
| 12 |
+
if not tags:
|
| 13 |
+
return "<div style='text-align: center; color: #6B7280; padding: 20px;'>๋ถ๋ฅ๋ฅผ ์คํํด์ฃผ์ธ์</div>"
|
| 14 |
+
|
| 15 |
+
# ํ๊ทธ๋ช
๋งคํ
|
| 16 |
+
tag_mapping = {
|
| 17 |
+
"platform-portal": "ํ๋ซํผ/ํฌํธ",
|
| 18 |
+
"e-commerce": "์ด์ปค๋จธ์ค",
|
| 19 |
+
"game": "๊ฒ์",
|
| 20 |
+
"it-solution-si": "IT์๋ฃจ์
/SI",
|
| 21 |
+
"o2o-vertical": "O2O/๋ฒํฐ์ปฌ",
|
| 22 |
+
"ai-data": "AI/๋ฐ์ดํฐ",
|
| 23 |
+
"cloud-saas": "ํด๋ผ์ฐ๋/SaaS",
|
| 24 |
+
"fintech": "ํํ
ํฌ",
|
| 25 |
+
"semiconductor": "๋ฐ๋์ฒด",
|
| 26 |
+
"electronics-home": "๊ฐ์ /์ ์์ ํ",
|
| 27 |
+
"automotive-mobility": "์๋์ฐจ/๋ชจ๋น๋ฆฌํฐ",
|
| 28 |
+
"battery": "2์ฐจ์ ์ง",
|
| 29 |
+
"display": "๋์คํ๋ ์ด",
|
| 30 |
+
"heavy-industry-shipbuilding": "์ค๊ณต์
/์กฐ์ ",
|
| 31 |
+
"steel-metal": "์ฒ ๊ฐ/๊ธ์",
|
| 32 |
+
"bank": "์ํ",
|
| 33 |
+
"securities": "์ฆ๊ถ",
|
| 34 |
+
"insurance": "๋ณดํ",
|
| 35 |
+
"card": "์นด๋",
|
| 36 |
+
"asset-management": "์์ฐ์ด์ฉ",
|
| 37 |
+
"dept-store-mart": "๋ฐฑํ์ /๋งํธ",
|
| 38 |
+
"convenience-store": "ํธ์์ ",
|
| 39 |
+
"fmcg-beverage": "FMCG/์์๋ฃ",
|
| 40 |
+
"fashion-beauty": "ํจ์
/๋ทฐํฐ",
|
| 41 |
+
"duty-free": "๋ฉด์ธ์ ",
|
| 42 |
+
"pharma-new-drug": "์ ์ฝ/์ ์ฝ๊ฐ๋ฐ",
|
| 43 |
+
"bio-cmo": "๋ฐ์ด์ค/CMO",
|
| 44 |
+
"medical-device": "์๋ฃ๊ธฐ๊ธฐ",
|
| 45 |
+
"digital-healthcare": "๋์งํธํฌ์ค์ผ์ด",
|
| 46 |
+
"entertainment": "์ํฐํ
์ธ๋จผํธ",
|
| 47 |
+
"contents-video": "์ฝํ
์ธ /์์์ ์",
|
| 48 |
+
"ad-agency": "๊ด๊ณ ๋ํ์ฌ",
|
| 49 |
+
"webtoon-webnovel": "์นํฐ/์น์์ค",
|
| 50 |
+
"broadcasting-press": "๋ฐฉ์ก/์ธ๋ก ",
|
| 51 |
+
"construction-engineering": "๊ฑด์ค/์์ง๋์ด๋ง",
|
| 52 |
+
"realestate-development": "๋ถ๋์ฐ๊ฐ๋ฐ",
|
| 53 |
+
"plant": "ํ๋ํธ",
|
| 54 |
+
"interior": "์ธํ
๋ฆฌ์ด",
|
| 55 |
+
"public-soc": "SOC (๊ณตํญ,๋๋ก,์ฒ ๋)",
|
| 56 |
+
"public-energy": "์๋์ง ๊ณต๊ธฐ์
",
|
| 57 |
+
"public-finance": "๊ธ์ต ๊ณต๊ธฐ์
",
|
| 58 |
+
"public-admin": "์ผ๋ฐํ์ ",
|
| 59 |
+
"mpe-semiconductor": "๋ฐ๋์ฒด ์๋ถ์ฅ",
|
| 60 |
+
"mpe-display": "๋์คํ๋ ์ด ์๋ถ์ฅ",
|
| 61 |
+
"mpe-battery": "2์ฐจ์ ์ง ์๋ถ์ฅ",
|
| 62 |
+
"auto-parts": "์๋์ฐจ ๋ถํ",
|
| 63 |
+
"chemical-materials": "ํํ/์์ฌ",
|
| 64 |
+
"hotel": "ํธํ
",
|
| 65 |
+
"travel-agency": "์ฌํ์ฌ",
|
| 66 |
+
"airline": "ํญ๊ณต์ฌ",
|
| 67 |
+
"leisure-resort": "๋ ์ /๋ฆฌ์กฐํธ",
|
| 68 |
+
"consulting": "์ปจ์คํ
",
|
| 69 |
+
"accounting-tax": "ํ๊ณ/์ธ๋ฌด",
|
| 70 |
+
"law-firm": "๋ฒ๋ฅ (๋กํ)",
|
| 71 |
+
"market-research": "๋ฆฌ์์น",
|
| 72 |
+
"logistics-delivery": "๋ฌผ๋ฅ/ํ๋ฐฐ",
|
| 73 |
+
"shipping": "ํด์ด",
|
| 74 |
+
"forwarding": "ํฌ์๋ฉ",
|
| 75 |
+
"land-transport": "์ก์์ด์ก",
|
| 76 |
+
"edutech": "์๋ํ
ํฌ",
|
| 77 |
+
"private-academy": "์
์/๋ณด์ตํ์",
|
| 78 |
+
"edu-publishing": "๊ต์ก์ถํ",
|
| 79 |
+
"language-edu": "์ธ๊ตญ์ด๊ต์ก",
|
| 80 |
+
"ngo-npo": "NGO/NPO",
|
| 81 |
+
"social-enterprise": "์ฌํ์ ๊ธฐ์
",
|
| 82 |
+
"foundation": "์ฌ๋จ"
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
cards_html = "<div style='display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;'>"
|
| 86 |
+
|
| 87 |
+
colors = ["#EBF8FF", "#ECFDF5", "#FEF2F2", "#F5F3FF", "#FFF7ED", "#F0FDFA", "#FDF2F8"]
|
| 88 |
+
border_colors = ["#1E40AF", "#059669", "#DC2626", "#7C3AED", "#EA580C", "#0F766E", "#BE185D"]
|
| 89 |
+
|
| 90 |
+
for i, tag in enumerate(tags):
|
| 91 |
+
color = colors[i % len(colors)]
|
| 92 |
+
border_color = border_colors[i % len(border_colors)]
|
| 93 |
+
tag_name = tag_mapping.get(tag, tag)
|
| 94 |
+
|
| 95 |
+
cards_html += f"""
|
| 96 |
+
<div style="
|
| 97 |
+
background-color: {color};
|
| 98 |
+
border: 2px solid {border_color};
|
| 99 |
+
border-radius: 12px;
|
| 100 |
+
padding: 15px;
|
| 101 |
+
margin: 5px;
|
| 102 |
+
min-width: 150px;
|
| 103 |
+
text-align: center;
|
| 104 |
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
| 105 |
+
">
|
| 106 |
+
<div style="
|
| 107 |
+
font-weight: bold;
|
| 108 |
+
color: {border_color};
|
| 109 |
+
font-size: 14px;
|
| 110 |
+
margin-bottom: 5px;
|
| 111 |
+
">#{tag_name}</div>
|
| 112 |
+
<div style="
|
| 113 |
+
color: #6B7280;
|
| 114 |
+
font-size: 12px;
|
| 115 |
+
font-family: monospace;
|
| 116 |
+
">{tag}</div>
|
| 117 |
+
</div>
|
| 118 |
+
"""
|
| 119 |
+
|
| 120 |
+
cards_html += "</div>"
|
| 121 |
+
return cards_html
|
| 122 |
+
|
| 123 |
+
def process_classification(job_title, company_name):
|
| 124 |
+
"""
|
| 125 |
+
๋ถ๋ฅ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๊ณ UI์ ํ์ํ ํํ๋ก ๋ณํํ๋ ํจ์
|
| 126 |
+
"""
|
| 127 |
+
try:
|
| 128 |
+
content, tags = classify_industry(job_title, company_name)
|
| 129 |
+
tag_cards = create_tag_cards(tags)
|
| 130 |
+
return content, tag_cards
|
| 131 |
+
except Exception as e:
|
| 132 |
+
error_content = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 133 |
+
|
| 134 |
+
์ฐ์
๋ถ๋ฅ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 135 |
+
|
| 136 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 137 |
+
|
| 138 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 139 |
+
"""
|
| 140 |
+
error_cards = create_tag_cards([])
|
| 141 |
+
return error_content, error_cards
|
| 142 |
+
|
| 143 |
+
def create_interface():
|
| 144 |
+
"""
|
| 145 |
+
Gradio ์ธํฐํ์ด์ค ์์ฑ
|
| 146 |
+
"""
|
| 147 |
+
with gr.Blocks(
|
| 148 |
+
title="๐ท๏ธ AI ์ฐ์
๋ถ๋ฅ๊ธฐ",
|
| 149 |
+
theme=gr.themes.Soft(),
|
| 150 |
+
css="""
|
| 151 |
+
.main-header {
|
| 152 |
+
text-align: center;
|
| 153 |
+
padding: 20px;
|
| 154 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 155 |
+
color: white;
|
| 156 |
+
border-radius: 10px;
|
| 157 |
+
margin-bottom: 20px;
|
| 158 |
+
}
|
| 159 |
+
.input-section {
|
| 160 |
+
background-color: #f8f9fa;
|
| 161 |
+
padding: 20px;
|
| 162 |
+
border-radius: 8px;
|
| 163 |
+
margin: 10px 0;
|
| 164 |
+
}
|
| 165 |
+
.example-section {
|
| 166 |
+
background-color: #f0f9ff;
|
| 167 |
+
padding: 15px;
|
| 168 |
+
border-radius: 8px;
|
| 169 |
+
margin: 10px 0;
|
| 170 |
+
}
|
| 171 |
+
"""
|
| 172 |
+
) as demo:
|
| 173 |
+
|
| 174 |
+
# ํค๋
|
| 175 |
+
gr.HTML("""
|
| 176 |
+
<div class="main-header">
|
| 177 |
+
<h1>๐ท๏ธ AI ์ฐ์
๋ถ๋ฅ๊ธฐ</h1>
|
| 178 |
+
<p>์ง๋ฌด์ ํ์ฌ๋ช
์ ๋ฐํ์ผ๋ก ์ ํํ ์ฐ์
๋ถ์ผ๋ฅผ ๋ถ๋ฅํฉ๋๋ค</p>
|
| 179 |
+
</div>
|
| 180 |
+
""")
|
| 181 |
+
|
| 182 |
+
# ์ค๋ช
|
| 183 |
+
gr.Markdown("""
|
| 184 |
+
### ๐ **์ฌ์ฉ ๋ฐฉ๋ฒ**
|
| 185 |
+
1. **์ง๋ฌด**: ๋ถ๋ฅํ๊ณ ์ถ์ ์ง๋ฌด๋ฅผ ์
๋ ฅํ์ธ์
|
| 186 |
+
2. **ํ์ฌ๋ช
**: ํด๋น ํ์ฌ๋ช
์ ์
๋ ฅํ์ธ์
|
| 187 |
+
3. **๋ถ๋ฅ**: '์ฐ์
๋ถ๋ฅ' ๋ฒํผ์ ํด๋ฆญํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ์ธ์
|
| 188 |
+
|
| 189 |
+
โจ **ํน์ง**: ํ์ฌ์ ์ฌ์
์์ญ๊ณผ ์ง๋ฌด ํน์ฑ์ ์ข
ํฉ์ ์ผ๋ก ๊ณ ๋ คํ์ฌ ์ ํํ ์ฐ์
ํ๊ทธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
|
| 190 |
+
""")
|
| 191 |
+
|
| 192 |
+
with gr.Row():
|
| 193 |
+
with gr.Column(scale=2):
|
| 194 |
+
# ์
๋ ฅ ์น์
|
| 195 |
+
gr.HTML('<div class="input-section">')
|
| 196 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 197 |
+
|
| 198 |
+
with gr.Row():
|
| 199 |
+
job_input = gr.Textbox(
|
| 200 |
+
label="๐ผ ์ง๋ฌด",
|
| 201 |
+
placeholder="์: ๊ฒฝ์๊ธฐํ, ๋ฐฑ์๋ ๊ฐ๋ฐ, ์จ๋ผ์ธ๋ง์ผํ
๋ฑ",
|
| 202 |
+
value="",
|
| 203 |
+
scale=1
|
| 204 |
+
)
|
| 205 |
+
|
| 206 |
+
company_input = gr.Textbox(
|
| 207 |
+
label="๐ข ํ์ฌ๋ช
",
|
| 208 |
+
placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ",
|
| 209 |
+
value="",
|
| 210 |
+
scale=1
|
| 211 |
+
)
|
| 212 |
+
|
| 213 |
+
classify_btn = gr.Button(
|
| 214 |
+
"๐ท๏ธ ์ฐ์
๋ถ๋ฅ",
|
| 215 |
+
variant="primary",
|
| 216 |
+
size="lg"
|
| 217 |
+
)
|
| 218 |
+
gr.HTML('</div>')
|
| 219 |
+
|
| 220 |
+
with gr.Column(scale=1):
|
| 221 |
+
# ์์ ๋ฐ ๊ฐ์ด๋
|
| 222 |
+
gr.HTML('<div class="example-section">')
|
| 223 |
+
gr.Markdown("### ๐ก **์์ ํ์ฌ**")
|
| 224 |
+
|
| 225 |
+
company_rows = [example_companies[i:i+2] for i in range(0, len(example_companies), 2)]
|
| 226 |
+
for row in company_rows:
|
| 227 |
+
with gr.Row():
|
| 228 |
+
for company in row:
|
| 229 |
+
example_btn = gr.Button(
|
| 230 |
+
company,
|
| 231 |
+
size="sm",
|
| 232 |
+
variant="secondary",
|
| 233 |
+
scale=1
|
| 234 |
+
)
|
| 235 |
+
example_btn.click(
|
| 236 |
+
fn=lambda x=company: x,
|
| 237 |
+
outputs=company_input
|
| 238 |
+
)
|
| 239 |
+
|
| 240 |
+
gr.Markdown("### ๐ผ **์์ ์ง๋ฌด**")
|
| 241 |
+
|
| 242 |
+
job_rows = [example_jobs[i:i+2] for i in range(0, len(example_jobs), 2)]
|
| 243 |
+
for row in job_rows:
|
| 244 |
+
with gr.Row():
|
| 245 |
+
for job in row:
|
| 246 |
+
job_btn = gr.Button(
|
| 247 |
+
job,
|
| 248 |
+
size="sm",
|
| 249 |
+
variant="secondary",
|
| 250 |
+
scale=1
|
| 251 |
+
)
|
| 252 |
+
job_btn.click(
|
| 253 |
+
fn=lambda x=job: x,
|
| 254 |
+
outputs=job_input
|
| 255 |
+
)
|
| 256 |
+
gr.HTML('</div>')
|
| 257 |
+
|
| 258 |
+
# ๊ฒฐ๊ณผ ์ถ๋ ฅ ์น์
|
| 259 |
+
with gr.Row():
|
| 260 |
+
with gr.Column(scale=2):
|
| 261 |
+
gr.Markdown("### ๐ **๋ถ๋ฅ ๊ฒฐ๊ณผ**")
|
| 262 |
+
result_output = gr.Markdown(
|
| 263 |
+
value="์ง๋ฌด์ ํ์ฌ๋ช
์ ์
๋ ฅํ๊ณ '์ฐ์
๋ถ๋ฅ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.",
|
| 264 |
+
elem_classes=["result-output"]
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
+
with gr.Column(scale=1):
|
| 268 |
+
gr.Markdown("### ๐ท๏ธ **์ฐ์
ํ๊ทธ**")
|
| 269 |
+
tag_cards = gr.HTML(
|
| 270 |
+
value="<div style='text-align: center; color: #6B7280; padding: 20px;'>๋ถ๋ฅ๋ฅผ ์คํํด์ฃผ์ธ์</div>",
|
| 271 |
+
elem_classes=["tag-cards"]
|
| 272 |
+
)
|
| 273 |
+
|
| 274 |
+
# ๋ถ๋ฅ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
| 275 |
+
classify_btn.click(
|
| 276 |
+
fn=process_classification,
|
| 277 |
+
inputs=[job_input, company_input],
|
| 278 |
+
outputs=[result_output, tag_cards],
|
| 279 |
+
api_name="classify_industry"
|
| 280 |
+
)
|
| 281 |
+
|
| 282 |
+
# ํธํฐ
|
| 283 |
+
gr.Markdown("""
|
| 284 |
+
---
|
| 285 |
+
**๐ก ๋ถ๋ฅ ๊ธฐ์ค**:
|
| 286 |
+
- **ITยทํ๋ซํผยท๊ฒ์**: ํ๋ซํผ, ์ด์ปค๋จธ์ค, ๊ฒ์, IT์๋ฃจ์
, ํํ
ํฌ ๋ฑ
|
| 287 |
+
- **์ ์กฐยทํ๋์จ์ด**: ๋ฐ๋์ฒด, ๊ฐ์ , ์๋์ฐจ, 2์ฐจ์ ์ง, ๋์คํ๋ ์ด ๋ฑ
|
| 288 |
+
- **๊ธ์ต**: ์ํ, ์ฆ๊ถ, ๋ณดํ, ์นด๋, ์์ฐ์ด์ฉ ๋ฑ
|
| 289 |
+
- **์ ํตยท์๋น์ฌ**: ๋ฐฑํ์ , ํธ์์ , FMCG, ํจ์
๋ทฐํฐ ๋ฑ
|
| 290 |
+
- **๊ธฐํ**: ๋ฐ์ด์ค์ ์ฝ, ๋ฏธ๋์ด์ฝํ
์ธ , ๊ฑด์ค๋ถ๋์ฐ, ๊ณต๊ธฐ์
๋ฑ
|
| 291 |
+
|
| 292 |
+
๐ค **Powered by**: OpenAI GPT-4o-mini with Web Search
|
| 293 |
+
""")
|
| 294 |
+
|
| 295 |
+
return demo
|
| 296 |
+
|
| 297 |
+
if __name__ == "__main__":
|
| 298 |
+
# Gradio ์ฑ ์คํ
|
| 299 |
+
demo = create_interface()
|
| 300 |
+
demo.launch(
|
| 301 |
+
server_name="0.0.0.0",
|
| 302 |
+
# server_port=7862,
|
| 303 |
+
share=True,
|
| 304 |
+
show_error=True
|
| 305 |
+
)
|
industry-classification/prompt.yaml
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
prompt: |
|
| 2 |
+
๋น์ ์ ๊ธฐ์
์ ์ฐ์
๋ถ๋ฅ๋ฅผ ์ ๋ฌธ์ ์ผ๋ก ์ํํ๋ AI ์ปจ์คํดํธ์
๋๋ค.
|
| 3 |
+
์ฃผ์ด์ง ์ง๋ฌด์ ํ์ฌ๋ช
์ ๋ฐํ์ผ๋ก ํด๋น ๊ธฐ์
์ด ์ํ๋ ์ฐ์
๋ถ์ผ๋ฅผ ์ ํํ๊ฒ ๋ถ๋ฅํด์ผ ํฉ๋๋ค.
|
| 4 |
+
|
| 5 |
+
### ์ง์นจ
|
| 6 |
+
1. **์น ๊ฒ์ ํ์ฉ**: ํ์ฌ๋ช
์ ๊ฒ์ํ์ฌ ์ต์ ์ฌ์
์์ญ๊ณผ ์ฃผ๋ ฅ ๋ถ์ผ๋ฅผ ํ์ธํฉ๋๋ค.
|
| 7 |
+
2. **์ ํํ ๋ถ๋ฅ**: ๊ฒ์ ๊ฒฐ๊ณผ์ ์ง๋ฌด๋ฅผ ์ข
ํฉ์ ์ผ๋ก ๊ณ ๋ คํ์ฌ ๊ฐ์ฅ ์ ํฉํ ์ฐ์
ํ๊ทธ๋ฅผ ์ ํํฉ๋๋ค.
|
| 8 |
+
3. **๋ค์ค ๋ถ๋ฅ ๊ฐ๋ฅ**: ํ๋์ ๊ธฐ์
์ด ์ฌ๋ฌ ์ฐ์
๋ถ์ผ์ ๊ฑธ์ณ ์์ ์ ์์ผ๋ฏ๋ก, ๊ด๋ จ๋ ๋ชจ๋ ํ๊ทธ๋ฅผ ํฌํจํ ์ ์์ต๋๋ค.
|
| 9 |
+
4. **ํ๊ทธ ID ์ฌ์ฉ**: ๋ฐ๋์ ์ ๊ณต๋ ํ๊ทธ ๋ชฉ๋ก์์ ์ ํํ tagId๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
|
| 10 |
+
|
| 11 |
+
### ์
๋ ฅ ์ ๋ณด
|
| 12 |
+
- **์ง๋ฌด:** {job_title}
|
| 13 |
+
- **ํ์ฌ๋ช
:** {company_name}
|
| 14 |
+
|
| 15 |
+
### ์ฌ์ฉ ๊ฐ๋ฅํ ์ฐ์
ํ๊ทธ ๋ชฉ๋ก
|
| 16 |
+
|
| 17 |
+
**IT ยท ํ๋ซํผ ยท ๊ฒ์**
|
| 18 |
+
- platform-portal: #ํ๋ซํผ/ํฌํธ
|
| 19 |
+
- e-commerce: #์ด์ปค๋จธ์ค
|
| 20 |
+
- game: #๊ฒ์
|
| 21 |
+
- it-solution-si: #IT์๋ฃจ์
/SI
|
| 22 |
+
- o2o-vertical: #O2O/๋ฒํฐ์ปฌ
|
| 23 |
+
- ai-data: #AI/๋ฐ์ดํฐ
|
| 24 |
+
- cloud-saas: #ํด๋ผ์ฐ๋/SaaS
|
| 25 |
+
- fintech: #ํํ
ํฌ
|
| 26 |
+
|
| 27 |
+
**์ ์กฐ ยท ํ๋์จ์ด**
|
| 28 |
+
- semiconductor: #๋ฐ๋์ฒด
|
| 29 |
+
- electronics-home: #๊ฐ์ /์ ์์ ํ
|
| 30 |
+
- automotive-mobility: #์๋์ฐจ/๋ชจ๋น๋ฆฌํฐ
|
| 31 |
+
- battery: #2์ฐจ์ ์ง
|
| 32 |
+
- display: #๋์คํ๋ ์ด
|
| 33 |
+
- heavy-industry-shipbuilding: #์ค๊ณต์
/์กฐ์
|
| 34 |
+
- steel-metal: #์ฒ ๊ฐ/๊ธ์
|
| 35 |
+
|
| 36 |
+
**๊ธ์ต**
|
| 37 |
+
- bank: #์ํ
|
| 38 |
+
- securities: #์ฆ๊ถ
|
| 39 |
+
- insurance: #๋ณดํ
|
| 40 |
+
- card: #์นด๋
|
| 41 |
+
- asset-management: #์์ฐ์ด์ฉ
|
| 42 |
+
|
| 43 |
+
**์ ํต ยท ์๋น์ฌ ยท ์ํ**
|
| 44 |
+
- dept-store-mart: #๋ฐฑํ์ /๋งํธ
|
| 45 |
+
- convenience-store: #ํธ์์
|
| 46 |
+
- fmcg-beverage: #FMCG/์์๋ฃ
|
| 47 |
+
- fashion-beauty: #ํจ์
/๋ทฐํฐ
|
| 48 |
+
- duty-free: #๋ฉด์ธ์
|
| 49 |
+
|
| 50 |
+
**๋ฐ์ด์ค ยท ์ ์ฝ ยท ์๋ฃ**
|
| 51 |
+
- pharma-new-drug: #์ ์ฝ/์ ์ฝ๊ฐ๋ฐ
|
| 52 |
+
- bio-cmo: #๋ฐ์ด์ค/CMO
|
| 53 |
+
- medical-device: #์๋ฃ๊ธฐ๊ธฐ
|
| 54 |
+
- digital-healthcare: #๋์งํธํฌ์ค์ผ์ด
|
| 55 |
+
|
| 56 |
+
**๋ฏธ๋์ด ยท ์ฝํ
์ธ ยท ๊ด๊ณ **
|
| 57 |
+
- entertainment: #์ํฐํ
์ธ๋จผํธ
|
| 58 |
+
- contents-video: #์ฝํ
์ธ /์์์ ์
|
| 59 |
+
- ad-agency: #๊ด๊ณ ๋ํ์ฌ
|
| 60 |
+
- webtoon-webnovel: #์นํฐ/์น์์ค
|
| 61 |
+
- broadcasting-press: #๋ฐฉ์ก/์ธ๋ก
|
| 62 |
+
|
| 63 |
+
**๊ฑด์ค ยท ๋ถ๋์ฐ**
|
| 64 |
+
- construction-engineering: #๊ฑด์ค/์์ง๋์ด๋ง
|
| 65 |
+
- realestate-development: #๋ถ๋์ฐ๊ฐ๋ฐ
|
| 66 |
+
- plant: #ํ๋ํธ
|
| 67 |
+
- interior: #์ธํ
๋ฆฌ์ด
|
| 68 |
+
|
| 69 |
+
**๊ณต๊ธฐ์
ยท ๊ณต๊ณต๊ธฐ๊ด**
|
| 70 |
+
- public-soc: #SOC (๊ณตํญ,๋๋ก,์ฒ ๋)
|
| 71 |
+
- public-energy: #์๋์ง ๊ณต๊ธฐ์
|
| 72 |
+
- public-finance: #๊ธ์ต ๊ณต๊ธฐ์
|
| 73 |
+
- public-admin: #์ผ๋ฐํ์
|
| 74 |
+
|
| 75 |
+
**์์ฌ ยท ๋ถํ ยท ์ฅ๋น (์๋ถ์ฅ)**
|
| 76 |
+
- mpe-semiconductor: #๋ฐ๋์ฒด ์๋ถ์ฅ
|
| 77 |
+
- mpe-display: #๋์คํ๋ ์ด ์๋ถ์ฅ
|
| 78 |
+
- mpe-battery: #2์ฐจ์ ์ง ์๋ถ์ฅ
|
| 79 |
+
- auto-parts: #์๋์ฐจ ๋ถํ
|
| 80 |
+
- chemical-materials: #ํํ/์์ฌ
|
| 81 |
+
|
| 82 |
+
**ํธํ
ยท ์ฌํ ยท ํญ๊ณต**
|
| 83 |
+
- hotel: #ํธํ
|
| 84 |
+
- travel-agency: #์ฌํ์ฌ
|
| 85 |
+
- airline: #ํญ๊ณต์ฌ
|
| 86 |
+
- leisure-resort: #๋ ์ /๋ฆฌ์กฐํธ
|
| 87 |
+
|
| 88 |
+
**์ ๋ฌธ ์๋น์ค**
|
| 89 |
+
- consulting: #์ปจ์คํ
|
| 90 |
+
- accounting-tax: #ํ๊ณ/์ธ๋ฌด
|
| 91 |
+
- law-firm: #๋ฒ๋ฅ (๋กํ)
|
| 92 |
+
- market-research: #๋ฆฌ์์น
|
| 93 |
+
|
| 94 |
+
**์ด์ก ยท ๋ฌผ๋ฅ**
|
| 95 |
+
- logistics-delivery: #๋ฌผ๋ฅ/ํ๋ฐฐ
|
| 96 |
+
- shipping: #ํด์ด
|
| 97 |
+
- forwarding: #ํฌ์๋ฉ
|
| 98 |
+
- land-transport: #์ก์์ด์ก
|
| 99 |
+
|
| 100 |
+
**๊ต์ก**
|
| 101 |
+
- edutech: #์๋ํ
ํฌ
|
| 102 |
+
- private-academy: #์
์/๋ณด์ตํ์
|
| 103 |
+
- edu-publishing: #๊ต์ก์ถํ
|
| 104 |
+
- language-edu: #์ธ๊ตญ์ด๊ต์ก
|
| 105 |
+
|
| 106 |
+
**๋น์๋ฆฌ ยท ์ฌํ์ ๊ธฐ์
**
|
| 107 |
+
- ngo-npo: #NGO/NPO
|
| 108 |
+
- social-enterprise: #์ฌํ์ ๊ธฐ์
|
| 109 |
+
- foundation: #์ฌ๋จ
|
| 110 |
+
|
| 111 |
+
### ์ถ๋ ฅ ํ์
|
| 112 |
+
๋ฐ๋์ ๋ค์๊ณผ ๊ฐ์ JSON ๋ฐฐ์ด ํ์์ผ๋ก๋ง ์๋ตํ์ธ์:
|
| 113 |
+
|
| 114 |
+
```json
|
| 115 |
+
["tagId1", "tagId2", ...]
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
### ์์
|
| 119 |
+
[์
๋ ฅ]
|
| 120 |
+
- ์ง๋ฌด: ๊ฒฝ์๊ธฐํ
|
| 121 |
+
- ํ์ฌ๋ช
: ์ผ์ฑ์ ์
|
| 122 |
+
|
| 123 |
+
[์ถ๋ ฅ]
|
| 124 |
+
```json
|
| 125 |
+
["semiconductor", "electronics-home"]
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
์ด์ ๋ค์ ์
๋ ฅ์ ๋ํ ์ฐ์
๋ถ๋ฅ๋ฅผ ์ํํด์ฃผ์ธ์.
|
jasoseo-context-report/.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
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
|
| 31 |
+
-----END CERTIFICATE-----
|
jasoseo-context-report/__pycache__/llm_functions.cpython-312.pyc
ADDED
|
Binary file (10.3 kB). View file
|
|
|
jasoseo-context-report/eval.json
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"context_report_generation_eval": {
|
| 3 |
+
"task_definition": {
|
| 4 |
+
"description": "Generate a structured context report based on the user's input (job, company, etc.). The output must be a JSON object following the specified schema, providing essential background information for writing a '์์์'. The content should be synthesized from public information as if processed by a web search and LLM pipeline.",
|
| 5 |
+
"input": {
|
| 6 |
+
"job_title": "string",
|
| 7 |
+
"company_name": "string",
|
| 8 |
+
"experience_level": "์ ์
| ๊ฒฝ๋ ฅ | ์ธํด | ๊ธฐํ"
|
| 9 |
+
},
|
| 10 |
+
"output_schema": {
|
| 11 |
+
"company_profile": {
|
| 12 |
+
"name": "string",
|
| 13 |
+
"vision_mission": "string",
|
| 14 |
+
"core_values": ["string", "..."],
|
| 15 |
+
"talent_philosophy": "string",
|
| 16 |
+
"recent_news_summary": "string",
|
| 17 |
+
"main_products_services": ["string", "..."]
|
| 18 |
+
},
|
| 19 |
+
"position_analysis": {
|
| 20 |
+
"role_summary": "string",
|
| 21 |
+
"required_skills": {
|
| 22 |
+
"hard": ["string", "..."],
|
| 23 |
+
"soft": ["string", "..."]
|
| 24 |
+
},
|
| 25 |
+
"keywords": ["string", "..."]
|
| 26 |
+
},
|
| 27 |
+
"industry_context": {
|
| 28 |
+
"trends": ["string", "..."],
|
| 29 |
+
"competitors": ["string", "..."]
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
},
|
| 33 |
+
"examples": [
|
| 34 |
+
{
|
| 35 |
+
"input": {
|
| 36 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 37 |
+
"company_name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)",
|
| 38 |
+
"experience_level": "์ ์
"
|
| 39 |
+
},
|
| 40 |
+
"output": {
|
| 41 |
+
"company_profile": {
|
| 42 |
+
"name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)",
|
| 43 |
+
"vision_mission": "๊ธ์ต์ ๋ชจ๋ ์๊ฐ์ ์ฝ๊ณ ๊ฐํธํ๊ฒ ๋ง๋๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ ๊ธฐ์ ๊ธฐ๋ฐ ๊ธ์ต ํ์ ๊ธฐ์
์
๋๋ค.",
|
| 44 |
+
"core_values": ["Customer Obsession (๊ณ ๊ฐ ์ค์ฌ)", "Excellence (ํ์ํจ)", "Radical Transparency (๊ทน๋์ ํฌ๋ช
์ฑ)", "Freedom and Responsibility (์์จ๊ณผ ์ฑ
์)"],
|
| 45 |
+
"talent_philosophy": "์ค์ค๋ก ๋ฌธ์ ๋ฅผ ์ ์ํ๊ณ ํด๊ฒฐํ๋ฉฐ, ๋๋ฃ์ ํฌ๋ช
ํ๊ฒ ์ํตํ์ฌ ์ต๊ณ ์ ์ฑ๊ณผ๋ฅผ ๋ง๋๋ ์ธ์ฌ๋ฅผ ์งํฅํฉ๋๋ค.",
|
| 46 |
+
"recent_news_summary": "ํ ์ค๋ฑ
ํฌ, ํ ์ค์ฆ๊ถ ๋ฑ ์ข
ํฉ ๊ธ์ต ํ๋ซํผ์ผ๋ก์ ํ์ฅ์ ๋์ด, ์๋ฐํฐ(MVNO) ์ฌ์
์ง์ถ ๋ฑ ๋น๊ธ์ต ๋ถ์ผ๋ก ์๋น์ค๋ฅผ ๋ค๊ฐํํ๋ฉฐ ์ฌ์ฉ์ ๊ฒฝํ์ ํ์ ํ๊ณ ์์ต๋๋ค.",
|
| 47 |
+
"main_products_services": ["ํ ์ค (๊ฐํธ์ก๊ธ, ๊ฒฐ์ )", "ํ ์ค๋ฑ
ํฌ", "ํ ์ค์ฆ๊ถ", "ํ ์คํ๋ ์ด์ค"]
|
| 48 |
+
},
|
| 49 |
+
"position_analysis": {
|
| 50 |
+
"role_summary": "๋์ฉ๋ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๋ ์์ ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๊ธ์ต ์๋น์ค์ ๋ฐฑ์๋ API๋ฅผ ๊ฐ๋ฐํ๊ณ ์ด์ํฉ๋๋ค. ๋ณต์กํ ๊ธ์ต ๋ฌธ์ ๋ฅผ ๊ธฐ์ ๋ก ํด๊ฒฐํ๋ฉฐ ์ต๊ณ ์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ๊ธฐ์ฌํฉ๋๋ค.",
|
| 51 |
+
"required_skills": {
|
| 52 |
+
"hard": ["Java/Kotlin", "Spring Framework", "RDBMS/NoSQL", "MSA (Microservice Architecture) ์ดํด"],
|
| 53 |
+
"soft": ["๋ฌธ์ ํด๊ฒฐ ๋ฅ๋ ฅ", "ํ์
๋ฐ ์ปค๋ฎค๋์ผ์ด์
", "ํ์ต ๋ฐ ์ฑ์ฅ ์์ง", "๋์ ์์ค์ ์ฑ
์๊ฐ"]
|
| 54 |
+
},
|
| 55 |
+
"keywords": ["ํํ
ํฌ", "๋์ฉ๋ ํธ๋ํฝ", "MSA", "๊ฒฐ์ ์์คํ
", "API", "๊ธ์ต ํ๋ซํผ"]
|
| 56 |
+
},
|
| 57 |
+
"industry_context": {
|
| 58 |
+
"trends": ["๊ฐํธ๊ฒฐ์ ์์ฅ์ ์ง์์ ์ฑ์ฅ", "๋ง์ด๋ฐ์ดํฐ ์ฌ์
ํ์ฑํ", "๋น
ํ
ํฌ ๊ธฐ์
์ ๊ธ์ต์
์ง์ถ ๊ฐ์ํ"],
|
| 59 |
+
"competitors": ["์นด์นด์คํ์ด", "๋ค์ด๋ฒํ์ด๋ธ์
"]
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
},
|
| 63 |
+
{
|
| 64 |
+
"input": {
|
| 65 |
+
"job_title": "์ํ๋ง์ผํ
",
|
| 66 |
+
"company_name": "CJ์ ์ผ์ ๋น",
|
| 67 |
+
"experience_level": "์ ์
"
|
| 68 |
+
},
|
| 69 |
+
"output": {
|
| 70 |
+
"company_profile": {
|
| 71 |
+
"name": "CJ์ ์ผ์ ๋น",
|
| 72 |
+
"vision_mission": "๊ธ๋ก๋ฒ No.1 ์ํ & ๋ฐ์ด์ค ๊ธฐ์
์ผ๋ก ์ฑ์ฅํ์ฌ ์ ์ธ๊ณ์ ํ๊ตญ์ ์๋ฌธํ๋ฅผ ์ ํํ๋ ๊ฒ์ ๋น์ ์ผ๋ก ํฉ๋๋ค.",
|
| 73 |
+
"core_values": ["์ธ์ฌ", "์์", "์ ์ง", "์ฐฝ์"],
|
| 74 |
+
"talent_philosophy": "๋์์์ด ๋์ ํ๊ณ ์ฑ์ฅํ๋ฉฐ, ๋งก์ ๋ถ์ผ์์ ์ต๊ณ ๋ฅผ ์ถ๊ตฌํ๋ 'ํ๊ณ ์ก์ด' ์ธ์ฌ๋ฅผ ์ ํธํฉ๋๋ค.",
|
| 75 |
+
"recent_news_summary": "'๋น๋น๊ณ ' ๋ธ๋๋๋ฅผ ์ค์ฌ์ผ๋ก K-ํธ๋์ ๊ธ๋ก๋ฒ ์ํ ํ์ฅ์ ๊ฐ์ํํ๊ณ ์์ผ๋ฉฐ, ๋ถ๋ฏธ ๋ฐ ์ ๋ฝ ์์ฅ ๊ณต๋ต์ ๊ฐํํ๊ณ ์๋ฌผ์ฑ ์ํ(Plant-based) ํฌํธํด๋ฆฌ์ค๋ฅผ ํ๋ํ๊ณ ์์ต๋๋ค.",
|
| 76 |
+
"main_products_services": ["๋น๋น๊ณ (๋ง๋, ๊น์น ๋ฑ)", "ํ๋ฐ", "์คํธ", "๊ฐ์ข
์กฐ๋ฏธ๋ฃ ๋ฐ ์์ค๋ฅ"]
|
| 77 |
+
},
|
| 78 |
+
"position_analysis": {
|
| 79 |
+
"role_summary": "๋ด๋น ๋ธ๋๋์ ๋ง์ผํ
์ ๋ต์ ์๋ฆฝํ๊ณ ์คํํฉ๋๋ค. ์์ฅ ๋ฐ ์๋น์ ๋ฐ์ดํฐ ๋ถ์์ ๊ธฐ๋ฐ์ผ๋ก ์ ์ ํ ๋ฐ์นญ, ๊ด๊ณ ์บ ํ์ธ, ํ๋ก๋ชจ์
๋ฑ์ ๊ธฐํํ๊ณ ์ด์ํ์ฌ ๋ธ๋๋ ์ฑ์ฅ์ ์ฃผ๋ํฉ๋๋ค.",
|
| 80 |
+
"required_skills": {
|
| 81 |
+
"hard": ["๋ฐ์ดํฐ ๋ถ์ ๋ฅ๋ ฅ (GA, SQL ๋ฑ)", "์์ฅ ์กฐ์ฌ ๋ฐ ๋ถ์", "๋ง์ผํ
์ ๋ต ๏ฟฝ๏ฟฝ๏ฟฝ๋ฆฝ"],
|
| 82 |
+
"soft": ["์ฐฝ์์ ์ฌ๊ณ ", "ํธ๋ ๋ ๋ฏผ๊ฐ์ฑ", "์ํํ ์ปค๋ฎค๋์ผ์ด์
", "๊ฒฐ๊ณผ ์งํฅ์ ํ๋"]
|
| 83 |
+
},
|
| 84 |
+
"keywords": ["FMCG", "๋ธ๋๋ ๋ง์ผํ
", "K-ํธ๋", "์ ์ ํ ๋ฐ์นญ", "์๋น์ ์กฐ์ฌ", "๋ฐ์ดํฐ ๊ธฐ๋ฐ"]
|
| 85 |
+
},
|
| 86 |
+
"industry_context": {
|
| 87 |
+
"trends": ["HMR(๊ฐ์ ๊ฐํธ์) ์์ฅ์ ๊ธ์ฑ์ฅ", "๊ฑด๊ฐ๊ณผ ์ง์๊ฐ๋ฅ์ฑ์ ์ค์ํ๋ 'ํฌ์ํ๋ ์ ' ํธ๋ ๋ ํ์ฐ", "์จ๋ผ์ธ ์ฑ๋ ์ค์ฌ์ ์ ํต ๊ตฌ์กฐ ๋ณํ"],
|
| 88 |
+
"competitors": ["๋์ ์ฒญ์ ์", "์ค๋๊ธฐ", "๋์ฌ"]
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"input": {
|
| 94 |
+
"job_title": "A&R",
|
| 95 |
+
"company_name": "ํ์ด๋ธ",
|
| 96 |
+
"experience_level": "์ธํด"
|
| 97 |
+
},
|
| 98 |
+
"output": {
|
| 99 |
+
"company_profile": {
|
| 100 |
+
"name": "ํ์ด๋ธ (HYBE)",
|
| 101 |
+
"vision_mission": "'We believe in music'์ด๋ผ๋ ๋ฏธ์
์๋, ์์
์ ๊ธฐ๋ฐํ ์ธ๊ณ ์ต๊ณ ์ ์ํฐํ
์ธ๋จผํธ ๋ผ์ดํ์คํ์ผ ํ๋ซํผ ๊ธฐ์
์ ์งํฅํฉ๋๋ค.",
|
| 102 |
+
"core_values": ["ํฌ ์ค์ฌ (Fan-centric)", "ํ์ (Innovation)", "์ง์ ์ฑ (Authenticity)", "์ง์๊ฐ๋ฅ์ฑ (Sustainability)"],
|
| 103 |
+
"talent_philosophy": "์์
๊ณผ ์ฝํ
์ธ ์ ๋ํ ๊น์ ์ดํด์ ์ด์ ์ ๋ฐํ์ผ๋ก, ์ฐ์
์ ๊ฒฝ๊ณ๋ฅผ ๋์ด ์๋ก์ด ๊ฐ์น๋ฅผ ์ฐฝ์ถํ๋ ์ ๋ฌธ๊ฐ๋ฅผ ์ถ๊ตฌํฉ๋๋ค.",
|
| 104 |
+
"recent_news_summary": "๋ฉํฐ ๋ ์ด๋ธ ์ฒด์ ๋ฅผ ๊ฐํํ๊ณ , ํฌ๋ค ํ๋ซํผ '์๋ฒ์ค(Weverse)'๋ฅผ ํตํด ํฌ ๋น์ฆ๋์ค๋ฅผ ํ์ฅํ๊ณ ์์ต๋๋ค. ๋ํ ๊ฒ์, ์นํฐ ๋ฑ IP(์ง์ ์ฌ์ฐ๊ถ)๋ฅผ ํ์ฉํ ์ฌ์
๋ค๊ฐํ์ ์ง์คํ๊ณ ์์ต๋๋ค.",
|
| 105 |
+
"main_products_services": ["์๋ฐ ๋ฐ ์์ ์ ์/์ ํต", "์ํฐ์คํธ ๋งค๋์ง๋จผํธ (BTS, ์ธ๋ธํด ๋ฑ)", "์๋ฒ์ค (Weverse) ํ๋ซํผ", "๊ณต์ฐ ๋ฐ MD ์ฌ์
"]
|
| 106 |
+
},
|
| 107 |
+
"position_analysis": {
|
| 108 |
+
"role_summary": "์ ์ธ ์ํฐ์คํธ ๋ฐ๊ตด ๋ฐ ๊ธฐ์กด ์ํฐ์คํธ์ ์จ๋ฒ ์ปจ์
๊ธฐํ, ๊ตญ๋ด์ธ ์๊ณก๊ฐ์์ ํ์
์ ํตํ ๊ณก ์๊ธ, ๋
น์ ๋ฑ ์๋ฐ ์ ์ ๊ณผ์ ์ ๋ฐ์ ์ง์ํ๋ ์
๋ฌด๋ฅผ ์ํํฉ๋๋ค.",
|
| 109 |
+
"required_skills": {
|
| 110 |
+
"hard": ["์์
์ฅ๋ฅด ๋ฐ ํธ๋ ๋์ ๋ํ ๋์ ์ดํด๋", "์ธ๊ตญ์ด ๋ฅ๋ ฅ (์์ด/์ผ๋ณธ์ด ๋ฑ)", "๊ธฐ๋ณธ์ ์ธ ์๊ณก/์์ฌ ์ง์ ์ฐ๋"],
|
| 111 |
+
"soft": ["์ฐฝ์์ ์ธ ๊ธฐํ๋ ฅ", "์ํํ ๋คํธ์ํน ๋ฐ ์ปค๋ฎค๋์ผ์ด์
", "๊ผผ๊ผผํจ๊ณผ ์ฑ
์๊ฐ", "๊ฐํ ์ด์ "]
|
| 112 |
+
},
|
| 113 |
+
"keywords": ["A&R", "K-POP", "์๋ฐ ๊ธฐํ", "IP ๋น์ฆ๋์ค", "์๋ฒ์ค", "์ฝํ
์ธ ์ ์"]
|
| 114 |
+
},
|
| 115 |
+
"industry_context": {
|
| 116 |
+
"trends": ["๊ธ๋ก๋ฒ ํฌ๋ค ํ๋ซํผ์ ์ค์์ฑ ์ฆ๋", "IP๋ฅผ ํ์ฉํ ์์์ค ๋ฉํฐ์ ์ฆ(OSMU) ์ ๋ต ๋ณดํธํ", "๋ฒ์ถ์ผ ์์ด๋ ๋ฑ ๊ธฐ์ ์ตํฉํ ์ฝํ
์ธ ๋ฑ์ฅ"],
|
| 117 |
+
"competitors": ["SM์ํฐํ
์ธ๋จผํธ", "JYP์ํฐํ
์ธ๋จผํธ", "YG์ํฐํ
์ธ๋จผํธ"]
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
]
|
| 122 |
+
}
|
| 123 |
+
}
|
jasoseo-context-report/llm_functions.py
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import re
|
| 4 |
+
import yaml
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
|
| 7 |
+
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
| 8 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 9 |
+
|
| 10 |
+
# ํ๋กฌํํธ ํ
ํ๋ฆฟ ๋ก๋
|
| 11 |
+
import os
|
| 12 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 13 |
+
prompt_path = os.path.join(current_dir, 'prompt.yaml')
|
| 14 |
+
with open(prompt_path, 'r', encoding='utf-8') as f:
|
| 15 |
+
prompt_data = yaml.safe_load(f)
|
| 16 |
+
prompt_template = prompt_data['prompt']
|
| 17 |
+
|
| 18 |
+
def parse_context_report(content):
|
| 19 |
+
"""
|
| 20 |
+
AI ์๋ต์์ ์ปจํ
์คํธ ๋ฆฌํฌํธ JSON์ ํ์ฑํ๋ ํจ์
|
| 21 |
+
"""
|
| 22 |
+
try:
|
| 23 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ๊ธธ์ด: {len(content)}")
|
| 24 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ์ฒซ 200์: {repr(content[:200])}")
|
| 25 |
+
|
| 26 |
+
# ํ
์คํธ ์ ์ฒ๋ฆฌ
|
| 27 |
+
cleaned_content = content.strip()
|
| 28 |
+
|
| 29 |
+
# 1. JSON ์ฝ๋ ๋ธ๋ก ์ฐพ๊ธฐ (```json ... ``` ํ์)
|
| 30 |
+
json_patterns = [
|
| 31 |
+
r'```json\s*(\{.*?\})\s*```',
|
| 32 |
+
r'```\s*(\{.*?\})\s*```',
|
| 33 |
+
r'```json\s*(.*?)\s*```',
|
| 34 |
+
r'```\s*(.*?)\s*```'
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
for pattern in json_patterns:
|
| 38 |
+
json_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 39 |
+
if json_match:
|
| 40 |
+
json_str = json_match.group(1).strip()
|
| 41 |
+
print(f"JSON ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 42 |
+
|
| 43 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 44 |
+
json_str = re.sub(r'\n\s*', ' ', json_str)
|
| 45 |
+
json_str = re.sub(r',\s*}', '}', json_str)
|
| 46 |
+
json_str = re.sub(r',\s*]', ']', json_str)
|
| 47 |
+
|
| 48 |
+
try:
|
| 49 |
+
parsed_json = json.loads(json_str)
|
| 50 |
+
if isinstance(parsed_json, dict) and 'company_profile' in parsed_json:
|
| 51 |
+
return parsed_json
|
| 52 |
+
except json.JSONDecodeError as e:
|
| 53 |
+
print(f"JSON ๋ธ๋ก ํ์ฑ ์คํจ: {e}")
|
| 54 |
+
|
| 55 |
+
# 2. ์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ JSON ์ฐพ๊ธฐ
|
| 56 |
+
brace_patterns = [
|
| 57 |
+
r'\{.*?\}'
|
| 58 |
+
]
|
| 59 |
+
|
| 60 |
+
for pattern in brace_patterns:
|
| 61 |
+
brace_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 62 |
+
if brace_match:
|
| 63 |
+
json_str = brace_match.group(0).strip()
|
| 64 |
+
print(f"์ค๊ดํธ ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 65 |
+
|
| 66 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 67 |
+
json_str = re.sub(r'\n\s*', ' ', json_str)
|
| 68 |
+
json_str = re.sub(r',\s*}', '}', json_str)
|
| 69 |
+
json_str = re.sub(r',\s*]', ']', json_str)
|
| 70 |
+
|
| 71 |
+
try:
|
| 72 |
+
parsed_json = json.loads(json_str)
|
| 73 |
+
if isinstance(parsed_json, dict) and 'company_profile' in parsed_json:
|
| 74 |
+
return parsed_json
|
| 75 |
+
except json.JSONDecodeError as e:
|
| 76 |
+
print(f"์ค๊ดํธ ๋ธ๋ก ํ์ฑ ์คํจ: {e}")
|
| 77 |
+
|
| 78 |
+
# 3. ์ ์ฒด ํ
์คํธ๋ฅผ JSON์ผ๋ก ํ์ฑ ์๋
|
| 79 |
+
try:
|
| 80 |
+
# ์ฝ๋ ๋ธ๋ก ๋ง์ปค ์ ๊ฑฐ
|
| 81 |
+
if cleaned_content.startswith('```'):
|
| 82 |
+
lines = cleaned_content.split('\n')
|
| 83 |
+
start_idx = 1 if lines[0].startswith('```') else 0
|
| 84 |
+
end_idx = len(lines)
|
| 85 |
+
for i in range(len(lines)-1, -1, -1):
|
| 86 |
+
if lines[i].strip() == '```':
|
| 87 |
+
end_idx = i
|
| 88 |
+
break
|
| 89 |
+
cleaned_content = '\n'.join(lines[start_idx:end_idx])
|
| 90 |
+
|
| 91 |
+
cleaned_content = cleaned_content.strip()
|
| 92 |
+
parsed_json = json.loads(cleaned_content)
|
| 93 |
+
if isinstance(parsed_json, dict) and 'company_profile' in parsed_json:
|
| 94 |
+
return parsed_json
|
| 95 |
+
except json.JSONDecodeError as e:
|
| 96 |
+
print(f"์ ์ฒด JSON ํ์ฑ ์คํจ: {e}")
|
| 97 |
+
|
| 98 |
+
# 4. ๊ธฐ๋ณธ ๊ตฌ์กฐ ๋ฐํ (ํ์ฑ ์คํจ ์)
|
| 99 |
+
print("JSON ํ์ฑ ์คํจ, ๊ธฐ๋ณธ ๊ตฌ์กฐ ๋ฐํ")
|
| 100 |
+
return {
|
| 101 |
+
"company_profile": {
|
| 102 |
+
"name": "ํ์ฑ ์คํจ",
|
| 103 |
+
"vision_mission": "์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.",
|
| 104 |
+
"core_values": ["์ ๋ณด ์์"],
|
| 105 |
+
"talent_philosophy": "์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.",
|
| 106 |
+
"recent_news_summary": "์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.",
|
| 107 |
+
"main_products_services": ["์ ๋ณด ์์"]
|
| 108 |
+
},
|
| 109 |
+
"position_analysis": {
|
| 110 |
+
"role_summary": "์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.",
|
| 111 |
+
"required_skills": {
|
| 112 |
+
"hard": ["์ ๋ณด ์์"],
|
| 113 |
+
"soft": ["์ ๋ณด ์์"]
|
| 114 |
+
},
|
| 115 |
+
"keywords": ["์ ๋ณด ์์"]
|
| 116 |
+
},
|
| 117 |
+
"industry_context": {
|
| 118 |
+
"trends": ["์ ๋ณด ์์"],
|
| 119 |
+
"competitors": ["์ ๋ณด ์์"]
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
except Exception as e:
|
| 124 |
+
print(f"์ปจํ
์คํธ ๋ฆฌํฌํธ ํ์ฑ ์ ์ฒด ์ค๋ฅ: {e}")
|
| 125 |
+
print(f"ํ์ฑ ์คํจํ ์ปจํ
์ธ : {repr(content)}")
|
| 126 |
+
return {
|
| 127 |
+
"company_profile": {
|
| 128 |
+
"name": "์ค๋ฅ ๋ฐ์",
|
| 129 |
+
"vision_mission": f"ํ์ฑ ์ค๋ฅ: {str(e)}",
|
| 130 |
+
"core_values": ["์ค๋ฅ"],
|
| 131 |
+
"talent_philosophy": f"ํ์ฑ ์ค๋ฅ: {str(e)}",
|
| 132 |
+
"recent_news_summary": f"ํ์ฑ ์ค๋ฅ: {str(e)}",
|
| 133 |
+
"main_products_services": ["์ค๋ฅ"]
|
| 134 |
+
},
|
| 135 |
+
"position_analysis": {
|
| 136 |
+
"role_summary": f"ํ์ฑ ์ค๋ฅ: {str(e)}",
|
| 137 |
+
"required_skills": {
|
| 138 |
+
"hard": ["์ค๋ฅ"],
|
| 139 |
+
"soft": ["์ค๋ฅ"]
|
| 140 |
+
},
|
| 141 |
+
"keywords": ["์ค๋ฅ"]
|
| 142 |
+
},
|
| 143 |
+
"industry_context": {
|
| 144 |
+
"trends": ["์ค๋ฅ"],
|
| 145 |
+
"competitors": ["์ค๋ฅ"]
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
def generate_context_report(job_title, company_name, experience_level):
|
| 150 |
+
"""
|
| 151 |
+
OpenAI API๋ฅผ ์ฌ์ฉํ์ฌ ์์์ ์ปจํ
์คํธ ๋ฆฌํฌํธ๋ฅผ ์์ฑํ๋ ํจ์
|
| 152 |
+
"""
|
| 153 |
+
try:
|
| 154 |
+
if not job_title or not company_name or not experience_level:
|
| 155 |
+
return "์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ๋ชจ๋ ์
๋ ฅํด์ฃผ์ธ์.", {}
|
| 156 |
+
|
| 157 |
+
# ํ๋กฌํํธ ์์ฑ
|
| 158 |
+
prompt = prompt_template.format(
|
| 159 |
+
job_title=job_title,
|
| 160 |
+
company_name=company_name,
|
| 161 |
+
experience_level=experience_level
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
# OpenAI Responses API ํธ์ถ (Web Search Preview ์ฌ์ฉ)
|
| 165 |
+
response = client.responses.create(
|
| 166 |
+
model="gpt-4o-mini",
|
| 167 |
+
tools=[{
|
| 168 |
+
"type": "web_search_preview",
|
| 169 |
+
"search_context_size": "high",
|
| 170 |
+
}],
|
| 171 |
+
input=f"๋น์ ์ ์๊ธฐ์๊ฐ์ ์์ฑ์ ์ํ ๊ธฐ์
๋ฐ ์ง๋ฌด ๋ถ์ ์ ๋ฌธ๊ฐ์
๋๋ค. ์น ๊ฒ์์ ํตํด ์ต์ ๊ธฐ์
์ ๋ณด์ ์ฐ์
๋ํฅ์ ํ์ธํ๊ณ ์ ํํ JSON ํ์์ผ๋ก ๊ตฌ์กฐํ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ฃผ์ธ์.\n\n{prompt}"
|
| 172 |
+
)
|
| 173 |
+
|
| 174 |
+
content = response.output_text
|
| 175 |
+
print(f"=== AI ์๋ต ์๋ณธ ===")
|
| 176 |
+
print(content)
|
| 177 |
+
print(f"=== ์ ์ฒด ์๋ต ๊ฐ์ฒด ===")
|
| 178 |
+
print(response)
|
| 179 |
+
|
| 180 |
+
# ์น ๊ฒ์ ์ฐธ๊ณ ๋งํฌ ์ถ๋ ฅ
|
| 181 |
+
if hasattr(response, 'web_search_results') and response.web_search_results:
|
| 182 |
+
print(f"=== ์ฐธ๊ณ ํ ์น ๊ฒ์ ๋งํฌ ===")
|
| 183 |
+
for i, result in enumerate(response.web_search_results, 1):
|
| 184 |
+
if hasattr(result, 'url'):
|
| 185 |
+
print(f"{i}. {result.url}")
|
| 186 |
+
elif hasattr(result, 'link'):
|
| 187 |
+
print(f"{i}. {result.link}")
|
| 188 |
+
|
| 189 |
+
print(f"=== AI ์๋ต ๋ ===")
|
| 190 |
+
|
| 191 |
+
report_data = parse_context_report(content)
|
| 192 |
+
|
| 193 |
+
if not report_data or 'company_profile' not in report_data:
|
| 194 |
+
return "์ปจํ
์คํธ ๋ฆฌํฌํธ ์์ฑ์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.", {}
|
| 195 |
+
|
| 196 |
+
# ๊ฒฐ๊ณผ ํฌ๋งทํ
|
| 197 |
+
result = f"""## ๐ {company_name} - {job_title} ์ปจํ
์คํธ ๋ฆฌํฌํธ
|
| 198 |
+
|
| 199 |
+
### ๐ข **๊ธฐ์
ํ๋กํ**
|
| 200 |
+
|
| 201 |
+
**๐ฏ ๋น์ & ๋ฏธ์
**
|
| 202 |
+
{report_data['company_profile']['vision_mission']}
|
| 203 |
+
|
| 204 |
+
**๐ ํต์ฌ ๊ฐ์น**
|
| 205 |
+
"""
|
| 206 |
+
for i, value in enumerate(report_data['company_profile']['core_values'], 1):
|
| 207 |
+
result += f"**{i}.** {value}\n"
|
| 208 |
+
|
| 209 |
+
result += f"""
|
| 210 |
+
**๐ฅ ์ธ์ฌ์**
|
| 211 |
+
{report_data['company_profile']['talent_philosophy']}
|
| 212 |
+
|
| 213 |
+
**๐ฐ ์ต๊ทผ ๋ํฅ**
|
| 214 |
+
{report_data['company_profile']['recent_news_summary']}
|
| 215 |
+
|
| 216 |
+
**๐๏ธ ์ฃผ์ ์ ํ/์๋น์ค**
|
| 217 |
+
"""
|
| 218 |
+
for i, service in enumerate(report_data['company_profile']['main_products_services'], 1):
|
| 219 |
+
result += f"**{i}.** {service}\n"
|
| 220 |
+
|
| 221 |
+
result += f"""
|
| 222 |
+
|
| 223 |
+
### ๐ผ **์ง๋ฌด ๋ถ์**
|
| 224 |
+
|
| 225 |
+
**๐ ์ญํ ์์ฝ**
|
| 226 |
+
{report_data['position_analysis']['role_summary']}
|
| 227 |
+
|
| 228 |
+
**๐ง ํ์ ์คํฌ**
|
| 229 |
+
|
| 230 |
+
*ํ๋ ์คํฌ:*
|
| 231 |
+
"""
|
| 232 |
+
for skill in report_data['position_analysis']['required_skills']['hard']:
|
| 233 |
+
result += f"โข {skill}\n"
|
| 234 |
+
|
| 235 |
+
result += "\n*์ํํธ ์คํฌ:*\n"
|
| 236 |
+
for skill in report_data['position_analysis']['required_skills']['soft']:
|
| 237 |
+
result += f"โข {skill}\n"
|
| 238 |
+
|
| 239 |
+
result += f"""
|
| 240 |
+
**๐ท๏ธ ํต์ฌ ํค์๋**
|
| 241 |
+
"""
|
| 242 |
+
for keyword in report_data['position_analysis']['keywords']:
|
| 243 |
+
result += f"`{keyword}` "
|
| 244 |
+
|
| 245 |
+
result += f"""
|
| 246 |
+
|
| 247 |
+
### ๐ **์ฐ์
๋งฅ๋ฝ**
|
| 248 |
+
|
| 249 |
+
**๐ ์ฃผ์ ํธ๋ ๋**
|
| 250 |
+
"""
|
| 251 |
+
for i, trend in enumerate(report_data['industry_context']['trends'], 1):
|
| 252 |
+
result += f"**{i}.** {trend}\n"
|
| 253 |
+
|
| 254 |
+
result += f"""
|
| 255 |
+
**๐ ์ฃผ์ ๊ฒฝ์์ฌ**
|
| 256 |
+
"""
|
| 257 |
+
for i, competitor in enumerate(report_data['industry_context']['competitors'], 1):
|
| 258 |
+
result += f"**{i}.** {competitor}\n"
|
| 259 |
+
|
| 260 |
+
result += f"""
|
| 261 |
+
|
| 262 |
+
---
|
| 263 |
+
**๐ ์
๋ ฅ ์ ๋ณด:**
|
| 264 |
+
- ํ์ฌ: {company_name}
|
| 265 |
+
- ์ง๋ฌด: {job_title}
|
| 266 |
+
- ๊ฒฝ๋ ฅ: {experience_level}
|
| 267 |
+
|
| 268 |
+
*๋ณธ ๋ฆฌํฌํธ๋ AI๊ฐ ์์ฑํ ๊ฒ์ผ๋ก, ์ค์ ์ ๋ณด์ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์์์ ์์ฑ ์ ์ฐธ๊ณ ์ฉ์ผ๋ก ํ์ฉํ์ธ์.*
|
| 269 |
+
"""
|
| 270 |
+
|
| 271 |
+
return result, report_data
|
| 272 |
+
|
| 273 |
+
except Exception as e:
|
| 274 |
+
error_msg = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 275 |
+
|
| 276 |
+
์ปจํ
์คํธ ๋ฆฌํฌํธ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 277 |
+
|
| 278 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 279 |
+
|
| 280 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 281 |
+
"""
|
| 282 |
+
return error_msg, {}
|
jasoseo-context-report/main.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from llm_functions import generate_context_report
|
| 3 |
+
|
| 4 |
+
# ์์ ๋ฐ์ดํฐ
|
| 5 |
+
example_companies = ["ํ ์ค", "์ผ์ฑ์ ์", "CJ์ ์ผ์ ๋น", "ํ์ด๋ธ", "ํ๋๊ฑด์ค", "์ ํ์ํ", "์นด์นด์ค", "๋ค์ด๋ฒ", "LG์ ์", "SKํ์ด๋์ค"]
|
| 6 |
+
example_jobs = ["๋ฐฑ์๋ ๊ฐ๋ฐ", "๊ฒฝ์๊ธฐํ", "์ํ๋ง์ผํ
", "A&R", "HRM(์ธ์ฌ์ด์)", "ํด์ธ์์
", "๋ฐ์ดํฐ ๋ถ์", "์จ๋ผ์ธ๋ง์ผํ
", "๊ธฐํ", "๊ฐ๋ฐ"]
|
| 7 |
+
experience_levels = ["์ ์
", "๊ฒฝ๋ ฅ", "์ธํด", "๊ธฐํ"]
|
| 8 |
+
|
| 9 |
+
def create_info_cards(report_data):
|
| 10 |
+
"""
|
| 11 |
+
๋ฆฌํฌํธ ๋ฐ์ดํฐ๋ฅผ ์นด๋ ํํ๋ก ํ์ํ๋ HTML ์์ฑ
|
| 12 |
+
"""
|
| 13 |
+
if not report_data or 'company_profile' not in report_data:
|
| 14 |
+
return "<div style='text-align: center; color: #6B7280; padding: 20px;'>๋ฆฌํฌํธ๋ฅผ ์์ฑํด์ฃผ์ธ์</div>"
|
| 15 |
+
|
| 16 |
+
# ๊ธฐ์
ํ๋กํ ์นด๋
|
| 17 |
+
company_card = f"""
|
| 18 |
+
<div style="
|
| 19 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 20 |
+
color: white;
|
| 21 |
+
border-radius: 15px;
|
| 22 |
+
padding: 20px;
|
| 23 |
+
margin: 10px 0;
|
| 24 |
+
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
| 25 |
+
">
|
| 26 |
+
<h3 style="margin: 0 0 15px 0; font-size: 18px;">๐ข ๊ธฐ์
ํ๋กํ</h3>
|
| 27 |
+
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 15px;">
|
| 28 |
+
<strong>๐ฏ ๋น์ /๋ฏธ์
:</strong><br>
|
| 29 |
+
{report_data['company_profile']['vision_mission']}<br><br>
|
| 30 |
+
<strong>๐ ํต์ฌ ๊ฐ์น:</strong><br>
|
| 31 |
+
{' โข '.join(report_data['company_profile']['core_values'])}<br><br>
|
| 32 |
+
<strong>๐ฅ ์ธ์ฌ์:</strong><br>
|
| 33 |
+
{report_data['company_profile']['talent_philosophy']}
|
| 34 |
+
</div>
|
| 35 |
+
</div>
|
| 36 |
+
"""
|
| 37 |
+
|
| 38 |
+
# ์ง๋ฌด ๋ถ์ ์นด๋
|
| 39 |
+
position_card = f"""
|
| 40 |
+
<div style="
|
| 41 |
+
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
|
| 42 |
+
color: white;
|
| 43 |
+
border-radius: 15px;
|
| 44 |
+
padding: 20px;
|
| 45 |
+
margin: 10px 0;
|
| 46 |
+
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
| 47 |
+
">
|
| 48 |
+
<h3 style="margin: 0 0 15px 0; font-size: 18px;">๐ผ ์ง๋ฌด ๋ถ์</h3>
|
| 49 |
+
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 15px;">
|
| 50 |
+
<strong>๐ ์ญํ :</strong><br>
|
| 51 |
+
{report_data['position_analysis']['role_summary']}<br><br>
|
| 52 |
+
<strong>๐ง ํ๋ ์คํฌ:</strong><br>
|
| 53 |
+
{' โข '.join(report_data['position_analysis']['required_skills']['hard'])}<br><br>
|
| 54 |
+
<strong>๐ก ์ํํธ ์คํฌ:</strong><br>
|
| 55 |
+
{' โข '.join(report_data['position_analysis']['required_skills']['soft'])}
|
| 56 |
+
</div>
|
| 57 |
+
</div>
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
# ์ฐ์
๋งฅ๋ฝ ์นด๋
|
| 61 |
+
industry_card = f"""
|
| 62 |
+
<div style="
|
| 63 |
+
background: linear-gradient(135deg, #fc4a1a 0%, #f7b733 100%);
|
| 64 |
+
color: white;
|
| 65 |
+
border-radius: 15px;
|
| 66 |
+
padding: 20px;
|
| 67 |
+
margin: 10px 0;
|
| 68 |
+
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
| 69 |
+
">
|
| 70 |
+
<h3 style="margin: 0 0 15px 0; font-size: 18px;">๐ ์ฐ์
๋งฅ๋ฝ</h3>
|
| 71 |
+
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 15px;">
|
| 72 |
+
<strong>๐ ์ฃผ์ ํธ๋ ๋:</strong><br>
|
| 73 |
+
{' โข '.join(report_data['industry_context']['trends'])}<br><br>
|
| 74 |
+
<strong>๐ ์ฃผ์ ๊ฒฝ์์ฌ:</strong><br>
|
| 75 |
+
{' โข '.join(report_data['industry_context']['competitors'])}
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
"""
|
| 79 |
+
|
| 80 |
+
# ํค์๋ ์นด๋
|
| 81 |
+
keywords_html = ""
|
| 82 |
+
if 'keywords' in report_data['position_analysis']:
|
| 83 |
+
keywords_html = "<div style='margin-top: 15px;'><strong>๐ท๏ธ ํต์ฌ ํค์๋:</strong><br>"
|
| 84 |
+
for keyword in report_data['position_analysis']['keywords']:
|
| 85 |
+
keywords_html += f"<span style='background: rgba(255,255,255,0.2); padding: 5px 10px; border-radius: 15px; margin: 2px; display: inline-block; font-size: 12px;'>{keyword}</span>"
|
| 86 |
+
keywords_html += "</div>"
|
| 87 |
+
|
| 88 |
+
return f"""
|
| 89 |
+
<div style="display: flex; flex-direction: column; gap: 10px;">
|
| 90 |
+
{company_card}
|
| 91 |
+
{position_card}
|
| 92 |
+
{industry_card}
|
| 93 |
+
<div style="
|
| 94 |
+
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
| 95 |
+
color: #333;
|
| 96 |
+
border-radius: 15px;
|
| 97 |
+
padding: 20px;
|
| 98 |
+
margin: 10px 0;
|
| 99 |
+
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
| 100 |
+
">
|
| 101 |
+
<h3 style="margin: 0 0 15px 0; font-size: 18px;">๐ท๏ธ ํต์ฌ ํค์๋</h3>
|
| 102 |
+
<div style="display: flex; flex-wrap: wrap; gap: 8px;">
|
| 103 |
+
{''.join([f'<span style="background: #667eea; color: white; padding: 8px 15px; border-radius: 20px; font-size: 14px; font-weight: bold;">{keyword}</span>' for keyword in report_data['position_analysis']['keywords']])}
|
| 104 |
+
</div>
|
| 105 |
+
</div>
|
| 106 |
+
</div>
|
| 107 |
+
"""
|
| 108 |
+
|
| 109 |
+
def process_report_generation(job_title, company_name, experience_level):
|
| 110 |
+
"""
|
| 111 |
+
๋ฆฌํฌํธ ์์ฑ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๊ณ UI์ ํ์ํ ํํ๋ก ๋ณํํ๋ ํจ์
|
| 112 |
+
"""
|
| 113 |
+
try:
|
| 114 |
+
content, report_data = generate_context_report(job_title, company_name, experience_level)
|
| 115 |
+
info_cards = create_info_cards(report_data)
|
| 116 |
+
return content, info_cards
|
| 117 |
+
except Exception as e:
|
| 118 |
+
error_content = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 119 |
+
|
| 120 |
+
์ปจํ
์คํธ ๋ฆฌํฌํธ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 121 |
+
|
| 122 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 123 |
+
|
| 124 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 125 |
+
"""
|
| 126 |
+
error_cards = create_info_cards({})
|
| 127 |
+
return error_content, error_cards
|
| 128 |
+
|
| 129 |
+
def create_interface():
|
| 130 |
+
"""
|
| 131 |
+
Gradio ์ธํฐํ์ด์ค ์์ฑ
|
| 132 |
+
"""
|
| 133 |
+
with gr.Blocks(
|
| 134 |
+
title="๐ ์์์ ์ปจํ
์คํธ ๋ฆฌํฌํธ",
|
| 135 |
+
theme=gr.themes.Soft(),
|
| 136 |
+
css="""
|
| 137 |
+
.main-header {
|
| 138 |
+
text-align: center;
|
| 139 |
+
padding: 20px;
|
| 140 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 141 |
+
color: white;
|
| 142 |
+
border-radius: 10px;
|
| 143 |
+
margin-bottom: 20px;
|
| 144 |
+
}
|
| 145 |
+
.input-section {
|
| 146 |
+
background-color: #f8f9fa;
|
| 147 |
+
padding: 20px;
|
| 148 |
+
border-radius: 8px;
|
| 149 |
+
margin: 10px 0;
|
| 150 |
+
}
|
| 151 |
+
.example-section {
|
| 152 |
+
background-color: #f0f9ff;
|
| 153 |
+
padding: 15px;
|
| 154 |
+
border-radius: 8px;
|
| 155 |
+
margin: 10px 0;
|
| 156 |
+
}
|
| 157 |
+
"""
|
| 158 |
+
) as demo:
|
| 159 |
+
|
| 160 |
+
# ํค๋
|
| 161 |
+
gr.HTML("""
|
| 162 |
+
<div class="main-header">
|
| 163 |
+
<h1>๐ ์์์ ์ปจํ
์คํธ ๋ฆฌํฌํธ</h1>
|
| 164 |
+
<p>๊ธฐ์
๊ณผ ์ง๋ฌด์ ๋ํ ์ข
ํฉ์ ์ธ ๋ถ์์ผ๋ก ์๋ฒฝํ ์๊ธฐ์๊ฐ์๋ฅผ ์ค๋นํ์ธ์</p>
|
| 165 |
+
</div>
|
| 166 |
+
""")
|
| 167 |
+
|
| 168 |
+
# ์ค๋ช
|
| 169 |
+
gr.Markdown("""
|
| 170 |
+
### ๐ **์ฌ์ฉ ๋ฐฉ๋ฒ**
|
| 171 |
+
1. **์ง๋ฌด**: ์ง์ํ๊ณ ์ ํ๋ ์ง๋ฌด๋ฅผ ์
๋ ฅํ์ธ์
|
| 172 |
+
2. **ํ์ฌ๋ช
**: ์ง์ ํ์ฌ๋ช
์ ์
๋ ฅํ์ธ์
|
| 173 |
+
3. **๊ฒฝ๋ ฅ ์์ค**: ์ ์
/๊ฒฝ๋ ฅ/์ธํด/๊ธฐํ ์ค ์ ํํ์ธ์
|
| 174 |
+
4. **์์ฑ**: '๋ฆฌํฌํธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ์ธ์
|
| 175 |
+
|
| 176 |
+
โจ **ํน์ง**: ๊ธฐ์
ํ๋กํ, ์ง๋ฌด ๋ถ์, ์ฐ์
๋งฅ๋ฝ์ ์ข
ํฉ์ ์ผ๋ก ๋ถ์ํ์ฌ ์์์ ์์ฑ์ ํ์ํ ํต์ฌ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
|
| 177 |
+
""")
|
| 178 |
+
|
| 179 |
+
with gr.Row():
|
| 180 |
+
with gr.Column(scale=2):
|
| 181 |
+
# ์
๋ ฅ ์น์
|
| 182 |
+
gr.HTML('<div class="input-section">')
|
| 183 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 184 |
+
|
| 185 |
+
with gr.Row():
|
| 186 |
+
job_input = gr.Textbox(
|
| 187 |
+
label="๐ผ ์ง๋ฌด",
|
| 188 |
+
placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๊ฒฝ์๊ธฐํ, ๋ง์ผํ
๋ฑ",
|
| 189 |
+
value="",
|
| 190 |
+
scale=1
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
+
company_input = gr.Textbox(
|
| 194 |
+
label="๐ข ํ์ฌ๋ช
",
|
| 195 |
+
placeholder="์: ํ ์ค, ์ผ์ฑ์ ์, ์นด์นด์ค ๋ฑ",
|
| 196 |
+
value="",
|
| 197 |
+
scale=1
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
experience_input = gr.Dropdown(
|
| 201 |
+
label="๐ ๊ฒฝ๋ ฅ ์์ค",
|
| 202 |
+
choices=experience_levels,
|
| 203 |
+
value="์ ์
",
|
| 204 |
+
interactive=True
|
| 205 |
+
)
|
| 206 |
+
|
| 207 |
+
generate_btn = gr.Button(
|
| 208 |
+
"๐ ๋ฆฌํฌํธ ์์ฑ",
|
| 209 |
+
variant="primary",
|
| 210 |
+
size="lg"
|
| 211 |
+
)
|
| 212 |
+
gr.HTML('</div>')
|
| 213 |
+
|
| 214 |
+
with gr.Column(scale=1):
|
| 215 |
+
# ์์ ๋ฐ ๊ฐ์ด๋
|
| 216 |
+
gr.HTML('<div class="example-section">')
|
| 217 |
+
gr.Markdown("### ๐ก **์์ ํ์ฌ**")
|
| 218 |
+
|
| 219 |
+
company_rows = [example_companies[i:i+2] for i in range(0, len(example_companies), 2)]
|
| 220 |
+
for row in company_rows:
|
| 221 |
+
with gr.Row():
|
| 222 |
+
for company in row:
|
| 223 |
+
example_btn = gr.Button(
|
| 224 |
+
company,
|
| 225 |
+
size="sm",
|
| 226 |
+
variant="secondary",
|
| 227 |
+
scale=1
|
| 228 |
+
)
|
| 229 |
+
example_btn.click(
|
| 230 |
+
fn=lambda x=company: x,
|
| 231 |
+
outputs=company_input
|
| 232 |
+
)
|
| 233 |
+
|
| 234 |
+
gr.Markdown("### ๐ผ **์์ ์ง๋ฌด**")
|
| 235 |
+
|
| 236 |
+
job_rows = [example_jobs[i:i+2] for i in range(0, len(example_jobs), 2)]
|
| 237 |
+
for row in job_rows:
|
| 238 |
+
with gr.Row():
|
| 239 |
+
for job in row:
|
| 240 |
+
job_btn = gr.Button(
|
| 241 |
+
job,
|
| 242 |
+
size="sm",
|
| 243 |
+
variant="secondary",
|
| 244 |
+
scale=1
|
| 245 |
+
)
|
| 246 |
+
job_btn.click(
|
| 247 |
+
fn=lambda x=job: x,
|
| 248 |
+
outputs=job_input
|
| 249 |
+
)
|
| 250 |
+
|
| 251 |
+
gr.Markdown("### ๐ **๊ฒฝ๋ ฅ ์์ค**")
|
| 252 |
+
with gr.Row():
|
| 253 |
+
for level in experience_levels:
|
| 254 |
+
level_btn = gr.Button(
|
| 255 |
+
level,
|
| 256 |
+
size="sm",
|
| 257 |
+
variant="secondary",
|
| 258 |
+
scale=1
|
| 259 |
+
)
|
| 260 |
+
level_btn.click(
|
| 261 |
+
fn=lambda x=level: x,
|
| 262 |
+
outputs=experience_input
|
| 263 |
+
)
|
| 264 |
+
|
| 265 |
+
gr.HTML('</div>')
|
| 266 |
+
|
| 267 |
+
# ๊ฒฐ๊ณผ ์ถ๋ ฅ ์น์
|
| 268 |
+
with gr.Row():
|
| 269 |
+
with gr.Column(scale=2):
|
| 270 |
+
gr.Markdown("### ๐ **์์ธ ๋ฆฌํฌํธ**")
|
| 271 |
+
result_output = gr.Markdown(
|
| 272 |
+
value="์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ์
๋ ฅํ๊ณ '๋ฆฌํฌํธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.",
|
| 273 |
+
elem_classes=["result-output"]
|
| 274 |
+
)
|
| 275 |
+
|
| 276 |
+
with gr.Column(scale=1):
|
| 277 |
+
gr.Markdown("### ๐ **ํต์ฌ ์ ๋ณด**")
|
| 278 |
+
info_cards = gr.HTML(
|
| 279 |
+
value="<div style='text-align: center; color: #6B7280; padding: 20px;'>๋ฆฌํฌํธ๋ฅผ ์์ฑํด์ฃผ์ธ์</div>",
|
| 280 |
+
elem_classes=["info-cards"]
|
| 281 |
+
)
|
| 282 |
+
|
| 283 |
+
# ์์ฑ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
| 284 |
+
generate_btn.click(
|
| 285 |
+
fn=process_report_generation,
|
| 286 |
+
inputs=[job_input, company_input, experience_input],
|
| 287 |
+
outputs=[result_output, info_cards],
|
| 288 |
+
api_name="generate_context_report"
|
| 289 |
+
)
|
| 290 |
+
|
| 291 |
+
# ํธํฐ
|
| 292 |
+
gr.Markdown("""
|
| 293 |
+
---
|
| 294 |
+
**๐ ๋ฆฌํฌํธ ๊ตฌ์ฑ**:
|
| 295 |
+
- **๐ข ๊ธฐ์
ํ๋กํ**: ๋น์ /๋ฏธ์
, ํต์ฌ๊ฐ์น, ์ธ์ฌ์, ์ต๊ทผ๋ํฅ, ์ฃผ์์ ํ/์๋น์ค
|
| 296 |
+
- **๐ผ ์ง๋ฌด ๋ถ์**: ์ญํ ์์ฝ, ํ์์คํฌ(ํ๋/์ํํธ), ํต์ฌํค์๋
|
| 297 |
+
- **๐ ์ฐ์
๋งฅ๋ฝ**: ์ฃผ์ํธ๋ ๋, ๊ฒฝ์์ฌ ์ ๋ณด
|
| 298 |
+
|
| 299 |
+
๐ก **ํ์ฉ ํ**: ์์ฑ๋ ํค์๋์ ์ ๋ณด๋ฅผ ์์์ ์์ฑ ์ ์ ๊ทน ํ์ฉํ์ฌ ๋ง์ถคํ ์๊ธฐ์๊ฐ์๋ฅผ ์์ฑํ์ธ์.
|
| 300 |
+
|
| 301 |
+
๐ค **Powered by**: OpenAI GPT-4o
|
| 302 |
+
""")
|
| 303 |
+
|
| 304 |
+
return demo
|
| 305 |
+
|
| 306 |
+
if __name__ == "__main__":
|
| 307 |
+
# Gradio ์ฑ ์คํ
|
| 308 |
+
demo = create_interface()
|
| 309 |
+
demo.launch(
|
| 310 |
+
server_name="0.0.0.0",
|
| 311 |
+
# server_port=7862,
|
| 312 |
+
share=True,
|
| 313 |
+
show_error=True
|
| 314 |
+
)
|
jasoseo-context-report/prompt.yaml
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
prompt: |
|
| 2 |
+
๋น์ ์ ์๊ธฐ์๊ฐ์ ์์ฑ์ ์ํ ๊ธฐ์
๋ฐ ์ง๋ฌด ๋ถ์ ์ ๋ฌธ๊ฐ์
๋๋ค.
|
| 3 |
+
์ฃผ์ด์ง ์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ๋ฐํ์ผ๋ก ์๊ธฐ์๊ฐ์ ์์ฑ์ ํ์ํ ํต์ฌ ์ ๋ณด๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ ๋ฆฌํด์ผ ํฉ๋๋ค.
|
| 4 |
+
|
| 5 |
+
### ์ง์นจ
|
| 6 |
+
1. **์น ๊ฒ์ ํ์ฉ**: ํ์ฌ๋ช
์ ๊ฒ์ํ์ฌ ์ต์ ๊ธฐ์
์ ๋ณด, ๋น์ /๋ฏธ์
, ํต์ฌ๊ฐ์น, ์ต๊ทผ ๋ด์ค, ์ฑ์ฉ ์ ๋ณด ๋ฑ์ ํ์ธํฉ๋๋ค.
|
| 7 |
+
2. **์ ํํ ์ ๋ณด**: ๊ฒ์๋ ์ต์ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ ํํ๊ณ ์ ๋ขฐํ ์ ์๋ ๋ด์ฉ์ ์ ๊ณตํฉ๋๋ค.
|
| 8 |
+
3. **์์์ ๊ด์ **: ์๊ธฐ์๊ฐ์ ์์ฑ์ ์ค์ง์ ์ผ๋ก ๋์์ด ๋๋ ์ ๋ณด์ ์ง์คํฉ๋๋ค.
|
| 9 |
+
4. **๊ตฌ์กฐํ๋ ์ถ๋ ฅ**: ์ง์ ๋ JSON ์คํค๋ง๋ฅผ ์ ํํ ๋ฐ๋ผ ์ถ๋ ฅํฉ๋๋ค.
|
| 10 |
+
|
| 11 |
+
### ์
๋ ฅ ์ ๋ณด
|
| 12 |
+
- **์ง๋ฌด:** {job_title}
|
| 13 |
+
- **ํ์ฌ๋ช
:** {company_name}
|
| 14 |
+
- **๊ฒฝ๋ ฅ ์์ค:** {experience_level}
|
| 15 |
+
|
| 16 |
+
### ์ถ๋ ฅ ํ์
|
| 17 |
+
๋ฐ๋์ ๋ค์ JSON ์คํค๋ง๋ฅผ ์ ํํ ๋ฐ๋ผ ์๋ตํ์ธ์:
|
| 18 |
+
|
| 19 |
+
```json
|
| 20 |
+
{{
|
| 21 |
+
"company_profile": {{
|
| 22 |
+
"name": "ํ์ฌ๋ช
",
|
| 23 |
+
"vision_mission": "ํ์ฌ์ ๋น์ ๊ณผ ๋ฏธ์
์ค๋ช
",
|
| 24 |
+
"core_values": ["ํต์ฌ๊ฐ์น1", "ํต์ฌ๊ฐ์น2", "ํต์ฌ๊ฐ์น3"],
|
| 25 |
+
"talent_philosophy": "์ธ์ฌ์ ๋ฐ ์ธ์ฌ ์ฒ ํ",
|
| 26 |
+
"recent_news_summary": "์ต๊ทผ ์ฃผ์ ๋ด์ค ๋ฐ ๋ํฅ ์์ฝ",
|
| 27 |
+
"main_products_services": ["์ฃผ์์ ํ1", "์ฃผ์์ ํ2", "์ฃผ์์ ํ3"]
|
| 28 |
+
}},
|
| 29 |
+
"position_analysis": {{
|
| 30 |
+
"role_summary": "ํด๋น ์ง๋ฌด์ ์ฃผ์ ์ญํ ๊ณผ ์ฑ
์ ์์ฝ",
|
| 31 |
+
"required_skills": {{
|
| 32 |
+
"hard": ["ํ๋์คํฌ1", "ํ๋์คํฌ2", "ํ๋์คํฌ3"],
|
| 33 |
+
"soft": ["์ํํธ์คํฌ1", "์ํํธ์คํฌ2", "์ํํธ์คํฌ3"]
|
| 34 |
+
}},
|
| 35 |
+
"keywords": ["ํค์๋1", "ํค์๋2", "ํค์๋3", "ํค์๋4", "ํค์๋5"]
|
| 36 |
+
}},
|
| 37 |
+
"industry_context": {{
|
| 38 |
+
"trends": ["์ฐ์
ํธ๋ ๋1", "์ฐ์
ํธ๋ ๋2", "์ฐ์
ํธ๋ ๋3"],
|
| 39 |
+
"competitors": ["๊ฒฝ์์ฌ1", "๊ฒฝ์์ฌ2", "๊ฒฝ์์ฌ3"]
|
| 40 |
+
}}
|
| 41 |
+
}}
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
### ์ธ๋ถ ์๊ตฌ์ฌํญ
|
| 45 |
+
|
| 46 |
+
**company_profile (๊ธฐ์
ํ๋กํ)**
|
| 47 |
+
- name: ์ ํํ ํ์ฌ๋ช
|
| 48 |
+
- vision_mission: ํ์ฌ์ ๋น์ ๊ณผ ๋ฏธ์
์ ๊ฐ๊ฒฐํ๊ฒ ์ค๋ช
(1-2๋ฌธ์ฅ)
|
| 49 |
+
- core_values: ํ์ฌ์ ํต์ฌ ๊ฐ์น 3-4๊ฐ (๋ฐฐ์ด ํํ)
|
| 50 |
+
- talent_philosophy: ํ์ฌ๊ฐ ์ถ๊ตฌํ๋ ์ธ์ฌ์๊ณผ ์ธ์ฌ ์ฒ ํ (1-2๋ฌธ์ฅ)
|
| 51 |
+
- recent_news_summary: ์ต๊ทผ 1-2๋
๊ฐ ์ฃผ์ ๋ด์ค๋ ์ฌ์
๋ํฅ ์์ฝ (2-3๋ฌธ์ฅ)
|
| 52 |
+
- main_products_services: ์ฃผ์ ์ ํ์ด๋ ์๋น์ค 3-4๊ฐ (๋ฐฐ์ด ํํ)
|
| 53 |
+
|
| 54 |
+
**position_analysis (์ง๋ฌด ๋ถ์)**
|
| 55 |
+
- role_summary: ํด๋น ์ง๋ฌด์ ์ฃผ์ ์ญํ ๊ณผ ์ฑ
์์ ๊ฒฝ๋ ฅ ์์ค์ ๋ง๊ฒ ์ค๋ช
(2-3๋ฌธ์ฅ)
|
| 56 |
+
- required_skills.hard: ํ์ํ ํ๋ ์คํฌ 3-4๊ฐ (๊ธฐ์ , ๋๊ตฌ, ์๊ฒฉ์ฆ ๋ฑ)
|
| 57 |
+
- required_skills.soft: ํ์ํ ์ํํธ ์คํฌ 3-4๊ฐ (์ญ๋, ํ๋, ์ฑํฅ ๋ฑ)
|
| 58 |
+
- keywords: ์์์์ ํ์ฉํ ์ ์๋ ํต์ฌ ํค์๋ 5-6๊ฐ
|
| 59 |
+
|
| 60 |
+
**industry_context (์ฐ์
๋งฅ๋ฝ)**
|
| 61 |
+
- trends: ํด๋น ์ฐ์
์ ์ฃผ์ ํธ๋ ๋ 3๊ฐ
|
| 62 |
+
- competitors: ์ฃผ์ ๊ฒฝ์์ฌ 3๊ฐ
|
| 63 |
+
|
| 64 |
+
### ์์
|
| 65 |
+
[์
๋ ฅ]
|
| 66 |
+
- ์ง๋ฌด: ๋ฐฑ์๋ ๊ฐ๋ฐ
|
| 67 |
+
- ํ์ฌ๋ช
: ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)
|
| 68 |
+
- ๊ฒฝ๋ ฅ ์์ค: ์ ์
|
| 69 |
+
|
| 70 |
+
[์ถ๋ ฅ]
|
| 71 |
+
```json
|
| 72 |
+
{{
|
| 73 |
+
"company_profile": {{
|
| 74 |
+
"name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)",
|
| 75 |
+
"vision_mission": "๊ธ์ต์ ๋ชจ๋ ์๊ฐ์ ์ฝ๊ณ ๊ฐํธํ๊ฒ ๋ง๋๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ ๊ธฐ์ ๊ธฐ๋ฐ ๊ธ์ต ํ์ ๊ธฐ์
์
๋๋ค.",
|
| 76 |
+
"core_values": ["Customer Obsession (๊ณ ๊ฐ ์ค์ฌ)", "Excellence (ํ์ํจ)", "Radical Transparency (๊ทน๋์ ํฌ๋ช
์ฑ)", "Freedom and Responsibility (์์จ๊ณผ ์ฑ
์)"],
|
| 77 |
+
"talent_philosophy": "์ค์ค๋ก ๋ฌธ์ ๋ฅผ ์ ์ํ๊ณ ํด๊ฒฐํ๋ฉฐ, ๋๋ฃ์ ํฌ๋ช
ํ๊ฒ ์ํตํ์ฌ ์ต๊ณ ์ ์ฑ๊ณผ๋ฅผ ๋ง๋๋ ์ธ์ฌ๋ฅผ ์งํฅํฉ๋๋ค.",
|
| 78 |
+
"recent_news_summary": "ํ ์ค๋ฑ
ํฌ, ํ ์ค์ฆ๊ถ ๋ฑ ์ข
ํฉ ๊ธ์ต ํ๋ซํผ์ผ๋ก์ ํ์ฅ์ ๋์ด, ์๋ฐํฐ(MVNO) ์ฌ์
์ง์ถ ๋ฑ ๋น๊ธ์ต ๋ถ์ผ๋ก ์๋น์ค๋ฅผ ๋ค๊ฐํํ๋ฉฐ ์ฌ์ฉ์ ๊ฒฝํ์ ํ์ ํ๊ณ ์์ต๋๋ค.",
|
| 79 |
+
"main_products_services": ["ํ ์ค (๊ฐํธ์ก๊ธ, ๊ฒฐ์ )", "ํ ์ค๋ฑ
ํฌ", "ํ ์ค์ฆ๊ถ", "ํ ์คํ๋ ์ด์ค"]
|
| 80 |
+
}},
|
| 81 |
+
"position_analysis": {{
|
| 82 |
+
"role_summary": "๋์ฉ๋ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๋ ์์ ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๊ธ์ต ์๋น์ค์ ๋ฐฑ์๋ API๋ฅผ ๊ฐ๋ฐํ๊ณ ์ด์ํฉ๋๋ค. ๋ณต์กํ ๊ธ์ต ๋ฌธ์ ๋ฅผ ๊ธฐ์ ๋ก ํด๊ฒฐํ๋ฉฐ ์ต๊ณ ์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ๊ธฐ์ฌํฉ๋๋ค.",
|
| 83 |
+
"required_skills": {{
|
| 84 |
+
"hard": ["Java/Kotlin", "Spring Framework", "RDBMS/NoSQL", "MSA (Microservice Architecture) ์ดํด"],
|
| 85 |
+
"soft": ["๋ฌธ์ ํด๊ฒฐ ๋ฅ๋ ฅ", "ํ์
๋ฐ ์ปค๋ฎค๋์ผ์ด์
", "ํ์ต ๋ฐ ์ฑ์ฅ ์์ง", "๋์ ์์ค์ ์ฑ
์๊ฐ"]
|
| 86 |
+
}},
|
| 87 |
+
"keywords": ["ํํ
ํฌ", "๋์ฉ๋ ํธ๋ํฝ", "MSA", "๊ฒฐ์ ์์คํ
", "API", "๊ธ์ต ํ๋ซํผ"]
|
| 88 |
+
}},
|
| 89 |
+
"industry_context": {{
|
| 90 |
+
"trends": ["๊ฐํธ๊ฒฐ์ ์์ฅ์ ์ง์์ ์ฑ์ฅ", "๋ง์ด๋ฐ์ดํฐ ์ฌ์
ํ์ฑํ", "๋น
ํ
ํฌ ๊ธฐ์
์ ๊ธ์ต์
์ง์ถ ๊ฐ์ํ"],
|
| 91 |
+
"competitors": ["์นด์นด์คํ์ด", "๋ค์ด๋ฒํ์ด๋ธ์
"]
|
| 92 |
+
}}
|
| 93 |
+
}}
|
| 94 |
+
```
|
| 95 |
+
|
| 96 |
+
์ด์ ๋ค์ ์
๋ ฅ์ ๋ํ ์ปจํ
์คํธ ๋ฆฌํฌํธ๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
jd-recommendation/__pycache__/llm_functions.cpython-312.pyc
ADDED
|
Binary file (8.5 kB). View file
|
|
|
jd-recommendation/eval.json
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"jd_recommendation_eval": {
|
| 3 |
+
"task_definition": {
|
| 4 |
+
"description": "Generate a representative job description based on the job title, company name, and experience level. The output should be a concise narrative summarizing key responsibilities and qualifications, suitable for preparing a '์์์'.",
|
| 5 |
+
"input": {
|
| 6 |
+
"job_title": "string",
|
| 7 |
+
"company_name": "string",
|
| 8 |
+
"experience_level": "์ ์
| ๊ฒฝ๋ ฅ | ์ธํด | ๊ธฐํ"
|
| 9 |
+
},
|
| 10 |
+
"output": {
|
| 11 |
+
"recommended_jd": "string"
|
| 12 |
+
}
|
| 13 |
+
},
|
| 14 |
+
"examples": [
|
| 15 |
+
{
|
| 16 |
+
"input": {
|
| 17 |
+
"job_title": "๊ฒฝ์๊ธฐํ",
|
| 18 |
+
"company_name": "์ผ์ฑ์ ์",
|
| 19 |
+
"experience_level": "์ ์
"
|
| 20 |
+
},
|
| 21 |
+
"output": {
|
| 22 |
+
"recommended_jd": "์ ์ฌ ๊ฒฝ์ ๋ชฉํ ๋ฌ์ฑ์ ์ํ ๋ฐ์ดํฐ ๋ถ์, ์์ฅ ๋ฆฌ์์น, ์ฌ์
์ ๋ต ์๋ฆฝ ์ง์ ์
๋ฌด๋ฅผ ์ํํฉ๋๋ค. ์ ๊ท ์ฌ์
๊ธฐํ๋ฅผ ๋ฐ๊ตดํ๊ณ , ๊ฒฝ์์ง์ ์์ฌ๊ฒฐ์ ์ ๋๊ธฐ ์ํ ๋ณด๊ณ ์ ์์ฑ ๋ฐ ๋ฐํ๋ฅผ ๋ด๋นํ๊ฒ ๋ฉ๋๋ค. ๋ฐ์ด๋ ๋ถ์๋ ฅ๊ณผ ๊ธฐํ๋ ฅ์ ๊ฐ์ถ ์ธ์ฌ๋ฅผ ์ฐพ์ต๋๋ค."
|
| 23 |
+
}
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"input": {
|
| 27 |
+
"job_title": "์จ๋ผ์ธ๋ง์ผํ
",
|
| 28 |
+
"company_name": "์ฟ ํก",
|
| 29 |
+
"experience_level": "์ธํด"
|
| 30 |
+
},
|
| 31 |
+
"output": {
|
| 32 |
+
"recommended_jd": "๋์งํธ ๋ง์ผํ
์บ ํ์ธ ๊ธฐํ ๋ฐ ์ด์์ ๋ณด์กฐํ๋ฉฐ, ์์
๋ฏธ๋์ด ์ฑ๋ ๊ด๋ฆฌ, ์ฝํ
์ธ ์ ์, ๊ด๊ณ ์ฑ๊ณผ ๋ฐ์ดํฐ ๋ถ์ ์
๋ฌด๋ฅผ ์ง์ํฉ๋๋ค. ์ต์ ๋ง์ผํ
ํธ๋ ๋๋ฅผ ํ์ตํ๊ณ ์ค์ ์
๋ฌด์ ์ ์ฉํ๋ฉฐ ์ฑ์ฅํ ๊ธฐํ๋ฅผ ์ ๊ณตํฉ๋๋ค."
|
| 33 |
+
}
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
"input": {
|
| 37 |
+
"job_title": "HRM(์ธ์ฌ์ด์)",
|
| 38 |
+
"company_name": "ํ์ด๋ธ",
|
| 39 |
+
"experience_level": "๊ฒฝ๋ ฅ"
|
| 40 |
+
},
|
| 41 |
+
"output": {
|
| 42 |
+
"recommended_jd": "๊ตฌ์ฑ์์ ์ฑ์ฅ๊ณผ ์กฐ์ง ๋ฌธํ ๋ฐ์ ์ ์ํ ์ธ์ฌ ์ด์ ์ ๋ฐ์ ๋ด๋นํฉ๋๋ค. ์ฑ์ฉ, ํ๊ฐ, ๋ณด์, ๋
ธ๋ฌด ๋ฑ HRM ํ๋ก์ธ์ค๋ฅผ ์ฃผ๋์ ์ผ๋ก ๊ฐ์ ํ๊ณ ์คํํ๋ฉฐ, ๊ธ๋ก๋ฒ ์ํฐํ
์ธ๋จผํธ ์ฐ์
์ ๋ง๋ ์ธ์ฌ ์ ๋ต์ ์๋ฆฝํฉ๋๋ค. 3๋
์ด์์ ๊ด๋ จ ๊ฒฝ๋ ฅ์ด ํ์ํฉ๋๋ค."
|
| 43 |
+
}
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
"input": {
|
| 47 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 48 |
+
"company_name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)",
|
| 49 |
+
"experience_level": "์ ์
"
|
| 50 |
+
},
|
| 51 |
+
"output": {
|
| 52 |
+
"recommended_jd": "ํ ์ค ์๋น์ค์ ์์ ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ์๋ฒ, ์ ํ๋ฆฌ์ผ์ด์
, API๋ฅผ ๊ฐ๋ฐํ๊ณ ์ด์ํฉ๋๋ค. ๋์ฉ๋ ํธ๋ํฝ ์ฒ๋ฆฌ ๊ฒฝํ์ ์๊ณ , ๊ธ์ต ์๋น์ค์ ๋ณต์กํ ๋ฌธ์ ๋ฅผ ๊ธฐ์ ๋ก ํด๊ฒฐํ๋ ๋ฐ ๊ธฐ์ฌํฉ๋๋ค. Java/Kotlin, Spring ํ๋ ์์ํฌ์ ๋ํ ์ดํด๊ฐ ํ์ํฉ๋๋ค."
|
| 53 |
+
}
|
| 54 |
+
},
|
| 55 |
+
{
|
| 56 |
+
"input": {
|
| 57 |
+
"job_title": "ํด์ธ์์
",
|
| 58 |
+
"company_name": "HMM (์์ด์น์ ์ )",
|
| 59 |
+
"experience_level": "๊ฒฝ๋ ฅ"
|
| 60 |
+
},
|
| 61 |
+
"output": {
|
| 62 |
+
"recommended_jd": "๊ธ๋ก๋ฒ ํด์ด ์์ฅ์์ ์ ๊ท ๊ณ ๊ฐ์ฌ๋ฅผ ๋ฐ๊ตดํ๊ณ ๊ธฐ์กด ๊ณ ๊ฐ ๊ด๊ณ๋ฅผ ๊ด๋ฆฌํ๋ฉฐ ์์
๋ชฉํ๋ฅผ ๋ฌ์ฑํฉ๋๋ค. ํด์ธ ๋ฒ์ธ ๋ฐ ํํธ๋์ฌ์์ ํ๋ ฅ์ ํตํด ์์
์ ๋ต์ ์๋ฆฝํ๊ณ , ์ด์ ํ์ ๋ฐ ๊ณ์ฝ ์ฒด๊ฒฐ์ ์ฃผ๋ํฉ๋๋ค. ๋น์ฆ๋์ค ์์ด ๋ฅํต ๋ฐ ๋์ข
์
๊ณ ๊ฒฝ๋ ฅ์๋ฅผ ์ฐ๋ํฉ๋๋ค."
|
| 63 |
+
}
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"input": {
|
| 67 |
+
"job_title": "์จ๋ผ์ธ๋ง์ผํ
",
|
| 68 |
+
"company_name": "์๋ชจ๋ ํผ์ํฝ",
|
| 69 |
+
"experience_level": "๊ฒฝ๋ ฅ"
|
| 70 |
+
},
|
| 71 |
+
"output": {
|
| 72 |
+
"recommended_jd": "์์ฌ ๋ธ๋๋์ ๋์งํธ ์ฑ๋(์์ฌ๋ชฐ, ์์
๋ฏธ๋์ด, ์ด์ปค๋จธ์ค) ๋ง์ผํ
์ ๋ต์ ์๋ฆฝํ๊ณ ์คํํฉ๋๋ค. ํผํฌ๋จผ์ค ๋ง์ผํ
, CRM, ๋ฐ์ดํฐ ๊ธฐ๋ฐ์ ๊ณ ๊ฐ ๋ถ์์ ํตํด ๋ธ๋๋ ์ธ์ง๋ ๋ฐ ๋งค์ถ ์ฆ๋์ ๊ธฐ์ฌํฉ๋๋ค. ๋ทฐํฐ/์๋น์ฌ ์ฐ์
๋ง์ผํ
๊ฒฝ๋ ฅ 5๋
์ด์์ ์ฐพ์ต๋๋ค."
|
| 73 |
+
}
|
| 74 |
+
},
|
| 75 |
+
{
|
| 76 |
+
"input": {
|
| 77 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 78 |
+
"company_name": "๋ฅ์จ",
|
| 79 |
+
"experience_level": "์ธํด"
|
| 80 |
+
},
|
| 81 |
+
"output": {
|
| 82 |
+
"recommended_jd": "๋ผ์ด๋ธ ๊ฒ์ ์๋น์ค์ ๋ฐฑ์๋ ์์คํ
๊ฐ๋ฐ ๋ฐ ์ ์ง๋ณด์ ์
๋ฌด๋ฅผ ์ง์ํฉ๋๋ค. ์ ๋ฐฐ ๊ฐ๋ฐ์๋ค์ ๋ฉํ ๋ง ํ์ ๊ฒ์ ์๋ฒ ์ธํ๋ผ๋ฅผ ์ดํดํ๊ณ , ๊ฐ์ข
ํด ๊ฐ๋ฐ์ ์ฐธ์ฌํ๋ฉฐ ์ค๋ฌด ๊ฒฝํ์ ์์ต๋๋ค. C++ ๋๋ Java์ ๋ํ ๊ธฐ๋ณธ ์ง์์ด ํ์ํฉ๋๋ค."
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
{
|
| 86 |
+
"input": {
|
| 87 |
+
"job_title": "๊ฒฝ์๊ธฐํ",
|
| 88 |
+
"company_name": "ํ๋๊ฑด์ค",
|
| 89 |
+
"experience_level": "๊ธฐํ"
|
| 90 |
+
},
|
| 91 |
+
"output": {
|
| 92 |
+
"recommended_jd": "ํน์ ํด์ธ ๊ฑด์ค ํ๋ก์ ํธ์ ์ฌ์
์ฑ ๊ฒํ ๋ฐ ๊ธฐํ ์
๋ฌด๋ฅผ ๋ด๋นํ ๊ณ์ฝ์ง ์ ๋ฌธ๊ฐ๋ฅผ ๋ชจ์งํฉ๋๋ค. ํ๋ก์ ํธ ์์ฃผ๋ฅผ ์ํ ์์ฅ ๋ถ์, ๋ฆฌ์คํฌ ๊ด๋ฆฌ, ์์ฐ ์๋ฆฝ ์
๋ฌด๋ฅผ ์ํํ๋ฉฐ, ๊ด๋ จ ๊ฒฝ๋ ฅ 3๋
์ด์ ๋ณด์ ๋ฐ ์ ๊ด ์๊ฒฉ์ฆ ์์ง์๋ฅผ ์ฐ๋ํฉ๋๋ค."
|
| 93 |
+
}
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"input": {
|
| 97 |
+
"job_title": "HRM(์ธ์ฌ์ด์)",
|
| 98 |
+
"company_name": "์ ํ์ํ",
|
| 99 |
+
"experience_level": "์ ์
"
|
| 100 |
+
},
|
| 101 |
+
"output": {
|
| 102 |
+
"recommended_jd": "์ํ์ ์ธ์ ์์ ๊ด๋ฆฌ ๋ฐ ์ด์ ์
๋ฌด๋ฅผ ์ํํฉ๋๋ค. ์ ์
ํ์ ์ฑ์ฉ ๋ฐ ๊ต์ก ํ๋ก๊ทธ๋จ ๊ธฐํ, ๊ธ์ฌ ๋ฐ ๋ณต๋ฆฌํ์ ๊ด๋ฆฌ, ์กฐ์ง๋ฌธํ ํ์ฑํ ํ๋์ ์ง์ํ๋ฉฐ ๊ธ์ต ์ธ์ฌ๋ก ์ฑ์ฅํ๊ฒ ๋ฉ๋๋ค."
|
| 103 |
+
}
|
| 104 |
+
},
|
| 105 |
+
{
|
| 106 |
+
"input": {
|
| 107 |
+
"job_title": "ํด์ธ์์
",
|
| 108 |
+
"company_name": "์ผ์ฑ๋ฐ์ด์ค๋ก์ง์ค",
|
| 109 |
+
"experience_level": "์ธํด"
|
| 110 |
+
},
|
| 111 |
+
"output": {
|
| 112 |
+
"recommended_jd": "๊ธ๋ก๋ฒ ์ ์ฝ/๋ฐ์ด์ค ๊ณ ๊ฐ์ฌ ๋์ ์์
ํ๋์ ์ง์ํฉ๋๋ค. ์์ฅ ์๋ฃ ์กฐ์ฌ, ์ ์ฌ ๊ณ ๊ฐ ๋ฆฌ์คํธ์
, ์ ์์ ์์ฑ ๋ณด์กฐ ๋ฐ ๋ด๋ถ ์ปค๋ฎค๋์ผ์ด์
์
๋ฌด๋ฅผ ํตํด ๋ฐ์ด์ค ์ฐ์
์ B2B ์์
ํ๋ก์ธ์ค๋ฅผ ๊ฒฝํํฉ๋๋ค."
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
]
|
| 116 |
+
}
|
| 117 |
+
}
|
jd-recommendation/llm_functions.py
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import re
|
| 4 |
+
import yaml
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
|
| 7 |
+
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
| 8 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 9 |
+
|
| 10 |
+
# ํ๋กฌํํธ ํ
ํ๋ฆฟ ๋ก๋
|
| 11 |
+
import os
|
| 12 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 13 |
+
prompt_path = os.path.join(current_dir, 'prompt.yaml')
|
| 14 |
+
with open(prompt_path, 'r', encoding='utf-8') as f:
|
| 15 |
+
prompt_data = yaml.safe_load(f)
|
| 16 |
+
prompt_template = prompt_data['prompt']
|
| 17 |
+
|
| 18 |
+
def parse_jd_recommendation(content):
|
| 19 |
+
"""
|
| 20 |
+
AI ์๋ต์์ ์ง๋ฌด๊ธฐ์ ์ JSON์ ํ์ฑํ๋ ํจ์
|
| 21 |
+
"""
|
| 22 |
+
try:
|
| 23 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ๊ธธ์ด: {len(content)}")
|
| 24 |
+
print(f"ํ์ฑํ ์ปจํ
์ธ ์ฒซ 200์: {repr(content[:200])}")
|
| 25 |
+
|
| 26 |
+
# ํ
์คํธ ์ ์ฒ๋ฆฌ
|
| 27 |
+
cleaned_content = content.strip()
|
| 28 |
+
|
| 29 |
+
# 1. JSON ์ฝ๋ ๋ธ๋ก ์ฐพ๊ธฐ (```json ... ``` ํ์)
|
| 30 |
+
json_patterns = [
|
| 31 |
+
r'```json\s*(\{.*?\})\s*```',
|
| 32 |
+
r'```\s*(\{.*?\})\s*```',
|
| 33 |
+
r'```json\s*(.*?)\s*```',
|
| 34 |
+
r'```\s*(.*?)\s*```'
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
for pattern in json_patterns:
|
| 38 |
+
json_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 39 |
+
if json_match:
|
| 40 |
+
json_str = json_match.group(1).strip()
|
| 41 |
+
print(f"JSON ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 42 |
+
|
| 43 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 44 |
+
json_str = re.sub(r'\n\s*', ' ', json_str)
|
| 45 |
+
json_str = re.sub(r',\s*}', '}', json_str)
|
| 46 |
+
|
| 47 |
+
try:
|
| 48 |
+
parsed_json = json.loads(json_str)
|
| 49 |
+
if isinstance(parsed_json, dict) and 'recommended_jd' in parsed_json:
|
| 50 |
+
return parsed_json['recommended_jd']
|
| 51 |
+
except json.JSONDecodeError as e:
|
| 52 |
+
print(f"JSON ๋ธ๋ก ํ์ฑ ์คํจ: {e}")
|
| 53 |
+
|
| 54 |
+
# 2. ์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ JSON ์ฐพ๊ธฐ
|
| 55 |
+
brace_patterns = [
|
| 56 |
+
r'\{.*?\}'
|
| 57 |
+
]
|
| 58 |
+
|
| 59 |
+
for pattern in brace_patterns:
|
| 60 |
+
brace_match = re.search(pattern, cleaned_content, re.DOTALL)
|
| 61 |
+
if brace_match:
|
| 62 |
+
json_str = brace_match.group(0).strip()
|
| 63 |
+
print(f"์ค๊ดํธ ๋ธ๋ก ๋ฐ๊ฒฌ: {repr(json_str[:100])}")
|
| 64 |
+
|
| 65 |
+
# JSON ๋ฌธ์์ด ์ ๋ฆฌ
|
| 66 |
+
json_str = re.sub(r'\n\s*', ' ', json_str)
|
| 67 |
+
json_str = re.sub(r',\s*}', '}', json_str)
|
| 68 |
+
|
| 69 |
+
try:
|
| 70 |
+
parsed_json = json.loads(json_str)
|
| 71 |
+
if isinstance(parsed_json, dict) and 'recommended_jd' in parsed_json:
|
| 72 |
+
return parsed_json['recommended_jd']
|
| 73 |
+
except json.JSONDecodeError as e:
|
| 74 |
+
print(f"์ค๊ดํธ ๋ธ๋ก ํ์ฑ ์คํจ: {e}")
|
| 75 |
+
|
| 76 |
+
# 3. ์ ์ฒด ํ
์คํธ๋ฅผ JSON์ผ๋ก ํ์ฑ ์๋
|
| 77 |
+
try:
|
| 78 |
+
# ์ฝ๋ ๋ธ๋ก ๋ง์ปค ์ ๊ฑฐ
|
| 79 |
+
if cleaned_content.startswith('```'):
|
| 80 |
+
lines = cleaned_content.split('\n')
|
| 81 |
+
start_idx = 1 if lines[0].startswith('```') else 0
|
| 82 |
+
end_idx = len(lines)
|
| 83 |
+
for i in range(len(lines)-1, -1, -1):
|
| 84 |
+
if lines[i].strip() == '```':
|
| 85 |
+
end_idx = i
|
| 86 |
+
break
|
| 87 |
+
cleaned_content = '\n'.join(lines[start_idx:end_idx])
|
| 88 |
+
|
| 89 |
+
cleaned_content = cleaned_content.strip()
|
| 90 |
+
parsed_json = json.loads(cleaned_content)
|
| 91 |
+
if isinstance(parsed_json, dict) and 'recommended_jd' in parsed_json:
|
| 92 |
+
return parsed_json['recommended_jd']
|
| 93 |
+
except json.JSONDecodeError as e:
|
| 94 |
+
print(f"์ ์ฒด JSON ํ์ฑ ์คํจ: {e}")
|
| 95 |
+
|
| 96 |
+
# 4. ์ง์ ํ
์คํธ์์ JD ๋ด์ฉ ์ถ์ถ ์๋
|
| 97 |
+
print("์ง์ ํ
์คํธ์์ JD ๋ด์ฉ ์ถ์ถ ์๋")
|
| 98 |
+
|
| 99 |
+
# "recommended_jd" ํค์๋ ๋ค์ ๋ด์ฉ ์ฐพ๊ธฐ
|
| 100 |
+
jd_patterns = [
|
| 101 |
+
r'"recommended_jd"\s*:\s*"([^"]+)"',
|
| 102 |
+
r'recommended_jd["\s]*:\s*["\s]*([^"]+)["\s]*',
|
| 103 |
+
r'์ง๋ฌด๊ธฐ์ ์[:\s]*([^\n]+)',
|
| 104 |
+
]
|
| 105 |
+
|
| 106 |
+
for pattern in jd_patterns:
|
| 107 |
+
match = re.search(pattern, cleaned_content, re.IGNORECASE)
|
| 108 |
+
if match:
|
| 109 |
+
jd_content = match.group(1).strip()
|
| 110 |
+
if len(jd_content) > 10: # ์ต์ ๊ธธ์ด ์ฒดํฌ
|
| 111 |
+
return jd_content
|
| 112 |
+
|
| 113 |
+
# 5. ์ตํ์ ์๋จ: ์ ์ฒด ํ
์คํธ๋ฅผ JD๋ก ๊ฐ์ฃผ (JSON ๋ง์ปค ์ ๊ฑฐ)
|
| 114 |
+
print("์ ์ฒด ํ
์คํธ๋ฅผ JD๋ก ๊ฐ์ฃผ")
|
| 115 |
+
cleaned_text = re.sub(r'```[a-z]*\s*', '', cleaned_content)
|
| 116 |
+
cleaned_text = re.sub(r'```\s*', '', cleaned_text)
|
| 117 |
+
cleaned_text = re.sub(r'\{.*?\}', '', cleaned_text, flags=re.DOTALL)
|
| 118 |
+
cleaned_text = cleaned_text.strip()
|
| 119 |
+
|
| 120 |
+
if len(cleaned_text) > 20:
|
| 121 |
+
return cleaned_text
|
| 122 |
+
|
| 123 |
+
return "์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค."
|
| 124 |
+
|
| 125 |
+
except Exception as e:
|
| 126 |
+
print(f"JD ํ์ฑ ์ ์ฒด ์ค๋ฅ: {e}")
|
| 127 |
+
print(f"ํ์ฑ ์คํจํ ์ปจํ
์ธ : {repr(content)}")
|
| 128 |
+
return f"ํ์ฑ ์ค๋ฅ: {str(e)}"
|
| 129 |
+
|
| 130 |
+
def generate_jd_recommendation(job_title, company_name, experience_level):
|
| 131 |
+
"""
|
| 132 |
+
OpenAI API๋ฅผ ์ฌ์ฉํ์ฌ ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ๋ ํจ์
|
| 133 |
+
"""
|
| 134 |
+
try:
|
| 135 |
+
if not job_title or not company_name or not experience_level:
|
| 136 |
+
return "์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ๋ชจ๋ ์
๋ ฅํด์ฃผ์ธ์.", ""
|
| 137 |
+
|
| 138 |
+
# ํ๋กฌํํธ ์์ฑ
|
| 139 |
+
prompt = prompt_template.format(
|
| 140 |
+
job_title=job_title,
|
| 141 |
+
company_name=company_name,
|
| 142 |
+
experience_level=experience_level
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
# OpenAI API ํธ์ถ
|
| 146 |
+
response = client.chat.completions.create(
|
| 147 |
+
model="gpt-4o",
|
| 148 |
+
messages=[
|
| 149 |
+
{"role": "system", "content": "๋น์ ์ ์ฑ์ฉ ๊ณต๊ณ ์์ฑ ์ ๋ฌธ๊ฐ์
๋๋ค. ์ ํํ JSON ํ์์ผ๋ก ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์ ๊ณตํด์ฃผ์ธ์."},
|
| 150 |
+
{"role": "user", "content": prompt}
|
| 151 |
+
],
|
| 152 |
+
temperature=0.3
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
content = response.choices[0].message.content
|
| 156 |
+
print(f"=== AI ์๋ต ์๋ณธ ===")
|
| 157 |
+
print(content)
|
| 158 |
+
print(f"=== AI ์๋ต ๋ ===")
|
| 159 |
+
|
| 160 |
+
jd_content = parse_jd_recommendation(content)
|
| 161 |
+
|
| 162 |
+
if not jd_content or jd_content == "์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.":
|
| 163 |
+
return "์ง๋ฌด๊ธฐ์ ์ ์์ฑ์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.", ""
|
| 164 |
+
|
| 165 |
+
# ๊ฒฐ๊ณผ ํฌ๋งทํ
|
| 166 |
+
result = f"""## ๐ {company_name} - {job_title} ์ง๋ฌด๊ธฐ์ ์
|
| 167 |
+
|
| 168 |
+
### ๐ผ **์ถ์ฒ ์ง๋ฌด๊ธฐ์ ์**
|
| 169 |
+
|
| 170 |
+
{jd_content}
|
| 171 |
+
|
| 172 |
+
---
|
| 173 |
+
|
| 174 |
+
### ๐ **์ง๋ฌด ์ ๋ณด ์์ฝ**
|
| 175 |
+
|
| 176 |
+
**๐ข ํ์ฌ:** {company_name}
|
| 177 |
+
**๐ผ ์ง๋ฌด:** {job_title}
|
| 178 |
+
**๐ ๊ฒฝ๋ ฅ:** {experience_level}
|
| 179 |
+
|
| 180 |
+
### ๐ก **์์์ ์์ฑ ํ**
|
| 181 |
+
|
| 182 |
+
์ ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ค์ ์ฌํญ์ ์์์์ ๋ฐ์ํด๋ณด์ธ์:
|
| 183 |
+
|
| 184 |
+
1. **ํต์ฌ ์
๋ฌด**: ์ธ๊ธ๋ ์ฃผ์ ์
๋ฌด์ ๊ด๋ จ๋ ๊ฒฝํ์ด๋ ์ญ๋์ ๊ฐ์กฐ
|
| 185 |
+
2. **์๊ตฌ ์คํฌ**: ํ์ํ ๊ธฐ์ ์ด๋ ๋ฅ๋ ฅ์ ๋ํ ๋ณธ์ธ์ ์ค๋น๋๋ฅผ ์ดํ
|
| 186 |
+
3. **ํ์ฌ ํน์ฑ**: ํด๋น ํ์ฌ์ ์ฌ์
์์ญ๊ณผ ์ฐ๊ด๋ ๊ด์ฌ์ฌ๋ ๊ฒฝํ์ ์ธ๊ธ
|
| 187 |
+
4. **์ฑ์ฅ ์์ง**: ์ง๋ฌด์์ ์๊ตฌํ๋ ์ฑ์ฅ ๊ฐ๋ฅ์ฑ๊ณผ ํ์ต ์์ง๋ฅผ ํํ
|
| 188 |
+
|
| 189 |
+
---
|
| 190 |
+
|
| 191 |
+
*๋ณธ ์ง๋ฌด๊ธฐ์ ์๋ AI๊ฐ ์์ฑํ ๊ฒ์ผ๋ก, ์ค์ ์ฑ์ฉ๊ณต๊ณ ์ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์์์ ์์ฑ ์ ์ฐธ๊ณ ์ฉ์ผ๋ก ํ์ฉํ์ธ์.*
|
| 192 |
+
"""
|
| 193 |
+
|
| 194 |
+
return result, jd_content
|
| 195 |
+
|
| 196 |
+
except Exception as e:
|
| 197 |
+
error_msg = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 198 |
+
|
| 199 |
+
์ง๋ฌด๊ธฐ์ ์ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 200 |
+
|
| 201 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 202 |
+
|
| 203 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 204 |
+
"""
|
| 205 |
+
return error_msg, ""
|
jd-recommendation/main.py
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from llm_functions import generate_jd_recommendation
|
| 3 |
+
|
| 4 |
+
# ์์ ๋ฐ์ดํฐ
|
| 5 |
+
example_companies = ["์ผ์ฑ์ ์", "์ฟ ํก", "ํ์ด๋ธ", "ํ ์ค", "ํ๋๊ฑด์ค", "์ ํ์ํ", "๋ฅ์จ", "์๋ชจ๋ ํผ์ํฝ", "์ผ์ฑ๋ฐ์ด์ค๋ก์ง์ค", "HMM"]
|
| 6 |
+
example_jobs = ["๊ฒฝ์๊ธฐํ", "์จ๋ผ์ธ๋ง์ผํ
", "HRM(์ธ์ฌ์ด์)", "๋ฐฑ์๋ ๊ฐ๋ฐ", "ํด์ธ์์
", "๋ฐ์ดํฐ ๋ถ์", "์์
", "๋ง์ผํ
", "๊ธฐํ", "๊ฐ๋ฐ"]
|
| 7 |
+
experience_levels = ["์ ์
", "๊ฒฝ๋ ฅ", "์ธํด", "๊ธฐํ"]
|
| 8 |
+
|
| 9 |
+
def create_jd_card(jd_content):
|
| 10 |
+
"""
|
| 11 |
+
์ง๋ฌด๊ธฐ์ ์๋ฅผ ์นด๋ ํํ๋ก ํ์ํ๋ HTML ์์ฑ
|
| 12 |
+
"""
|
| 13 |
+
if not jd_content:
|
| 14 |
+
return "<div style='text-align: center; color: #6B7280; padding: 20px;'>์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํด์ฃผ์ธ์</div>"
|
| 15 |
+
|
| 16 |
+
# ๋ฌธ์ฅ ๋จ์๋ก ๋ถ๋ฆฌํ์ฌ ๋ ์ฝ๊ธฐ ์ฝ๊ฒ ํ์
|
| 17 |
+
sentences = jd_content.split('. ')
|
| 18 |
+
formatted_content = ""
|
| 19 |
+
|
| 20 |
+
for i, sentence in enumerate(sentences):
|
| 21 |
+
if sentence.strip():
|
| 22 |
+
# ๋ง์ง๋ง ๋ฌธ์ฅ์ด ์๋๋ฉด ๋ง์นจํ ์ถ๊ฐ
|
| 23 |
+
if i < len(sentences) - 1 and not sentence.endswith('.'):
|
| 24 |
+
sentence += '.'
|
| 25 |
+
formatted_content += f"<p style='margin: 10px 0; line-height: 1.6;'>{sentence.strip()}</p>"
|
| 26 |
+
|
| 27 |
+
return f"""
|
| 28 |
+
<div style="
|
| 29 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 30 |
+
color: white;
|
| 31 |
+
border-radius: 15px;
|
| 32 |
+
padding: 25px;
|
| 33 |
+
margin: 15px 0;
|
| 34 |
+
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
|
| 35 |
+
border: 1px solid rgba(255,255,255,0.1);
|
| 36 |
+
">
|
| 37 |
+
<div style="
|
| 38 |
+
display: flex;
|
| 39 |
+
align-items: center;
|
| 40 |
+
margin-bottom: 20px;
|
| 41 |
+
padding-bottom: 15px;
|
| 42 |
+
border-bottom: 1px solid rgba(255,255,255,0.2);
|
| 43 |
+
">
|
| 44 |
+
<div style="
|
| 45 |
+
background: rgba(255,255,255,0.2);
|
| 46 |
+
border-radius: 50%;
|
| 47 |
+
width: 40px;
|
| 48 |
+
height: 40px;
|
| 49 |
+
display: flex;
|
| 50 |
+
align-items: center;
|
| 51 |
+
justify-content: center;
|
| 52 |
+
margin-right: 15px;
|
| 53 |
+
font-size: 18px;
|
| 54 |
+
">๐</div>
|
| 55 |
+
<h3 style="margin: 0; font-size: 20px; font-weight: bold;">์ถ์ฒ ์ง๋ฌด๊ธฐ์ ์</h3>
|
| 56 |
+
</div>
|
| 57 |
+
|
| 58 |
+
<div style="
|
| 59 |
+
background: rgba(255,255,255,0.1);
|
| 60 |
+
border-radius: 12px;
|
| 61 |
+
padding: 20px;
|
| 62 |
+
backdrop-filter: blur(10px);
|
| 63 |
+
">
|
| 64 |
+
{formatted_content}
|
| 65 |
+
</div>
|
| 66 |
+
|
| 67 |
+
<div style="
|
| 68 |
+
margin-top: 20px;
|
| 69 |
+
padding-top: 15px;
|
| 70 |
+
border-top: 1px solid rgba(255,255,255,0.2);
|
| 71 |
+
font-size: 14px;
|
| 72 |
+
opacity: 0.8;
|
| 73 |
+
text-align: center;
|
| 74 |
+
">
|
| 75 |
+
๐ก ์ด ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ง์ถคํ ์๊ธฐ์๊ฐ์๋ฅผ ์์ฑํด๋ณด์ธ์
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
"""
|
| 79 |
+
|
| 80 |
+
def create_tips_card():
|
| 81 |
+
"""
|
| 82 |
+
์์์ ์์ฑ ํ ์นด๋ ์์ฑ
|
| 83 |
+
"""
|
| 84 |
+
return """
|
| 85 |
+
<div style="
|
| 86 |
+
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
|
| 87 |
+
color: white;
|
| 88 |
+
border-radius: 15px;
|
| 89 |
+
padding: 25px;
|
| 90 |
+
margin: 15px 0;
|
| 91 |
+
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
|
| 92 |
+
">
|
| 93 |
+
<h3 style="margin: 0 0 20px 0; font-size: 18px; display: flex; align-items: center;">
|
| 94 |
+
<span style="margin-right: 10px;">๐ก</span>
|
| 95 |
+
์์์ ์์ฑ ํ
|
| 96 |
+
</h3>
|
| 97 |
+
|
| 98 |
+
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 20px;">
|
| 99 |
+
<div style="margin-bottom: 15px;">
|
| 100 |
+
<strong>1. ํต์ฌ ์
๋ฌด ๋งค์นญ</strong><br>
|
| 101 |
+
<span style="font-size: 14px; opacity: 0.9;">์ง๋ฌด๊ธฐ์ ์์ ์ฃผ์ ์
๋ฌด์ ๊ด๋ จ๋ ๊ฒฝํ์ ๊ตฌ์ฒด์ ์ผ๋ก ์์ </span>
|
| 102 |
+
</div>
|
| 103 |
+
|
| 104 |
+
<div style="margin-bottom: 15px;">
|
| 105 |
+
<strong>2. ์๊ตฌ ์ญ๋ ์ดํ</strong><br>
|
| 106 |
+
<span style="font-size: 14px; opacity: 0.9;">์ธ๊ธ๋ ์คํฌ๊ณผ ์ญ๋์ ๋ํ ๋ณธ์ธ์ ์ค๋น๋๋ฅผ ์ฆ๋ช
</span>
|
| 107 |
+
</div>
|
| 108 |
+
|
| 109 |
+
<div style="margin-bottom: 15px;">
|
| 110 |
+
<strong>3. ํ์ฌ ํน์ฑ ๋ฐ์</strong><br>
|
| 111 |
+
<span style="font-size: 14px; opacity: 0.9;">ํด๋น ํ์ฌ์ ์ฌ์
์์ญ๊ณผ ์ฐ๊ด๋ ๊ด์ฌ์ฌ๋ ๊ฒฝํ์ ํฌํจ</span>
|
| 112 |
+
</div>
|
| 113 |
+
|
| 114 |
+
<div>
|
| 115 |
+
<strong>4. ์ฑ์ฅ ์์ง ํํ</strong><br>
|
| 116 |
+
<span style="font-size: 14px; opacity: 0.9;">์ง๋ฌด์์ ์๊ตฌํ๋ ์ฑ์ฅ ๊ฐ๋ฅ์ฑ๊ณผ ํ์ต ์์ง๋ฅผ ๊ฐ์กฐ</span>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
</div>
|
| 120 |
+
"""
|
| 121 |
+
|
| 122 |
+
def process_jd_generation(job_title, company_name, experience_level):
|
| 123 |
+
"""
|
| 124 |
+
์ง๋ฌด๊ธฐ์ ์ ์์ฑ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๊ณ UI์ ํ์ํ ํํ๋ก ๋ณํํ๋ ํจ์
|
| 125 |
+
"""
|
| 126 |
+
try:
|
| 127 |
+
content, jd_content = generate_jd_recommendation(job_title, company_name, experience_level)
|
| 128 |
+
jd_card = create_jd_card(jd_content)
|
| 129 |
+
tips_card = create_tips_card()
|
| 130 |
+
return content, jd_card + tips_card
|
| 131 |
+
except Exception as e:
|
| 132 |
+
error_content = f"""## โ ์ค๋ฅ ๋ฐ์
|
| 133 |
+
|
| 134 |
+
์ง๋ฌด๊ธฐ์ ์ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
|
| 135 |
+
|
| 136 |
+
**์ค๋ฅ ๋ด์ฉ:** {str(e)}
|
| 137 |
+
|
| 138 |
+
๋ค์ ์๋ํด์ฃผ์ธ์.
|
| 139 |
+
"""
|
| 140 |
+
error_card = create_jd_card("")
|
| 141 |
+
return error_content, error_card
|
| 142 |
+
|
| 143 |
+
def create_interface():
|
| 144 |
+
"""
|
| 145 |
+
Gradio ์ธํฐํ์ด์ค ์์ฑ
|
| 146 |
+
"""
|
| 147 |
+
with gr.Blocks(
|
| 148 |
+
title="๐ AI ์ง๋ฌด๊ธฐ์ ์ ์์ฑ๊ธฐ",
|
| 149 |
+
theme=gr.themes.Soft(),
|
| 150 |
+
css="""
|
| 151 |
+
.main-header {
|
| 152 |
+
text-align: center;
|
| 153 |
+
padding: 20px;
|
| 154 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 155 |
+
color: white;
|
| 156 |
+
border-radius: 10px;
|
| 157 |
+
margin-bottom: 20px;
|
| 158 |
+
}
|
| 159 |
+
.input-section {
|
| 160 |
+
background-color: #f8f9fa;
|
| 161 |
+
padding: 20px;
|
| 162 |
+
border-radius: 8px;
|
| 163 |
+
margin: 10px 0;
|
| 164 |
+
}
|
| 165 |
+
.example-section {
|
| 166 |
+
background-color: #f0f9ff;
|
| 167 |
+
padding: 15px;
|
| 168 |
+
border-radius: 8px;
|
| 169 |
+
margin: 10px 0;
|
| 170 |
+
}
|
| 171 |
+
"""
|
| 172 |
+
) as demo:
|
| 173 |
+
|
| 174 |
+
# ํค๋
|
| 175 |
+
gr.HTML("""
|
| 176 |
+
<div class="main-header">
|
| 177 |
+
<h1>๐ AI ์ง๋ฌด๊ธฐ์ ์ ์์ฑ๊ธฐ</h1>
|
| 178 |
+
<p>๋ง์ถคํ ์ง๋ฌด๊ธฐ์ ์๋ก ์๋ฒฝํ ์๊ธฐ์๊ฐ์๋ฅผ ์ค๋นํ์ธ์</p>
|
| 179 |
+
</div>
|
| 180 |
+
""")
|
| 181 |
+
|
| 182 |
+
# ์ค๋ช
|
| 183 |
+
gr.Markdown("""
|
| 184 |
+
### ๐ **์ฌ์ฉ ๋ฐฉ๋ฒ**
|
| 185 |
+
1. **์ง๋ฌด**: ์ง์ํ๊ณ ์ ํ๋ ์ง๋ฌด๋ฅผ ์
๋ ฅํ์ธ์
|
| 186 |
+
2. **ํ์ฌ๋ช
**: ์ง์ ํ์ฌ๋ช
์ ์
๋ ฅํ์ธ์
|
| 187 |
+
3. **๊ฒฝ๋ ฅ ์์ค**: ์ ์
/๊ฒฝ๋ ฅ/์ธํด/๊ธฐํ ์ค ์ ํํ์ธ์
|
| 188 |
+
4. **์์ฑ**: '์ง๋ฌด๊ธฐ์ ์ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ์ธ์
|
| 189 |
+
|
| 190 |
+
โจ **ํน์ง**: ์ค์ ์ฑ์ฉ๊ณต๊ณ ์คํ์ผ์ ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํ์ฌ ์์์ ์์ฑ์ ํ์ํ ํต์ฌ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
|
| 191 |
+
""")
|
| 192 |
+
|
| 193 |
+
with gr.Row():
|
| 194 |
+
with gr.Column(scale=2):
|
| 195 |
+
# ์
๋ ฅ ์น์
|
| 196 |
+
gr.HTML('<div class="input-section">')
|
| 197 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 198 |
+
|
| 199 |
+
with gr.Row():
|
| 200 |
+
job_input = gr.Textbox(
|
| 201 |
+
label="๐ผ ์ง๋ฌด",
|
| 202 |
+
placeholder="์: ๊ฒฝ์๊ธฐํ, ๋ฐฑ์๋ ๊ฐ๋ฐ, ์จ๋ผ์ธ๋ง์ผํ
๋ฑ",
|
| 203 |
+
value="",
|
| 204 |
+
scale=1
|
| 205 |
+
)
|
| 206 |
+
|
| 207 |
+
company_input = gr.Textbox(
|
| 208 |
+
label="๐ข ํ์ฌ๋ช
",
|
| 209 |
+
placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ",
|
| 210 |
+
value="",
|
| 211 |
+
scale=1
|
| 212 |
+
)
|
| 213 |
+
|
| 214 |
+
experience_input = gr.Dropdown(
|
| 215 |
+
label="๐ ๊ฒฝ๋ ฅ ์์ค",
|
| 216 |
+
choices=experience_levels,
|
| 217 |
+
value="์ ์
",
|
| 218 |
+
interactive=True
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
generate_btn = gr.Button(
|
| 222 |
+
"๐ ์ง๋ฌด๊ธฐ์ ์ ์์ฑ",
|
| 223 |
+
variant="primary",
|
| 224 |
+
size="lg"
|
| 225 |
+
)
|
| 226 |
+
gr.HTML('</div>')
|
| 227 |
+
|
| 228 |
+
with gr.Column(scale=1):
|
| 229 |
+
# ์์ ๋ฐ ๊ฐ์ด๋
|
| 230 |
+
gr.HTML('<div class="example-section">')
|
| 231 |
+
gr.Markdown("### ๐ก **์์ ํ์ฌ**")
|
| 232 |
+
|
| 233 |
+
company_rows = [example_companies[i:i+2] for i in range(0, len(example_companies), 2)]
|
| 234 |
+
for row in company_rows:
|
| 235 |
+
with gr.Row():
|
| 236 |
+
for company in row:
|
| 237 |
+
example_btn = gr.Button(
|
| 238 |
+
company,
|
| 239 |
+
size="sm",
|
| 240 |
+
variant="secondary",
|
| 241 |
+
scale=1
|
| 242 |
+
)
|
| 243 |
+
example_btn.click(
|
| 244 |
+
fn=lambda x=company: x,
|
| 245 |
+
outputs=company_input
|
| 246 |
+
)
|
| 247 |
+
|
| 248 |
+
gr.Markdown("### ๐ผ **์์ ์ง๋ฌด**")
|
| 249 |
+
|
| 250 |
+
job_rows = [example_jobs[i:i+2] for i in range(0, len(example_jobs), 2)]
|
| 251 |
+
for row in job_rows:
|
| 252 |
+
with gr.Row():
|
| 253 |
+
for job in row:
|
| 254 |
+
job_btn = gr.Button(
|
| 255 |
+
job,
|
| 256 |
+
size="sm",
|
| 257 |
+
variant="secondary",
|
| 258 |
+
scale=1
|
| 259 |
+
)
|
| 260 |
+
job_btn.click(
|
| 261 |
+
fn=lambda x=job: x,
|
| 262 |
+
outputs=job_input
|
| 263 |
+
)
|
| 264 |
+
|
| 265 |
+
gr.Markdown("### ๐ **๊ฒฝ๋ ฅ ์์ค**")
|
| 266 |
+
with gr.Row():
|
| 267 |
+
for level in experience_levels:
|
| 268 |
+
level_btn = gr.Button(
|
| 269 |
+
level,
|
| 270 |
+
size="sm",
|
| 271 |
+
variant="secondary",
|
| 272 |
+
scale=1
|
| 273 |
+
)
|
| 274 |
+
level_btn.click(
|
| 275 |
+
fn=lambda x=level: x,
|
| 276 |
+
outputs=experience_input
|
| 277 |
+
)
|
| 278 |
+
|
| 279 |
+
gr.HTML('</div>')
|
| 280 |
+
|
| 281 |
+
# ๊ฒฐ๊ณผ ์ถ๋ ฅ ์น์
|
| 282 |
+
with gr.Row():
|
| 283 |
+
with gr.Column(scale=2):
|
| 284 |
+
gr.Markdown("### ๐ **์์ธ ์ง๋ฌด๊ธฐ์ ์**")
|
| 285 |
+
result_output = gr.Markdown(
|
| 286 |
+
value="์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ์
๋ ฅํ๊ณ '์ง๋ฌด๊ธฐ์ ์ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.",
|
| 287 |
+
elem_classes=["result-output"]
|
| 288 |
+
)
|
| 289 |
+
|
| 290 |
+
with gr.Column(scale=1):
|
| 291 |
+
gr.Markdown("### ๐ผ **์ง๋ฌด๊ธฐ์ ์ & ํ**")
|
| 292 |
+
jd_cards = gr.HTML(
|
| 293 |
+
value="<div style='text-align: center; color: #6B7280; padding: 20px;'>์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํด์ฃผ์ธ์</div>",
|
| 294 |
+
elem_classes=["jd-cards"]
|
| 295 |
+
)
|
| 296 |
+
|
| 297 |
+
# ์์ฑ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
| 298 |
+
generate_btn.click(
|
| 299 |
+
fn=process_jd_generation,
|
| 300 |
+
inputs=[job_input, company_input, experience_input],
|
| 301 |
+
outputs=[result_output, jd_cards],
|
| 302 |
+
api_name="generate_jd_recommendation"
|
| 303 |
+
)
|
| 304 |
+
|
| 305 |
+
# ํธํฐ
|
| 306 |
+
gr.Markdown("""
|
| 307 |
+
---
|
| 308 |
+
**๐ ์ง๋ฌด๊ธฐ์ ์ ํน์ง**:
|
| 309 |
+
- **ํ์ค์ ์ธ ๋ด์ฉ**: ์ค์ ์ฑ์ฉ๊ณต๊ณ ์คํ์ผ์ ์ง๋ฌด ์ค๋ช
|
| 310 |
+
- **๊ฒฝ๋ ฅ๋ณ ๋ง์ถค**: ์ ์
/๊ฒฝ๋ ฅ/์ธํด/๊ธฐํ์ ๋ฐ๋ฅธ ์ ์ ํ ์์ค์ ์๊ตฌ์ฌํญ
|
| 311 |
+
- **ํ์ฌ ํน์ฑ ๋ฐ์**: ํด๋น ํ์ฌ์ ์ฌ์
์์ญ๊ณผ ํน์ฑ์ ๊ณ ๋ คํ ๋ด์ฉ
|
| 312 |
+
- **์์์ ์ฐ๊ณ**: ์๊ธฐ์๊ฐ์ ์์ฑ์ ์ง์ ํ์ฉ ๊ฐ๋ฅํ ๊ตฌ์ฒด์ ์ ๋ณด
|
| 313 |
+
|
| 314 |
+
๐ก **ํ์ฉ ๋ฐฉ๋ฒ**: ์์ฑ๋ ์ง๋ฌด๊ธฐ์ ์์ ํต์ฌ ํค์๋์ ์๊ตฌ์ฌํญ์ ์์์์ ๋ฐ์ํ์ฌ ๋ง์ถคํ ์ง์์๋ฅผ ์์ฑํ์ธ์.
|
| 315 |
+
|
| 316 |
+
๐ค **Powered by**: OpenAI GPT-4o
|
| 317 |
+
""")
|
| 318 |
+
|
| 319 |
+
return demo
|
| 320 |
+
|
| 321 |
+
if __name__ == "__main__":
|
| 322 |
+
# Gradio ์ฑ ์คํ
|
| 323 |
+
demo = create_interface()
|
| 324 |
+
demo.launch(
|
| 325 |
+
server_name="0.0.0.0",
|
| 326 |
+
server_port=7863,
|
| 327 |
+
share=True,
|
| 328 |
+
show_error=True
|
| 329 |
+
)
|
jd-recommendation/prompt.yaml
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
prompt: |
|
| 2 |
+
๋น์ ์ ์ฑ์ฉ ๊ณต๊ณ ์์ฑ ์ ๋ฌธ๊ฐ์
๋๋ค.
|
| 3 |
+
์ฃผ์ด์ง ์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ๋ฐํ์ผ๋ก ํด๋น ํฌ์ง์
์ ๋ํ ๋ํ์ ์ธ ์ง๋ฌด๊ธฐ์ ์(Job Description)๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
|
| 4 |
+
|
| 5 |
+
### ์ง์นจ
|
| 6 |
+
1. **ํ์ค์ ์ธ ๋ด์ฉ**: ์ค์ ์ฑ์ฉ ๊ณต๊ณ ์์ ๋ณผ ์ ์๋ ํ์ค์ ์ด๊ณ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ ์์ฑํฉ๋๋ค.
|
| 7 |
+
2. **๊ฒฝ๋ ฅ ์์ค ๋ฐ์**: ์ ์
/๊ฒฝ๋ ฅ/์ธํด/๊ธฐํ์ ๋ฐ๋ผ ์ ์ ํ ์์ค์ ์
๋ฌด์ ์๊ตฌ์ฌํญ์ ์ ์ํฉ๋๋ค.
|
| 8 |
+
3. **๊ฐ๊ฒฐํ๊ณ ๋ช
ํ**: ์์์ ์์ฑ์ ๋์์ด ๋๋๋ก ํต์ฌ ๋ด์ฉ์ ๊ฐ๊ฒฐํ๊ฒ ์ ๋ฆฌํฉ๋๋ค.
|
| 9 |
+
4. **ํ์ฌ ํน์ฑ ๋ฐ์**: ํด๋น ํ์ฌ์ ์ฌ์
์์ญ๊ณผ ํน์ฑ์ ๊ณ ๋ คํ ์ง๋ฌด ๋ด์ฉ์ ์์ฑํฉ๋๋ค.
|
| 10 |
+
|
| 11 |
+
### ์
๋ ฅ ์ ๋ณด
|
| 12 |
+
- **์ง๋ฌด:** {job_title}
|
| 13 |
+
- **ํ์ฌ๋ช
:** {company_name}
|
| 14 |
+
- **๊ฒฝ๋ ฅ ์์ค:** {experience_level}
|
| 15 |
+
|
| 16 |
+
### ์ถ๋ ฅ ํ์
|
| 17 |
+
๋ฐ๋์ ๋ค์ JSON ํ์์ผ๋ก๋ง ์๋ตํ์ธ์:
|
| 18 |
+
|
| 19 |
+
```json
|
| 20 |
+
{{
|
| 21 |
+
"recommended_jd": "์ง๋ฌด๊ธฐ์ ์ ๋ด์ฉ"
|
| 22 |
+
}}
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
### ์์ฑ ์๊ตฌ์ฌํญ
|
| 26 |
+
|
| 27 |
+
**์ง๋ฌด๊ธฐ์ ์ ๋ด์ฉ (recommended_jd)**
|
| 28 |
+
- 2-4๋ฌธ์ฅ์ผ๋ก ๊ตฌ์ฑ๋ ๊ฐ๊ฒฐํ ์ค๋ช
|
| 29 |
+
- ์ฃผ์ ์
๋ฌด์ ์ฑ
์ ํฌํจ
|
| 30 |
+
- ๊ฒฝ๋ ฅ ์์ค์ ๋ง๋ ์ ์ ํ ์๊ตฌ์ฌํญ
|
| 31 |
+
- ํด๋น ํ์ฌ์ ํน์ฑ๊ณผ ์ฌ์
์์ญ ๋ฐ์
|
| 32 |
+
- ์์์ ์์ฑ์ ๋์์ด ๋๋ ๊ตฌ์ฒด์ ์ธ ์ ๋ณด ํฌํจ
|
| 33 |
+
|
| 34 |
+
### ๊ฒฝ๋ ฅ ์์ค๋ณ ๊ฐ์ด๋๋ผ์ธ
|
| 35 |
+
|
| 36 |
+
**์ ์
**
|
| 37 |
+
- ๊ธฐ๋ณธ์ ์ธ ์
๋ฌด ์ํ๊ณผ ํ์ต ๊ธฐํ ๊ฐ์กฐ
|
| 38 |
+
- ์ฑ์ฅ ๊ฐ๋ฅ์ฑ๊ณผ ๊ต์ก ํ๋ก๊ทธ๋จ ์ธ๊ธ
|
| 39 |
+
- ๊ธฐ์ด์ ์ธ ์คํฌ๊ณผ ์ญ๋ ์๊ตฌ
|
| 40 |
+
|
| 41 |
+
**๊ฒฝ๋ ฅ**
|
| 42 |
+
- ์ ๋ฌธ์ ์ธ ์
๋ฌด ์ํ๊ณผ ๋ฆฌ๋์ญ ์ญํ
|
| 43 |
+
- ๊ตฌ์ฒด์ ์ธ ๊ฒฝ๋ ฅ ์ฐ์์ ์ ๋ฌธ ์คํฌ ์๊ตฌ
|
| 44 |
+
- ์ฑ๊ณผ ์ฐฝ์ถ๊ณผ ํ ๊ธฐ์ฌ ๊ฐ์กฐ
|
| 45 |
+
|
| 46 |
+
**์ธํด**
|
| 47 |
+
- ์ค๋ฌด ๊ฒฝํ๊ณผ ํ์ต ๊ธฐํ ์ ๊ณต
|
| 48 |
+
- ๋ฉํ ๋ง๊ณผ ๊ต์ก ํ๋ก๊ทธ๋จ ์ฐธ์ฌ
|
| 49 |
+
- ๊ธฐ๋ณธ ์
๋ฌด ์ง์๊ณผ ํ๋ก์ ํธ ์ฐธ์ฌ
|
| 50 |
+
|
| 51 |
+
**๊ธฐํ**
|
| 52 |
+
- ํน์ํ ๊ณ ์ฉ ํํ๋ ํ๋ก์ ํธ์ฑ ์
๋ฌด
|
| 53 |
+
- ๊ณ์ฝ์ง, ํ๊ฒฌ์ง ๋ฑ์ ํน์ฑ ๋ฐ์
|
| 54 |
+
- ํน์ ๊ธฐ๊ฐ์ด๋ ์กฐ๊ฑด์ ์
๋ฌด
|
| 55 |
+
|
| 56 |
+
### ์์
|
| 57 |
+
[์
๋ ฅ]
|
| 58 |
+
- ์ง๋ฌด: ๊ฒฝ์๊ธฐํ
|
| 59 |
+
- ํ์ฌ๋ช
: ์ผ์ฑ์ ์
|
| 60 |
+
- ๊ฒฝ๋ ฅ ์์ค: ์ ์
|
| 61 |
+
|
| 62 |
+
[์ถ๋ ฅ]
|
| 63 |
+
```json
|
| 64 |
+
{{
|
| 65 |
+
"recommended_jd": "์ ์ฌ ๊ฒฝ์ ๋ชฉํ ๋ฌ์ฑ์ ์ํ ๋ฐ์ดํฐ ๋ถ์, ์์ฅ ๋ฆฌ์์น, ์ฌ์
์ ๋ต ์๋ฆฝ ์ง์ ์
๋ฌด๋ฅผ ์ํํฉ๋๋ค. ์ ๊ท ์ฌ์
๊ธฐํ๋ฅผ ๋ฐ๊ตดํ๊ณ , ๊ฒฝ์์ง์ ์์ฌ๊ฒฐ์ ์ ๋๊ธฐ ์ํ ๋ณด๊ณ ์ ์์ฑ ๋ฐ ๋ฐํ๋ฅผ ๋ด๋นํ๊ฒ ๋ฉ๋๋ค. ๋ฐ์ด๋ ๋ถ์๋ ฅ๊ณผ ๊ธฐํ๋ ฅ์ ๊ฐ์ถ ์ธ์ฌ๋ฅผ ์ฐพ์ต๋๋ค."
|
| 66 |
+
}}
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
์ด์ ๋ค์ ์
๋ ฅ์ ๋ํ ์ง๋ฌด๊ธฐ์ ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
jd-recommendation/propmt.yaml
ADDED
|
File without changes
|
main.py
ADDED
|
@@ -0,0 +1,474 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import os
|
| 3 |
+
import sys
|
| 4 |
+
import importlib.util
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
import dotenv
|
| 7 |
+
|
| 8 |
+
dotenv.load_dotenv()
|
| 9 |
+
|
| 10 |
+
# ํ์ฌ ๋๋ ํ ๋ฆฌ ์ค์
|
| 11 |
+
current_dir = Path(__file__).parent
|
| 12 |
+
|
| 13 |
+
# ๊ฐ ๊ธฐ๋ฅ๋ณ ๋ชจ๋ ๋ก๋ ํจ์
|
| 14 |
+
def load_module_from_path(module_name, file_path):
|
| 15 |
+
"""๋์ ์ผ๋ก ๋ชจ๋์ ๋ก๋ํ๋ ํจ์"""
|
| 16 |
+
try:
|
| 17 |
+
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
| 18 |
+
module = importlib.util.module_from_spec(spec)
|
| 19 |
+
spec.loader.exec_module(module)
|
| 20 |
+
return module
|
| 21 |
+
except Exception as e:
|
| 22 |
+
print(f"๋ชจ๋ ๋ก๋ ์คํจ {module_name}: {e}")
|
| 23 |
+
return None
|
| 24 |
+
|
| 25 |
+
# ๊ฐ ๊ธฐ๋ฅ๋ณ ๋ชจ๋ ๋ฐ ํจ์ ๋ก๋
|
| 26 |
+
modules = {}
|
| 27 |
+
available_features = {}
|
| 28 |
+
|
| 29 |
+
# 1. commonly-asked-question
|
| 30 |
+
try:
|
| 31 |
+
llm_functions_path = current_dir / "commonly-asked-question" / "llm_functions.py"
|
| 32 |
+
if llm_functions_path.exists():
|
| 33 |
+
modules['commonly_asked'] = load_module_from_path("commonly_asked_llm", llm_functions_path)
|
| 34 |
+
available_features['commonly_asked'] = modules['commonly_asked'] is not None
|
| 35 |
+
else:
|
| 36 |
+
available_features['commonly_asked'] = False
|
| 37 |
+
except Exception as e:
|
| 38 |
+
print(f"commonly-asked-question ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 39 |
+
available_features['commonly_asked'] = False
|
| 40 |
+
|
| 41 |
+
# 2. question-recommendation
|
| 42 |
+
try:
|
| 43 |
+
llm_functions_path = current_dir / "question-recommendation" / "llm_functions.py"
|
| 44 |
+
if llm_functions_path.exists():
|
| 45 |
+
modules['question_rec'] = load_module_from_path("question_rec_llm", llm_functions_path)
|
| 46 |
+
available_features['question_rec'] = modules['question_rec'] is not None
|
| 47 |
+
else:
|
| 48 |
+
available_features['question_rec'] = False
|
| 49 |
+
except Exception as e:
|
| 50 |
+
print(f"question-recommendation ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 51 |
+
available_features['question_rec'] = False
|
| 52 |
+
|
| 53 |
+
# 3. jd-recommendation
|
| 54 |
+
try:
|
| 55 |
+
llm_functions_path = current_dir / "jd-recommendation" / "llm_functions.py"
|
| 56 |
+
if llm_functions_path.exists():
|
| 57 |
+
modules['jd_rec'] = load_module_from_path("jd_rec_llm", llm_functions_path)
|
| 58 |
+
available_features['jd_rec'] = modules['jd_rec'] is not None
|
| 59 |
+
else:
|
| 60 |
+
available_features['jd_rec'] = False
|
| 61 |
+
except Exception as e:
|
| 62 |
+
print(f"jd-recommendation ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 63 |
+
available_features['jd_rec'] = False
|
| 64 |
+
|
| 65 |
+
# 4. industry-classification
|
| 66 |
+
try:
|
| 67 |
+
llm_functions_path = current_dir / "industry-classification" / "llm_functions.py"
|
| 68 |
+
if llm_functions_path.exists():
|
| 69 |
+
modules['industry'] = load_module_from_path("industry_llm", llm_functions_path)
|
| 70 |
+
available_features['industry'] = modules['industry'] is not None
|
| 71 |
+
else:
|
| 72 |
+
available_features['industry'] = False
|
| 73 |
+
except Exception as e:
|
| 74 |
+
print(f"industry-classification ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 75 |
+
available_features['industry'] = False
|
| 76 |
+
|
| 77 |
+
# 5. jasoseo-context-report
|
| 78 |
+
try:
|
| 79 |
+
llm_functions_path = current_dir / "jasoseo-context-report" / "llm_functions.py"
|
| 80 |
+
if llm_functions_path.exists():
|
| 81 |
+
modules['jasoseo'] = load_module_from_path("jasoseo_llm", llm_functions_path)
|
| 82 |
+
available_features['jasoseo'] = modules['jasoseo'] is not None
|
| 83 |
+
else:
|
| 84 |
+
available_features['jasoseo'] = False
|
| 85 |
+
except Exception as e:
|
| 86 |
+
print(f"jasoseo-context-report ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 87 |
+
available_features['jasoseo'] = False
|
| 88 |
+
|
| 89 |
+
# 6. company-size-classification
|
| 90 |
+
try:
|
| 91 |
+
llm_functions_path = current_dir / "company-size-classification" / "llm_functions.py"
|
| 92 |
+
if llm_functions_path.exists():
|
| 93 |
+
modules['company_size'] = load_module_from_path("company_size_llm", llm_functions_path)
|
| 94 |
+
available_features['company_size'] = modules['company_size'] is not None
|
| 95 |
+
else:
|
| 96 |
+
available_features['company_size'] = False
|
| 97 |
+
except Exception as e:
|
| 98 |
+
print(f"company-size-classification ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 99 |
+
available_features['company_size'] = False
|
| 100 |
+
|
| 101 |
+
# OpenAI ๊ด๋ จ ๋ชจ๋
|
| 102 |
+
try:
|
| 103 |
+
from openai import OpenAI
|
| 104 |
+
import yaml
|
| 105 |
+
openai_available = True
|
| 106 |
+
except ImportError:
|
| 107 |
+
openai_available = False
|
| 108 |
+
|
| 109 |
+
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
| 110 |
+
client = None
|
| 111 |
+
if openai_available and os.getenv("OPENAI_API_KEY"):
|
| 112 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 113 |
+
|
| 114 |
+
# ๊ณตํต CSS ์คํ์ผ
|
| 115 |
+
common_css = """
|
| 116 |
+
.main-header {
|
| 117 |
+
text-align: center;
|
| 118 |
+
padding: 20px;
|
| 119 |
+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
| 120 |
+
color: white;
|
| 121 |
+
border-radius: 10px;
|
| 122 |
+
margin-bottom: 20px;
|
| 123 |
+
}
|
| 124 |
+
.input-section {
|
| 125 |
+
background-color: #f8f9fa;
|
| 126 |
+
padding: 20px;
|
| 127 |
+
border-radius: 8px;
|
| 128 |
+
margin: 10px 0;
|
| 129 |
+
}
|
| 130 |
+
.example-section {
|
| 131 |
+
background-color: #f0f9ff;
|
| 132 |
+
padding: 15px;
|
| 133 |
+
border-radius: 8px;
|
| 134 |
+
margin: 10px 0;
|
| 135 |
+
}
|
| 136 |
+
.tab-container {
|
| 137 |
+
margin: 20px 0;
|
| 138 |
+
height: 100%;
|
| 139 |
+
}
|
| 140 |
+
"""
|
| 141 |
+
|
| 142 |
+
# ์์ ๋ฐ์ดํฐ
|
| 143 |
+
example_companies = ["์ผ์ฑ์ ์", "ํ ์ค", "์นด์นด์ค", "๋ค์ด๋ฒ", "LG์ ์", "ํ๋์๋์ฐจ", "CJ์ ์ผ์ ๋น", "ํ์ด๋ธ", "์ฟ ํก", "๋ฐฐ๋ฌ์๋ฏผ์กฑ", "์ ํ์ํ", "SKT", "ํฌ์ค์ฝ", "ํ๋๊ฑด์ค", "์๋ชจ๋ ํผ์ํฝ"]
|
| 144 |
+
example_jobs = ["๋ฐฑ์๋ ๊ฐ๋ฐ", "ํ๋ก ํธ์๋ ๊ฐ๏ฟฝ๏ฟฝ๏ฟฝ", "๋ฐ์ดํฐ ์ฌ์ด์ธํฐ์คํธ", "๋ง์ผํ
", "์์
", "๊ธฐํ", "๋์์ธ", "HR", "์ฌ๋ฌด", "A&R", "๊ฒฝ์๊ธฐํ", "ํด์ธ์์
", "์จ๋ผ์ธ๋ง์ผํ
", "์ํ๋ง์ผํ
", "HRM(์ธ์ฌ์ด์)"]
|
| 145 |
+
experience_levels = ["์ ์
", "๊ฒฝ๋ ฅ", "์ธํด", "๊ธฐํ"]
|
| 146 |
+
|
| 147 |
+
# ๊ณตํต ํจ์๋ค
|
| 148 |
+
def create_example_buttons(companies, jobs, company_input, job_input):
|
| 149 |
+
"""์์ ๋ฒํผ๋ค์ ์์ฑํ๋ ํจ์"""
|
| 150 |
+
|
| 151 |
+
gr.Markdown("### ๐ก **์์ ํ์ฌ**")
|
| 152 |
+
with gr.Row():
|
| 153 |
+
for company in companies[:5]:
|
| 154 |
+
btn = gr.Button(company, size="sm", variant="secondary")
|
| 155 |
+
btn.click(fn=lambda x=company: x, outputs=company_input)
|
| 156 |
+
|
| 157 |
+
with gr.Row():
|
| 158 |
+
for company in companies[5:10]:
|
| 159 |
+
btn = gr.Button(company, size="sm", variant="secondary")
|
| 160 |
+
btn.click(fn=lambda x=company: x, outputs=company_input)
|
| 161 |
+
|
| 162 |
+
gr.Markdown("### ๐ผ **์์ ์ง๋ฌด**")
|
| 163 |
+
with gr.Row():
|
| 164 |
+
for job in jobs[:5]:
|
| 165 |
+
btn = gr.Button(job, size="sm", variant="secondary")
|
| 166 |
+
btn.click(fn=lambda x=job: x, outputs=job_input)
|
| 167 |
+
|
| 168 |
+
with gr.Row():
|
| 169 |
+
for job in jobs[5:10]:
|
| 170 |
+
btn = gr.Button(job, size="sm", variant="secondary")
|
| 171 |
+
btn.click(fn=lambda x=job: x, outputs=job_input)
|
| 172 |
+
|
| 173 |
+
# 1. ์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ์์ฑ ํญ
|
| 174 |
+
def create_commonly_asked_tab():
|
| 175 |
+
if not available_features.get('commonly_asked'):
|
| 176 |
+
gr.Markdown("โ **์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)")
|
| 177 |
+
return
|
| 178 |
+
gr.HTML("""
|
| 179 |
+
<div class="main-header">
|
| 180 |
+
<h2>๐ฏ ์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ์์ฑ</h2>
|
| 181 |
+
<p>ํ์ฌ์ ์ง๋ฌด์ ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ AI๊ฐ ์์ฑํด๋๋ฆฝ๋๋ค</p>
|
| 182 |
+
</div>
|
| 183 |
+
""")
|
| 184 |
+
|
| 185 |
+
with gr.Row():
|
| 186 |
+
with gr.Column(scale=2):
|
| 187 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 188 |
+
|
| 189 |
+
company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช
", placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ")
|
| 190 |
+
job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ง์ผํ
, ๊ธฐํ ๋ฑ")
|
| 191 |
+
|
| 192 |
+
with gr.Row():
|
| 193 |
+
experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์
", interactive=True)
|
| 194 |
+
num_questions_input = gr.Dropdown(label="๐ ์์ฑํ ์ง๋ฌธ ์", choices=[1, 2, 3, 4, 5], value=3, interactive=True)
|
| 195 |
+
|
| 196 |
+
common_questions_list = [
|
| 197 |
+
"์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์", "์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "๋ณธ์ธ์ ๊ฐ์ ์ ๋ฌด์์ธ๊ฐ์",
|
| 198 |
+
"๊ฐ์ฅ ๋์ ์ ์ธ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ณต ๊ฒฝํ์ ๋งํด์ฃผ์ธ์", "์คํจ ๊ฒฝํ์ ๋งํด์ฃผ์ธ์",
|
| 199 |
+
"์
์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ฒฉ์ ์ฅ๋จ์ ์ ๋งํด์ฃผ์ธ์", "์กด๊ฒฝํ๋ ์ธ๋ฌผ์ ๋๊ตฌ์ธ๊ฐ์",
|
| 200 |
+
"๋ง์ง๋ง์ผ๋ก ํ๊ณ ์ถ์ ๋ง์?"
|
| 201 |
+
]
|
| 202 |
+
selected_questions = gr.CheckboxGroup(label="๐ ์ฐธ๊ณ ํ ์ผ๋ฐ ์ง๋ฌธ (์ ํ)", choices=common_questions_list, value=common_questions_list[:3])
|
| 203 |
+
|
| 204 |
+
generate_btn = gr.Button("๐ฏ ๋ฉด์ ์ง๋ฌธ ์์ฑ", variant="primary", size="lg")
|
| 205 |
+
|
| 206 |
+
with gr.Column(scale=1):
|
| 207 |
+
create_example_buttons(example_companies, example_jobs, company_input, job_input)
|
| 208 |
+
|
| 209 |
+
gr.Markdown("### ๐ **์์ฑ๋ ๋ฉด์ ์ง๋ฌธ**")
|
| 210 |
+
result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ '๋ฉด์ ์ง๋ฌธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.")
|
| 211 |
+
|
| 212 |
+
def process_question_generation(company, job, experience, selected, num):
|
| 213 |
+
try:
|
| 214 |
+
content, _ = modules['commonly_asked'].generate_interview_questions(company, job, experience, selected, num)
|
| 215 |
+
return content
|
| 216 |
+
except Exception as e:
|
| 217 |
+
return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}"
|
| 218 |
+
|
| 219 |
+
generate_btn.click(
|
| 220 |
+
fn=process_question_generation,
|
| 221 |
+
inputs=[company_input, job_input, experience_input, selected_questions, num_questions_input],
|
| 222 |
+
outputs=result_output
|
| 223 |
+
)
|
| 224 |
+
|
| 225 |
+
# 2. ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ํญ
|
| 226 |
+
def create_question_recommendation_tab():
|
| 227 |
+
if not available_features.get('question_rec') or not openai_available:
|
| 228 |
+
gr.Markdown("โ **๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ ๋๋ API ํค ์์)")
|
| 229 |
+
return
|
| 230 |
+
gr.HTML("""
|
| 231 |
+
<div class="main-header">
|
| 232 |
+
<h2>๐ก ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ</h2>
|
| 233 |
+
<p>์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ์
๋ ฅํ๋ฉด AI๊ฐ ๋ง์ถคํ ์ง๋ฌธ์ ์ถ์ฒํฉ๋๋ค</p>
|
| 234 |
+
</div>
|
| 235 |
+
""")
|
| 236 |
+
|
| 237 |
+
with gr.Row():
|
| 238 |
+
with gr.Column(scale=2):
|
| 239 |
+
gr.Markdown("### ๐ **์ ๋ณด ์
๋ ฅ**")
|
| 240 |
+
job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ง์ผํ
, ๊ธฐํ ๋ฑ")
|
| 241 |
+
company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช
", placeholder="์: ํ ์ค, ์ผ์ฑ์ ์, ๋ค์ด๋ฒ ๋ฑ")
|
| 242 |
+
experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์
")
|
| 243 |
+
submit_btn = gr.Button("๐ก ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ๋ฐ๊ธฐ", variant="primary", size="lg")
|
| 244 |
+
|
| 245 |
+
with gr.Column(scale=1):
|
| 246 |
+
create_example_buttons(example_companies, example_jobs, company_input, job_input)
|
| 247 |
+
|
| 248 |
+
gr.Markdown("### ๐ฌ **์ถ์ฒ ๋ฉด์ ์ง๋ฌธ**")
|
| 249 |
+
result_output = gr.Textbox(label="", placeholder="์ถ์ฒ๋ ๋ฉด์ ์ง๋ฌธ์ด ์ฌ๊ธฐ์ ํ์๋ฉ๋๋ค.", lines=5, show_label=False, interactive=False)
|
| 250 |
+
|
| 251 |
+
def recommend_question(job, company, experience):
|
| 252 |
+
try:
|
| 253 |
+
if not client: return "โ OpenAI API ํค๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค."
|
| 254 |
+
prompt_path = current_dir / "question-recommendation" / "prompt.yaml"
|
| 255 |
+
with open(prompt_path, 'r', encoding='utf-8') as f:
|
| 256 |
+
prompts = yaml.safe_load(f)
|
| 257 |
+
|
| 258 |
+
result = modules['question_rec'].generate_question_recommendation(client, prompts, job, company, experience)
|
| 259 |
+
parsed = modules['question_rec'].parse_question_recommendation(result)
|
| 260 |
+
return parsed.get('recommended_question', "์ง๋ฌธ ์์ฑ์ ์คํจํ์ต๋๋ค.")
|
| 261 |
+
except Exception as e:
|
| 262 |
+
return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}"
|
| 263 |
+
|
| 264 |
+
submit_btn.click(fn=recommend_question, inputs=[job_input, company_input, experience_input], outputs=result_output)
|
| 265 |
+
|
| 266 |
+
# 3. ์ง๋ฌด๊ธฐ์ ์ ์์ฑ ํญ
|
| 267 |
+
def create_jd_recommendation_tab():
|
| 268 |
+
if not available_features.get('jd_rec'):
|
| 269 |
+
gr.Markdown("โ **์ง๋ฌด๊ธฐ์ ์ ์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)")
|
| 270 |
+
return
|
| 271 |
+
gr.HTML("""
|
| 272 |
+
<div class="main-header">
|
| 273 |
+
<h2>๐ AI ์ง๋ฌด๊ธฐ์ ์ ์์ฑ๊ธฐ</h2>
|
| 274 |
+
<p>๋ง์ถคํ ์ง๋ฌด๊ธฐ์ ์๋ก ์๋ฒฝํ ์๊ธฐ์๊ฐ์๋ฅผ ์ค๋นํ์ธ์</p>
|
| 275 |
+
</div>
|
| 276 |
+
""")
|
| 277 |
+
|
| 278 |
+
with gr.Row():
|
| 279 |
+
with gr.Column(scale=2):
|
| 280 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 281 |
+
job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๊ฒฝ์๊ธฐํ, ๋ฐฑ์๋ ๊ฐ๋ฐ, ์จ๋ผ์ธ๋ง์ผํ
๋ฑ")
|
| 282 |
+
company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช
", placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ")
|
| 283 |
+
experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์
", interactive=True)
|
| 284 |
+
generate_btn = gr.Button("๐ ์ง๋ฌด๊ธฐ์ ์ ์์ฑ", variant="primary", size="lg")
|
| 285 |
+
|
| 286 |
+
with gr.Column(scale=1):
|
| 287 |
+
create_example_buttons(example_companies, example_jobs, company_input, job_input)
|
| 288 |
+
|
| 289 |
+
gr.Markdown("### ๐ **์์ฑ๋ ์ง๋ฌด๊ธฐ์ ์**")
|
| 290 |
+
result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ '์ง๋ฌด๊ธฐ์ ์ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.")
|
| 291 |
+
|
| 292 |
+
def process_jd_generation(job, company, experience):
|
| 293 |
+
try:
|
| 294 |
+
content, _ = modules['jd_rec'].generate_jd_recommendation(job, company, experience)
|
| 295 |
+
return content
|
| 296 |
+
except Exception as e:
|
| 297 |
+
return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}"
|
| 298 |
+
|
| 299 |
+
generate_btn.click(fn=process_jd_generation, inputs=[job_input, company_input, experience_input], outputs=result_output)
|
| 300 |
+
|
| 301 |
+
# 4. ์ฐ์
๋ถ๋ฅ ํญ
|
| 302 |
+
def create_industry_classification_tab():
|
| 303 |
+
if not available_features.get('industry'):
|
| 304 |
+
gr.Markdown("โ **์ฐ์
๋ถ๋ฅ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)")
|
| 305 |
+
return
|
| 306 |
+
gr.HTML("""
|
| 307 |
+
<div class="main-header">
|
| 308 |
+
<h2>๐ท๏ธ AI ์ฐ์
๋ถ๋ฅ๊ธฐ</h2>
|
| 309 |
+
<p>์ง๋ฌด์ ํ์ฌ๋ช
์ ๋ฐํ์ผ๋ก ์ ํํ ์ฐ์
๋ถ์ผ๋ฅผ ๋ถ๋ฅํฉ๋๋ค</p>
|
| 310 |
+
</div>
|
| 311 |
+
""")
|
| 312 |
+
|
| 313 |
+
with gr.Row():
|
| 314 |
+
with gr.Column(scale=2):
|
| 315 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 316 |
+
job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๊ฒฝ์๊ธฐํ, ๋ฐฑ์๋ ๊ฐ๋ฐ, ์จ๋ผ์ธ๋ง์ผํ
๋ฑ")
|
| 317 |
+
company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช
", placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ")
|
| 318 |
+
classify_btn = gr.Button("๐ท๏ธ ์ฐ์
๋ถ๋ฅ", variant="primary", size="lg")
|
| 319 |
+
|
| 320 |
+
with gr.Column(scale=1):
|
| 321 |
+
create_example_buttons(example_companies, example_jobs, company_input, job_input)
|
| 322 |
+
|
| 323 |
+
gr.Markdown("### ๐ **๋ถ๋ฅ ๊ฒฐ๊ณผ**")
|
| 324 |
+
result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ '์ฐ์
๋ถ๋ฅ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.")
|
| 325 |
+
|
| 326 |
+
def process_classification(job, company):
|
| 327 |
+
try:
|
| 328 |
+
content, _ = modules['industry'].classify_industry(job, company)
|
| 329 |
+
return content
|
| 330 |
+
except Exception as e:
|
| 331 |
+
return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}"
|
| 332 |
+
|
| 333 |
+
classify_btn.click(fn=process_classification, inputs=[job_input, company_input], outputs=result_output)
|
| 334 |
+
|
| 335 |
+
# 5. ์์์ ์ปจํ
์คํธ ๋ฆฌํฌํธ ํญ
|
| 336 |
+
def create_jasoseo_context_tab():
|
| 337 |
+
if not available_features.get('jasoseo'):
|
| 338 |
+
gr.Markdown("โ **์์์ ์ปจํ
์คํธ ๋ฆฌํฌํธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)")
|
| 339 |
+
return
|
| 340 |
+
gr.HTML("""
|
| 341 |
+
<div class="main-header">
|
| 342 |
+
<h2>๐ ์์์ ์ปจํ
์คํธ ๏ฟฝ๏ฟฝํฌํธ</h2>
|
| 343 |
+
<p>๊ธฐ์
๊ณผ ์ง๋ฌด์ ๋ํ ์ข
ํฉ์ ์ธ ๋ถ์์ผ๋ก ์๋ฒฝํ ์๊ธฐ์๊ฐ์๋ฅผ ์ค๋นํ์ธ์</p>
|
| 344 |
+
</div>
|
| 345 |
+
""")
|
| 346 |
+
|
| 347 |
+
with gr.Row():
|
| 348 |
+
with gr.Column(scale=2):
|
| 349 |
+
gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์
๋ ฅ**")
|
| 350 |
+
job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๊ฒฝ์๊ธฐํ, ๋ง์ผํ
๋ฑ")
|
| 351 |
+
company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช
", placeholder="์: ํ ์ค, ์ผ์ฑ์ ์, ์นด์นด์ค ๋ฑ")
|
| 352 |
+
experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์
", interactive=True)
|
| 353 |
+
generate_btn = gr.Button("๐ ๋ฆฌํฌํธ ์์ฑ", variant="primary", size="lg")
|
| 354 |
+
|
| 355 |
+
with gr.Column(scale=1):
|
| 356 |
+
create_example_buttons(example_companies, example_jobs, company_input, job_input)
|
| 357 |
+
|
| 358 |
+
gr.Markdown("### ๐ **์ปจํ
์คํธ ๋ฆฌํฌํธ**")
|
| 359 |
+
result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ '๋ฆฌํฌํธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.")
|
| 360 |
+
|
| 361 |
+
def process_report_generation(job, company, experience):
|
| 362 |
+
try:
|
| 363 |
+
content, _ = modules['jasoseo'].generate_context_report(job, company, experience)
|
| 364 |
+
return content
|
| 365 |
+
except Exception as e:
|
| 366 |
+
return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}"
|
| 367 |
+
|
| 368 |
+
generate_btn.click(fn=process_report_generation, inputs=[job_input, company_input, experience_input], outputs=result_output)
|
| 369 |
+
|
| 370 |
+
# 6. ๊ธฐ์
๊ท๋ชจ ๋ถ๋ฅ ํญ
|
| 371 |
+
def create_company_size_tab():
|
| 372 |
+
if not available_features.get('company_size'):
|
| 373 |
+
gr.Markdown("โ **๊ธฐ์
๊ท๋ชจ ๋ถ๋ฅ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)")
|
| 374 |
+
return
|
| 375 |
+
gr.HTML("""
|
| 376 |
+
<div class="main-header">
|
| 377 |
+
<h2>๐ข AI ๊ธฐ์
๊ท๋ชจ ์์ธก๊ธฐ</h2>
|
| 378 |
+
<p>์ค์๊ฐ ์น ์ ๋ณด๋ฅผ ํ์ฉํ ๊ธฐ์
์ ๋ณด ๋ถ์</p>
|
| 379 |
+
</div>
|
| 380 |
+
""")
|
| 381 |
+
|
| 382 |
+
with gr.Row():
|
| 383 |
+
with gr.Column(scale=2):
|
| 384 |
+
gr.Markdown("### ๐ **๊ธฐ์
์ ๋ณด ์
๋ ฅ**")
|
| 385 |
+
company_input = gr.Textbox(label="๐ข ๊ธฐ์
๋ช
์
๋ ฅ", placeholder="๋ถ์ํ๊ณ ์ถ์ ๊ธฐ์
๋ช
์ ์
๋ ฅํ์ธ์ (์: ์ผ์ฑ์ ์, ์นด์นด์ค ๋ฑ)")
|
| 386 |
+
analyze_btn = gr.Button("๐ ๊ธฐ์
๊ท๋ชจ ๋ถ์", variant="primary", size="lg")
|
| 387 |
+
|
| 388 |
+
with gr.Column(scale=1):
|
| 389 |
+
gr.Markdown("""
|
| 390 |
+
### โน๏ธ **๋ถ๋ฅ ๊ธฐ์ค**
|
| 391 |
+
- **๋๊ธฐ์
**: ๋งค์ถ 1์กฐ์ ์ด์
|
| 392 |
+
- **์ค๊ฒฌ๊ธฐ์
**: ๋งค์ถ 1000์ต-1์กฐ์
|
| 393 |
+
- **์ค์๊ธฐ์
**: ๋งค์ถ 1000์ต์ ๋ฏธ๋ง
|
| 394 |
+
- **์คํํธ์
**: ์ค๋ฆฝ 10๋
์ด๋ด
|
| 395 |
+
- **์ธ๊ตญ๊ณ๊ธฐ์
**: ํด์ธ ๋ณธ์ฌ
|
| 396 |
+
- **๊ณต๊ณต๊ธฐ๊ด/๊ณต๊ธฐ์
**: ์ ๋ถ ์ถ์/์ถ์ฐ
|
| 397 |
+
""")
|
| 398 |
+
|
| 399 |
+
gr.Markdown("### ๐ผ **์์ ๊ธฐ์
์ ํ** (ํด๋ฆญํ๋ฉด ์๋ ์
๋ ฅ๋ฉ๋๋ค)")
|
| 400 |
+
example_company_names = ["์ผ์ฑ์ ์", "ํ๋์๋์ฐจ", "SKํ์ด๋์ค", "ํฌ์ค์ฝํ๋ฉ์ค", "ํ ์ค", "์นด์นด์ค", "๋ค์ด๋ฒ", "์ฟ ํก", "๋ฐฐ๋ฌ์๋ฏผ์กฑ", "๋น๊ทผ๋ง์ผ"]
|
| 401 |
+
with gr.Row():
|
| 402 |
+
for company in example_company_names[:5]:
|
| 403 |
+
btn = gr.Button(company, size="sm", variant="secondary")
|
| 404 |
+
btn.click(fn=lambda x=company: x, outputs=company_input)
|
| 405 |
+
with gr.Row():
|
| 406 |
+
for company in example_company_names[5:]:
|
| 407 |
+
btn = gr.Button(company, size="sm", variant="secondary")
|
| 408 |
+
btn.click(fn=lambda x=company: x, outputs=company_input)
|
| 409 |
+
|
| 410 |
+
gr.Markdown("### ๐ **๋ถ์ ๊ฒฐ๊ณผ**")
|
| 411 |
+
result_output = gr.Markdown("๊ธฐ์
๋ช
์ ์
๋ ฅํ๊ณ '๊ธฐ์
๊ท๋ชจ ๋ถ์' ๋ฒํผ์ ํด๋ฆญํ์ธ์.")
|
| 412 |
+
|
| 413 |
+
def process_analysis_result(company):
|
| 414 |
+
try:
|
| 415 |
+
content, _ = modules['company_size'].analyze_company_size(company)
|
| 416 |
+
return content
|
| 417 |
+
except Exception as e:
|
| 418 |
+
return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}"
|
| 419 |
+
|
| 420 |
+
analyze_btn.click(fn=process_analysis_result, inputs=[company_input], outputs=result_output)
|
| 421 |
+
|
| 422 |
+
# ๋ฉ์ธ ์ ํ๋ฆฌ์ผ์ด์
์์ฑ
|
| 423 |
+
def create_main_app():
|
| 424 |
+
with gr.Blocks(
|
| 425 |
+
title="๐ JasoSeo Agent - ์ทจ์
์ง์ AI ๋๊ตฌ",
|
| 426 |
+
theme=gr.themes.Soft(primary_hue="purple", secondary_hue="pink", neutral_hue="gray"),
|
| 427 |
+
css=common_css
|
| 428 |
+
) as app:
|
| 429 |
+
|
| 430 |
+
gr.HTML("""
|
| 431 |
+
<div style="text-align: center; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 15px; margin-bottom: 30px;">
|
| 432 |
+
<h1 style="font-size: 32px; margin-bottom: 10px;">๐ JasoSeo Agent</h1>
|
| 433 |
+
<p style="font-size: 18px; margin-bottom: 0; opacity: 0.9;">AI ๊ธฐ๋ฐ ์ทจ์
์ง์ ํตํฉ ํ๋ซํผ</p>
|
| 434 |
+
</div>
|
| 435 |
+
""")
|
| 436 |
+
|
| 437 |
+
status_items = [name for name, ok in available_features.items() if ok]
|
| 438 |
+
status_text = f"โ
์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ ({len(status_items)}/{len(available_features)}): {', '.join(status_items)}" if status_items else "โ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค."
|
| 439 |
+
gr.Markdown(f"**{status_text}**")
|
| 440 |
+
|
| 441 |
+
|
| 442 |
+
|
| 443 |
+
with gr.Tabs(elem_classes="tab-container"):
|
| 444 |
+
with gr.Tab("๐ฏ ๋ฉด์ ์ง๋ฌธ ์์ฑ", elem_id="commonly-asked-tab"):
|
| 445 |
+
create_commonly_asked_tab()
|
| 446 |
+
|
| 447 |
+
with gr.Tab("๐ก ์ง๋ฌธ ์ถ์ฒ", elem_id="question-recommendation-tab"):
|
| 448 |
+
create_question_recommendation_tab()
|
| 449 |
+
|
| 450 |
+
with gr.Tab("๐ ์ง๋ฌด๊ธฐ์ ์", elem_id="jd-recommendation-tab"):
|
| 451 |
+
create_jd_recommendation_tab()
|
| 452 |
+
|
| 453 |
+
with gr.Tab("๐ท๏ธ ์ฐ์
๋ถ๋ฅ", elem_id="industry-classification-tab"):
|
| 454 |
+
create_industry_classification_tab()
|
| 455 |
+
|
| 456 |
+
with gr.Tab("๐ ์ปจํ
์คํธ ๋ฆฌํฌํธ", elem_id="jasoseo-context-tab"):
|
| 457 |
+
create_jasoseo_context_tab()
|
| 458 |
+
|
| 459 |
+
with gr.Tab("๐ข ๊ธฐ์
๊ท๋ชจ", elem_id="company-size-tab"):
|
| 460 |
+
create_company_size_tab()
|
| 461 |
+
|
| 462 |
+
return app
|
| 463 |
+
|
| 464 |
+
if __name__ == "__main__":
|
| 465 |
+
if not os.getenv("OPENAI_API_KEY"):
|
| 466 |
+
print("โ ๏ธ OPENAI_API_KEY ํ๊ฒฝ ๋ณ์๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค. ์ผ๋ถ ๊ธฐ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.")
|
| 467 |
+
|
| 468 |
+
print("\n๐ ๋ชจ๋ ๋ก๋ ์ํ:")
|
| 469 |
+
for feature, available in available_features.items():
|
| 470 |
+
print(f" {'โ
' if available else 'โ'} {feature}")
|
| 471 |
+
|
| 472 |
+
print("\n๐ JasoSeo Agent ์์ ์ค...")
|
| 473 |
+
app = create_main_app()
|
| 474 |
+
app.launch(share=True, show_error=True, debug=True)
|
question-recommendation/.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
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
|
| 31 |
+
-----END CERTIFICATE-----
|
question-recommendation/__pycache__/llm_functions.cpython-312.pyc
ADDED
|
Binary file (5.18 kB). View file
|
|
|
question-recommendation/eval.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"recommended_question_generation_eval": {
|
| 3 |
+
"task_definition": {
|
| 4 |
+
"description": "Generate a single, relevant interview question based on the user's input. The question must be specific to the company and job role by incorporating information such as the company's core business, known values, or major products, avoiding overly generic or hyper-specific inquiries.",
|
| 5 |
+
"input": {
|
| 6 |
+
"job_title": "string",
|
| 7 |
+
"company_name": "string",
|
| 8 |
+
"experience_level": "์ ์
| ๊ฒฝ๋ ฅ | ์ธํด | ๊ธฐํ"
|
| 9 |
+
},
|
| 10 |
+
"output": {
|
| 11 |
+
"recommended_question": "string"
|
| 12 |
+
}
|
| 13 |
+
},
|
| 14 |
+
"examples": [
|
| 15 |
+
{
|
| 16 |
+
"input": {
|
| 17 |
+
"job_title": "๋ฐฑ์๋ ๊ฐ๋ฐ",
|
| 18 |
+
"company_name": "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)",
|
| 19 |
+
"experience_level": "์ ์
"
|
| 20 |
+
},
|
| 21 |
+
"output": {
|
| 22 |
+
"recommended_question": "ํ ์ค๋ '์์ ์ ์ฑ
์' ๋ฌธํ๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ๋ณธ์ธ์ ๊ฒฝํ์ ๋น์ถ์ด ๋ณผ ๋, ์ด๋ฌํ ๋ฌธํ ์์์ ๋๋ฃ ๊ฐ๋ฐ์์ ๊ธฐ์ ์ ๊ฐ๋ฑ์ด ๋ฐ์ํ์ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด๊ฒฐํด ๋๊ฐ ๊ฒ์ธ์ง ์ค๋ช
ํด์ฃผ์ธ์."
|
| 23 |
+
}
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"input": {
|
| 27 |
+
"job_title": "์ํ๋ง์ผํ
",
|
| 28 |
+
"company_name": "CJ์ ์ผ์ ๋น",
|
| 29 |
+
"experience_level": "๊ฒฝ๋ ฅ"
|
| 30 |
+
},
|
| 31 |
+
"output": {
|
| 32 |
+
"recommended_question": "๋น์ฌ์ '๋น๋น๊ณ ' ๋ธ๋๋๊ฐ ๊ธ๋ก๋ฒ K-ํธ๋ ๋ํ์ฃผ์๋ก ์๋ฆฌ๋งค๊นํ์ต๋๋ค. ๊ฒฝ๋ ฅ ๋ง์ผํฐ๋ก์, ๋น๋น๊ณ ์ ์ฑ๊ณต ์์ธ์ ๋ฌด์์ด๋ผ๊ณ ๋ถ์ํ๋ฉฐ, ๋ณธ์ธ์ด ํฉ๋ฅํ๋ค๋ฉด ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ธ๋๋์ ๋ค์ ์ฑ์ฅ์ ์ด๋๊ณ ์ถ์ผ์ ๊ฐ์?"
|
| 33 |
+
}
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
"input": {
|
| 37 |
+
"job_title": "A&R",
|
| 38 |
+
"company_name": "ํ์ด๋ธ",
|
| 39 |
+
"experience_level": "์ธํด"
|
| 40 |
+
},
|
| 41 |
+
"output": {
|
| 42 |
+
"recommended_question": "ํ์ด๋ธ๋ ๋ฉํฐ ๋ ์ด๋ธ ์ฒด์ ๋ฅผ ํตํด ์์
์ ๋ค์์ฑ์ ์ถ๊ตฌํ๊ณ ์์ต๋๋ค. ๋ณธ์ธ์ด ๊ฐ์ฅ ๊ด์ฌ ์๊ฒ ์ง์ผ๋ณธ ํ์ด๋ธ ์ฐํ ๋ ์ด๋ธ์ ์ด๋์ด๋ฉฐ, ํด๋น ๋ ์ด๋ธ์ ์์
์ ๋ฐฉํฅ์ฑ์ ๊ธฐ์ฌํ ์ ์๋ ์์ ๋ง์ ๊ฐ์ ์ ๋ฌด์์ด๋ผ๊ณ ์๊ฐํ๋์?"
|
| 43 |
+
}
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
"input": {
|
| 47 |
+
"job_title": "๊ฒฝ์๊ธฐํ",
|
| 48 |
+
"company_name": "ํ๋๊ฑด์ค",
|
| 49 |
+
"experience_level": "์ ์
"
|
| 50 |
+
},
|
| 51 |
+
"output": {
|
| 52 |
+
"recommended_question": "๊ฑด์ค์
์ ์ต๊ทผ ์์ ๋ฐ ํ๊ฒฝ(ESG) ๊ท์ ๊ฐ ๊ฐํ๋๋ ๋ฑ ์ธ๋ถ ํ๊ฒฝ ๋ณํ๊ฐ ํฐ ์ฐ์
์
๋๋ค. ๊ฒฝ์๊ธฐํ ์ง๋ฌด ๋ด๋น์๋ก์ ์ด๋ฌํ ๋ณํ์ ๋์ํ๊ธฐ ์ํด ์ด๋ค ์ญ๋์ด ๊ฐ์ฅ ์ค์ํ๋ค๊ณ ์๊ฐํ๋์ง ๋ณธ์ธ์ ๊ฒฝํ๊ณผ ์ฐ๊ฒฐ์ง์ด ๋ง์ํด์ฃผ์ธ์."
|
| 53 |
+
}
|
| 54 |
+
},
|
| 55 |
+
{
|
| 56 |
+
"input": {
|
| 57 |
+
"job_title": "ํด์ธ์์
",
|
| 58 |
+
"company_name": "์ผ์ฑ์ ์",
|
| 59 |
+
"experience_level": "๊ฒฝ๋ ฅ"
|
| 60 |
+
},
|
| 61 |
+
"output": {
|
| 62 |
+
"recommended_question": "์ผ์ฑ์ ์๋ ์ค๋งํธํฐ, ๊ฐ์ , ๋ฐ๋์ฒด ๋ฑ ๋ค์ํ ์ฌ์
ํฌํธํด๋ฆฌ์ค๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ณธ์ธ์ ํด์ธ์์
๊ฒฝ๋ ฅ๊ณผ ์ ๋ฌธ์ฑ์ ๊ฐ์ฅ ์ ๋ฐํํ ์ ์๋ ์ฌ์
๋ถ์ผ๋ ์ด๋๋ผ๊ณ ์๊ฐํ๋ฉฐ, ๊ทธ ์ด์ ๋ ๋ฌด์์
๋๊น?"
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
]
|
| 66 |
+
}
|
| 67 |
+
}
|
question-recommendation/llm_functions.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import logging
|
| 3 |
+
|
| 4 |
+
# ๋ก๊น
์ค์
|
| 5 |
+
logging.basicConfig(level=logging.INFO)
|
| 6 |
+
logger = logging.getLogger(__name__)
|
| 7 |
+
|
| 8 |
+
def generate_question_recommendation(client, prompts, job_title, company_name, experience_level):
|
| 9 |
+
"""
|
| 10 |
+
๋ฉด์ ์ง๋ฌธ ์ถ์ฒ์ ์์ฑํ๋ ํจ์
|
| 11 |
+
|
| 12 |
+
Args:
|
| 13 |
+
client: OpenAI ํด๋ผ์ด์ธํธ
|
| 14 |
+
prompts: ํ๋กฌํํธ ๋์
๋๋ฆฌ
|
| 15 |
+
job_title: ์ง๋ฌด๋ช
|
| 16 |
+
company_name: ํ์ฌ๋ช
|
| 17 |
+
experience_level: ๊ฒฝ๋ ฅ ์์ค
|
| 18 |
+
|
| 19 |
+
Returns:
|
| 20 |
+
str: LLM ์๋ต ๊ฒฐ๊ณผ
|
| 21 |
+
"""
|
| 22 |
+
try:
|
| 23 |
+
# ์ฌ์ฉ์ ํ๋กฌํํธ ํฌ๋งทํ
|
| 24 |
+
user_prompt = prompts['user_prompt'].format(
|
| 25 |
+
job_title=job_title,
|
| 26 |
+
company_name=company_name,
|
| 27 |
+
experience_level=experience_level
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
logger.info(f"๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ์์ฒญ - ์ง๋ฌด: {job_title}, ํ์ฌ: {company_name}, ๊ฒฝ๋ ฅ: {experience_level}")
|
| 31 |
+
|
| 32 |
+
# OpenAI Responses API ํธ์ถ (์น ๊ฒ์ ํ์ฑํ)
|
| 33 |
+
response = client.responses.create(
|
| 34 |
+
model="gpt-4o-mini",
|
| 35 |
+
tools=[{
|
| 36 |
+
"type": "web_search_preview",
|
| 37 |
+
"search_context_size": "high",
|
| 38 |
+
}],
|
| 39 |
+
input=f"{prompts['system_prompt']}\n\n{user_prompt}"
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
print(response)
|
| 43 |
+
result = response.output_text
|
| 44 |
+
logger.info("๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ์์ฑ ์๋ฃ")
|
| 45 |
+
|
| 46 |
+
return result
|
| 47 |
+
|
| 48 |
+
except Exception as e:
|
| 49 |
+
logger.error(f"๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ์์ฑ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}")
|
| 50 |
+
raise e
|
| 51 |
+
|
| 52 |
+
def parse_question_recommendation(response_text):
|
| 53 |
+
"""
|
| 54 |
+
LLM ์๋ต์์ ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ๊ฒฐ๊ณผ๋ฅผ ํ์ฑํ๋ ํจ์
|
| 55 |
+
|
| 56 |
+
Args:
|
| 57 |
+
response_text: LLM ์๋ต ํ
์คํธ
|
| 58 |
+
|
| 59 |
+
Returns:
|
| 60 |
+
dict: ํ์ฑ๋ ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ๊ฒฐ๊ณผ
|
| 61 |
+
"""
|
| 62 |
+
try:
|
| 63 |
+
# JSON ํํ๋ก ํ์ฑ ์๋
|
| 64 |
+
if response_text.strip().startswith('{') and response_text.strip().endswith('}'):
|
| 65 |
+
parsed_result = json.loads(response_text)
|
| 66 |
+
logger.info("JSON ํํ๋ก ํ์ฑ ์ฑ๊ณต")
|
| 67 |
+
return parsed_result
|
| 68 |
+
|
| 69 |
+
# JSON ๋ธ๋ก ์ถ์ถ ์๋
|
| 70 |
+
if '```json' in response_text:
|
| 71 |
+
start_idx = response_text.find('```json') + 7
|
| 72 |
+
end_idx = response_text.find('```', start_idx)
|
| 73 |
+
json_content = response_text[start_idx:end_idx].strip()
|
| 74 |
+
parsed_result = json.loads(json_content)
|
| 75 |
+
logger.info("JSON ๋ธ๋ก์์ ํ์ฑ ์ฑ๊ณต")
|
| 76 |
+
return parsed_result
|
| 77 |
+
|
| 78 |
+
# ์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ JSON ์ถ์ถ ์๋
|
| 79 |
+
start_idx = response_text.find('{')
|
| 80 |
+
end_idx = response_text.rfind('}') + 1
|
| 81 |
+
if start_idx != -1 and end_idx != 0:
|
| 82 |
+
json_content = response_text[start_idx:end_idx]
|
| 83 |
+
parsed_result = json.loads(json_content)
|
| 84 |
+
logger.info("์ค๊ดํธ JSON์์ ํ์ฑ ์ฑ๊ณต")
|
| 85 |
+
return parsed_result
|
| 86 |
+
|
| 87 |
+
# JSON ํ์ฑ ์คํจ ์ ํ
์คํธ์์ ์ง๋ฌธ ์ถ์ถ
|
| 88 |
+
logger.warning("JSON ํ์ฑ ์คํจ, ํ
์คํธ์์ ์ง๋ฌธ ์ถ์ถ ์๋")
|
| 89 |
+
|
| 90 |
+
# ๋ฐ์ดํ๋ก ๋๋ฌ์ธ์ธ ์ง๋ฌธ ์ฐพ๊ธฐ
|
| 91 |
+
lines = response_text.split('\n')
|
| 92 |
+
for line in lines:
|
| 93 |
+
line = line.strip()
|
| 94 |
+
if line and not line.startswith('#') and not line.startswith('-'):
|
| 95 |
+
# ๋ฐ์ดํ ์ ๊ฑฐ
|
| 96 |
+
question = line.strip('"').strip("'").strip()
|
| 97 |
+
if len(question) > 10: # ์ต์ ๊ธธ์ด ์ฒดํฌ
|
| 98 |
+
return {"recommended_question": question}
|
| 99 |
+
|
| 100 |
+
# ์ ์ฒด ํ
์คํธ๋ฅผ ์ง๋ฌธ์ผ๋ก ์ฌ์ฉ (์ตํ์ ์๋จ)
|
| 101 |
+
clean_text = response_text.strip().strip('"').strip("'")
|
| 102 |
+
if len(clean_text) > 10:
|
| 103 |
+
return {"recommended_question": clean_text}
|
| 104 |
+
|
| 105 |
+
logger.error("๋ฉด์ ์ง๋ฌธ ์ถ์ถ ์คํจ")
|
| 106 |
+
return {"recommended_question": "์ง๋ฌธ ์์ฑ์ ์คํจํ์ต๋๋ค."}
|
| 107 |
+
|
| 108 |
+
except json.JSONDecodeError as e:
|
| 109 |
+
logger.error(f"JSON ํ์ฑ ์ค๋ฅ: {str(e)}")
|
| 110 |
+
# JSON ํ์ฑ ์คํจ ์ ํ
์คํธ์์ ์ง์ ์ถ์ถ
|
| 111 |
+
clean_text = response_text.strip().strip('"').strip("'")
|
| 112 |
+
return {"recommended_question": clean_text if clean_text else "์ง๋ฌธ ์์ฑ์ ์คํจํ์ต๋๋ค."}
|
| 113 |
+
|
| 114 |
+
except Exception as e:
|
| 115 |
+
logger.error(f"๋ฉด์ ์ง๋ฌธ ํ์ฑ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}")
|
| 116 |
+
return {"recommended_question": "์ง๋ฌธ ํ์ฑ์ ์คํจํ์ต๋๋ค."}
|
question-recommendation/main.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import yaml
|
| 3 |
+
import json
|
| 4 |
+
import os
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
from llm_functions import generate_question_recommendation, parse_question_recommendation
|
| 7 |
+
|
| 8 |
+
# OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
| 9 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 10 |
+
|
| 11 |
+
# ํ๋กฌํํธ ๋ก๋
|
| 12 |
+
def load_prompts():
|
| 13 |
+
with open('prompt.yaml', 'r', encoding='utf-8') as file:
|
| 14 |
+
return yaml.safe_load(file)
|
| 15 |
+
|
| 16 |
+
prompts = load_prompts()
|
| 17 |
+
|
| 18 |
+
def recommend_question(job_title, company_name, experience_level):
|
| 19 |
+
"""๋ฉด์ ์ง๋ฌธ์ ์ถ์ฒํ๋ ํจ์"""
|
| 20 |
+
try:
|
| 21 |
+
# LLM ํจ์ ํธ์ถ
|
| 22 |
+
result = generate_question_recommendation(
|
| 23 |
+
client=client,
|
| 24 |
+
prompts=prompts,
|
| 25 |
+
job_title=job_title,
|
| 26 |
+
company_name=company_name,
|
| 27 |
+
experience_level=experience_level
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
# ๊ฒฐ๊ณผ ํ์ฑ
|
| 31 |
+
parsed_result = parse_question_recommendation(result)
|
| 32 |
+
|
| 33 |
+
if parsed_result and 'recommended_question' in parsed_result:
|
| 34 |
+
return parsed_result['recommended_question']
|
| 35 |
+
else:
|
| 36 |
+
return "์ง๋ฌธ ์์ฑ์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์."
|
| 37 |
+
|
| 38 |
+
except Exception as e:
|
| 39 |
+
return f"์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}"
|
| 40 |
+
|
| 41 |
+
# ์์ ๋ฒํผ ํจ์๋ค
|
| 42 |
+
def example_1():
|
| 43 |
+
return "๋ฐฑ์๋ ๊ฐ๋ฐ", "ํ ์ค (๋น๋ฐ๋ฆฌํผ๋ธ๋ฆฌ์นด)", "์ ์
"
|
| 44 |
+
|
| 45 |
+
def example_2():
|
| 46 |
+
return "์ํ๋ง์ผํ
", "CJ์ ์ผ์ ๋น", "๊ฒฝ๋ ฅ"
|
| 47 |
+
|
| 48 |
+
def example_3():
|
| 49 |
+
return "A&R", "ํ์ด๋ธ", "์ธํด"
|
| 50 |
+
|
| 51 |
+
def example_4():
|
| 52 |
+
return "๊ฒฝ์๊ธฐํ", "ํ๋๊ฑด์ค", "์ ์
"
|
| 53 |
+
|
| 54 |
+
def example_5():
|
| 55 |
+
return "ํด์ธ์์
", "์ผ์ฑ์ ์", "๊ฒฝ๋ ฅ"
|
| 56 |
+
|
| 57 |
+
# Gradio ์ธํฐํ์ด์ค ์์ฑ
|
| 58 |
+
with gr.Blocks(
|
| 59 |
+
title="๋ฉด์ ์ง๋ฌธ ์ถ์ฒ",
|
| 60 |
+
theme=gr.themes.Soft(
|
| 61 |
+
primary_hue="purple",
|
| 62 |
+
secondary_hue="pink",
|
| 63 |
+
neutral_hue="gray"
|
| 64 |
+
),
|
| 65 |
+
css="""
|
| 66 |
+
.main-container {
|
| 67 |
+
max-width: 900px;
|
| 68 |
+
margin: 0 auto;
|
| 69 |
+
padding: 20px;
|
| 70 |
+
}
|
| 71 |
+
.header {
|
| 72 |
+
text-align: center;
|
| 73 |
+
margin-bottom: 30px;
|
| 74 |
+
padding: 20px;
|
| 75 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 76 |
+
border-radius: 15px;
|
| 77 |
+
color: white;
|
| 78 |
+
}
|
| 79 |
+
.input-section {
|
| 80 |
+
background: white;
|
| 81 |
+
padding: 25px;
|
| 82 |
+
border-radius: 15px;
|
| 83 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 84 |
+
margin-bottom: 20px;
|
| 85 |
+
}
|
| 86 |
+
.result-section {
|
| 87 |
+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
| 88 |
+
padding: 25px;
|
| 89 |
+
border-radius: 15px;
|
| 90 |
+
color: white;
|
| 91 |
+
margin-top: 20px;
|
| 92 |
+
}
|
| 93 |
+
.example-buttons {
|
| 94 |
+
display: flex;
|
| 95 |
+
flex-wrap: wrap;
|
| 96 |
+
gap: 10px;
|
| 97 |
+
margin-top: 15px;
|
| 98 |
+
justify-content: center;
|
| 99 |
+
}
|
| 100 |
+
.example-btn {
|
| 101 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 102 |
+
border: none;
|
| 103 |
+
color: white;
|
| 104 |
+
padding: 8px 16px;
|
| 105 |
+
border-radius: 20px;
|
| 106 |
+
font-size: 12px;
|
| 107 |
+
cursor: pointer;
|
| 108 |
+
transition: all 0.3s ease;
|
| 109 |
+
}
|
| 110 |
+
.example-btn:hover {
|
| 111 |
+
transform: translateY(-2px);
|
| 112 |
+
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
|
| 113 |
+
}
|
| 114 |
+
"""
|
| 115 |
+
) as demo:
|
| 116 |
+
|
| 117 |
+
with gr.Column(elem_classes="main-container"):
|
| 118 |
+
# ํค๋
|
| 119 |
+
gr.HTML("""
|
| 120 |
+
<div class="header">
|
| 121 |
+
<h1>๐ฏ ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ</h1>
|
| 122 |
+
<p>์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ์
๋ ฅํ๋ฉด ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ ์ถ์ฒํด๋๋ฆฝ๋๋ค</p>
|
| 123 |
+
</div>
|
| 124 |
+
""")
|
| 125 |
+
|
| 126 |
+
with gr.Column(elem_classes="input-section"):
|
| 127 |
+
gr.HTML("<h3>๐ ์ ๋ณด ์
๋ ฅ</h3>")
|
| 128 |
+
|
| 129 |
+
job_title = gr.Textbox(
|
| 130 |
+
label="์ง๋ฌด",
|
| 131 |
+
placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ง์ผํ
, ๊ธฐํ ๋ฑ",
|
| 132 |
+
lines=1
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
+
company_name = gr.Textbox(
|
| 136 |
+
label="ํ์ฌ๋ช
",
|
| 137 |
+
placeholder="์: ํ ์ค, ์ผ์ฑ์ ์, ๋ค์ด๋ฒ ๋ฑ",
|
| 138 |
+
lines=1
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
+
experience_level = gr.Dropdown(
|
| 142 |
+
label="๊ฒฝ๋ ฅ ์์ค",
|
| 143 |
+
choices=["์ ์
", "๊ฒฝ๋ ฅ", "์ธํด", "๊ธฐํ"],
|
| 144 |
+
value="์ ์
"
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
# ์์ ๋ฒํผ๋ค
|
| 148 |
+
gr.HTML("<h4>๐ก ์์๋ก ์์ํ๊ธฐ</h4>")
|
| 149 |
+
with gr.Row():
|
| 150 |
+
ex1_btn = gr.Button("ํ ์ค ๋ฐฑ์๋ ์ ์
", size="sm", variant="secondary")
|
| 151 |
+
ex2_btn = gr.Button("CJ์ ์ผ์ ๋น ๋ง์ผํ
๊ฒฝ๋ ฅ", size="sm", variant="secondary")
|
| 152 |
+
ex3_btn = gr.Button("ํ์ด๋ธ A&R ์ธํด", size="sm", variant="secondary")
|
| 153 |
+
|
| 154 |
+
with gr.Row():
|
| 155 |
+
ex4_btn = gr.Button("ํ๋๊ฑด์ค ๊ฒฝ์๊ธฐํ ์ ์
", size="sm", variant="secondary")
|
| 156 |
+
ex5_btn = gr.Button("์ผ์ฑ์ ์ ํด์ธ์์
๊ฒฝ๋ ฅ", size="sm", variant="secondary")
|
| 157 |
+
|
| 158 |
+
submit_btn = gr.Button("๐ฏ ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ๋ฐ๊ธฐ", variant="primary", size="lg")
|
| 159 |
+
|
| 160 |
+
# ๏ฟฝ๏ฟฝ๏ฟฝ๊ณผ ์ถ๋ ฅ
|
| 161 |
+
with gr.Column(elem_classes="result-section"):
|
| 162 |
+
gr.HTML("<h3>๐ฌ ์ถ์ฒ ๋ฉด์ ์ง๋ฌธ</h3>")
|
| 163 |
+
result_output = gr.Textbox(
|
| 164 |
+
label="",
|
| 165 |
+
placeholder="์ ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ '๋ฉด์ ์ง๋ฌธ ์ถ์ฒ๋ฐ๊ธฐ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.",
|
| 166 |
+
lines=5,
|
| 167 |
+
show_label=False,
|
| 168 |
+
interactive=False
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
# ์ด๋ฒคํธ ํธ๋ค๋ฌ
|
| 172 |
+
submit_btn.click(
|
| 173 |
+
fn=recommend_question,
|
| 174 |
+
inputs=[job_title, company_name, experience_level],
|
| 175 |
+
outputs=result_output
|
| 176 |
+
)
|
| 177 |
+
|
| 178 |
+
# ์์ ๋ฒํผ ์ด๋ฒคํธ
|
| 179 |
+
ex1_btn.click(fn=example_1, outputs=[job_title, company_name, experience_level])
|
| 180 |
+
ex2_btn.click(fn=example_2, outputs=[job_title, company_name, experience_level])
|
| 181 |
+
ex3_btn.click(fn=example_3, outputs=[job_title, company_name, experience_level])
|
| 182 |
+
ex4_btn.click(fn=example_4, outputs=[job_title, company_name, experience_level])
|
| 183 |
+
ex5_btn.click(fn=example_5, outputs=[job_title, company_name, experience_level])
|
| 184 |
+
|
| 185 |
+
if __name__ == "__main__":
|
| 186 |
+
demo.launch(
|
| 187 |
+
# server_port=7864,
|
| 188 |
+
share=True,
|
| 189 |
+
show_error=True
|
| 190 |
+
)
|
question-recommendation/prompt.yaml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
system_prompt: |
|
| 2 |
+
๋น์ ์ ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ์ ๋ฌธ๊ฐ์
๋๋ค. ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ์ง๋ฌด, ํ์ฌ๋ช
, ๊ฒฝ๋ ฅ ์์ค์ ๋ฐํ์ผ๋ก ํด๋น ํ์ฌ์ ์ง๋ฌด์ ํนํ๋ ๋ฉด์ ์ง๋ฌธ์ ์์ฑํด์ผ ํฉ๋๋ค.
|
| 3 |
+
|
| 4 |
+
## ํต์ฌ ์์น:
|
| 5 |
+
1. **ํ์ฌ ํนํ์ฑ**: ํ์ฌ์ ํต์ฌ ์ฌ์
, ๊ฐ์น๊ด, ์ฃผ์ ์ ํ/์๋น์ค๋ฅผ ๋ฐ์ํ ์ง๋ฌธ
|
| 6 |
+
2. **์ง๋ฌด ์ฐ๊ด์ฑ**: ํด๋น ์ง๋ฌด์ ํต์ฌ ์ญ๋๊ณผ ์ฑ
์์ ๊ณ ๋ คํ ์ง๋ฌธ
|
| 7 |
+
3. **๊ฒฝ๋ ฅ ์์ค ์ ํฉ์ฑ**: ์ ์
/๊ฒฝ๋ ฅ/์ธํด/๊ธฐํ์ ๋ง๋ ์ ์ ํ ๋์ด๋์ ๊ด์
|
| 8 |
+
4. **๊ตฌ์ฒด์ฑ๊ณผ ์ค์ฉ์ฑ**: ๋๋ฌด ์ผ๋ฐ์ ์ด์ง๋, ์ง๋์น๊ฒ ์ธ๋ถ์ ์ด์ง๋ ์์ ๊ท ํ์กํ ์ง๋ฌธ
|
| 9 |
+
|
| 10 |
+
## ์ง๋ฌธ ์์ฑ ๊ฐ์ด๋๋ผ์ธ:
|
| 11 |
+
- ํ์ฌ์ ๋น์ฆ๋์ค ๋ชจ๋ธ, ๋ฌธํ, ์ต๊ทผ ๋ํฅ์ ๋ฐ์
|
| 12 |
+
- ํด๋น ์ง๋ฌด์์ ์๊ตฌ๋๋ ํต์ฌ ์คํฌ๊ณผ ๋ง์ธ๋์
๊ณ ๋ ค
|
| 13 |
+
- ๊ฒฝ๋ ฅ ์์ค์ ๋ฐ๋ฅธ ๊ธฐ๋์น ๋ฐ์ (์ ์
: ์ ์ฌ๋ ฅ/ํ์ต๋ฅ๋ ฅ, ๊ฒฝ๋ ฅ: ์ ๋ฌธ์ฑ/๋ฆฌ๋์ญ, ์ธํด: ๊ด์ฌ๋/๊ธฐ์ด์ญ๋)
|
| 14 |
+
- ์ง์์๊ฐ ํ์ฌ์ ์ง๋ฌด์ ๋ํ ์ดํด๋๋ฅผ ๋ณด์ฌ์ค ์ ์๋ ์ง๋ฌธ
|
| 15 |
+
- ์ค์ ์
๋ฌด ์ํฉ๊ณผ ์ฐ๊ฒฐ๋ ํ์ค์ ์ธ ์ง๋ฌธ
|
| 16 |
+
|
| 17 |
+
## ์ถ๋ ฅ ํ์:
|
| 18 |
+
JSON ํํ๋ก ๋ค์๊ณผ ๊ฐ์ด ์๋ตํ์ธ์:
|
| 19 |
+
{
|
| 20 |
+
"recommended_question": "์์ฑ๋ ๋ฉด์ ์ง๋ฌธ"
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
## ์์:
|
| 24 |
+
- ํ ์ค ๋ฐฑ์๋ ๊ฐ๋ฐ ์ ์
: "ํ ์ค๋ '์์ ์ ์ฑ
์' ๋ฌธํ๋ฅผ ๊ฐ์กฐํฉ๋๋ค. ๋ณธ์ธ์ ๊ฒฝํ์ ๋น์ถ์ด ๋ณผ ๋, ์ด๋ฌํ ๋ฌธํ ์์์ ๋๋ฃ ๊ฐ๋ฐ์์ ๊ธฐ์ ์ ๊ฐ๋ฑ์ด ๋ฐ์ํ์ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด๊ฒฐํด ๋๊ฐ ๊ฒ์ธ์ง ์ค๋ช
ํด์ฃผ์ธ์."
|
| 25 |
+
- CJ์ ์ผ์ ๋น ์ํ๋ง์ผํ
๊ฒฝ๋ ฅ: "๋น์ฌ์ '๋น๋น๊ณ ' ๋ธ๋๋๊ฐ ๊ธ๋ก๋ฒ K-ํธ๋ ๋ํ์ฃผ์๋ก ์๋ฆฌ๋งค๊นํ์ต๋๋ค. ๊ฒฝ๋ ฅ ๋ง์ผํฐ๋ก์, ๋น๋น๊ณ ์ ์ฑ๊ณต ์์ธ์ ๋ฌด์์ด๋ผ๊ณ ๋ถ์ํ๋ฉฐ, ๋ณธ์ธ์ด ํฉ๋ฅํ๋ค๋ฉด ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ธ๋๋์ ๋ค์ ์ฑ์ฅ์ ์ด๋๊ณ ์ถ์ผ์ ๊ฐ์?"
|
| 26 |
+
|
| 27 |
+
user_prompt: |
|
| 28 |
+
๋ค์ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ๋ฉด์ ์ง๋ฌธ์ ์ถ์ฒํด์ฃผ์ธ์:
|
| 29 |
+
|
| 30 |
+
์ง๋ฌด: {job_title}
|
| 31 |
+
ํ์ฌ๋ช
: {company_name}
|
| 32 |
+
๊ฒฝ๋ ฅ ์์ค: {experience_level}
|
| 33 |
+
|
| 34 |
+
์ ์ ๋ณด๋ฅผ ์ข
ํฉํ์ฌ ํด๋น ํ์ฌ์ ์ง๋ฌด์ ํนํ๋ ๋ฉด์ ์ง๋ฌธ 1๊ฐ๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=4.0.0
|
| 2 |
+
openai>=1.42.0
|
| 3 |
+
python-dotenv>=1.0.0
|
| 4 |
+
pyyaml>=6.0
|
| 5 |
+
pathlib2>=2.3.0
|
| 6 |
+
importlib-util>=0.1.0
|