스스로 일하는 AI – AI Agent 완벽 가이드: ReAct부터 Multi-Agent까지


핵심 요약

“ChatGPT에게 일을 시키면 왜 한 번에 하나만 하고 끝날까? 인터넷 검색도, 파일 저장도, 이메일 발송도 스스로 하면 안 될까?”
이 질문의 답이 바로 AI Agent(에이전트)입니다. AI Agent는 LLM이 스스로 생각하고, 도구를 사용하며, 목표를 달성할 때까지 자율적으로 행동하는 시스템입니다.

핵심 아키텍처는 Model(두뇌) + Tools(손과 발) + Orchestration(조율)으로 구성됩니다.
ReAct(Reasoning + Acting)는 “생각 → 행동 → 관찰 → 다시 생각” 사이클로 작동하며, 질문 응답 정확도를 30% 이상 향상시킵니다.
AutoGPT는 목표만 주면 스스로 계획하고 실행하는 완전 자율 에이전트이고, BabyAGI는 작업 생성→우선순위→실행을 반복하는 목표 기반 시스템입니다.
Function Calling(Tool Use)은 LLM이 외부 API를 호출하는 핵심 기술로, “서울 날씨 알려줘” → get_weather(“서울”) 자동 호출 → 답변 생성 흐름입니다.
Multi-Agent 시스템에서는 CrewAI(역할 기반), AutoGen(대화 기반), LangGraph(그래프 기반)가 대표적입니다.
2024년 Anthropic이 발표한 MCP(Model Context Protocol)는 “AI의 USB-C 포트”로, 모든 도구를 표준화된 방식으로 연결합니다.
Gartner는 2028년까지 업무 결정의 15%가 AI Agent로 자율 수행될 것으로 전망합니다.

본 포스팅에서는 Agent 아키텍처, ReAct/AutoGPT/BabyAGI 비교, Function Calling, Multi-Agent 시스템, LangChain Agent 구현, 실전 자동화 에이전트 구축까지 완벽하게 다룹니다.


📍 목차

  1. AI Agent란? – 스스로 일하는 AI의 시대
  2. Agent 아키텍처 – 3가지 핵심 구성요소
  3. ReAct: Reasoning + Acting
  4. AutoGPT, BabyAGI, AgentGPT 비교
  5. Function Calling (Tool Use)
  6. Multi-Agent 시스템
  7. LangChain Agent 실전 구현
  8. 실전 자동화 에이전트 구축

1. AI Agent란? – 스스로 일하는 AI의 시대

1-1. 기존 AI vs AI Agent

비유로 이해하기:

기존 ChatGPT:
"뛰어난 컨설턴트"
- 질문하면 답변
- 실행은 사람이 직접
- 한 번에 하나의 질문

AI Agent:
"뛰어난 비서"
- 목표를 주면 스스로 계획
- 필요한 도구를 사용해 실행
- 결과를 확인하고 다음 행동 결정
- 목표 달성까지 자율적으로 반복

핵심 차이:

┌──────────────┬──────────────────┬──────────────────┐
│     항목     │    기존 LLM      │    AI Agent      │
├──────────────┼──────────────────┼──────────────────┤
│ 상호작용     │ 질문-답변        │ 목표-실행-완료   │
│ 실행 주체    │ 사람             │ AI              │
│ 도구 사용    │ 불가             │ API, 검색 등    │
│ 자율성       │ 수동적           │ 자율적          │
│ 반복 작업    │ 매번 지시 필요   │ 스스로 반복     │
│ 외부 연동    │ 불가             │ 다양한 시스템   │
└──────────────┴──────────────────┴──────────────────┘

1-2. AI Agent의 정의

공식 정의:

AI Agent:
LLM을 두뇌로 사용하여,
주어진 목표를 달성하기 위해
스스로 계획하고, 도구를 사용하며,
환경과 상호작용하는 자율 시스템

핵심 능력:
1. 추론 (Reasoning): 상황 분석, 계획 수립
2. 행동 (Acting): 도구 호출, API 실행
3. 관찰 (Observing): 결과 확인
4. 학습 (Learning): 경험 반영

1-3. AI Agent가 중요한 이유

Gartner 2025 전략 기술 트렌드:

"Agentic AI는 2025년 1위 전략 기술 트렌드"

예측:
├── 2028년까지 일상 업무의 15%를 AI가 자율 결정
├── 기업 소프트웨어의 33%가 Agent 기능 포함
├── 시장 규모: 2025년 51억$ → 2030년 470억$
└── 연평균 성장률 24%

도입 효과:

실제 기업 사례:

✅ 업무 처리 시간 41% 단축
✅ 데이터 기반 결정 정확도 35% 상승
✅ 고객 대응 SLA 24% 향상
✅ 연간 260시간 업무 절감 (주당 5시간)

2. Agent 아키텍처 – 3가지 핵심 구성요소

2-1. Google AI Agent 아키텍처

3대 핵심 구성요소:

┌─────────────────────────────────────────────────────┐
│                   AI AGENT                          │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌─────────────────┐                               │
│  │     Model       │  ← 두뇌 (GPT-4, Claude 등)    │
│  │  (LLM Engine)   │                               │
│  └────────┬────────┘                               │
│           │                                         │
│  ┌────────▼────────┐                               │
│  │  Orchestration  │  ← 조율 (ReAct, CoT 등)       │
│  │     Layer       │                               │
│  └────────┬────────┘                               │
│           │                                         │
│  ┌────────▼────────┐                               │
│  │     Tools       │  ← 도구 (API, 검색, DB 등)    │
│  │   (Actions)     │                               │
│  └─────────────────┘                               │
│                                                     │
└─────────────────────────────────────────────────────┘

2-2. 각 구성요소 상세

1. Model (모델) – 두뇌:

역할:
- 추론과 의사결정
- 자연어 이해/생성
- 계획 수립

선택지:
├── GPT-4o/o1: 범용 추론
├── Claude 3.5: 복잡한 분석
├── Gemini 2.0: 멀티모달
└── 오픈소스: Llama, Mistral

2. Tools (도구) – 손과 발:

역할:
- 외부 세계와 상호작용
- 실제 작업 수행
- 정보 수집

종류:
├── 웹 검색: Google, Tavily
├── 코드 실행: Python Interpreter
├── API 호출: REST, GraphQL
├── 데이터베이스: SQL, Vector DB
├── 파일 시스템: 읽기/쓰기
└── 외부 서비스: Slack, Email, Calendar

3. Orchestration (오케스트레이션) – 지휘자:

역할:
- 정보 수집 → 내부 추론 → 행동 결정 → 피드백
- 반복 사이클 관리
- 메모리/상태 관리

프레임워크:
├── ReAct: 추론 + 행동 교차
├── Plan-and-Execute: 계획 후 실행
├── Tree of Thoughts: 분기 탐색
└── Reflexion: 자기 반성

2-3. Agent 동작 흐름

사용자: "다음 주 서울 출장 일정 잡아줘"

[1단계: 정보 수집]
Agent: "다음 주 날짜가 언제지? 서울의 회의실 예약 상황은?"
→ 캘린더 API 호출, 회의실 시스템 조회

[2단계: 내부 추론]
Agent: "월요일은 이미 회의가 있고, 화요일이 비어있네.
        회의실 A는 오후에 가능해."

[3단계: 행동 실행]
Agent: → 캘린더에 일정 등록
       → 회의실 예약
       → 참석자에게 이메일 발송

[4단계: 피드백]
Agent: "화요일 오후 2시에 서울 사무실 회의실 A에서
        출장 회의를 잡았습니다. 참석자들에게 안내 메일을
        발송했습니다."

[반복]
사용자: "시간을 3시로 변경해줘"
Agent: → 위 사이클 반복...

3. ReAct: Reasoning + Acting

3-1. ReAct란?

정의:

ReAct = Reasoning + Acting

추론(Reasoning)과 행동(Acting)을 교차 수행하며
문제를 해결하는 프롬프트 설계 기법

핵심 아이디어:
"생각하고 → 행동하고 → 관찰하고 → 다시 생각하고"
사이클을 반복

왜 ReAct가 필요한가:

기존 방식의 한계:

Reasoning Only (CoT):
- 내부 지식만 사용
- 외부 정보 접근 불가
- 환각 위험 높음

Acting Only:
- 추론 없이 바로 행동
- 무작정 검색
- 비효율적

ReAct:
- 추론 + 행동 결합
- 필요할 때 외부 정보 획득
- 추론으로 행동 계획 수립
- 30% 이상 정확도 향상

3-2. ReAct 작동 방식

Think-Act-Observe 사이클:

질문: "Apple Remote가 처음 어떤 기기와 상호작용하도록 설계되었나요?"

[Thought 1] Apple Remote에 대해 검색해야 해.
[Action 1] Search[Apple Remote]
[Observation 1] Apple Remote는 Apple TV, Mac 등과
                함께 사용되는 리모컨이다...

[Thought 2] 처음 설계된 기기를 알아야 해.
            Front Row 소프트웨어와 관련이 있네.
[Action 2] Search[Front Row software Apple]
[Observation 2] Front Row는 2005년 iMac G5와 함께
                출시된 미디어 소프트웨어...

[Thought 3] 2005년 iMac G5와 함께 출시되었고,
            나중에 Apple TV에서도 사용됨.
[Action 3] Finish[iMac과 Apple TV]

답변: "Apple Remote는 iMac과 Apple TV와 상호작용하기 위해
      처음 설계되었습니다."

3-3. ReAct 프롬프트 템플릿

REACT_PROMPT = """
당신은 질문에 답하기 위해 사고(Thought)와 행동(Action)을 
교차하며 수행하는 AI 어시스턴트입니다.

사용 가능한 도구:
- Search[query]: 위키피디아에서 정보 검색
- Lookup[keyword]: 현재 문서에서 키워드 찾기
- Finish[answer]: 최종 답변 제출

형식:
Thought: [현재 상황 분석 및 다음 행동 계획]
Action: [도구명][입력값]
Observation: [도구 실행 결과]
... (반복)
Thought: [최종 결론 도출]
Action: Finish[최종 답변]

예시:
질문: 콜로라도 조산 운동의 동쪽 지역에는 어떤 고원이 있나요?

Thought: 콜로라도 조산 운동에 대해 먼저 검색해야 합니다.
Action: Search[콜로라도 조산 운동]
Observation: 콜로라도 조산 운동은 로키산맥 형성에 기여한...
             동쪽 지역은 하이 플레인스에 해당합니다.

Thought: 하이 플레인스가 동쪽 지역의 고원입니다.
Action: Finish[하이 플레인스]

이제 다음 질문에 답하세요:
질문: {question}
"""

3-4. LangChain ReAct 구현

from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain.tools import Tool
from langchain import hub

# LLM 초기화
llm = ChatOpenAI(model="gpt-4", temperature=0)

# 도구 정의
tools = [
    Tool(
        name="Search",
        func=search_wikipedia,
        description="위키피디아에서 정보를 검색합니다."
    ),
    Tool(
        name="Calculator",
        func=calculator,
        description="수학 계산을 수행합니다."
    ),
]

# ReAct 프롬프트 로드
prompt = hub.pull("hwchase17/react")

# ReAct 에이전트 생성
agent = create_react_agent(llm, tools, prompt)

# 에이전트 실행기
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,  # 사고 과정 출력
    max_iterations=10
)

# 실행
result = agent_executor.invoke({
    "input": "2024년 노벨 물리학상 수상자와 그의 주요 업적은?"
})
print(result["output"])

4. AutoGPT, BabyAGI, AgentGPT 비교

4-1. AutoGPT

특징:

AutoGPT (2023.03):
"목표만 주면 스스로 계획하고 실행하는 완전 자율 에이전트"

핵심 기능:
├── 자율적 목표 분해
├── 인터넷 검색
├── 장기/단기 메모리 관리
├── 파일 읽기/쓰기
├── 코드 실행
└── GPT-4 기반 추론

작동 방식:
1. 사용자가 목표 설정 ("블로그 운영해서 수익 내기")
2. AI가 하위 작업 생성
3. 각 작업 자율 실행
4. 결과 평가 및 다음 작업 결정
5. 목표 달성까지 반복

장단점:

장점:
✅ 최소한의 사용자 개입
✅ 복잡한 다단계 작업 처리
✅ 인터넷 검색 및 파일 조작
✅ 완전 자율 동작

단점:
❌ 높은 API 비용 (많은 토큰 사용)
❌ 무한 루프 가능성
❌ 예측 불가능한 행동
❌ 설정 복잡도 높음

4-2. BabyAGI

특징:

BabyAGI (2023.04):
"작업을 생성하고, 우선순위를 정하고, 실행하는 목표 기반 시스템"

핵심 구조:
├── Task Creation Agent: 새 작업 생성
├── Task Prioritization Agent: 우선순위 결정
├── Execution Agent: 작업 실행
└── Vector DB: 결과 저장/검색

작동 방식:
1. 초기 목표와 첫 작업 설정
2. 작업 실행 및 결과 저장
3. 결과 기반 새 작업 생성
4. 작업 목록 우선순위 재정렬
5. 다음 작업 실행 (반복)

특별한 점:

- 105줄의 간결한 코드
- 인간의 작업 방식 모방
  (아침에 일어나 → 첫 작업 → 새 작업 추가 → 
   우선순위 조정 → 반복)
- 메모리를 통한 지속적 학습
- 확장 용이한 미니멀 설계

4-3. AgentGPT

특징:

AgentGPT:
"브라우저에서 바로 사용하는 웹 기반 AI 에이전트"

핵심 장점:
├── 설치 불필요 (웹 기반)
├── 직관적인 UI
├── 비기술 사용자도 접근 가능
├── 빠른 프로토타이핑
└── 저렴한 진입 비용

4-4. 비교표

┌────────────────┬───────────────┬───────────────┬───────────────┐
│     항목       │   AutoGPT     │   BabyAGI     │  AgentGPT     │
├────────────────┼───────────────┼───────────────┼───────────────┤
│ 자율성         │ 매우 높음     │ 높음          │ 중간          │
│ 설정 난이도    │ 높음          │ 중간          │ 낮음          │
│ 메모리         │ 벡터DB+파일   │ 벡터DB        │ 세션 기반     │
│ 확장성         │ 높음          │ 높음          │ 제한적        │
│ 비용           │ 높음          │ 중간          │ 낮음          │
│ 실행 환경      │ 로컬          │ 로컬          │ 웹 브라우저   │
├────────────────┼───────────────┼───────────────┼───────────────┤
│ 추천 대상      │ 개발자        │ 중급 사용자   │ 초보자        │
│ 추천 용도      │ 복잡한 자동화 │ 연구/실험     │ 빠른 테스트   │
└────────────────┴───────────────┴───────────────┴───────────────┘

5. Function Calling (Tool Use)

5-1. Function Calling이란?

정의:

Function Calling:
LLM이 사용자의 자연어 요청을 분석하여
적절한 함수(도구)를 선택하고
필요한 매개변수를 추출하여 호출하는 기술

= AI Agent의 "손과 발"

예시:
사용자: "서울의 현재 날씨 알려줘"
LLM 분석: get_weather(location="서울") 호출 필요
→ 함수 실행 → 결과 반환 → 자연어 답변 생성

왜 중요한가:

Function Calling 이전:
- LLM은 텍스트만 생성
- 실제 행동 불가
- 외부 시스템 연동 불가

Function Calling 이후:
- LLM이 도구를 "호출"
- 실제 API 실행
- 데이터베이스 조회
- 이메일 발송
- 캘린더 일정 추가
→ 진정한 AI Agent 탄생!

5-2. Function Calling 작동 방식

┌─────────────────────────────────────────────────────────────┐
│                  Function Calling 흐름                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  [1] 사용자: "내일 서울 날씨 알려줘"                          │
│                     │                                        │
│                     ▼                                        │
│  [2] LLM 분석: "날씨 정보가 필요하네.                         │
│                 get_weather 함수를 호출해야겠어."             │
│                     │                                        │
│                     ▼                                        │
│  [3] 함수 호출 결정:                                         │
│      {                                                       │
│        "name": "get_weather",                               │
│        "arguments": {                                        │
│          "location": "서울",                                 │
│          "date": "2025-11-27"                               │
│        }                                                     │
│      }                                                       │
│                     │                                        │
│                     ▼                                        │
│  [4] 실제 함수 실행 (개발자 코드)                             │
│      result = get_weather("서울", "2025-11-27")             │
│      → {"temp": 5, "condition": "맑음", "humidity": 45}     │
│                     │                                        │
│                     ▼                                        │
│  [5] LLM에 결과 전달                                         │
│                     │                                        │
│                     ▼                                        │
│  [6] 최종 답변 생성:                                         │
│      "내일 서울 날씨는 맑음이며, 기온은 5도,                   │
│       습도는 45%입니다. 따뜻하게 입고 나가세요!"              │
│                                                              │
└─────────────────────────────────────────────────────────────┘

5-3. OpenAI Function Calling 구현

import openai
import json

# 1. 함수 정의 (JSON Schema)
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "특정 지역의 현재 날씨를 조회합니다.",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "도시 이름 (예: 서울, 부산)"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "온도 단위"
                    }
                },
                "required": ["location"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "send_email",
            "description": "이메일을 발송합니다.",
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string", "description": "수신자 이메일"},
                    "subject": {"type": "string", "description": "제목"},
                    "body": {"type": "string", "description": "본문"}
                },
                "required": ["to", "subject", "body"]
            }
        }
    }
]

# 2. 실제 함수 구현
def get_weather(location: str, unit: str = "celsius") -> dict:
    """실제로는 날씨 API를 호출"""
    # 예시 응답
    return {
        "location": location,
        "temperature": 5,
        "unit": unit,
        "condition": "맑음"
    }

def send_email(to: str, subject: str, body: str) -> dict:
    """실제로는 이메일 API를 호출"""
    return {"status": "sent", "to": to}

# 3. 함수 매핑
available_functions = {
    "get_weather": get_weather,
    "send_email": send_email
}

# 4. 대화 실행
def chat_with_tools(user_message: str):
    messages = [{"role": "user", "content": user_message}]

    # 첫 번째 API 호출
    response = openai.chat.completions.create(
        model="gpt-4",
        messages=messages,
        tools=tools,
        tool_choice="auto"
    )

    response_message = response.choices[0].message

    # 함수 호출이 필요한 경우
    if response_message.tool_calls:
        messages.append(response_message)

        for tool_call in response_message.tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)

            # 함수 실행
            function_response = available_functions[function_name](**function_args)

            # 결과를 메시지에 추가
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "name": function_name,
                "content": json.dumps(function_response, ensure_ascii=False)
            })

        # 최종 응답 생성
        final_response = openai.chat.completions.create(
            model="gpt-4",
            messages=messages
        )

        return final_response.choices[0].message.content

    return response_message.content

# 사용 예시
result = chat_with_tools("서울 날씨 알려주고, 팀장님께 오늘 재택근무한다고 이메일 보내줘")
print(result)

5-4. MCP (Model Context Protocol)

2024년 11월 Anthropic이 발표한 혁신:

MCP (Model Context Protocol):
"AI의 USB-C 포트"

문제:
- 각 도구마다 별도 연동 코드 필요
- N개 모델 × M개 도구 = N×M 통합 작업

해결:
- 표준화된 프로토콜
- 한 번 만들면 모든 AI에서 사용
- N + M 통합 작업으로 축소

핵심 구성:
├── MCP Host: AI 어시스턴트 (Claude, ChatGPT)
├── MCP Client: 연결 관리
├── MCP Server: 도구/데이터 제공
└── 표준 메시지 형식

MCP 활용 예시:

# MCP 서버 예시 (Python)
from mcp import Server, Tool

server = Server("my-tools")

@server.tool("read_file")
async def read_file(path: str) -> str:
    """파일 내용을 읽습니다."""
    with open(path, "r") as f:
        return f.read()

@server.tool("write_file")
async def write_file(path: str, content: str) -> str:
    """파일에 내용을 씁니다."""
    with open(path, "w") as f:
        f.write(content)
    return f"파일 저장 완료: {path}"

@server.tool("search_web")
async def search_web(query: str) -> list:
    """웹에서 정보를 검색합니다."""
    # Tavily API 호출
    results = tavily_search(query)
    return results

# 서버 실행
server.run()

6. Multi-Agent 시스템

6-1. Multi-Agent란?

정의:

Multi-Agent 시스템:
여러 전문화된 AI 에이전트가 협력하여
복잡한 작업을 수행하는 시스템

비유:
단일 에이전트 = 1인 기업
멀티 에이전트 = 전문가 팀

예시:
- 기획자 Agent: 전체 계획 수립
- 연구원 Agent: 정보 조사
- 작가 Agent: 콘텐츠 작성
- 편집자 Agent: 검토 및 수정
- 발행자 Agent: 최종 발행

6-2. Multi-Agent 협업 패턴

1. 계층적 (Hierarchical):

          ┌──────────────┐
          │   Manager    │
          │   Agent      │
          └──────┬───────┘
                 │
    ┌────────────┼────────────┐
    │            │            │
┌───▼───┐   ┌───▼───┐   ┌───▼───┐
│Worker │   │Worker │   │Worker │
│Agent A│   │Agent B│   │Agent C│
└───────┘   └───────┘   └───────┘

- Manager가 작업 분배
- Worker가 실행
- 결과를 Manager에게 보고

2. 순차적 (Sequential):

┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐
│ Agent A │ ─→ │ Agent B │ ─→ │ Agent C │ ─→ │ Agent D │
│ (기획)  │    │ (조사)  │    │ (작성)  │    │ (검토)  │
└─────────┘    └─────────┘    └─────────┘    └─────────┘

- 파이프라인 형태
- 각 에이전트가 다음에게 전달
- 워크플로우 명확

3. 협업적 (Collaborative):

        ┌─────────────────────────┐
        │       Shared State      │
        └────┬─────┬─────┬────────┘
             │     │     │
        ┌────▼─┐ ┌─▼───┐ ┌▼────┐
        │Agent│ │Agent│ │Agent│
        │  A  │ │  B  │ │  C  │
        └──┬──┘ └──┬──┘ └──┬──┘
           │       │       │
           └───────┴───────┘
                   │
              (토론/합의)

- 공유 상태 기반
- 에이전트 간 토론
- 합의 도출

6-3. 주요 Multi-Agent 프레임워크

CrewAI:

CrewAI:
"역할 기반 협업 AI 팀"

특징:
├── 직관적인 역할/목표 정의
├── 자동 작업 분배
├── 사용자 친화적
└── 빠른 프로토타이핑

코드 예시:
from crewai import Agent, Task, Crew

# 에이전트 정의
researcher = Agent(
    role="연구원",
    goal="최신 AI 트렌드 조사",
    backstory="10년 경력의 AI 연구원"
)

writer = Agent(
    role="작가",
    goal="쉽고 재미있는 글 작성",
    backstory="기술 블로그 전문 작가"
)

# 작업 정의
research_task = Task(
    description="2025년 AI Agent 트렌드 조사",
    agent=researcher
)

write_task = Task(
    description="조사 결과를 블로그 글로 작성",
    agent=writer
)

# Crew 실행
crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task]
)

result = crew.kickoff()

AutoGen (Microsoft):

AutoGen:
"대화 기반 멀티 에이전트"

특징:
├── 에이전트 간 대화로 협업
├── Human-in-the-loop 지원
├── 코드 실행 기능
└── 복잡한 워크플로우

코드 예시:
import autogen

# 설정
config = {"model": "gpt-4"}

# 에이전트 정의
assistant = autogen.AssistantAgent(
    name="assistant",
    llm_config=config
)

user_proxy = autogen.UserProxyAgent(
    name="user_proxy",
    human_input_mode="TERMINATE",
    code_execution_config={"work_dir": "coding"}
)

# 대화 시작
user_proxy.initiate_chat(
    assistant,
    message="피보나치 수열 100번째 값 계산해줘"
)

LangGraph:

LangGraph:
"그래프 기반 상태 관리 에이전트"

특징:
├── 복잡한 워크플로우 시각화
├── 조건부 분기 지원
├── 상태 관리 용이
└── LangChain 생태계 통합

코드 구조:
from langgraph.graph import StateGraph

# 상태 정의
class AgentState(TypedDict):
    messages: list
    next_agent: str

# 그래프 구성
graph = StateGraph(AgentState)

graph.add_node("researcher", researcher_node)
graph.add_node("writer", writer_node)
graph.add_node("reviewer", reviewer_node)

graph.add_edge("researcher", "writer")
graph.add_conditional_edges(
    "writer",
    should_review,
    {"review": "reviewer", "done": END}
)

app = graph.compile()

6-4. 프레임워크 비교

┌─────────────┬──────────────┬──────────────┬──────────────┐
│    항목     │   CrewAI     │   AutoGen    │  LangGraph   │
├─────────────┼──────────────┼──────────────┼──────────────┤
│ 협업 방식   │ 역할 기반    │ 대화 기반    │ 그래프 기반  │
│ 학습 곡선   │ 낮음         │ 중간         │ 높음         │
│ 유연성      │ 중간         │ 높음         │ 매우 높음    │
│ 상태 관리   │ 자동         │ 대화 기록    │ 명시적       │
│ 코드 실행   │ 제한적       │ 강력         │ 도구 통합    │
│ 시각화      │ 기본         │ 기본         │ 우수         │
├─────────────┼──────────────┼──────────────┼──────────────┤
│ 추천 용도   │ 빠른 MVP     │ 연구/실험    │ 프로덕션     │
│ 추천 대상   │ 입문자       │ 중급         │ 고급         │
└─────────────┴──────────────┴──────────────┴──────────────┘

