ChatGPT(LLM)와 RAG를 이용하여 '예비 KT 에이블러들을 위한 QA 챗봇 모델' 만들기
- -
layout: single
title: "jupyter notebook 변환하기!"
categories: coding
tag: [python, blog, jekyll]
toc: true
author_profile: false
챗봇 만들기
0.미션
예비 KT 에이블러들을 위한 QA 챗봇 모델 만들기
Vector DB에 데이터 추가하기
Retriever, memory, LLM를 연결하기
실행시 이력 DB 생성하고 기록하기
test
1.환경준비
(1) 라이브러리 Import
import pandas as pd
import numpy as np
import os
import sqlite3
from datetime import datetime
import openai
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage, Document
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA, ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
(2) OpenAI API Key 확인
https://platform.openai.com/api-keys
위 링크에서 자신의 API Key 생성 - gpt-3.5-turbo로 준비하기
API.key 파일을 만들고 거기에 API key 저장하기
with open("API.key") as f:
os.environ['OPENAI_API_KEY'] = f.readlines()[0]
openai.api_key = os.getenv('OPENAI_API_KEY')
print(openai.api_key[:10])
sk-proj-Gt
만약 환경변수 키 설정이 잘 안된다면 아래 코드셀의 주석을 해제하고, 자신의 api key를 입력하고 실행
아래 코드는 키 지정을 임시로 수행함.
파이썬 파일(.ipynb, .py)안에서 매번 수행해야 함.
# os.environ['OPENAI_API_KEY'] = '여러분의 OpenAI API키'
# openai.api_key = os.getenv('OPENAI_API_KEY')
2.Vector DB 만들기
데이터 로딩
1일차에서 제공한 csv 파일의 구조를 그대로 이용
에이블스쿨 홈페이지 FAQ 데이터 수집(https://aivle.kt.co.kr/home/brd/faq/main?mcd=MC00000056)
- 모든 질문을 csv 형태로 저장
데이터프레임으로 저장하기
import os
import shutil
folder = "./db" # 경로 지정 -> 크로마 함수에서 폴더 만들어 줄것임
if os.path.exists(folder):
shutil.rmtree(folder)
벡터 데이터베이스
1일차 벡터 데이터베이스를 그대로 이용
Embedding 모델 : text-embedding-ada-002
DB 경로 : ./db
# Chroma 데이터베이스 인스턴스 생성
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
VectorDB = Chroma(persist_directory = folder, embedding_function = embeddings)
데이터 입력
기존 입력을 모두 제거하고 추가 사항만 모두 입력
meta data로 '구분' 칼럼 값 추가하기
data = pd.read_csv('aivleschool_qa.csv', encoding='utf-8')
print(len(data))
data.head()
10
구분 | QA | |
---|---|---|
0 | 모집/선발 | 최종 학력 또는 전공과 관계없이 지원할 수 있나요?\nKT 에이블스쿨은 정규 4년제... |
1 | 모집/선발 | 35세 이상은 지원할 수 없나요?\n본 교육 과정은 34세 이하를 대상으로 하는 교... |
2 | 모집/선발 | 미취업자의 기준이 뭔가요?\n미취업자의 기준은 아래와 같습니다.\n1) 기간의 정함... |
3 | 모집/선발 | 직장인도 지원할 수 있나요?\nKT 에이블스쿨은 미취업자를 대상으로 하며, 교육 시... |
4 | 모집/선발 | 아르바이트를 하고 있는데 지원할 수 있나요?\n고용보험에 가입이 되어 있는 경우 1... |
# 데이터프레임의 텍스트 열(시리즈)을 리스트로 변환
text_list = data['QA'].tolist()
meta = data['구분'].tolist()
# 리스트 내용을 각각 document로 변환
documents = [Document(page_content=text_list[i], metadata={'category':meta[i]}) for i in range(data.shape[0])]
# Insert
VectorDB.add_documents(documents)
['8951da8c-d7e9-407a-a7f5-56fadae9fbd3', 'cc5329e5-ffa7-427c-8d49-dc8a90237911', '40e55b59-c475-433e-8a3d-f43efcaf5c5c', 'a13a108d-ad38-41b4-a70a-2f18536d5f85', 'b249f7c5-ae02-4298-98ed-695ae1f581c9', '84fe8e11-1623-46a8-b182-a1f9d0ea72a5', '353c0437-fde9-4b1f-9e9b-0f8d23eaa5fc', 'ea624090-f572-44d5-aace-12a7010f51f4', 'ef485096-1269-49b7-87ed-5844932ff32c', 'b512581c-99d9-4d7e-b4aa-84224bdb967b']
크롤링
타겟 페이지 F12
import requests
from bs4 import BeautifulSoup
import re
cookies = {
"SESSION": "b99bed4c-742c-4d57-9c4a-9717a92cac89",
"TS01e6903a": "01a4caa0ef3d44ff7f7af4169e465024fe6016d11b29570fb287df2b6330b2cfbb1d57f8c49a63becfea866fb526e4ceb549492fa13ffc6824f77d18b3717ab6068a96d1e0"
}
doc_crawl=[]
catagories=[]
contents=[]
for i in range(1, 11):
url_qna=f"https://aivle.kt.co.kr/home/brd/faq/listJson?ctgrCd=&pageIndex={i}"
response=requests.get(url=url_qna, cookies=cookies)
data_json=response.json()
return_list = data_json.get('returnList', [])
# print(return_list)
if return_list:
for elem in return_list:
raw_content = elem.get('atclCts', '')
soup = BeautifulSoup(raw_content, 'html.parser')
content = soup.get_text()
metadata = {'category': elem.get('ctgrNm', '')}
# 특수 문자 제거
content = re.sub(r'\r\n|\r|\n', '', content)
content = re.sub(r'\s+', ' ', content)
catagories.append(elem.get('ctgrNm', ''))
contents.append(content)
doc_elem_crawl=Document(page_content=content, metadata=metadata)
doc_crawl.append(doc_elem_crawl)
VectorDB.add_documents(doc_crawl)
C:\Users\kim_h\AppData\Local\Temp\ipykernel_2516\2011595320.py:25: MarkupResemblesLocatorWarning: The input looks more like a filename than markup. You may want to open this file and pass the filehandle into Beautiful Soup. soup = BeautifulSoup(raw_content, 'html.parser')
['b0746580-5236-476a-904d-e8524a63094f', '3228f4c3-7396-40bc-b863-5cf38d6d6a76', '55157a08-f0fa-4c83-b263-c39d7aac610e', 'a89ca8ea-250b-450d-8237-8e8e4967dc51', 'bb0cef70-90ae-42c6-ab99-5a0e98856091', '8dcb6151-dfb0-43e7-8da8-7b370a03465d', 'fdc9f098-ec2a-4cbd-989a-849409b5d99b', '5320731e-40b9-4a10-ae92-566768880cc4', 'bebb1ebf-15f6-48d4-8444-8da666f17b65', '9452a3eb-4b2d-4e91-8c38-b7b9b94b4341', '8d552b4b-0415-48c0-98e7-553962800862', '7df33588-e5b7-4be5-bc13-969764ffae90', '04acf0c5-b92a-4423-a648-5e9ca5f5e102', '5bd8cb9d-d807-456c-97de-d7da3b1006fb', '854e7ed6-dd4f-4030-b613-20ecd9a6b110', '1863da3d-6b92-4dff-ad2f-9cb6f1124df2', 'fd28965c-1be8-4635-bec5-aa34aeef63d1', '0a9a8ab8-4618-4b89-97cd-533a9cc61861', '87045114-8948-42a3-ab68-7d66cef296a7', '50f07918-8f7d-48c2-a449-94a87ff3176d', 'f22e33be-f904-4599-990c-000d38dff098', '8b91da30-831f-49d2-93ea-d85bcbe93b89', '4d057b1d-5797-4fac-9fcf-aa90c7bfece9', '90c0e1f9-cc9c-4381-90ac-4eba04d1bceb', '2aadc44b-7642-4e3b-8a02-7bd868733bce', '5f1264ff-82b3-4608-b305-0db1b4cff90e', 'edf79e38-bb74-402f-bb31-b1aab595f3e4', '78f0b7ba-9705-4582-8c47-4ec65e8aea68', '8645a1a2-6401-4caa-be26-16e961a7c776', 'cfb12384-122f-44ec-a81f-2b6bb8372960', '3adb91fe-94f9-4f6c-a890-cd74af1ae502', '754d3f00-d258-44cc-89ea-70743d7c15c0', '97156bc6-7198-4d65-86a1-6803bfcff1c0', '4a4aac99-7e3d-41c3-ab5d-55d8abd23b1a', '6307d193-2250-4627-8c70-5051f42d86a0', 'f4890302-c712-47c6-a80f-3b5fd198bbfb', '48a85f36-3ed0-428c-9cdd-ce183994ee36', 'c1e344e5-f211-4709-b00a-8e7fd7b12794', '93043b04-ffe3-407d-bc11-9d5c94dae41a', '62178ea2-405f-40bd-8581-082e3a89ea86', '2b37a748-172a-4755-ac2b-f7fb1a3a0899', '43676982-5067-4c39-8787-d1318c41cd32', 'cdc5beda-c978-4b5c-a60b-9a69e6315aa0', '2f25782a-ef02-4c32-8b32-9312ef9ad0b1', '39a5b972-7ccf-4035-b583-6fe74f0f6af9', '4517c89d-8e7d-4fec-a4ad-f74b83ea8958', '35c08f96-ed00-41a6-83fb-8abe9d96395f', '478e968d-d123-4755-baa0-7e593eec4395', 'afed0efe-508e-4317-84cd-c162f7c86bdc', 'e6476d88-1ca0-457f-8333-a3200e7fd687', 'deda0093-a17b-461c-bdbf-75ff7dedbbd2', 'd0c1b672-8743-4863-8950-f13fcb8e1aad', '0478ec3a-4e6f-4c33-8f27-588244823f1e', '33f032ab-4b22-46f2-8769-523e8442e8ef', '090abfe0-2044-4a77-acaa-94633efbd826', 'dafb766e-d24f-485d-b046-7b8d66848220', '1d913bc4-2cf6-452f-bfa1-56f56578689d', 'fcfc7e39-5d95-469a-a7fe-dc4574a82cec', 'd97a985a-436a-4f8f-85cf-e7ebbb59f2d7', 'ca298ac7-9154-4660-82af-d746c53160b3', 'efa1bd6c-9618-461f-93ea-d91c944e1892', '9912a2fd-3e82-48f9-a542-672949e2e5be', '53adfed5-4c05-41da-a81a-ac15152d7314', '48f63ac4-4397-4ad2-a59f-49039881f099', 'd1526b07-1e6e-42bc-a689-5b26fd24a728', '6513fb4e-f2ca-424f-b5bf-7d7f30941243', 'b632d470-9342-42e4-b4b6-0c01711cd3e8', 'aa992cbb-aa50-4dd1-a229-3a3fb9958d09']
database_df = pd.DataFrame({'구분': catagories, '내용': contents})
print(len(database_df))
database_df.head()
68
구분 | 내용 | |
---|---|---|
0 | 모집/선발 | KT 에이블스쿨은 정규 4년제 대학 졸업자 및 졸업예정자를 대상으로 하는 교육입니다... |
1 | 모집/선발 | 본 교육 과정은 34세 이하를 대상으로 하는 교육입니다. 단, 모집시점에 35세라도... |
2 | 모집/선발 | 미취업자의 기준은 아래와 같습니다. 1) 기간의 정함이 있는 근로인 경우, 2) 고... |
3 | 모집/선발 | KT 에이블스쿨은 미취업자를 대상으로 하며, 교육 시작일 기준 재직자는 지원이 불가... |
4 | 모집/선발 | 고용보험에 가입이 되어 있는 경우 15시간/주 미만 근로인 경우에만 미취업자로 간주... |
- 입력된 데이터 조회
VectorDB.get().keys()
dict_keys(['ids', 'embeddings', 'metadatas', 'documents', 'uris', 'data'])
VectorDB.get()['metadatas'][:3]
[{'category': '국민내일배움카드'}, {'category': '모집/선발'}, {'category': '국민내일배움카드'}]
VectorDB.get()['documents'][:3]
['훈련장려금은 실업자 지급이 원칙입니다. 다만, 주 15시간 미만으로 근로하며, 해당 근로사실과 동일하게 고용보험에 가입되어 있는 경우 예외적으로 훈련장려금이 지급됩니다. 더불어, 훈련 수강일정과 근로시간은 중복될 수 없습니다. 자세한 사항은 관할 고용센터에 문의 부탁 드립니다. ', '교육 등록신청을 하지 않거나 교육 일정 시작 전에 교육 등록을 취소해도 지원자격에 해당하는 경우 다시 지원이 가능합니다. 다만, 교육 과정 확정자신고일(교육시작일로부터 7일)이 지난 후 중도 퇴교를 할 경우 과정을 수강한 것으로 간주되며, 향후 K-Digital Training (K-DT) 과정에 재지원은 가능하나 무료 수강은 어렵습니다.', '장학금이 소득으로 인식되는 경우 훈련장려금이 지급되지 않을 수 있습니다.훈련장려금은 고용센터에서 지급요건을 최종 검토 후 지급처리 되므로, 먼저 학교 행정처에 장학금 소득 처리 여부 문의 후 거주지 관할 고용센터(HRD-Net 확인) 혹은 훈련 권역별 고용센터(아래 참고)로 연락하시어 훈련장려금 지급 여부에 대해 다시 한 번 문의하시기 바랍니다.※ 수도권: 성남고용센터 충남/충북: 대전고용센터 대구/경북: 대구고용센터 전남/전북: 광주고용센터 부산/경남: 부산고용센터 - 고용노동부 대표번호 1350, 거주지 근처 지도검색, HRD-Net 메인 하단 지역별 기관검색에서 확인 가능 ']
temp = [a['category'] for a in VectorDB.get()['metadatas']]
database_df = pd.DataFrame({'구분': temp, '내용': VectorDB.get()['documents']})
print(len(database_df))
database_df.head()
78
구분 | 내용 | |
---|---|---|
0 | 국민내일배움카드 | 훈련장려금은 실업자 지급이 원칙입니다. 다만, 주 15시간 미만으로 근로하며, 해당... |
1 | 모집/선발 | 교육 등록신청을 하지 않거나 교육 일정 시작 전에 교육 등록을 취소해도 지원자격에 ... |
2 | 국민내일배움카드 | 장학금이 소득으로 인식되는 경우 훈련장려금이 지급되지 않을 수 있습니다.훈련장려금은... |
3 | 모집/선발 | 현재 KT 에이블스쿨은 KT 채용 인적성검사와 같은 과목의 인적성검사를 운영하고 있... |
4 | 모집/선발 | 코딩테스트는 AI개발자 Track 지원자를 대상으로 진행되며, 사용 가능한 프로그래... |
3.RAG+LLM모델
모델 : ConversationalRetrievalChain
LLM 모델 : gpt-3.5-turbo
retriever : 벡터DB
- 유사도 높은 문서 3개 가져오도록 설정
memory 사용
요구사항
질문 history 관리를 위한 이력 저장 DB 생성
DB 명 : db_chatlog
테이블 명 : history
id INTEGER PRIMARY KEY : 이렇게 설정하면 자동증가 값으로 채워짐
datetime TEXT : 질문시점 yyyy-mm-dd hh:mi:ss
query TEXT : 질문
sim1 REAL : 첫번째 문서의 유사도 점수
sim2 REAL : 두번째 문서의 유사도 점수
sim3 REAL : 세번째 문서의 유사도 점수
answer TEXT : 답변
유사도 점수는 similarity_search_with_score 메서드를 이용해서 저장해야 함
질문과 답변이 진행될 때마다 history 테이블에 데이터 입력
- 관리용 DB, 테이블 생성
import os
root = './db_chatlog'
os.makedirs(root, exist_ok=True)
path = root + '/db_chatlog.db'
if os.path.exists(path):
os.remove(path)
conn = sqlite3.connect(path) # 해당 경로에 있으면 연결하고 없으면 만든다.
# 커서 객체 생성
cursor = conn.cursor()
# test 테이블 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS history (
id INTEGER PRIMARY KEY,
datetime TEXT NOT NULL,
query TEXT NOT NULL,
sim1 REAL NOT NULL,
sim2 REAL NOT NULL,
sim3 REAL NOT NULL,
answer TEXT NOT NULL
)
''')
# 변경사항 커밋 (저장)
conn.commit()
# 연결 종료
conn.close()
conn = sqlite3.connect(path)
data = pd.DataFrame({'datetime': [], 'query': [],
'sim1': [], 'sim2': [], 'sim3': [],
'answer': []})
data.to_sql('history', conn, if_exists='append', index=False) # test 테이블이 있으면 insert, 없으면 생성
# 확인
df = pd.read_sql('SELECT * FROM history', conn)
display(df)
# ③ 연결 종료
conn.close()
id | datetime | query | sim1 | sim2 | sim3 | answer |
---|
- 모델 선언
from langchain.chat_models import ChatOpenAI
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
chat = ChatOpenAI(model="gpt-3.5-turbo",
streaming=True, callbacks=[StreamingStdOutCallbackHandler()]) # 스트리밍 설정
k=3
retriever = VectorDB.as_retriever(search_kwargs={"k": k})
# 대화 메모리 생성
memory = ConversationBufferMemory(memory_key="chat_history", input_key="question", output_key="answer",
return_messages=True)
# ConversationalRetrievalQA 체인 생성 -> chat모델, 검색기, 메모리 연결
qa = ConversationalRetrievalChain.from_llm(llm=chat, retriever=retriever, memory=memory,
return_source_documents=True, output_key="answer")
- 모델 사용 및 이력 확인
# 첫번째 질문
from datetime import datetime
# 현재 시간
dt = datetime.now()
dt = dt.strftime('%Y-%m-%d %H:%M:%S')
query1 = "최종 학력 또는 전공과 관계없이 지원할 수 있나요?"
print('질문 : ', query1)
result = qa(query1)
# result['answer']
질문 : 최종 학력 또는 전공과 관계없이 지원할 수 있나요? KT 에이블스쿨은 정규 4년제 대학 졸업자 및 졸업예정자를 대상으로 하는 교육이므로, 최종 학력이나 전공에 관계 없이 해당 조건을 충족하는 경우 모두 지원할 수 있습니다. 단, AI개발자 Track은 기본적인 코딩 역량이 필요하다는 점을 참고하시기 바랍니다.
query = result['question']
answer = result['answer']
sims = VectorDB.similarity_search_with_score(query, k = 3) #← 데이터베이스에서 유사도가 높은 문서를 가져옴
sim1 = sims[0][1]
sim2 = sims[1][1]
sim3 = sims[2][1]
new_data = {
'datetime': [dt],
'query': [query],
'sim1': [sim1],
'sim2': [sim2],
'sim3': [sim3],
'answer': [answer]
}
new_data_df = pd.DataFrame(new_data)
conn = sqlite3.connect(path) # 해당 경로에 있으면 연결하고 없으면 만든다.
new_data_df.to_sql('history', conn, if_exists='append', index=False)
df = pd.read_sql('SELECT * FROM history', conn)
display(df)
# 연결 종료
conn.close()
id | datetime | query | sim1 | sim2 | sim3 | answer | |
---|---|---|---|---|---|---|---|
0 | 1 | 2024-06-04 15:56:47 | 최종 학력 또는 전공과 관계없이 지원할 수 있나요? | 0.189875 | 0.264856 | 0.266282 | KT 에이블스쿨은 정규 4년제 대학 졸업자 및 졸업예정자를 대상으로 하는 교육이므로... |
memory.load_memory_variables({})
{'chat_history': [HumanMessage(content='최종 학력 또는 전공과 관계없이 지원할 수 있나요?'), AIMessage(content='KT 에이블스쿨은 정규 4년제 대학 졸업자 및 졸업예정자를 대상으로 하는 교육이므로, 최종 학력이나 전공에 관계 없이 해당 조건을 충족하는 경우 모두 지원할 수 있습니다. 단, AI개발자 Track은 기본적인 코딩 역량이 필요하다는 점을 참고하시기 바랍니다.')]}
함수화 - 최종
from datetime import datetime
chat = ChatOpenAI(model="gpt-3.5-turbo")
k=3
retriever = VectorDB.as_retriever(search_kwargs={"k": k})
# 대화 메모리 생성
memory = ConversationBufferMemory(memory_key="chat_history", input_key="question", output_key="answer",
return_messages=True)
# ConversationalRetrievalQA 체인 생성 -> chat모델, 검색기, 메모리 연결
qa = ConversationalRetrievalChain.from_llm(llm=chat, retriever=retriever, memory=memory,
return_source_documents=True, output_key="answer")
def chatting(query):
print(f'질문 : {query}')
# 현재 시간
dt = datetime.now()
dt = dt.strftime('%Y-%m-%d %H:%M:%S')
result = qa(query)
answer = result['answer']
print(f'답변 : {answer}')
print('=' * 50)
sims = VectorDB.similarity_search_with_score(query, k = 3) #← 데이터베이스에서 유사도가 높은 문서를 가져옴
sim1 = sims[0][1]
sim2 = sims[1][1]
sim3 = sims[2][1]
new_data = {
'datetime': [dt],
'query': [query],
'sim1': [sim1],
'sim2': [sim2],
'sim3': [sim3],
'answer': [answer]
}
new_data_df = pd.DataFrame(new_data)
conn = sqlite3.connect(path) # 해당 경로에 있으면 연결하고 없으면 만든다.
new_data_df.to_sql('history', conn, if_exists='append', index=False)
# 연결 종료
conn.close()
while True:
query = input('질문 > ')
query = query.strip()
if len(query) == 0:
print('Enter 입력 -> 대화 종료')
break
chatting(query)
print(memory.load_memory_variables({}))
print()
conn = sqlite3.connect(path) # 해당 경로에 있으면 연결하고 없으면 만든다.
df = pd.read_sql('SELECT * FROM history', conn)
display(df)
conn.close()
질문 : 몇 살부터 지원 가능한가요? 답변 : 34세 이하를 대상으로 하는 교육이지만, 모집시점에 35세라도 해당연도 1월 1일 이후 출생자는 지원이 가능합니다. ================================================== 질문 : 그럼 17살도 지원 가능 한가요? 답변 : 17세는 해당 지원 대상이 아닙니다. 이 교육 과정은 만 34세 이하의 대상을 대상으로 합니다. ================================================== 질문 : 직장인도 지원 가능한가요? 답변 : KT 에이블스쿨은 미취업자를 대상으로 하며, 재직자는 지원이 불가능합니다.따라서 직장인은 해당 대상에 포함되지 않습니다. ================================================== Enter 입력 -> 대화 종료 {'chat_history': [HumanMessage(content='몇 살부터 지원 가능한가요?'), AIMessage(content='34세 이하를 대상으로 하는 교육이지만, 모집시점에 35세라도 해당연도 1월 1일 이후 출생자는 지원이 가능합니다.'), HumanMessage(content='그럼 17살도 지원 가능 한가요?'), AIMessage(content='17세는 해당 지원 대상이 아닙니다. 이 교육 과정은 만 34세 이하의 대상을 대상으로 합니다.'), HumanMessage(content='직장인도 지원 가능한가요?'), AIMessage(content='KT 에이블스쿨은 미취업자를 대상으로 하며, 재직자는 지원이 불가능합니다.따라서 직장인은 해당 대상에 포함되지 않습니다.')]}
id | datetime | query | sim1 | sim2 | sim3 | answer | |
---|---|---|---|---|---|---|---|
0 | 1 | 2024-06-04 15:56:47 | 최종 학력 또는 전공과 관계없이 지원할 수 있나요? | 0.189875 | 0.264856 | 0.266282 | KT 에이블스쿨은 정규 4년제 대학 졸업자 및 졸업예정자를 대상으로 하는 교육이므로... |
1 | 2 | 2024-06-04 15:57:05 | 몇 살부터 지원 가능한가요? | 0.261709 | 0.273430 | 0.291227 | 34세 이하를 대상으로 하는 교육이지만, 모집시점에 35세라도 해당연도 1월 1일 ... |
2 | 3 | 2024-06-04 15:57:16 | 그럼 17살도 지원 가능 한가요? | 0.295267 | 0.296652 | 0.318797 | 17세는 해당 지원 대상이 아닙니다. 이 교육 과정은 만 34세 이하의 대상을 대상... |
3 | 4 | 2024-06-04 15:57:26 | 직장인도 지원 가능한가요? | 0.211667 | 0.230160 | 0.239245 | KT 에이블스쿨은 미취업자를 대상으로 하며, 재직자는 지원이 불가능합니다.따라서 직... |
'KT AIVLE SCHOOL' 카테고리의 다른 글
RAG - 모델이 질문과 모델의 답변을 기억하기 및 이어지는 질문과 답변하기 (0) | 2024.06.04 |
---|---|
RAG - 외부 VectorDB와 LLM 연결하기 (0) | 2024.06.04 |
1. LangChain (RAG) 일단 실행해보기 (0) | 2024.06.04 |
huggingface, gemma 라이센스 (0) | 2024.04.29 |
미니프로젝트 - 실주행시간 예측 - (0) | 2024.04.23 |
소중한 공감 감사합니다