반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

Chapter 6. AI Agents

2023. 11. 16. 02:13 | Posted by 솔웅


반응형

https://www.pinecone.io/learn/series/langchain/langchain-agents/

 

Superpower LLMs with Conversational Agents | Pinecone

Large Language Models (LLMs) are incredibly powerful, yet they lack particular abilities that the “dumbest” computer programs can handle with ease. Logic, calculation, and search are examples of where computers typically excel, but LLMs struggle. Compu

www.pinecone.io

 

Superpower LLMs with Conversational Agents

 

Large Language Models (LLMs) are incredibly powerful, yet they lack particular abilities that the “dumbest” computer programs can handle with ease. Logic, calculation, and search are examples of where computers typically excel, but LLMs struggle.

 

LLM(대형 언어 모델)은 믿을 수 없을 만큼 강력하지만 "가장 멍청한" 컴퓨터 프로그램이 쉽게 처리할 수 있는 특정 기능이 부족합니다. 논리, 계산 및 검색은 일반적으로 컴퓨터가 뛰어나지만 LLM은 어려움을 겪는 예입니다.

Computers can solve incredibly complex math problems, yet if we ask GPT-4 to tell us the answer to 4.1 * 7.9, it fails:

 

컴퓨터는 엄청나게 복잡한 수학 문제를 해결할 수 있지만 GPT-4에게 4.1 * 7.9에 대한 답을 알려달라고 요청하면 실패합니다.

 

Asking GPT-4 to perform a simple calculation often results in an incorrect answer. A simple calculator can perform this same calculation without issue.  GPT-4에 간단한 계산을 요청하면 잘못된 대답이 나오는 경우가 많습니다. 간단한 계산기를 사용하면 문제 없이 동일한 계산을 수행할 수 있습니다.

 

According to a simple calculator, the answer is 19.357, rounded to three decimal places. Isn’t it fascinating that a simple calculator program can do this, but an incredibly sophisticated AI engine fails?

 

간단한 계산기를 사용하면 답은 19.357이며 소수점 이하 세 자리까지 반올림됩니다. 간단한 계산기 프로그램으로 이런 일을 할 수 있는데 믿을 수 없을 정도로 정교한 AI 엔진이 실패한다는 것이 흥미롭지 않나요?

That’s not all. If I ask GPT-4, “How do I use the LLMChain in LangChain?” it struggles again:

 

그게 다가 아닙니다. GPT-4에게 “LangChain에서 LLMChain을 어떻게 사용하나요?”라고 묻는다면, 다시 어려움을 겪습니다.

 

The LangChain spoken about here isn’t the LangChain we know. It’s an old blockchain project. The response is both outdated and full of false information. 여기서 말하는 LangChain은 우리가 알고 있는 LangChain이 아닙니다. 오래된 블록체인 프로젝트입니다. 응답은 오래되었으며 잘못된 정보로 가득 차 있습니다.

 

It’s true that LangChain was a blockchain project [1] [2]. Yet, there didn’t seem to be any “LLMChain” component nor “LANG tokens” — these are both hallucinations.

 

LangChain이 블록체인 프로젝트였던 것은 사실입니다 [1] [2]. 그러나 "LLMChain" 구성 요소나 "LANG 토큰"은 없는 것 같습니다. 둘 다 환상 hallucinations 입니다.

The reason GPT-4 is unable to tell us about LangChain is that it has no connection to the outside world. Its only knowledge is what it captured from its training data, which cuts off in late 2021.

 

GPT-4가 LangChain에 대해 우리에게 말할 수 없는 이유는 LangChain이 외부 세계와 연결되어 있지 않기 때문입니다. 유일한 지식은 훈련 데이터에서 캡처한 내용이며, 이는 2021년 말에 중단됩니다.

With significant weaknesses in today’s generation of LLMs, we must find solutions to these problems. One “suite” of potential solutions comes in the form of “agents”.

 

오늘날 LLM 세대에는 심각한 약점이 있으므로 이러한 문제에 대한 해결책을 찾아야 합니다. 잠재적인 솔루션 중 하나의 "제품군"은 "에이전트" 형태로 제공됩니다.

These agents don’t just solve the problems we saw above but many others. In fact, adding agents has an almost unlimited upside in their LLM-enhancing abilities.

 

이러한 에이전트는 위에서 본 문제뿐만 아니라 다른 많은 문제도 해결합니다. 실제로 에이전트를 추가하면 LLM 강화 능력에 거의 무한한 이점이 있습니다.

In this chapter, we’ll talk about agents. We’ll learn what they are, how they work, and how to use them within the LangChain library to superpower our LLMs.

 

이번 장에서는 에이전트에 대해 이야기하겠습니다. 우리는 LLM이 무엇인지, 어떻게 작동하는지, LLM을 강화하기 위해 LangChain 라이브러리 내에서 사용하는 방법을 배울 것입니다.

 

https://youtu.be/jSP-gSEyVeI?si=SrQq0VwxGeqmYsJN

 

 

What are Agents?

We can think of agents as enabling “tools” for LLMs. Like how a human would use a calculator for maths or perform a Google search for information — agents allow an LLM to do the same thing.

 

에이전트는 LLM을 위한 "도구"를 활성화하는 것으로 생각할 수 있습니다. 인간이 수학을 위해 계산기를 사용하거나 Google에서 정보를 검색하는 것과 마찬가지로 에이전트는 LLM이 동일한 작업을 수행하도록 허용합니다.

 

Agents are LLMs that can use tools like calculators, search, or executing code 에이전트는 계산기, 검색, 코드 실행과 같은 도구를 사용할 수 있는 LLM입니다.

 

 

Using agents, an LLM can write and execute Python code. It can search for information and even query a SQL database.

 

LLM은 에이전트를 사용하여 Python 코드를 작성하고 실행할 수 있습니다. 정보를 검색하고 SQL 데이터베이스에 쿼리할 수도 있습니다.

 

Let’s take a look at a straightforward example of this. We will begin with a “zero-shot” agent (more on this later) that allows our LLM to use a calculator.

 

이에 대한 간단한 예를 살펴보겠습니다. LLM이 계산기를 사용할 수 있게 해주는 "제로샷" 에이전트(나중에 자세히 설명)부터 시작하겠습니다.

 

Agents and Tools

 

To use agents, we require three things: 에이전트를 사용하려면 다음 세 가지가 필요합니다.

  • A base LLM,  기본 LLM,
  • A tool that we will be interacting with,  우리가 상호작용하게 될 도구
  • An agent to control the interaction.  상호작용을 제어하는 에이전트

Let’s start by installing langchain and initializing our base LLM.

 

langchain을 설치하고 기본 LLM을 초기화하는 것부터 시작해 보겠습니다.

 

from langchain import OpenAI

llm = OpenAI(
    openai_api_key="OPENAI_API_KEY",
    temperature=0,
    model_name="text-davinci-003"
)

 

제 로컬에서는 아래와 같이 LLM 을 초기화 했습니다.

 

 

Now to initialize the calculator tool. When initializing tools, we either create a custom tool or load a prebuilt tool. In either case, the “tool” is a utility chain given a tool name and description.

 

이제 계산기 도구를 초기화합니다. 도구를 초기화할 때 사용자 정의 도구를 생성하거나 사전 구축된 도구를 로드합니다. 두 경우 모두 " tool  도구"는 도구 이름과 설명이 지정된 유틸리티 체인입니다.

For example, we could create a new calculator tool from the existing llm_math chain:

 

예를 들어 기존 llm_math 체인에서 새로운 계산기 도구를 만들 수 있습니다.

 

from langchain.chains import LLMMathChain
from langchain.agents import Tool

llm_math = LLMMathChain(llm=llm)

# initialize the math tool
math_tool = Tool(
    name='Calculator',
    func=llm_math.run,
    description='Useful for when you need to answer questions about math.'
)
# when giving tools to LLM, we must pass as list of tools
tools = [math_tool]

 

이 코드는 langchain 패키지에서 수학적 계산을 수행하기 위한 도구를 초기화하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. from langchain.chains import LLMMathChain: langchain 패키지에서 수학적 계산을 수행하는 체인을 가져옵니다.
  2. from langchain.agents import Tool: langchain 패키지에서 도구를 가져옵니다. 도구는 특정 작업을 수행하는 함수와 설명을 함께 가지고 있는 객체입니다.
  3. llm_math = LLMMathChain(llm=llm): 수학적 계산을 수행하는 체인 객체를 초기화합니다.
    • llm=llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
  4. math_tool = Tool(name='Calculator', func=llm_math.run, description='Useful for when you need to answer questions about math.'): 수학 계산을 위한 도구 객체를 초기화합니다.
    • name='Calculator': 도구의 이름을 설정합니다. 여기서는 'Calculator'로 설정되어 있습니다.
    • func=llm_math.run: 도구가 수행할 작업을 지정하는 함수를 설정합니다. 여기서는 llm_math 체인의 run 메서드를 사용합니다.
    • description='Useful for when you need to answer questions about math.': 도구에 대한 설명을 설정합니다. 사용자에게 도구의 용도를 설명하는 데 사용됩니다.
  5. tools = [math_tool]: 도구를 포함하는 리스트를 생성합니다. tools 리스트에는 현재는 하나의 도구인 math_tool이 포함되어 있습니다.

이렇게 생성된 tools 리스트는 나중에 다른 기능이나 에이전트에게 제공되어 활용될 수 있습니다. 예를 들어, 언어 모델에게 특정 도구를 사용하여 수학적 계산을 수행하도록 지시할 때 활용될 수 있습니다.

 

 

tools[0].name, tools[0].description
('Calculator', 'Useful for when you need to answer questions about math.')

 

 

We must follow this process when using custom tools. However, a prebuilt llm_math tool does the same thing. So, we could do the same as above like so:

 

사용자 정의 도구를 사용할 때는 이 프로세스를 따라야 합니다. 그러나 사전 구축된 llm_math 도구도 동일한 작업을 수행합니다. 따라서 위와 동일한 작업을 다음과 같이 수행할 수 있습니다.

 

from langchain.agents import load_tools

tools = load_tools(
    ['llm-math'],
    llm=llm
)
tools[0].name, tools[0].description
('Calculator', 'Useful for when you need to answer questions about math.')

 

 

Naturally, we can only follow this second approach if a prebuilt tool for our use case exists.

 

당연히 우리 사용 사례에 맞게 사전 구축된 도구가 있는 경우에만 이 두 번째 접근 방식을 따를 수 있습니다.

 

We now have the LLM and tools but no agent. To initialize a simple agent, we can do the following:

 

이제 LLM과 도구는 있지만 에이전트는 없습니다. 단순 에이전트를 초기화하려면 다음을 수행할 수 있습니다.

 

from langchain.agents import initialize_agent

zero_shot_agent = initialize_agent(
    agent="zero-shot-react-description",
    tools=tools,
    llm=llm,
    verbose=True,
    max_iterations=3
)

 

이 코드는 langchain 패키지에서 에이전트를 초기화하는 작업을 수행하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. from langchain.agents import initialize_agent: langchain 패키지에서 에이전트를 초기화하는 함수인 initialize_agent를 가져옵니다.
  2. zero_shot_agent = initialize_agent(agent="zero-shot-react-description", tools=tools, llm=llm, verbose=True, max_iterations=3): 에이전트를 초기화합니다.
    • agent="zero-shot-react-description": 초기화할 에이전트의 유형을 지정합니다. 여기서는 'zero-shot-react-description'으로 설정되어 있습니다.
    • tools=tools: 사용할 도구를 지정합니다. 앞서 초기화한 수학 도구(math_tool)를 사용합니다.
    • llm=llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • verbose=True: 초기화 및 실행 과정에서 발생하는 정보를 자세히 출력하도록 설정합니다.
    • max_iterations=3: 에이전트가 수행할 최대 반복 횟수를 설정합니다. 여기서는 최대 3회까지 반복합니다.

이렇게 초기화된 zero_shot_agent는 특정 유형의 에이전트입니다. 여기서는 'zero-shot-react-description' 에이전트로, 언어 모델과 도구를 활용하여 특정 작업을 수행할 수 있습니다. 설정된 도구와 언어 모델을 사용하여 에이전트가 지정된 작업을 수행하도록 요청할 수 있습니다.

 

https://python.langchain.com/docs/modules/agents/agent_types/

 

Agent Types | 🦜️🔗 Langchain

Agents use an LLM to determine which actions to take and in what order.

python.langchain.com

 

The agent used here is a "zero-shot-react-description" agent. Zero-shot means the agent functions on the current action only — it has no memory. It uses the ReAct framework to decide which tool to use, based solely on the tool’s description.

 

여기서 사용된 에이전트는 "zero-shot-react-description" 에이전트입니다. 제로샷은 에이전트가 현재 작업에서만 작동하며 메모리가 없음을 의미합니다. ReAct 프레임워크를 사용하여 도구 설명만을 기반으로 사용할 도구를 결정합니다.

We won’t discuss the ReAct framework in this chapter, but you can think of it as if an LLM could cycle through Reasoning and Action steps. Enabling a multi-step process for identifying answers.

 

이 장에서는 ReAct 프레임워크에 대해 논의하지 않지만 LLM이 추론 및 작업 단계를 순환할 수 있는 것처럼 생각할 수 있습니다. 답변을 식별하기 위한 다단계 프로세스를 활성화합니다.

With our agent initialized, we can begin using it. Let’s try a few prompts and see how the agent responds.

 

에이전트가 초기화되면 사용을 시작할 수 있습니다. 몇 가지 프롬프트를 시도하고 상담원이 어떻게 응답하는지 살펴보겠습니다.

 

zero_shot_agent("what is (4.5*2.1)^2.2?")

 

> Entering new AgentExecutor chain...
 I need to calculate this expression
Action: Calculator
Action Input: (4.5*2.1)^2.2
Observation: Answer: 139.94261298333066

Thought: I now know the final answer
Final Answer: 139.94261298333066

> Finished chain.
{'input': 'what is (4.5*2.1)^2.2?', 'output': '139.94261298333066'}
(4.5*2.1)**2.2
139.94261298333066

 

 

The answer here is correct. Let’s try another:  여기에 대한 대답은 정확합니다. 다른 것을 시도해 봅시다:

 

이렇게 Calculator tool을 사용하지 않고 ChatGPT에 같은 질문을 하면 아래와 같이 엉뚱한 대답을 내 놓는다.

 

이렇듯 LLM 모듈은 계산에 약하고 이를 보완 하기 위해 외부 Tool을 이용하고 이 때 사용하는 것이 agent 임

 

zero_shot_agent("if Mary has four apples and Giorgio brings two and a half apple "
                "boxes (apple box contains eight apples), how many apples do we "
                "have?")
> Entering new AgentExecutor chain...
 I need to figure out how many apples are in the boxes
Action: Calculator
Action Input: 8 * 2.5
Observation: Answer: 20.0

Thought: I need to add the apples Mary has to the apples in the boxes
Action: Calculator
Action Input: 4 + 20.0
Observation: Answer: 24.0

Thought: I now know the final answer
Final Answer: We have 24 apples.

> Finished chain.
{'input': 'if Mary has four apples and Giorgio brings two and a half apple boxes (apple box contains eight apples), how many apples do we have?',
 'output': 'We have 24 apples.'}

 

 

Looks great! But what if we decide to ask a non-math question? What if we ask an easy common knowledge question?

 

멋져요! 하지만 수학이 아닌 질문을 하기로 결정하면 어떻게 될까요? 쉬운 상식 질문을 하면 어떨까요?

 

Note : 똑같은 질문을 Calculator를 사용하지 않고 곧바로 ChatGPT에게 질문을 해 보았다. 이번에는 맞게 계산 하였다. 

 

 

 

Looks great! But what if we decide to ask a non-math question? What if we ask an easy common knowledge question?

 

멋져요! 하지만 수학이 아닌 질문을 하기로 결정하면 어떻게 될까요? 쉬운 상식 질문을 하면 어떨까요?

 

zero_shot_agent("what is the capital of Norway?")
> Entering new AgentExecutor chain...
 I need to look up the answer
Action: Look up
Action Input: Capital of Norway
Observation: Look up is not a valid tool, try another one.
Thought: I need to find the answer using a tool
Action: Calculator
Action Input: N/A

 

 

 

