๋ญ์ค๋ฏธ์คยท๋ญ์ฒด์ธยท๋ญ๊ทธ๋ํ: ๊ฐ๋ฐ์๊ฐ LLM ์ฑ์ โ์ ํโ์ผ๋ก ๋ง๋๋ 3๋จ๊ณ ๋๊ตฌ
๋ญ์ค๋ฏธ์คยท๋ญ์ฒด์ธยท๋ญ๊ทธ๋ํ: ๊ฐ๋ฐ์๊ฐ LLM ์ฑ์ โ์ ํโ์ผ๋ก ๋ง๋๋ 3๋จ๊ณ ๋๊ตฌ LLM์ผ๋ก ์ฑ๋ด์ ๋ง๋ค๋ฉด ์ฒ์์ ๊ธ๋ฐฉ ๋ฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ๋ฉฐ์น ...
๋ญ์ค๋ฏธ์คยท๋ญ์ฒด์ธยท๋ญ๊ทธ๋ํ: ๊ฐ๋ฐ์๊ฐ LLM ์ฑ์ โ์ ํโ์ผ๋ก ๋ง๋๋ 3๋จ๊ณ ๋๊ตฌ
LLM์ผ๋ก ์ฑ๋ด์ ๋ง๋ค๋ฉด ์ฒ์์ ๊ธ๋ฐฉ ๋ฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ๋ฉฐ์น ๋ง ์ง๋๋ ์ด๋ฐ ๋ฌธ์ ๊ฐ ํฐ์ ธ์. ํ๋กฌํํธ๊ฐ ์ฌ๊ธฐ์ ๊ธฐ ํฉ์ด์ง๊ณ , ๋ํ ํ๋ฆ์ด ๊ผฌ์ด๊ณ , ์ด๋ ๋จ๊ณ์์ ์ ๋ต์ด ์ด์ํด์ก๋์ง ์ถ์ ์ด ์ ๋ฉ๋๋ค.
ํ ์ค ์์ฝ: ์ญํ ๋ถ๋ด์ด ํต์ฌ
- ๋ญ์ฒด์ธ: LLM ์ฑ์ *๋ถํ(์ฒด์ธ/๋๊ตฌ/ํ๋กฌํํธ)*์ ๋น ๋ฅด๊ฒ ์กฐ๋ฆฝํ๋ ํ๋ ์์ํฌ
- ๋ญ๊ทธ๋ํ: ์ํ์ ๋ถ๊ธฐ๋ฅผ ๊ฐ์ง ๋ํ/์์ด์ ํธ ํ๋ฆ์ ๊ทธ๋ํ๋ก ์ค๊ณ
- ๋ญ์ค๋ฏธ์ค: ์คํ ๊ธฐ๋ก์ ๊ธฐ๋ฐ์ผ๋ก ๋๋ฒ๊น , ํ ์คํธ, ํ์ง ์ ๊ฒ์ ๋๋ ๋๊ตฌ
๋ญ์ฒด์ธ: โ์กฐ๋ฆฝ ๊ฐ๋ฅํโ LLM ๊ฐ๋ฐ ๊ธฐ๋ณธ๊ธฐ
๋ญ์ฒด์ธ์ ๊ฐ๋ฐ์๊ฐ ์์ฃผ ์ฐ๋ ํจํดโํ๋กฌํํธ ํ ํ๋ฆฟ, ์ถ๋ ฅ ํ์, ๋๊ตฌ ํธ์ถ, ๊ฒ์ ๊ธฐ๋ฐ ์ง์(RAG) ๊ฐ์โ์ ๋ชจ๋ํํด๋ ๋๋์ ๋๋ค. ํนํ โํ ๋ฒ ๋ง๋ ํ๋ฆ์ ์ฝ๋๋ก ์ฌ์ฌ์ฉโํ๊ธฐ๊ฐ ์ฌ์์.
์ธ์ ์ ์ฉํ ๊น?
- ์ฌ๋ด ๋ฌธ์ ๊ฒ์ ๊ธฐ๋ฐ Q&A(RAG) ํ๋กํ ํ์
- ๊ท์น์ด ์๋ ์์ฝ/๋ถ๋ฅ ํ์ดํ๋ผ์ธ
- ํจ์ ํธ์ถ(ํด ํธ์ถ)๊ณผ LLM ์๋ต์ ์ฎ๋ ์์
๋ฏธ๋ ์์: ๋ฌธ์ ๊ธฐ๋ฐ Q&A ๋ผ๋(๊ฐ๋ ์ฝ๋)
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
("system", "๋๋ ๊ฐ๋ฐ ๋ฌธ์ ๋์ฐ๋ฏธ์ผ. ๊ทผ๊ฑฐ๊ฐ ์์ผ๋ฉด ๋ชจ๋ฅธ๋ค๊ณ ๋งํด."),
("user", "์ง๋ฌธ: {q}\n\n์ฐธ๊ณ ๋ฌธ์:\n{context}")
])
chain = prompt | llm | StrOutputParser()
answer = chain.invoke({
"q": "๋ญ๊ทธ๋ํ๋ ์ ํ์ํด?",
"context": "- ๋ญ๊ทธ๋ํ๋ ์ํ/๋ถ๊ธฐ/๋ฃจํ๋ฅผ ๊ทธ๋ํ๋ก ํํ...\n- ๋ณต์กํ ์์ด์ ํธ ํ๋ฆ..."
})
print(answer)
ํต์ฌ์ ํ๋กฌํํธ โ ๋ชจ๋ธ โ ํ์ฑ์ด ํ์ดํ๋ก ์ด์ด์ง๊ณ , ๊ฐ ๋จ๊ณ๊ฐ ๊ต์ฒด ๊ฐ๋ฅํ๋ค๋ ์ ์ ๋๋ค.
๋ญ๊ทธ๋ํ: ์์ด์ ํธ๋ฅผ โ์ํ ๋จธ์ โ์ฒ๋ผ ๋ค๋ฃจ๊ธฐ
๋ญ์ฒด์ธ๋ง์ผ๋ก๋ ๋ง์ ๊ฑธ ๋ง๋ค ์ ์์ง๋ง, ์์ด์ ํธ๊ฐ ๋ณต์กํด์ง๋ฉด ์ด๋ฐ ์๊ตฌ๊ฐ ์๊น๋๋ค.
- ์ฌ์ฉ์์ ์๋๋ฅผ ๋ถ๋ฅํด์ ๋ถ๊ธฐํ๊ณ ์ถ๋ค
- ๋๊ตฌ ํธ์ถ์ด ์คํจํ๋ฉด ์ฌ์๋ํ๊ณ ์ถ๋ค
- ํน์ ์กฐ๊ฑด์ด๋ฉด ๋ฃจํ๋ฅผ ๋๋ฉฐ ์ถ๊ฐ ์ง๋ฌธ์ ํ๊ณ ์ถ๋ค
- ๋ํ ์ํ(๋ฉ๋ชจ๋ฆฌ/์ค๊ฐ ๊ฒฐ๊ณผ)๋ฅผ ๋ช ์์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ถ๋ค ์ด๋ ๋ญ๊ทธ๋ํ๋ ๋ํ ํ๋ฆ์ ๋ ธ๋(node)์ ์ฃ์ง(edge)๋ก ๊ตฌ์ฑํด ๊ทธ๋ํ ๊ธฐ๋ฐ ์คํ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. โ๊ทธ๋๊ทธ๋ ํ๋กฌํํธ๋ก ๋์งโ์ด ์๋๋ผ, ํ๋ฆ ์์ฒด๋ฅผ ์ค๊ณํ๋ ๋๋์ด ๊ฐํด์.
์์ ์๋๋ฆฌ์ค: ๊ฐ๋ฐ Q&A ์์ด์ ํธ
- ์ง๋ฌธ ๋ถ๋ฅ(์ผ๋ฐ/๋ฒ๊ทธ/์ํคํ ์ฒ)
- ๋ฒ๊ทธ๋ฉด: ์ฌํ ์ ๋ณด ์ง๋ฌธ โ ๋ก๊ทธ ์์ฝ โ ์์ธ ํ๋ณด ๋์ถ
- ์ํคํ ์ฒ๋ฉด: ์ ์ฝ์กฐ๊ฑด ์์ง โ ๋์ ๋น๊ต โ ๊ฒฐ๋ก ์ด๋ฐ ํ๋ฆ์ ๊ทธ๋ํ๋ก ๋ง๋ค๋ฉด, ์ด๋์ ์ด๋ค ์ํ๋ก ๋์ด๊ฐ๋์ง๊ฐ ๋ถ๋ช ํด์ง๊ณ ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๋๋ค.
๋ญ์ค๋ฏธ์ค: โ์ ์ด๋ฐ ๋ต์ด ๋์์ง?โ๋ฅผ ๋๊น์ง ์ถ์
LLM ์ฑ์ ์ด์ํ๋ค ๋ณด๋ฉด ๊ฐ์ฅ ํ๋ ๊ฒ ์ด๊ฑฐ์์.
- ๊ฐ์ ์ง๋ฌธ์ธ๋ฐ ๋ต์ด ๋งค๋ฒ ๋ฌ๋ผ์(๋น๊ฒฐ์ ์ฑ)
- ์ด๋ ๋จ๊ณ์์ ํ๋กฌํํธ/๋๊ตฌ ์ ๋ ฅ์ด ์๋ชป๋๋์ง ๊ฐ์ด ์์ด์
- ๊ฐ์ ํ๋๋ฐ ์ค์ ๋ก ๋์์ก๋์ง ๊ธฐ์ค์ด ์์ด์ ๋ญ์ค๋ฏธ์ค๋ ์คํ์ ํธ๋ ์ด์ฑ ํํ๋ก ๊ธฐ๋กํด, ๊ฐ ๋จ๊ณ ์ ๋ ฅ/์ถ๋ ฅ, ์ง์ฐ ์๊ฐ, ์คํจ ์ง์ ์ ํ์ธํ๋ ๋ฐ ๋์์ ์ค๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ผ์ด์ค๋ฅผ ๋ชจ์ ํ๊ท ํ ์คํธ์ฒ๋ผ ๋น๊ตํด๋ณผ ์๋ ์์ด์. ๊ฐ๋ฐ์ ์ ์ฅ์์๋ โ๊ฐโ์ด ์๋๋ผ ๊ธฐ๋ก ๊ธฐ๋ฐ์ผ๋ก ์์ ํ ์ ์๋ค๋ ๊ฒ ๊ฐ์ฅ ํฝ๋๋ค.
์ธ ๋๊ตฌ๋ฅผ ๊ฐ์ด ์ฐ๋ ์ถ์ฒ ํ๋ฆ
1) ๋ญ์ฒด์ธ์ผ๋ก ๋น ๋ฅด๊ฒ ๊ธฐ๋ฅ์ ๋ฌถ๋๋ค
- ํ๋กฌํํธ ํ ํ๋ฆฟ ์ ๋ฆฌ
- ๋๊ตฌ(๊ฒ์, DB, ์ฌ๋ด API) ์ฐ๊ฒฐ
- ์ถ๋ ฅ ํํ(JSON ๋ฑ) ๊ฐ์
2) ๋ญ๊ทธ๋ํ๋ก ์๋น์ค ๋ก์ง์ ๊ตฌ์กฐํํ๋ค
- ์๋ ๋ถ๊ธฐ, ์คํจ ์ฌ์๋, ์ฌ์ฉ์ ์ถ๊ฐ ์ง๋ฌธ ๊ฐ์ ํ๋ฆ์ ๊ทธ๋ํ๋ก ๊ณ ์
- ์ํ๋ฅผ ๋ช ์์ ์ผ๋ก ์ค๊ณ(์: user_intent, context_docs, final_answer)
3) ๋ญ์ค๋ฏธ์ค๋ก ํ์ง์ ๊พธ์คํ ๊ด๋ฆฌํ๋ค
- โ๋์ ๋ต๋ณโ ์ผ์ด์ค๋ฅผ ์ ์ฅํด ์ฌํ
- ๋ณ๊ฒฝ ์ /ํ ๊ฒฐ๊ณผ๋ฅผ ๋น๊ตํ๋ฉฐ ๊ฐ์
๊ฐ๋ฐ ๊ด์ ์ฒดํฌ๋ฆฌ์คํธ(์ค๋ฌด์ฉ)
- ์ถ๋ ฅ ๊ณ์ฝ: ์ต์ข ์๋ต์ JSON ์คํค๋ง๋ก ๊ณ ์ ํ ๊ฒ์ธ๊ฐ?
- ๋๊ตฌ ์คํจ ์ ๋ต: ํ์์์/์ฌ์๋/๋์ฒด ๊ฒฝ๋ก๊ฐ ์๋๊ฐ?
- ์ํ ์ค๊ณ: ์ด๋ค ๊ฐ์ ์ํ๋ก ๋จ๊ธฐ๊ณ , ์ธ์ ํ๊ธฐํ ๊ฒ์ธ๊ฐ?
- ํ๊ฐ ๊ธฐ์ค: โ์ข์ ๋ตโ์ ์กฐ๊ฑด์ ๋ฌธ์ฅ์ผ๋ก๋ผ๋ ์ ์ํ๋๊ฐ?
๋ง๋ฌด๋ฆฌ: โ์ ๋๋ตํ๋ ๋ชจ๋ธโ๋ณด๋ค โ๊ด๋ฆฌ๋๋ ์์คํ โ
๋ญ์ฒด์ธยท๋ญ๊ทธ๋ํยท๋ญ์ค๋ฏธ์ค๋ฅผ ํ ๋ฌธ์ฅ์ผ๋ก ์ ๋ฆฌํ๋ฉด ๋ง๋ค๊ณ (๋ญ์ฒด์ธ), ํ๋ฆ์ ์ธ์ฐ๊ณ (๋ญ๊ทธ๋ํ), ๊ฒ์ฆํ๊ณ ๊ณ ์น๋ค(๋ญ์ค๋ฏธ์ค)์ ๋๋ค. LLM ์ฑ์ ๋ฐ๋ชจ๋ ๋น ๋ฅด์ง๋ง, ์ ํ์ ๋ค๋ฆ ๋๋ค. ์ธ ๋๊ตฌ๋ฅผ ์ ์ ํ ์์ผ๋ฉด ์ฐ์ฐํ ์ ๋๋ ์ฑ๋ด์ด ์๋๋ผ ๊ฐ๋ฐ ๊ฐ๋ฅํ ์๋น์ค๋ก ํ ๋จ๊ณ ์ฌ๋ผ๊ฐ ์ ์์ด์.
โฌ๏ธ ์ด ๊ธ์ด ๋์์ด ๋์ จ๋ค๋ฉด, ์๋ ๊ด๊ณ ๋ฅผ ํ ๋ฒ๋ง ํด๋ฆญํด์ฃผ์ธ์! ์ ์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค ๐โโ๏ธ โฌ๏ธ