@@ -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