AI 에이전트 시작하기: LangGraph 개념과 실습
AI 에이전트는 LLM(Large Language Model)을 활용하여 복잡한 작업을 수행하는 자동화된 시스템입니다. 일반적인 LLM 사용이 단순 프롬프트-응답 방식이라면, 에이전트는 더 복잡하고 반복적인 작업을 수행할 수 있습니다.
AI 에이전트의 핵심 디자인 패턴
- 계획(Planning): 작업을 수행하기 위한 단계를 미리 생각하고 계획합니다.
- 도구 사용(Tool Use): 검색, 계산 등 필요한 도구들을 활용합니다.
- 반성(Reflection): 결과를 반복적으로 개선하며, 여러 LLM이 결과를 검토하고 제안할 수 있습니다.
- 다중 에이전트 통신: 각각의 LLM이 고유한 역할을 수행하며 서로 협력합니다.
- 메모리: 여러 단계에 걸친 진행 상황과 결과를 추적합니다.
LangGraph 소개
LangGraph는 LangChain의 확장으로, 에이전트와 다중 에이전트 워크플로우를 구축하기 위해 특별히 설계되었습니다. 주요 특징은 다음과 같습니다.
핵심 컴포넌트
- 노드(Nodes)
- 에이전트나 함수를 나타냅니다.
- LLM 호출, 도구 실행 등의 작업을 수행합니다.
- 엣지(Edges)
- 노드들을 연결합니다.
- 워크플로우의 흐름을 정의합니다.
- 조건부 엣지(Conditional Edges)
- 다음 노드로의 이동을 결정하는 조건을 포함합니다.
- 워크플로우의 분기를 관리합니다.
State 관리
LangGraph의 중요한 특징 중 하나는 상태 관리입니다. 에이전트 상태(Agent State)는 아래와 같습니다.
- 그래프의 모든 부분에서 접근 가능
- 지속성 레이어에 저장 가능
- 나중에 상태를 복구하여 작업 재개 가능
AI 에이전트와 LangGraph 이해하기
AI 에이전트는 LLM을 사용해 복잡한 작업을 처리하는 자동화된 시스템입니다. 단순한 프롬프트-응답이 아닌, 여러 단계의 작업을 수행할 수 있죠. LangGraph를 사용해 이런 에이전트를 만들어보겠습니다.
먼저 필요한 라이브러리들을 가져옵니다.
from typing import List, TypeVar, Annotated, TypedDict
from operator import add
from langchain_openai import ChatOpenAI
from langchain_core.messages import AnyMessage, SystemMessage, HumanMessage, ToolMessage
from langgraph.graph import StateGraph, END
from langchain.tools import Tool
import getpass
import os
# API 키 설정
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ")
1. 도구 설정: 계산기 예제
간단한 계산기 도구를 만들어보겠습니다. 이 계산기는 하나의 수식을 받거나 여러 인자를 받아 계산할 수 있습니다.
def calculator(*args) -> float:
"""수학 계산을 수행하는 함수"""
if len(args) == 1:
return eval(str(args[0]))
return eval(' '.join(str(arg) for arg in args))
tool = Tool(
name="calculator",
func=calculator,
description="Useful for performing mathematical calculations"
)
2. 상태 관리
LangGraph의 핵심 기능 중 하나는 상태 관리입니다. 대화 이력을 messages 리스트에 저장하고, operator.add로 새로운 메시지를 추가합니다.
class AgentState(TypedDict):
messages: Annotated[List[AnyMessage], add]
3. 에이전트 클래스
에이전트의 핵심 로직을 담당하는 클래스를 만듭니다.
class Agent:
def __init__(self, model, tools, system=""):
self.system = system
self.tools = {t.name: t for t in tools}
self.model = model.bind_tools(tools)
self.graph = self._create_graph()
그래프 생성
def _create_graph(self):
workflow = StateGraph(AgentState)
# 노드 추가
workflow.add_node("llm", self.call_model)
workflow.add_node("action", self.take_action)
# 엣지 추가
workflow.add_conditional_edges(
"llm",
self.should_use_tool,
{True: "action", False: END}
)
workflow.add_edge("action", "llm")
workflow.set_entry_point("llm")
return workflow.compile()
여기서 중요한 컴포넌트들을 살펴보겠습니다.
- 노드(Nodes)
llm
: 사용자 입력을 처리하고 도구 사용을 결정합니다.action
: 실제 도구를 실행합니다.
- 엣지(Edges)
- 조건부 엣지: 도구 사용 여부에 따라 다음 단계를 결정합니다.
- 일반 엣지: 도구 실행 후 다시 LLM으로 돌아갑니다.
도구 실행 로직
def take_action(self, state: AgentState):
tool_calls = state["messages"][-1].tool_calls
results = []
for t in tool_calls:
if t["name"] not in self.tools:
result = "bad tool name, retry"
else:
args_values = list(t["args"].values())
try:
result = self.tools[t["name"]].invoke(*args_values)
except Exception as e:
result = f"Error executing tool: {str(e)}"
results.append(
ToolMessage(
tool_call_id=t["id"],
name=t["name"],
content=str(result)
)
)
return {"messages": results}
4. 실행 및 테스트
에이전트를 초기화하고 테스트해 봅시다.
system_prompt = """You are a helpful assistant that can use tools to accomplish tasks.
When you need to perform calculations, use the calculator tool.
Always explain your reasoning before and after using tools."""
model = ChatOpenAI(temperature=0)
agent = Agent(model=model, tools=[tool], system=system_prompt)
def run_agent(question: str):
print(f"\nQuestion: {question}")
messages = [HumanMessage(content=question)]
result = agent.graph.invoke({"messages": messages})
print(f"Final Answer: {result['messages'][-1].content}")
return result
이 구조의 장점은:
- 명확한 실행 흐름: 그래프 구조로 실행 흐름을 쉽게 이해할 수 있습니다.
- 유연한 확장성: 새로운 도구나 노드를 쉽게 추가할 수 있습니다.
- 상태 추적: 대화 이력과 작업 진행 상황을 효과적으로 관리합니다.
실제로 에이전트를 테스트해 보고 그 결과를 시각화해 보겠습니다.
# 테스트할 질문들 준비
test_questions = [
"What is 25 * 48?",
"If I have 3 groups of 17 items each, how many items do I have in total?"
]
print("=== 에이전트 테스트 시작 ===")
for question in test_questions:
run_agent(question)
print("=== 테스트 완료 ===\n")
# 그래프 시각화
print("=== 그래프 구조 시각화 ===")
from IPython.display import Image
Image(agent.graph.get_graph().draw_png())
첫 번째 질문 "What is 25 * 48?"
- LLM이 계산 필요성을 인식
- calculator 도구 호출
- 결과를 받아 최종 답변 생성
두 번째 질문 "If I have 3 groups of 17 items each, how many items do I have in total?"
- LLM이 문제를 이해하고 수식으로 변환
- calculator(3 * 17) 실행
- 결과를 문맥에 맞게 설명
그래프 구조를 보면
- LLM 노드 (시작점)
- Action 노드 (도구 실행)
- 조건부 분기와 순환 구조
이러한 시각화를 통해 에이전트의 의사결정 과정과 작업 흐름을 명확하게 이해할 수 있습니다.
이 기본 구조를 바탕으로 다음과 같은 기능을 추가할 수 있습니다.
- 여러 도구를 사용하는 복잡한 작업 처리
- 중간 결과를 저장하고 불러오는 기능
- 사용자와의 대화형 상호작용
- 외부 API나 데이터베이스와의 연동
이렇게 만든 에이전트는 단순 계산부터 복잡한 정보 처리까지 다양한 작업을 자동화하는 데 활용할 수 있습니다.
'Tech & Development > AI' 카테고리의 다른 글
Claude의 새로운 기능: 맞춤형 응답 스타일 설정 (0) | 2024.11.28 |
---|---|
Anthropic의 Model Context Protocol(MCP) : 사용 가이드 (0) | 2024.11.27 |
LLM의 토큰(Token): AI의 글자 단위 (0) | 2024.11.10 |
Anthropic Computer Use 가이드: 사용 후기 (1) | 2024.10.26 |
Anthropic의 10월 업데이트: Computer Use와 Claude 3.5 모델 개선 (1) | 2024.10.26 |
댓글
이 글 공유하기
다른 글
-
Claude의 새로운 기능: 맞춤형 응답 스타일 설정
Claude의 새로운 기능: 맞춤형 응답 스타일 설정
2024.11.28 -
Anthropic의 Model Context Protocol(MCP) : 사용 가이드
Anthropic의 Model Context Protocol(MCP) : 사용 가이드
2024.11.27 -
LLM의 토큰(Token): AI의 글자 단위
LLM의 토큰(Token): AI의 글자 단위
2024.11.10 -
Anthropic Computer Use 가이드: 사용 후기
Anthropic Computer Use 가이드: 사용 후기
2024.10.26