7. LangChain Agent 실전 구현

7-1. LangChain Agent 기본 구조

# 필요 패키지
# pip install langchain langchain-openai langchain-community

from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.tools import Tool
from langchain_community.tools.tavily_search import TavilySearchResults

# 1. LLM 초기화
llm = ChatOpenAI(model="gpt-4", temperature=0)

# 2. 도구 정의
search_tool = TavilySearchResults(max_results=3)

def calculator(expression: str) -> str:
    """수학 계산을 수행합니다."""
    try:
        result = eval(expression)
        return str(result)
    except:
        return "계산할 수 없습니다."

tools = [
    search_tool,
    Tool(
        name="Calculator",
        func=calculator,
        description="수학 계산이 필요할 때 사용합니다. 입력은 수식입니다."
    )
]

# 3. 프롬프트 템플릿
prompt = ChatPromptTemplate.from_messages([
    ("system", """
    당신은 유능한 AI 어시스턴트입니다.
    사용자의 질문에 답하기 위해 필요한 도구를 사용하세요.
    항상 단계별로 생각하고, 정확한 정보를 제공하세요.
    """),
    MessagesPlaceholder(variable_name="chat_history", optional=True),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 4. 에이전트 생성
agent = create_openai_functions_agent(llm, tools, prompt)

# 5. 에이전트 실행기
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    max_iterations=10,
    handle_parsing_errors=True
)

# 6. 실행
result = agent_executor.invoke({
    "input": "2024년 엔비디아 시가총액을 검색하고, 애플과의 차이를 계산해줘"
})

print(result["output"])

7-2. LangGraph 기반 고급 Agent

from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage

# 상태 정의
class AgentState(TypedDict):
    messages: Annotated[list, add_messages]

# LLM + 도구 바인딩
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools(tools)

# 노드 함수들
def agent_node(state: AgentState):
    """에이전트 추론 노드"""
    response = llm_with_tools.invoke(state["messages"])
    return {"messages": [response]}

def tool_node(state: AgentState):
    """도구 실행 노드"""
    last_message = state["messages"][-1]
    tool_results = []

    for tool_call in last_message.tool_calls:
        # 도구 찾기 및 실행
        tool = next(t for t in tools if t.name == tool_call["name"])
        result = tool.invoke(tool_call["args"])

        tool_results.append(
            ToolMessage(
                content=str(result),
                tool_call_id=tool_call["id"]
            )
        )

    return {"messages": tool_results}

def should_continue(state: AgentState):
    """도구 호출이 필요한지 판단"""
    last_message = state["messages"][-1]

    if hasattr(last_message, "tool_calls") and last_message.tool_calls:
        return "tools"
    return END

# 그래프 구성
graph = StateGraph(AgentState)

# 노드 추가
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)

# 엣지 추가
graph.add_edge(START, "agent")
graph.add_conditional_edges(
    "agent",
    should_continue,
    {"tools": "tools", END: END}
)
graph.add_edge("tools", "agent")

# 컴파일
app = graph.compile()

# 실행
result = app.invoke({
    "messages": [HumanMessage(content="오늘 서울 날씨와 적합한 옷차림 추천해줘")]
})

print(result["messages"][-1].content)

7-3. 대화형 Agent (메모리 포함)

from langchain.memory import ConversationBufferMemory
from langchain.agents import AgentExecutor, create_openai_functions_agent

# 메모리 설정
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# 대화형 프롬프트
prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 친절한 AI 비서입니다. 이전 대화를 기억합니다."),
    MessagesPlaceholder(variable_name="chat_history"),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 에이전트 생성
agent = create_openai_functions_agent(llm, tools, prompt)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True
)

# 대화형 인터페이스
def chat(user_input: str):
    result = agent_executor.invoke({"input": user_input})
    return result["output"]

# 사용
print(chat("내 이름은 홍길동이야"))
# → "안녕하세요, 홍길동님!"

print(chat("내 이름이 뭐라고 했지?"))
# → "홍길동이라고 하셨습니다!"  # 이전 대화 기억

8. 실전 자동화 에이전트 구축

8-1. 프로젝트 구조

my-ai-agent/
├── agents/
│   ├── __init__.py
│   ├── researcher.py      # 조사 에이전트
│   ├── writer.py          # 작성 에이전트
│   └── reviewer.py        # 검토 에이전트
├── tools/
│   ├── __init__.py
│   ├── search.py          # 웹 검색
│   ├── file_ops.py        # 파일 작업
│   └── email.py           # 이메일 발송
├── workflows/
│   ├── __init__.py
│   └── content_pipeline.py # 콘텐츠 생성 파이프라인
├── config.py
├── main.py
└── requirements.txt

8-2. 콘텐츠 자동 생성 에이전트

# workflows/content_pipeline.py

from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
from tools.search import search_tool
from tools.file_ops import write_file_tool

# LLM 설정
llm = ChatOpenAI(model="gpt-4", temperature=0.7)

# 1. 연구원 에이전트
researcher = Agent(
    role="Senior AI Researcher",
    goal="최신 AI 트렌드와 기술에 대한 심층 조사 수행",
    backstory="""
    당신은 10년 경력의 AI 연구원입니다.
    복잡한 기술 주제를 조사하고 핵심을 파악하는 데 뛰어납니다.
    항상 신뢰할 수 있는 출처에서 정보를 수집합니다.
    """,
    tools=[search_tool],
    llm=llm,
    verbose=True
)

# 2. 작가 에이전트
writer = Agent(
    role="Tech Blog Writer",
    goal="전문적이면서도 이해하기 쉬운 블로그 글 작성",
    backstory="""
    당신은 기술 블로그 전문 작가입니다.
    복잡한 기술을 일반인도 이해할 수 있게 설명하는 능력이 있습니다.
    SEO를 고려한 구조화된 글을 작성합니다.
    """,
    llm=llm,
    verbose=True
)

# 3. 편집자 에이전트
editor = Agent(
    role="Content Editor",
    goal="글의 품질과 정확성 검토 및 개선",
    backstory="""
    당신은 꼼꼼한 편집자입니다.
    문법, 논리적 흐름, 사실 정확성을 검토합니다.
    독자 관점에서 글의 가독성을 평가합니다.
    """,
    llm=llm,
    verbose=True
)

# 작업 정의
def create_content_tasks(topic: str):
    research_task = Task(
        description=f"""
        다음 주제에 대해 심층 조사하세요: {topic}

        조사 내용:
        1. 최신 동향과 트렌드
        2. 주요 기술과 개념
        3. 실제 사용 사례
        4. 미래 전망
        5. 신뢰할 수 있는 출처 목록

        결과물: 구조화된 조사 보고서
        """,
        agent=researcher,
        expected_output="상세한 조사 보고서 (Markdown 형식)"
    )

    writing_task = Task(
        description=f"""
        조사 결과를 바탕으로 블로그 글 작성:

        요구사항:
        1. 3000자 이상의 심층 분석
        2. SEO 최적화 (H2, H3 소제목 사용)
        3. 실용적인 예시 포함
        4. 독자 참여 유도 결론

        결과물: 완성된 블로그 포스트
        """,
        agent=writer,
        expected_output="SEO 최적화된 블로그 포스트 (Markdown)",
        context=[research_task]
    )

    editing_task = Task(
        description="""
        작성된 글을 다음 기준으로 검토하고 개선:

        1. 문법 및 맞춤법 확인
        2. 논리적 흐름 검토
        3. 사실 정확성 확인
        4. 가독성 개선 제안
        5. SEO 최적화 확인

        결과물: 최종 수정된 블로그 포스트
        """,
        agent=editor,
        expected_output="최종 검토된 블로그 포스트",
        context=[writing_task]
    )

    return [research_task, writing_task, editing_task]

# Crew 생성 및 실행
def generate_content(topic: str):
    tasks = create_content_tasks(topic)

    crew = Crew(
        agents=[researcher, writer, editor],
        tasks=tasks,
        process=Process.sequential,  # 순차 실행
        verbose=True
    )

    result = crew.kickoff()
    return result

# 메인 실행
if __name__ == "__main__":
    topic = "2025년 AI Agent 기술 동향"
    final_content = generate_content(topic)

    # 파일 저장
    with open(f"output/{topic}.md", "w") as f:
        f.write(final_content)

    print("콘텐츠 생성 완료!")

8-3. 이메일 자동화 에이전트

# 이메일 분류 및 응답 자동화 에이전트

from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.tools import Tool
import json

llm = ChatOpenAI(model="gpt-4", temperature=0)

# 도구 정의
def classify_email(email_content: str) -> dict:
    """이메일을 분류합니다."""
    categories = ["긴급", "일반", "스팸", "문의", "불만"]
    # 실제로는 LLM이나 분류 모델 사용
    return {"category": "문의", "priority": "high"}

def draft_response(email_data: str) -> str:
    """이메일 응답 초안을 작성합니다."""
    data = json.loads(email_data)
    # 실제로는 템플릿 + LLM 조합
    return f"""
    안녕하세요,

    문의해 주셔서 감사합니다.
    {data.get('topic', '해당 건')}에 대해 검토 후 
    24시간 내에 답변 드리겠습니다.

    감사합니다.
    """

def send_email(email_json: str) -> str:
    """이메일을 발송합니다."""
    data = json.loads(email_json)
    # 실제로는 SMTP 또는 API 사용
    return f"이메일 발송 완료: {data['to']}"

def log_action(action_data: str) -> str:
    """작업을 로그에 기록합니다."""
    # 실제로는 DB 또는 로그 시스템
    return "로그 기록 완료"

tools = [
    Tool(name="ClassifyEmail", func=classify_email,
         description="이메일 내용을 분석하여 카테고리와 우선순위를 분류"),
    Tool(name="DraftResponse", func=draft_response,
         description="이메일 응답 초안 작성. JSON 형식 입력"),
    Tool(name="SendEmail", func=send_email,
         description="이메일 발송. JSON: {to, subject, body}"),
    Tool(name="LogAction", func=log_action,
         description="작업 내용을 시스템에 기록")
]

