본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 02. 18:36

AI 에이전트가 웹을 읽기 위해 항상 브라우저가 필요한 것은 아니다

요약

AI 에이전트 구축 시 Playwright와 같은 브라우저 자동화 도구의 리소스 비용과 실패 위험을 지적합니다. 단순 데이터 추출 목적이라면 브라우저 대신 비동기 추출 모델을 사용하여 에이전트의 추론 루프가 차단되지 않도록 설계해야 합니다.

핵심 포인트

  • 브라우저 자동화는 CPU, 메모리, 시간 비용이 높은 고충실도 도구임
  • 브라우저 세션의 상태 유지 특성으로 인해 타임아웃 및 리소스 부족 문제 발생 가능
  • 단순 텍스트/메타데이터 추출 시 브라우저는 과도한 장치가 될 수 있음
  • 비동기 작업 모델(Async Job Model)을 통해 에이전트의 차단을 방지할 것

웹사이트에서 데이터를 가져와야 하는 에이전트를 구축한다고 가정해 봅시다. 첫 번째 버전은 로컬에서 잘 작동하기 때문에 Playwright를 사용합니다. 페이지를 열고, 셀렉터(selector)를 기다리고, DOM을 읽는 방식입니다. 하지만 이를 프로덕션(production) 환경에서 실행하면 실패 양상이 달라집니다. 페이지가 networkidle 상태에 도달하지 못해 작업이 멈춰버립니다. 여러 브라우저가 동시에 실행되면 컨테이너의 메모리가 부족해집니다. 단 하나의 느린 사이트가 에이전트 루프(agent loop) 전체를 차단합니다.

문제는 대개 모델의 문제가 아닙니다. 웹 액세스 계층(web access layer)의 형태가 문제입니다.

브라우저 자동화는 기본값이 아닌 고충실도(high-fidelity) 도구이다

Playwright와 Puppeteer는 브라우저가 꼭 필요할 때 유용합니다. 클라이언트 측 JavaScript를 실행하고, 쿠키를 유지하며, 버튼을 클릭하고, 양식을 채우고, 탐색(navigation)을 처리하며, 문제가 발생했을 때 스크린샷을 제공합니다.

하지만 이러한 충실도에는 CPU, 메모리, 그리고 시간이라는 비용이 따릅니다.

흔히 발생하는 실패 사례는 다음과 같습니다:

TimeoutError: page.waitForSelector: Timeout 30000ms exceeded.

또는 부하가 걸렸을 때:

Error: browserType.launch: Target page, context or browser has been closed

이것들은 드문 예외 상황이 아닙니다. 브라우저 세션이 상태 유지(stateful) 리소스이기 때문에 발생하는 현상입니다. 에이전트가 200개의 페이지를 가져와야 한다면, 페이지를 순차적으로 실행하며 오랜 시간을 기다리거나, 브라우저를 병렬로 실행하며 리소스 비용을 지불해야 합니다. 또한 모든 작업에 대해 큐(queues), 재시도(retries), 프록시 처리(proxy handling), 세션 정리(session cleanup), 그리고 관찰 가능성(observability)을 갖추어야 합니다.

대화형 양식, 시각적 검증, 클라이언트 측 상태에 의존하는 인증 흐름, 또는 복잡한 JavaScript 실행 후에만 나타나는 데이터와 같이 작업이 정말로 브라우저 동작을 필요로 할 때만 브라우저 자동화를 사용하십시오.

만약 에이전트가 단순히 구조화된 텍스트, 메타데이터, 가격, 리뷰 또는 검색 결과만을 필요로 한다면, 브라우저는 종종 과도한 장치가 됩니다.

비동기 추출 경계(async extraction boundary)를 선호하라

많은 에이전트 워크플로우를 위한 더 나은 패턴은 다음과 같습니다: 추출 작업(extraction job)을 제출하고, 작업 ID(job ID)를 받은 뒤, 다른 작업을 계속 수행하다가, 타입이 지정된 결과(typed result)를 위해 폴링(poll)하는 방식입니다.

웹 요청(web requests)은 지속 시간이 예측 불가능하기 때문에 이러한 경계가 중요합니다. 에이전트는 45초가 걸릴 수도 있거나 속도 제한(rate limit)으로 인해 실패할 수도 있는 단일 HTTP 요청에 대해 자신의 추론 루프(reasoning loop)를 차단(block)해서는 안 됩니다.

일반적인 흐름은 다음과 같습니다:

POST /tasks
-> 202 Accepted { "job_id": "abc", "status": "processing" }

...

Wire는 웹 추출(web extraction) 작업에 이러한 비동기 작업 모델(async job model)을 사용하여, 먼저 job_id를 반환하고 추출이 완료되면 나중에 구조화된 결과(structured results)를 반환합니다.

다음은 이러한 방식의 API에 작동하는 작은 폴러(poller) 예시입니다. 중요한 부분은 에이전트가 무한 루프에 빠지지 않도록 하는 종료 상태(terminal states), Retry-After, 그리고 최대 대기 시간(maximum wait)입니다.

import time
import httpx

...

이 패턴은 재시도(retries)를 더 안전하게 만들어 주기도 합니다. 동기식 스크레이핑(synchronous scrape)을 재시도할 경우, 대상 워크플로(workflow)가 양식을 제출하거나 상태를 변경한다면 의도치 않게 부수 효과(side effects)가 중복될 수 있습니다. 작업 ID(job ID)를 폴링하는 것은 대개 멱등성(idempotent)을 유지합니다. 작업을 다시 시작하지 않고도 필요한 만큼 GET /jobs/{id}를 호출할 수 있습니다.

에이전트가 직접 사용할 수 있는 데이터 반환

에이전트는 파싱 로직(parsing logic)을 숨기기에 적합한 장소가 아닙니다.

도구가 가공되지 않은 HTML(raw HTML)을 반환하면, 모델은 매번 구조를 추론해야 합니다. 이는 토큰 사용량을 증가시키고 실패 원인을 진단하기 어렵게 만듭니다. 더 나은 추출 계층(extraction layer)은 타입이 지정된 필드(typed fields)를 반환합니다:

{
  "title": "Example thread title",
  "author": "user123",
...

이렇게 하면 에이전트에게 안정적인 계약(contract)을 제공할 수 있습니다. LLM은 해당 값들이 DOM의 어디에 위치하는지 추측하는 대신 score, comments, created_at을 바탕으로 추론할 수 있습니다.

트레이드오프(tradeoff)는 타입이 지정된 추출이 스키마(schemas)에 의존한다는 점입니다. 사이트의 마크업(markup)이나 동작이 변경되면 누군가는 여전히 추출기(extractor)를 업데이트해야 합니다. 하지만 이점은 모든 에이전트 프롬프트(agent prompt)나 파서(parser) 내부가 아닌 한 곳에서 수정이 이루어진다는 것입니다.

Wire는 선언된 인증 요구 사항(auth requirements) 및 크레딧 비용(credit costs)과 함께 사이트별 작업 카탈로그를 제공하며, 이는 플랫폼별 파싱 및 세션 처리(session handling)를 에이전트 코드 외부로 분리하는 한 가지 방법입니다.

이를 직접 구축하더라도 동일한 설계 원칙이 적용됩니다. 입력 파라미터(input parameters), 출력 스키마(output schemas), 재시도 동작(retry behavior), 그리고 인증 모드(authentication mode)를 포함하여 액션을 정의하십시오. 웹 접근을 즉흥적인 브라우저 스크립트가 아닌, 하나의 API 계약(API contract)처럼 취급해야 합니다.

브라우저로 전환(fallback)해야 하는 시점을 명확히 정의하십시오

API 우선 추출(API-first extraction) 방식이 모든 브라우저 자동화(browser automation)를 대체할 수 있는 것은 아닙니다.

다음과 같은 경우에는 추출 API를 사용하십시오:

  • 데이터가 주로 텍스트이거나 구조화된 레코드(structured records)인 경우
  • 워크플로(workflow)당 많은 페이지를 처리해야 하는 경우
  • 지연 시간(latency)과 리소스 사용량이 중요한 경우
  • 작업이 실행되는 동안 에이전트가 계속 다른 작업을 수행할 수 있어야 하는 경우
  • 출력 스키마(output schema)를 예측할 수 있는 경우

다음과 같은 경우에는 브라우저를 사용하십시오:

  • 워크플로에 클릭, 양식(forms) 입력 또는 탐색 상태(navigation state)가 필요한 경우
  • 스크린샷이나 시각적 검증(visual assertions)이 필요한 경우
  • 페이지가 복잡한 클라이언트 측 렌더링(client-side rendering)에 의존하는 경우
  • CAPTCHA 또는 대화형 인증(interactive auth)이 흐름의 일부인 경우
  • 사용자 경험(user experience) 자체를 테스트하는 경우

두 방식을 혼합하여 사용하는 것도 괜찮지만, 의도적으로 수행해야 합니다. 예를 들어, 제품 페이지의 95%는 API 추출을 사용하고, 대화형 흐름을 거쳐야만 데이터가 나타나는 소수의 사이트에 대해서만 Playwright를 예약해 두는 식입니다. 여러분이 피해야 할 것은 첫 번째 프로토타입에서 그렇게 했다는 이유만으로 모든 요청을 브라우저를 통해 보내는 것입니다.

아키텍처가 핵심적인 부분입니다

프로덕션 에이전트(production agents)를 위한 유용한 패턴은

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0