Skip to content

Commit 3151801

Browse files
authored
Interview csy3 2 (#28)
잡플래너 ui 수정
1 parent 1ae60c2 commit 3151801

File tree

2 files changed

+273
-644
lines changed

2 files changed

+273
-644
lines changed

backend/core/views/job_planner/job_planner_view.py

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,6 +2100,11 @@ def post(self, request):
21002100
"error": "Invalid input type. Use 'url' or 'text'."
21012101
}, status=status.HTTP_400_BAD_REQUEST)
21022102

2103+
# 크롤링 결과 로그 출력
2104+
print(f"📄 크롤링 결과 ({len(company_info) if company_info else 0}자):")
2105+
print(company_info[:1000] if company_info else "(없음)")
2106+
print("--- 크롤링 끝 ---")
2107+
21032108
# LLM으로 종합 분석
21042109
analysis = self._analyze_company_with_llm(company_name, company_info)
21052110

@@ -2121,31 +2126,6 @@ def _fetch_from_url(self, url):
21212126
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
21222127
}
21232128

2124-
# 채용 사이트 → BeautifulSoup 방식
2125-
if any(domain in url for domain in JOB_SITE_DOMAINS):
2126-
response = requests.get(url, headers=headers, timeout=10)
2127-
response.raise_for_status()
2128-
soup = BeautifulSoup(response.text, 'html.parser')
2129-
for tag in soup(["script", "style"]):
2130-
tag.decompose()
2131-
text = soup.get_text(separator='\n', strip=True)
2132-
2133-
# 결과가 너무 짧으면 trafilatura로 fallback
2134-
if len(text) < 200:
2135-
import trafilatura
2136-
fallback = trafilatura.extract(response.text)
2137-
if fallback:
2138-
return fallback
2139-
2140-
return text
2141-
2142-
# 일반 사이트(회사 홈페이지, 뉴스, 블로그 등) → trafilatura
2143-
import trafilatura
2144-
downloaded = trafilatura.fetch_url(url)
2145-
text = trafilatura.extract(downloaded)
2146-
if not text:
2147-
raise Exception("URL에서 텍스트를 추출할 수 없습니다.")
2148-
21492129
# 채용 사이트 → BeautifulSoup 방식
21502130
if any(domain in url for domain in JOB_SITE_DOMAINS):
21512131
response = requests.get(url, headers=headers, timeout=10)
@@ -2173,7 +2153,7 @@ def _fetch_from_url(self, url):
21732153
return text
21742154

21752155
def _analyze_company_with_llm(self, company_name, company_info):
2176-
"""LLM으로 기업 종합 분석"""
2156+
"""LLM으로 기업 종합 분석 (크롤링 정보 부족 시 웹서치 보충)"""
21772157
api_key = os.getenv('OPENAI_API_KEY')
21782158
if not api_key:
21792159
return {
@@ -2185,34 +2165,7 @@ def _analyze_company_with_llm(self, company_name, company_info):
21852165
"welfare": {}
21862166
}
21872167

