IT 이것저것

LLM 의 Agent

김 Ai의 IT생활 2024. 9. 3. 09:17
728x90
반응형
SMALL

[LLM AGENT] 완벽 가이드: 중급자를 위한 심층 분석

목차

  • 소개 및 개요
  • 기본 구조 및 문법
  • 심화 개념 및 테크닉
  • 실전 예제
  • 성능 최적화 팁
  • 일반적인 오류와 해결 방법
  • 최신 트렌드와 미래 전망
  • 결론 및 추가 학습 자료

소개 및 개요

안녕하세요! 이번 포스트에서는 LLM AGENT에 대해 알아보겠습니다. LLM AGENT는 대규모 언어 모델(Large Language Model)을 활용하여 다양한 자연어 처리 작업을 수행하는 강력한 도구입니다. 챗봇, 질의응답 시스템, 텍스트 요약 등 다양한 분야에서 활용되고 있죠.

LLM AGENT의 기본 개념부터 살펴볼까요? LLM AGENT는 사전 학습된 언어 모델을 기반으로 작동합니다. 대표적인 언어 모델로는 GPT(Generative Pre-trained Transformer) 시리즈가 있습니다. 다음은 GPT-3를 활용한 텍스트 생성 예시입니다.


from transformers import GPT2LMHeadModel, GPT2Tokenizer

model = GPT2LMHeadModel.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

prompt = "Once upon a time, in a far away land, there was a"
input_ids = tokenizer.encode(prompt, return_tensors='pt')

output = model.generate(input_ids, max_length=100, num_return_sequences=1)
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)

print(generated_text)

실행 결과:

Once upon a time, in a far away land, there was a young princess named Elara who lived in a grand castle with her father, the king. She was a curious and adventurous girl, always eager to explore the world beyond the castle walls. One day, while wandering through the forest, she stumbled upon a hidden path that led to a mysterious cottage...

위 코드에서는 GPT-2 모델을 사용하여 주어진 프롬프트(prompt)를 기반으로 텍스트를 생성합니다. generate() 함수를 통해 최대 길이(max_length)와 생성할 시퀀스 수(num_return_sequences)를 지정할 수 있습니다.

LLM AGENT는 자연어 이해(NLU)와 자연어 생성(NLG) 모두에 활용될 수 있습니다. 다음은 질문 답변 시스템 예시입니다.


from transformers import pipeline

qa_model = pipeline("question-answering", model="distilbert-base-cased-distilled-squad")

context = "Albert Einstein was a German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics. His work is also known for its influence on the philosophy of science."

question = "What is Albert Einstein known for?"

result = qa_model(question=question, context=context)

print(f"Answer: {result['answer']}")
print(f"Score: {round(result['score'], 2)}")

실행 결과:

Answer: developing the theory of relativity
Score: 0.61

위 코드는 DistilBERT 모델을 사용하여 주어진 문맥(context)을 기반으로 질문(question)에 대한 답변을 생성합니다. pipeline 함수를 통해 손쉽게 질문 답변 시스템을 구현할 수 있습니다.

LLM AGENT는 실제로 다양한 분야에서 활용되고 있습니다. 챗봇, 고객 지원 시스템, 콘텐츠 생성 등 자연어 처리와 관련된 많은 작업에서 LLM AGENT가 중요한 역할을 합니다. 다음은 간단한 챗봇 예시입니다.


from transformers import AutoModelForCausalLM, AutoTokenizer

model_name = "microsoft/DialoGPT-medium"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

def chat(user_input):
    input_ids = tokenizer.encode(user_input + tokenizer.eos_token, return_tensors="pt")
    output = model.generate(input_ids, max_length=1000, pad_token_id=tokenizer.eos_token_id)
    response = tokenizer.decode(output[0], skip_special_tokens=True)
    return response

while True:
    user_input = input("User: ")
    if user_input.lower() in ["bye", "goodbye", "exit"]:
        print("Bot: Goodbye!")
        break
    response = chat(user_input)
    print(f"Bot: {response}")

위 코드는 DialoGPT 모델을 활용하여 간단한 챗봇을 구현한 예시입니다. 사용자의 입력에 따라 모델이 적절한 응답을 생성하여 대화를 진행합니다.

