[๊ฐ์๋ ธํธ] RAG From Scratch : Query Routing & Structuring
์๋ณธ ๊ฒ์๊ธ: https://velog.io/@euisuk-chung/RAG-From-Scratch-10-11

- ํด๋น ๋ธ๋ก๊ทธ ํฌ์คํธ๋ RAG From Scratch : Coursework ๊ฐ์ ํํธ 10 - 11 ๋ด์ฉ์ ๋ค๋ฃจ๊ณ ์์ต๋๋ค.
| ๋น๋์ค | ์์ฝ | ๊ฐ์ ๋งํฌ | ์ฌ๋ผ์ด๋ |
|---|---|---|---|
| Part 10 (๋ผ์ฐํ ) | ์ฟผ๋ฆฌ๋ฅผ ๊ด๋ จ ๋ฐ์ดํฐ ์์ค๋ก ์ ๋ํ๊ธฐ ์ํ ๋ ผ๋ฆฌ์ ๋ฐ ์๋ฏธ์ ์ฟผ๋ฆฌ ๋ผ์ฐํ ์ ๋ค๋ฃน๋๋ค. | ๐ ๊ฐ์ | ๐ ์ฌ๋ผ์ด๋ |
| Part 11 (์ฟผ๋ฆฌ ๊ตฌ์กฐํ) | ์์ฐ์ด ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ๋ก ๋ณํํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ ํจ์จํํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃน๋๋ค. | ๐ ๊ฐ์ | ๐ ์ฐธ๊ณ ์๋ฃ |
Part 10 (๋ผ์ฐํ )

