# 패키지 불러오기
import re
import requests
import streamlit as st
from transformers import pipeline
# 글로벌 변수 선언
## 모델 불러오기(https://huggingface.co/gangyeolkim/kobart-korean-summarizer-v2) 는 테스트용 모델 입니다.
pipe = pipeline("summarization", model="gangyeolkim/kobart-korean-summarizer-v2")
## assitant 아바타 이미지 경로
assistant_icon_path = "https://huggingface.co/spaces/randmimc/aitom/resolve/main/chat_icon/assistant.ico"
## 세션 상태에서 approval_state 및 messages 초기화
## ※ 세션(session) :
## 사용자의 인터랙션을 관리하는 기능입니다.
## Streamlit은 기본적으로 사용자가 앱과 상호작용할 때마다 전체 코드가 다시 실행되는 구조인데,
## 세션 상태(Session State)를 활용하면 데이터를 유지하면서도 효율적인 앱을 만들 수 있습니다.
if "approval_state" not in st.session_state:
st.session_state.approval_state = "require"
if "messages" not in st.session_state:
st.session_state.messages = []
if "number" not in st.session_state:
st.session_state.number = []
# CSS 작성
## st.markdown는 텍스트를 마크다운 형식으로 랜더링 하는 함수이지만, unsafe_allow_html=True 옵션을 사용하면 HTML/CSS를 직접 적용할 수 있습니다.
## 스트림릿에서 디폴트로 적용하는 디자인이 맘에 들지 않는다면 CSS를 작성하여 변경할 수 있습니다.
st.markdown("""
""", unsafe_allow_html=True)
# 메세지 wrapper
# html 테그를 이용하여 챗팅 매세지마다 css 스타일을 적용하기 위해 작성된 함수입니다.
def user_message_style(question):
return f"""
"""
def assistant_message_style(assistant_icon_path, answer):
return f"""
{answer}
"""
# BACK
## 과거 채팅 내용 출력
## 스트림릿의 st.chat_input() 메서드는 사용자가 입력을 주면 세션내용을 기억하면서 코드를 다시 실행하는 특성이 있습니다.
## 따라서 세션에 저장된 과거 대화 내용을 화면에 출력하기 위해서 새로 실행된 코드에 과거 내용을 미리 뿌려둘 수 잇게 아래와 같은 코드를 작성해 두어야 합니다.
for message in st.session_state.messages:
if message["role"] == "user":
st.markdown(user_message_style(message["content"]), unsafe_allow_html=True)
else:
st.markdown(assistant_message_style(assistant_icon_path, message["content"]), unsafe_allow_html=True)
# 인증 메세지
## 본 코드는 다른 챗봇과 달리 인증을 위해 챗봇이 먼저 사용자에게 말을 거는 주고를 가집니다.
## 세션이 아무 메세지도 가지고 있지 않다면 인증을 위한 말을 먼저 걸게 구성합니다.
## 인증 메세지
if not st.session_state.messages:
greeting = "접속 코드를 입력해주세요"
st.session_state.messages.append({"role": "assistant", "content": greeting})
st.markdown(assistant_message_style(assistant_icon_path, greeting), unsafe_allow_html=True)
## 인증 및 응답 생성
## prompt :=`는 "월러스 연산자" (:=, walrus operator)로, 입력값이 있으면 이를 prompt 변수에 할당하면서 동시에 조건문을 실행하는 기능을 합니다.
if prompt := st.chat_input():
# 사용자 질문 세션에 저장
st.session_state.messages.append({"role": "user", "content": prompt})
# 사용자 질문 화면에 표시
st.markdown(user_message_style(prompt), unsafe_allow_html=True)
# 인증
if st.session_state.approval_state == "require":
url = "http://llm.theimc.co.kr/reference/"
st.session_state.number = prompt
response = requests.get(url, data={'number':st.session_state.number})
if response.text == "true":
st.session_state.approval_state = "approved"
response = "이제 8b 모델을 사용할 수 있습니다. 단 디자인은 채팅 형태이지만 멀티턴(말이 대화처럼 연결되는 기능)을 지원하지 않습니다. 차후 업데이트 예정입니다."
else:
response = "승인되지 않았습니다. 접속 코드를 다시 입력해주세요"
# 응답 생성
else:
url = "http://llm.theimc.co.kr/reference/base_sllm"
headers = {"Content-Type": "application/x-www-form-urlencoded",
"secret-key" : st.session_state.number}
data = {
"question": prompt
}
response = requests.post(url, headers=headers, data=data)
response = response.json()
print(response)
# 어시스턴스의 메세지를 세션에 저장
st.session_state.messages.append({"role": "assistant", "content": response})
# 어시스턴스의 메세지를 화면에 표시
st.html(assistant_message_style(assistant_icon_path, response))