Langchain OpenAI Agent 살펴보기

2024. 9. 3. 15:34카테고리 없음

 

langchain의 create_openai_functions_agent 함수로 생성된 agent를 실행할 때, prompt에서 강제로 지정하는 parameters가 있다.

각각의 parameter가 어떤 의미를 가지는지, 어떻게 실행이 되는지 살펴보자.

 

prompt (ChatPromptTemplate)
  [system message]           |  "you're helpful assistant."
  [message placeholder]   |  {chat_history}
  [human placeholder]       |  {input}
  [message placeholder]   |  {agent_scratchpad}

 

 

우선, 각 parameters를 살펴보기 전에 개념 정리를 하고 가자.

  • Tool : Agent가 사용할 수 있는 도구
  • Agent : 어떤 Action을 취할 지 결정하는 역할
  • AgentExecutor : 주어진 Agent, Tools를 사용해서 Action을 실행

여기서 중요한 건 Agent와 AgentExecutor는 다른 개념이고, 다른 역할을 수행한다는 것이다.

 

 

보통 openai Function Callings를 사용해서 agent를 만들게 되면 아래와 같다.

agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent, tools)

# [use_case 1] 처음 질문하는 경우
response = agent_executor.invoke({"input": question})

# [use_case 2] 과거 기록을 가지고 질문하는 경우
response = agent_executor.invoke({
	"input": question,
	"chat_history": [
    	HumanMessage(content=question_history),
        AIMessage(content=answer_history)
    ]
})

# response 결과 = {"input": question, "output": answer}

 

L1 : OpenAI Function Calling을 사용해서, Agent Instance 를 생성한다.

따라서 parameter로 주어지는 llm은 반드시 OpanAI Function Calling 과 소통이 가능해야 한다.

 

내부 동작 과정을 살펴보면 다음과 같다.

  1. llm에 tools binding 시킨다.
  2. agent chain 으로 연결한 뒤에 반환한다.
    1. (AgentAction, observation) 묶음이 AIMessage로 {agent_scratchpad} 변수로 가져온다.
    2. prompt를 업데이트 및 할당 시킨다.
    3. 위에서 tools binded llm을 실행시킨다.
    4. Output parsing해서 반환한다.

이런 식으로 중간 과정의 agent / tool 결과물들이 prompt의 {agent_scratchpad}에 passed 된다.

따라서 prompt 내에서는 반드시 존재해야 하며, 없을 경우 assert 된다.

 

하지만 prompt의 {chat_history}는 optional하게 있어도 되고 없어도 된다.

 

 

L2,3 : AgentExecutor를 세팅 및 실행한다.

AgentExecutor 는 Chain을 상속한다.

여기서 invoke를 호출하는데, invoke 함수는 Chain에서 수행이 되며, Chain.invoke는 AgentExecutor._call을 호출해서 연산한다.

 

Chain.invoke

  1. prep_inputs 함수로 메모리에 저장된 messages 등을 세팅한다.
  2. callback_manager를 세팅한다.
  3. _call(inputs, run_manager)를 수행하여 결과를 가져온다.
  4. prep_outputs 함수로 결과를 처리하여 반환한다.

 

AgentExecutor._call

  1. {tool_name: tool}를 세팅한다.
  2. 반복적으로 _should_continue를 수행한다. 시간이나 횟수로 제어한다. (-> _iter_next_step)
    1. output = agent.plan( 중간결과물, 콜백, inputs )
    2. output이 AgentFinish이면 끝내고, AgentAction이면 actions = [output]
    3. actions를 돌면서, _perform_agent_action( tool_dict ~~ )를 수행한다. ( observation = tool.run() )
  3. _return 으로 (출력값, 중간결과물, 콜백)을 반환한다.
반응형