[κ°μλ ΈνΈ] RAG From Scratch : Overview
μλ³Έ κ²μκΈ: https://velog.io/@euisuk-chung/RAG-From-Scratch-Overview
- ν΄λΉ λΈλ‘κ·Έ ν¬μ€νΈλ RAG From Scratch : Coursework κ°μ ννΈ 1 - 4 λ΄μ©μ λ€λ£¨κ³ μμ΅λλ€.
λΉλμ€ | μμ½ | κ°μ λ§ν¬ | μ¬λΌμ΄λ |
---|---|---|---|
Part 1 (κ°μ) | RAGλ₯Ό μκ°νλ©°, μ리μ¦κ° κΈ°λ³Έ κ°λ λΆν° κ³ κΈ κΈ°μ κΉμ§ λ€λ£° κ²μμ μ€λͺ ν©λλ€. | π κ°μ | π μ¬λΌμ΄λ |
Part 2 (μΈλ±μ±) | κ²μμ μ νμ±κ³Ό μλμ μ€μν μΈλ±μ± κ³Όμ μ μ΄μ μ λ§μΆ₯λλ€. | π κ°μ | π μ¬λΌμ΄λ |
Part 3 (κ²μ) | κ²μμ μ λ°μ±μ μν΄ μΈλ±μ€λ₯Ό μ¬μ©ν λ¬Έμ κ²μμ λ€λ£Ήλλ€. | π κ°μ | π μ¬λΌμ΄λ |
Part 4 (μμ±) | LLMμ ν΅ν λ΅λ³ μμ±μ μν RAG ν둬ννΈ κ΅¬μ±μ νꡬν©λλ€. | π κ°μ | π μ¬λΌμ΄λ |
Part 1 (κ°μ)
- RAGμ κΈ°λ³Έ κ°λ
μκ°:
- μ΄ λΉλμ€ μ리μ¦λ RAG(Retrieval-Augmented Generation)μ κΈ°λ³Έ μμΉμ λ€λ£¨κ³ , κ³ κΈ μ£Όμ κΉμ§ νμ₯ν΄ λκ°λ κ³Όμ μ μ€λͺ ν©λλ€.
- RAGμ μ£Όμ λκΈ°λ λν μΈμ΄ λͺ¨λΈ(LLM)μ΄ λͺ¨λ λ°μ΄ν°λ₯Ό ν¬ν¨νμ§ μλλ€λ μ μμ μμλ©λλ€. μλ₯Ό λ€μ΄, κ°μΈ λ°μ΄ν°λ μ΅κ·Ό λ°μ΄ν°λ LLMμ μ¬μ νμ΅μ ν¬ν¨λμ§ μμ μ μμ΅λλ€.
- λν, LLMμ 컨ν
μ€νΈ μλμ°(context windows)λΌλ μ νμ΄ μμ΅λλ€. μ΅κ·Όμλ μ΄ μ»¨ν
μ€νΈ μλμ°κ° μ μ λ 컀μ§κ³ μμ§λ§, μ¬μ ν μΈλΆ μμ€λ₯Ό ν΅ν΄ λ°μ΄ν°λ₯Ό μ°κ²°νλ κ²μ΄ μ€μν©λλ€.
- RAGμ μΈ κ°μ§ μ£Όμ λ¨κ³:
- μΈλ±μ±(Indexing): μΈλΆ λ¬Έμλ₯Ό μΈλ±μ±νμ¬ μ λ ₯ 쿼리μ λ°λΌ μ½κ² κ²μν μ μλλ‘ ν©λλ€.
- κ²μ(Retrieval): μ§λ¬Έμ λν λ¬Έμλ₯Ό κ²μνκ³ , μ΄ λ¬Έμλ₯Ό LLMμ μ λ ₯ν©λλ€.
- μμ±(Generation): κ²μλ λ¬Έμλ₯Ό λ°νμΌλ‘ LLMμ΄ λ΅λ³μ μμ±ν©λλ€.
μ½λ μμ°
1. Install Packages
- νμ ν¨ν€μ§λ₯Ό μ€μΉν©λλ€.
1
pip install langchain_community tiktoken langchain-openai langchainhub chromadb langchain bs4
- μ£Όμ λΌμ΄λΈλ¬λ¦¬λ₯Ό μν¬νΈν©λλ€:
1
2
3
4
5
6
7
8
import bs4
from langchain import hub
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
- API KEY λ° μ£Όμ νκ²½ λ³μλ₯Ό μ ν ν΄μ€λλ€:
1
2
# OPEN_AI CHATGPT KEY μ€μ
os.environ['OPENAI_API_KEY'] = <your-api-key>
1
2
3
4
5
6
# langsmithμ© ν€ μ€μ
# <https://docs.smith.langchain.com/>
import os
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_ENDPOINT'] = '<https://api.smith.langchain.com>'
os.environ['LANGCHAIN_API_KEY'] = <your-api-key>
(μ°Έκ³ ) LangSmith API Key λ°κΈ λ°©λ²
- λ§ν¬ : https://smith.langchain.com/
μ λ§ν¬μμ Personal > Setting > Creating API Keyμμ λ°κΈ κ°λ₯
π‘ LangChain & LangSmith?
LangChain
κ³ΌLangSmith
λ λκ·λͺ¨ μΈμ΄ λͺ¨λΈ(LLM) μ ν리μΌμ΄μ μ κ°λ°μ μ§μνλ λ κ°μ§ κ°λ ₯ν λꡬλ‘, κ°κ°μ λͺ©μ κ³Ό μ¬μ© μ¬λ‘κ° λ€λ¦ λλ€. - μ΄ λ λꡬλ₯Ό μ μ΄ν΄νλ κ²μ LLM κΈ°λ° μ ν리μΌμ΄μ μ ν¨μ¨μ μΌλ‘ κ°λ°νκ³ μ΄μνλ λ° μ€μν μν μ ν©λλ€.
LangChain βοΈ
- LangChainμ μ£Όλ‘ LLMμ νμ©νμ¬ μ ν리μΌμ΄μ μ μ μνκ² κ°λ°νκ³ νλ‘ν νμ μ ꡬμΆνκΈ° μν νλ μμν¬μ λλ€. PythonμΌλ‘ μ 곡λλ μ€ν μμ€ ν¨ν€μ§λ‘, λ€μν LLMμ μ¬μ©νμ¬ λ³΅μ‘ν μΈμ΄ μ²λ¦¬ μμ μ μνν μ μμ΅λλ€. LangChainμ λ€μκ³Ό κ°μ νΉμ§μ κ°μ§κ³ μμ΅λλ€:
- 체μΈκ³Ό μμ΄μ νΈ: LangChainμ μ¬λ¬ μμ μ 체μΈ(Chain) ννλ‘ μ°κ²°νκ±°λ, 볡μ‘ν μμ¬ κ²°μ κ³Όμ μ μμ΄μ νΈ(Agent)λ‘ κ΅¬ννμ¬ μλνν μ μμ΅λλ€.
- ν둬ννΈ ν νλ¦Ώ: νΉμ μμ μ λ§λ ν둬ννΈ ν νλ¦Ώμ μ½κ² μ μνκ³ νμ©ν μ μμ΅λλ€.
- λ©λͺ¨λ¦¬ μμ€ν : μμ μ μνλ₯Ό μ μ§νκΈ° μν΄ λ€μν λ©λͺ¨λ¦¬ μμ€ν μ μ¬μ©ν μ μμ΅λλ€.
LangSmith βοΈ
- LangSmithλ LangChain μ ν리μΌμ΄μ μ κ°λ°, ν μ€νΈ, λͺ¨λν°λ§, κ·Έλ¦¬κ³ λ°°ν¬λ₯Ό μν μ’ ν©μ μΈ DevOps νλ«νΌμ λλ€. μ΄λ λκ·λͺ¨ LLM μ ν리μΌμ΄μ μ κ΄λ¦¬νκ³ μ΅μ ννλ λ° νμν λ€μν κΈ°λ₯μ μ 곡νλ©°, νΉν λ€μκ³Ό κ°μ κΈ°λ₯μ΄ λ보μ λλ€:
- λλ²κΉ : λͺ¨λΈμ λͺ¨λ λ¨κ³μμ μ λ ₯κ³Ό μΆλ ₯μ μΆμ ν μ μμ΄, μμμΉ λͺ»ν κ²°κ³Όλ μ€λ₯λ₯Ό μ½κ² μλ³ν μ μμ΅λλ€.
- ν μ€νΈ: μλ‘μ΄ μ²΄μΈκ³Ό ν둬ννΈ ν νλ¦Ώμ μ€νν μ μλ νκ²½μ μ 곡νμ¬, μμ μ±κ³Ό μ±λ₯μ νμΈν μ μμ΅λλ€.
- λͺ¨λν°λ§: μ ν리μΌμ΄μ μ μ§μ° μκ°κ³Ό ν ν° μ¬μ©λμ μΆμ νμ¬ λ¬Έμ λ₯Ό μΌμΌν¬ μ μλ νΈμΆμ μλ³ν μ μμ΅λλ€.
- νκ°: 볡μ‘ν ν둬ννΈ μ²΄μΈμ νκ°νκ³ , μ±λ₯μ μ΅μ νν μ μλ λꡬλ₯Ό μ 곡ν©λλ€.
- νλ‘μ νΈ λΆμ: μ€ν μΉ΄μ΄νΈ, μ€λ₯ λ°μλ₯ , ν ν° μ¬μ©λ λ±μ νλ‘μ νΈ λ¨μλ‘ λΆμν μ μμ΅λλ€.
(μ°Έκ³ ) Langfuse π§¬
- Langfuseλ LLM(λκ·λͺ¨ μΈμ΄ λͺ¨λΈ) μ ν리μΌμ΄μ μ μν μ€νμμ€ κ΄μΈ‘μ± λ° λΆμ νλ«νΌμΌλ‘, λ€μκ³Ό κ°μ μ£Όμ κΈ°λ₯μ μ 곡ν©λλ€:
- κ΄μΈ‘μ±: 볡μ‘ν LLM μ± μ€νμ μκ°μ UIλ₯Ό ν΅ν΄ νμνκ³ λλ²κΉ ν μ μμ΅λλ€. λκΈ° μκ°, λΉμ©, μ±λ₯ μ μ λ±μ μμΈ μ 보λ₯Ό ν¬ν¨ν μ€μ²©λ λ·°λ₯Ό μ 곡ν©λλ€.
- λΆμ: λΉμ©, μ§μ° μκ°, μλ΅ νμ§μ μΈ‘μ νκ³ κ°μ ν μ μμ΅λλ€. λͺ¨λΈλ³ ν ν° μ¬μ©λ, νκ° μ μ λ±μ 리ν¬νΈλ‘ μ 곡ν©λλ€.
- ν둬ννΈ κ΄λ¦¬: Langfuse λ΄μμ ν둬ννΈλ₯Ό κ΄λ¦¬, λ²μ κ΄λ¦¬, λ°°ν¬ν μ μμ΄ ν¨μ¨μ μΈ ν둬ννΈ μμ§λμ΄λ§μ΄ κ°λ₯ν©λλ€.
- νκ°: LLM μμ±μ λν μ μλ₯Ό μμ§νκ³ κ³μ°ν©λλ€. λͺ¨λΈ κΈ°λ° νκ°, μ¬μ©μ νΌλλ°± μμ§, μλ μ μ λ§€κΈ°κΈ° λ± λ€μν νκ° λ°©λ²μ μ§μν©λλ€.
- μ€ν λ° ν μ€νΈ: μ λ²μ μ λ°°ν¬νκΈ° μ μ μ± λμμ μΆμ νκ³ ν μ€νΈν μ μμ΅λλ€. λ°μ΄ν°μ μ μ¬μ©νμ¬ μμ μ μΆλ ₯ μμ ν μ€νΈνκ³ μ±λ₯μ λ²€μΉλ§ν¬ν μ μμ΅λλ€.
- ν΅ν©: LlamaIndex, Langchain λ± μ£Όμ LLM νλ μμν¬μμ ν΅ν©μ μ 곡νμ¬ λ€μν LLM μ ν리μΌμ΄μ μμ μ¬μ©ν μ μμ΅λλ€.
2. Indexing
- μ΄μ νμν νκ²½ μ€μ μ λ€νμΌλ, Indexing μ½λλ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#### INDEXING ####
# Load Documents
loader = WebBaseLoader(
web_paths=("<https://velog.io/@euisuk-chung/κΏν-Velog-κΈμ¨λ₯Ό-λ΄-λ§μλλ‘-μμ-νκ΄ν>",),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
class_=("post-content", "post-title", "post-header")
)
),
)
docs = loader.load()
# Split
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
# Embed
vectorstore = Chroma.from_documents(documents=splits,
embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
- μ μ½λμμ
Chroma
λ vectorstoreμ ν μ’ λ₯λ‘, LangChain λΌμ΄λΈλ¬λ¦¬μμ μμ£Ό μ¬μ©λλ ꡬν체μ λλ€. -
Vectorstoreλ₯Ό μ¬μ©νλ©΄ λκ·λͺ¨ λ°μ΄ν°μ μμ ν¨μ¨μ μΈ μ μ¬μ± κ²μμ μνν μ μμ΄, μμ°μ΄ μ²λ¦¬λ κΈ°κ³νμ΅ μ ν리μΌμ΄μ μμ λ리 νμ©λ©λλ€.
- Chroma, Pinecone, Faiss λ± λ€μν ꡬνμ²΄κ° μμ΅λλ€.
-
μ£Όμ νΉμ§μ λ€μκ³Ό κ°μ΅λλ€:
- κ³ μ°¨μ λ²‘ν° λ°μ΄ν°λ₯Ό μ μ₯νκ³ κ²μνλ λ° νΉνλμ΄ μμ΅λλ€.
- ν μ€νΈ, μ΄λ―Έμ§, μ€λμ€ λ±μ λ°μ΄ν°λ₯Ό 벑ν°λ‘ λ³ννμ¬ μ μ₯ν©λλ€.
- μ μ¬μ± κ²μμ λΉ λ₯΄κ² μνν μ μμ΄ μΆμ² μμ€ν , μ΄λ―Έμ§ κ²μ λ±μ νμ©λ©λλ€.
3. Retreive and Generate
- Indexingμ΄ λλ λ€, κ²μκΈ°(retriever)λ₯Ό μ μνκ³ , κ²μλ λ¬Έμμ ν¨κ» μ§λ¬Έμ LLMμ μ λ¬νμ¬ λ΅λ³μ μμ±(generate)ν©λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#### RETRIEVAL and GENERATION ####
# Prompt
prompt = hub.pull("rlm/rag-prompt")
# LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# Post-processing
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
# Chain
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# Question
rag_chain.invoke("What is Task Decomposition?")
## Answer Returned
'Task Decomposition is a technique used to break down complex tasks into smaller, more manageable steps.
It involves methods like Chain of Thought (CoT) and Tree of Thoughts, which guide models to think step by step and explore multiple reasoning possibilities.
This approach enhances model performance by simplifying and structuring tasks systematically.'
- langsmith ν΄μ μ¬μ©νλ©΄ μ¬μ΄νΈ > νλ‘μ νΈλ‘ μ μνμ¬ μλμ κ°μ΄ μ§λ¬Έκ³Ό κ²μλ λ¬Έμ, κ·Έλ¦¬κ³ μμ±λ λ΅λ³μ νμΈν μ μμ΅λλ€.
Part 2 (μΈλ±μ±)
- μ΄λ² μμμ RAG(Retrieval-Augmented Generation) νμ΄νλΌμΈμ λ λ²μ§Έ ννΈλ‘, βμΈλ±μ±(Indexing)βμ λν΄ λ€λ£Ήλλ€.
- μ΄μ μμμμλ RAG νμ΄νλΌμΈμ μ£Όμ κ΅¬μ± μμ(μΈλ±μ±, κ²μ, μμ±)μ λν΄ κ°κ΄μ μΌλ‘ μ€λͺ νμΌλ©°, μ΄λ² μμμμλ κ·Έ μ€ μΈλ±μ±μ λν΄ μ¬λ μκ² μ€λͺ ν©λλ€.
-
μΈλ±μ±μ μν : μΈλ±μ±μ 첫 λ²μ§Έ λ¨κ³λ μΈλΆ λ¬Έμλ₯Ό λ‘λνκ³ μ΄λ₯Ό β리νΈλ¦¬λ²(Retriever)βμ λ£λ κ²μ λλ€.
-
리νΈλ¦¬λ²(Retriever)μ λͺ©νλ μ λ ₯λ μ§λ¬Έμ λν΄ κ΄λ ¨ λ¬Έμλ₯Ό μ°Ύμλ΄λ κ²μ λλ€.
βοΈ μ¬μ μ μλ―Έλ‘
retrieve
λ βνμνλ€βλΌλ λ»μΌλ‘, _βμ°λ¦¬κ° μ§λ¬Έν μ§μλ¬Έκ³Ό μ μ¬ν λ΄μ©μ λ¬Έμλ₯Ό μ μ₯ν΄λ VectorDBμμ νμν΄ μ¨λ€β_λΌκ³ μ§μν΄λ³Ό μλ μμ κ² κ°μ΅λλ€.
-
- κ΄κ³(μ μ¬μ±)μ ν립νλ λ°©λ²μ μ£Όλ‘ λ¬Έμμ μμΉμ νν(numerical representation)μ μ¬μ©νλ κ²μ
λλ€. μ΄λ μμ νμμ ν
μ€νΈλ³΄λ€λ λ²‘ν° λΉκ΅κ° ν¨μ¬ μ½κΈ° λλ¬Έμ
λλ€.
-
λ²‘ν° νν λ°©λ²:
- Sparse Vectors: κ³Όκ±°μλ κ΅¬κΈ λ±μμ λ¬Έμμ λ¨μ΄ λΉλμλ₯Ό κΈ°λ°μΌλ‘ νλ ν¬μ 벑ν°(sparse vectors)λ₯Ό μμ±νλ ν΅κ³μ λ°©λ²μ΄ λ§μ΄ μ¬μ©λμμ΅λλ€. μ΄ λ²‘ν°μ κ° μμΉλ ν° μ΄ν μ§ν© μ€ νΉμ λ¨μ΄μ λ°μ νμλ₯Ό λνλ΄λ©°, λ¬Έμμ ν¬ν¨λμ§ μμ λ¨μ΄μ κ²½μ° κ°μ΄ 0μ΄ λ©λλ€.
- Embedding Methods: μ΅κ·Όμλ λ¬Έμλ₯Ό κ³ μ λ κΈΈμ΄μ 벑ν°λ‘ μμΆνλ λ¨Έμ λ¬λ κΈ°λ° μλ² λ©(embedding) λ°©λ²μ΄ κ°λ°λμμ΅λλ€. μ΄ λ°©λ²μ λ¬Έμμ μλ―Έμ λ΄μ©μ 벑ν°μ μμΆν΄ λ΄μλ΄λ©°, μ΄λ¬ν 벑ν°λ κ²μμ λ§€μ° ν¨κ³Όμ μ λλ€.
-
λ¬Έμ λΆν λ° μλ² λ©:
- λ¬Έμλ μλ² λ© λͺ¨λΈμ μ νλ 컨ν μ€νΈ μλμ°(512~8000 ν ν°) λλ¬Έμ λΆν λ©λλ€. κ° λ¬Έμ μ‘°κ°μ 벑ν°λ‘ μμΆλλ©°, μ΄ λ²‘ν°λ λ¬Έμμ μλ―Έμ μλ―Έλ₯Ό λ΄κ³ μμ΅λλ€.
- μ§λ¬Έλ λμΌν λ°©μμΌλ‘ μλ² λ©λλ©°, μ΄λ κ² μμ±λ 벑ν°λ€μ λΉκ΅νμ¬ κ΄λ ¨ λ¬Έμλ₯Ό κ²μνκ² λ©λλ€.
-
μ½λ μμ°
1. tiktoken
ν¨ν€μ§μ ν ν° κ°μ κ³μ°
1
2
3
4
5
6
7
8
9
10
import tiktoken
def num_tokens_from_string(string: str, encoding_name: str) -> int:
"""Returns the number of tokens in a text string."""
encoding = tiktoken.get_encoding(encoding_name)
num_tokens = len(encoding.encode(string))
return num_tokens
num_tokens_from_string(question, "cl100k_base")
μ€λͺ :
tiktoken
ν¨ν€μ§λ₯Ό μ¬μ©νμ¬ λ¬Έμμ΄μ ν ν° κ°μλ₯Ό κ³μ°ν©λλ€. μ¬κΈ°μ βν ν°βμ ν μ€νΈλ₯Ό ꡬμ±νλ μμ λ¨μλ‘, μΌλ°μ μΌλ‘ λ¨μ΄ λλ λ¨μ΄μ μΌλΆλ₯Ό μλ―Έν©λλ€.num_tokens_from_string
ν¨μλ μ£Όμ΄μ§ λ¬Έμμ΄κ³Ό μΈμ½λ© λ°©μμ μ¬μ©νμ¬ ν΄λΉ λ¬Έμμ΄μ ν ν° κ°μλ₯Ό λ°νν©λλ€.tiktoken.get_encoding(encoding_name)
μ μ§μ λ μΈμ½λ© λ°©μμ λΆλ¬μ€κ³ ,encoding.encode(string)
μ λ¬Έμμ΄μ ν ν°μΌλ‘ μΈμ½λ©ν©λλ€.- λ§μ§λ§μΌλ‘
len(encoding.encode(string))
μ μΈμ½λ©λ ν ν° λ¦¬μ€νΈμ κΈΈμ΄(ν ν° κ°μ)λ₯Ό λ°νν©λλ€.
tiktoken ν¨ν€μ§ μ€λͺ :
tiktoken
μ μ£Όλ‘ OpenAIμ λͺ¨λΈλ€(μ: GPT-3.5, GPT-4 λ±)μμ μ¬μ©λλ ν ν°ν(tokenization) λΌμ΄λΈλ¬λ¦¬μ λλ€. μ΄ ν¨ν€μ§λ ν μ€νΈλ₯Ό ν ν°μΌλ‘ λ³ννκ³ , μ΄λ¬ν ν ν°μ΄ λͺ¨λΈμ μ λ ₯λ λμ ν ν° μλ₯Ό κ³μ°νλ λ° μ¬μ©λ©λλ€. κ° ν ν°μ μ½ 4μ μ λλ‘ κ΅¬μ±λ λ¨μμ΄λ©°, μ΄λ λͺ¨λΈμ΄ ν μ€νΈλ₯Ό μ²λ¦¬ν λμ κΈ°λ³Έμ μΈ λ¨μκ° λ©λλ€.
2. ν μ€νΈ μλ² λ© λͺ¨λΈ
1
2
3
4
5
6
from langchain_openai import OpenAIEmbeddings
embd = OpenAIEmbeddings()
query_result = embd.embed_query(question)
document_result = embd.embed_query(document)
len(query_result)
μ€λͺ :
- μ΄ μ½λ λΈλ‘μμλ
langchain_openai
ν¨ν€μ§μOpenAIEmbeddings
λ₯Ό μ¬μ©νμ¬ μ£Όμ΄μ§ μ§λ¬Έκ³Ό λ¬Έμλ₯Ό μλ² λ©ν©λλ€. - μλ² λ©(embedding)μ΄λ ν μ€νΈλ₯Ό κ³ μ°¨μ 벑ν°λ‘ λ³ννλ κ³Όμ μ λλ€. μ΄ λ²‘ν°λ€μ μλ―Έμ μΌλ‘ μ μ¬ν ν μ€νΈλ€μ΄ μλ‘ κ°κΉμ΄ μμΉνλλ‘ νμ¬, ν μ€νΈμ μλ―Έλ₯Ό μμΉμ μΌλ‘ ννν μ μκ² ν©λλ€.
embed_query
λ©μλλ μ£Όμ΄μ§ ν μ€νΈ(μ§λ¬Έμ΄λ λ¬Έμ)λ₯Ό μλ² λ©νμ¬ λ²‘ν° ννμΌλ‘ λ³νν©λλ€.- κ²°κ³Όμ μΌλ‘
query_result
μdocument_result
λ κ°κ° μ§λ¬Έκ³Ό λ¬Έμμ μλ² λ© λ²‘ν°κ° λ©λλ€.(printλ‘ κΈΈμ΄ μΆλ ₯ μ λμΌ κΈΈμ΄μ μλ°°λ© λ²‘ν°κ° μμ±λλ κ²μ νμΈν μ μμ)
3. μ½μ¬μΈ μ μ¬λ κ³μ°
1
2
3
4
5
6
7
8
9
10
11
import numpy as np
def cosine_similarity(vec1, vec2):
dot_product = np.dot(vec1, vec2)
norm_vec1 = np.linalg.norm(vec1)
norm_vec2 = np.linalg.norm(vec2)
return dot_product / (norm_vec1 * norm_vec2)
similarity = cosine_similarity(query_result, document_result)
print("Cosine Similarity:", similarity)
μ€λͺ :
- μ΄ λΈλ‘μ λ μλ² λ© λ²‘ν° κ°μ μ½μ¬μΈ μ μ¬λλ₯Ό κ³μ°ν©λλ€.
- μ½μ¬μΈ μ μ¬λλ λ λ²‘ν° μ¬μ΄μ κ°λλ₯Ό κΈ°λ°μΌλ‘ μ μ¬μ±μ μΈ‘μ νλ©°, 1μ κ°κΉμΈμλ‘ λ 벑ν°κ° μ μ¬νλ€λ κ²μ μλ―Έν©λλ€.
np.dot(vec1, vec2)
λ λ 벑ν°μ λ΄μ μ κ³μ°νκ³ ,np.linalg.norm(vec1)
μnp.linalg.norm(vec2)
λ κ°κ°μ 벑ν°μ ν¬κΈ°(λ Έλ¦)λ₯Ό κ³μ°ν©λλ€.- λ§μ§λ§μΌλ‘
dot_product / (norm_vec1 * norm_vec2)
λ μ½μ¬μΈ μ μ¬λλ₯Ό λ°νν©λλ€.
- μ κ° μ¬μ©ν GPT λͺ¨λΈμ μλ°°λ© κΈ°λ°μ Queryμ, Documentμ μ μ¬λλ κ·Έλ κ² λμ§ μμ§λ§, μ΄λμ λμ μ μ¬μ±μ λκ³ μκΈ΄νλ€μ!
4. λ¬Έμ λ‘λ
1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader(
web_paths=("<https://lilianweng.github.io/posts/2023-06-23-agent/>",),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
class_=("post-content", "post-title", "post-header")
)
),
)
blog_docs = loader.load()
μ€λͺ :
- μ΄ λΈλ‘μμλ
langchain_community
μWebBaseLoader
λ₯Ό μ¬μ©νμ¬ μ§μ λ μΉ νμ΄μ§μμ λ¬Έμλ₯Ό λ‘λν©λλ€. WebBaseLoader
λ μΉ νμ΄μ§μ νΉμ HTML μμλ₯Ό μΆμΆνμ¬ ν μ€νΈλ‘ λ³ννλ μν μ ν©λλ€. μ¬κΈ°μλbs4.SoupStrainer
λ₯Ό μ¬μ©νμ¬class_
λ‘ μ§μ λ μμλ€λ§ μΆμΆν©λλ€.loader.load()
λ λ‘λλ λ¬Έμλ₯Ό λ°νν©λλ€.
5. ν μ€νΈ λΆν κΈ°
1
2
3
4
5
6
7
8
9
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=300,
chunk_overlap=50
)
splits = text_splitter.split_documents(blog_docs)
μ€λͺ :
- μ΄ λΆλΆμ κΈ΄ ν
μ€νΈλ₯Ό μμ λ©μ΄λ¦¬λ‘ λΆν νλ κ³Όμ μ
λλ€.
RecursiveCharacterTextSplitter
λ ν μ€νΈλ₯Ό νΉμ ν¬κΈ°λ‘ λλλ, λ©μ΄λ¦¬ κ°μ κ²ΉμΉλ λΆλΆλ ν¬ν¨λλλ‘ ν©λλ€. chunk_size=300
μ κ° λ©μ΄λ¦¬μ μ΅λ ν¬κΈ°λ₯Ό μ€μ νλ©°,chunk_overlap=50
μ λ©μ΄λ¦¬ κ°μ κ²ΉμΉλ λΆλΆμ ν¬κΈ°λ₯Ό μ€μ ν©λλ€.- μ΅μ’
μ μΌλ‘
split_documents
λ©μλλ₯Ό ν΅ν΄ λ¬Έμλ₯Ό λΆν ν©λλ€.
6. λ²‘ν° μ€ν μ΄
1
2
3
4
5
6
7
8
9
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
vectorstore = Chroma.from_documents(documents=splits,
embedding=OpenAIEmbeddings())
# κ²μκΈ° μμ±
retriever = vectorstore.as_retriever()
μ€λͺ :
- μ΄ μ½λμμλ λΆν λ λ¬Έμ λ©μ΄λ¦¬λ€μ λ²‘ν° μ€ν μ΄μ μΈλ±μ±ν©λλ€.
Chroma
λ ν μ€νΈμ μλ² λ©μ μ μ₯νκ³ κ²μν μ μλ λ²‘ν° μ€ν μ΄λ₯Ό μμ±νλ μν μ ν©λλ€. Chroma.from_documents
λ λ¬Έμμ μλ² λ©μ μμ±νμ¬ λ²‘ν° μ€ν μ΄μ μ μ₯ν©λλ€.- λ§μ§λ§μΌλ‘
vectorstore.as_retriever()
λ₯Ό ν΅ν΄ μ μ₯λ μλ² λ©μμ ν μ€νΈ κ²μμ΄ κ°λ₯ν κ²μκΈ°λ₯Ό μμ±ν©λλ€.
Part 3 (κ²μ)
- μ΄ λΉλμ€λ LangChainμ Lanceκ° μ§ννλ βRAG From Scratchβ μ리μ¦μ μΈ λ²μ§Έ μμμΌλ‘, μ΄λ² μ£Όμ λ μ 보 κ²μ(Retrieval)μ λλ€.
- μμΈνμ κΈ°λ³Έ κ°λ
- λ¬Έμλ₯Ό μμΈννλ κ³Όμ μ λ¬Έμλ₯Ό μμ μ‘°κ°(Chunks)μΌλ‘ λλκ³ , μ΄λ₯Ό μλ² λ©(Embedding)νμ¬ λ²‘ν°ννλ κ²μ λλ€.
- μ΄ λ²‘ν°νλ μλ² λ©μ λ¬Έμμ μλ―Έμ λ΄μ©μ λ°λΌ κ³ μ°¨μ 곡κ°μ ν μ μΌλ‘ ννλ©λλ€. μ΄ μ μ μμΉλ λ¬Έμμ μλ―Έλ₯Ό λ°μνλ©°, μ§λ¬Έλ λμΌν λ°©μμΌλ‘ μλ² λ©λμ΄ ν΄λΉ 곡κ°μμ λ¬Έμμμ μ μ¬μ±μ κ²μνκ² λ©λλ€.
μ½λ μμ°
- λ¬Έμκ° μλ² λ©λ κ³ μ°¨μ 곡κ°μμ μ§λ¬Έκ³Ό μ μ¬ν λ¬Έμλ₯Ό κ²μνλ κ³Όμ μ λ‘컬 λ€μ΄λ²νλ κ²μ(Local Neighborhood Search)μ΄λΌκ³ ν μ μμ΅λλ€.
- μ΄ κ²μ κ³Όμ μμ μ§λ¬Έκ³Ό κ°κΉμ΄ μμΉμ μλ λ¬Έμλ€μ μ°Ύμλ΄κ³ , μ΄λ₯Ό κΈ°λ°μΌλ‘ κ΄λ ¨ λ¬Έμλ₯Ό λ°νν©λλ€.
- λ¬Έμ κ²μ μ, λ°νν λ¬Έμμ μλ₯Ό κ²°μ νλ K-κ°μ μ€μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, K=1λ‘ μ€μ νλ©΄ μ§λ¬Έκ³Ό κ°μ₯ κ°κΉμ΄ ν κ°μ λ¬Έμλ§ λ°νν©λλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13
# Index from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma # μμμ λ³Έ κ²μ²λΌ vectorstore μ μΈ vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings()) retriever = vectorstore.as_retriever(search_kwargs={"k": 1}) docs = retriever.get_relevant_documents("What is Task Decomposition?") len(docs) # 1μ΄ λ°νλ¨
Part 4 (μμ±)
- ν΄λΉ μμμμλ λ¬Έμ κ²μμ ν΅ν΄ μ»μ λ°μ΄ν°λ₯Ό κΈ°λ°μΌλ‘
LLM(Large Language Model)μ νμ©νμ¬ λ΅λ³μ μμ±νλ κ³Όμ
μ μ€μ μ λ‘λλ€.
(볡μ΅) λ¬Έμ μ½μ κ³Ό LLM 컨ν μ€νΈ μλμ°
- λ¬Έμ κ²μ ν, λ¬Έμλ₯Ό μμ λ¨μλ‘ λλ λ€, μ΄λ₯Ό 벑ν°λ‘ λ³ννμ¬ λ²‘ν° μ€ν μ΄μ μ μ₯ν©λλ€.
- μ§λ¬Έλ λ§μ°¬κ°μ§λ‘ 벑ν°λ‘ λ³ννμ¬ KNN(K-Nearest Neighbors)κ³Ό κ°μ κΈ°λ²μΌλ‘ κ²μλ λ¬Έμμ λΉκ΅ν©λλ€.
- κ²μλ λ¬Έμλ LLMμ 컨ν μ€νΈ μλμ°μ μ½μ λμ΄ λ΅λ³ μμ±μ μ¬μ©λ©λλ€.
μμμ 보μ¬λλ¦° κ·Έλ¦Όμ μ’ λ μμΈνκ² μ΄ν΄λ³΄λλ‘ νκ² μ΅λλ€:
- Documents β Embedding β Vectorstore
- Documents: μ΄ λΆλΆμ μ°λ¦¬κ° μ²λ¦¬νκ³ μ νλ μλ³Έ λ¬Έμμ λλ€. λ€μν ν μ€νΈ λ°μ΄ν°κ° ν¬ν¨λμ΄ μμ μ μμ΅λλ€.
- Embedding: λ¬Έμλ₯Ό μ§μ μ μΌλ‘ κ²μνκΈ° μ΄λ €μ°λ―λ‘, μ΄ λ¬Έμλ€μ μλ² λ©(embedding)νμ¬ κ³ μ°¨μ 벑ν°λ‘ λ³νν©λλ€. μλ² λ©λ 벑ν°λ λ¬Έμμ μλ―Έμ νΉμ§μ ν¬ν¨νκ³ μμΌλ©°, μ΄λ₯Ό λ°νμΌλ‘ μ μ¬λλ₯Ό κ³μ°ν μ μμ΅λλ€.
- Vectorstore: 벑ν°λ‘ λ³νλ λ¬Έμλ€μ λ²‘ν° μ€ν μ΄(vectorstore)μ μ μ₯λ©λλ€. λ²‘ν° μ€ν μ΄λ λμ€μ μ§λ¬Έκ³Ό μ μ¬ν λ¬Έμλ₯Ό ν¨μ¨μ μΌλ‘ κ²μνκΈ° μν΄ μ¬μ©λ©λλ€. (Ex. KNN, HNSW κΈ°λ² λ±μ κΈ°λ°μΌλ‘ κ²μμ μνν©λλ€.)
HNSW(Hierarchical Navigable Small World)
: κ³ μ°¨μ λ²‘ν° λ°μ΄ν°μ κ·Όμ¬ μ΅κ·Όμ μ΄μ(Approximate Nearest Neighbor) κ²μμ μν ν¨μ¨μ μΈ μκ³ λ¦¬μ¦μ λλ€.
- Question β Embedding β Vectorstore β Relevant Documents
- Question: μ¬μ©μκ° μ§λ¬Έμ λμ§λ©΄, μ΄ μ§λ¬Έλ λ¬Έμμ λμΌν λ°©μμΌλ‘ μλ² λ©λ©λλ€. μ¦, μ§λ¬Έλ 벑ν°λ‘ λ³νλ©λλ€.
- Vectorstore β Relevant Documents: λ³νλ μ§λ¬Έ 벑ν°λ λ²‘ν° μ€ν μ΄μμ λ¬Έμ 벑ν°λ€κ³Ό λΉκ΅λμ΄ κ°μ₯ μ μ¬ν λ¬Έμλ€μ΄ κ²μλ©λλ€.
- μ΄ λ¬Έμλ€μ΄ Relevant Documentsλ‘ νμλ©λλ€. μ΄λ μ§λ¬Έκ³Ό μλ―Έμ μΌλ‘ κ°μ₯ κ°κΉμ΄ λ¬Έμλ€μ΄λ©°, LLMμ 컨ν μ€νΈλ‘ μ¬μ©λ©λλ€.
- Dict μμ±
- κ²μλ λ¬Έμμ μ§λ¬Έμ DictλΌλ μλ£ κ΅¬μ‘°λ‘ λ³νλ©λλ€.
- μ΄ Dictλ λ κ°μ§ νλλ₯Ό ν¬ν¨νκ³ μλλ°:
- {Context}: κ²μλ λ¬Έμκ° λ€μ΄κ°λλ€.
- {Question}: μ¬μ©μμ μ§λ¬Έμ΄ λ€μ΄κ°λλ€.
- μ΄ Dictλ Prompt Templateμ λ€μ΄κ° λ°μ΄ν°λ₯Ό μ μνλ μ€μν μν μ ν©λλ€.
- Prompt Template
- ν둬ννΈ ν
νλ¦Ώ(Prompt Template)μ LLM(Large Language Model)μ μ΄μ©νμ¬ ν
μ€νΈλ₯Ό μμ±ν λ μ€μν μν μ ν©λλ€.
- LLMμ ν μ€νΈ λ°μ΄ν°λ₯Ό λ°μλ€μ΄λ λ°©μμ΄ λ§€μ° μ μ°νμ§λ§, μ¬μ©μκ° μνλ λλ‘ κ²°κ³Όλ₯Ό λμΆνλ €λ©΄ μΌκ΄λκ³ κ΅¬μ‘°νλ λ°©μμΌλ‘ λͺ¨λΈμκ² μ 보λ₯Ό μ 곡ν νμκ° μμ΅λλ€. ν둬ννΈ ν νλ¦Ώμ λ°λ‘ μ΄ κ³Όμ μ λκΈ° μν λꡬμ λλ€.
- ν둬ννΈ ν
νλ¦Ώμ ν
μ€νΈ μμ± κ³Όμ μ μ½κ² λ°λ³΅ κ°λ₯νκ² νκ³ , κ°κΈ° λ€λ₯Έ μ
λ ₯μ λ°λΌ λ³νν μ μλ μΌμ’
μ ν
νλ¦Ώμ μ 곡ν©λλ€.
- λ¬Έμμ μ§λ¬Έμ κΈ°λ°μΌλ‘ λ΅λ³μ μμ±νλ μμ μ ν λ, λͺ¨λΈμ λμΌν κ΅¬μ‘°λ‘ μ 보(λ¬Έμμ μ§λ¬Έ)λ₯Ό μ λ¬νλ κ²μ΄ μ€μν©λλ€.
- ν둬ννΈ ν
νλ¦Ώμ λ¬Έμλ₯Ό {context}μ, μ§λ¬Έμ {question}μ μ½μ
ν¨μΌλ‘μ¨ μ΄ κ΅¬μ‘°λ₯Ό μ μ§ν΄ μ€λλ€.
1 2 3 4 5 6 7 8
# μμ ν둬ννΈ ν νλ Answer the question based only on the following context: {context} Question: {question}
- μ΄μ , μ€μ λ°μ΄ν°λ₯Ό ν둬ννΈ ν νλ¦Ώμ μ±μ λ£λ μκ°, Prompt ValueλΌλ μ΅μ’ ν둬ννΈκ° λ§λ€μ΄μ§λλ€. μ΄ ν둬ννΈλ ν μ€νΈλ‘ λ³νλμ΄ LLMμ μ λ¬ν μ€λΉκ° λ μνμ λλ€.
- μλ₯Ό λ€μ΄, ν
νλ¦Ώμ κ²μλ λ¬Έμμ μ§λ¬Έμ΄ μ½μ
λλ©΄ λ€μκ³Ό κ°μ ννλ‘ λ³νλ©λλ€.
1 2 3 4 5 6
Answer the question based only on the following context: "Document 1 content here. Document 2 content here..." Question: "What is Task Decomposition?"
- ν둬ννΈ ν
νλ¦Ώ(Prompt Template)μ LLM(Large Language Model)μ μ΄μ©νμ¬ ν
μ€νΈλ₯Ό μμ±ν λ μ€μν μν μ ν©λλ€.
Q. μλ κ·Έλ₯ dictλ‘ μ£Όλ©΄ λμ§ μλ? μ ν둬ννΈ ν νλ¦Ώμ μ¬μ©νμ§?
A. μ΄ λ°©μμ λ€μκ³Ό κ°μ μ₯μ μ΄ μμ΅λλ€:
- μλν: μ¬λ¬ κ°μ μ§λ¬Έκ³Ό 컨ν μ€νΈμ λν΄ λμΌν νμμ ν둬ννΈλ₯Ό μλμΌλ‘ μμ±ν μ μμ΅λλ€.
- μ¬μ¬μ©μ±: κ°μ ν둬ννΈ ν νλ¦Ώμ λ€μν μ λ ₯ λ°μ΄ν°μ μ¬μ©ν μ μμ΅λλ€.
- μΌκ΄μ±: μΌμ ν νμμΌλ‘ LLMμ λ°μ΄ν°λ₯Ό μ λ¬νμ¬, λ μΌκ΄λ κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€.
- LLM (Large Language Model)
- Prompt Valueκ° LLMμ μ λ¬λ©λλ€. LLMμ 컨ν μ€νΈ μλμ°(Context Window)λ₯Ό μ¬μ©ν΄ μ λ¬λ λ¬Έμμ μ§λ¬Έμ λ°νμΌλ‘ λ΅λ³μ μμ±ν©λλ€.
- Parser
- LLMμμ μμ±λ λ΅λ³μ Parserλ₯Ό ν΅ν΄ μ²λ¦¬λ©λλ€. Parserλ LLMμμ μμ±λ ν μ€νΈ λ°μ΄ν°λ₯Ό μ μ ν νμ±νμ¬ μ΅μ’ μ μΌλ‘ Answerλ‘ λ°νν©λλ€.
μ½λ μμ°
- λ¬Έμλ₯Ό λ‘λνκ³ , μ΄λ₯Ό λΆν ν ν, μλ² λ©μ μ μ©νμ¬ λ²‘ν°λ‘ λ³ννκ³ λ²‘ν° μ€ν μ΄μ μ μ₯νλ μμ μ 보μ¬μ€λλ€.
- μμ± λΆλΆμμλ κ°λ¨ν ν둬ννΈ ν νλ¦Ώμ λ§λ€μ΄, λ¬Έλ§₯(context)κ³Ό μ§λ¬Έ(question)μ λ°νμΌλ‘ λ΅λ³μ μμ±νλ λ°©μμ μ€λͺ ν©λλ€.
- LangChainμμ μ 곡νλ
LangChain Expression Language
λ₯Ό νμ©νμ¬ ν둬ννΈ, LLM, νμ(parser), κ·Έλ¦¬κ³ λ¦¬νΈλ¦¬λ²(retriever)λ₯Ό μ½κ² μ°κ²°ν μ μμ΅λλ€.
(1) ν둬ννΈ ν νλ¦Ώμ΄ LLMμ λ€μ΄κ°λ κ³Όμ
- μλ μ½λλ₯Ό ν΅ν΄ ν둬ννΈ ν
νλ¦Ώμ LLMμ μ λ¬λκ³ , κ·Έ κ²°κ³Όλ‘ λ΅λ³μ΄ μμ±ν μ μμ΅λλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate # ν둬ννΈ ν νλ¦Ώ μ μ template = """Answer the question based only on the following context: {context} Question: {question} """ # ν νλ¦Ώμ ChatPromptTemplate κ°μ²΄λ‘ λ³ν prompt = ChatPromptTemplate.from_template(template) # LLM μμ± llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) # 체μΈ(chain) μμ±: ν둬ννΈμ LLM μ°κ²° chain = prompt | llm # μ€ν: 컨ν μ€νΈμ μ§λ¬Έμ ν νλ¦Ώμ μ½μ νμ¬ λ΅λ³ μμ± # μμμ μ μΈν΄λ docsμ Questionμ Invokeνλ νν chain.invoke({"context": docs, "question": "What is Task Decomposition?"})
- ν둬ννΈ ν νλ¦Ώ μ μ: λ¨Όμ ν νλ¦Ώ λ¬Έμμ΄μ μ μν©λλ€. μ¬κΈ°μ {context}λ κ²μλ λ¬Έμκ° μ½μ λλ μ리μ΄κ³ , {question}μ μ§λ¬Έμ΄ μ½μ λλ μ리μ λλ€. μ΄ ν νλ¦Ώμ λ΅λ³μ μμ±νλ λ° νμν λͺ¨λ μ 보λ₯Ό μ 곡ν©λλ€.
- ν νλ¦Ώμ κ°μ²΄λ‘ λ³ν: ChatPromptTemplate.from_template() λ©μλλ₯Ό μ¬μ©ν΄ λ¬Έμμ΄ ννμ ν νλ¦Ώμ κ°μ²΄λ‘ λ³νν©λλ€. μ΄ κ°μ²΄λ λμ€μ λ°μ΄ν°κ° μ½μ λ μ μλ μ€λΉλ ν νλ¦Ώμ λλ€.
- LLM μ μ: ChatOpenAI ν΄λμ€μμ gpt-3.5-turboλΌλ λͺ¨λΈμ μ ννμ¬ LLMμ μ μν©λλ€. μ¬κΈ°μ temperature=0μ λͺ¨λΈμ΄ λμ± μΌκ΄λ(μ¦, λ λλ€ν) λ΅λ³μ μμ±νλλ‘ μ€μ ν κ²μ λλ€.
- ν둬ννΈμ LLM μ°κ²°(Chain): ν둬ννΈ ν νλ¦Ώκ³Ό LLMμ μ°κ²°νμ¬ μ²΄μΈμ λ§λλλ€. μ΄ μ²΄μΈμ ν둬ννΈμ λ°μ΄ν°λ₯Ό μ½μ νκ³ , LLMμ νΈμΆν΄ λ΅λ³μ μμ±νλ μ 체 νλ‘μΈμ€λ₯Ό νλμ νλ¦μΌλ‘ λ¬Άμ΅λλ€.
- μ€ν: chain.invoke() λ©μλλ₯Ό ν΅ν΄ {context}μλ λ¬Έμ(docs)κ°, {question}μλ μ§λ¬Έμ΄ μ½μ λ ν둬ννΈκ° LLMμ μ λ¬λ©λλ€. λͺ¨λΈμ μ΄ ν둬ννΈλ₯Ό κΈ°λ°μΌλ‘ λ΅λ³μ μμ±νκ³ , κ·Έ κ²°κ³Όλ₯Ό λ°νν©λλ€.
(2) LangChainκ³Ό ν둬ννΈ ν νλ¦Ώ
- LangChainμμλ ν둬ννΈ ν νλ¦Ώμ λ³΄λ€ μ½κ² μ¬μ©ν μ μλ λ€μν λꡬλ₯Ό μ 곡ν©λλ€.
- μλ₯Ό λ€μ΄, ν
νλ¦Ώκ³Ό LLM, κ·Έλ¦¬κ³ νμλ₯Ό μ°κ²°νμ¬ νλμ νμ΄νλΌμΈμ λ§λ€κ³ , μ΄λ₯Ό ν΅ν΄ κ²μ κΈ°λ° λ΅λ³ μμ±(RAG)μ μνν μ μμ΅λλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
from langchain import hub from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough prompt_hub_rag = hub.pull("rlm/rag-prompt") # RAG μ²΄μΈ μμ± rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt_hub_rag # νΈμΆν template μ¬μ© | llm | StrOutputParser() ) # μ§λ¬Έμ λν λ΅λ³ μμ± rag_chain.invoke("What is Task Decomposition?")
- μ λλ‘ κ²°κ³Όκ° μΆλ ₯λκ³ , μ€νλ κ²μ νμΈν μ μμ΅λλ€: