웹을 탐색하고 데이터를 추출할 수 있는 AI 에이전트를 구축하는 방법
요약
Python과 Playwright, LLM API를 활용하여 자율적으로 웹을 탐색하고 데이터를 추출하는 AI 에이전트 구축 방법을 설명하는 튜토리얼입니다. 브라우저 컨트롤러, LLM 기반의 의사결정 구조, 그리고 실행 루프를 설계하는 과정을 단계별로 다룹니다.
핵심 포인트
- Playwright를 사용하여 현대적인 웹 사이트 자동화 구현
- LLM을 에이전트의 '두뇌'로 활용하여 다음 행동 결정
- 관찰-결정-행동의 반복 루프를 통한 자율적 작업 수행
- 구조화된 JSON 데이터 추출 및 페이지 탐색 기능 구현
서론 (Introduction)
자율적으로 웹을 탐색할 수 있는 AI 에이전트는 더 이상 공상 과학이 아닙니다. 적절한 도구만 있다면 웹사이트를 탐색하고, 구조화된 데이터를 추출하며, 인간의 개입 없이 결정을 내리는 에이전트를 구축할 수 있습니다. 이 튜토리얼에서는 Python, 헤드리스 브라우저 (headless browser), 그리고 LLM API를 사용하여 웹 브라우징 AI 에이전트를 처음부터 구축해 보겠습니다.
우리가 구축할 에이전트는 다음과 같은 작업을 수행할 수 있습니다:
- 모든 URL로 이동
- 페이지 콘텐츠 읽기
- 자연어 지침에 기반하여 특정 데이터 추출
- 링크를 따라가고 결과 페이지를 넘기며 탐색 (paginate)
- 추출된 데이터를 구조화된 JSON으로 저장
준비물 (What You'll Need)
- Python 3.10 이상
- LLM API 키 (OpenAI, Anthropic, 또는 로컬 Ollama)
- 브라우저 자동화를 위한 Playwright
- Python 및 웹 개념에 대한 기본적인 이해
1단계: 환경 설정 (Step 1: Setting Up the Environment)
먼저, 의존성 패키지들을 설치해 보겠습니다:
pip install playwright openai beautifulsoup4
playwright install chromium
우리는 Selenium보다 더 신뢰할 수 있고 현대적인 JavaScript 중심의 사이트들을 잘 처리하는 Playwright를 브라우저 자동화에 사용할 것입니다. LLM의 경우 OpenAI의 API를 사용하겠지만, 동일한 패턴은 어떤 LLM 제공업체와도 작동합니다.
2단계: 브라우저 컨트롤러 (Step 2: The Browser Controller)
브라우저 컨트롤러는 기초가 되는 부분으로, 에이전트에게 눈과 손을 제공합니다. URL로 이동하고, 페이지 콘텐츠를 읽으며, 요소(elements)와 상호작용할 수 있습니다.
import asyncio
from playwright.async_api import async_playwright
...
컨트롤러는 navigate(이동), read text(텍스트 읽기), click elements(요소 클릭), get links(링크 가져오기), take screenshots(스크린샷 찍기)와 같은 간단한 API를 노출합니다. 에이전트는 이러한 기본 기능(primitives)을 사용하여 웹을 탐색할 것입니다.
3단계: 에이전트 두뇌 (Step 3: The Agent Brain)
두뇌는 현재 페이지 콘텐츠를 수신하고 다음에 무엇을 할지 결정하는 LLM입니다. 우리는 다음과 같은 간단한 루프를 사용할 것입니다: 페이지 읽기, LLM에게 무엇을 할지 질문하기, 동작 실행하기, 반복하기.
import json
from openai import AsyncOpenAI
...
두뇌는 마지막 10개의 메시지를 컨텍스트 (Context)로 사용합니다. 이는 컨텍스트 윈도우 (Context Window)를 초과하지 않으면서도 자신이 수행한 일을 기억하기에 충분한 양입니다. 온도는 낮게 (0.2) 유지되는데, 이는 에이전트가 창의적이기보다는 예측 가능하기를 원하기 때문입니다.
4단계: 에이전트 루프 (Agent Loop)
이제 두뇌를 브라우저에 연결합니다. 에이전트 루프는 시스템의 핵심입니다. 에이전트는 목표가 달성되거나 반복 횟수가 소진될 때까지 관찰하고, 결정하고, 행동하는 과정을 반복합니다.
class WebAgent:
def __init__(self, api_key: str, goal: str, max_steps: int = 20):
self.browser = BrowserController()
...
5단계: 에이전트 실행하기
실제 작업, 즉 블로그에서 모든 기사 제목을 추출하는 작업을 통해 에이전트를 테스트해 보겠습니다:
async def main():
agent = WebAgent(
api_key="sk-...",
...
6단계: 프로덕션 환경 준비하기 (Production-Ready)
기본적인 에이전트는 작동하지만, 프로덕션 (Production) 환경에서 사용하려면 다음 사항들이 필요합니다:
에러 핸들링 (Error handling): 브라우저 타임아웃 (Timeout), 네트워크 오류, LLM API 제한 등은 모두 발생할 수 있습니다. 모든 동작을 재시도 로직이 포함된 try/except 블록으로 감싸세요.
속도 제한 (Rate limiting): 웹사이트를 과도하게 공격하지 마세요. 동작 사이에 지연 시간 (최소 1~2초)을 추가하고 robots.txt를 준수하세요.
스텔스 (Stealth): 많은 사이트가 헤드리스 브라우저 (Headless browser)를 차단합니다. 기본 Chromium 대신 Camoufox (Firefox 기반의 안티 디텍트 브라우저)와 같은 스텔스 브라우저를 사용하세요.
비용 제어 (Cost control): 각 LLM 호출에는 비용이 발생합니다. 페이지 콘텐츠를 캐싱 (Cache)하고, 공격적으로 내용을 잘라내며 (Truncate), 단순한 결정에는 더 저렴한 모델을 사용하세요.
구조화된 추출 (Structured extraction): LLM에게 가공되지 않은 HTML에서 데이터를 추출하라고 요청하는 대신, CSS 선택자 (CSS selectors)와 LLM 추출을 결합하여 사용하세요. 이 방식이 더 신뢰할 수 있고 저렴합니다.
7단계: 고급 패턴
다중 페이지 탐색 (Multi-page navigation): 에이전트는 페이지네이션 (Pagination) 링크를 자동으로 따라갈 수 있습니다. "다음" 버튼을 찾아 클릭하는 "next_page" 동작을 추가하세요.
양식 채우기 (Form filling): 필드 선택자와 값을 담은 딕셔너리 (Dictionary)를 인자로 받는 "fill_form" 동작을 추가하세요.
병렬 브라우징 (Parallel browsing): 대량 추출 (Bulk extraction)을 위해 asyncio.gather()를 사용하여 여러 에이전트를 동시에 실행하세요. 각 에이전트는 자신만의 브라우저 인스턴스를 가집니다.
자가 치유 (Self-healing): 셀렉터 (Selector)가 실패할 경우, 에이전트는 페이지 콘텐츠를 기반으로 대체 셀렉터를 찾도록 LLM (대규모 언어 모델)에 요청할 수 있습니다.
결론
웹 브라우징 AI 에이전트를 구축하는 것은 생각보다 간단합니다. 핵심은 단순히 관찰하고(observe), 결정하고(decide), 행동하는(act) 루프(loop)입니다. 복잡함은 오류를 처리하고, 속도 제한 (Rate limits)을 준수하며, 데이터를 정확하게 추출하는 등 신뢰성을 확보하는 과정에서 발생합니다. 하지만 기본 아키텍처 (Architecture)는 직관적이며, 100줄 미만의 Python 코드로 작동하는 에이전트를 만들 수 있습니다.
웹 자동화의 미래는 웹사이트가 변경될 때마다 깨져버리는 하드코딩된 셀렉터를 사용하는 Selenium 스크립트가 아닙니다. 페이지 변화에 적응하고, 문맥을 이해하며, 자연어 지침에 따라 데이터를 추출할 수 있는 AI 에이전트가 미래입니다. 도구들은 이미 오늘날 준비되어 있습니다. 여러분이 해야 할 일은 그것들을 연결하는 것뿐입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기