Skip to content

Commit

Permalink
Code style update: GPT API 관련 공통 기능 모듈화
Browse files Browse the repository at this point in the history
  • Loading branch information
sangeun0612 committed Oct 24, 2024
1 parent a9c5610 commit 27066c0
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 154 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ key/vocal-entity-420406-b9648ba69fca.json
key/llama-433214-97936398ef7a.json
!key/*.md
key/WelfareBot.pem
key/welfarebot2-a32d04dcf403.json

# test audio
public/*
Expand Down
64 changes: 13 additions & 51 deletions backend/chatModel.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,29 @@
// GPT API를 호출해서 응답을 가져옴
const OpenAI = require("openai");
// 대화 진행 모델
const { callOpenAI } = require("./openaiClient");
const { promptData, modelData } = require("./configLoader");

const openai = new OpenAI({
api_key: process.env.OPENAI_API_KEY,
});

// JSON 파일에서 프롬프트와 모델명 가져오기
const fs = require("fs");
const path = require("path");
const promptPath = path.resolve(__dirname, "../key/prompt.json");
const promptData = JSON.parse(fs.readFileSync(promptPath, "utf-8"));
// 프롬프트, 모델명, 토큰 수 설정
const Prompt = promptData.playground_chat;

const modelNamePath = path.resolve(__dirname, "../key/model.json");
const modelNameData = JSON.parse(fs.readFileSync(modelNamePath, "utf-8"));
const modelName = modelNameData.Chat;
const modelName = modelData.Chat;
const maxTokens = 256;

// 각 사용자의 대화 기록을 저장
const conversationsMap = new Map();


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

// 대화 기록이 없으면 초기화
if (!conversations) {
conversations = [
{
role: "system",
content: Prompt,
},
];
conversationsMap.set(phoneNumber, conversations);
}
let conversations = conversationsMap.get(phoneNumber) || [ { role: "system", content: Prompt } ];

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

// 대화 기록을 기반으로 GPT API에 응답을 요청
const response = await openai.chat.completions.create({
model: modelName,
messages: conversations,
temperature: 0.0,
max_tokens: 256,
top_p: 0.0,
frequency_penalty: 0,
presence_penalty: 0,
});
conversations.push({ role: "user", content: gptRequest });

// gpt 응답 추출
const gptResponse = response.choices[0].message;
const gptContent = gptResponse.content;
// GPT API 호출
const gptContent = await callOpenAI(modelName, conversations, maxTokens);

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

// console.log("대화 모델 로그: ", conversations);
return gptContent;
Expand Down
70 changes: 21 additions & 49 deletions backend/chatSummaryModel.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,42 @@
// GPT API를 호출해서 응답을 가져옴
const OpenAI = require("openai");
// 대화 요약 모델
const { callOpenAI } = require("./openaiClient");
const { promptData, modelData } = require("./configLoader");
const { conversationsMap } = require("./chatModel");

const openai = new OpenAI({
api_key: process.env.OPENAI_API_KEY,
});

// JSON 파일에서 프롬프트 가져오기
const fs = require("fs");
const path = require("path");
const promptPath = path.resolve(__dirname, "../key/prompt.json");
const promptData = JSON.parse(fs.readFileSync(promptPath, "utf-8"));
// 프롬프트, 모델명, 토큰 수 설정
const Prompt = promptData.playground_summary;

const modelNamePath = path.resolve(__dirname, "../key/model.json");
const modelNameData = JSON.parse(fs.readFileSync(modelNamePath, "utf-8"));
const modelName = modelNameData.Summary;

const {conversationsMap} = require("./chatModel");
const modelName = modelData.Summary;
const maxTokens = 1024;

// 각 사용자의 대화 기록을 저장
const allConversationsMap = new Map();


// STT로 전사된 텍스트를 GPT API에 전달하고 응답을 처리하는 함수
async function getChatSummaryModelResponse(phoneNumber) {

// `chatModel.js`에서 해당 사용자의 대화 기록 가져오기
const contents = conversationsMap.get(phoneNumber);
// 대화 요약을 위해 진행된 대화 내용 가져오기
let contents = conversationsMap.get(phoneNumber) || [];

// 시스템 메시지를 제외한 사용자와 봇의 대화 내용을 하나의 문자열로 합침
const mergedContent = contents
.slice(1) // 첫 번째 시스템 메시지 제외
.map(item => `${item.role}: ${item.content}`) // role과 content를 조합
.join('\n'); // 줄바꿈으로 병합

// 요약 모델 프롬프트와 대화 기록
const conversations = [
{
role: "system",
content: Prompt,
},
...contents.slice(1), //시스템 프롬프트 제외
{ role: "system", content: Prompt },
{ role: "user", content: mergedContent },
];

//console.log("요약 모델 로그: ", conversations);
// GPT API 호출
const gptContent = await callOpenAI(modelName, conversations, maxTokens);

// 대화 기록을 기반으로 GPT API에 응답을 요청
const response = await openai.chat.completions.create({
model: modelName,
messages: conversations,
temperature: 0.0,
max_tokens: 1024,
top_p: 0.0,
frequency_penalty: 0,
presence_penalty: 0,
});

// gpt 응답 추출
const gptResponse = response.choices[0].message;
const gptContent = gptResponse.content;

// GPT의 응답을 대화 기록에 추가
conversations.push({
role: "assistant",
content: gptContent,
});

// 해당 사용자의 대화 요약 기록 저장
// 현재 대화 내용을 전체 대화 내용에 추가
conversations.push({ role: "assistant", content: gptContent });
allConversationsMap.set(phoneNumber, conversations);

// console.log("대화 요약 모델 로그: ", allConversationsMap.get(phoneNumber));

return gptContent;
}

Expand Down
13 changes: 13 additions & 0 deletions backend/configLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 프롬프트 및 모델명 가져오기
const fs = require("fs");
const path = require("path");

function loadConfig(fileName) {
const filePath = path.resolve(__dirname, `../key/${fileName}`);
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
}

const promptData = loadConfig("prompt.json");
const modelData = loadConfig("model.json");

module.exports = { promptData, modelData };
23 changes: 23 additions & 0 deletions backend/openaiClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// OpenAI 초기화 및 GPT API 호출
const OpenAI = require("openai");

const openai = new OpenAI({
api_key: process.env.OPENAI_API_KEY,
});

// GPT API 호출
async function callOpenAI(modelName, messages, maxTokens = 256) {
const response = await openai.chat.completions.create({
model: modelName,
messages: messages,
temperature: 0.0,
max_tokens: maxTokens,
top_p: 0.0,
frequency_penalty: 0,
presence_penalty: 0,
});

return response.choices[0].message.content;
}

module.exports = { callOpenAI };
5 changes: 1 addition & 4 deletions backend/playBeepSound.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ async function playBeepSound(ws, streamSid) {
audioStream.on('error', console.error);
}

/**
* 음성 파일을 읽어 mulaw 형식의 오디오 데이터로 변환하고 스트림을 반환
* @param {string} audioFilePath - 변환할 음성 파일 경로
*/
// 음성 파일을 읽어 mulaw 형식의 오디오 데이터로 변환하고 스트림을 반환
async function convertAudioToMulawStream(audioFilePath) {
const ffmpeg = require('fluent-ffmpeg');
const passThroughStream = new PassThrough();
Expand Down
10 changes: 5 additions & 5 deletions backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,17 @@ http.createServer(app).listen(80, () => {
console.log("HTTP 서버가 포트 80에서 실행 중입니다. HTTPS로 리디렉션합니다.");
});


// 전화 번호 목록 가져오기
app.get('/api/getPhoneNumbers', async (req, res) => {
try {
const phoneNumbers = await getPhoneNumbers();
res.json(phoneNumbers);
} catch (error) {
console.error("전화번호 목록 불러오기 오류:", error);
res.status(500).send("오류 발생");
}
});


// 위기 유형 가져오기
app.get('/api/getCrisisTypes', async (req, res) => {
const phoneNumber = decodeURIComponent(req.query.phoneNumber);
Expand All @@ -65,22 +64,23 @@ app.get('/api/getCrisisTypes', async (req, res) => {
res.json(crisisTypes);
} catch (error) {
console.error('위기 유형 가져오기 오류:', error);
res.status(500).send('오류 발생');
}
});


// 위기 유형 업데이트
app.post('/api/updateCrisisTypes', async (req, res) => {
const { phoneNumber, crisisTypes } = req.body;
try {
await updateCrisisTypes(phoneNumber, crisisTypes);
console.log('위기 유형 업데이트 성공');
res.status(200).send('위기 유형 업데이트 성공');
} catch (error) {
console.error('위기 유형 업데이트 오류:', error);
res.status(500).send('위기 유형 업데이트 실패');
}
});


// 현재 진행 중인 전화 상태 저장
const activeCalls = new Map();

Expand All @@ -100,7 +100,7 @@ app.get("/call", async (req, res) => {
// 전화 걸기
try {
await callUser(phoneNumber);
console.log("\n", phoneNumber, "로 전화가 성공적으로 걸렸습니다")
console.log("\n", phoneNumber, "로 전화가 성공적으로 걸렸습니다");
res.status(200).send('전화가 성공적으로 걸렸습니다.');
} catch (error) {
// 오류 발생 시 전화 상태 초기화
Expand Down
56 changes: 12 additions & 44 deletions backend/sttCorrectionModel.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,31 @@
// GPT API를 호출해서 응답을 가져옴
const OpenAI = require("openai");
// STT 오류 교정 모델
const { callOpenAI } = require("./openaiClient");
const { promptData, modelData } = require("./configLoader");

const openai = new OpenAI({
api_key: process.env.OPENAI_API_KEY,
});

// JSON 파일에서 프롬프트 가져오기
const fs = require("fs");
const path = require("path");
const promptPath = path.resolve(__dirname, "../key/prompt.json");
const promptData = JSON.parse(fs.readFileSync(promptPath, "utf-8"));
// 프롬프트, 모델명, 토큰 수 설정
const Prompt = promptData.stt_correction_241015;

const modelNamePath = path.resolve(__dirname, "../key/model.json");
const modelNameData = JSON.parse(fs.readFileSync(modelNamePath, "utf-8"));
const modelName = modelNameData.stt_correction;
const modelName = modelData.stt_correction;
const maxTokens = 256;

// 각 사용자의 대화 기록을 저장
const allConversationsMap = new Map();


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

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

// GPT API에 응답 요청
const response = await openai.chat.completions.create({
model: modelName,
messages: conversations,
temperature: 0.0,
max_tokens: 256,
top_p: 0.0,
frequency_penalty: 0,
presence_penalty: 0,
});

// gpt 응답 추출
const gptResponse = response.choices[0].message;
const gptContent = gptResponse.content;

conversations.push({
role: "assistant",
content: gptContent,
});
// GPT API 호출
const gptContent = await callOpenAI(modelName, conversations, maxTokens);

// 현재 대화 내용을 해당 사용자의 전체 대화 내용에 추가
// 현재 대화 내용을 전체 대화 내용에 추가
conversations.push({ role: "assistant", content: gptContent });
let userConversations = allConversationsMap.get(phoneNumber) || [];
userConversations.push(conversations);
allConversationsMap.set(phoneNumber, userConversations);
Expand Down
1 change: 0 additions & 1 deletion backend/tts.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const client = new TextToSpeechClient({
keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS,
});


async function sendTTSResponse(ws, streamSid, gptResponse){
const speechStream = await synthesizeSpeechToStream(gptResponse);

Expand Down

0 comments on commit 27066c0

Please sign in to comment.