LLM(대규모 언어 모델) 을 의사결정 엔진으로 사용하여 작업을 수행하는 시스템
모델은 입력된 데이터를 분석하여 맥락에 맞는 의사결정을 수행
시스템은 사용자의 요청을 이해하고 적절한 해결책을 제시
복잡한 작업을 자동화하여 업무 효율성을 높일 수 있음
AgentExecutor는 LangChain의 기본 에이전트 실행 시스템
에이전트의 계획-실행-관찰 사이클을 자동으로 관리
에이전트의 행동을 모니터링하고 결과를 반환
@tool 데코레이터를 사용해 계산(파이썬 코드 실행) 기능을 가진 커스텀 도구를 정의
데코레이터를 통해 함수가 Tool Calling 시스템에 등록되어 LLM이 호출 가능
@tool
def calculate(expression: str) -> float:
"""수학 계산을 수행합니다.
Args:
expression (str): 계산식 (python eval 함수 사용)
"""
return eval(expression)
# 도구 실행
calculate.invoke("3+2")
- 출력
5
프롬프트 템플릿은 에이전트의 기본 행동과 응답 방식을 정의하는 지침
에이전트의 일관된 응답과 효율적인 도구 사용을 위한 기본 틀 제공
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 프롬프트 템플릿 정의
prompt = ChatPromptTemplate.from_messages([
("system", "당신은 사용자의 요청을 처리하는 AI Assistant입니다."),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
# 프롬프트 템플릿 실행
response = prompt.invoke({
"input": "광주 날씨 어때?",
"agent_scratchpad": [] # 에이전트 스크래치패드 (메시지 기록)
})
# 프롬프트 템플릿 실행 결과
pprint(response.messages)
- 출력
[SystemMessage(content='당신은 사용자의 요청을 처리하는 AI Assistant입니다.', additional_kwargs={}, response_metadata={}),
HumanMessage(content='광주 날씨 어때?', additional_kwargs={}, response_metadata={})]
ChatGPT 모델이 에이전트의 핵심 추론 엔진으로 사용됨
모델은 사용자 입력을 분석하고 적절한 도구를 선택하여 작업 수행
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini",temperature=0)
에이전트는 LLM과 도구를 통합하여 복잡한 작업을 수행하는 시스템
프롬프트 템플릿을 기반으로 사용자 요청을 해석하고 적절한 도구 선택
도구 실행 결과를 분석하여 최종 응답을 생성하는 워크플로우 구현
from langchain_core.tools import tool
from typing import Literal
@tool
def get_weather(city: Literal["서울", "부산", "대구", "인천", "광주"]):
"""한국 주요 도시의 날씨 정보를 가져옵니다."""
weather_data = {
"서울": "맑음",
"부산": "흐림",
"대구": "맑음",
"인천": "비",
"광주": "구름많음"
}
if city in weather_data:
return f"{city}은(는) {weather_data[city]}"
else:
raise AssertionError("지원하지 않는 도시입니다")
@tool
def calculate(expression: str) -> float:
"""수학 계산을 수행합니다.
Args:
expression (str): 계산식 (python eval 함수 사용)
"""
return eval(expression)
from langchain.agents import create_tool_calling_agent
# 도구 목록 생성
tools = [get_weather, calculate]
# 에이전트 생성 (도구 호출)
agent = create_tool_calling_agent(llm, tools, prompt)
AgentExecutor는 에이전트의 작업 흐름을 관리하고 결과를 처리하는 컴포넌트
사용자 입력부터 최종 출력까지의 전체 프로세스를 조율하고 제어
에러 처리, 로깅, 결과 포맷팅 등 시스템 운영에 필요한 기능 제공
from langchain.agents import AgentExecutor
# 에이전트 실행기 생성
agent_executor = AgentExecutor(
agent=agent, # 도구 호출 에이전트
tools=tools, # 도구 목록
verbose=True, # 상세 로그 출력
)
# 에이전트 실행
response = agent_executor.invoke(
{"input": "서울의 날씨는 어떤가요?"}
)
- 출력
> Entering new AgentExecutor chain...
Invoking: `get_weather` with `{'city': '서울'}`
서울은(는) 맑음서울의 날씨는 맑습니다.
> Finished chain.
# 에이전트 실행 결과 출력
pprint(response)
- 출력
{'input': '서울의 날씨는 어떤가요?', 'output': '서울의 날씨는 맑습니다.'}
return_intermediate_steps=True
# 에이전트 실행기 생성
agent_executor = AgentExecutor(
agent=agent, # 도구 호출 에이전트
tools=tools, # 도구 목록
return_intermediate_steps=True # 중간 단계 반환 (기본값 False)
)
response = agent_executor.invoke(
{"input": "32 더하기 18은 얼마인가요?"}
)
# 에이전트 실행 결과 출력
pprint(response)
- 출력
{'input': '32 더하기 18은 얼마인가요?',
'intermediate_steps': [(ToolAgentAction(tool='calculate', tool_input={'expression': '32 + 18'}, log="\nInvoking: `calculate` with `{'expression': '32 + 18'}`\n ... ,
50)],
'output': '32 더하기 18은 50입니다.'}
LangGraph는 LangChain의 확장 도구로 고급 에이전트 개발을 지원
그래프 기반 워크플로우를 통해 복잡한 에이전트 로직을 구현할 수 있음
상태 관리와 타입 안전성을 통해 안정적인 에이전트 실행을 보장
AgentExecutor보다 더 유연한 사용자 정의가 가능함
LangGraph의 react agent executor는 메시지 목록으로 상태를 관리
에이전트의 출력에 도구 호출이 없을 때까지 메시지를 계속 처리
시작 시 초기 메시지 목록을 입력으로 사용
실행 결과로 전체 대화 기록을 포함한 그래프 상태를 반환
메시지 기반 상태 관리를 통해 에이전트의 실행 흐름을 체계적으로 제어
from langgraph.prebuilt import create_react_agent
# 도구 실행 에인전트 생성
langgraph_agent_executor = create_react_agent(model, tools)
# 입력 스키마 출력
langgraph_agent_executor.get_input_jsonschema()
# 에이전트 실행
messages = langgraph_agent_executor.invoke(
{"messages": [("human", "32 곱하기 18은 얼마인가요?")]}
)
# 에이전트 실행 결과 출력
messages
- 출력
{'messages': [HumanMessage(content='32 곱하기 18은 얼마인가요?', additional_kwargs={}, response_metadata={}, id='fa9ab22b-f53b-437e-9486-7ae8c1ee1403'),
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_vrMS3LIQMiukc3Yv5100dyTo', 'function': {'arguments': '{"expression":"32 * 18"}', 'name': 'calculate'}, 'type': 'function'}], 'refusal': None}, ...),
ToolMessage(content='576', name='calculate', id='c2079fb4-fa4e-4e1a-8493-e2001ceed828', tool_call_id='call_vrMS3LIQMiukc3Yv5100dyTo'),
AIMessage(content='32 곱하기 18은 576입니다.', additional_kwargs={'refusal': None}, ...]}