Skip to content

Commit

Permalink
Merge branch 'main' of github.com:kookmin-sw/capstone-2024-30
Browse files Browse the repository at this point in the history
  • Loading branch information
mclub4 committed May 27, 2024
2 parents a056bf0 + 11ca2c5 commit 00d3785
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 39 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/69c09b39-f44e-4ed
<td><img src="https://github.com/kookmin-sw/capstone-2024-30/assets/52407470/7627b57d-585c-4021-b02a-5ae6daded453" width="250"></td>
</tr>
<tr align="center">
<td>최지훈</td>
<td>김민제</td>
<td>조현진</td>
<td><a href="https://github.com/ji-hunc">최지훈</a></td>
<td><a href="https://github.com/kevinmj12">김민제</a></td>
<td><a href="https://github.com/mclub4">조현진</a></td>
</tr>
<tr align="center">
<td>****1683</td>
Expand All @@ -171,9 +171,9 @@ https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/69c09b39-f44e-4ed
<td><img src="https://github.com/kookmin-sw/capstone-2024-30/assets/52407470/1c9ac172-5d97-4002-b254-c003f5d07ac2" width="250"></td>
</tr>
<tr align="center">
<td>채원찬</td>
<td>김혜성</td>
<td>최영락</td>
<td><a href="https://github.com/BlueBerrySoda">채원찬</a></td>
<td><a href="https://github.com/Borikhs">김혜성</a></td>
<td><a href="https://github.com/guahama">최영락</a></td>
</tr>
<tr align="center">
<td>****1676</td>
Expand Down
16 changes: 16 additions & 0 deletions ai/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
### API KEY

OPENAI_API_KEY =
CLOVA_KEY =
CLOVA_URL =
LANGCHAIN_API_KEY =
TAVILY_API_KEY =
DEEPL_API_KEY =

### Database

DB_ENDPOINT =
DB_PORT =
DB_NAME =
MYSQL_USERNAME =
MYSQL_PASSWORD =
20 changes: 17 additions & 3 deletions ai/AI.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,38 @@
# Usage
다음 세 가지 방법 중 선택

### 1. 외국민 App
### 1. 외국민 App (추천) `gpt-4o 모델`
플레이스토어의 외국민 어플리케이션을 다운받아 챗봇을 사용

### 2. Python

이 방법은 API KEY가 필요 합니다!

