63 lines
2.6 KiB
Python
63 lines
2.6 KiB
Python
import ollama
|
|
import json
|
|
import re
|
|
|
|
def analyze_voc_with_gemma(voc_content):
|
|
"""
|
|
Gemma 3 1B를 이용해 VOC 본문의 문맥을 분석하고 구조화된 데이터를 반환합니다.
|
|
"""
|
|
|
|
# 모델에게 부여할 페르소나와 규칙
|
|
system_prompt = (
|
|
"너는 부산교통공사의 열차 운행 민원 분석 전문가야. "
|
|
"다음 민원 내용을 분석해서 반드시 아래의 JSON 형식으로만 응답해줘.\n"
|
|
"형식: {\"line\": \"\", \"set_num\": \"\", \"car_num\": \"\", \"direction\": \"\", \"summary\": \"\"}\n"
|
|
"단, 정보가 없으면 빈 문자열로 둬."
|
|
)
|
|
|
|
# Few-shot: 소형 모델일수록 예시를 주는 것이 중요합니다.
|
|
user_prompt = f"""
|
|
민원 예시 1: "사하역에서 노포방향 열차를 탔는데 34편성 3호차 바닥이 더러워요."
|
|
응답: {{"line": "1호선", "set_num": "34편성", "car_num": "3호차", "direction": "노포행(하선)", "summary": "34편성 3호차 객실 바닥 오염 제보"}}
|
|
|
|
민원 내용: "{voc_content}"
|
|
응답:"""
|
|
|
|
try:
|
|
response = ollama.generate(
|
|
model='gemma3:1b', # 또는 본인이 설정한 gemma3 모델명
|
|
system=system_prompt,
|
|
prompt=user_prompt,
|
|
options={
|
|
"temperature": 0.1, # 낮을수록 일관된 결과가 나옵니다.
|
|
"num_predict": 150 # 출력 길이를 제한하여 속도를 높입니다.
|
|
}
|
|
)
|
|
|
|
# JSON 결과만 추출 (소형 모델은 가끔 앞뒤에 설명을 붙일 수 있음)
|
|
result_text = response['response']
|
|
json_match = re.search(r'\{.*\}', result_text, re.DOTALL)
|
|
|
|
if json_match:
|
|
return json.loads(json_match.group(0))
|
|
else:
|
|
return {"error": "JSON 파싱 실패", "raw": result_text}
|
|
|
|
except Exception as e:
|
|
return {"error": str(e)}
|
|
|
|
# --- 실제 테스트 실행 ---
|
|
if __name__ == "__main__":
|
|
# 1. 테스트용 비정형 민원
|
|
test_voc = "방금 서면역에서 다대포가는 기차 탔는데 3호차 구석에 누가 음료수를 쏟았네요. 34편성입니다."
|
|
|
|
print(f"--- VOC 분석 시작 (Gemma 3 1B) ---")
|
|
analysis_result = analyze_voc_with_gemma(test_voc)
|
|
|
|
# 2. 결과 출력
|
|
print(json.dumps(analysis_result, indent=4, ensure_ascii=False))
|
|
|
|
# 3. 기존 HWP 자동화 로직과 연계 예시
|
|
if "error" not in analysis_result:
|
|
print(f"\n[알림] 분석된 방향: {analysis_result.get('direction')}")
|
|
print(f"[알림] 요약 내용: {analysis_result.get('summary')}") |