-
์ ๊ทธ๋ฆผ์ ๋จ๊ณ์ ๋ฐ๋ผ ๊ฐ ๊ณผ์ ์ ์ญํ ๊ณผ ๊ฐ๋ ์ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ๊ฒ ์ต๋๋ค:
- Question (์ง๋ฌธ) : ์ฌ์ฉ์๊ฐ ์์คํ ์ ์ ๋ ฅํ๋ ์์ฐ์ด ํํ์ ์ง๋ฌธ์ ๋๋ค. ์ด๋ ์ ์ฒด ํ๋ก์ธ์ค์ ์์์ ์ด ๋ฉ๋๋ค.
- Query Translation (์ฟผ๋ฆฌ ๋ฒ์ญ) : ์ฌ์ฉ์์ ์์ฐ์ด ์ง๋ฌธ์ ์์คํ ์ด ์ดํดํ ์ ์๋ ํ์์ผ๋ก ๋ณํํ๋ ๊ณผ์ ์ ๋๋ค. ์ด๋ ์์ฐ์ด ์ฒ๋ฆฌ ๊ธฐ์ ์ ํ์ฉํ์ฌ ์ํ๋ฉ๋๋ค.
- Routing (๋ผ์ฐํ , ์ด๋ฒ ์ฑํฐ๐) : ๋ณํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ ์ ํ ์ฒ๋ฆฌ ๊ฒฝ๋ก๋ ๋ฐ์ดํฐ ์์ค๋ก ์๋ดํ๋ ๊ณผ์ ์ ๋๋ค. ์ง๋ฌธ์ ํน์ฑ์ ๋ฐ๋ผ ์ต์ ์ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํฉ๋๋ค.
- Query Construction (์ฟผ๋ฆฌ ๊ตฌ์ฑ) : ๋ผ์ฐํ ๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๊ฒ์ ์์ง์์ ์ฌ์ฉํ ์ ์๋ ํํ์ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- Indexing (์ธ๋ฑ์ฑ) : ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฌธ์ ์ปฌ๋ ์ ์์ ํจ์จ์ ์ธ ๊ฒ์์ ์ํด ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ๊ณ ์กฐ์งํํ๋ ๊ณผ์ ์ ๋๋ค. ์ด๋ ์ฃผ๋ก ์์คํ ๊ตฌ์ถ ๋จ๊ณ์์ ์ํ๋ฉ๋๋ค.
- Retrieval (๊ฒ์) : ๊ตฌ์ฑ๋ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ธ๋ฑ์ฑ๋ ๋ฐ์ดํฐ์์ ๊ด๋ จ ์ ๋ณด๋ฅผ ์ถ์ถํ๋ ๊ณผ์ ์ ๋๋ค. ์ด ๋จ๊ณ์์ ์ง๋ฌธ๊ณผ ๊ฐ์ฅ ๊ด๋ จ์ฑ ๋์ ์ ๋ณด๋ฅผ ์ฐพ์๋ ๋๋ค.
- Generation (์์ฑ) : ๊ฒ์๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ ์์ฑํ๋ ๊ณผ์ ์ ๋๋ค. ์ด ๋จ๊ณ์์๋ ์ฃผ๋ก ์์ฐ์ด ์์ฑ ๊ธฐ์ ์ด ์ฌ์ฉ๋ฉ๋๋ค.
- Answer (๋ต๋ณ) : ์ต์ข ์ ์ผ๋ก ์์ฑ๋ ๋ต๋ณ์ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์๋ ์ง๋ฌธ์ ๋ํ ์๋ต์ผ๋ก, ์์ฐ์ด ํํ๋ก ํํ๋ฉ๋๋ค.
- ์ด ๊ณผ์ ์ ์ง๋ฌธ ์๋ต ์์คํ ์ ์ ํ์ ์ธ ํ์ดํ๋ผ์ธ์ ๋ํ๋ด๋ฉฐ, ๊ฐ ๋จ๊ณ๋ ์ฌ์ฉ์์ ์ง๋ฌธ์ ๋ํด ์ ํํ๊ณ ๊ด๋ จ์ฑ ๋์ ๋ต๋ณ์ ์ ๊ณตํ๊ธฐ ์ํด ์ ๊ธฐ์ ์ผ๋ก ์๋ํฉ๋๋ค.
- ์ด๋ฒ ๊ฐ์๋ 3. Routing(๋ผ์ฐํ )์ด๋ผ๋ ๊ฐ๋ ์ ์ค๋ช ํ๊ณ , ๋ ๊ฐ์ง ์ฃผ์ ๋ผ์ฐํ ๋ฐฉ๋ฒ์ธ โ ๋ ผ๋ฆฌ์ ๋ผ์ฐํ (Logical Routing)๊ณผ โก ์๋ฏธ์ ๋ผ์ฐํ (Semantic Routing)์ ๋ค๋ฃน๋๋ค.
1. ๋ผ์ฐํ ๊ฐ๋
-
๋ผ์ฐํ (Routing)์ ์ง๋ฌธ์ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ก ์ ๋ฌํ๋ ํ๋ก์ธ์ค๋ฅผ ์๋ฏธํฉ๋๋ค.
- RAG(์ง๋ฌธ-๋ต๋ณ ์์ฑ ๋ชจ๋ธ)์์ ๋ผ์ฐํ ์ ํน์ ์ง๋ฌธ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ ์ ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ํ๋กฌํํธ์ ์ฐ๊ฒฐํ๋ ์ญํ ์ ํฉ๋๋ค.
-
๋ค๋ฅด๊ฒ ์ ์ํด๋ณธ๋ค๋ฉด, ๋ผ์ฐํ ์ ์๋์ ๊ฐ์ด ์ ์ํด๋ณผ ์ ์์ต๋๋ค:
์ ์: ์ ๋ ฅ๋ ์ฟผ๋ฆฌ๋ ์์ ์ ์ ์ ํ ๋ชจ๋ธ์ด๋ ์ฒ๋ฆฌ ๊ฒฝ๋ก๋ก ์๋ดํ๋ ๊ณผ์ ์ ๋๋ค.๋ชฉ์ : ์ฃผ์ด์ง ์ ๋ ฅ์ ๊ฐ์ฅ ์ ํฉํ LLM์ด๋ ์ฒ๋ฆฌ ๋ชจ๋์ ์ ํํฉ๋๋ค.์๋ ๋ฐฉ์: ์ ๋ ฅ์ ํน์ฑ์ ๋ถ์ํ์ฌ ๋ฏธ๋ฆฌ ์ ์๋ ๊ท์น์ด๋ ํ์ต๋ ์๊ณ ๋ฆฌ์ฆ์ ํตํด ์ต์ ์ ์ฒ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.์ ์ฉ: ๋ค์ํ LLM์ ํจ์จ์ ์ผ๋ก ํ์ฉํ๊ฑฐ๋, ํน์ ๋๋ฉ์ธ์ ํนํ๋ ๋ชจ๋ธ๋ก ์ฟผ๋ฆฌ๋ฅผ ์ ๋ฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์์ ์๋๋ฆฌ์ค: ์ฌ์ฉ์๊ฐ ์ฝ๋ฉ ๊ด๋ จ ์ง๋ฌธ์ ํ ๋, ์์คํ ์ ๊ทธ ์ง๋ฌธ์ ์ ์ ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ๋ฌธ์(์: Python, JS, Golang)๋ก ๋ผ์ฐํ ํ๋ ๊ฒ์ ๋๋ค.
- ๋ผ์ฐํ
๋ฐฉ๋ฒ์ ํฌ๊ฒ
๋ ผ๋ฆฌ์ ๋ผ์ฐํ (Logical Routing)๊ณผ์๋ฏธ์ ๋ผ์ฐํ (Semantic Routing)์ผ๋ก ๋๋ ์ ์์ต๋๋ค. ์ด ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋๊ณ ๊ตฌ๋ถ๋ฉ๋๋ค:
2.1. ๋ ผ๋ฆฌ์ ๋ผ์ฐํ (Logical Routing) ์ค๋ช

๋ ผ๋ฆฌ์ ๋ผ์ฐํ ๊ฐ๋
- ๋ ผ๋ฆฌ์ ๋ผ์ฐํ ์ ์์คํ ์ด ๋ค์ํ ๋ฐ์ดํฐ ์์ค ์ค ์ด๋ค ์์ค๋ฅผ ์ฌ์ฉํ ์ง ๋ฏธ๋ฆฌ ์ค์ ๋ ๊ท์น์ ๋ฐ๋ผ ๊ฒฐ์ ํ๋ ๋ฐฉ์์ ๋๋ค.
- ์ฌ์ฉ์๊ฐ ์ง๋ฌธ์ ์ ๋ ฅํ๋ฉด LLM(Large Language Model)์ ๊ทธ ์ง๋ฌธ์ด ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฌธ์ ์์ค์ ๊ฐ์ฅ ๊ด๋ จ์ด ์๋์ง ๊ฒฐ์ ํ๊ณ , ํด๋น ์์ค๋ก ๋ผ์ฐํ ํ์ฌ ๋ต๋ณ์ ์์ฑํฉ๋๋ค.
ํน์ง
- ์ฃผ๋ก โ๊ตฌ์กฐํ๋ ์ถ๋ ฅโ์ ์ฌ์ฉํ์ฌ ๋ผ์ฐํ ์ ์ํํฉ๋๋ค. ์ฆ, ์์คํ ์ ์ง๋ฌธ์ ๋ฏธ๋ฆฌ ์ ์๋ ๊ท์น์ ๋ฐ๋ผ ๋ถ๋ฅํ๊ณ ๊ทธ์ ๋ง๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ ํํฉ๋๋ค.
- ์ง๋ฌธ์ด ๋ช ํํ ๊ตฌ๋ถ ๊ฐ๋ฅํ ์ฃผ์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ด๋ จ์ด ์์ ๋ ๋งค์ฐ ์ ํฉํ ๋ฐฉ๋ฒ์ ๋๋ค.
๊ณผ์
-
์ฌ์ฉ์๊ฐ ์ง๋ฌธ์ ์ ๋ ฅํฉ๋๋ค.
-
LLM์ด ๊ทธ ์ง๋ฌธ์ ๋ถ์ํ์ฌ ๋ฏธ๋ฆฌ ์ค์ ๋ ๋ฐ์ดํฐ ์์ค ๋ชฉ๋ก(์: Python ๋ฌธ์, JS ๋ฌธ์ ๋ฑ) ์ค์์ ๊ฐ์ฅ ์ ํฉํ ์์ค๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
-
์ ํ๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ฐํ์ผ๋ก ๋ต๋ณ์ ์์ฑํฉ๋๋ค.
์ฝ๋ ์ค๋ช
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
28
from typing import Literal
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
# Data model
class RouteQuery(BaseModel):
"""Route a user query to the most relevant datasource."""
datasource: Literal["python_docs", "js_docs", "golang_docs"] = Field(
..., description="Given a user question choose which datasource would be most relevant for answering their question",
)
# LLM with function call
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(RouteQuery)
# Prompt ์ ์
system = """
You are an expert at routing a user question to the appropriate data source.
Based on the programming language the question is referring to, route it to the relevant data source.
"""
prompt = ChatPromptTemplate.from_messages(
[("system", system), ("human", "{question}")])
# Define router
router = prompt | structured_llm
RouteQuery๋ ์ฌ์ฉ์ ์ง๋ฌธ์ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ก ๋ผ์ฐํ ํ๊ธฐ ์ํด ๋ฏธ๋ฆฌ ์ ์๋datasource์ต์ ์ ํฌํจํ๋ ํด๋์ค์ ๋๋ค.Field(...)์์ โฆ์ Python์ pydantic ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ฌ์ฉ๋๋ ํน๋ณํ ํํ์ผ๋ก, ํ๋๋ฅผ ํ์ ํ๋๋ก ์ง์ ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.- ์ ์ฝ๋์์ datasource ํ๋๋ ํ์๋ก ์ ๊ณต๋์ด์ผ ํ๋ฉฐ, ๊ฐ์ด ์๋ค๋ฉด ๋ชจ๋ธ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
structured_llm์ LLM์ด ๊ตฌ์กฐํ๋ ์ถ๋ ฅ ํ์์ ์ฌ์ฉํ๋๋ก ์ค์ ๋ LLM์ ๋๋ค.prompt๋ ์์คํ ์ด ์ง๋ฌธ์ ์ฒ๋ฆฌํ๊ณ ๋ฐ์ดํฐ ์์ค๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ๋ฒ์ ์ ์ํ๋ ํ ํ๋ฆฟ์ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
# ์ง๋ฌธ ์์
question = """
Why doesn't the following code work:
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages(["human", "speak in {language}"])
prompt.invoke("french")
"""
# LLM์ด ์ง๋ฌธ์ ๋ถ์ํ์ฌ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ฐํ
result = router.invoke({"question": question})
result์๋ RouteQuery(datasource=โpython_docsโ)๊ฐ์ด ๋ค์ด๊ฐ ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.- ์ฌ์ฉ์๋ Python ์ฝ๋์ ๊ด๋ จ๋ ์ง๋ฌธ์ ์ ๋ ฅํ์ต๋๋ค. (question)
- LLM์ ๋ฏธ๋ฆฌ ์ค์ ๋ ์ง์นจ์ ๋ฐ๋ผ ์ง๋ฌธ์ ๋ถ์ํฉ๋๋ค. (router.invoke({โquestionโ: question}))
-
LLM์ ์ง๋ฌธ์ ๋งฅ๋ฝ์ด Python๊ณผ ๊ด๋ จ๋์ด ์์์ ๊ฐ์งํ๊ณ , (router = prompt structured_llm) - RouteQuery(datasource=โpython_docsโ)๋ผ๋ ๊ตฌ์กฐํ๋ ์ถ๋ ฅ์ ์์ฑํ์ฌ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ฐํํฉ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
# ์ ํ๋ ๋ฐ์ดํฐ ์์ค์ ๋ฐ๋ผ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ ์ํ
def choose_route(result):
if "python_docs" in result.datasource.lower():
return "chain for python_docs"
elif "js_docs" in result.datasource.lower():
return "chain for js_docs"
else:
return "chain for golang_docs"
# ์ต์ข
์ ์ผ๋ก ์ ํ๋ ๊ฒฝ๋ก์ ๋ฐ๋ผ ๋ผ์ฐํ
full_chain = router | RunnableLambda(choose_route)
full_chain.invoke({"question": question}) # 'chain for python_docs'
choose_route()ํจ์๋ ๋ฐํ๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ ๋จ๊ณ์์ ์ด๋ค ์ฒ๋ฆฌ๋ฅผ ํ ์ง ๊ฒฐ์ ํฉ๋๋ค.- ์ด ์์์์ ์ฌ์ฉ์๋ ์ง๋ฌธ์ ์
๋ ฅํ๊ณ , ์์คํ
์ ์ด๋ฅผ ๋ถ์ํ์ฌ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ ํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, Python๊ณผ ๊ด๋ จ๋ ์ง๋ฌธ์ด๋ผ๋ฉด
python_docs๋ก ๋ผ์ฐํ ๋ฉ๋๋ค.
- ์ด ์์์์ ์ฌ์ฉ์๋ ์ง๋ฌธ์ ์
๋ ฅํ๊ณ , ์์คํ
์ ์ด๋ฅผ ๋ถ์ํ์ฌ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ ํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, Python๊ณผ ๊ด๋ จ๋ ์ง๋ฌธ์ด๋ผ๋ฉด
2.2. ์๋ฏธ์ ๋ผ์ฐํ (Semantic Routing) ์ค๋ช