We run into an error. The problem here is that the agent keeps trying to use a tool. Yet, our agent contains only one tool — the calculator.

 

오류가 발생했습니다. 여기서 문제는 에이전트가 계속해서 도구를 사용하려고 한다는 것입니다. 그러나 우리 에이전트에는 계산기라는 단 하나의 도구만 포함되어 있습니다.

 

Fortunately, we can fix this problem by giving our agent more tools! Let’s add a plain and simple LLM tool:

 

다행히 에이전트에게 더 많은 도구를 제공하면 이 문제를 해결할 수 있습니다! 평범하고 간단한 LLM 도구를 추가해 보겠습니다.

 

from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

prompt = PromptTemplate(
    input_variables=["query"],
    template="{query}"
)

llm_chain = LLMChain(llm=llm, prompt=prompt)

# initialize the LLM tool
llm_tool = Tool(
    name='Language Model',
    func=llm_chain.run,
    description='use this tool for general purpose queries and logic'
)

 

이 코드는 langchain 패키지에서 특정 언어 모델을 사용하는 도구를 초기화하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. from langchain.prompts import PromptTemplate: langchain 패키지에서 프롬프트 템플릿을 가져옵니다. 프롬프트 템플릿은 언어 모델에 전달되는 입력을 구성하는 데 사용됩니다.
  2. from langchain.chains import LLMChain: langchain 패키지에서 언어 모델을 사용하는 체인을 가져옵니다.
  3. prompt = PromptTemplate(input_variables=["query"], template="{query}"): 사용자의 질문 또는 쿼리를 받을 수 있는 프롬프트 템플릿을 초기화합니다.
    • input_variables=["query"]: 프롬프트 템플릿에 전달될 입력 변수를 설정합니다. 여기서는 "query"라는 변수를 사용합니다.
    • template="{query}": 프롬프트의 템플릿을 설정합니다. "{query}"는 나중에 이 변수에 대응되는 실제 질문이 들어갈 자리를 나타냅니다.
  4. llm_chain = LLMChain(llm=llm, prompt=prompt): 언어 모델을 사용하는 체인 객체를 초기화합니다.
    • llm=llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • prompt=prompt: 체인이 사용할 프롬프트 템플릿을 설정합니다.
  5. llm_tool = Tool(name='Language Model', func=llm_chain.run, description='use this tool for general purpose queries and logic'): 언어 모델을 사용하는 도구 객체를 초기화합니다.
    • name='Language Model': 도구의 이름을 설정합니다. 여기서는 'Language Model'로 설정되어 있습니다.
    • func=llm_chain.run: 도구가 수행할 작업을 지정하는 함수를 설정합니다. 여기서는 llm_chain 체인의 run 메서드를 사용합니다.
    • description='use this tool for general purpose queries and logic': 도구에 대한 설명을 설정합니다. 사용자에게 언어 모델을 사용하여 일반적인 쿼리와 논리에 사용할 수 있음을 안내하는 데 사용됩니다.

이렇게 초기화된 llm_tool 객체는 나중에 다른 기능이나 에이전트에게 제공되어 활용될 수 있습니다. 사용자의 일반적인 질문이나 쿼리를 언어 모델을 사용하여 처리하는 데 사용될 수 있는 도구입니다.

 

With this, we have a new general-purpose LLM tool. All we do is add it to the tools list and reinitialize the agent:

 

이를 통해 우리는 새로운 범용 LLM 도구를 갖게 되었습니다. 우리가 하는 일은 도구 목록에 이를 추가하고 에이전트를 다시 초기화하는 것뿐입니다.

 

tools.append(llm_tool)

# reinitialize the agent
zero_shot_agent = initialize_agent(
    agent="zero-shot-react-description",
    tools=tools,
    llm=llm,
    verbose=True,
    max_iterations=3
)

 

이 코드는 기존에 초기화한 에이전트(zero_shot_agent)에 새로운 도구(llm_tool)를 추가하고, 추가된 도구를 사용하여 에이전트를 다시 초기화하는 작업을 수행하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. tools.append(llm_tool): 에이전트의 도구 리스트에 새로운 도구인 llm_tool을 추가합니다. tools는 이전에 초기화한 도구 리스트입니다.
  2. zero_shot_agent = initialize_agent(agent="zero-shot-react-description", tools=tools, llm=llm, verbose=True, max_iterations=3): 새로운 도구가 추가된 상태에서 에이전트를 다시 초기화합니다.
    • agent="zero-shot-react-description": 초기화할 에이전트의 유형을 지정합니다. 여기서는 'zero-shot-react-description'으로 설정되어 있습니다.
    • tools=tools: 업데이트된 도구 리스트를 설정합니다. 이 리스트에는 기존 도구와 새로 추가된 llm_tool이 포함되어 있습니다.
    • llm=llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • verbose=True: 초기화 및 실행 과정에서 발생하는 정보를 자세히 출력하도록 설정합니다.
    • max_iterations=3: 에이전트가 수행할 최대 반복 횟수를 설정합니다. 여기서는 최대 3회까지 반복합니다.

이렇게 업데이트된 zero_shot_agent는 새로운 도구가 추가된 상태에서 재설정된 상태를 나타냅니다. 이제 이 에이전트는 언어 모델을 사용하여 일반적인 쿼리 및 논리를 처리하는 도구인 llm_tool을 사용할 수 있습니다.

 

 

Now we can ask the agent questions about both math and general knowledge. Let’s try the following:

 

이제 상담원에게 수학과 일반 지식에 관한 질문을 할 수 있습니다. 다음을 시도해 봅시다:

 

zero_shot_agent("what is the capital of Norway?")
> Entering new AgentExecutor chain...
 I need to find out what the capital of Norway is
Action: Language Model
Action Input: What is the capital of Norway?
Observation: 

The capital of Norway is Oslo.
Thought: I now know the final answer
Final Answer: The capital of Norway is Oslo.

> Finished chain.
{'input': 'what is the capital of Norway?',
 'output': 'The capital of Norway is Oslo.'}

 

로컬 실행 결과는 아래와 같습니다.

 

 

Now we get the correct answer! We can ask the first question:

 

이제 우리는 정답을 얻었습니다! 우리는 첫 번째 질문을 할 수 있습니다:

 

zero_shot_agent("what is (4.5*2.1)^2.2?")
> Entering new AgentExecutor chain...
 I need to calculate this expression
Action: Calculator
Action Input: (4.5*2.1)^2.2
Observation: Answer: 139.94261298333066

Thought: I now know the final answer
Final Answer: 139.94261298333066

> Finished chain.
{'input': 'what is (4.5*2.1)^2.2?', 'output': '139.94261298333066'}

 

 

 

And the agent understands it must refer to the calculator tool, which it does — giving us the correct answer.

 

그리고 상담원은 계산기 도구를 참조해야 한다는 것을 이해하고 있으며 이를 통해 우리에게 정답을 제공합니다.

 

With that complete, we should understand the workflow in designing and prompting agents with different tools. Now let’s move on to the different types of agents and tools available to us.

 

이를 완료하면 다양한 도구를 사용하여 상담원을 설계하고 안내하는 작업 흐름을 이해해야 합니다. 이제 우리가 사용할 수 있는 다양한 유형의 에이전트와 도구를 살펴보겠습니다.

 

Agent Types

 

LangChain offers several types of agents. In this section, we’ll examine a few of the most common.

 

LangChain은 여러 유형의 에이전트를 제공합니다. 이 섹션에서는 가장 일반적인 몇 가지 사항을 살펴보겠습니다.

 

Zero Shot ReAct

We’ll start with the agent we saw earlier, the zero-shot-react-description agent.

 

앞서 본 에이전트인 zero-shot-react-description 에이전트부터 시작하겠습니다.

As described earlier, we use this agent to perform “zero-shot” tasks on some input. That means the agent considers one single interaction with the agent — it will have no memory.

 

앞서 설명한 것처럼 우리는 이 에이전트를 사용하여 일부 입력에 대해 "제로샷" 작업을 수행합니다. 즉, 에이전트는 에이전트와의 단일 상호 작용을 고려하므로 메모리가 없습니다.

Let’s create a tools list to use with the agent. We will include an llm-math tool and a SQL DB tool that we defined here.

 

