본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 23. 17:44

스크래핑 API는 실패한 요청에 대해 비용을 청구해서는 안 됩니다

요약

웹 스크래핑 API가 실패한 요청에 대해 비용을 청구하는 문제점을 지적하며, 에이전트 중심의 개발 환경에 맞는 설계 방식을 제안합니다. 실패 시 비용을 면제하고 기계가 읽을 수 있는 구조화된 진단 정보를 제공해야 함을 강조합니다.

핵심 포인트

  • 실패한 요청에 비용을 청구하면 서비스 제공자의 실패 감지 인센티브가 저하됨
  • 에이전트 시대에는 실패가 예외가 아닌 핵심적인 업무 흐름임
  • 구조화된 실패(Structured failure)를 통해 에이전트의 분기 처리를 지원해야 함
  • 실패 시 비용을 면제해야 합리적인 재시도 로직 구현이 가능함

저는 대부분의 웹 스크래핑 (Web Scraping) API를 사용해 보았습니다. 이들은 해피 패스 (Happy path, 정상적인 경로): 도달 가능한 페이지를 제공하면 HTML이나 JSON을 돌려주는 작업에는 능숙합니다. 하지만 거의 모든 API가 조용히 비싼 습관을 공유하고 있습니다. 페이지가 차단되어 쓰레기 같은 결과물을 전달했을 때조차 요청에 대해 비용을 청구한다는 점입니다.

사람이 직접 스크레이퍼를 운영하던 시대에는 이를 그냥 넘길 수 있었습니다. 사람이 결과물을 보고 쓰레기라는 것을 확인한 뒤 다음으로 넘어가면 그만이었으니까요. 하지만 에이전트 (Agents)의 시대에는 이는 실제적인 문제이며, 왜 그런지 고민해 볼 가치가 있습니다.

실패는 예외가 아니라, 업무량 그 자체입니다

어떤 추출 도구든 오픈 웹 (Open web)을 대상으로 대규모 작업을 수행하면, 상당 부분의 요청은 실패하게 됩니다: CAPTCHA, 로그인 벽, 속도 제한 (Rate limits), 지리적 차단 (Geo blocks), 결코 정착하지 않는 JavaScript 셸 (JavaScript shells), 혹은 내용이 거의 없는 빈 페이지들 말입니다. 이것은 예외적인 케이스가 아닙니다. 당신이 실행하는 모든 작업의 일정한 비율을 차지하는 부분입니다.

따라서 실패 경로는 제품의 구석진 부분이 아닙니다. 관리되지 않고 실행되는 에이전트에게 있어, 실패는 가장 흥미로운 동작의 대부분을 차지합니다. 그리고 도구가 이를 처리하는 데에는 두 가지 방식이 있습니다.

정직하지 못한 방식: 비어 있거나 부분적으로 조작된 필드와 함께 200 상태 코드를 반환하고, 요청 비용을 청구합니다. 호출자는 실제 결과와 가짜 결과를 쉽게 구별할 수 없습니다. 사람은 할 수 있을지 몰라도, 에이전트는 할 수 없습니다. 에이전트는 조작된 필드를 가져가서 그것을 바탕으로 확신을 가지고 영원히 추론을 이어갈 것입니다.

정직한 방식: 무엇이 잘못되었는지 명시하는 구조화된 실패 (Structured failure)를 반환하고, 이에 대해 비용을 청구하지 않습니다. 호출자가 사람인지 에이전트인지에 관계없이, 그 결과에 따라 분기 처리를 할 수 있습니다.

이로부터 파생되는 두 가지 설계 결정

1. 실패한 추출에 대해서는 비용을 청구하지 마세요. 이것은 단순한 가격 책정 전략처럼 들릴 수 있습니다. 하지만 실제로는 인센티브 정렬 (Incentive-alignment) 결정입니다. 만약 제공업체가 실패에 대해 비용을 청구한다면, 그들에게는 실패를 잘 감지해야 할 이유가 없습니다. 그들의 관심사는 무엇이든 반환하고 다음으로 넘어가는 것입니다. 만약 실패에 대해 비용을 청구하지 않는다면, 실패를 정확하게 감지하는 것이 갑자기 그들 자신의 이익과도 일치하게 됩니다. 가격 책정은 공급업체를 포함한 모든 이의 행동을 형성합니다.

