callcenter 프로젝트 완료

- 상담 기록 분석 및 요약
- 상담 기록 db 저장
- 상담 평가
- 상담 평가 db 저장
This commit is contained in:
2026-06-18 13:13:31 +09:00
parent b0503baac5
commit 5f5edb1e6d
20 changed files with 288 additions and 15 deletions
@@ -0,0 +1,39 @@
from backend.ai.llm import hugging_llm
from langchain_core.prompts import ChatPromptTemplate
from backend.prompts.all_prompt import SUMMARY_SYSTEM_PROMPT, CALL_ASSISTANT_PROMPT
from backend.repository.models import CallHistory
from backend.schemas.summary_schema import CallSummary, CallCreate
from sqlalchemy.orm import Session
from backend.schemas.assistant_schema import AssistantRequest
from langchain_chroma import Chroma
from backend.ai.embedding import watson_embedding
from langchain_core.output_parsers import StrOutputParser
# 질의 응답
def answer_assistant_question(customer_id:int, question:str, db:Session):
# 1 단계 : 벡터 DB에서 질의
# 벡터db 불러오기
vectorstore = Chroma(embedding_function=watson_embedding, persist_directory="./vectordb")
# as_retriever()
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# invoke() = docs => page_content join
docs = retriever.invoke(question)
sim_context = "\n\n".join(doc.page_content for doc in docs)
# 2 단계 : DB 검색
# 고객이 이전에 질문한 내역을 추출
if customer_id:
histories = db.query(CallHistory).filter(CallHistory.customer_id == customer_id).order_by(CallHistory.created_at.desc()).limit(5).all()
# 문제, 해결 컬럼만 문자열로 추출
customer_text ="\n".join([f"""
문제: {h.customer_issue}\n
해결: {h.resolution}
""" for h in histories])
# 1, 2 단계 => LLM => 답변 생성
prompt = ChatPromptTemplate.from_template(CALL_ASSISTANT_PROMPT)
chain = prompt | hugging_llm | StrOutputParser()
result = chain.invoke({"sim_context": sim_context, "customer_text": customer_text, "question": question})
return {"answer" : result}
# return AssistantRequest(answer=result)
@@ -1,8 +1,8 @@
from backend.ai.llm import hugging_llm
from langchain_core.prompts import ChatPromptTemplate
from backend.prompts.all_prompt import SUMMARY_SYSTEM_PROMPT
from backend.repository.models import CallHistory
from backend.schemas.summary_schema import CallSummary, CallCreate
from backend.prompts.all_prompt import SUMMARY_SYSTEM_PROMPT, CALL_EVALUATION_PROMPT
from backend.repository.models import CallHistory, CallEvaluation
from backend.schemas.summary_schema import CallSummary, CallCreate, CallEvaluationResponse
from sqlalchemy.orm import Session
from backend.schemas.summary_schema import CallRequest
@@ -41,15 +41,51 @@ def save_call_history(db, data):
return history
def evaluate_call():
def evaluate_call(transcript:str):
"""상담 평가"""
structured_llm = hugging_llm.with_structured_output(CallEvaluationResponse)
prompt = ChatPromptTemplate.from_template(CALL_EVALUATION_PROMPT)
pass
chain = prompt | structured_llm
return chain.invoke({"transcript":transcript})
def save_call_evaluation():
def calculate_score(evaluation):
score = 0
if evaluation.identity_verification:
score += 25
if evaluation.empathy:
score += 25
if evaluation.issue_resolution:
score += 25
if evaluation.survey_guidance:
score += 25
return score
def save_call_evaluation(db:Session, call_id:int, evaluation:CallEvaluationResponse):
"""상담 평가 내용 저장"""
score = calculate_score(evaluation)
entity = CallEvaluation(
call_id = call_id,
identity_verification = evaluation.identity_verification,
identity_verification_reason = evaluation.identity_verification_reason,
empathy = evaluation.empathy,
empathy_reason = evaluation.empathy_reason,
issue_resolution = evaluation.issue_resolution,
issue_resolution_reason = evaluation.issue_resolution_reason,
survey_guidance = evaluation.survey_guidance,
survey_guidance_reason = evaluation.survey_guidance_reason,
score = score,
)
db.add(entity)
db.commit()
db.refresh(entity)
pass
def create_call_history(req: CallRequest, db:Session):
# 요약
@@ -66,7 +102,19 @@ def create_call_history(req: CallRequest, db:Session):
customer_issue = summary.customer_issue,
resolution = summary.resolution
)
history = save_call_history(db = db, data = call_data)
return save_call_history(db = db, data = call_data)
# 상담 평가
evaluation = evaluate_call(req.transcript)
# 평가 저장
save_call_evaluation(db = db, call_id=history.call_id, evaluation=evaluation)
return CallSummary(
summary=summary.summary,
keywords=summary.keywords,
category=summary.category,
sentiment=summary.sentiment,
action_items=summary.action_items,
customer_issue=summary.customer_issue,
resolution=summary.resolution,
)
@@ -0,0 +1,23 @@
from sqlalchemy.orm import Session
from backend.repository.models import CallEvaluation
from backend.schemas.evaluation_schema import EvaluationResponse
# 질의 응답
def get_call_evaluation(call_id:int, db:Session):
# DB 검색 - call_id와 일치하는 정보 추출
if call_id:
evaluation = db.query(CallEvaluation).filter(CallEvaluation.call_id == call_id).first()
return EvaluationResponse(
identity_verification=evaluation.identity_verification,
identity_verification_reason=evaluation.identity_verification_reason,
empathy=evaluation.empathy,
empathy_reason=evaluation.empathy_reason,
issue_resolution=evaluation.issue_resolution,
issue_resolution_reason=evaluation.issue_resolution_reason,
survey_guidance=evaluation.survey_guidance,
survey_guidance_reason=evaluation.survey_guidance_reason,
score=evaluation.score,
created_at=evaluation.created_at,
)