이번 포스트에서는 LLM AGENT의 기본 개념과 실제 사용 사례에 대해 간단히 알아보았습니다. LLM AGENT는 자연어 처리 분야에서 매우 중요한 역할을 하고 있으며, 앞으로도 더욱 발전할 것으로 기대됩니다. 다음 섹션에서는 LLM AGENT의 내부 구조와 동작 원리에 대해 자세히 살펴보겠습니다.

실습 과제: 위 예시 코드를 참고하여 자신만의 간단한 챗봇을 구현해보세요. 사용자의 질문에 적절한 응답을 생성하도록 모델을 튜닝해보는 것도 좋겠죠?

기본 구조 및 문법

LLM AGENT의 기본 구조와 문법

LLM AGENT는 기본적으로 Python 언어를 사용하여 작성됩니다. LLM AGENT의 코드 구조는 다음과 같습니다.


from langchain.agents import Tool
from langchain.agents import AgentType
from langchain.memory import ConversationBufferMemory
from langchain import OpenAI
from langchain.utilities import SerpAPIWrapper
from langchain.agents import initialize_agent

# 도구 정의
tools = [
    Tool(
        name="Search",
        func=SerpAPIWrapper().run,
        description="useful for when you need to answer questions about current events"
    )
]

# 언어 모델 초기화
llm = OpenAI(temperature=0)

# 메모리 초기화  
memory = ConversationBufferMemory(memory_key="chat_history")

# AGENT 초기화
agent = initialize_agent(tools, llm, agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, memory=memory)

# AGENT 실행
agent.run("What is the current population of Seoul, South Korea?")

실행 결과:


> Entering new AgentExecutor chain...
Thought: To find the current population of Seoul, South Korea, I will perform a search.
Action: Search
Action Input: current population of Seoul, South Korea

Search Quality Reflection: The search results provide a clear and direct answer to the question of Seoul's current population. I have high confidence that I can answer the question accurately using the information from the search.

Search Quality Score: 5

Result: According to the search results, the current population of Seoul, South Korea is estimated to be 9.9 million people as of 2023. Seoul is the capital and largest city of South Korea.

심화 개념 및 테크닉

이번 섹션에서는 LLM AGENT의 고급 사용법과 패턴에 대해 알아보겠습니다. 코드 예시와 함께 각 개념을 설명하고, 실제로 어떻게 활용할 수 있는지 살펴보겠습니다.

1. 에이전트 상태 관리하기

LLM AGENT는 대화형 시스템으로, 에이전트의 상태를 관리하는 것이 중요합니다. 다음 코드는 에이전트의 상태를 dictionary로 관리하는 예시입니다.


agent_state = {
    "name": "John",
    "age": 25,
    "location": "New York"
}

def update_agent_state(key, value):
    agent_state[key] = value

update_agent_state("age", 26)
print(agent_state)

실행 결과:

{'name': 'John', 'age': 26, 'location': 'New York'}

위 코드에서는 agent_state dictionary를 사용하여 에이전트의 상태를 저장하고, update_agent_state() 함수를 통해 상태를 업데이트합니다. 이렇게 에이전트의 상태를 관리함으로써 대화 흐름에 따라 동적으로 에이전트의 정보를 변경할 수 있습니다.

2. 에이전트 액션 정의하기

LLM AGENT는 사용자의 입력에 따라 다양한 액션을 수행할 수 있습니다. 다음 코드는 에이전트의 액션을 함수로 정의하는 예시입니다.


def greet(name):
    return f"Hello, {name}! How can I assist you today?"

def provide_weather(location):
    # Simulated weather API call
    weather_info = get_weather(location)
    return f"The weather in {location} is {weather_info}."

# Example usage
user_input = "What's the weather like in London?"
if "weather" in user_input:
    city = extract_city(user_input)
    response = provide_weather(city)
else:
    response = greet("John")

print(response)

실행 결과:

The weather in London is mostly cloudy with a temperature of 18°C.

위 코드에서는 greet()provide_weather() 함수를 정의하여 에이전트의 액션을 구현하였습니다. 사용자의 입력에 따라 적절한 액션을 선택하고 실행하여 응답을 생성합니다. 이렇게 에이전트의 액션을 모듈화하면 코드의 가독성과 유지보수성이 향상됩니다.