에이전트와 함께 사용할 도구 목록을 만들어 보겠습니다. 여기서 정의한 llm-math 도구와 SQL DB 도구를 포함하겠습니다.

 

tools = load_tools(
    ["llm-math"], 
    llm=llm
)

# add our custom SQL db tool
tools.append(sql_tool)

 

We initialize the zero-shot-react-description agent like so:

 

다음과 같이 zero-shot-react-description 에이전트를 초기화합니다.

 

from langchain.agents import initialize_agent

zero_shot_agent = initialize_agent(
    agent="zero-shot-react-description", 
    tools=tools, 
    llm=llm,
    verbose=True,
    max_iterations=3,
)

 

To give some context on the SQL DB tool, we will be using it to query a “stocks database” that looks like this:

 

SQL DB 도구에 대한 컨텍스트를 제공하기 위해 이를 사용하여 다음과 같은 "주식 데이터베이스"를 쿼리하겠습니다.

 

 

 

Now we can begin asking questions about this SQL DB and pairing it with calculations via the calculator tool.

 

이제 이 SQL DB에 대해 질문하고 계산기 도구를 통해 이를 계산과 연결할 수 있습니다.

 

result = zero_shot_agent(
    "What is the multiplication of the ratio between stock prices for 'ABC' "
    "and 'XYZ' in January 3rd and the ratio between the same stock prices in "
    "January the 4th?"
)
> Entering new AgentExecutor chain...
 I need to compare the stock prices of 'ABC' and 'XYZ' on two different days
Action: Stock DB
Action Input: Stock prices of 'ABC' and 'XYZ' on January 3rd and January 4th

> Entering new SQLDatabaseChain chain...
Stock prices of 'ABC' and 'XYZ' on January 3rd and January 4th 
SQLQuery: SELECT stock_ticker, price, date FROM stocks WHERE (stock_ticker = 'ABC' OR stock_ticker = 'XYZ') AND (date = '2023-01-03' OR date = '2023-01-04')
SQLResult: [('ABC', 232.0, '2023-01-03'), ('ABC', 225.0, '2023-01-04'), ('XYZ', 798.0, '2023-01-03'), ('XYZ', 795.0, '2023-01-04')]
Answer: The stock prices of 'ABC' and 'XYZ' on January 3rd and January 4th were 232.0 and 798.0 respectively for 'ABC' and 'XYZ' on January 3rd, and 225.0 and 795.0 respectively for 'ABC' and 'XYZ' on January 4th.
> Finished chain.

Observation:  The stock prices of 'ABC' and 'XYZ' on January 3rd and January 4th were 232.0 and 798.0 respectively for 'ABC' and 'XYZ' on January 3rd, and 225.0 and 795.0 respectively for 'ABC' and 'XYZ' on January 4th.
Thought: I need to calculate the ratio between the two stock prices on each day
Action: Calculator
Action Input: 232.0/798.0 and 225.0/795.0
Observation: Answer: 0.2907268170426065
0.2830188679245283

Thought: I need to calculate the multiplication of the two ratios
Action: Calculator
Action Input: 0.2907268170426065 * 0.2830188679245283
Observation: Answer: 0.08228117463469994

Thought:

> Finished chain.

 

이 코드는 langchain 패키지를 사용하여 에이전트를 초기화하고 특정 도구를 추가한 후, 에이전트에 질문을 전달하여 결과를 얻는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. tools = load_tools(["llm-math"], llm=llm): llm-math 도구를 로드하여 초기 도구 리스트에 추가합니다. llm-math 도구는 수학적 계산을 수행하는 도구입니다. load_tools 함수는 해당 도구를 초기화하고 리스트에 추가하는 역할을 합니다.
  2. tools.append(sql_tool): 사용자가 만든 sql_tool 도구를 초기 도구 리스트에 추가합니다. 이 도구는 SQL 데이터베이스에 대한 쿼리를 실행하는 데 사용됩니다.
  3. from langchain.agents import initialize_agent: langchain 패키지에서 에이전트를 초기화하는 함수 initialize_agent를 가져옵니다.
  4. zero_shot_agent = initialize_agent(agent="zero-shot-react-description", tools=tools, llm=llm, verbose=True, max_iterations=3): 에이전트를 초기화합니다.
    • agent="zero-shot-react-description": 초기화할 에이전트의 유형을 지정합니다. 여기서는 'zero-shot-react-description'으로 설정되어 있습니다.
    • tools=tools: 업데이트된 도구 리스트를 설정합니다. 이 리스트에는 llm-math와 사용자 정의 sql_tool이 포함되어 있습니다.
    • llm=llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • verbose=True: 초기화 및 실행 과정에서 발생하는 정보를 자세히 출력하도록 설정합니다.
    • max_iterations=3: 에이전트가 수행할 최대 반복 횟수를 설정합니다. 여기서는 최대 3회까지 반복합니다.
  5. result = zero_shot_agent("What is the multiplication of the ratio between stock prices for 'ABC' and 'XYZ' in January 3rd and the ratio between the same stock prices in January the 4th?"): 에이전트에 특정 질문을 전달하여 결과를 얻습니다. 이 질문은 주식 가격의 비율에 관한 수학적 계산과 SQL 데이터베이스에 대한 쿼리를 포함하고 있습니다.

이렇게 초기화된 에이전트를 사용하면 다양한 도구를 활용하여 다양한 유형의 질문에 대한 답변을 얻을 수 있습니다.

 

Note : Custom SQL db tool인 sql_tool이 정의 돼 있지 않기 때문에 위 소스코드는 로컬에서 돌리면 에러가 납니다.

 

 

 

We can see a lot of output here. At each step, there is a Thought that results in a chosen Action and Action Input. If the Action were to use a tool, then an Observation (the output from the tool) is passed back to the agent.

 

여기서는 많은 결과를 볼 수 있습니다. 각 단계에는 선택한 행동과 행동 입력을 초래하는 생각이 있습니다. 작업이 tool 도구를 사용하는 경우 관찰 Observation  (도구의 출력)이 에이전트에 다시 전달됩니다.

If we look at the prompt being used by the agent, we can see how the LLM decides which tool to use.

 

에이전트가 사용하는 프롬프트를 보면 LLM이 사용할 도구를 어떻게 결정하는지 확인할 수 있습니다.

 

print(zero_shot_agent.agent.llm_chain.prompt.template)
Answer the following questions as best you can. You have access to the following tools:

Calculator: Useful for when you need to answer questions about math.
Stock DB: Useful for when you need to answer questions about stocks and their prices.

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [Calculator, Stock DB]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}

 

prompt는 아래와 같이 로컬에서 확인해 볼 수 있습니다.

 

 

 

We first tell the LLM the tools it can use (Calculator and Stock DB). Following this, an example format is defined; this follows the flow of Question (from the user), Thought, Action, Action Input, Observation — and repeat until reaching the Final Answer.

 

먼저 LLM에 사용할 수 있는 도구(계산기 및 Stock DB)를 알려줍니다. 다음에는 예제 형식이 정의됩니다. 이는 (사용자의) 질문, 생각, 행동, 행동 입력, 관찰의 흐름을 따르며 최종 답변에 도달할 때까지 반복됩니다.

These tools and the thought process separate agents from chains in LangChain.

 

이러한 도구와 사고 프로세스는 LangChain의 체인에서 에이전트를 분리합니다.

Whereas a chain defines an immediate input/output process, the logic of agents allows a step-by-step thought process. The advantage of this step-by-step process is that the LLM can work through multiple reasoning steps or tools to produce a better answer.

 

체인이 즉각적인 입력/출력 프로세스를 정의하는 반면, 에이전트의 논리는 단계별 사고 프로세스를 허용합니다. 이 단계별 프로세스의 장점은 LLM이 여러 추론 단계나 도구를 통해 작업하여 더 나은 답변을 생성할 수 있다는 것입니다.

There is still one part of the prompt we still need to discuss. The final line is "Thought:{agent_scratchpad}".

 

아직 논의해야 할 프롬프트의 한 부분이 있습니다. 마지막 줄은 "Thought:{agent_scratchpad}"입니다.

The agent_scratchpad is where we add every thought or action the agent has already performed. All thoughts and actions (within the current agent executor chain) can then be accessed by the next thought-action-observation loop, enabling continuity in agent actions.

 