์๋ฏธ์ ๋ผ์ฐํ ๊ฐ๋
- ์๋ฏธ์ ๋ผ์ฐํ ์ ์ง๋ฌธ๊ณผ ์ฌ๋ฌ ํ๋กฌํํธ ๊ฐ์ ์๋ฏธ์ ์ ์ฌ์ฑ์ ๊ธฐ๋ฐ์ผ๋ก ์ ํฉํ ํ๋กฌํํธ๋ฅผ ์ ํํ๋ ๋ฐฉ์์ ๋๋ค.
- ์ฌ๊ธฐ์ ์ง๋ฌธ๊ณผ ํ๋กฌํํธ๋ ์๋ฒ ๋ฉ(๋ฒกํฐํ)๋ ํ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํ์ฌ, ๊ฐ์ฅ ์ ์ฌํ ํ๋กฌํํธ๋ฅผ ์ ํํฉ๋๋ค.
ํน์ง
- ์ง๋ฌธ๊ณผ ํ๋กฌํํธ ๊ฐ์ ์๋ฏธ์ ์ ์ฌ์ฑ์ ๋ฐํ์ผ๋ก ๋ผ์ฐํ ์ ์ํํฉ๋๋ค.
- ๋ฏธ๋ฆฌ ์ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์๋๋ผ, ์ง๋ฌธ์ ์๋ฏธ๋ฅผ ํ์ ํด ๊ฐ์ฅ ์ ํฉํ ํ๋กฌํํธ๋ฅผ ์ ํํ๋ ๋ฐฉ์์ ๋๋ค.
- ์ง๋ฌธ์ด ๋จ์ํ ์ ๋ณด ์กฐํ๊ฐ ์๋๋ผ, ์๋ฏธ์ ์ผ๋ก ์ ์ฌํ ์ฌ๋ฌ ๊ฐ๋ฅ์ฑ์ ๊ณ ๋ คํด์ผ ํ ๋ ์ ํฉํฉ๋๋ค.
๊ณผ์
-
์ฌ์ฉ์๊ฐ ์ง๋ฌธ์ ์ ๋ ฅํ๋ฉด ์์คํ ์ด ๊ทธ ์ง๋ฌธ์ ์๋ฒ ๋ฉ(๋ฒกํฐํ)ํฉ๋๋ค.
-
์์คํ ์ ์ฌ๋ฌ ํ๋กฌํํธ ์ค์์ ์ง๋ฌธ๊ณผ ๊ฐ์ฅ ์ ์ฌํ ํ๋กฌํํธ๋ฅผ ์ ํํฉ๋๋ค.
-
์ ํ๋ ํ๋กฌํํธ์ ๋ฐ๋ผ ๋ต๋ณ์ ์ ๊ณตํฉ๋๋ค.
์ฝ๋ ์ค๋ช
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from langchain.utils.math import cosine_similarity
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
# ๋ ๊ฐ์ง ํ๋กฌํํธ ์ ์
physics_template = """You are a very smart physics professor. \
You are great at answering questions about physics in a concise and easy to understand manner. \
When you don't know the answer to a question you admit that you don't know.
Here is a question:
{query}"""
math_template = """You are a very good mathematician. You are great at answering math questions. \
You are so good because you are able to break down hard problems into their component parts, \
answer the component parts, and then put them together to answer the broader question.
- ๋ฌผ๋ฆฌํ ํ๋กฌํํธ์ ์ํ ํ๋กฌํํธ ๋ ๊ฐ์ง๊ฐ ์ฃผ์ด์ง๋ฉฐ, ์์คํ ์ด ์ง๋ฌธ์ ๋ถ์ํ ํ ์ ํฉํ ํ๋กฌํํธ๋ฅผ ์ ํํฉ๋๋ค.
1
2
3
4
5
6
7
Here is a question:
{query}"""
# ํ๋กฌํํธ ์๋ฒ ๋ฉ
embeddings = OpenAIEmbeddings()
prompt_templates = [physics_template, math_template]
prompt_embeddings = embeddings.embed_documents(prompt_templates)
OpenAIEmbeddings()๋ฅผ ์ฌ์ฉํ์ฌ ์ง๋ฌธ๊ณผ ํ๋กฌํํธ๋ฅผ ์๋ฒ ๋ฉํฉ๋๋ค.cosine_similarity()ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ง๋ฌธ๊ณผ ํ๋กฌํํธ ๊ฐ์ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํ๊ณ , ๊ฐ์ฅ ์ ์ฌํ ํ๋กฌํํธ๋ฅผ ์ ํํฉ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ์ง๋ฌธ์ ์ ํฉํ ํ๋กฌํํธ๋ก ๋ผ์ฐํ
def prompt_router(input):
query_embedding = embeddings.embed_query(input["query"])
similarity = cosine_similarity([query_embedding], prompt_embeddings)[0]
most_similar = prompt_templates[similarity.argmax()]
print("Using MATH" if most_similar == math_template else "Using PHYSICS")
return PromptTemplate.from_template(most_similar)
chain = (
{"query": RunnablePassthrough()}
| RunnableLambda(prompt_router)
| ChatOpenAI()
| StrOutputParser()
)
print(chain.invoke("What's a black hole"))
- ์์คํ
์ ์ ํ๋ ํ๋กฌํํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ต๋ณ์ ์ ๊ณตํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ์ง๋ฌธ์ด โ๋ธ๋ํ์ ๋ฌด์์ธ๊ฐ?โ๋ผ๋ฉด ์๋์ ๊ฐ์ด ๋ฌผ๋ฆฌํ ๊ด๋ จ ํ๋กฌํํธ๊ฐ ์ ํ๋๊ณ ๋ต๋ณ์ ์ ๊ณตํ๊ฒ ๋ฉ๋๋ค.
1
2
3
4
5
6
7
Using PHYSICS
A black hole is a region in space where the gravitational pull is so strong that nothing, not even light, can escape from it. This occurs because a significant amount of mass has been compressed into a very small area.
The boundary around a black hole is called the event horizon, and once something crosses this boundary, it cannot escape. Black holes can be formed from the remnants of massive stars that have ended their life cycles in a supernova explosion and collapsed under their own gravity.
They are fascinating objects that challenge our understanding of physics, particularly in the realms of general relativity and quantum mechanics.
(์ ๋ฆฌ) ๋ ผ๋ฆฌ์ ๋ผ์ฐํ vs ์๋ฏธ์ ๋ผ์ฐํ ๋น๊ต
| ๊ตฌ๋ถ | ๋ ผ๋ฆฌ์ ๋ผ์ฐํ (Logical Routing) | ์๋ฏธ์ ๋ผ์ฐํ (Semantic Routing) |
|---|---|---|
| ๋ผ์ฐํ ๊ธฐ์ค | ๋ฏธ๋ฆฌ ์ ์๋ ๋ฐ์ดํฐ ์์ค ๋ชฉ๋ก์ ๊ธฐ๋ฐ | ์ง๋ฌธ๊ณผ ํ๋กฌํํธ ๊ฐ์ ์๋ฏธ์ ์ ์ฌ์ฑ์ ๊ธฐ๋ฐ |
| ๋ฐ์ดํฐ ์์ค ์ ํ | LLM์ด ๋ฐ์ดํฐ ์์ค ๋ชฉ๋ก์์ ์ ํฉํ ์์ค๋ฅผ ์ ํ | ์ง๋ฌธ์ ์๋ฏธ๋ฅผ ๋ถ์ํด ๊ฐ์ฅ ์ ์ฌํ ํ๋กฌํํธ๋ ๋ฐ์ดํฐ๋ฅผ ์ ํ |
| ์ฃผ์ ํ์ฉ | ๋ฐ์ดํฐ ์์ค๋ ์๋ฃ๊ฐ ๋ช ํํ ๊ตฌ๋ถ๋์ด ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ | ๋ค์ํ ์๋ฏธ๋ฅผ ํฌํจํ๋ ์ง๋ฌธ์ ๋ํด ์ ์ฐํ ๋ต๋ณ ์ ๊ณต |
| ์ค์ ์์ | ํ๋ก๊ทธ๋๋ฐ ๋ฌธ์, ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฌธ์ ๋ฑ ํน์ ์ฃผ์ ์ DB | ํน์ ๋๋ฉ์ธ์ ๊ด๋ จ๋ ์ฌ๋ฌ ์๋ฏธ๊ฐ ํผ์ฌ๋ ์ง๋ฌธ์ ๋ํ ๋ต๋ณ ์ ํ |
| ์ ํฉํ ์ํฉ | ์ง๋ฌธ์ด ์ด๋ DB์์ ์ฒ๋ฆฌ๋ ์ง ๋ฏธ๋ฆฌ ๋ช ํํ ๊ฒฝ์ฐ | ์ง๋ฌธ์ด ๋ค์ํ ์๋ฏธ๋ก ํด์๋ ์ ์์ ๋ ์ ํฉ |
- ์ ํ
์ด๋ธ ๋น๊ต๋ฅผ ํตํด,
- ๋ ผ๋ฆฌ์ ๋ผ์ฐํ ์ ๋ฏธ๋ฆฌ ์ค์ ๋ ๊ท์น์ ๋ฐ๋ผ ์ ์ ํ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ ํํ๋ ๋ฐ๋ฉด,
- ์๋ฏธ์ ๋ผ์ฐํ ์ ์ง๋ฌธ์ ์๋ฏธ์ ์ ์ฌ์ฑ์ ๊ธฐ๋ฐ์ผ๋ก ๋ผ์ฐํ ์ด ์ด๋ฃจ์ด์ง๋ค๋ ์ฐจ์ด์ ์ ์ดํดํ ์ ์์ต๋๋ค.
Part 11 (์ฟผ๋ฆฌ ๊ตฌ์กฐํ)