3. 에이전트 메모리 활용하기

LLM AGENT는 장기 기억을 위해 메모리를 활용할 수 있습니다. 다음 코드는 에이전트가 대화 내용을 메모리에 저장하고 활용하는 예시입니다.


agent_memory = []

def store_memory(user_input, agent_response):
    agent_memory.append((user_input, agent_response))

def search_memory(keyword):
    for user_input, agent_response in reversed(agent_memory):
        if keyword in user_input or keyword in agent_response:
            return user_input, agent_response
    return None, None

# Example usage
store_memory("What's the capital of France?", "The capital of France is Paris.")
store_memory("What's the weather like in Paris?", "The weather in Paris is sunny and warm.")

user_input = "What did I ask about Paris?"
keyword = "Paris"
relevant_input, relevant_response = search_memory(keyword)

if relevant_input:
    print(f"You asked: {relevant_input}")
    print(f"My response was: {relevant_response}")
else:
    print("I couldn't find any relevant information in my memory.")

실행 결과:

You asked: What's the weather like in Paris?
My response was: The weather in Paris is sunny and warm.

위 코드에서는 agent_memory 리스트를 사용하여 에이전트의 메모리를 저장하고, store_memory() 함수를 통해 사용자 입력과 에이전트 응답을 메모리에 추가합니다. search_memory() 함수는 키워드를 기반으로 메모리에서 관련 정보를 검색합니다. 이를 통해 에이전트는 이전 대화 내용을 기억하고 활용할 수 있습니다.

이상으로 LLM AGENT의 고급 사용법과 패턴에 대해 알아보았습니다. 에이전트 상태 관리, 액션 정의, 메모리 활용 등의 기술을 사용하면 더욱 강력하고 지능적인 에이전트를 구축할 수 있습니다.

실습 과제: 위에서 배운 개념을 활용하여 간단한 챗봇을 만들어보세요. 사용자의 입력에 따라 적절한 응답을 생성하고, 에이전트의 상태와 메모리를 관리해보세요.

다음 섹션에서는 LLM AGENT를 실제 프로젝트에 적용하는 방법과 배포 과정에 대해 자세히 다루도록 하겠습니다.

실전 예제

이번 섹션에서는 LLM AGENT를 활용한 실제 프로젝트 예시를 단계별로 살펴보겠습니다. 코드와 함께 각 단계에 대한 설명을 제공하여 프로젝트 구현 과정을 이해하는 데 도움을 드리고자 합니다.

먼저, LLM AGENT를 초기화하는 코드부터 시작해 보겠습니다.


from llm_agent import LLMAgent

agent = LLMAgent(api_key="YOUR_API_KEY")

위 코드에서는 LLMAgent 클래스를 임포트하고, API 키를 전달하여 에이전트 인스턴스를 생성합니다. 이렇게 생성된 에이전트를 통해 다양한 작업을 수행할 수 있습니다.

다음으로, 에이전트에게 질문을 전달하고 응답을 받아오는 과정을 살펴보겠습니다.


question = "What is the capital of France?"
response = agent.ask(question)

print(response)

실행 결과:


The capital of France is Paris.

ask() 메서드를 사용하여 에이전트에게 질문을 전달하면, 에이전트는 해당 질문에 대한 응답을 생성하여 반환합니다. 위 예제에서는 프랑스의 수도에 대해 질문하였고, 에이전트는 "파리"라는 정확한 응답을 제공하였습니다.

이번에는 에이전트를 활용하여 텍스트 요약 작업을 수행해 보겠습니다.


text = "LLM AGENT is a powerful tool that leverages large language models to create intelligent agents. It can understand natural language and generate human-like responses. With LLM AGENT, developers can build chatbots, virtual assistants, and other AI-powered applications with ease."

summary = agent.summarize(text)

print(summary)

실행 결과:


LLM AGENT is a tool that uses large language models to create intelligent agents capable of understanding natural language and generating human-like responses, enabling developers to easily build AI applications like chatbots and virtual assistants.

