AdaptiveRAG

질문의 복잡성에 따라 적합한 검색 및 답변 생성 전략을 동적으로 선택하는 방법이다.

  1. 사용자 질문의 복잡성 수준을 분석
  2. 수준에 따라 적합한 처리 전략을 선택함

논문에서는 Single-Step Approach, Multi-Step Approach 등으로 구분함.

AdaptiveRAG논문에서는 Single과 Multi를 혼합하도록 문제의 복잡성을 분석하는 단계를 중간에 두는 것을 제안했다.

핵심은 문제의 복잡성을 분석하는 단계가 얼마나 효과적으로 동작하느냐임.

AdaptiveRAG 구현

여기서 라우팅 개념이 나온다. 문제의 복잡성에 따라 어떤 RAG전략을 택할지를 선택해야 하기 때문이고, 이 선택을 그래프 내 라우팅이라고 함.

from typing import Literal
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field

# 라우팅 결정을 위한 데이터 모델
class ToolSelector(BaseModel):
    """Routes the user question to the most appropriate tool."""
    tool: Literal["search_menu", "search_web", "search_wine"] = Field(
        description="Select one of the tools: search_menu, search_wine or search_web based on the user's question.",
    )

# 구조화된 출력을 위한 LLM 설정
structured_llm = llm.with_structured_output(ToolSelector)

# 라우팅을 위한 프롬프트 템플릿
system = dedent("""You are an AI assistant specializing in routing user questions to the appropriate tool.
Use the following guidelines:
- For questions about the restaurant's menu, use the search_menu tool.
- For wine recommendations or pairing information, use the search_wine tool.
- For any other information or the most up-to-date data, use the search_web tool.
Always choose the most appropriate tool based on the user's question.""")

route_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system),
        ("human", "{question}"),
    ]
)

# 질문 라우터 정의
question_router = route_prompt | structured_llm

# 테스트 실행
print(question_router.invoke({"question": "채식주의자를 위한 메뉴가 있나요?"}))
print(question_router.invoke({"question": "스테이크 메뉴와 어울리는 와인을 추천해주세요."}))
print(question_router.invoke({"question": "2022년 월드컵 우승 국가는 어디인가요?"}))

특이하게도 라우팅을 위해 함수가 아니라 클래스를 정의하고, 내부에 프롬프트를 적어둔다.

그리고 with_structured_output() 메서드의 인자에 해당 클래스를 전달해주면, 이제 llm은 ToolSelector 클래스 내부의 tool 중 하나를 결과로 반환한다.

라우팅은 별게 아니고, 이 llm의 시스템 프롬프트로 라우팅을 하라고 하는게 다임. llm이 수준을 스스로 판단해서 툴을 정하라고 지시함.

💡 Literal 은 파이썬 3.8에 새로 도입되었음. 특정 변수의 값의 범위, 종류를 명확하게 지정하는데 사용하는 타입힌팅임.