2188-
try:
2189-
client = openai.OpenAI(api_key=api_key)
2190-
2191-
response = client.chat.completions.create(
2192-
model="gpt-4o-mini",
2193-
messages=[
2194-
{
2195-
"role": "system",
2196-
"content": """당신은 IT 기업 분석 전문가입니다.
2197-
회사 정보를 바탕으로 다음 4가지 항목을 분석하여 JSON 형식으로 반환하세요:
2198-
1. 회사 개요 및 비전
2199-
2. 기술 스택 및 개발 문화
2200-
3. 성장성 및 안정성
2201-
4. 복지 및 근무환경
2202-
2203-
정보가 부족하면 일반적인 인사이트를 제공하세요."""
2204-
},
2205-
{
2206-
"role": "user",
2207-
"content": f"""다음 회사 정보를 분석해주세요:
2208-
2209-
회사명: {company_name}
2210-
2211-
정보:
2212-
{company_info[:3000]}
2213-
2214-
JSON 형식으로 반환:
2215-
{{
2168+
json_format = f"""{{
22162169
"company_name": "{company_name}",
22172170
"overview": {{
22182171
"description": "회사 소개 (2-3문장)",
@@ -2240,20 +2193,61 @@ def _analyze_company_with_llm(self, company_name, company_info):
22402193
"work_life_balance": "워라밸 평가 및 설명",
22412194
"remote_work": "리모트 근무 가능 여부"
22422195
}},
2243-
"overall_score": {{
2244-
"tech_score": 0.0-1.0,
2245-
"growth_score": 0.0-1.0,
2246-
"welfare_score": 0.0-1.0,
2247-
"total_score": 0.0-1.0
2248-
}},
22492196
"recommendation": "이 회사에 지원하면 좋은 이유 또는 주의사항 (3-4문장)"
22502197
}}"""
2251-
}
2252-
],
2253-
temperature=0.5
2254-
)
22552198

2256-
content = response.choices[0].message.content
2199+
try:
2200+
client = openai.OpenAI(api_key=api_key)
2201+
use_web_search = not company_info or len(company_info.strip()) < 200
2202+
2203+
if use_web_search:
2204+
# 크롤링 정보 부족 → Responses API + web_search로 실시간 검색
2205+
print(f"🔍 크롤링 정보 부족 ({len(company_info.strip()) if company_info else 0}자) → 웹서치 사용")
2206+
response = client.responses.create(
2207+
model="gpt-4o-mini",
2208+
tools=[{"type": "web_search_preview"}],
2209+
input=f"""당신은 IT 기업 분석 전문가입니다.
2210+
"{company_name}" 회사에 대해 웹 검색을 수행하여 다음 정보를 수집하고 JSON 형식으로 반환하세요.
2211+
검색 키워드 예시: "{company_name} 기술스택", "{company_name} 복지", "{company_name} 채용", "{company_name} 투자"
2212+
2213+
중요: 검색 결과에서 확인할 수 없는 정보는 절대 추측하거나 지어내지 마세요. 확인되지 않은 항목은 문자열이면 null, 리스트면 빈 배열 []로 남겨주세요.
2214+
2215+
반드시 아래 JSON 형식만 반환하세요:
2216+
{json_format}"""
2217+
)
2218+
content = response.output_text
2219+
else:
2220+
# 크롤링 정보 충분 → 기존 Chat Completions 방식
2221+
response = client.chat.completions.create(
2222+
model="gpt-4o-mini",
2223+
messages=[
2224+
{
2225+
"role": "system",
2226+
"content": """당신은 IT 기업 분석 전문가입니다.
2227+
회사 정보를 바탕으로 다음 4가지 항목을 분석하여 JSON 형식으로 반환하세요:
2228+
1. 회사 개요 및 비전
2229+
2. 기술 스택 및 개발 문화
2230+
3. 성장성 및 안정성
2231+
4. 복지 및 근무환경
2232+
2233+
중요: 제공된 정보에서 확인할 수 없는 항목은 절대 추측하거나 지어내지 마세요. 확인되지 않은 항목은 문자열이면 null, 리스트면 빈 배열 []로 남겨주세요."""
2234+
},
2235+
{
2236+
"role": "user",
2237+
"content": f"""다음 회사 정보를 분석해주세요:
2238+
2239+
회사명: {company_name}
2240+
2241+
정보:
2242+
{company_info[:3000]}
2243+
2244+
JSON 형식으로 반환:
2245+
{json_format}"""
2246+
}
2247+
],
2248+
temperature=0.5
2249+
)
2250+
content = response.choices[0].message.content
22572251

22582252
# JSON 추출
22592253
if '```json' in content:
@@ -2273,7 +2267,6 @@ def _analyze_company_with_llm(self, company_name, company_info):
22732267
"tech_stack": {"languages": [], "frameworks": [], "tools": [], "culture": "", "tech_blog": ""},
22742268
"growth": {"funding": "", "market_position": "", "growth_potential": "중", "stability": "중"},
22752269
"welfare": {"salary_level": "", "benefits": [], "work_life_balance": "", "remote_work": ""},
2276-
"overall_score": {"tech_score": 0.5, "growth_score": 0.5, "welfare_score": 0.5, "total_score": 0.5},
22772270
"recommendation": "정보가 부족하여 분석할 수 없습니다."
22782271
}
22792272

0 commit comments

Comments
 (0)