-
์ ๊ทธ๋ฆผ์ ๋จ๊ณ์ ๋ฐ๋ผ ๊ฐ ๊ณผ์ ์ ์ญํ ๊ณผ ๊ฐ๋ ์ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ๊ฒ ์ต๋๋ค:
- Question (์ง๋ฌธ) : ์ฌ์ฉ์๊ฐ ์์คํ ์ ์ ๋ ฅํ๋ ์์ฐ์ด ํํ์ ์ง๋ฌธ์ ๋๋ค. ์ด๋ ์ ์ฒด ํ๋ก์ธ์ค์ ์์์ ์ด ๋ฉ๋๋ค.
- Query Translation (์ฟผ๋ฆฌ ๋ฒ์ญ) : ์ฌ์ฉ์์ ์์ฐ์ด ์ง๋ฌธ์ ์์คํ ์ด ์ดํดํ ์ ์๋ ํ์์ผ๋ก ๋ณํํ๋ ๊ณผ์ ์ ๋๋ค. ์ด๋ ์์ฐ์ด ์ฒ๋ฆฌ ๊ธฐ์ ์ ํ์ฉํ์ฌ ์ํ๋ฉ๋๋ค.
- Routing (๋ผ์ฐํ ) : ๋ณํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ ์ ํ ์ฒ๋ฆฌ ๊ฒฝ๋ก๋ ๋ฐ์ดํฐ ์์ค๋ก ์๋ดํ๋ ๊ณผ์ ์ ๋๋ค. ์ง๋ฌธ์ ํน์ฑ์ ๋ฐ๋ผ ์ต์ ์ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํฉ๋๋ค.
- Query Construction (์ฟผ๋ฆฌ ๊ตฌ์ฑ, ์ด๋ฒ ์ฑํฐ๐) : ๋ผ์ฐํ ๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๊ฒ์ ์์ง์์ ์ฌ์ฉํ ์ ์๋ ํํ์ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- Indexing (์ธ๋ฑ์ฑ) : ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฌธ์ ์ปฌ๋ ์ ์์ ํจ์จ์ ์ธ ๊ฒ์์ ์ํด ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ๊ณ ์กฐ์งํํ๋ ๊ณผ์ ์ ๋๋ค. ์ด๋ ์ฃผ๋ก ์์คํ ๊ตฌ์ถ ๋จ๊ณ์์ ์ํ๋ฉ๋๋ค.
- Retrieval (๊ฒ์) : ๊ตฌ์ฑ๋ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ธ๋ฑ์ฑ๋ ๋ฐ์ดํฐ์์ ๊ด๋ จ ์ ๋ณด๋ฅผ ์ถ์ถํ๋ ๊ณผ์ ์ ๋๋ค. ์ด ๋จ๊ณ์์ ์ง๋ฌธ๊ณผ ๊ฐ์ฅ ๊ด๋ จ์ฑ ๋์ ์ ๋ณด๋ฅผ ์ฐพ์๋ ๋๋ค.
- Generation (์์ฑ) : ๊ฒ์๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ ์์ฑํ๋ ๊ณผ์ ์ ๋๋ค. ์ด ๋จ๊ณ์์๋ ์ฃผ๋ก ์์ฐ์ด ์์ฑ ๊ธฐ์ ์ด ์ฌ์ฉ๋ฉ๋๋ค.
- Answer (๋ต๋ณ) : ์ต์ข ์ ์ผ๋ก ์์ฑ๋ ๋ต๋ณ์ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์๋ ์ง๋ฌธ์ ๋ํ ์๋ต์ผ๋ก, ์์ฐ์ด ํํ๋ก ํํ๋ฉ๋๋ค.
-
์ด๋ฒ ๊ฐ์์์๋ Query Construction (or Structuring)(์ฟผ๋ฆฌ ๊ตฌ์กฐํ)์ ๋ํด ๋ค๋ฃน๋๋ค. ์ฟผ๋ฆฌ ๊ตฌ์กฐํ๋ ์์ฐ์ด๋ก ๋ ์ง๋ฌธ์ ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋๋ฉ์ธ์ ๋ง๋ ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ๋ก ๋ณํํ๋ ๊ณผ์ ์ ์ค๋ช ํฉ๋๋ค. ํนํ ๋ฒกํฐ ์คํ ์ด์์ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ง์๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ค์ ์ ๋ก๋๋ค.
1. ์ฟผ๋ฆฌ ๊ตฌ์กฐํ ๊ฐ๋
- ์ฟผ๋ฆฌ ๊ตฌ์กฐํ๋ ์ฌ์ฉ์๊ฐ ์์ฐ์ด๋ก ๋ฌป๋ ์ง๋ฌธ์ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ณด๋ค ๊ตฌ์ฒด์ ์ผ๋ก ๋ณํํ๋ ๊ณผ์ ์ ๋๋ค.
- ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ โ2024๋ ์ดํ์ ๊ฒ์๋ Lang Chain ๊ด๋ จ ๋น๋์ค๋ฅผ ์ฐพ์์ฃผ์ธ์โ๋ผ๊ณ ์ง๋ฌธํ ๊ฒฝ์ฐ, ์ด ์ง๋ฌธ์ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ก ๋ณํ๋์ด ๋ฒกํฐ ์คํ ์ด์ ์ ํฉํ ์ฟผ๋ฆฌ๋ก ๋ง๋ค์ด์ง๋๋ค.
2. ์ฟผ๋ฆฌ ๊ตฌ์กฐํ์ ์ฃผ์ ํ๋ฆ
2.1. ์์ฐ์ด ์ง๋ฌธ โ ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ:
-
์ฌ์ฉ์๊ฐ ์์ฐ์ด๋ก ์ง๋ฌธ์ ์ ๋ ฅํ๋ฉด, LLM์ด ํด๋น ์ง๋ฌธ์ ๋ถ์ํ์ฌ ๋ฉํ๋ฐ์ดํฐ ํํฐ(์: ๋ ์ง, ์กฐํ์, ๋น๋์ค ๊ธธ์ด)๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฒ์์ ์ ํฉํ ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ๋ก ๋ณํํฉ๋๋ค.
- ์์: ์ ํ๋ธ ๋น๋์ค ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๊ณ ๋ฉํ๋ฐ์ดํฐ ํํฐ ์ ์ฉ
- ๋งํฌ : Self-reflective RAG with LangGraph: Self-RAG and CRAG