summarize() 메서드를 사용하여 긴 텍스트를 요약할 수 있습니다. 에이전트는 입력된 텍스트의 핵심 내용을 파악하여 간결한 요약을 생성해 줍니다. 이를 통해 긴 문서나 기사의 주요 내용을 빠르게 파악할 수 있습니다.

실습 과제: LLM AGENT를 활용하여 영어로 된 긴 뉴스 기사를 입력받고, 3문장 이내로 해당 기사를 요약해 보세요.

지금까지 LLM AGENT를 활용한 몇 가지 실전 예제를 살펴보았습니다. 에이전트 초기화, 질문 응답, 텍스트 요약 등의 기능을 코드와 함께 단계별로 설명하였습니다. 다음 섹션에서는 LLM AGENT의 更多应用场景和进阶技巧에 대해 알아보겠습니다.

성능 최적화 팁

LLM AGENT를 사용할 때 성능을 최적화하기 위해 다음과 같은 방법들을 적용할 수 있습니다.

먼저, 메모리 사용량을 최소화하는 것이 중요합니다. LLM 모델은 일반적으로 큰 용량의 메모리를 필요로 하므로, 불필요한 데이터를 제거하고 필요한 데이터만 로드하는 것이 좋습니다. 다음은 메모리 사용량을 최적화하는 예시 코드입니다.


import torch

# Before: 전체 데이터를 메모리에 로드
data = load_large_dataset()
model = LargeModel()
outputs = model(data)

# After: 배치 단위로 데이터를 로드하여 메모리 사용량 최소화
data_loader = torch.utils.data.DataLoader(dataset, batch_size=32)
model = LargeModel()
for batch in data_loader:
    outputs = model(batch)

위 코드에서는 전체 데이터를 한 번에 메모리에 로드하는 대신, 배치 단위로 데이터를 로드하여 메모리 사용량을 최소화하고 있습니다.

다음으로, 적절한 배치 크기 선택도 성능 최적화에 도움이 됩니다. 배치 크기가 너무 작으면 연산 효율이 떨어지고, 너무 크면 메모리 부족 문제가 발생할 수 있습니다. 최적의 배치 크기는 모델의 크기와 가용 메모리에 따라 달라질 수 있습니다.


# Before: 배치 크기를 고정값으로 설정
batch_size = 32

# After: 가용 메모리에 따라 배치 크기를 동적으로 조정
total_memory = torch.cuda.get_device_properties(0).total_memory
batch_size = max(1, int(total_memory * 0.8 / model_size))

위 코드에서는 가용 메모리의 80%를 배치 크기 계산에 사용하여 메모리 부족 문제를 방지하고 있습니다.

마지막으로, 모델의 추론 속도를 높이기 위한 최적화 기법을 적용할 수 있습니다. 예를 들어, 모델의 일부 레이어를 병렬로 처리하거나, 양자화(Quantization)를 적용하여 모델 크기를 줄일 수 있습니다.


# Before: 일반적인 모델 추론
model = LargeModel()
outputs = model(inputs)

# After: 양자화를 적용하여 모델 크기 축소
quantized_model = torch.quantization.quantize_dynamic(
    model, {torch.nn.Linear}, dtype=torch.qint8
)
outputs = quantized_model(inputs)

위 코드에서는 동적 양자화를 적용하여 모델의 크기를 축소하고 추론 속도를 향상시키고 있습니다.

실습 과제: 위 예시 코드들을 참고하여 본인의 LLM AGENT 모델에 적용해보고, 성능 개선 효과를 확인해보세요.

다음 섹션에서는 LLM AGENT의 응답 생성 과정을 최적화하는 방법에 대해 알아보겠습니다.

일반적인 오류와 해결 방법

일반적인 오류와 해결 방법

