The Challenge
버티컬 AI 스타트업은 2개월 차 무렵 모두 같은 벽에 부딪힙니다. 지원 코파일럿, 법률 조사 어시스턴트, 또는 컴플라이언스 봇을 출시합니다. 첫 데모는 고객을 확보합니다. 그 후 데이터가 노후화되고 답변이 현실과 어긋나기 시작합니다.
많은 팀이 AI 파트는 깔끔하게 구축하지만 데이터 파트는 뒷전으로 미루는 모습을 지켜보았습니다. 수집 파이프라인은 누군가의 노트북에서 실행되는 Python 스크립트 하나뿐입니다. 200개의 소스 URL을 한 번 스크랩하고, 깔끔한 Markdown을 벡터 저장소에 덤프한 뒤 모두가 자축합니다. 6주 후, 답변의 절반이 삭제된 페이지, 지원 중단된 API, 또는 3월에 출시되었다가 5월에 다시 변경 출시된 제품 기능을 인용하게 됩니다.
해결책은 간단해 보입니다. 매주 모든 소스를 다시 크롤링하는 것입니다. 현실은 더 가혹합니다. 2026년 기준, 신뢰할 수 있는 사이트의 약 60%가 AI 크롤러를 차단하며(2023년 말 23%에서 증가), 차단 방식은 더 이상 단순한 User-Agent 확인 수준이 아닙니다. 세션 동작, request 주기, 핸드셰이크 수준의 신호를 분석합니다. 1월에 정상 작동하던 단순 스크립트가 3월에는 아무런 오류 없이 빈 페이지만 반환합니다.
더 심각한 점은, 일부 사이트가 임베딩을 오염시킬 때까지 타르핏 콘텐츠(실제 텍스트처럼 읽히는 마르코프 생성 횡설수설)를 제공한다는 것입니다. 결국 엔지니어는 제품을 개발하는 대신 근무 시간의 절반을 스크래퍼 패치에 소비하게 됩니다. 검색 품질이 떨어지고, 고객이 이를 알아차리며, AI 개발을 위해 채용한 팀이 스크래퍼 유지보수 팀으로 전락합니다.
The Approach
재크롤링 문제는 모든 request에서 내려야 하는 세 가지 구체적인 결정으로 나뉩니다.
- 렌더링 여부. 대부분의 문서 포털은 깔끔한 HTML을 제공합니다. 점차 늘어나는 비중(Next.js 기반 사이트, 클라이언트 사이드 렌더링을 사용하는 모든 사이트)의 소스는 유용한 콘텐츠를 반환하기 위해 완전한 브라우저 렌더링이 필요합니다.
- 어떤 proxy를 사용할 것인가? 주거용, 데이터센터, 모바일, 위치 지정, 특정 ISP. 적절한 선택은 타깃에 따라 달라집니다.
- 실제로 정상 작동했는가? 본문이 비어 있는 200 응답이나 인증 페이지는 HTTP request는 성공했지만 크롤링에는 실패한 것입니다.
FourA와 같은 플랫폼은 이러한 각각의 문제를 핵심 기능으로 처리합니다.
렌더링 결정의 경우, 비용이 저렴하고 빠른 처리에는 Single을 호출하고 JS 비중이 높은 타깃에는 Browser를 호출합니다. 호출 body의 형태가 동일하므로, 수집 코드는 수백 개의 사이트별 예외를 처리하는 대신 소스별 플래그 하나로 분기할 수 있습니다.
proxy 선택의 경우, Proxy Finder가 모든 Single, Browser, Auto 호출의 일부로 실행됩니다. 플랫폼이 request마다 정상 작동하는 출구를 선택하고, response에 불투명 ID를 반환하며(Single/Browser의 경우 최상위 r.proxy, Auto의 경우 r.session.proxy), 동일한 출구를 유지해야 할 때 후속 호출에서 해당 ID를 재사용합니다. 크롤러가 자체적인 proxy 순위 알고리즘을 유지할 필요가 없습니다. (풀 크기가 더 이상 차별화 요소가 되지 않는 이유에 대해서는 Why Proxy Pool Size Stopped Mattering in 2026에서 다룬 바 있습니다.)
"실제로 제대로 작동했는가"에 대한 문제를 해결하기 위해, 모든 request는 validate 블록을 지원합니다. 허용되는 상태 코드, 필수 header 값, 반드시 포함되거나 제외되어야 하는 body 문자열 등 성공 기준을 직접 정의할 수 있습니다. FourA는 7가지 결과 중 하나를 반환하며, 오직 success 결과에 대해서만 과금됩니다. 콘텐츠 규칙을 통과하지 못한 200 응답은 application_fail 처리되어 데이터셋에 절대 포함되지 않습니다.
JS 렌더링이 필요한 문서 포털의 recrawl 호출 예시는 다음과 같습니다. Auto 모드를 통해 오케스트레이션을 처리합니다. 적절한 제품(Single, Proxy 또는 Browser)을 자동으로 선택하고, 봇 방어를 처리하며, 다음 recrawl 시 동일한 출구를 유지할 수 있도록 session triple을 반환합니다.
import requests
r = requests.post(
"https://api.foura.ai/api/auto",
headers={"Authorization": "Bearer pk_live_..."},
json={
"url": "https://docs.example.com/changelog",
"validate": {
"status": {"accept": [200]},
"data": {"accept": ["<article"], "fail": ["captcha", "Just a moment"]},
},
},
).json()
# r["data"] or r["body"] — rendered content (Auto runs the right sub-product per host;
# Single populates "data", Browser populates "body")
# r["session"] — { "proxy": "<base36 id>", "cookies": [...], "userAgent": "..." }
# On the next recrawl, pass r["session"]["proxy"] back as `ignoreProxies: [<id>]` to avoid
# the same exit, or via /api/single with `proxy: <id>` to stick to it.
타겟 사이트가 Cloudflare 중간 페이지를 반환하면 validate.data.fail 규칙이 이를 감지합니다. 사용량에 기록되는 결과는 application_fail입니다. 비용은 청구되지 않으며, 인제스천 코드는 "잠시만 기다려 주십시오..." 페이지를 임베딩에 전달하는 대신 다른 프록시로 재시도해야 함을 인식합니다.
더 큰 규모의 말뭉치라면 기존 작업 큐에 동일한 패턴을 적용할 수 있습니다. 당사가 인터뷰한 팀들은 이전 크롤링 결과와 야간 diff를 실행하여 실제로 변경된 문서만 다시 임베딩하며, 500개 소스 규모의 말뭉치를 몇 시간 만에 갱신합니다. 작업 큐 관리는 사용자가 담당하고, 프록시 교체, 렌더링 결정, 성공 여부 판정은 당사가 처리합니다.
결과
인프라 병목 현상이 해결되었을 때의 최신성 유지 루프 동작 방식입니다 (버티컬 AI 팀 전반에서 확인되는 패턴 기반의 예시 시나리오):
- 출시 초기 200개 URL 단발성 수집 대신, 매주 500개 소스 URL 재크롤링
- 스크래퍼 유지 관리에 소요되는 엔지니어링 시간 주당 2시간 미만 (기존 1-2일에서 단축)
- 검색 데이터 최신성 지연 범위: 무제한 대신 5-7일 유지
- 벡터 저장소 내 쓰레기 데이터 비율 제로에 근접: Cloudflare 중간 페이지 및 타르핏 페이지가 임베딩 모델에 도달하기 전
validate계층에서 차단됨 - 소스별 예측 가능한 비용: 실패한 크롤링은 과금되지 않음
이러한 방식들이 마법 같다는 뜻이 아닙니다. 핵심은 지극히 평범하고 예측 가능하다는 점이며, 프로덕션 AI에 필요한 것이 바로 그것입니다. (호스팅형 LLM 추출의 경제성이 무너지는 지점에 대한 자세한 내용은 LLM 추출의 채산성이 맞지 않는 순간을 참고하십시오.)
핵심 요약
버티컬 AI를 구축하는 대부분의 팀은 프롬프트, 모델 선택, 검색 알고리즘이 해자라고 생각합니다. 하지만 그렇지 않습니다. 진짜 해자는 최신성 유지 루프, 즉 매주 지식 베이스를 정확하게 유지하는 겉보기엔 단순한 인프라입니다.
2026년까지 버티컬 AI 시장에서 성공하는 팀은 가장 기발한 프롬프트를 작성하는 팀이 아닐 것입니다. 데이터가 항상 최신 상태로 유지되어 사용자가 그 신선함을 인식조차 하지 못하게 만드는 팀이 승리할 것입니다.