1 2 3 4 5 6 7 8 9
from langchain_community.document_loaders import YoutubeLoader # https://youtu.be/pbAd8O1Lvm4 docs = YoutubeLoader.from_youtube_url( "https://www.youtube.com/watch?v=pbAd8O1Lvm4", add_video_info=True ).load() docs[0].metadata- ์ ์ฝ๋๋ YouTube์์ ๋น๋์ค๋ฅผ ๋ก๋ํ๊ณ ํด๋น ๋น๋์ค์ ๋ฉํ๋ฐ์ดํฐ(์: ์ ๋ชฉ, ์กฐํ์, ๊ฒ์์ผ)๋ฅผ ๊ฐ์ ธ์ค๋ ์์์ ๋๋ค.
2.2. ๋ฉํ๋ฐ์ดํฐ ํํฐ ์ฌ์ฉ:
- ๋ฒกํฐ ์คํ ์ด์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฐ์ด ์ง๋ฌธ์ ์ฒ๋ฆฌํฉ๋๋ค.
-
ํํฐ๋ก๋ ์กฐํ์, ๊ฒ์์ผ, ๋น๋์ค ๊ธธ์ด ๋ฑ์ด ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ๋ณด๋ค ์ธ๋ฐํ ๊ฒ์์ ํ ์ ์์ต๋๋ค. (
view_count,publish_date,length๋ฑ์ ํํฐ๋ก ์ฌ์ฉํ์ฌ ๊ฒ์ํ ์ ์์ต๋๋ค.)-
์๋๋ ์์์ ํธ์ถํ ์์์ ์ ๋ณด์ ๋๋ค.
1 2 3 4 5 6 7 8
{'source': 'pbAd8O1Lvm4', 'title': 'Self-reflective RAG with LangGraph: Self-RAG and CRAG', 'description': 'Unknown', 'view_count': 23406, 'thumbnail_url': 'https://i.ytimg.com/vi/pbAd8O1Lvm4/hq720.jpg', 'publish_date': '2024-02-07 00:00:00', 'length': 1058, 'author': 'LangChain'}
-
2.3. 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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
import datetime from typing import Literal, Optional, Tuple from langchain_core.pydantic_v1 import BaseModel, Field class TutorialSearch(BaseModel): """Search over a database of tutorial videos about a software library.""" content_search: str = Field( ..., description="Similarity search query applied to video transcripts.", ) title_search: str = Field( ..., description=( "Alternate version of the content search query to apply to video titles. " "Should be succinct and only include key words that could be in a video " "title." ), ) min_view_count: Optional[int] = Field( None, description="Minimum view count filter, inclusive. Only use if explicitly specified.", ) max_view_count: Optional[int] = Field( None, description="Maximum view count filter, exclusive. Only use if explicitly specified.", ) earliest_publish_date: Optional[datetime.date] = Field( None, description="Earliest publish date filter, inclusive. Only use if explicitly specified.", ) latest_publish_date: Optional[datetime.date] = Field( None, description="Latest publish date filter, exclusive. Only use if explicitly specified.", ) min_length_sec: Optional[int] = Field( None, description="Minimum video length in seconds, inclusive. Only use if explicitly specified.", ) max_length_sec: Optional[int] = Field( None, description="Maximum video length in seconds, exclusive. Only use if explicitly specified.", ) def pretty_print(self) -> None: for field in self.__fields__: if getattr(self, field) is not None and getattr(self, field) != getattr( self.__fields__[field], "default", None ): print(f"{field}: {getattr(self, field)}")-
LLM์ ํจ์ ํธ์ถ์ ์ฌ์ฉํ์ฌ ์์ฐ์ด ์ง๋ฌธ์ ์ฒ๋ฆฌํ๊ณ , ์ด๋ฅผ JSON ํ์์ ๊ตฌ์กฐํ๋ ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ๋ฐํํฉ๋๋ค. ์ด ๊ฐ์ฒด๋ ๊ฒ์ ์ฟผ๋ฆฌ๋ก ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
structured_llm = llm.with_structured_output(TutorialSearch)์ ์์ ์ค์ ํด๋ TutorialSearch์ผ๋ก ์ถ๋ ฅํ๋๋ก ์ ์ํด๋ก๋๋ค. ``` from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI
Create the Prompt Template:
system = โ"โYou are an expert at converting user questions into database queries. You have access to a database of tutorial videos about a software library for building LLM-powered applications. Given a question, return a database query optimized to retrieve the most relevant results.โโโ
prompt = ChatPromptTemplate.from_messages([(โsystemโ, system), (โhumanโ, โ{question}โ)])
Initialize the Language Model (LLM)
llm = ChatOpenAI(model=โgpt-3.5-turbo-0125โ, temperature=0) structured_llm = llm.with_structured_output(TutorialSearch)
Prompt and LLM into a Query Analyzer
query_analyzer = prompt | structured_llm
```
-
2.4. User Question ์ฒ๋ฆฌ:
-
์์์ ์ ์ํ
prompt์query_analyzer๋ฅผ ๋ฐํ์ผ๋ก User Question์ ์ฒ๋ฆฌํฉ๋๋ค.- prompt = ChatPromptTemplate.from_messages([(โsystemโ, system), (โhumanโ, โ{question}โ)])
-
query_analyzer = prompt structured_llm
-
์๋์ ๊ฐ์ ํํ๋ก question์ ์ฒ๋ฆฌํด์ค๋๋ค.
1
query_analyzer.invoke({"question": "your question"}).pretty_print()ํ๋กฌํํธ ์์ฑ: ์ฌ์ฉ์ ์ง๋ฌธ์ ํ๋กฌํํธ์ ์ฝ์ ํฉ๋๋ค.LLM ์ฒ๋ฆฌ: LLM์ด ํ๋กฌํํธ๋ฅผ ์ฝ๊ณ TutorialSearch ๊ตฌ์กฐ์ ๋ง๋ ์ถ๋ ฅ์ ์์ฑํฉ๋๋ค.๊ตฌ์กฐํ๋ ์ถ๋ ฅ: ๊ฒฐ๊ณผ๋ฅผ TutorialSearch ๊ฐ์ฒด๋ก ํ์ฑํ๊ณ ์ถ๋ ฅํฉ๋๋ค.
์์: ์ฌ์ฉ์๊ฐ ๋ค์๊ณผ ๊ฐ์ ์ง๋ฌธ์ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค:
1
"2023๋
6์ ์ดํ์ ๊ฒ์๋ LangChain์ ๊ดํ ์์ ์ค 10๋ถ ์ดํ์ ์์์ ๋ณด์ฌ์ค."
-
์ด ์์ฐ์ด ์ง๋ฌธ์ LLM(๋ํ ์ธ์ด ๋ชจ๋ธ)๊ณผ ์ฟผ๋ฆฌ ๋ถ์ ์ฒด์ธ(query analyzer)์ ์ฌ์ฉํด,
TutorialSearch์ ๊ฐ์ ๋ฐ์ดํฐ ๋ชจ๋ธ๋ก ๋ณํํ ์ ์์ต๋๋ค.1 2 3 4 5 6 7 8 9
class TutorialSearch(BaseModel): content_search: str = None title_search: str = None earliest_publish_date: Optional[date] = None latest_publish_date: Optional[date] = None min_length_sec: Optional[int] = None max_length_sec: Optional[int] = None min_view_count: Optional[int] = None max_view_count: Optional[int] = None -
์ฌ๊ธฐ์ ์ฌ์ฉ์ ์ง๋ฌธ์ ๋ณํํ๋ฉด ๋ค์๊ณผ ๊ฐ์
TutorialSearch๊ฐ์ฒด๊ฐ ์์ฑ๋ ์ ์์ต๋๋ค:1 2 3 4 5 6
TutorialSearch( content_search='LangChain', title_search='LangChain', earliest_publish_date=datetime.date(2023, 6, 1), max_length_sec=600 # 10๋ถ์ ์ด ๋จ์๋ก ๋ณํํ ๊ฐ ) -
์ด ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ๋ ์ด์ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ง์ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด:
earliest_publish_dateํ๋๋2023๋ 6์ 1์ผ ์ดํ์ ๊ฒ์๋ ์์๋ง ํํฐ๋งํฉ๋๋ค.max_length_secํ๋๋10๋ถ ์ดํ์ ์์๋ง ํํฐ๋งํฉ๋๋ค.content_search์title_searchํ๋๋ LangChain์ด๋ผ๋ ํค์๋๊ฐ ํฌํจ๋ ์ฝํ ์ธ ๋ ์ ๋ชฉ์ ์ฐพ์ต๋๋ค.
-
์ด ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ง์ ์ ์ฉํ๋ฉด, ์กฐ๊ฑด์ ๋ง๋ ์์๋ง์ ๋ฐํํ ์ ์์ต๋๋ค.
2.5. ์ถ๊ฐ ์์
- ์์ฐ์ด ์ง๋ฌธ: โ2023๋
์ ๊ฒ์๋ chat langchain ๋น๋์คโ
- ์ง์๋ฌธ:
1 2 3
query_analyzer.invoke( {"question": "videos on chat langchain published in 2023"} ).pretty_print() - ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ ์ถ๋ ฅ:
1 2 3 4
content_search: chat langchain title_search: 2023 earliest_publish_date: 2023-01-01 latest_publish_date: 2023-12-31
- ์ง์๋ฌธ:
- ์์ฐ์ด ์ง๋ฌธ: โ2024๋
์ด์ ์ ๊ฒ์๋ chat langchain ๋น๋์คโ
- ์ง์๋ฌธ:
1 2 3
query_analyzer.invoke( {"question": "videos that are focused on the topic of chat langchain that are published before 2024"} ).pretty_print() - ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ ์ถ๋ ฅ:
1 2 3
content_search: chat langchain title_search: chat langchain latest_publish_date: 2023-12-31
- ์ง์๋ฌธ:
- ์์ฐ์ด ์ง๋ฌธ: โ5๋ถ ์ดํ์ ๋ฉํฐ๋ชจ๋ฌ ๋ชจ๋ธ ๊ด๋ จ ๋น๋์คโ
- ์ง์๋ฌธ:
1 2 3
query_analyzer.invoke( {"question": "how to use multi-modal models in an agent, only videos under 5 minutes"} ).pretty_print() - ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ ์ถ๋ ฅ:
1 2 3
content_search: multi-modal models agent title_search: multi-modal models agent max_length_sec: 300
- ์ง์๋ฌธ: