홈으로 돌아가기

AI 에이전트: Python에서의 아키텍처와 구현

이 기사는 개발자를 위한 AI 에이전트 아키텍처를 설명: 구성 요소(LLM, 도구, 메모리, 플래너), ReAct 패턴, 다중 에이전트 시스템 및 LangChain을 사용한 Python 실습 구현.

AI 에이전트: 이론에서 작동 코드까지
Advertisement 728x90

AI 에이전트 구축 방법: 아키텍처, ReAct, 그리고 Python을 활용한 실용적 구현

AI 에이전트는 단순히 '스마트 챗봇'이 아니라, 계획 수립, 도구 선택, 외부 호출 수행, 그리고 실시간으로 행동을 조정할 수 있는 자율 시스템입니다. RAG이 생성 전에 단지 맥락만 제공하는 반면, 에이전트는 목표 분석부터 최종 결과까지 자체 점검을 포함한 전체 과제 해결 주기를 관리합니다. 이는 특히 API, 코드, 데이터베이스 또는 외부 서비스와의 다단계 상호작용이 필요한 시나리오에서 개발자들에게 근본적으로 새로운 수준의 자동화를 제공합니다.

복잡한 작업에 RAG이 부족한 이유

RAG은 외부 소스를 통해 지식을 업데이트하는 특정 문제를 해결하지만, 정적인 방식으로 작동합니다. 모델은 일회성으로 조각들을 받아 답변을 생성할 뿐, 결과가 부적합할 경우 재조회하거나 중간 출력의 신뢰성을 평가하거나 재계획하는 메커니즘은 없습니다. 현실 세계의 워크플로우에서는 이러한 한계가 매우 중요합니다:

  • 기술 문서를 분석할 때는 링크를 순차적으로 따라가며 다양한 파일에서 코드를 추출하고 검증해야 합니다.
  • Excel 데이터를 기반으로 보고서를 생성할 때는 먼저 테이블을 읽고, 지표를 결정한 후 이를 계산하고 마지막으로 결과를 포맷해야 합니다.
  • CI/CD를 자동화할 때는 오류 로그를 해석하고 진단을 실행한 뒤 수정을 적용하고 결과를 확인해야 합니다.

이러한 모든 시나리오는 단일 생성을 넘어섭니다. 바로 여기서 동적 아키텍처—즉, 에이전트—가 필요합니다.

Google AdInline article slot

현대 AI 에이전트의 핵심 구성 요소

에이전트는 하나의 거대한 몸체가 아닙니다. 서로 협력하는 모듈들의 조화로운 시스템이며, 각 구성 요소는 명확히 정의된 기능을 수행하며 전체 로직을 다시 작성하지 않고도 교체하거나 확장할 수 있습니다.

LLM: 의사결정의 핵심

모델은 최종 답변을 직접 생성하는 것이 아니라 ‘뇌’ 역할을 합니다. 계획을 세우고 도구를 선택하며 호출 결과를 해석하고 다음 단계를 결정합니다. 모델의 역할은 텍스트 생산이 아닌 전략적 관리입니다.

Google AdInline article slot

도구: 환경과의 인터페이스

이는 HTTP 요청을 통한 REST API 호출, 샌드박스에서의 Python 코드 실행, 파일 읽기/쓰기, SQL 쿼리 실행, CLI 유틸리티 호출 등 모든 외부 기능을 의미합니다. 도구는 명확한 설명(문서 문자열), 타입 지정된 인수, 그리고 오류 처리 기능을 갖추어야만 LLM이 안전하게 사용할 수 있습니다.

메모리: 단기 및 장기

Google AdInline article slot

단기 메모리는 현재 대화 컨텍스트와 중간 결과(예: 생성된 리소스의 ID)로 구성됩니다. 장기 메모리는 벡터 기반 지식 베이스, 캐시된 응답, 그리고 사용자 세션의 과거 데이터를 포함합니다. 이를 통해 에이전트는 호출 간의 맥락을 기억하고 경험을 바탕으로 학습할 수 있습니다.

플래너와 오류 컨트롤러

플래너는 목표를 단계별로 나누고 진행 상황을 추적하며 루프를 방지합니다. 오류 컨트롤러는 도구 결과의 유효성을 검증하고, 출처와 비교하여 사실을 확인하며 문제가 발생하면 재시도를 시작합니다. 이러한 구성 요소가 없으면 에이전트는 불안정하고 예측 불가능합니다.

ReAct: LLM을 위한 투명한 행동 패턴

ReAct(Reason + Act + Observe)는 프레임워크가 아니라, 명확한 에이전트 워크플로우 주기를 정의하는 행동 템플릿입니다. 이는 모델의 내부 추론 과정을 가시적이고 제어 가능하게 만듭니다:

  • Reason—모델은 현재 상태를 분석하고 다음 행동에 대한 가설을 세우며 그 필요성을 설명합니다.
  • Act—모델은 특정 인수를 전달하여 도구를 호출합니다.
  • Observe—모델은 호출 결과를 받고 해당 결과가 과제에 적합한지 평가합니다.

이 사이클은 목표가 달성될 때까지 반복됩니다. 예를 들어, 라이브러리가 Python 3.12과 호환되는지 정보를 찾을 때, 모델은 먼저 PyPI와 GitHub를 확인해야 한다고 ‘reason’하고, 이후 get_pypi_info('requests')를 호출하여 ‘act’하며, ‘observe’한 뒤 저장소의 소스 코드를 분석할지 여부를 결정합니다.