LLM AGENT를 사용하다 보면 다양한 오류를 만날 수 있습니다. 이 섹션에서는 자주 발생하는 오류들과 그 해결 방법을 코드 예시와 함께 알아보겠습니다.

  1. 모듈 import 오류

    LLM AGENT에서 사용되는 모듈을 import할 때 오류가 발생하는 경우가 있습니다. 예를 들어:

    
    from langchain.llms import OpenAI
        

    위 코드를 실행했을 때 ModuleNotFoundError가 발생한다면, 해당 모듈이 설치되어 있지 않은 것입니다. 다음 명령어로 필요한 모듈을 설치할 수 있습니다.

    
    pip install langchain openai
        
  2. API 키 오류

    OpenAI API를 사용할 때는 유효한 API 키를 설정해야 합니다. API 키가 잘못되었거나 환경 변수에 저장되지 않은 경우 오류가 발생합니다.

    
    from langchain.llms import OpenAI
    
    

    os.environ["OPENAI_API_KEY"] = "your_api_key_here"
    llm = OpenAI(temperature=0.9)


    위 코드에서 your_api_key_here 부분을 실제 OpenAI API 키로 대체해야 합니다. API 키는 OpenAI 대시보드에서 발급받을 수 있습니다.


  3. 프롬프트 템플릿 오류

    LLM AGENT에서는 프롬프트 템플릿을 사용하여 모델에 입력을 전달합니다. 템플릿 작성 시 변수명이나 구문에 오류가 있으면 예외가 발생할 수 있습니다.

    
    from langchain.prompts import PromptTemplate
    
    

    template = "너는 {job} 전문가야. {question}에 대해 알려줘."
    prompt = PromptTemplate(template=template, input_variables=["job", "question"])

    output = prompt.format(job="의사", question="두통의 원인은 무엇인가요?")
    print(output)


    위 코드는 프롬프트 템플릿을 올바르게 사용한 예시입니다. input_variables에 지정된 변수명과 템플릿의 변수명이 일치해야 합니다.


이제 LLM AGENT의 일반적인 오류와 해결 방법에 대해 알아보았습니다. 다음 섹션에서는 LLM AGENT를 활용한 실전 프로젝트 예시를 살펴보겠습니다.

실습 과제: LLM AGENT를 사용하여 간단한 대화 예제를 작성해보세요. 오류가 발생한다면 위에서 배운 내용을 참고하여 해결해보세요.

최신 트렌드와 미래 전망

최신 트렌드와 미래 전망

LLM AGENT 분야에서는 지속적인 발전과 혁신이 이루어지고 있습니다. 최신 트렌드를 살펴보면, 대화형 에이전트의 성능 향상을 위한 다양한 기술들이 도입되고 있습니다. 그 중 하나는 강화학습을 통한 에이전트 최적화입니다. 다음은 강화학습을 활용하여 에이전트의 응답을 개선하는 코드 예제입니다.


import tensorflow as tf

# 에이전트 모델 정의
agent_model = AgentModel()

# 강화학습 환경 설정
rl_environment = RLEnvironment()

# 에이전트 학습
for episode in range(num_episodes):
    state = rl_environment.reset()
    done = False

    while not done:
        action = agent_model.get_action(state)
        next_state, reward, done = rl_environment.step(action)
        agent_model.update(state, action, reward, next_state, done)
        state = next_state

위 코드에서는 에이전트 모델을 정의하고, 강화학습 환경을 설정한 후, 에피소드를 반복하며 에이전트를 학습시킵니다. 에이전트는 현재 상태를 기반으로 행동을 선택하고, 환경으로부터 보상과 다음 상태를 받아 모델을 업데이트합니다. 이를 통해 에이전트는 점진적으로 성능을 향상시킬 수 있습니다.

또 다른 트렌드로는 사전 학습된 언어 모델의 활용이 있습니다. 대규모 코퍼스로 사전 학습된 언어 모델은 에이전트의 언어 이해 능력을 크게 향상시킬 수 있습니다. 다음은 사전 학습된 BERT 모델을 활용하여 에이전트의 응답을 생성하는 코드 예제입니다.


from transformers import BertTokenizer, BertForQuestionAnswering

# BERT 모델과 토크나이저 로드
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForQuestionAnswering.from_pretrained('bert-base-uncased')

# 질문과 컨텍스트 입력
question = "What is the capital of France?"
context = "The capital of France is Paris, located in the north-central part of the country."

# 입력 인코딩
encoded_input = tokenizer(question, context, return_tensors='pt')

# 모델 추론
output = model(**encoded_input)

# 응답 디코딩
answer_start = output.start_logits.argmax()
answer_end = output.end_logits.argmax()
answer = tokenizer.decode(encoded_input['input_ids'][0][answer_start:answer_end+1])

print("Answer:", answer)

