AI Agent Development and Optimization Series (Part 1): Creating First Agent

작성자: Finnick Huo
2025년 9월 8일

AI 에이전트는 자동화의 새로운 프런티어를 대표하며, 스스로 추론하고 계획하며 자율적으로 행동을 실행할 수 있는 지능형 시스템의 잠재력을 보여줍니다. 이 분야는 빠르게 진화하고 있으며, 개발자와 연구자들은 효과적인 에이전트 시스템을 구축하기 위한 다양한 접근 방식을 탐구하고 있습니다. 각 방식은 저마다의 장단점과 고려사항을 가지고 있습니다.

이번 글에서는 실습 예제를 통해 AI 에이전트의 기본을 이해할 수 있는 실질적인 접근법을 소개합니다. 에이전트를 만드는 데 “정답”은 없지만, 핵심 개념을 쉽게 익히고 직접 간단하면서도 작동 가능한 에이전트를 만들어볼 수 있는 직관적인 방법론을 다뤄보겠습니다.

여기서 다루는 기법과 인사이트는 급변하는 에이전트 개발 환경 속에서 하나의 관점일 뿐입니다. 이 가이드를 마치면 여러분은 동작하는 에이전트를 직접 경험하게 되고, 다른 접근법과 최적화 전략을 탐구할 수 있는 기초 지식을 얻게 될 것입니다.


AI 에이전트란 무엇인가?

AI 에이전트는 환경을 인지하고, 문제를 추론하며, 특정 목표를 달성하기 위해 행동할 수 있는 자율 시스템입니다. 사전에 정해진 경로만 따르는 전통적 소프트웨어와 달리, 에이전트는 상황과 결과에 따라 행동을 적응시킬 수 있습니다.

AI 에이전트를 정의하는 핵심 특성은 다음과 같습니다:

  • 자율성 (Autonomy): 지속적인 인간 개입 없이 독립적으로 작동
  • 반응성 (Reactivity): 환경의 변화에 적절히 반응
  • 능동성 (Proactivity): 목표 달성을 위해 주도적으로 행동
  • 사회적 능력 (Social ability): 필요 시 다른 에이전트나 인간과 상호작용

이러한 능력 덕분에 AI 에이전트는 의사결정, 다단계 문제 해결, 변화하는 조건에 대한 동적 적응이 필요한 작업에 특히 강력합니다.


에이전트의 기본 원리 이해하기

최적화 전략을 논하기 전에, 먼저 AI 에이전트가 어떻게 작동하는지 명확히 이해해야 합니다. 아래 다이어그램은 가장 단순한 에이전트 처리 흐름을 보여줍니다:

  1. 요청 수신: 사용자가 입력이나 쿼리를 제공
  2. 분석 및 계획: AI 모델이 어떤 행동을 취할지 결정
  3. 도구 실행: 에이전트가 적절한 함수나 API 호출
  4. 결과 반환: 처리된 정보를 사용자에게 전달

주의: 이는 기본적인 에이전트 워크플로우일 뿐입니다. 더 강력한 시스템은 ReAct (Reasoning and Acting) 패러다임이나 Plan-and-Execute 같은 방식을 채택합니다.

실제 복잡성은 에이전트가 다음과 같은 상황을 처리할 때 발생합니다:

  • 연속적인 여러 도구 호출
  • 오류 처리 및 복구
  • 대화 맥락 관리
  • 중간 결과에 따른 동적 의사결정

간단한 에이전트 예제

퍼포먼스 문제의 기원이 어디서 오는지 이해하기 위해, 기초적인 예제부터 시작해봅시다. 여기서는 LangGraph를 사용하지만, 원리는 다른 에이전트 프레임워크에도 적용됩니다.

도구 만들기

import time
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

from dotenv import load_dotenv
import os

load_dotenv()

# 간단한 도구 정의
@tool
def get_user_info(user_id: str) -> str:
    """
    사용자에 대한 기본 정보를 가져옵니다.
    
    매개변수:
    - user_id: 조회할 사용자의 ID 또는 이름.

    반환:
         사용자 정보를 포함한 문자열.
    """
    # API 호출 시뮬레이션
    return f"User {user_id}: Active account, Premium tier"

에이전트 만들기

# ReAct 패턴을 활용한 기본 에이전트 생성
model = ChatOpenAI(
    model=os.getenv("MODEL_NAME", "openai/gpt-4o"),
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url=os.getenv("MODEL_BASE_URL")
)

simple_agent = create_react_agent(
    model=model,
    tools=[get_user_info],
    prompt="You are a helpful assistant that can look up user information."
)

