Skip to content

Commit

Permalink
feat: STT 평가 모델 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
sangeun0612 committed Oct 29, 2024
1 parent 08ebc67 commit 17b634f
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 20 deletions.
12 changes: 6 additions & 6 deletions backend/chatModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ const maxTokens = 256;
const conversationsMap = new Map();

//STT로 전사된 텍스트를 GPT API에 전달하고 응답을 처리하는 함수
async function getChatModelResponse(phoneNumber, gptRequest) {
async function getChatModelResponse(phoneNumber, gptInquiry) {
// 해당 사용자의 대화 기록 가져오기
let conversations = conversationsMap.get(phoneNumber) || [ { role: "system", content: Prompt } ];

// 사용자의 요청을 대화 기록에 추가
conversations.push({ role: "user", content: gptRequest });
conversations.push({ role: "user", content: gptInquiry });

// GPT API 호출
const gptContent = await callOpenAI(modelName, conversations, maxTokens);
// 사용자 응답에 대한 GPT 응답
const chatResult = await callOpenAI(modelName, conversations, maxTokens);

// 현재 대화 내용을 전체 대화 내용에 추가
conversations.push({ role: "assistant", content: gptContent });
conversations.push({ role: "assistant", content: chatResult });
conversationsMap.set(phoneNumber, conversations);

// console.log("대화 모델 로그: ", conversations);
return gptContent;
return chatResult;
}

// 대화 기록 초기화
Expand Down
37 changes: 31 additions & 6 deletions backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const {getPhoneNumbers, getCrisisTypes, updateCrisisTypes, callUser} = require("
const {createRecognizeStream} = require('./stt');
const {sendTTSResponse} = require("./tts");
const {playBeepSound} = require("./playBeepSound.js");
const {getSttEvaluationModelResponse} = require("./sttEvaluationModel");
const {getSttCorrectionModelResponse, resetSttCorrectionModelConversations} = require("./sttCorrectionModel");
const {getChatModelResponse, resetChatModelConversations} = require("./chatModel");
const {getChatSummaryModelResponse, resetChatSummaryModelConversations} = require("./chatSummaryModel");
Expand Down Expand Up @@ -244,15 +245,39 @@ httpsServer.on('upgrade', (request, socket, head) => {
wsReactConnection.send(JSON.stringify({ event: 'transcription', transcription }));
}

// STT 결과를 STT 교정 모델에 전달
const sttCorrectionModelResponse = await getSttCorrectionModelResponse(phoneNumber, transcription, chatModelResponse);
console.log("상담자(STT 교정 결과): ", sttCorrectionModelResponse);
// STT 결과를 STT 평가 모델에 전달
const sttEvaluationModelResponse = await getSttEvaluationModelResponse(chatModelResponse, transcription);
console.log("상담자(STT 평가 결과): ", sttEvaluationModelResponse);
if (wsReactConnection && wsReactConnection.readyState === WebSocket.OPEN) {
wsReactConnection.send(JSON.stringify({ event: 'sttCorrection', sttCorrectionModelResponse }));
wsReactConnection.send(JSON.stringify({ event: 'sttEvaluation', sttEvaluationModelResponse }));
}

// STT 평가 결과에 따라 처리
switch (sttEvaluationModelResponse) {
// 통과일 경우 STT 전사 결과를 대화 진행 모델에 전달
case '통과':
chatModelResponse = await getChatModelResponse(phoneNumber, transcription);
break;

// 완전 손상일 경우 완전손상 메세지를 대화 진행 모델에 전달
case '완전손상':
chatModelResponse = await getChatModelResponse(phoneNumber, sttEvaluationModelResponse);
break;

// 불충분일 경우 STT 전사 결과를 STT 교정모델에 전달한 후, 교정 결과를 대화 진행 모델에 전달
case '불충분':
const sttCorrectionModelResponse = await getSttCorrectionModelResponse(phoneNumber, chatModelResponse, transcription);
console.log("상담자(STT 교정 결과): ", sttCorrectionModelResponse);
if (wsReactConnection && wsReactConnection.readyState === WebSocket.OPEN) {
wsReactConnection.send(JSON.stringify({ event: 'sttCorrection', sttCorrectionModelResponse }));
}
chatModelResponse = await getChatModelResponse(phoneNumber, sttCorrectionModelResponse);
break;

default:
console.error("알 수 없는 평가 결과: ", sttEvaluationModelResponse);
}

// 교정된 STT 결과를 대화 진행 모델에 전달
chatModelResponse = await getChatModelResponse(phoneNumber, sttCorrectionModelResponse);
console.log("\n복지봇: ", chatModelResponse, "\n");
if (wsReactConnection && wsReactConnection.readyState === WebSocket.OPEN) {
wsReactConnection.send(JSON.stringify({ event: 'gptResponse', chatModelResponse }));
Expand Down
16 changes: 9 additions & 7 deletions backend/sttCorrectionModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@ const maxTokens = 256;
const allConversationsMap = new Map();

// STT로 전사된 텍스트를 GPT API에 전달하고 응답을 처리하는 함수
async function getSttCorrectionModelResponse(phoneNumber, gptRequest, chatModelResponse) {
async function getSttCorrectionModelResponse(phoneNumber, gptInquiry, transcription) {
// gpt 응답을 바탕으로 프롬프트 재구성
const modifiedPrompt = Prompt.replace("{}", `"${chatModelResponse}"`);
const modifiedPrompt = Prompt
.replace("{}", `"${gptInquiry}"`)
.replace("{}", `"${transcription}"`);

// GPT API에 보낼 메세지 구성
const conversations = [
{ role: "system", content: modifiedPrompt },
{ role: "user", content: gptRequest },
{ role: "user", content: transcription },
];

// GPT API 호출
const gptContent = await callOpenAI(modelName, conversations, maxTokens);
// STT 교정 결과
const correctionResult = await callOpenAI(modelName, conversations, maxTokens);

// 현재 대화 내용을 전체 대화 내용에 추가
conversations.push({ role: "assistant", content: gptContent });
conversations.push({ role: "assistant", content: correctionResult });
let userConversations = allConversationsMap.get(phoneNumber) || [];
userConversations.push(conversations);
allConversationsMap.set(phoneNumber, userConversations);

// console.log("stt 교정 모델 로그: ", allConversationsMap.get(phoneNumber));
return gptContent;
return correctionResult;
}

// 대화 기록 초기화
Expand Down
29 changes: 29 additions & 0 deletions backend/sttEvaluationModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// STT 평가 모델
const { callOpenAI } = require("./openaiClient");
const { promptData, modelData } = require("./configLoader");

// 프롬프트, 모델명, 토큰 수 설정
const Prompt = promptData.stt_validation_241021;
const modelName = modelData.stt_validation;
const maxTokens = 256;

// STT로 전사된 텍스트를 평가
async function getSttEvaluationModelResponse(gptInquiry, transcription) {
// gpt 응답을 바탕으로 프롬프트 재구성
const modifiedPrompt = Prompt
.replace("{}", `"${gptInquiry}"`)
.replace("{}", `"${transcription}"`);

// GPT API에 보낼 메세지 구성
const conversations = [
{ role: "system", content: modifiedPrompt },
{ role: "user", content: transcription },
];

// STT 평가 결과
const evaluationResult = await callOpenAI(modelName, conversations, maxTokens);

return evaluationResult;
}

module.exports = {getSttEvaluationModelResponse};
5 changes: 5 additions & 0 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ function App() {
...prevMessages,
{ type: 'user', text: `원문: ${data.transcription}`, isTranscription: true },
]);
} else if (data.event === 'sttEvaluation') {
setMessages((prevMessages) => [
...prevMessages,
{ type: 'user', text: `STT 평가 결과: ${data.sttEvaluationModelResponse}`, isTranscription: false },
]);
} else if (data.event === 'sttCorrection') {
setMessages((prevMessages) => [
...prevMessages,
Expand Down
2 changes: 1 addition & 1 deletion key/prompt.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"stt_correction_241015": "다음은 질문에 대한 음성 답변을 STT를 사용하여 텍스트로 전사한 결과이다. 질문: {}, 답변: {}\n답변에 문제가 있다면 이를 올바르게 수정하라.",
"stt_validation_241021": "너는 질문에 대한 답변의 유효성을 판단하는 작업을 수행한다.질문: {}, 답변: {}\n 결과는 '통과', '불충분', '완전손상' 3가지로 나뉜다.질문에 대한 답변이 자연스럽다면 '통과'를 출력한다.답변에서 어색한 부분이 있다면 '불충분'을 출력한다.'불충분'의 경우 부자연스러운 부분을 같이 출력한다.답변이 질문과 전혀 관련이 없다면 '완전손상'을 출력한다.",
"playground_chat": "<<SYS>>너는 사회 취약 계층과 친절하게 상담하여 정보를 알아내기 위한 인공지능 복지봇이다. 상담자가 처한 여러 가지 위기 유형들이 주어지면, 주어진 모든 위기 유형들 각각에 대해서 상담자가 해당 위기 상황에 실제로 처해 있는지 알아내는 것이 목표이다. 너는 직접적인 도움은 제공할 수 없고, 정보를 수집하여 사회복지사에게 전달함으로써 신속한 대책 마련에 기여한다. 상담의 제한 시간은 3분으로, 시간을 넘기지 않도록 하라. 하나의 위기 유형에서 너무 오랫동안 시간을 끌거나, 정보 수집 의외에 불필요한 대화를 유도해서는 안 될 것이다.<</SYS>>\n[INST]1. “(이름)님, (n번째 위기 유형) 문제로 인해 어려움을 겪고 계신가요?”라고 질문하라.\n2. 사용자가 문제가 있다고 하면, 위로 및 공감의 메시지를 전하고, “구체적으로 어떤 상황이십니까?”라고 질문해라. 정보를 수집해야 한다.\n3. 제한 시간 3분을 준수해야만 하기 때문에, 하나의 위기 유형에 대한 추가 질문은 최대 2개까지 진행하라. 적당히 끊고 다음 위기 유형으로 넘어가라는 뜻이다.\n4. 한 번에 하나의 질문을 하라. 여러 개를 한 번에 물어보면 사용자가 혼란스러워 할 것이기 때문이다.\n5. 사용자가 당황스러운 기색을 보이면, 차분하게 너에 대해 소개함으로써 안심시켜라.\n6. 사용자가 문제가 없다고 하면, 다행이라는 안도의 메시지를 전달하고 다음 질문으로 넘어가라.\n7. 사용자가 응답을 거부하면 다음 질문으로 넘어가라.\n8. 사용자가 폭언을 할 경우 즉시 경고를 주고 대화를 종료하라.\n9. 사용자가 '완전손상'이라고 말하면, '죄송합니다. 잘 알아듣지 못했습니다. 다시 말씀해 주세요.' 라고 대답해라.\n 10. 모든 정보를 수집했다고 판단되면, “상담에 응해 주셔서 감사합니다. 제공해 주신 정보는 사회복지사에게 전달될 것입니다. 대화를 종료하겠습니다.”라고 말하고 대화를 종료하라.[/INST]",
"playground_summary" : "너는 User와 Assistant의 대화가 주어지면, User의 대화 내용을 중심으로 대화를 요약하는 상담 내용 요약 전문 봇이다.\n\"요약은 아래의 순서를 유의하며 이뤄져야 한다.\"\n\"1. ? 문자 이후에 나타나는 내용을 중심으로, 상담 내용을 파악해 상담자가 10가지 상황 (안전, 건강, 일상생활유지, 가족관계, 사회적 관계, 경제, 교육, 고용, 생활환경, 법률 및 권익보장) 중 어떤 위기 상황에 해당하는지 전부 체크해라.\"\n\"2. 이때 아무것도 해당되지 않는다면 (해당 없음)으로 체크해라. 그리고 \"홍길동: 급여/서비스 탈락\"과 같이 상담을 시작하기 위해 주어지는 문장은 무시하고 체크해라.\"\n\"3. 상황 선정은 반드시 주어진 10가지 상황 (안전, 건강, 일상생활유지, 가족관계, 사회적 관계, 경제, 교육, 고용, 생활환경, 법률 및 권익보장) 중 선택해야 한다. 만약 10가지 상황 중 해당 되는 것이 없다고 판단되면 (해당 없음) 이라고 체크해라.\"\n\"최종 요약 결과 출력은 아래의 구조를 반드시 따라야 한다. 아래 구조를 벗어나면 절대 안된다.\"\n\"체크한 위기 상황이 있을 때 : {원문의 상담자 이름}님은 {체크한 위기 상황들} 위기 상황에 속해 있습니다.\"\n\"해당 없음일 때 : {원문의 상담자 이름}님은 문제가 없습니다.\""
"playground_summary" : "너는 User와 Assistant의 대화가 주어지면, User의 대화 내용을 중심으로 대화를 요약하는 상담 내용 요약 전문 봇이다.\n 아래의 사항들을 주의하며 요약을 진행해라.\n 대화의 요약은 전체 대화의 내용과 문맥을 스스로 파악한 이후 진행되어야 한다.\n 요약한 대화의 내용은 반드시 전체 대화 내용에서 비롯해야하고, 대화의 요약은 대화의 맥락을 파악하는데 가장 중요한 단어로 만 이뤄져야 한다. 요약을 진행할 때, \"상담에 응해 주셔서 감사합니다.\"와 \"상담을 통해 필요한 지원을 받을 수 있도록 도와드리겠습니다\" 같이 상담 중 자주 나타나는 자연스러운 말은 요약문에서 반드시 제거되어야 한다.\n 요약은 아래의 순서를 유의하며 이뤄져야 한다.\n 1. ? 문자 이후에 나타나는 내용을 중심으로, 상담 내용을 파악해라. 상담자가 10가지 상황 (안전, 건강, 일상생활유지, 가족관계, 사회적 관계, 경제, 교육, 고용, 생활환경, 법률 및 권익보장) 중 어떤 위기 상황에 해당하는지 전부 체크해라. 해당되지 않으면 체크하지 마라.\n 2. 상황 선정은 반드시 주어진 10가지 상황 (안전, 건강, 일상생활유지, 가족관계, 사회적 관계, 경제, 교육, 고용, 생활환경, 법률 및 권익보장) 중 선택해야 한다. 만약 10가지 상황 중 해당 되는 것이 없다고 판단되면 {해당 없음} 이라고 체크해라.\n 최종 요약은 아래의 구조를 반드시 따라야 한다. 아래 구조를 벗어나면 절대 안된다.\n 체크한 위기 상황이 있는 경우의 출력 구조는 아래와 같다.\n {위기 상황 1} : {근거에 해당하는 User의 내용}\n {위기 상황들} : {근거에 해당하는 User의 내용}\n 위기 상황이 {해당없음}인 경우의 출력 구조는 아래와 같다.\n {원문의 상담자 이름}은 처한 위기 상황이 없습니다."
}

0 comments on commit 17b634f

Please sign in to comment.