한창 중간고사가 끝나고 밀린 강의와 과제에 허덕이던 11월 초 청천벽력같은 과제가 떨어졌습니다. 인공지능 수업에서 팀 프로젝트 과제를 하나 내주었습니다.
파이썬으로 규칙 기반 챗봇을 만드는 과제입니다.
지식을 규칙의 형태로 표현하고 주어진 문제 상황에 적용될 수 있는 규칙들을 사용하여 문제에 대한 해를 찾도록 하는 지식 기반 시스템입니다.
규칙(rule) : 문제 해결을 위한 지식
사실(fact) : 문제 영역에 대해 알려진 데이터나 정보
전체 규칙의 집합을 관리하는 부분
생성 메모리(production memory)라고도 합니다.
사용자로부터 받은 문제에 대한 정보를 관리
추론과정의 중간결과를 저장하고, 유도된 최종해 저장
작업 메모리에 저장되는 모든 것을 사실이라 합니다.
추론 엔진(inference engine)
실행할 수 있는 규칙을 찾아서, 해당 규칙을 실행하는 역할
패턴 매칭 - 경합 해소 - 규칙 실행의 과정 반복패턴 매칭(pateern matching)
작업 메모리의 사실과 규칙베이스에 있는 규칙의 조건부를 대조하여 일치하는 규칙을 찾는 과정
경합 집합(conflict set)
규칙들의 집합, 실행 가능한 규칙들의 집합
경합 해소(conflict resolution)
경합 집합에서 하나의 규칙을 선택
사용자 인터페이스(user interface)
규칙베이스 및 작업 메모리 관리 및 추론 엔진 조작
외부 인터페이스(external interface)
외부 데이터나 함수의 기능 사용 지원
프로젝트에서 기반으로 사용한 규칙 기반 챗봇 예제 코드
규칙 기반 챗봇은 사용자가 입력을 하면 그 입력에 매치되는 규칙(대답)을 응답합니다.
교수님께서 예제로 주신 코드를 기반으로 개발을 진행했습니다. 하지만, 예제에 있는 wordnet
유의어 모듈은 한글을 지원하지 않기 때문에 번역을 하거나 한국어 자연어 처리 라이브러리인 KONLPY
를 사용해야 했습니다.
해결책으로 네이버 파파고 API를 사용했습니다. 사용자 입력을 영어로 번역하여 그 결과에 wordnet
을 적용할 수 있었습니다.
백엔드 개발을 목표로 하고 있는 제가 가장 흥미를 느낄 수 있었던 부분입니다. 개강 전 열심히 공부했던 내용이 과연 어떻게 도움이 될지 궁금했습니다.
사용자 인터페이스는 정해진 것은 아니지만, 팀 수준에 맞게 터미널, 웹, 앱 등을 활용해야 했습니다. 어떻게 할 지 고민하다 7달전 html과 css 공부를 할 때 카카오톡 클론코딩을 했던 것이 생각나 그 화면을 활용하기로 했습니다.
위와 같은 화면입니다.
화면 개발을 하며 이전에 배웠던 HTML, CSS, Javascript등의 개념을 복습할 수 있었습니다.
가장 어려웠던 점은 비동기 통신 구현입니다. 입력 버튼을 누르면 form
태그의 효과때문인지 새로고침이 되어 초기화가 되었습니다. 화면 새로고침 없이 내가 원하는 부분만 리로드 될 수 있게 만들고 싶었습니다.
JQuery와 AJAX를 활용하여 구현할 수 있었습니다. 아래는 코드의 일부입니다.
var request = {'data':userText}; // json 형식으로 만들기
$.ajax({ // ajax로 서버와 비동기 통신하는 코드 -> 새로고침 하지 않고 통신 가능
type : "POST",
url : '{{url_for("data")}}',
dataType : "JSON", // json으로 통신
data : JSON.stringify(request),
contentType: "application/json",
error : function(){
console.log("서버와 통신 실패");
alert('서버와 통신 실패');
},
success : function(response){
console.log("서버와 통신 성공");
console.log(time)
time[0].innerText = response['time'];
text[0].innerHTML = response['chatbotText'];
...
저는 사실 개강 전 열심히 공부했던 Spring
프레임워크를 사용해보고 싶었지만, python으로만 개발해야 했기 때문에, Flask
라는
웹 프레임워크를 사용해보았습니다. 프레임워크가 달라도 근본적인 내용들은 비슷할 것이라고 생각했습니다.
실제로 개발을 해보니, Spring을 공부했던 것이 큰 도움이 되었습니다.
화면도 하나뿐인 간단한 프로젝트라 서버 개발은 아래의 코드가 전부입니다.
from flask import Flask, render_template, request, jsonify
import chatbot
import datetime
import translate
from pytz import timezone
app = Flask(__name__)
@app.route('/') # '/' == 'index.html'
def index():
today = translate.en_to_ko(datetime.date.today().strftime('%A %B %d, %Y')) # 날짜 데이터 보내주기
time = datetime.datetime.now(timezone('Asia/Seoul')).strftime('%p %I:%M')
return render_template('index.html', today=today, time=time) # 채팅창 랜더링
@app.route('/data', methods = ['POST']) #
def data():
req = request.get_json() # 요청에 사용자 입력에서 값을 가져옴
text = req['data']
print("사용자 입력 :",text)
response = chatbot.pick_response(text) # 사용자 입력에 대한 챗봇의 응답
print("챗봇 응답 : ", response)
time = datetime.datetime.now(timezone('Asia/Seoul')).strftime('%p %I:%M')
data = {'chatbotText' : response, 'time' : time}
return jsonify(data)
if __name__ == '__main__':
app.run(port=5001, debug=True)
추가로 파이썬으로 구현된 웹 어플리케이션을 웹 호스팅해주는 서비스인 Pythonanywhere
을 통하여 배포도 할 수 있었습니다.
'서버를 이렇게 배포하는구나' 라는 것도 어느정도 알게 되었습니다.
사용자가 맛집을 추천해달라고 지역과 음식 이름을 입력하면, 네이버 검색 API를 활용하여 지역
+ 이름
+ '맛집' 으로 검색된 상위 10개 식당정보를 가져옵니다. 그 정보를 활용하여 응답을 구성합니다.
제가 복학 전 주로 공부했던 내용들을 실제 과제에 써볼 수 있어 이제까지 공부했던 것들이 도움이 되는 보람찬 느낌을 받았습니다.
보통 과제 하나를 할때는 많게는 3일이 걸렸는데, 이 과제는 일주일정도 시간을 들인 진심을 다한 과제였습니다. 다른 공부도 할 것이 많아 이 프로젝트에 더 시간을 투자하기 어려운게 아쉬웠습니다.
비록 매우 작지만, 드디어 한 걸음을 내딛은 느낌입니다. 이후 하게될 더 큰 프로젝트들은 더 개선된 모습을 볼 수 있을 것이라고 생각합니다.