Agent_scratchpad는 에이전트가 이미 수행한 모든 생각이나 행동을 추가하는 곳입니다. 그러면 (현재 에이전트 실행자 체인 내의) 모든 생각과 행동은 다음 생각-행동-관찰 루프를 통해 액세스될 수 있으므로 에이전트 작업의 연속성이 가능해집니다.

 

Conversational ReAct

The zero-shot agent works well but lacks conversational memory. This lack of memory can be problematic for chatbot-type use cases that need to remember previous interactions in a conversation.

 

제로샷 에이전트는 잘 작동하지만 대화 메모리가 부족합니다. 이러한 메모리 부족은 대화에서 이전 상호 작용을 기억해야 하는 챗봇 유형 사용 사례에 문제가 될 수 있습니다.

Fortunately, we can use the conversational-react-description agent to remember interactions. We can think of this agent as the same as our previous Zero Shot ReAct agent, but with conversational memory.

 

다행스럽게도 대화형 반응 설명 에이전트를 사용하여 상호작용을 기억할 수 있습니다. 이 에이전트는 이전 Zero Shot ReAct 에이전트와 동일하지만 대화 메모리가 있다고 생각할 수 있습니다.

To initialize the agent, we first need to initialize the memory we’d like to use. We will use the simple ConversationBufferMemory.

 

에이전트를 초기화하려면 먼저 사용하려는 메모리를 초기화해야 합니다. 간단한 ConversationBufferMemory를 사용하겠습니다.

 

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")

 

We pass this to the memory parameter when initializing our agent:

 

에이전트를 초기화할 때 이것을 memory 매개변수에 전달합니다.

 

conversational_agent = initialize_agent(
    agent='conversational-react-description', 
    tools=tools, 
    llm=llm,
    verbose=True,
    max_iterations=3,
    memory=memory,
)

 

이 코드는 langchain 패키지에서 대화형 에이전트를 초기화하고 대화 기록을 저장하기 위한 메모리를 설정하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. from langchain.memory import ConversationBufferMemory: 대화 기록을 저장하기 위한 메모리 클래스인 ConversationBufferMemory를 가져옵니다.
  2. memory = ConversationBufferMemory(memory_key="chat_history"): chat_history라는 키를 사용하여 대화 기록을 저장하는 메모리를 초기화합니다. 이 메모리는 나중에 에이전트가 대화 기록을 사용하여 대화를 이해하고 지속할 수 있도록 도와줍니다.
  3. conversational_agent = initialize_agent(agent='conversational-react-description', tools=tools, llm=llm, verbose=True, max_iterations=3, memory=memory): 대화형 에이전트를 초기화합니다.
    • agent='conversational-react-description': 초기화할 에이전트의 유형을 지정합니다. 여기서는 'conversational-react-description'으로 설정되어 있습니다.
    • tools=tools: 업데이트된 도구 리스트를 설정합니다. 이 리스트에는 llm-math, 사용자 정의 sql_tool, 그리고 앞서 초기화한 대화 모델 도구 등이 포함됩니다.
    • llm=llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • verbose=True: 초기화 및 실행 과정에서 발생하는 정보를 자세히 출력하도록 설정합니다.
    • max_iterations=3: 에이전트가 수행할 최대 반복 횟수를 설정합니다. 여기서는 최대 3회까지 반복합니다.
    • memory=memory: 에이전트에 대화 기록을 저장하는 데 사용할 메모리를 설정합니다. 여기서는 ConversationBufferMemory로 초기화한 memory 변수를 사용합니다.

이렇게 초기화된 conversational_agent는 대화 기록을 저장하고 활용하여 더 자연스럽게 대화할 수 있는 기능을 가진 에이전트입니다.

 

 

If we run this agent with a similar question, we should see a similar process followed as before:

 

비슷한 질문으로 이 에이전트를 실행하면 이전과 유사한 프로세스가 뒤따르는 것을 볼 수 있습니다.

 

result = conversational_agent(
    "Please provide me the stock prices for ABC on January the 1st"
)
> Entering new AgentExecutor chain...

Thought: Do I need to use a tool? Yes
Action: Stock DB
Action Input: ABC on January the 1st

> Entering new SQLDatabaseChain chain...
ABC on January the 1st 
SQLQuery: SELECT price FROM stocks WHERE stock_ticker = 'ABC' AND date = '2023-01-01'
SQLResult: [(200.0,)]
Answer: The price of ABC on January the 1st was 200.0.
> Finished chain.

Observation:  The price of ABC on January the 1st was 200.0.
Thought: Do I need to use a tool? No
AI: Is there anything else I can help you with?

> Finished chain.

 

로컬에서 돌렸더니 이것을 Calculator 도구를 사용해 버리네요. 아마 SQL DB 도구는 정의가 안 돼 있기 때문에 유일하게 정의 돼 있는 Calculator 도구를 사용하나 봅니다. 그런데 ABC의 1월 1일 주가를 800불이라고 대답해 버리네요. 무엇을 근거로 했는지 모르겠습니다. 아마 Hallucination 현상인 것 같습니다.

 

 

So far, this looks very similar to our last zero-shot agent. However, unlike our zero-shot agent, we can now ask follow-up questions. Let’s ask about the stock price for XYZ on the same date without specifying January 1st.

 

지금까지 이는 마지막 제로샷 에이전트와 매우 유사해 보입니다. 하지만 제로샷 에이전트와 달리 이제 후속 질문을 할 수 있습니다. 1월 1일을 지정하지 않고 같은 날짜의 XYZ 주가에 대해 물어보겠습니다.

 

result = conversational_agent(
    "What are the stock prices for XYZ on the same day?"
)
> Entering new AgentExecutor chain...

Thought: Do I need to use a tool? Yes
Action: Stock DB
Action Input: Stock prices for XYZ on January 1st

> Entering new SQLDatabaseChain chain...
Stock prices for XYZ on January 1st 
SQLQuery: SELECT price FROM stocks WHERE stock_ticker = 'XYZ' AND date = '2023-01-01'
SQLResult: [(810.0,)]
Answer: The stock price for XYZ on January 1st was 810.0.
> Finished chain.

Observation:  The stock price for XYZ on January 1st was 810.0.
Thought: Do I need to use a tool? No
AI: Is there anything else I can help you with?

> Finished chain.

 

로컬에서 돌리니까 신택스 에러가 나 버리네요.

 

XYZ stock price는 100 불 이라고 설정해 놓고 뭔가 valid 한 numerical expression이 아니라면서 신택스 에러를 내네요.

 

어쨌든 이번 섹터에서는 ConversationBufferMemory를 사용해서 이전 질문 답변 히스토리를 기억해서 대화를 이어가는 방법을 배우는 거니까 그냥 그렇게 알고 넘어 가겠습니다. 교재에 나오는 예제에서는 이전 대화를 잘 기억해서 on the same day를 1월 1일로 알아 먹고 이에 맞는 SQL 쿼리를 작성했습니다.

 

We can see in the first Action Input that the agent is looking for "Stock prices for XYZ on January 1st". It knows we are looking for January 1st because we asked for this date in our previous interaction.

 

첫 번째 작업 입력에서 에이전트가 "1월 1일 XYZ의 주가"를 찾고 있음을 확인할 수 있습니다. 이전 상호작용에서 이 날짜를 요청했기 때문에 1월 1일을 찾고 있다는 것을 알고 있습니다.

How can it do this? We can take a look at the prompt template to find out:

 

어떻게 이런 일을 할 수 있나요? 프롬프트 템플릿을 살펴보면 다음 사항을 확인할 수 있습니다.

 

print(conversational_agent.agent.llm_chain.prompt.template)
Assistant is a large language model trained by OpenAI.

Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.

Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.

Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.

TOOLS:
------

Assistant has access to the following tools:

> Calculator: Useful for when you need to answer questions about math.
> Stock DB: Useful for when you need to answer questions about stocks and their prices.

To use a tool, please use the following format:

```
Thought: Do I need to use a tool? Yes
Action: the action to take, should be one of [Calculator, Stock DB]
Action Input: the input to the action
Observation: the result of the action
```

When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:

```
Thought: Do I need to use a tool? No
AI: [your response here]
```

Begin!

Previous conversation history:
{chat_history}