1. `git clone https://github.com/kookmin-sw/capstone-2024-30.git`
2. `cd YOUR PATH/ai/`
3. `pip install -r requirements.txt`
4. 벡터 저장소 FAISS 폴더를 `/ai` 에 위치 [다운로드 링크](https://drive.google.com/file/d/1-U5X_xRg0PLITrDWDNMeZK_NAP5IIwsL/view?usp=sharing)
5. `python run_chatbot.py`
5. /ai에 `.env` 파일 생성
```
OPENAI_API_KEY =
LANGCHAIN_API_KEY =
TAVILY_API_KEY =
CHANNEL_ID =
DEEPL_API_KEY =
PAPAGO_ID =
PAPAGO_API_KEY =
```
7. `python run_chatbot.py`

### 3. DiscordBot
### 3. DiscordBot `gpt-3.5-turbo`

![image](https://github.com/kookmin-sw/capstone-2024-30/assets/54922676/ea2fd088-3bfa-4fb1-940f-ab34dc6b74d0)

- 디스코드 채널의 KUKU 봇 초대 후 명령어를 통해 채팅
- 봇 초대 권한 필요 (서버 관리자)
- 봇 초대 링크 : https://discord.com/oauth2/authorize?client_id=1229021729192677488
- `!p 질문 내용` 명령어로 채팅 가능
- (비용 문제로 gpt-3.5-turbo를 사용중. 외국민 앱과 성능이 다를 수 있음)

# Metrics
![image](https://github.com/kookmin-sw/capstone-2024-30/assets/54922676/2d4ed4fc-1f19-44a4-aa30-915b39c84a1c)
Expand Down
Binary file modified ai/FAISS/NAVER/index.faiss
Binary file not shown.
Binary file modified ai/FAISS/NAVER/index.pkl
Binary file not shown.
6 changes: 0 additions & 6 deletions ai/llm/llm_rag.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ def set_chain(self):
self.score_route
)

self.translate_chain = (
self.translate_prompt
| self.llm
| StrOutputParser()
)

def qna_route(self, info):
if "casual" in info["topic"].lower():
self.result = self.casual_answer_chain.invoke(self.ko_query)
Expand Down
5 changes: 3 additions & 2 deletions ai/llm/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ def casual_prompt():
def is_qna_prompt():
prompt = PromptTemplate.from_template(
"""Given the user input below, classify it as either being about `question`, `casual`.
Input that asks for information is always classified as a question.
Do not respond with more than one word.
Input that asks for information is always classified as a 'question'. On the other hand, inputs that have casual conversations or ask about you should be classified as casual.
<input>
{input}
</input>
Expand Down Expand Up @@ -43,6 +42,8 @@ def rag_prompt():
'''
You are an assistant 'KUKU' for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.
REMEMBER : your name is 'KUKU'.
Question: {question}
Context: {context}
Expand Down
3 changes: 2 additions & 1 deletion ai/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ langchainhub==0.1.15
beautifulsoup4==4.12.3
pypdf==4.1.0
python-dotenv==1.0.1
langchain-text-splitters==0.0.1
langchain-text-splitters==0.0.1
tavily-python
2 changes: 1 addition & 1 deletion ai/run_chatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@
if q == str(0):
break
print('AI : ', end='')
print(llm.query(q, 'en'))
print(llm.query(q, 'ko'))
print()
24 changes: 11 additions & 13 deletions ai/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

class Query(BaseModel):
query: str
target_lang: str

class CustomException(Exception):
def __init__(self, name: str):
Expand All @@ -47,10 +48,11 @@ async def lifespan(app:FastAPI):
naver_vdb.load_local(vector_db_path + '/NAVER')

llm = LLM_RAG(trace=True)
llm.set_retriver(data_type='notice', retriever=notice_vdb.get_retriever(k=2))
llm.set_retriver(data_type='school_info', retriever=school_vdb.get_retriever(k=3))
llm.set_retriver(data_type='naver', retriever= naver_vdb.get_retriever(k=5))
llm.set_retriver(data_type='notice', retriever=notice_vdb.get_retriever())
llm.set_retriver(data_type='school_info', retriever=school_vdb.get_retriever())
llm.set_retriver(data_type='naver', retriever=school_vdb.get_retriever())
llm.set_chain()
vdb = VectorDB()
yield

app = FastAPI(lifespan=lifespan)
Expand All @@ -75,7 +77,7 @@ async def lifespan(app:FastAPI):
allow_headers=["*"],
)

@sched.scheduled_job('cron', hour='1', minute='30', id='load announcement')
@sched.scheduled_job('cron', hour='0', minute='30', id='load announcement')
def log_new_announcements():
# 하루 전의 시간 계산
one_day_ago = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=1)
Expand All @@ -84,20 +86,20 @@ def log_new_announcements():
# 조회된 announcement 로그에 기록
docs = []
for announcement in new_announcements:
doc = Document()
doc.page_content = announcement.document
doc = Document(announcement.document)
doc.metadata['title'] = announcement.title
doc.metadata['datetime'] = announcement.writtenDate
docs.append(doc)
with open(f'{datetime.datetime.now(datetime.UTC)}.pkl', 'wb') as f:
pickle.dump(docs, f)
with open(f'./data/{datetime.datetime.now(datetime.UTC).date()}.pkl', 'wb') as f:
pickle.dump(docs, f)
vdb.add_content(f'./data/{datetime.datetime.now(datetime.UTC).date()}.pkl', './FAISS/NOTICE')

@app.get("/")
async def initiate():
sched.start()
return "안녕하세요! 국민대학교 전용 챗봇 KUKU입니다. 국민대학교에 대한 건 모든 질문해주세요!"

@app.post("/query")
@app.post("/api/chatbot")
async def query(query: Query):
try:
ans = llm.query(query.query, query.target_lang)
Expand All @@ -109,10 +111,6 @@ async def query(query: Query):
'answer': ans
}})

@app.post("/input")
async def input(data: UploadFile):
vdb.add_content(data.file)
return

@app.exception_handler(CustomException)
async def MyCustomExceptionHandler(request: Request, exception: CustomException):
Expand Down
2 changes: 1 addition & 1 deletion ai/vectordb/vector_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def add_content(self, content, vector_db_path='./'): # url, txt, pdf, csv 또는

self.load_local(vector_db_path)

text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=150)
if content.startswith('https:'):
loader = WebBaseLoader(content)
elif content.endswith('.txt'):
Expand Down
30 changes: 30 additions & 0 deletions back/BACK.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ Could not initialize class com.microsoft.cognitiveservices.speech.SpeechConfig

<br>

### **API 응답 및 문서**

Response로 받는 Json 형식이 정해져있지 않다면, 프론트 개발자들은 매번 API 문서를 참고하여 매번 그에 맞춰 수정해야될 것이다. 따라서, 프론트엔드에서 모듈화하여 유연하게 Response를 받을 수 있게 하기 위해 API 공통 응답을 설계했다. 공통 API 응답 설계는 [카카오의 API 공통응답 기술문서](https://docs.kakaoi.ai/kakao_work/webapireference/commonguide/)를 참고하였다.

![image](https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/5dd65c4f-dd1e-4e6c-848f-3ede0d82194a)

성공했을 때는 위와 같이 성공 여부를 알려주는 success, 그에 대한 message, 그리고 응답에 대한 결과값인 response로 구성된다. response안에 이제 프론트 측에서 원하는 결과가 담겨있다.

![image](https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/9f1a40dc-03e6-4a19-adb6-2339d7c8ecfd)

실패했을 때는 success가 false, 실패에 대한 message, 그리고 오류 코드를 알려주는 code로 구성된다. 해당 오류 코드는 서버 측에서 Enum으로 정의되어 있으며, 테스트를 용이하게 위해서 만들었다.

![image](https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/609b8800-59ba-445c-8a9c-8a075cc69a73)

API 문서는 Swagger를 사용하였다. 소프트웨어공학에서 Agile Process에 대해서 과도한 문서화를 하지 말라고 언급하였다. 특히, API 문서화 같은 경우는 계속해서 응답 형식이나 파라미터 등이 변할 수 있는데, 매번 API 문서를 최신화 하는 것도 어렵고, 서버와 문서가 서로 안맞는 정합성 문제가 발생할 수도 있다. 그러면, 오히려 문서를 유지보수하거나 오류를 해결하는데 Cost와 Time을 증가시킨다.

따라서, Swagger를 이용하여 API가 변경되더라도 자동으로 API 문서를 최신화 해도록 구성하였다. 이로써, API 문서를 유지 보수하는데 시간을 크게 줄일 수 있었다. 또한, Swagger를 통해 API 문서에서 바로 테스트를 진행해볼 수도 있어서 협업의 능률을 향상시켰다.

<br>

### **배포**

AWS EC2 인스턴스에 배포한다던지, 컴퓨터와 노트북을 번갈아가며 개발하다던지, 이러면 각각 개발 환경이 틀려 매번 설정을 해주어야 한다. 하지만 Docker가 있다면? 귀찮게 그럴 필요 없이 쉽게 배포를 진행할 수 있다. 따라서, 실행하는 OS 환경에 상관없이, 언제나 같은 환경에서 결과를 낼 수 있도록 Docker Container화를 진행했다. Ruby On Rails나 AI서버의 Docker Container화는 다른 것과 별반 다를게 없는데, Spring Container화를 좀 특이하게 진행하였다. 일반적인 Docker 배포 방식으로 Spring 서버를 배포한다면, jar 파일이 무거워질수록 docker image를 만드는 과정이 비효율적으로 된다. 그런데, Docker의 장점이 레이어마다 캐쉬를 사용하고, 이를 통해 빠르게 이미지를 만들 수 있다는 것이다. 하지만, 해당 방식으로 진행하면 소스 코드가 한줄만 바꿔도 캐쉬가 깨지기 때문에 다시 연산을 해야되가지고, Docker를 사용하는 장점이 없어진다. 왜냐하면, Spring의 모든 애플리케이션 코드와 라이브러리가 Single layer에 배치되기 때문이다. 결국 컨테이너 환경에서의 시작 시간에도 영향을 미친다.
Expand Down Expand Up @@ -300,6 +320,16 @@ JWT Secret, HMAC Secret, API Key 등등을 우리 Code에 Hard Coding해서는

<br>

### **테스트 진행 강화**

현재 시간 부족으로 테스트 코드는 일부 시나리오에 대해서만 통합 테스트가 진행되고 있다. 하지만, 통합 테스트 뿐만 아니라 각각 Domain에 대하여 단위 테스트가 진행될 필요성이 있다. 따라서, 더욱 이상적인 CI/CD 파이프라인이 진행되기 위해서 테스트 코드를 강화할 필요가 있다.

![image](https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/3a40cdfd-ce4f-4716-a9c0-06d96cafbfc5)

또한, 현재는 우리 테스트 코드의 Code Coverage를 시각적으로 측정할 수 있는 방법이 없다. 그래서, 우리가 미쳐 생각하지 못한 시나리오나 Domain에 대하여 누락될 가능성도 있다. 그래서 추후 위 사진과 같이 Jacoco같은 라이브러리를 이용하여 우리 테스트 코드의 Code Coverage를 측정하고, html로 리포트를 생성하여 팀원들이 쉽게 볼 수 있도록 추출할 것이다.

<br>

### **인스턴스 성능의 한계**

<img src="https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/61f41786-00e2-4ae2-b059-9bbe080edc91">
Expand Down
12 changes: 6 additions & 6 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ This project aims to develop a comprehensive app service for international stude
<td><img src="https://github.com/kookmin-sw/capstone-2024-30/assets/52407470/7627b57d-585c-4021-b02a-5ae6daded453" width="250"></td>
</tr>
<tr align="center">
<td>최지훈</td>
<td>김민제</td>
<td>조현진</td>
<td><a href="https://github.com/ji-hunc">최지훈</a></td>
<td><a href="https://github.com/kevinmj12">김민제</a></td>
<td><a href="https://github.com/mclub4">조현진</a></td>
</tr>
<tr align="center">
<td>****1683</td>
Expand All @@ -202,9 +202,9 @@ This project aims to develop a comprehensive app service for international stude
<td><img src="https://github.com/kookmin-sw/capstone-2024-30/assets/52407470/1c9ac172-5d97-4002-b254-c003f5d07ac2" width="250"></td>
</tr>
<tr align="center">
<td>채원찬</td>
<td>김혜성</td>
<td>최영락</td>
<td><a href="https://github.com/BlueBerrySoda">채원찬</a></td>
<td><a href="https://github.com/Borikhs">김혜성</a></td>
<td><a href="https://github.com/guahama">최영락</a></td>
</tr>
<tr align="center">
<td>****1676</td>
Expand Down

0 comments on commit 00d3785

Please sign in to comment.