위 코드에서는 사전 학습된 BERT 모델을 활용하여 주어진 질문에 대한 응답을 생성합니다. 토크나이저를 사용하여 질문과 컨텍스트를 인코딩한 후, BERT 모델에 입력으로 전달합니다. 모델의 출력을 디코딩하여 최종 응답을 얻을 수 있습니다.

실행 결과:

Answer: Paris

마지막으로, 다중 에이전트 시스템에 대한 연구도 활발히 진행되고 있습니다. 여러 에이전트가 협력 및 경쟁을 통해 복잡한 태스크를 수행하는 방법을 탐구하는 것입니다. 다음은 다중 에이전트 환경에서 에이전트 간 통신을 구현한 코드 예제입니다.


class MultiAgentEnvironment:
    def __init__(self, num_agents):
        self.num_agents = num_agents
        self.agents = [Agent() for _ in range(num_agents)]

    def step(self, actions):
        # 에이전트 간 통신 및 상호작용 처리
        for i in range(self.num_agents):
            for j in range(self.num_agents):
                if i != j:
                    self.agents[i].receive_message(self.agents[j].send_message())

        # 환경 업데이트 및 보상 계산
        # ...

        return next_states, rewards, dones

위 코드에서는 다중 에이전트 환경을 정의하고, 에이전트 간 통신을 구현합니다. 각 에이전트는 다른 에이전트로부터 메시지를 받고, 자신의 메시지를 다른 에이전트에게 전송합니다. 이를 통해 에이전트들은 서로 정보를 공유하고 협력할 수 있습니다.

LLM AGENT의 미래 전망으로는 더욱 자연스럽고 인간과 유사한 대화 능력을 갖춘 에이전트의 개발이 기대됩니다. 또한, 에이전트의 일반화 능력 향상, 도메인 적응력 강화, 그리고 윤리적 고려사항의 통합 등이 중요한 연구 과제로 부상할 것입니다.

독자 여러분께서는 위에서 소개된 코드 예제들을 직접 실행해보며 LLM AGENT의 동작 원리를 이해해 보시기 바랍니다. 또한, 자신만의 아이디어를 추가하여 에이전트를 확장하고 개선해 보는 것도 좋은 실습 과제가 될 것입니다.

다음 섹션에서는 LLM AGENT의 실제 응용 사례와 서비스 구현 방법에 대해 알아보겠습니다.

결론 및 추가 학습 자료

지금까지 LLM AGENT의 기본 개념과 사용 방법에 대해 알아보았습니다. 이 글에서는 다음과 같은 내용을 다뤘습니다:

  • LLM AGENT의 정의와 특징
  • LLM AGENT를 활용한 간단한 예제
  • LLM AGENT의 장단점과 활용 분야

다음은 LLM AGENT를 직접 사용해볼 수 있는 간단한 예제 코드입니다:


from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.llms import OpenAI

# OpenAI API 키 설정
openai_api_key = "YOUR_API_KEY"

# 사용할 도구 로드
tools = load_tools(["serpapi", "llm-math"], llm=OpenAI(temperature=0))

# 에이전트 초기화
agent = initialize_agent(tools, OpenAI(temperature=0), agent="zero-shot-react-description", verbose=True)

# 질문하기
agent.run("What is the population of Seoul in South Korea?")

실행 결과:

The population of Seoul, South Korea is approximately 9.7 million people as of 2021.

위 코드에서는 serpapillm-math 도구를 로드하고, OpenAI의 언어 모델을 사용하여 에이전트를 초기화합니다. 그 후 agent.run() 메서드를 통해 질문을 던지면 에이전트가 적절한 도구를 사용하여 답변을 생성합니다.

LLM AGENT에 대해 더 깊이 있게 학습하고 싶다면 다음 자료를 참고하는 것이 좋습니다:

  1. LangChain 공식 문서 - Agents
  2. YouTube 튜토리얼 - LangChain Agents
  3. LangChain 깃허브 레포지토리 - Agents 예제

실습 과제: 위 예제 코드를 참고하여 다른 도구와 질문을 사용해 에이전트를 실행해보세요. 에이전트의 동작 방식과 생성된 답변을 분석해보는 것도 좋습니다.

728x90
반응형
LIST