New input: {input}
{agent_scratchpad}

 

프롬프트를 확인하는 작업은 로컬에서도 잘 작동합니다.

 

 

이 Agent Type들은 각각 그 기능에 맞는 Prompt를 탬플릿화 해서 제공하는 방법으로 원하는 기능을 취하는 것 같습니다.

 

We have a much larger instruction setup at the start of the prompt, but most important are the two lines near the end of the prompt:

 

프롬프트 시작 부분에는 훨씬 더 큰 명령 설정이 있지만 가장 중요한 것은 프롬프트 끝 부분에 있는 두 줄입니다.

Previous conversation history: {chat_history}    이전 대화 기록: {chat_history}

Here is where we add all previous interactions to the prompt. Within this space will be the information that we asked "Please provide me the stock prices for ABC on January the 1st" — allowing the agent to understand that our follow-up question refers to the same date.

 

여기에서 이전의 모든 상호 작용을 프롬프트에 추가합니다. 이 공간에는 "1월 1일 ABC의 주가를 알려주십시오"라고 요청한 정보가 있습니다. 이를 통해 상담원은 후속 질문이 동일한 날짜를 참조한다는 것을 이해할 수 있습니다.

It’s worth noting that the conversational ReAct agent is designed for conversation and struggles more than the zero-shot agent when combining multiple complex steps. We can see this if we ask the agent to answer our earlier question:

 

대화형 ReAct 에이전트는 대화용으로 설계되었으며 여러 복잡한 단계를 결합할 때 제로샷 에이전트보다 더 많은 어려움을 겪는다는 점은 주목할 가치가 있습니다. 상담원에게 이전 질문에 대한 답변을 요청하면 이를 확인할 수 있습니다.

 

result = conversational_agent(
    "What is the multiplication of the ratio of the prices of stocks 'ABC' "
    "and 'XYZ' in January 3rd and the ratio of the same prices of the same "
    "stocks in January the 4th?"
)


> Entering new AgentExecutor chain...
Thought: Do I need to use a tool? Yes
Action: Stock DB
Action Input: Get the ratio of the prices of stocks 'ABC' and 'XYZ' in January 3rd and the ratio of the same prices of the same stocks in January the 4th

> Entering new SQLDatabaseChain chain...
Get the ratio of the prices of stocks 'ABC' and 'XYZ' in January 3rd and the ratio of the same prices of the same stocks in January the 4th 
SQLQuery: SELECT (SELECT price FROM stocks WHERE stock_ticker = 'ABC' AND date = '2023-01-03') / (SELECT price FROM stocks WHERE stock_ticker = 'XYZ' AND date = '2023-01-03') AS ratio_jan_3, (SELECT price FROM stocks WHERE stock_ticker = 'ABC' AND date = '2023-01-04') / (SELECT price FROM stocks WHERE stock_ticker = 'XYZ' AND date = '2023-01-04') AS ratio_jan_4 FROM stocks LIMIT 5;
SQLResult: [(0.2907268170426065, 0.2830188679245283), (0.2907268170426065, 0.2830188679245283), (0.2907268170426065, 0.2830188679245283), (0.2907268170426065, 0.2830188679245283), (0.2907268170426065, 0.2830188679245283)]
Answer: The ratio of the prices of stocks 'ABC' and 'XYZ' in January 3rd is 0.2907268170426065 and the ratio of the same prices of the same stocks in January the 4th is 0.2830188679245283.
> Finished chain.

Observation:  The ratio of the prices of stocks 'ABC' and 'XYZ' in January 3rd is 0.2907268170426065 and the ratio of the same prices of the same stocks in January the 4th is 0.2830188679245283.
Thought: Do I need to use a tool? No
AI: The answer is 0.4444444444444444. Is there anything else I can help you with?

> Finished chain.
Spent a total of 2518 tokens

 

질문을 잘 이해하고 거기에 맞는 SQL 쿼리를 잘 작성한 것 같습니다.

 

참고로 로컬에서 돌려도 SQL DB 툴 없이 Calculator로 자기가 주가를 만들어 내서 답을 내 줍니다.

 

Langchain 에서 제공하는 프롬프트에는 확실하지 않으면 모른다고 대답해라 라는 부분이 없기 때문에 ChatGPT가 그냥 알아서 주가를 만들어 내고 그 값을 기반으로 질문에 답하고 있습니다.

 

With this, the agent still manages to solve the question but uses a more complex approach of pure SQL rather than relying on more straightforward SQL and the calculator tool.

 

이를 통해 에이전트는 여전히 문제를 해결하지만 더 간단한 SQL 및 계산기 도구에 의존하기보다는 순수 SQL의 더 복잡한 접근 방식을 사용합니다.

 

ReAct Docstore

Another common agent is the react-docstore agent. As before, it uses the ReAct methodology, but now it is explicitly built for information search and lookup using a LangChain docstore.

 

또 다른 일반적인 에이전트는 React-docstore 에이전트입니다. 이전과 마찬가지로 ReAct 방법론을 사용하지만 이제는 LangChain docstores  를 사용하여 정보 검색 및 조회를 위해 명시적으로 구축되었습니다.

LangChain docstores allow us to store and retrieve information using traditional retrieval methods. One of these docstores is Wikipedia, which gives us access to the information on the site.

 

LangChain docstores  를 사용하면 전통적인 검색 방법을 사용하여 정보를 저장하고 검색할 수 있습니다. 이러한 문서 저장소 중 하나는 Wikipedia이며, 이를 통해 사이트의 정보에 액세스할 수 있습니다.

We will implement this agent using two docstore methods — Search and Lookup. With Search, our agent will search for a relevant article, and with Lookup, the agent will find the relevant chunk of information within the retrieved article. To initialize these two tools, we do:

 

Search 및 Lookup이라는 두 가지 Docstore 방법을 사용하여 이 에이전트를 구현합니다. 검색을 통해 에이전트는 관련 기사를 검색하고, Lookup을 통해 에이전트는 검색된 기사 내에서 관련 정보 덩어리를 찾습니다. 이 두 도구를 초기화하려면 다음을 수행합니다.

 

from langchain import Wikipedia
from langchain.agents.react.base import DocstoreExplorer

docstore=DocstoreExplorer(Wikipedia())
tools = [
    Tool(
        name="Search",
        func=docstore.search,
        description='search wikipedia'
    ),
    Tool(
        name="Lookup",
        func=docstore.lookup,
        description='lookup a term in wikipedia'
    )
]

 

Now initialize the agent: 이제 에이전트를 초기화합니다.

 

docstore_agent = initialize_agent(
    tools, 
    llm, 
    agent="react-docstore", 
    verbose=True,
    max_iterations=3
)

 

이 코드는 langchain 패키지를 사용하여 Wikipedia 문서 스토어를 활용하는 에이전트를 초기화하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. from langchain import Wikipedia: langchain 패키지에서 Wikipedia 문서 스토어를 가져옵니다.
  2. from langchain.agents.react.base import DocstoreExplorer: Wikipedia 문서 스토어를 탐색하기 위한 기본 도구를 가져옵니다.
  3. docstore = DocstoreExplorer(Wikipedia()): Wikipedia 문서 스토어를 초기화합니다. Wikipedia()는 Wikipedia의 내용을 검색하고 가져오기 위한 도구를 제공합니다.
  4. tools = [...]: docstore에서 제공하는 검색 및 조회 기능을 사용하는 두 가지 도구를 초기화합니다.
    • Tool(name="Search", func=docstore.search, description='search wikipedia'): Wikipedia에서 검색을 수행하는 도구입니다.
    • Tool(name="Lookup", func=docstore.lookup, description='lookup a term in wikipedia'): Wikipedia에서 용어를 조회하는 도구입니다.
  5. docstore_agent = initialize_agent(tools, llm, agent="react-docstore", verbose=True, max_iterations=3): Wikipedia 문서 스토어를 사용하는 에이전트를 초기화합니다.
    • tools: 사용할 도구 리스트를 설정합니다. 여기서는 Wikipedia 문서 스토어를 활용하는 검색 및 조회 도구가 포함됩니다.
    • llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • agent="react-docstore": 초기화할 에이전트의 유형을 지정합니다. 여기서는 'react-docstore'으로 설정되어 있습니다.
    • verbose=True: 초기화 및 실행 과정에서 발생하는 정보를 자세히 출력하도록 설정합니다.
    • max_iterations=3: 에이전트가 수행할 최대 반복 횟수를 설정합니다. 여기서는 최대 3회까지 반복합니다.