# 에이전트 설정
prompt = ChatPromptTemplate.from_messages([
    ("system", """
    당신은 이메일 관리 AI 비서입니다.

    수신된 이메일을 분석하고:
    1. 카테고리와 우선순위 분류
    2. 적절한 응답 초안 작성
    3. 긴급 건은 알림
    4. 모든 작업 로그 기록

    항상 친절하고 전문적인 톤을 유지하세요.
    """),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

agent = create_openai_functions_agent(llm, tools, prompt)
email_agent = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 실행 예시
incoming_email = """
발신자: customer@example.com
제목: 제품 환불 문의

안녕하세요,
지난주 구매한 제품에 문제가 있어 환불을 요청드립니다.
빠른 처리 부탁드립니다.
"""

result = email_agent.invoke({
    "input": f"다음 이메일을 처리해주세요:\n\n{incoming_email}"
})

print(result["output"])

8-4. 성능 최적화 팁

1. 비용 관리:
   ☑ 간단한 작업은 GPT-3.5 사용
   ☑ 복잡한 추론만 GPT-4 사용
   ☑ 캐싱으로 중복 호출 방지
   ☑ 토큰 사용량 모니터링

2. 안정성 향상:
   ☑ 재시도 로직 (exponential backoff)
   ☑ 타임아웃 설정
   ☑ Fallback 전략
   ☑ 에러 핸들링

3. 보안:
   ☑ API 키 환경 변수 관리
   ☑ 민감 정보 필터링
   ☑ 권한 최소화 원칙
   ☑ 감사 로그 기록

4. 모니터링:
   ☑ LangSmith로 추적
   ☑ 성공/실패율 대시보드
   ☑ 응답 시간 측정
   ☑ 비용 추적

FAQ: AI Agent Q&A

Q1. AI Agent와 RPA의 차이점은?

A. 지능과 자율성의 차이:

RPA (Robotic Process Automation):
- 규칙 기반 자동화
- 미리 정의된 워크플로우
- 예외 상황 처리 어려움
- "만약 A이면 B를 해라"

AI Agent:
- 추론 기반 자동화
- 목표만 주면 스스로 계획
- 예외 상황 자율 처리
- "목표 X를 달성해라"

결합:
- AI Agent + RPA = Intelligent Automation
- Agent가 판단, RPA가 실행
- 복잡한 비즈니스 프로세스 자동화

Q2. AI Agent 도입 시 주의할 점은?

A. 점진적 접근과 가드레일:

1. 점진적 도입:
   - 간단한 작업부터 시작
   - 성공 후 복잡한 작업으로 확장
   - 파일럿 → 검증 → 확대

2. Human-in-the-loop:
   - 중요 결정은 사람이 승인
   - 자동 실행 범위 제한
   - 긴급 중단 버튼 마련

3. 가드레일:
   - 비용 한도 설정
   - 실행 횟수 제한
   - 민감 작업 차단

4. 모니터링:
   - 모든 행동 로깅
   - 이상 행동 감지
   - 정기적 성과 평가

Q3. 어떤 프레임워크로 시작해야 하나요?

A. 목적에 따라:

초보자:
→ LangChain Agent (풍부한 문서, 커뮤니티)

빠른 MVP:
→ CrewAI (직관적, 역할 기반)

연구/실험:
→ AutoGen (대화 기반, 유연)

프로덕션:
→ LangGraph (상태 관리, 복잡한 워크플로우)

엔터프라이즈:
→ Vertex AI Agent Builder (Google)
→ Amazon Bedrock Agents
→ Azure AI Agent Service

Q4. AI Agent의 미래는?

A. 2025년 이후 전망:

1. Agentic AI 시대:
   - 자율적 의사결정 확대
   - 업무 15%가 AI 자율 처리 (2028)

2. Multi-Agent 협업:
   - 전문 에이전트 팀
   - 자동 역할 분배
   - 복잡한 문제 해결

3. MCP 표준화:
   - 모든 도구 통합
   - 플러그 앤 플레이
   - 생태계 확장

4. 산업별 특화:
   - 의료 진단 에이전트
   - 법률 분석 에이전트
   - 금융 트레이딩 에이전트

외부 참고 자료

AI Agent를 더 깊게 배우고 싶다면:


최종 정리: AI Agent 마스터

핵심 메시지:

✅ AI Agent = LLM + Tools + Orchestration
✅ ReAct: 생각 → 행동 → 관찰 → 반복
✅ Function Calling: AI의 손과 발
✅ Multi-Agent: 전문가 팀 협업
✅ MCP: AI의 USB-C 포트 (표준화)
✅ 2028년 업무 15%가 AI 자율 처리
✅ LangChain/CrewAI/LangGraph로 구현

실전 체크리스트:

Agent 구축 시:
☑ 명확한 목표 정의
☑ 필요한 도구 식별
☑ 오케스트레이션 방식 선택
☑ 가드레일 설정
☑ Human-in-the-loop 설계
☑ 모니터링/로깅 구축

성능 최적화:
☑ 비용 관리 (모델 선택)
☑ 재시도 로직
☑ 캐싱 전략
☑ 병렬 처리

같이보기

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다