[LLM] Langchain ReAct Agent에 DALL-E tool 추가하기

2024. 8. 2. 17:01DL

안녕하세요 오랜만에 또 글을 씁니다.

 

요즘 많은 분들이 Agent를 활용해서, AI Product를 만들고 계신데요, 그중에서 우리가 일반적으로 사용하는 gpt에도 들어있는 기능을 한번 구현해보고자 합니다.

 

우리가 GPT에 질문을 할 때 "테슬라 모델3에 황금색 필름 래핑한 모습인 사진 보여줘" 같은 질문을 하게 된다면. GPT는 DALL-E-3를 호출하여 이미지를 생성하고 쳇 화면에 표출해 주곤합니다.

이미지 생성 예시

이런 이미지는 어떻게 쳇 화면에서 바로 인식하고 생성하는것일까요?

 

바로 ReAct Agent같은 반응형을 이용하면 가능합니다. Agent는 다양한 Tool을 등록하고 등록된 tools를 Agent LLM이 질문(요구사항)에 따라 어떤 도구를 사용할지 판단하는 과정을 거칩니다. 이 과정에서 이미지를 생성해야하는 경우 DALL-E를 사용하게 하면 됩니다.

 

전반적인 코드와 설명 

from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain_community.utilities.dalle_image_generator import DallEAPIWrapper
import requests
from PIL import Image
from io import BytesIO
from langchain.tools import Tool
from langchain_core.runnables import (
    RunnableBranch,
    RunnableLambda,
    RunnableParallel,
    RunnablePassthrough,
)

# DALL-E 래퍼 생성
# !! 중요 : 해당 모둘을 OPENAI API KEY를 환경변수에서 받아오도록 설정 돼 있음. 내부 코드를 열어 key불러오는 파트에 try: except처리를 통해 키를 입력받을 수 있도록 합시다.
dalle = DallEAPIWrapper(model="dall-e-3")

llm = ChatOpenAI(
	openai_api_key = "your api key num",
    temperature=0.7,
    model="gpt-4o-mini",
)

# DALL-E 이미지 생성을 위한 프롬프트 템플릿 정의
DALLE_PROMPT = PromptTemplate(
    input_variables=["image_desc"],
    template="Create a detailed image description for DALL-E based on the following: {image_desc}"
)

# DALL-E에 보낼 이미지 생성 문자를 생성하는 Chain정의
description_chain = RunnablePassthrough() | DALLE_PROMPT | llm

# 이미지 생성을 실행하는 함수 정의
def generate_image_url(image_description):
    """
    이미지 설명을 바탕으로 DALL-E를 사용해 이미지를 생성하고 URL을 반환합니다.

    Args:
    image_description (str): 생성할 이미지에 대한 설명

    Returns:
    str: 생성된 이미지의 URL
    """
    # LLM을 사용하여 상세한 이미지 설명 생성
    detailed_description = dalle_llm_chain.invoke(image_description)
    # DALL-E를 사용하여 이미지 URL 생성
    image_url = dalle.run(detailed_description.content)

	# 생성된 이미지는 Base64 || Byte 가 아니라, openai에서 url을 제공합니다.
    return image_url

# Agent에 사용할 Tool 정의
# @tool 데코레이터를 사용해도 가능합니다!
dalle_tool = Tool(
    name="DALL-E Image Generator",
    func=generate_image_url,
    description="""Generate an image based on a text description specifically related to electric cars or electric car technology, and return the image URL. 
    The input must be a string describing the desired image and must include elements related to electric vehicles or their technology."""
)

tools = [dalle_tool]

# Sonnet Agent Executor # Construct the ReAct agent
sonnet_agent = create_react_agent(
    llm=claude_sonnet_llm,
    tools=tools,
    prompt=prompt_factory.AGENT_PROMPT_SONNET)

 

Agent 진행 Flow Chart

Agent가 이미지를 생성하는 사고 로직

 

너무 어려운것이 없습니다.

 

단순히 Langchain에서 제공하는 모듈을 로드하고, 각각 맞는 Prompt를 정의하고 우리가 일반적으로 Agent에 Tool을 등록하는 방식을 이용하면 단순하게 그림을 그려주는 Agent를 만들 수 있습니다.

 

 

주의 해야할점, 개선 점

1. 이미지 생성이 완벽하지 않을 수 있습니다. 
    - 이미지를 생성하는것은 DALL-E의 역할이고 아무리 좋은 Description이 주어진다 하더라도, 생성된 이미지가 맘에 들지 않거나, 이상할 수 있다는 점을 인지해야합니다.

 

2. Agent가 DALL-E에게 주는 명령 Action Input을 구체화 하는 프롬프트를 작성해야합니다. 그렇지 않으면 너무 단순한 내용, 실제 질문과 동떨어진 내용의 input이 들어가고 원하는 생성 결과물을 얻을 수 없을것 입니다.

 

3. Agent에 목적성을 부여한다면? 예를들어 연예인에 관한 내용에만 그림을 그리게 하고싶다거나 한다면 해당 내용을 잘 정의해야합니다.

 

4. 단. 부정적인 그림 (선정적, 종교, 인종 차별적 그림들은 자체적으로 못그리게 막아둔것 같아서 이런점은 특별하게 고려하지 않아도 좋을것 같습니다.)