또한 이는 여러분의 재시도 로직 (retry logic)을 합리적으로 만들어 줍니다. 만약 차단된 모든 페이지와 모든 일시적인 타임아웃 (timeout)에 비용이 발생한다면, 에이전트 (agent)의 재시도 루프 (retry loop)는 청구서가 도착할 때까지 알아차리지 못하는 느린 할당량 누출 (quota leak)이 됩니다. 실패가 무료라면, 크레딧 (credits)이 증발하는 것을 감시할 필요 없이 합리적으로 재시도할 수 있습니다.

2. 문자열이 아닌, 기계가 읽을 수 있는 진단 정보 (diagnostics)를 반환하세요. 자유 형식의 텍스트 에러 (free-text errors)는 인간에게는 괜찮지만 에이전트에게는 쓸모가 없습니다. 에이전트에게는 조건문을 실행할 수 있는 안정적인 필드가 필요합니다. 다음과 같은 형태가 필요합니다:

{
  "success": false,
  "diagnostics": {
...

안정적인 reason 열거형 (enum)이 있다면, 에이전트는 당연히 올바른 조치를 취할 수 있습니다: timeout 시 재시도, captcha 시 포기, access_denied 시 소스 교체, login_required 시 에스컬레이션 (escalate). 문자열 파싱 (string parsing)도, 추측도 필요 없습니다.

"하지만 이것이 가장 저렴한 것은 아닙니다"

정직함은 양날의 검이기에 말씀드리자면, 실패 시 과금하지 않는 모델이 자동으로 가장 저렴한 옵션이 되는 것은 아닙니다. 만약 여러분의 작업이 기가바이트당 가능한 최저 비용으로 원시 HTML을 가져오는 것이라면, 단순한 프록시 (proxy)나 저가형 HTML 엔드포인트 (endpoint)가 더 나을 것입니다. 그것은 실제 사용 사례이며, 그러한 도구들은 그 용도에 적합합니다.

정직한 실패 모델 (honest-failure model)은 다른 작업에서 승리합니다. 바로 에이전트나 파이프라인 (pipeline)에 공급되는 구조화된 추출 (structured extraction) 작업입니다. 이 경우, 틀렸지만 확신에 찬 결과는 깔끔한 실패보다 더 비용이 많이 듭니다. 만약 조작된 가격이나 환각 (hallucinated)된 연락처가 여러분의 제품에 포함된다면, 그 비용은 크레딧으로 측정할 수 없는 수준이 됩니다.

이 기준으로 공급업체를 평가하는 방법

다음에 스크래핑 (scraping) 또는 추출 (extraction) API를 테스트할 때, 단순히 성공하는 경로 (happy path)만 테스트하지 마세요. 여러분이 차단될 것을 알고 있는 세 가지 페이지, 즉 CAPTCHA 벽, 로그인 전용 페이지, 그리고 무거운 싱글 페이지 애플리케이션 (single-page app)을 대상으로 테스트해 보세요. 그런 다음 두 가지를 확인하십시오:

  1. 이 세 가지에 대해 비용을 청구했는가?
  2. 프로그램이 응답만 보고 실패 여부와 그 이유를 알 수 있는가?

만약 답변이 "네, 비용을 청구했습니다"와 "아니요, 별로 그렇지 않습니다"라면, 여러분의 에이전트들은 고전하게 될 것이며, 여러분의 청구서 또한 비명을 지르게 될 것입니다.

저는 제 자신의 에이전트 프로젝트에서 이 문제에 계속 부딪혔기 때문에, 정확히 이 두 가지 결정을 바탕으로 Haunt를 구축했습니다. 하지만 여러분이 무엇을 사용하든 핵심은 변하지 않습니다. 에이전트 시대에는 도구가 어떻게 성공하느냐보다 어떻게 실패하느냐가 더 중요합니다. 정직하게 실패하는 도구를 선택하고, 그 실패에 대한 비용은 0원으로 책정하십시오.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0