김이언
김이언
🏅 AI 마스터
🌿 뉴비 파트너
🌈 지피터스금손
🚀 SNS 챌린지 달성자

Langchain - 1차 과제

수요일의 OT 이후 방을 바꾸어야 하나 심각하게 고민했어요.🤣 훌륭한 파트너님 두 분에 열정적인 서포터님👍 그리고 아주 좋은 학습 계획이 있음에도 저를 믿을 수가 없었거든요! 과연 끝까지 해낼 수 있을지 걱정스럽지만, 랭체인이 무엇인지 알아가는 것에 목표를 두었습니다.😁

  • 랭체인 1-1. 프롬프트와 LLM을 사용한 체인 구성

  • 랭체인 1-2. 여러 체인을 연결하여 복잡한 질문에 답하기

  • 랭체인 1-3. 분기 및 병합을 활용한 체인 구성

  • 랭체인 1-4. 체인에 메모리 추가하기

  • 랭체인 1-5. SQL 데이터베이스 쿼리하기




랭체인 1-1. 프롬프트와 LLM을 사용한 체인 구성

  1. 사용자 입력을 받아 프롬프트에 추가하고, 모델로 전달하여 원시 모델 출력을 반환하는 체인을 만드는 방법을 배웁니다.

  2. 먼저, 필요한 라이브러리를 설치하고, 프롬프트 템플릿과 LLM을 결합하여 기본 체인을 구성합니다.

  3. 그 다음, 출력 포맷을 변환하기 위해 출력 파서를 추가하고, 입력을 단순화하기 위한 구성 요소를 추가하는 방법을 배웁니다.

# 환경변수 등록, 생략

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

# LLM, 응답 인스턴스 설정
model = ChatOpenAI(model="gpt-4o")
output_parser = StrOutputParser()

# 프롬프트 생성, 템플릿 설정
prompt = ChatPromptTemplate.from_template("{topic}에 대한 짧은 농담을 한글로 해줘.")

# LCEL 체인 생성
chain = prompt | model | output_parser

# topic 입력받기
topic = input("농담의 주제: ")

# 체인 호출, 결과 저장, 출력
result = chain.invoke({"topic": topic})
print(result)
  • 아무래도 미국적인 농담을 구사하네요~


랭체인 1-2. 여러 체인을 연결하여 복잡한 질문에 답하기

두개 이상의 체인을 사용하여 질문에 답하는 방법을 배웁니다.

  1. 첫 번째 체인은 특정 인물이 태어난 도시를 찾습니다. ex) “what is the city Barack Obama is from?”

  2. 두 번째 체인은 해당 도시가 속한 국가를 찾는데 이때 입력받은 언어로 답해야합니다. ex) “what country is the city Seoul in? respond in french”

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

# LLM, 응답 인스턴스 설정
model = ChatOpenAI(model="gpt-4o")
output_parser = StrOutputParser()

# 프롬프트 생성, 템플릿 설정
prompt1 = ChatPromptTemplate.from_template("{person}이 태어난 도시를 찾아줘.")
prompt2 = ChatPromptTemplate.from_template("{city}가 속한 국가를 알려줘. in {language}.")

# 사용자의 입력받기
person = input("인물 이름: ")
language = input("번역 언어: ")

# chain1 생성 및 호출
chain1 = prompt1 | model | output_parser
city = chain1.invoke({"person": person})

# chain2 생성 및 호출
chain2 = prompt2 | model | output_parser
result = chain2.invoke({"city": city, "language": language})
print(result)
  • 4o 모델을 사용해서 춘천이 닭갈비와 막국수로 유명하다는 부가 정보까지 알려줍니다.


랭체인 1-3. 분기 및 병합을 활용한 체인 구성

  1. 하나의 입력을 받아 여러 컴포넌트에서 동시에 처리하고, 이후 다른 컴포넌트에서 결과를 합쳐 최종 응답을 생성하는 체인을 만드는 방법을 배웁니다. 이를 통해 복잡한 계산 그래프를 구성하고, 다양한 관점에서 문제를 분석할 수 있습니다.

  2. 먼저, 주제에 대한 논쟁을 생성하는 컴포넌트를 구성합니다. 그 다음, 이 논쟁의 긍정적 측면과 부정적 측면을 나누어 평가하는 분기를 만듭니다. 마지막으로, 이러한 분석을 바탕으로 종합적인 응답을 생성하는 컴포넌트를 추가합니다.

  3. 이 과정을 통해, 복잡한 문제에 대해 다각도로 분석하고, 여러 분석 결과를 종합하여 의사결정을 내리는 과정을 학습할 수 있습니다.

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

# LLM, 응답 인스턴스 설정
model = ChatOpenAI(model="gpt-4o")
output_parser = StrOutputParser()

# 사용자의 입력받기
topic = input("논쟁 주제: ")

# 프롬프트 설정
prompt_topic = ChatPromptTemplate.from_template("다음 주제에 대한 논쟁을 생성해줘: {topic}")
prompt_positive = ChatPromptTemplate.from_template("다음 논쟁의 긍정적인 측면을 평가해줘: {debate}")
prompt_negative = ChatPromptTemplate.from_template("다음 논쟁의 부정적인 측면을 평가해줘: {debate}")
prompt_summary = ChatPromptTemplate.from_template("다음 긍정적, 부정적 분석을 종합하여 결론을 내려줘: {positive} {negative}")

