[랭체인] 라우팅 체인 - 유연한 AI 응답 시스템 구축하기steemCreated with Sketch.

in #kr-dev27 days ago (edited)

안녕하세요, AI 개발자 여러분! 오늘은 LangChain의 강력한 기능 중 하나인 라우팅 체인에 대해 알아보겠습니다. 라우팅 체인을 사용하면 질문의 내용에 따라 다른 AI 모델이나 프롬프트를 선택적으로 사용할 수 있어, 더욱 정확하고 맥락에 맞는 응답을 생성할 수 있습니다.

1. 기본 설정

먼저, 필요한 라이브러리를 설치하고 OpenAI API 키를 설정합니다.

!pip install -Uq langchain_core langchain_openai langchain langchain_community
import os
from google.colab import userdata

os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')

참고: 이 부분은 Google Colab에서 작업할 때 필요한 단계입니다. 로컬 환경에서는 API 키를 직접 설정해주세요.

2. 간단한 분류 체인 만들기

우리의 첫 번째 단계는 사용자의 질문을 'LangChain', 'OpenAI', 또는 'Other' 중 하나로 분류하는 간단한 체인을 만드는 것입니다.

from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate

chain = (
    PromptTemplate.from_template(
        """아래의 사용자 질문이 주어졌을 때, 'LangChain', 'OpenAI', 'Other' 중 어느 것에 관한 질문인지 분류하세요.

두 단어 이상으로 응답하지 마세요.

질문: {question}
분류:"""
    )
    | ChatOpenAI()
    | StrOutputParser()
)

result = chain.invoke({
    "question": "OpenAI를 호출하려면 어떻게 하나요?"
})
print(result)  # 출력: OpenAI

이 체인은 사용자의 질문을 입력받아 한 단어로 분류합니다.

3. 특화된 응답 체인 만들기

다음으로, 각 카테고리에 대한 특화된 응답 체인을 만듭니다.

langchain_chain = PromptTemplate.from_template(
    """귀하는 랭체인 전문가입니다. 
항상 "해리슨 체이스가 말했듯이"로 시작하는 질문에 답하세요. 
다음 질문에 답하세요:

질문: {question}
답변:"""
)  | ChatOpenAI()

openai_chain = PromptTemplate.from_template(
    """귀하는 OpenAI 전문가입니다. 
항상 "사무엘 해리스 알트먼이 나에게 말했듯이"로 시작하는 질문에 답하세요.
다음 질문에 답하세요:

질문: {question}
답변:"""
) | ChatOpenAI()

general_chain = PromptTemplate.from_template(
    """다음 질문에 답변하세요:

질문: {question}
답변:"""
) | ChatOpenAI()

각 체인은 특정 주제에 대해 전문가처럼 대답하도록 설계되었습니다.

4. 라우팅 함수 정의

이제 분류 결과에 따라 적절한 체인을 선택하는 라우팅 함수를 정의합니다.

def route(info):
    if "openai" in info["topic"].lower():
        return openai_chain
    elif "langchain" in info["topic"].lower():
        return langchain_chain
    else:
        return general_chain

5. 전체 체인 조립하기

마지막으로, 모든 구성 요소를 하나의 체인으로 조립합니다.

from langchain_core.runnables import RunnableLambda

full_chain = {
    "topic": chain, 
    "question": lambda x: x["question"]
} | RunnableLambda(route)

이 체인은 입력된 질문을 분류하고, 그 결과에 따라 적절한 응답 체인으로 라우팅합니다.

6. 체인 사용하기

이제 우리의 체인을 다양한 질문으로 테스트해 볼 수 있습니다.

print(full_chain.invoke({"question": "OpenAI는 어떻게 사용하나요?"}))
print(full_chain.invoke({"question": "랭체인은 어떻게 사용하나요?"}))
print(full_chain.invoke({"question": "2 + 2는?"}))

각 질문은 적절한 전문가 체인으로 라우팅되어 답변됩니다.

7. 고급 라우팅: 임베딩 기반 프롬프트 선택

더 복잡한 시나리오에서는 코사인 유사도를 사용하여 가장 적절한 프롬프트를 선택할 수 있습니다.

from langchain.utils.math import cosine_similarity
from langchain_openai import OpenAIEmbeddings

# 물리학 질문에 대한 템플릿을 정의합니다.
physics_template = """당신은 매우 똑똑한 물리학 교수입니다. 
물리학에 대한 질문에 간결하고 이해하기 쉽게 대답하는 데 능숙합니다. 
질문에 대한 답을 모를 때는 모른다고 인정합니다.

다음은 질문입니다:
{query}"""

# 수학 질문에 대한 템플릿을 정의합니다.
math_template = """당신은 아주 훌륭한 수학자입니다. 당신은 수학 문제에 대한 답을 잘합니다. 
당신은 어려운 문제를 구성 요소로 분해하고, "구성 요소에 답한 다음 "더 넓은 질문에 답할 수 있기 때문에 매우 훌륭합니다.
구성 요소에 답한 다음 이를 종합하여 더 넓은 질문에 답할 수 있기 때문입니다.

여기 질문이 있습니다:
{query}"""

# OpenAIEmbeddings 객체를 생성합니다.
embeddings = OpenAIEmbeddings()

# 물리학과 수학 템플릿을 리스트로 묶습니다.
prompt_templates = [physics_template, math_template]

# 템플릿들을 임베딩합니다.
prompt_embeddings = embeddings.embed_documents(prompt_templates)


# 입력된 질문에 따라 적절한 템플릿을 선택하는 함수입니다.
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()  # 선택된 템플릿을 사용하여 OpenAI와 대화합니다.
    | StrOutputParser()  # 결과를 문자열로 파싱합니다.
)

# 체인을 실행하여 질문에 대한 답변을 출력합니다.
print(chain.invoke("블랙홀이란 무엇인가요?"))
print(chain.invoke("경로 통합이란 무엇인가요?"))

이 고급 라우팅 방식은 질문의 내용을 더 깊이 이해하고, 가장 적합한 전문가 프롬프트를 선택합니다.

결론

LangChain의 라우팅 체인을 사용하면 다양한 질문에 대해 맥락에 맞는 정확한 응답을 제공할 수 있는 유연한 AI 시스템을 구축할 수 있습니다. 이는 chatbot, 질문-답변 시스템, 또는 지식 기반 애플리케이션을 개발할 때 매우 유용한 기능입니다.

이 튜토리얼이 여러분의 LangChain 프로젝트에 도움이 되었기를 바랍니다. 질문이나 의견이 있다면 언제든 댓글로 남겨주세요!

행복한 코딩 되세요! 🚀🤖

#LangChain

Posted using Obsidian Steemit plugin

Sort:  

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Congratulations, your post has been upvoted by @upex with a 0.22% upvote. We invite you to continue producing quality content and join our Discord community here. Visit https://botsteem.com to utilize usefull and productive automations #bottosteem #upex

Coin Marketplace

STEEM 0.15
TRX 0.12
JST 0.025
BTC 55528.94
ETH 2373.33
USDT 1.00
SBD 2.36