이 에이전트는 LangGraph의 create_react_agent 함수로 만들어졌으며, ReAct 패턴을 구현합니다. 이 패턴은 에이전트가 **추론(reasoning)**과 **행동(acting)**을 번갈아 수행할 수 있게 합니다.


에이전트 테스트하기

# 전체 시간 측정
start_time = time.time()

# 에이전트 테스트
result = simple_agent.invoke({
    "messages": [("user", "What's the status of user Bob?")]
})

end_time = time.time()
elapsed = end_time - start_time

print(result) # 결과 전체 출력
print(f"Total time consumption: {elapsed:.2f} seconds")

에이전트 출력 이해하기

코드를 실행하면, 에이전트는 요청을 내부적으로 처리하는 과정을 구조화된 응답으로 보여줍니다. 주요 결과는 다음과 같습니다 (불필요한 로그 생략):

{
    "messages": [
        HumanMessage(content="What's the status of user Bob?"),
        AIMessage(
            content="",
            response_metadata={
                "token_usage": {
                    "completion_tokens": 57,
                    "prompt_tokens": 176,
                    "total_tokens": 233
                },
                "finish_reason": "tool_calls"
            },
            tool_calls=[
                {
                    "name": "get_user_info",
                    "args": {"user_id": "Bob"}
                }
            ]
        ),
        ToolMessage(content="User Bob: Active account, Premium tier"),
        AIMessage(
            content="User **Bob** currently has an **active** account and is on the **Premium tier**.",
            response_metadata={
                "token_usage": {
                    "completion_tokens": 62,
                    "prompt_tokens": 218,
                    "total_tokens": 280
                },
                "finish_reason": "stop"
            }
        )
    ]
}

Total time consumption: 3.79 seconds

에이전트의 추론 과정 분석

출력은 네 가지 주요 메시지 유형으로 구성됩니다. 이는 ReAct 패턴을 따르는 에이전트 프레임워크에서 표준적인 순서입니다:

  1. HumanMessage
    • 사용자의 최초 요청
    • 에이전트가 이 메시지를 받아 AI 모델에 전달
  2. 첫 번째 AIMessage
    • 모델이 입력을 검토하고 도구 호출이 필요하다고 판단
    • 도구 이름, 매개변수, 토큰 사용량 메타데이터 포함
    • 예: 첫 요청에서 총 233 토큰 사용
  3. ToolMessage
    • 에이전트가 지정된 도구를 실행
    • 실행 결과가 메시지로 반환
  4. 두 번째 AIMessage
    • 모델이 도구의 출력을 받아 사용자에게 제공할 최종 응답을 생성
    • 읽기 좋은 형식으로 결과를 정리
    • 두 번째 응답에서는 총 280 토큰 사용

요약:
이 쿼리는 3.79초 만에 완료되었습니다. 토큰 사용량과 응답 시간은 아직 합리적인 수준입니다.


내가 만든 것 이해하기

축하합니다! 이제 여러분은 자율 시스템의 핵심 원리를 보여주는 동작하는 AI 에이전트를 직접 만들어보았습니다. 이 에이전트는 다음을 할 수 있습니다:

  • 요청을 해석하고 도구 사용 여부를 스스로 결정
  • 적절한 매개변수로 함수를 자동 실행
  • 사용자 친화적인 응답을 포맷팅
  • 합리적인 리소스 사용량으로 효율적 작업 수행

즉, 요청 → 추론 → 행동 → 응답 이라는 기본 패턴을 경험한 것입니다. 단순하지만, 이 패턴은 훨씬 더 복잡한 시스템으로 확장될 수 있습니다.


에이전트 개발에서 얻은 핵심 인사이트

  • 도구 통합: @tool 데코레이터와 명확한 문서화는 모델이 함수를 이해하고 효과적으로 사용할 수 있게 합니다.
  • ReAct 패턴: 추론과 행동의 반복은 문제를 체계적으로 분해하고 해결하는 데 도움을 줍니다.
  • 성능 인식: 토큰 사용량과 응답 시간을 모니터링하면 에이전트 운영의 계산 비용을 이해할 수 있습니다.

다음 단계

이제 더 정교한 과제에 도전할 준비가 되었습니다. 2부에서는 에이전트가 여러 도구와 복잡한 의사결정을 다룰 때 어떤 일이 벌어지는지, 그리고 시스템이 커질수록 왜 성능 최적화가 중요한지 살펴보겠습니다.

메일: salesinquiry@enterprisedb.com