AI Agent ์คํฐ๋์์ AI Agent ๊ธฐ๋ฐ์ ์ธํ๋ฃจ์ธ์ ๋งค์นญ ํ๋ซํผ์ ์ค์ต ํ๋ก์ ํธ๋ก ์งํํ๊ณ ์๋ค. ๊ด๊ณ ์ฃผ๊ฐ ๊ด๊ณ ์ปจ์ , ์์ดํ , ์์ฐ ๋ฑ์ ์ ๋ ฅํ๋ฉด, LangGraph ๊ธฐ๋ฐ AI Agent๊ฐ DB์์ ์ต์ ์ ์ธํ๋ฃจ์ธ์๋ฅผ ๊ฒ์ํ๊ณ ์ถ์ฒํด์ฃผ๋ ์๋น์ค์ด๋ค.
์คํฐ๋์์๋ ํ๋ก์ ํธ ์ค์ต๊ณผ ๋ณํํ์ฌ UC Berkeley์ LLM Agent ๊ฐ์๋ฅผ ํ ๊ฐ์์ฉ ์๊ฐํ๊ณ ์๋๋ฐ, ์ด ๊ฐ์๋ฅผ ํตํด LlamaIndex๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ฒ ๋์๋ค.
๊ธฐ์กด ํ๋ก์ ํธ๋ SQL ๊ธฐ๋ฐ์ ์ ํ ๋งค์นญ(์นดํ ๊ณ ๋ฆฌ๋ช , ํ๋ซํผ, ํ๋ก์ ์ ๋ฒ์)์ผ๋ก ์ธํ๋ฃจ์ธ์๋ฅผ ๊ฒ์ํ๊ณ ์์๋๋ฐ, LlamaIndex๋ฅผ ๋์ ํ๋ฉด ์์ฐ์ด ๊ธฐ๋ฐ ์๋งจํฑ ๊ฒ์๊ณผ ๊ณผ๊ฑฐ ์ฑ๊ณต ์ฌ๋ก๋ฅผ ๊ทผ๊ฑฐ๋ก ํ RAG ๋ถ์์ด ๊ฐ๋ฅํด์ง๋ค๋ ์ ์์ ์ฐ๋ฆฌ ํ๋ก์ ํธ์ ๋์ ํ๊ฒ ๋์๋ค.
ํ๋ก์ ํธ์ ๋์ ํ LlamaIndex ๊ด๋ จ ์ฝ๋๋ค์ ๋ถ์ํ๊ธฐ ์ ์, LlamaIndex๊ฐ ์ ํํ ๋ฌด์์ด๊ณ , ์ด๋ค ๊ฐ๋ ๋ค๋ก ๊ตฌ์ฑ๋์ด ์๋์ง ์ ๋๋ก ์์๋ณด์.
LlamaIndex(๊ตฌ GPT Index)๋ LLM ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ ๋ฐ์ดํฐ ํ๋ ์์ํฌ์ด๋ค.
ํต์ฌ ๋ชฉ์ ์ ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ LLM์ ์ฐ๊ฒฐํ๋ ๊ฒ์ด๋ค.
LLM(GPT-4, Claude ๋ฑ)์ ํ์ต ๋ฐ์ดํฐ๊น์ง๋ง ์๊ณ ์๊ณ , ์ฌ์ฉ์์ ๊ฐ์ธ ๋ฐ์ดํฐ(DB, ๋ฌธ์, API ๋ฑ)๋ ๋ชจ๋ฅธ๋ค. LlamaIndex๋ ์ด ๊ฐ๊ทน์ ๋ฉ์์ค๋ค.
| ๋ฌธ์ | LlamaIndex์ ํด๊ฒฐ |
|---|---|
| LLM์ ๋ด ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ฆ | ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ ์ธ๋ฑ์ฑํ์ฌ LLM์ ์ ๊ณต |
| ๋ฌธ์๊ฐ ๋๋ฌด ๊ธธ์ด ์ปจํ ์คํธ์ ์ ๋ค์ด๊ฐ | ์ฒญํน + ์๋ฒ ๋ฉ์ผ๋ก ๊ด๋ จ ๋ถ๋ถ๋ง ๊ฒ์ |
| ๋จ์ ๊ฒ์์ ์๋ฏธ๋ฅผ ๋ชป ์ก์ | ์๋งจํฑ ๊ฒ์(๋ฒกํฐ ์ ์ฌ๋) ์ ๊ณต |
| ๋ฐ์ดํฐ ์์ค๊ฐ ๋ค์ํจ | ํตํฉ ์ปค๋ฅํฐ(PDF, DB, API, ์น ๋ฑ) ์ ๊ณต |
๐ก ์๋ณธ ๋ฐ์ดํฐ โ Document โ Node(์ฒญํฌ)
Document๋ LlamaIndex์์ ์๋ณธ ๋ฐ์ดํฐ ํ๋๋ฅผ ํํํ๋ ๊ฐ์ฒด์ด๋ค.
PDF ํ์ผ ํ๋, DB ํ ํ๋, ์น ํ์ด์ง ํ๋ ๋ฑ์ด ๊ฐ๊ฐ ํ๋์ Document๊ฐ ๋๋ค.
๐ก Document = text(์๋ฒ ๋ฉ ๋์, ๊ฒ์์ ๊ธฐ์ค) + metadata(๋ถ๊ฐ ์ ๋ณด, ํํฐ๋ง์ฉ)
text๋ง ๋ฃ๊ธฐ (๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์์ฑ)
from llama_index.core import Document
doc = Document(text="์ธํ๋ฃจ์ธ์ ๊น์ฒ ์๋ ๋ทฐํฐ ์นดํ
๊ณ ๋ฆฌ ์ ํ๋ฒ์
๋๋ค.")
text์ ๋ค์ด๊ฐ๋ ๋ฌธ์์ด์ด ๋์ค์ ์๋ฒ ๋ฉ(๋ฒกํฐ ๋ณํ)์ ๋์์ด ๋๋ค.text์ ํฌํจ์์ผ์ผ ํ๋ค.doc = Document(
text="์ธํ๋ฃจ์ธ์ ๊น์ฒ ์๋ ๋ทฐํฐ ์นดํ
๊ณ ๋ฆฌ ์ ํ๋ฒ์
๋๋ค.",
metadata={
"influencer_id": "123",
"total_followers": 150000,
"categories": ["๋ทฐํฐ", "๋ผ์ดํ์คํ์ผ"],
},
)์ค์ ๋ฐ์ดํฐ๋ ๋ณดํต Document ํ๋๊ฐ ๋งค์ฐ ๊ธธ๋ค.
์๋ฅผ ๋ค์ด PDF ํ ์ฅ์ด ์์ฒ ๊ธ์์ผ ์ ์๋ค. ์ด๊ฑธ ํต์จฐ๋ก ์๋ฒ ๋ฉํ๋ฉด ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
๊ทธ๋์ Document๋ฅผ ์์ ์กฐ๊ฐ(Node)์ผ๋ก ์ชผ๊ฐ๋ ๊ณผ์ ์ด ํ์ํ๋ค. ์ด๊ฒ์ด ์ฒญํน(Chunking)์ด๋ค.
from llama_index.core.node_parser import SentenceSplitter
parser = SentenceSplitter(chunk_size=512, chunk_overlap=50)
nodes = parser.get_nodes_from_documents([doc])
chunk_size=512: ํ Node์ ์ต๋ ํ ํฐ ์. ํ๋์ ์ฒญํฌ๊ฐ ์ต๋ 512ํ ํฐ๊น์ง ๋ด๊ธธ ์ ์๋ค.
chunk_overlap=50: ์ธ์ ํ Node ๊ฐ์ 50ํ ํฐ์ ๊ฒน์น๊ฒ ํ๋ค.
chunk_overlap=0)Node 1: "๊น์ฒ ์๋ ๋ทฐํฐ ์ ํ๋ฒ์ด๋ค. ์ฃผ๋ก ํ์ฅํ ๋ฆฌ๋ทฐ๋ฅผ ํ๋ฉฐ, ํนํ ์คํจ์ผ์ด ์ ํ์ ๋ํ ์ ๋ฌธ์ฑ์ด ๋๋ค. ์ต๊ทผ์๋ LG์ํ๊ฑด๊ฐ๊ณผ"
Node 2: "ํ์
ํ์ฌ ํฐ ์ฑ๊ณผ๋ฅผ ๋๋ค. ํด๋น ์บ ํ์ธ์์ ์กฐํ์ 50๋ง, ์ข์์ 3๋ง์ ๋ฌ์ฑํ๋ค..."๐ "LG์ํ๊ฑด๊ฐ๊ณผ ํ์ ํ์ฌ ํฐ ์ฑ๊ณผ๋ฅผ ๋๋ค"๋ผ๋ ๋ฌธ๋งฅ์ด ๋ Node๋ก ๋ถ๋ฆฌ๋์ด ์๋ฏธ๊ฐ ๋๊ธด๋ค. "LG์ํ๊ฑด๊ฐ๊ณผ" ๊ฒ์ ์ Node 1์์ ๊ฑธ๋ฆฌ์ง๋ง, ์ฑ๊ณผ ์ ๋ณด๋ Node 2์๋ง ์๋ค.
chunk_overlap=50)Node 1: "๊น์ฒ ์๋ ๋ทฐํฐ ์ ํ๋ฒ์ด๋ค. ์ฃผ๋ก ํ์ฅํ ๋ฆฌ๋ทฐ๋ฅผ ํ๋ฉฐ, ํนํ ์คํจ์ผ์ด ์ ํ์ ๋ํ ์ ๋ฌธ์ฑ์ด ๋๋ค. ์ต๊ทผ์๋ LG์ํ๊ฑด๊ฐ๊ณผ ํ์
ํ์ฌ ํฐ ์ฑ๊ณผ๋ฅผ ๋๋ค."
Node 2: "์ต๊ทผ์๋ LG์ํ๊ฑด๊ฐ๊ณผ ํ์
ํ์ฌ ํฐ ์ฑ๊ณผ๋ฅผ ๋๋ค. ํด๋น ์บ ํ์ธ์์ ์กฐํ์ 50๋ง, ์ข์์ 3๋ง์ ๋ฌ์ฑํ๋ค..."๐ ๊ฒน์น๋ ๊ตฌ๊ฐ ๋๋ถ์ ๋ฌธ๋งฅ์ด ์ ์ง๋๋ค.
SentenceSplitter๋ ๋ฌธ์ฅ ๊ฒฝ๊ณ๋ฅผ ์กด์คํ๋ฉด์ ๋๋๋ ๋๊ตฌ๋ก, LlamaIndex๊ฐ ๋ด๋ถ์ ์ผ๋ก ์๋ ์ฒ๋ฆฌํด์ค๋ค.
์ค์ ๋ก VectorStoreIndex.from_documents(documents)๋ฅผ ํธ์ถํ๋ฉด, LlamaIndex๊ฐ ๋ด๋ถ์ ์ผ๋ก ๋ค์ ๊ณผ์ ์ ์๋ ์ํํ๋ค.
SentenceSplitter, chunk_size=1024)๋ช
์์ ์ผ๋ก SentenceSplitter๋ฅผ ์ง์ ์ฐ๋ ๊ฒฝ์ฐ๋ ๊ธฐ๋ณธ๊ฐ(1024ํ ํฐ)์ด ์๋ ๋ค๋ฅธ ์ค์ ์ ์ฐ๊ณ ์ถ์ ๋์ด๋ค.
๋ด๋ถ์ ์ผ๋ก ., !, ?, \n ๊ฐ์ ๋ฌธ์ฅ ๊ตฌ๋ถ์๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถํ ํ ๋ค, chunk_size์ ๋ง๊ฒ ๋ฌธ์ฅ๋ค์ ๋ฌถ๋๋ค.
์์ฑ๋ Node๋ ์๋ณธ Document์ ์ ๋ณด๋ฅผ ๊ทธ๋๋ก ๊ฐ์ง๊ณ ์๋ค.
for node in nodes:
print(node.text) # ์ฒญํฌ ํ
์คํธ
print(node.metadata) # Document์์ ์์๋ฐ์ ๋ฉํ๋ฐ์ดํฐ
print(node.relationships) # ์ด์ /๋ค์ Node์์ ๊ด๊ณ
print(node.node_id) # ๊ณ ์ ID
ํนํ relationships๊ฐ ์ค์ํ๋ค. Node๋ ์์ ์ ์ด์ Node, ๋ค์ Node, ์๋ณธ Document์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ๋ค. ๋๋ถ์ ๊ฒ์ ๊ฒฐ๊ณผ์์ "์๋ค ๋งฅ๋ฝ"์ ์ถ์ ํ ์ ์๋ค.
ํ ์คํธ๋ฅผ ๊ณ ์ฐจ์ ๋ฒกํฐ(์ซ์ ๋ฐฐ์ด)๋ก ๋ณํํ๋ ๊ฒ์ด๋ค.
"๋ทฐํฐ ์ ํ๋ฒ" โ [0.12, -0.34, 0.56, ..., 0.78] (1536์ฐจ์)
"ํ์ฅํ ๋ฆฌ๋ทฐ์ด" โ [0.11, -0.33, 0.55, ..., 0.77] (๋น์ทํ ๋ฒกํฐ)
"๊ฒ์ ์คํธ๋ฆฌ๋จธ" โ [-0.45, 0.67, -0.12, ..., 0.23] (๋ค๋ฅธ ๋ฒกํฐ)
์๋ฏธ๊ฐ ๋น์ทํ ํ ์คํธ๋ ๋ฒกํฐ ๊ณต๊ฐ์์ ๊ฐ๊น์ด ์์นํ๋ค. ์ด๊ฒ์ด ์๋งจํฑ ๊ฒ์์ ์๋ฆฌ์ด๋ค.
from llama_index.embeddings.openai import OpenAiEmbedding
embed_model = OpenAIEmbedding(model="text-embedding-3-small")
OPENAI_API_KEY ํ์from llama_index.embeddings.huggingface import HuggingFaceEmbedding
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
Node๋ค์ ๊ฒ์ ๊ฐ๋ฅํ ๊ตฌ์กฐ๋ก ์กฐ์งํ๋ ๊ฒ์ด๋ค. LlamaIndex์ ์ด๋ฆ์ด ์ฌ๊ธฐ์ ์๋ค.
from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
Documents โ ์ฒญํน โ Nodes โ ์๋ฒ ๋ฉ โ ๋ฒกํฐ ์ ์ฅ
โ
์ง์ โ ์ง์ ์๋ฒ ๋ฉ โ ์ฝ์ฌ์ธ ์ ์ฌ๋ ๊ณ์ฐ โ ์์ K๊ฐ ๋
ธ๋ ๋ฐํ
VectorStoreIndex๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์ธ๋ฑ์ฑ ๋จ๊ณ์, ์ ์ฅ๋ ๋ฐ์ดํฐ์์ ์ฐพ๋ ๊ฒ์ ๋จ๊ณ๋ก ๋๋๋ค.
Documents โ ์ฒญํน โ Nodes โ ์๋ฒ ๋ฉ โ ๋ฒกํฐ ์ ์ฅ
Documents ์์ฑ
doc = Document(
text="๊น์ฒ ์: ๋ทฐํฐ ์ ๋ฌธ ์ ํ๋ฒ. ์นดํ
๊ณ ๋ฆฌ: ๋ทฐํฐ, ๋ผ์ดํ์คํ์ผ. ํ๋ก์: 150000๋ช
.",
metadata={"influencer_id": "123", "total_followers": 150000},
)
์ธํ๋ฃจ์ธ์ 50๋ช ์ด๋ฉด Document 50๊ฐ๊ฐ ๋ง๋ค์ด์ง๋ค.
์ฒญํน โ Nodes
Document 1 ("๊น์ฒ ์: ๋ทฐํฐ ์ ๋ฌธ ์ ํ๋ฒ...") โ Node 1
Document 2 ("์ด์ํฌ: ์คํจ์ผ์ด ์ ๋ฌธ...") โ Node 2
Document 3 ("๋ฐ์ง๋ฏผ: ๋ฉ์ดํฌ์
์ ๋ฌธ...") โ Node 3
...
์ด ํ๋ก์ ํธ์์๋ ์ธํ๋ฃจ์ธ์ ํ ๋ช
๋น ํ
์คํธ๊ฐ ์งง์์ Document 1๊ฐ = Node 1๊ฐ์ด๋ค.
๋ง์ฝ ํ
์คํธ๊ฐ ๊ธธ์๋ค๋ฉด Document 1๊ฐ๊ฐ ์ฌ๋ฌ Node๋ก ์ชผ๊ฐ์ง๋ค.
์๋ฒ ๋ฉ (ํต์ฌ)
๊ฐ Node์ ํ
์คํธ๋ฅผ ์ซ์ ๋ฐฐ์ด(๋ฒกํฐ)๋ก ๋ณํํ๋ค. ์ด๊ฒ VectorStoreIndex์ ํต์ฌ์ด๋ค.
Node 1 "๊น์ฒ ์: ๋ทฐํฐ ์ ๋ฌธ ์ ํ๋ฒ..."
โ ์๋ฒ ๋ฉ ๋ชจ๋ธ (OpenAI text-embedding-ada-002)
[0.12, -0.34, 0.56, 0.01, ..., 0.78] โ 1536์ฐจ์ ๋ฒกํฐ
Node 2 "์ด์ํฌ: ์คํจ์ผ์ด ์ ๋ฌธ..."
โ ์๋ฒ ๋ฉ ๋ชจ๋ธ
[0.11, -0.33, 0.55, 0.02, ..., 0.77] โ ๋ทฐํฐ์ ๋น์ท โ ๋ฒกํฐ๋ ๋น์ท!
Node 3 "์ ๋ฏผ์: ๊ฒ์ ์คํธ๋ฆฌ๋จธ..."
โ ์๋ฒ ๋ฉ ๋ชจ๋ธ
[-0.45, 0.67, -0.12, 0.89, ..., 0.23] โ ๋ทฐํฐ์ ๋ค๋ฆ โ ๋ฒกํฐ๋ ๋ค๋ฆ!
๋ฒกํฐ๋ก ๋ณํํ๋ ์ด์ ๋, ํ
์คํธ๋ผ๋ฆฌ๋ "์๋ฏธ์ ์ ์ฌ๋"๋ฅผ ์ง์ ๊ณ์ฐํ ์ ์์ง๋ง, ๋ฒกํฐ๋ผ๋ฆฌ๋ ์ํ์ ์ผ๋ก ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฒกํฐ ์ ์ฅ
๋ณํ๋ ๋ฒกํฐ๋ค์ Vector Store์ ์ ์ฅํ๋ค.
์ด ๊ณผ์ ์ด VectorStoreIndex.from_documents(documents) ํ ์ค๋ก ์ ๋ถ ์คํ๋๋ค.
2๋จ๊ณ: ๊ฒ์ (์ง์)
์ง์ โ ์ง์ ์๋ฒ ๋ฉ โ ์ฝ์ฌ์ธ ์ ์ฌ๋ ๊ณ์ฐ โ ์์ K๊ฐ ๋
ธ๋ ๋ฐํ
์ง์ ์๋ฒ ๋ฉ
์ฌ์ฉ์์ ์ง์๋ ๋์ผํ ์๋ฒ ๋ฉ ๋ชจ๋ธ๋ก ๋ฒกํฐ๋ก ๋ณํํ๋ค.
"์นํ๊ฒฝ ๋ทฐํฐ ์ธํ๋ฃจ์ธ์ ์ถ์ฒํด์ค"
โ ๊ฐ์ ์๋ฒ ๋ฉ ๋ชจ๋ธ
[0.13, -0.31, 0.54, 0.03, ..., 0.76] โ ์ง์ ๋ฒกํฐ
๊ฐ์ ๋ชจ๋ธ์ ์จ์ผ ๊ฐ์ ๋ฒกํฐ ๊ณต๊ฐ์์ ๋น๊ตํ ์ ์๋ค. ์ธ๋ฑ์ฑ ๋ OpenAI ๋ชจ๋ธ์ ์ผ์ผ๋ฉด, ๊ฒ์ ๋๋ OpenAI ๋ชจ๋ธ์ ์จ์ผ ํ๋ค.
์ฝ์ฌ์ธ ์ ์ฌ๋ ๊ณ์ฐ
์ง์ ๋ฒกํฐ์ ์ ์ฅ๋ ๋ชจ๋ ๋ฒกํฐ ์ฌ์ด์ ์ฝ์ฌ์ธ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํ๋ค.
์ฝ์ฌ์ธ ์ ์ฌ๋๋ ๋ ๋ฒกํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฐฉํฅ์ด ์ผ๋ง๋ ๋น์ทํ์ง๋ฅผ -1~1 ์ฌ์ด ๊ฐ์ผ๋ก ๋ํ๋ธ ๊ฒ์ผ๋ก, 1์ ๊ฐ๊น์ฐ๋ฉด ์๋ฏธ๊ฐ ๋น์ทํ๊ณ , 0์ ๊ฐ๊น์ฐ๋ฉด ๊ด๋ จ์ด ์๊ณ , -1์ ๊ฐ๊น์ฐ๋ฉด ์๋ฏธ๊ฐ ๋ฐ๋์ด๋ค.
์ง์ ๋ฒกํฐ: [0.13, -0.31, 0.54, ...] ("์นํ๊ฒฝ ๋ทฐํฐ ์ธํ๋ฃจ์ธ์ ์ถ์ฒํด์ค")
vs Node 1 [0.12, -0.34, 0.56, ...] ("๊น์ฒ ์: ๋ทฐํฐ ์ ๋ฌธ ์ ํ๋ฒ")
โ ์ฝ์ฌ์ธ ์ ์ฌ๋: 0.94 โ
๋งค์ฐ ์ ์ฌ!
vs Node 2 [0.11, -0.33, 0.55, ...] ("์ด์ํฌ: ์คํจ์ผ์ด ์ ๋ฌธ")
โ ์ฝ์ฌ์ธ ์ ์ฌ๋: 0.91 โ
์ ์ฌ!
vs Node 3 [-0.45, 0.67, -0.12, ...] ("์ ๋ฏผ์: ๊ฒ์ ์คํธ๋ฆฌ๋จธ")
โ ์ฝ์ฌ์ธ ์ ์ฌ๋: 0.23 โ ๊ด๋ จ ์์
์์ K๊ฐ ๋
ธ๋ ๋ฐํ
์ ์ฌ๋ ์ ์๊ฐ ๋์ ์์๋ก ์ ๋ ฌํ์ฌ ์์ K๊ฐ๋ฅผ ๋ฐํํ๋ค.
similarity_top_k=3 ์ด๋ฉด:
1์: Node 1 (๊น์ฒ ์: ๋ทฐํฐ ์ ๋ฌธ) ์ ์ฌ๋: 0.94
2์: Node 2 (์ด์ํฌ: ์คํจ์ผ์ด ์ ๋ฌธ) ์ ์ฌ๋: 0.91
3์: Node 7 (๋ฐ์ง๋ฏผ: ๋ฉ์ดํฌ์
์ ๋ฌธ) ์ ์ฌ๋: 0.88
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
4์: Node 5 (์ต์์ง: ํจ์
์ ๋ฌธ) ์ ์ฌ๋: 0.72 โ ์ฌ๊ธฐ๋ถํฐ ์๋ฆผ
...
| ์ธ๋ฑ์ค | ์ค๋ช | ์ฉ๋ |
|---|---|---|
| VectorStoreIndex | ๋ฒกํฐ ์ ์ฌ๋ ๊ธฐ๋ฐ ๊ฒ์ | ๊ฐ์ฅ ๋ฒ์ฉ์ , ์๋งจํฑ ๊ฒ์ |
| KnowledgeGraphIndex | ์ง์ ๊ทธ๋ํ ๊ตฌ์กฐ | ์ํฐํฐ ๊ฐ ๊ด๊ณ ํ์ |
| SummaryIndex | ์ ์ฒด ๋ฌธ์ ์์ฝ | ๋ฌธ์ ์ ์ฒด๋ฅผ ๋ค ์ฝ์ด์ผ ํ ๋ |
| TreeIndex | ํธ๋ฆฌ ๊ตฌ์กฐ ์์ฝ | ๊ณ์ธต์ ์์ฝ |
| KeywordTableIndex | ํค์๋ ๊ธฐ๋ฐ ๊ฒ์ | ์ ํํ ํค์๋ ๋งค์นญ |
์ด ๋์ ์ฐจ์ด๋ฅผ ํ ๋ง๋๋ก ํ๋ฉด, Retriever๋ ๊ฒ์๋ง, Query Engine์ ๊ฒ์ + LLM ๋ต๋ณ ์์ฑ์ด๋ค.
retriever = index.as_retriever(similarity_top_k=5)
nodes = retriever.retrieve("๋ทฐํฐ ์นดํ
๊ณ ๋ฆฌ ์ธํ๋ฃจ์ธ์ ์ฐพ์์ค")
๋ฐํ๋๋ nodes์ ํํ
for node in nodes:
print(node.get_text()) # "๊น์ฒ ์: ๋ทฐํฐ ์ ๋ฌธ ์ ํ๋ฒ. ์นดํ
๊ณ ๋ฆฌ: ๋ทฐํฐ, ๋ผ์ดํ์คํ์ผ..."
print(node.get_score()) # 0.9234 (์ ์ฌ๋ ์ ์)
print(node.metadata) # {"influender_id": "123", "total_followers": 150000}
LLM์ ์ ํ ์ฌ์ฉํ์ง ์๋๋ค. ์๋ฒ ๋ฉ ๋ชจ๋ธ๋ก ๋ฒกํฐ ์ ์ฌ๋๋ง ๊ณ์ฐํด์ ๊ฒฐ๊ณผ๋ฅผ ๋๋ ค์ค๋ค. ๊ทธ๋์ ๋น ๋ฅด๊ณ ๋น์ฉ๋ ์ ๋ค.
query_engine = index.as_query_engine(similarity_top_k=5)
response = query_engine.query("๋ทฐํฐ ์นดํ
๊ณ ๋ฆฌ ์ธํ๋ฃจ์ธ์ ์ถ์ฒํด์ค")
๋์ ๊ณผ์
LLM์ ์ฌ์ฉํ๋ฏ๋ก, ์์ฐ์ด๋ก ์ ๋ฆฌ๋ ๋ต๋ณ์ด ๋์จ๋ค.

VectorStoreIndex.from_documents()๋ฅผ ํธ์ถํ๋ฉด ๋ด๋ถ์ ์ผ๋ก ๋ชจ๋ Documents์ ๋ํด ์๋ฒ ๋ฉ API๋ฅผ ํธ์ถํ๋ค.
๊ทธ๋์ ํ ๋ฒ ๋ง๋ ์ธ๋ฑ์ค๋ฅผ ๋์คํฌ์ ์ ์ฅํด๋๊ณ , ๋ค์์๋ ์ ์ฅ๋ ๊ฒ์ ๋ก๋๋ง ํ๋ฉด ๋๋ค. ์๋ฒ ๋ฉ API๋ฅผ ๋ค์ ํธ์ถํ ํ์๊ฐ ์๋ค.
index.storage_context.persist(persist_dir="./storage")
์ด๋ ๊ฒ ํ๋ฉด ./storage/ ํด๋์ JSON ํ์ผ๋ค์ด ์๊ธด๋ค.
./storage/
โโโ docstore.json โ Document/Node ์๋ณธ ํ
์คํธ + ๋ฉํ๋ฐ์ดํฐ
โโโ index_store.json โ ์ธ๋ฑ์ค ๊ตฌ์กฐ ์ ๋ณด
โโโ default__vector_store.json โ ์๋ฒ ๋ฉ ๋ฒกํฐ๊ฐ๋ค
๋ฐ๋ผ์ ๋ค์ ์คํ ์์๋ ๋ก๋๋ง ํ๋ฉด ๋๋ค.
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
# chromaDB ํด๋ผ์ด์ธํธ ์์ฑ (๋์คํฌ์ ์๊ตฌ ์ ์ฅ)
chroma_client = chromadb.PersistentClient(path="./chroma_db")
# ์ปฌ๋ ์
= ๋ฒกํฐ๋ฅผ ๋ด๋ ๊ทธ๋ฃน (DB์ ํ
์ด๋ธ๊ณผ ๋น์ทํ ๊ฐ๋
)
collection = chroma_client.get_or_create_collection("influencer_profiles")
## LlamaIndex๊ฐ ์ด ์ปฌ๋ ์
์ ๋ฒกํฐ ์ ์ฅ์๋ก ์ฌ์ฉํ๋๋ก ์ฐ๊ฒฐ
vector_store = ChromaVectorStore(chroma_collection=collection)
๋์คํฌ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ ์ฅ๋๋ค.
./chroma_db/
โโโ chroma.sqlite3 โ ๋ฒกํฐ + ๋ฉํ๋ฐ์ดํฐ๊ฐ SQLite๋ก ์ ์ฅ๋จ
โโโ [๋ด๋ถ ํ์ผ๋ค...]
pip install chromadb)| ๋ก์ปฌ ํ์ผ์ ์ ์ฅ | ChromaDB์ ์ ์ฅ | |
|---|---|---|
| ์ ์ฅ | indexโJSON ํ์ผ๋ก ์ง๋ ฌํ | indexโChromaDB๊ฐ ์์ฒด ํ์์ผ๋ก ์ ์ฅ |
| ๋ก๋ | JSON ํ์ผ ์ ์ฒด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆผ | ์ฐ๊ฒฐ๋ง ๋งบ๊ณ , ์ค์ ๋ฐ์ดํฐ๋ ๊ฒ์ ์์๋ง ์ฝ์ |
| ๊ฒ์ | ๋ฉ๋ชจ๋ฆฌ์์ ๋ฒกํฐ ๋น๊ต | ChromaDB๊ฐ ์ต์ ํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ฒกํฐ ๋น๊ต |
LlamaIndex์ ๊ฐ์ฅ ๋ํ์ ์ธ ํจํด์ด๋ค.

SentenceSplitter ๋ฑ์ผ๋ก ์ชผ๊ฐ ์์ ์กฐ๊ฐ(Chunk)์ด๋ค. ๊ฒ์์ ์ต์ ๋จ์๊ฐ ๋๋ค.LlamaIndex๋ 160๊ฐ ์ด์์ ๋ฐ์ดํฐ ์์ค ์ปค๋ฅํฐ๋ฅผ ์ ๊ณตํ๋ค.
์น ํ์ด์ง
from llama_index.readers.web import SimpleWebPageReader
from llama_index.readers.file import PDFReader
๋ฐ์ดํฐ๋ฒ ์ด์ค
from llama_index.readers.database import DatabaseReader
CSV
from llama_index.readers.file import CSVReader
์ด ๋ฐ์๋ Notion, Slack, Google Docs ๋ฑ ์์ญ ๊ฐ์ง์ด๋ค.
| ํญ๋ชฉ | LlamaIndex | LangChain |
|---|---|---|
| ํต์ฌ ๋ชฉ์ | ๋ฐ์ดํฐ ์ธ๋ฑ์ฑ & ๊ฒ์ (RAG) | LLM ์ ํ๋ฆฌ์ผ์ด์ ์ค์ผ์คํธ๋ ์ด์ |
| ๊ฐ์ | ๋ค์ํ ์ธ๋ฑ์ค, ์๋ฒ ๋ฉ, ๊ฒ์ ์ต์ ํ | Agent, Chain, ๋๊ตฌ ์ฐ๊ฒฐ |
| ์ด ํ๋ก์ ํธ์์ | ๋ฒกํฐ ๊ฒ์, KG ์ธ๋ฑ์ค | Agent ์ค์ผ์คํธ๋ ์ด์ (LangGraph) |
| ๋น์ | ๋์๊ด ์ฌ์ (๋ฐ์ดํฐ๋ฅผ ์ ๋ฆฌํ๊ณ ์ฐพ์์ค) | ํ๋ก์ ํธ ๋งค๋์ (์์ ์ ์ฐ๊ฒฐํ๊ณ ์กฐ์จ) |