자바스크립트 AI 챗봇 만들기 part3 : 자연어 처리와 사전 학습된 AI 모델 적용
part2까지 웹 UI와 기본 대화 로직을 완성했다. 이번에는 챗봇을 더 똑똑하게 만든다. 자연어 처리(NLP)를 통해 사용자의 의도를 파악하고, TensorFlow.js의 사전 학습된 QnA 모델을 적용해 질문에 답변한다.
이전엔 간단한 예시로 대체했지만, 이제 실제 사전 학습된 모델을 사용한다.
3부에서 무엇을 다루는가?
3부의 목표는 다음과 같다:
- 자연어 처리의 기본 개념을 이해한다.
- TensorFlow.js와 QnA 모델을 설정한다.
- 사용자의 질문을 분석하고 답변을 생성한다.
part2에서 만든 my-chatbot
폴더를 이어서 사용한다.
자연어 처리란 무엇인가?
자연어 처리(NLP)는 컴퓨터가 인간의 언어를 이해하고 생성하는 기술이다. 챗봇에서는 사용자가 입력한 문장을 분석해 의도를 파악하거나 질문에 답한다. 예를 들어, "오늘 날씨가 어때?"라고 물으면 "날씨"라는 의도를 인식하고 적절한 답변을 제공한다.
이번 포스팅에서는 TensorFlow.js의 QnA 모델을 사용한다. 이 모델은 BERT 기반으로, 주어진 문맥에서 질문에 대한 답을 찾아낸다.
TensorFlow.js와 QnA 모델 설정하기
TensorFlow.js는 자바스크립트로 머신러닝을 구현하는 라이브러리다. QnA 모델은 사전 학습된 상태로 제공되며, 설치 없이 CDN으로 바로 가져온다.
1. 필요한 스크립트 추가
index.html
의 안에 다음 스크립트를 추가한다:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/qna@latest"></script>
- 첫 번째는 TensorFlow.js 핵심 라이브러리다.
- 두 번째는 QnA 모델이다.
2. 모델 로드 확인
모델이 브라우저에서 잘 로드되는지 확인한다. 콘솔에 로드 메시지를 출력한다.
QnA 모델로 질문 처리하기
QnA 모델은 문맥(컨텍스트)과 질문을 입력받아 답변을 생성한다. 챗봇에 통합하려면 문맥을 미리 정의하고 질문을 처리한다.
문맥 정의
모델이 답변할 수 있는 기본 문맥을 설정한다. 예를 들어, 챗봇에 대한 정보다:
const context = `
이 챗봇은 자바스크립트로 만들어졌다. 이름은 Chatbot이며 bdool에서 개발했다.
현재 날짜는 2025년 2월 28일이다. 주요 기능은 대화와 질문에 답하는 것이다.
날씨 정보도 제공할 수 있다. 개발자는 사용자를 돕기 위해 만든다.
`;
이 문맥에서 사용자의 질문을 처리한다.
코드 수정
script.js
를 아래처럼 수정한다:
const messages = document.getElementById('chat-messages');
const userInput = document.getElementById('user-input');
const sendBtn = document.getElementById('send-btn');
function addMessage(text, isUser = false) {
const message = document.createElement('p');
message.textContent = text;
message.style.textAlign = isUser ? 'right' : 'left';
message.style.background = isUser ? '#ff4e00' : '#f0f0f0';
message.style.color = isUser ? '#fff' : '#333';
message.style.padding = '8px 12px';
message.style.margin = '5px 0';
message.style.borderRadius = '4px';
message.style.display = 'inline-block';
messages.appendChild(message);
messages.scrollTop = messages.scrollHeight;
}
// 기본 문맥 정의
const context = `
이 챗봇은 자바스크립트로 만들어졌다. 이름은 Chatbot이며 bdool에서 개발했다.
현재 날짜는 2025년 2월 28일이다. 주요 기능은 대화와 질문에 답하는 것이다.
날씨 정보도 제공할 수 있다. 개발자는 사용자를 돕기 위해 만든다.
`;
let qnaModel;
// 모델 로드
async function loadQnAModel() {
try {
qnaModel = await qna.load();
console.log('QnA 모델이 로드됐다');
addMessage('챗봇 준비가 완료됐다! 질문을 기다린다.');
} catch (err) {
console.error('모델 로드 실패:', err);
addMessage('모델 로드에 실패했다. 기본 응답만 제공한다.');
}
}
// 질문 처리
async function getAnswer(question) {
if (!qnaModel) {
return '모델이 아직 로드되지 않았다. 잠시 기다린다.';
}
try {
const answers = await qnaModel.findAnswers(question, context);
if (answers.length > 0 && answers[0].text) {
return answers[0].text;
}
return '질문에 대한 답을 찾지 못했다. 다른 질문을 해본다.';
} catch (err) {
console.error('답변 생성 실패:', err);
return '답변을 생성하지 못했다.';
}
}
// 기본 키워드 응답
function getKeywordResponse(input) {
input = input.toLowerCase();
if (input.includes('안녕')) return '안녕! 나도 반갑다.';
if (input.includes('뭐해')) return '너랑 대화하려고 기다린다!';
if (input.includes('날씨')) return '날씨를 알려면 도시 이름을 말해준다.';
return null;
}
async function sendMessage() {
const inputText = userInput.value.trim();
if (inputText) {
addMessage(inputText, true);
const keywordResponse = getKeywordResponse(inputText);
let response;
if (keywordResponse) {
response = keywordResponse;
} else {
response = await getAnswer(inputText);
}
setTimeout(() => addMessage(response), 500);
userInput.value = '';
}
}
sendBtn.addEventListener('click', sendMessage);
userInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
// 페이지 로드 시 모델 초기화
window.onload = loadQnAModel;
코드 설명
- loadQnAModel
: 페이지 로드 시 QnA 모델을 초기화한다. 성공하면 메시지를 표시한다.
- getAnswer
: 사용자의 질문을 문맥과 함께 모델에 전달하고 답변을 받는다.
- getKeywordResponse
: 기본 키워드 응답을 우선 처리한다.
- sendMessage
: 키워드 응답이 없으면 모델로 질문을 처리한다.
테스트
브라우저에서 index.html
을 열고 다음 질문을 테스트한다:
- "챗봇의 이름이 뭐야?" → "Chatbot" 반환
- "누가 만들었어?" → "bdool" 반환
- "안녕" → 키워드 응답 "안녕! 나도 반갑다."
모델 로드에 몇 초 걸릴 수 있다. F12로 콘솔을 확인한다.
QnA 모델의 동작 원리
QnA 모델은 BERT(Transformers 기반)를 사용한다. 문맥과 질문을 토큰화하고, 답변 가능성을 계산해 가장 적합한 텍스트를 반환한다.
- **문맥**: 고정된 텍스트다. 질문에 답할 수 있는 정보를 담는다.
- **제한**: 문맥에 없는 정보는 답하지 못한다.
더 많은 정보를 처리하려면 문맥을 동적으로 업데이트하거나 다른 모델을 고려한다.
성능 및 한계
장점
- 학습 없이 바로 사용한다.
- 브라우저에서 실행되니 서버가 필요 없다.
한계
- 모델 크기가 커서 로드 시간이 길다 (약 100MB).
- 문맥에 의존하니 일반 대화는 제한적이다.
로드 시간이 길면 사용자에게 "모델 로드 중이다" 메시지를 표시한다.
개선 방법
- **문맥 확장**: API로 동적 데이터를 추가한다.
- **다른 모델**: 의도 분류 모델(예: Universal Sentence Encoder)을 혼합한다.
마무리
사전 학습된 QnA 모델을 챗봇에 적용했다. 이제 질문에 대한 답변을 생성한다. 4부에서는 외부 API를 연동해 날씨 기능을 추가한다.
'코딩 공부 > 자바스크립트 실습' 카테고리의 다른 글
자바스크립트 AI 챗봇 만들기 part5 (2) | 2025.02.28 |
---|---|
자바스크립트 AI 챗봇 만들기 part4 (2) | 2025.02.28 |
자바스크립트 AI 챗봇 만들기 Part 2 (0) | 2025.02.28 |
자바스크립트 AI 챗봇 만들기 Part 1 (2) | 2025.02.28 |
자바스크립트로 만드는 실시간 채팅 앱 (Part 3) (1) | 2025.02.26 |