Langchain에서 agent를 생성할 때 AgentType을 선택할 수 있었는데 AgentType들이 어떤것이 있는지 확인해보려고 한다.
from langchain.agents import initialize_agent, Tool
from langchain.agents.agent_types import AgentType
from langchain_community.chat_models import ChatOpenAI
agent = initialize_agent(
tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
AgentType
확인해보니 deprecated되었다고 한다. 그렇다면 어떤걸 사용하는게 좋을까?
@deprecated("0.1.0",
message=AGENT_DEPRECATION_WARNING,
removal="1.0",
)classAgentType(str, Enum):"""An enum for agent types.
See documentation: https://python.langchain.com/docs/modules/agents/agent_types/
"""
ZERO_SHOT_REACT_DESCRIPTION = "zero-shot-react-description""""A zero shot agent that does a reasoning step before acting."""
REACT_DOCSTORE = "react-docstore""""A zero shot agent that does a reasoning step before acting.
This agent has access to a document store that allows it to look up
relevant information to answering the question.
"""
SELF_ASK_WITH_SEARCH = "self-ask-with-search""""An agent that breaks down a complex question into a series of simpler questions.
This agent uses a search tool to look up answers to the simpler questions
in order to answer the original complex question.
"""
CONVERSATIONAL_REACT_DESCRIPTION = "conversational-react-description"
CHAT_ZERO_SHOT_REACT_DESCRIPTION = "chat-zero-shot-react-description""""A zero shot agent that does a reasoning step before acting.
This agent is designed to be used in conjunction
"""
CHAT_CONVERSATIONAL_REACT_DESCRIPTION = "chat-conversational-react-description"
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION = (
"structured-chat-zero-shot-react-description"
)
"""An zero-shot react agent optimized for chat models.
This agent is capable of invoking tools that have multiple inputs.
"""
OPENAI_FUNCTIONS = "openai-functions""""An agent optimized for using open AI functions."""
OPENAI_MULTI_FUNCTIONS = "openai-multi-functions"
AGENT_DEPRECATION_WARNING
langchain의 agnet는 여전히 지원하지만 LangGraph를 사용하면 유연하게 구성할 수 있다고 한다.
추후 LangGraph를 사용하는 방법도 공부 해야겠다.
공부할 todo를 정해야할듯 하다.
AGENT_DEPRECATION_WARNING = (
"LangChain agents will continue to be supported, but it is recommended for new ""use cases to be built with LangGraph. LangGraph offers a more flexible and ""full-featured framework for building agents, including support for ""tool-calling, persistence of state, and human-in-the-loop workflows. For ""details, refer to the ""`LangGraph documentation <https://langchain-ai.github.io/langgraph/>`_"" as well as guides for ""`Migrating from AgentExecutor <https://python.langchain.com/docs/how_to/migrate_agent/>`_"# noqa: E501" and LangGraph's ""`Pre-built ReAct agent <https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/>`_."# noqa: E501
)
from langchain.agents import Tool
from langchain.agents.agent_types import AgentType
defadd_tool(input_str : str) -> str:# print(input_str)try:
arr = list(map(int, input_str.split()))
returnstr(sum(arr))
except Exception as e:
returnf"에러: {str(e)}"defchat_tool(input_st: str):return llm.invoke(input_st)
api_key = ''
model = 'gpt-4o-mini'
llm = ChatOpenAI(api_key=api_key, model=model)
# description은 툴의 설명을 적으며 어떤 상황에서 툴을 사용하게 될지, 입력은 어떻게 정의할지 작성한다.# func는 해당 툴을 사용할 때 어떤 함수를 사용할지 정의한다.
tools = [
Tool( name= 'AddTool', func=add_tool, description="두 숫자를 더합니다. 입력은 두 숫자를 공백으로 구분한 문자열로 입력합니다. 입력 형식: '3 5'"),
Tool( name= 'ChatTool', func=chat_tool
, description="일반적인 질문이나 대화에 답변합니다. 계산, 검색, 도구 실행이 필요하지 않은 경우 사용하세요. 입력 예시: '오늘 기분이 어때?' 또는 'AI는 어떻게 작동해?'")
]
2. agent 작성
from langchain_community.chat_models import ChatOpenAI
from langchain.agents import initialize_agent
# llm 기반의 agent트 생성# agentType은 분류되지 않은 추론형# verbose agent의 동작 과정 확인
agent = initialize_agent(
tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
확인해보니 "'3 5'" 와 같이 입력이 들어가서 description을 수정해주니 정상 동작했다. before : .....입력 형식: '3 5'"
after : 입력 형식: 3 5"
또한 아래와 같이 Exception 발생 시 Exception을 추론하여 재시도하며 이후 마지막에는 다른 Tool(ChatTool)을 사용하여 결과를 만들어내는 것을 확인 할 수 있다.
> Entering new AgentExecutor chain...
3하고 7을 더하는 계산이 필요하다.
Action: AddTool
Action Input: '3 7'
Observation: 에러: invalid literal forint() with base 10: "'3"
Thought:입력 형식이 잘못된 것 같다. 숫자들에 불필요한 따옴표가 포함되어 있는 것 같다. 따옴표 없이 다시 시도해 보아야겠다.
Action: AddTool
Action Input: '3 7'
Observation: 에러: invalid literal forint() with base 10: "'3"
Thought:입력 형식이 여전히 잘못된 것 같다. 따옴표가 여전히 포함되어 있는 것 같지 않지만, 정확한 문제는 확인해봐야겠다.
Action: AddTool
Action Input: '3 7'
Observation: 에러: invalid literal forint() with base 10: "'3"
Thought:입력 형식에 문제가 있는 것 같다. 두 숫자를 더하는 방법을 다시 살펴봐야겠다.
Action: AddTool
Action Input: '3 7'
Observation: 에러: invalid literal forint() with base 10: "'3"
Thought:입력 형식에 문제가 발생하고 있다. 숫자를 더하기 위해 입력을 정확하게 조정해야 할 것 같다.
Action: AddTool
Action Input: '3 7'
Observation: 에러: invalid literal forint() with base 10: "'3"
Thought:입력 형식이 계속해서 잘못된 결과를 초래하고 있다. 문제를 해결하기 위해 입력을 다시 확인하고 수정해야 할 것 같다.
Action: AddTool
Action Input: '3 7'
Observation: 에러: invalid literal forint() with base 10: "'3"
Thought:입력 형식에 문제가 발생하고 있는 것 같다. 계속해서 같은 오류가 발생하고 있으므로, 다른 방법을 통해 질문에 답변해야 할 것 같다.
Action: ChatTool
Action Input: '3하고 7을 더해줘.'
Observation: content='3과 7을 더하면 10입니다.' additional_kwargs={} response_metadata={'token_usage': {'completion_tokens': 12, 'prompt_tokens': 17, 'total_tokens': 29, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_80cf447eee', 'finish_reason': 'stop', 'logprobs': None} id='run-3c1360fb-0f39-4f8c-9932-95fe87de0518-0'
Thought:I now know the final answer.
Final Answer: 3과 7을 더하면 10입니다.
> Finished chain.
3과 7을 더하면 10입니다.
# 입력 받는 타입으 str, 그 외 값을 받는가면 str로 castingdefadd_too(input_str : str) -> str:try:
arr = list(input_str.split())
returnstr(sum(arr))
except Exception as e:
returnf"에러: {str(e)}"
2. 툴 선택을 위한 Prompt 작성
# 일반대화와 두 수를 더하는 2가지의 TOOL 정의
TOOL_PROMPT_DISC="""
당신은 다음 도구를 사용할 수 있습니다:
도구 이름: AddTool
기능: 두 숫자를 더합니다.
입력 예시: "3 5"
도구 이름: ChatTool
기능: 일반적인 질문이나 대화에 답변합니다. 계산, 검색, 도구 실행이 필요하지 않은 경우 사용하세요.
입력 예시: "오늘 기분이 어때?" 또는 "AI는 어떻게 작동해?"
사용자가 질문하면, 어떤 도구를 사용할지 판단하고 다음 형식으로 대답하세요:
사용할 도구: <도구 이름>
입력값: <도구에 줄 입력값>
사용자의 질문: "{question}"
"""
3. 툴 선택 Prompt를 사용한 LLM 결과 출력
from langchain_community.chat_models import ChatOpenAI
api_key = 'api_key'
model = 'gpt-4o-mini'
llm = ChatOpenAI(api_key=api_key, model=model)
query = "3더하기 5의 값은 뭐지?"
TOOL_PROMPT = TOOL_PROMPT_DISC.format(question=query)
TOOL_RESULT = llm.invoke(TOOL_PROMPT)
4. 툴의 사용
import re
match = re.search(r"사용할 도구:\s*(\w+)\s*입력값:\s*[\"']?(.+?)[\"']?$", TOOL_RESULT.content.strip(), re.DOTALL)
tool = match.group(1)
tool_input = match.group(2)
print(tool)
print(tool_input)
if tool == 'AddTool':
tool_result = add_tool(tool_input)
print(tool_result)
elif tool == 'ChatTool':
llm.invoke(tool_input)
5. 툴의 결과로 답변생성
import re
match = re.search(r"사용할 도구:\s*(\w+)\s*입력값:\s*[\"']?(.+?)[\"']?$", TOOL_RESULT.content.strip(), re.DOTALL)
tool = match.group(1)
tool_input = match.group(2)
print(tool)
print(tool_input)
if tool == 'AddTool':
tool_result = add_tool(tool_input)
print(tool_result)
FINAL_PROMPT_DISC = """
사용자의 질문: "{question}"
도구 실행 결과: {result}
이제 사용자에게 자연어로 대답하세요.
"""
FINAL_PROMPT = FINAL_PROMPT_DISC.format(question = query, result=tool_result)
print(llm.invoke(FINAL_PROMPT))
elif tool == 'ChatTool':
llm.invoke(tool_input)
.py로 만든 파일
from langchain_community.chat_models import ChatOpenAI
import re
api_key = ''
model = 'gpt-4o-mini'
llm = ChatOpenAI(api_key=api_key, model=model)
######## prompt# 도구 선택 프롬프트
tool_prompt_disc="""
당신은 다음 도구를 사용할 수 있습니다:
도구 이름: AddTool
기능: 두 숫자를 더합니다.
입력 예시: "3 5"
도구 이름: ChatTool
기능: 일반적인 질문이나 대화에 답변합니다. 계산, 검색, 도구 실행이 필요하지 않은 경우 사용하세요.
입력 예시: "오늘 기분이 어때?" 또는 "AI는 어떻게 작동해?"
사용자가 질문하면, 어떤 도구를 사용할지 판단하고 다음 형식으로 대답하세요:
사용할 도구: <도구 이름>
입력값: <도구에 줄 입력값>
사용자의 질문: "{question}"
"""
final_prompt_disc="""
사용자의 질문: "{question}"
도구 실행 결과: {result}
이제 사용자에게 자연어로 대답하세요.
"""########defadd_tool(input_str : str) -> str:try:
arr = list(map(int, input_str.split()))
returnstr(sum(arr))
except Exception as e:
returnf"에러: {str(e)}"defrun_agent(query: str):
tool_prompt = tool_prompt_disc.format(question=query)
tool_result = llm.invoke(tool_prompt)
match = re.search(r"사용할 도구:\s*(\w+)\s*입력값:\s*[\"']?(.+?)[\"']?$", tool_result.content.strip(), re.DOTALL)
tool = match.group(1)
tool_input = match.group(2)
print(tool_result.content)
if tool == "AddTool":
add_result = add_tool(tool_input)
final_prompt = final_prompt_disc.format(question = query, result=add_result)
return llm.invoke(final_prompt).content
elif tool == "ChatTool":
final_prompt = final_prompt_disc.format(question = query, result=tool_input)
return llm.invoke(final_prompt).content
if __name__ == '__main__':
query="3 더하기 5는 ?"# query="오늘 저녁메뉴는 뭘 먹는게 좋을까?print("사용자 질문 :", query)
result = run_agent(query)
print("llm 답변: ",result)