ReAct의 장점은 재현성과 디버깅 가능성입니다. 모든 단계—계획 → 호출 → 결과 → 새로운 결정—가 로그로 남습니다. 이는 감사와 추적이 필수인 프로덕션 시스템에서 매우 중요합니다.

멀티에이전트 시스템: 특화를 통한 확장

단일 범용 에이전트는 복잡성이 증가함에 따라 금세 한계에 부딪힙니다. 멀티에이전트 시스템(MAS)은 역할을 분담함으로써 이를 해결합니다. 하나의 거대한 몸체 대신, 오케스트레이터가 조율하는 전문 에이전트 팀이 존재합니다.

MAS에서 일반적으로 볼 수 있는 역할은 다음과 같습니다:

  • 플래너—목표를 분해하고 하위 작업의 순서를 결정하며 실행자에게 할당합니다.
  • 리서처—API, 문서, 데이터베이스 등 외부 소스를 다룹니다.
  • 엑시큐터—코드를 실행하고 파일을 수정하며 설정을 적용합니다.
  • 밸리데이터—결과의 정확성, 요구 사항 준수 여부, 그리고 안전성을 확인합니다.

오케스트레이터는 결과를 수집하고 갈등을 해결하며 최종 답변을 구성합니다. 이 접근법은 세 가지 주요 장점을 제공합니다:

  • 병렬성: 여러 에이전트가 독립적인 하위 작업을 동시에 처리할 수 있습니다.
  • 신뢰성 향상: 밸리데이터가 엑시큐터가 놓칠 수 있는 오류를 잡아냅니다.
  • 디버깅 용이성: 한 역할에서 실패하더라도 전체 시스템이 마비되지 않습니다.

하지만 MAS는 잘 설계된 상호작용 프로토콜과 순환 의존성에 대한 보호가 필요합니다. 예를 들어, 리서처가 밸리데이터로부터 데이터를 요청하지만 밸리데이터는 리서처의 확인을 기다리는 경우처럼 말입니다.

실습: LangChain을 활용한 최소한의 어시스턴트 에이전트

날씨를 조회하고, 이벤트를 찾아내며, 이메일을 보내는 간단하면서도 완전한 기능을 갖춘 에이전트를 만들어 보겠습니다. 목표는 프로덕션 준비된 솔루션을 만드는 것이 아니라, 구성 요소들이 어떻게 하나의 통합 시스템으로 결합되는지를 보여주는 것입니다.

모델과 환경 초기화

Qwen 3.5 (9B)를 Ollama를 통해 사용하겠습니다. 이 모델은 에이전트 작업에 충분히 강력하면서도 Google Colab에서 실행하기에 충분히 작은 크기입니다. 연결은 표준 방식으로 이루어집니다:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="qwen3.5:9b",
    base_url="http://localhost:11434/v1",
    api_key="ollama",
    temperature=0.3,
)

도구 정의

각 도구는 @tool로 장식된 Python 함수로, 명확한 문서 문자열과 타입 지정된 인수를 갖추어야 합니다. 예를 들어, get_weather:

@tool
def get_weather(city: str) -> str:
    """지정된 도시의 현재 날씨를 반환합니다.
러시아어 또는 영어로 된 도시 이름을 입력하세요."""
    # ... Open-Meteo API를 이용한 구현
    return f"{name}: {weather['temperature_2m']}°C, {desc}, wind {weather['wind_speed_10m']} km/h"

함수가 네트워크 오류, 존재하지 않는 도시, 잘못된 날씨 코드 등을 처리하도록 하는 것이 중요합니다. 그렇지 않으면 에이전트가 예상된 답변 대신 비구조화된 텍스트를 받게 됩니다.

사용자 프롬프트와 컨텍스트

프롬프트는 역할, 제약 조건, 그리고 응답의 톤을 정의합니다. 기술적인 에이전트의 경우, 다음 사항을 명시적으로 언급하는 것이 중요합니다:

  • 어떤 도구가 사용 가능하며 언제 사용해야 하는지;
  • 오류가 발생했을 때 어떻게 해야 하는지(재시도, 사용자에게 추가 정보 요청, 혹은 거절);
  • 최종 답변을 어떻게 포맷할 것인지(예: JSON만, 설명 없음).

USER_CONTEXT에는 개인화된 데이터—이름, 선호 사항, 상호작용 이력—가 포함됩니다. 이를 통해 에이전트는 톤과 세부 수준을 맞춤화할 수 있습니다.

무엇이 중요한가

  • AI 에이전트는 확장된 프롬프트를 가진 LLM이 아닙니다. 구성 요소들 간에 명확한 책임 분배가 이루어지는, 아키텍처적으로 복잡한 시스템입니다.
  • ReAct는 단순한 ‘기능’이 아니라, 프로덕션에서 투명성, 디버깅 가능성, 그리고 안전성을 보장하기 위해 반드시 필요한 패턴입니다.
  • 도구는 타입 지정되고 문서화되어야 하며 오류에 강해야 합니다. 그렇지 않으면 에이전트가 실행을 제어하지 못하게 됩니다.
  • 멀티에이전트 시스템은 트렌드 때문이 아니라, 복잡성을 확장하기 위해 필요합니다. 한 에이전트만으로는 수십 개의 도구와 소스를 신뢰성 있게 관리할 수 없습니다.
  • 프로덕션 에이전트에는 추적 메커니즘, 워크플로우의 모든 단계를 로그로 기록하는 기능, 그리고 입출력 데이터의 엄격한 검증이 필수적입니다.

— Editorial Team

Advertisement 728x90

다음 읽기