이렇게 초기화된 docstore_agent는 Wikipedia 문서 스토어를 활용하여 검색 및 조회를 수행할 수 있는 에이전트입니다.

 

 

Let’s try the following: 다음을 시도해 봅시다:

 

docstore_agent("What were Archimedes' last words?")
> Entering new AgentExecutor chain...
Thought: I need to search Archimedes and find his last words.
Action: Search[Archimedes]
Observation: Archimedes of Syracuse (; c. 287 – c. 212 BC) was a Greek mathematician, physicist, engineer...
Thought: The paragraph does not mention Archimedes' last words. I need to look up "last words".
Action: Lookup[last words]
Observation: (Result 1/1) Plutarch (45–119 AD) wrote in his Parallel Lives that Archimedes was related to King Hiero...
Thought: The last words attributed to Archimedes are "Do not disturb my circles", so the answer is "Do not disturb my circles".
Action: Finish["Do not disturb my circles"]

> Finished chain.
{'input': "What were Archimedes' last words?",
 'output': '"Do not disturb my circles"'}

 

로컬에서 돌리면 아래와 같이 iteration limit이나 time limit에 걸려서 stop 합니다. 

어쨌든 위키피디아에서 질문한 내용을 검색해서 답을 찾으려고 시도는 하네요.

 

 

The prompt for this agent is very long, so we’ll show a shortened version. All it contains are several examples of how this agent should use the Search and Lookup tools:

 

이 에이전트에 대한 프롬프트는 매우 길기 때문에 단축 버전을 표시하겠습니다. 여기에는 이 에이전트가 검색 및 조회 도구를 어떻게 사용해야 하는지에 대한 몇 가지 예가 포함되어 있습니다.

 

Question: What is the elevation range for the area that the eastern sector of the Colorado orogeny extends into?

Thought: I need to search Colorado orogeny, find the area that the eastern sector of the Colorado orogeny extends into, then find the elevation range of the area.
Action: Search[Colorado orogeny]
Observation: The Colorado orogeny was an episode of mountain building (an orogeny) in Colorado and surrounding areas.

Thought: It does not mention the eastern sector. So I need to look up eastern sector.
Action: Lookup[eastern sector]
Observation: (Result 1 / 1) The eastern sector extends into the High Plains and is called the Central Plains orogeny.

Thought: The eastern sector of Colorado orogeny extends into the High Plains. So I need to search High Plains and find its elevation range.
Action: Search[High Plains]
Observation: High Plains refers to one of two distinct land regions

Thought: I need to instead search High Plains (United States).
Action: Search[High Plains (United States)]
Observation: The High Plains are a subregion of the Great Plains. From east to west, the High Plains rise in elevation from around 1,800 to 7,000 ft (550 to 2,130 m).[3]

Thought: High Plains rise in elevation from around 1,800 to 7,000 ft, so the answer is 1,800 to 7,000 ft.
Action: Finish[1,800 to 7,000 ft]

 

The prompt contains several examples in a similar format. At the end of the prompt, we see:

 

프롬프트에는 비슷한 형식의 여러 예가 포함되어 있습니다. 프롬프트가 끝나면 다음이 표시됩니다.

 

Question: {input}
{agent_scratchpad}

 

As before, we have an {input} to pass in the most recent user query and the {agent_scratchpad} to keep track of previous thoughts and actions.

 

이전과 마찬가지로 가장 최근의 사용자 쿼리를 전달하기 위한 {input}과 이전 생각과 행동을 추적하기 한 {agent_scratchpad}가 있습니다.

Unlike our conversational agent, there is no {chat_history} input. That means that we are using another zero-shot agent.

 

대화형 에이전트와 달리 {chat_history} 입력이 없습니다. 이는 우리가 또 다른 제로샷 에이전트를 사용하고 있음을 의미합니다.

 

Note : 프롬프트가 길어서 교재에서는 일부만 보여 줬는데. 저는 로컬에서 프롬프트를 전부 출력해 봤습니다.

 

 

전체 프롬프트 내용은 2023년 11월 15일 현재 아래와 같습니다.

 

Question: What is the elevation range for the area that the eastern sector of the Colorado orogeny extends into?
Thought: I need to search Colorado orogeny, find the area that the eastern sector of the Colorado orogeny extends into, then find the elevation range of the area.
Action: Search[Colorado orogeny]
Observation: The Colorado orogeny was an episode of mountain building (an orogeny) in Colorado and surrounding areas.
Thought: It does not mention the eastern sector. So I need to look up eastern sector.
Action: Lookup[eastern sector]
Observation: (Result 1 / 1) The eastern sector extends into the High Plains and is called the Central Plains orogeny.
Thought: The eastern sector of Colorado orogeny extends into the High Plains. So I need to search High Plains and find its elevation range.
Action: Search[High Plains]
Observation: High Plains refers to one of two distinct land regions
Thought: I need to instead search High Plains (United States).
Action: Search[High Plains (United States)]
Observation: The High Plains are a subregion of the Great Plains. From east to west, the High Plains rise in elevation from around 1,800 to 7,000 ft (550 to 2,130 m).[3]
Thought: High Plains rise in elevation from around 1,800 to 7,000 ft, so the answer is 1,800 to 7,000 ft.
Action: Finish[1,800 to 7,000 ft]

Question: Musician and satirist Allie Goertz wrote a song about the "The Simpsons" character Milhouse, who Matt Groening named after who?
Thought: The question simplifies to "The Simpsons" character Milhouse is named after who. I only need to search Milhouse and find who it is named after.
Action: Search[Milhouse]
Observation: Milhouse Mussolini Van Houten is a recurring character in the Fox animated television series The Simpsons voiced by Pamela Hayden and created by Matt Groening.
Thought: The paragraph does not tell who Milhouse is named after, maybe I can look up "named after".
Action: Lookup[named after]
Observation: (Result 1 / 1) Milhouse was named after U.S. president Richard Nixon, whose middle name was Milhous.
Thought: Milhouse was named after U.S. president Richard Nixon, so the answer is Richard Nixon.
Action: Finish[Richard Nixon]

Question: Which documentary is about Finnish rock groups, Adam Clayton Powell or The Saimaa Gesture?
Thought: I need to search Adam Clayton Powell and The Saimaa Gesture, and find which documentary is about Finnish rock groups.
Action: Search[Adam Clayton Powell]
Observation: Could not find [Adam Clayton Powell]. Similar: [’Adam Clayton Powell III’, ’Seventh Avenue (Manhattan)’, ’Adam Clayton Powell Jr. State Office Building’, ’Isabel Washington Powell’, ’Adam Powell’, ’Adam Clayton Powell (film)’, ’Giancarlo Esposito’].
Thought: To find the documentary, I can search Adam Clayton Powell (film).
Action: Search[Adam Clayton Powell (film)]
Observation: Adam Clayton Powell is a 1989 American documentary film directed by Richard Kilberg. The film is about the rise and fall of influential African-American politician Adam Clayton Powell Jr.[3][4] It was later aired as part of the PBS series The American Experience.
Thought: Adam Clayton Powell (film) is a documentary about an African-American politician, not Finnish rock groups. So the documentary about Finnish rock groups must instead be The Saimaa Gesture.
Action: Finish[The Saimaa Gesture]

Question: What profession does Nicholas Ray and Elia Kazan have in common?
Thought: I need to search Nicholas Ray and Elia Kazan, find their professions, then find the profession they have in common.
Action: Search[Nicholas Ray]
Observation: Nicholas Ray (born Raymond Nicholas Kienzle Jr., August 7, 1911 - June 16, 1979) was an American film director, screenwriter, and actor best known for the 1955 film Rebel Without a Cause.
Thought: Professions of Nicholas Ray are director, screenwriter, and actor. I need to search Elia Kazan next and find his professions.
Action: Search[Elia Kazan]
Observation: Elia Kazan was an American film and theatre director, producer, screenwriter and actor.
Thought: Professions of Elia Kazan are director, producer, screenwriter, and actor. So profession Nicholas Ray and Elia Kazan have in common is director, screenwriter, and actor.
Action: Finish[director, screenwriter, actor]

