[AI] 9. 파이썬으로 구현하면?

늘 공부하는 괴짜·2025년 3월 30일
0

AI : Langchain (RAG)

목록 보기
9/38

주피터 노트북에 적었던 것을 1개 파일로 모아본다.

import os, time
from langchain_community.document_loaders import Docx2txtLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from dotenv import load_dotenv
from langchain_community.embeddings import OllamaEmbeddings
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone
from langchain_community.chat_models import ChatOllama
from langchain import hub
from langchain.chains import RetrievalQA
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from pprint import pprint

# 환경변수 로드.
load_dotenv()

# 텍스트 스플리터
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)

# 문서 가져와서 쪼개기.
loader = Docx2txtLoader("./system.docx")

# 가져온 문서를 쪼갠다.
document_list = loader.load_and_split(text_splitter=text_splitter)

# 임베딩 설정
# 경량화된 한국어 지원되는 ollama 모델...
embeddings = OllamaEmbeddings(
    model="llama3.2:3b"
)

# pinecone API KEY
pinecone_api_key = os.environ.get("PINECONE_API_KEY")

pc = Pinecone(api_key=pinecone_api_key)

# embedding 과 dimension 맞춰야 함...
pinecone_database = PineconeVectorStore.from_documents(
    documents=document_list,
    embedding=embeddings,
    pinecone_api_key=pinecone_api_key,
    index_name="index-system"
)

# llm 설정
llm = ChatOllama(
    model="llama3.2:3b"
)  

# prompt model 설정
prompt_model = hub.pull("rlm/rag-prompt")

# 질문(query) 설정
query = "제9조(홈페이지 등 공개용 웹 서버 관리) 내용은?"

# retriever (데이터 가져오는) 설정
retriever = pinecone_database.as_retriever(search_kwargs={"k":4})

# qa (질문과 답변) 체이닝
qa_chain = RetrievalQA.from_chain_type(
    llm,
    retriever=retriever,
    chain_type_kwargs={"prompt": prompt_model}
)

# 사용자 사전 설정.
dictionary = ["목차를 나타내는 표현 -> (홈페이지 등 공개용 웹 서버 관리) 추가"]

# prompt 설정 
prompt = ChatPromptTemplate.from_template(f"""
    사용자의 질문을 보고, 우리의 사전을 참고해서 질문을 변경해 주세요.
    만약 변경할 필요가 없다고 판단된다면, 사용자의 질문을 변경하지 않아도 됩니다.
    사전 : {dictionary}
    
    질문 : {{question}}
""")

# 설정된 prompt 를 llm 에 입력하고 문자열 파싱을 한다.
dictionary_chain = prompt | llm | StrOutputParser()

# 적절하게 변경된 질문을 qa_chain 에 입력한다.
dictionary_qa_chain = {"query": dictionary_chain} | qa_chain

# invoke 로 실행.
ai_message = dictionary_qa_chain.invoke({"question" : query})

pprint(ai_message)

동작은 뭐... 되긴 한다. 시간이 좀더 걸리는 느낌...

profile
인공지능이라는 옷을 입었습니다. 뭔가 멋지면서도 잘 맞습니다.

0개의 댓글