# Advanced Sequential Chain 구성
chain_topic = prompt_topic | model | output_parser
chain_positive = {"debate":chain_topic} | prompt_positive | model | output_parser
chain_negative = {"debate":chain_topic} | prompt_negative | model | output_parser
chain_summary = {"positive":chain_positive,"negative":chain_negative} | prompt_summary | model | output_parser

# 체인 호출 및 결과 출력
result = chain_summary.invoke({"topic": topic})
print(result)
  • 결과가 출력되기까지 약간의 시간이 걸립니다.


랭체인 1-4. 체인에 메모리 추가하기

  1. 어떻게 임의의 체인에 메모리를 추가하여 대화의 맥락을 유지할 수 있는지 배웁니다. 이 과정에서 메모리 클래스를 사용하고 수동으로 연결하는 방법을 실습합니다.

  2. 첫 번째 단계로, 메모리에 사용자의 입력과 챗봇의 응답을 저장하는 방법을 배우고, 이를 통해 이전 대화의 맥락을 다음 대화에 활용하는 방법을 실습합니다.

  3. 예를 들어, 사용자가 "hi im bob"이라고 입력했을 때, 이 정보를 메모리에 저장하고, 다음 대화에서 "whats my name"이라는 질문에 "Your name is Bob."라고 응답하는 과정을 통해 메모리의 사용 방법을 배웁니다.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

# LLM, 메모리 설정
model = ChatOpenAI(model="gpt-4o")
memory = ConversationBufferMemory()

# ConversationChain 설정
conversation = ConversationChain(llm=model, memory=memory)

# role 프롬프트 설정, 실행
role_prompt = "You are a highly capable assistant. Always provide helpful and accurate information in korean."
conversation.predict(input=role_prompt)

while True:
    user_input = input("사용자 입력: ")  # 사용자의 입력받기
    if user_input.lower() in ["exit", "quit", "bye"]:  # 대화 종료 조건
        print("Bye!")
        break
    result = conversation.predict(input=user_input)  # 체인 실행
    print(result)

# 전체 메모리 기록 출력
# print(memory.buffer)
  • 일정을 관리하는 능력있는 Assistant의 역할을 잘 해줍니다.


랭체인 1-5. SQL 데이터베이스 쿼리하기

  1. 사용자의 질문에 답하기 위해 SQL 데이터베이스를 쿼리하는 방법을 배웁니다. 이 과정에서는 SQL 쿼리를 생성하여 데이터베이스에 질문을 하고, 결과를 얻어 자연어로 응답을 생성하는 전체 과정을 실습합니다.

  2. 먼저, Chinook 샘플 데이터베이스를 사용하여 테이블 스키마를 가져오고, 이를 기반으로 SQL 쿼리를 작성합니다. 그 다음, 작성된 쿼리를 실행하여 결과를 얻고, 이 결과를 바탕으로 자연어 응답을 생성합니다.

  3. 예를 들어, "How many employees are there?"라는 질문에 대해 SQL 쿼리를 생성하고, 실행 결과를 바탕으로 "There are 8 employees."라는 응답을 생성하는 방법을 배웁니다.

from langchain_community.utilities import SQLDatabase
from langchain.chains import create_sql_query_chain
from langchain_openai import ChatOpenAI
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool

# SQLite 데이터베이스 Chinook을 기반으로 SQLDatabase 인스턴스 생성
db = SQLDatabase.from_uri("sqlite:///Chinook.db")

# 모델 생성
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

# SQL 쿼리 실행 도구 설정
execute_query = QuerySQLDataBaseTool(db=db)

# SQL 쿼리 체인 설정
write_query = create_sql_query_chain(llm, db)

from operator import itemgetter
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough

# 사용자의 질문, SQL 쿼리, SQL 결과를 기반으로 자연어 응답을 작성하는 프롬프트 템플릿 설정
answer_prompt = PromptTemplate.from_template(
    """Given the following user question, corresponding SQL query, and SQL result, answer the user question.

Question: {question}
SQL Query: {query}
SQL Result: {result}
Answer: """
)

# 답변 체인 설정
answer = answer_prompt | llm | StrOutputParser()

chain = (
    RunnablePassthrough.assign(query=write_query).assign( # write_query 실행하여 query에 할당
        result=itemgetter("query") | execute_query # query 값으로 execute_query 실행하여 result에 할당
    )
    | answer # answer 실행, 최종 결과 생성
)

# 사용자 질문 입력, 결과 출력
user_question = input("질문 입력: ")
print(chain.invoke({"question": user_question}))
  • Decimal Objects에 대한 워닝이 있습니다. 워닝이 나오지 않게 하는 방법도 있었으나 문자열만 다루고 있어서 일단은 무시했어요.



제대로 되었는지 의문스럽지만, 과제를 했다는 것에 만족하며 업로드합니다.
다음 과제는 더 어렵겠죠? 🥶

#11기랭체인

9
4개의 답글

👉 이 게시글도 읽어보세요