Question: Which magazine was started first Arthur’s Magazine or First for Women?
Thought: I need to search Arthur’s Magazine and First for Women, and find which was started first.
Action: Search[Arthur’s Magazine]
Observation: Arthur’s Magazine (1844-1846) was an American literary periodical published in Philadelphia in the 19th century.
Thought: Arthur’s Magazine was started in 1844. I need to search First for Women next.
Action: Search[First for Women]
Observation: First for Women is a woman’s magazine published by Bauer Media Group in the USA.[1] The magazine was started in 1989.
Thought: First for Women was started in 1989. 1844 (Arthur’s Magazine) < 1989 (First for Women), so Arthur’s Magazine was started first.
Action: Finish[Arthur’s Magazine]

Question: Were Pavel Urysohn and Leonid Levin known for the same type of work?
Thought: I need to search Pavel Urysohn and Leonid Levin, find their types of work, then find if they are the same.
Action: Search[Pavel Urysohn]
Observation: Pavel Samuilovich Urysohn (February 3, 1898 - August 17, 1924) was a Soviet mathematician who is best known for his contributions in dimension theory.
Thought: Pavel Urysohn is a mathematician. I need to search Leonid Levin next and find its type of work.
Action: Search[Leonid Levin]
Observation: Leonid Anatolievich Levin is a Soviet-American mathematician and computer scientist.
Thought: Leonid Levin is a mathematician and computer scientist. So Pavel Urysohn and Leonid Levin have the same type of work.
Action: Finish[yes]


Question: {input}
{agent_scratchpad}

 

 

Let’s look at one final agent — the self-ask-with-search agent. This agent is the first you should consider when connecting an LLM with a search engine.

 

최종 에이전트인 검색을 통한 자체 질문 에이전트를 살펴보겠습니다. 이 에이전트는 LLM을 검색 엔진에 연결할 때 가장 먼저 고려해야 할 에이전트입니다.

The agent will perform searches and ask follow-up questions as often as required to get a final answer. We initialize the agent like so:

 

상담원은 최종 답변을 얻기 위해 필요한 만큼 자주 검색을 수행하고 후속 질문을 합니다. 다음과 같이 에이전트를 초기화합니다.

 

from langchain import SerpAPIWrapper

# initialize the search chain
search = SerpAPIWrapper(serpapi_api_key='serp_api_key')

# create a search tool
tools = [
    Tool(
        name="Intermediate Answer",
        func=search.run,
        description='google search'
    )
]

# initialize the search enabled agent
self_ask_with_search = initialize_agent(
    tools,
    llm,
    agent="self-ask-with-search",
    verbose=True
)

 

이 코드는 langchain 패키지를 사용하여 SerpAPI를 활용하여 구글 검색을 수행하는 에이전트를 초기화하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다:

  1. from langchain import SerpAPIWrapper: langchain 패키지에서 SerpAPI를 활용한 검색 기능을 제공하는 SerpAPIWrapper를 가져옵니다.
  2. search = SerpAPIWrapper(serpapi_api_key='serp_api_key'): SerpAPIWrapper를 초기화하고, API 키를 설정하여 검색 객체를 생성합니다. 여기서 'serp_api_key'는 실제 SerpAPI의 API 키로 대체되어야 합니다.
  3. tools = [...]: SerpAPI 검색을 수행하는 도구를 초기화합니다.
    • Tool(name="Intermediate Answer", func=search.run, description='google search'): Google 검색을 수행하는 도구입니다.
  4. self_ask_with_search = initialize_agent(tools, llm, agent="self-ask-with-search", verbose=True): 검색 기능이 포함된 에이전트를 초기화합니다.
    • tools: 사용할 도구 리스트를 설정합니다. 여기서는 SerpAPI를 통한 Google 검색이 가능한 도구가 포함됩니다.
    • llm: 사용할 언어 모델을 설정합니다. 여기서는 llm 변수에 저장된 대화형 OpenAI 언어 모델을 사용합니다.
    • agent="self-ask-with-search": 초기화할 에이전트의 유형을 지정합니다. 여기서는 'self-ask-with-search'로 설정되어 있습니다.
    • verbose=True: 초기화 및 실행 과정에서 발생하는 정보를 자세히 출력하도록 설정합니다.

이렇게 초기화된 self_ask_with_search 에이전트는 SerpAPI를 활용하여 Google 검색을 수행할 수 있는 도구를 가지고 있습니다. 이 에이전트를 사용하면 특정 질문에 대한 중간 응답을 검색하여 얻을 수 있습니다.

 

Now let’s ask a question requiring multiple searches and “self ask” steps.

 

이제 여러 검색과 " self ask " 단계가 필요한 질문을 해보겠습니다.

 

self_ask_with_search(
    "who lived longer; Plato, Socrates, or Aristotle?"
)
> Entering new AgentExecutor chain...
 Yes.
Follow up: How old was Plato when he died?
Intermediate answer: eighty
Follow up: How old was Socrates when he died?
Intermediate answer: approximately 71
Follow up: How old was Aristotle when he died?
Intermediate answer: 62 years
So the final answer is: Plato

> Finished chain.
{'input': 'who lived longer; Plato, Socrates, or Aristotle?',
 'output': 'Plato'}

 

질문은 플라톤과 소크라테스 그리고 아리스토텔레스 중 누가 가장 오래 살았는가 입니다.

SerpAPI는 구글 검색을 도와 주는 API 인 것 같습니다. 이곳에 가입해서 API key를 얻어서 로컬에서 돌렸습니다.

 

 

 

로컬에서는 질문을 잘 못 이해해서 구글 검색할 때 질문을 When did someone die? 로 했네요. 교재에서는 How old was when some one died? 라고 제대로 했는데 말이죠.

어쨌든 SERPAPI를 사용하는 것과 스스로 질문을 만들어 내는 동작은 잘 하는 것 같습니다.

 

질문에서 who를 Who로 바꾸어 보았습니다.

 

 

이랬더니 답변이 제대로 나옵니다. w를 W로 바꾸었을 뿐인데 ChatGPT는 다르게 해석하네요.

하여간 이 기능은 로컬에서도 제대로 작동하는 것을 확인 했습니다.

 

재미 삼아 하나 더 질문 해 봤습니다.

 

 

올해 5월에 83세의 나이로 죽은 Tina Turner의 정보도 구글 검색으로 찾았네요.

 

We can see the multi-step process of the agent. It performs multiple follow-up questions to hone in on the final answer.

 

에이전트의 다단계 프로세스를 볼 수 있습니다. 최종 답을 찾기 위해 여러 가지 후속 질문을 수행합니다.

That’s it for this chapter on LangChain agents. As you have undoubtedly noticed, agents cover a vast scope of tooling in LangChain. We have covered much of the essentials, but there is much more that we could talk about.

 

LangChain 에이전트에 대한 이번 장의 내용은 이것입니다. 의심할 바 없이 아시다시피 에이전트는 LangChain에서 광범위한 도구를 다루고 있습니다. 우리는 필수적인 내용을 많이 다루었지만, 이야기할 수 있는 내용이 훨씬 더 많습니다.

The transformative potential of agents is a monumental leap forward for Large Language Models (LLMs), and it is only a matter of time before the term “LLM agents” becomes synonymous with LLMs themselves.

 

에이전트의 혁신적인 잠재력은 LLM(대형 언어 모델)의 획기적인 도약이며 "LLM 에이전트"라는 용어가 LLM 자체와 동의어가 되는 것은 시간 문제일 뿐입니다.

By empowering LLMs to utilize tools and navigate complex, multi-step thought processes within these agent frameworks, we are venturing into a mind-bogglingly huge realm of AI-driven opportunities.

 

LLM이 도구를 활용하고 이러한 에이전트 프레임워크 내에서 복잡하고 다단계 사고 프로세스를 탐색할 수 있도록 지원함으로써 우리는 놀라울 정도로 거대한 AI 기반 기회 영역으로 모험을 떠나고 있습니다.

 

References

[1] Langchain.io (2019), Wayback Machine

[2] Jun-hang Lee, Mother of Language Slides (2018), SlideShare

 

 

 

 

반응형