
30일 동안 5개의 AI 크롤러가 내 사이트를 14,300번 방문했다. User-Agent를 통해 알게 된 LLMO에 관한 사실
요약
서버 액세스 로그 분석을 통해 GA4 등 일반 분석 도구로는 확인할 수 없는 AI 크롤러의 실제 트래픽 패턴을 파악하는 방법을 다룹니다. robots.txt만으로는 부족한 LLMO(Large Language Model Optimization) 대응을 위해 User-Agent 기반의 데이터 분석이 중요함을 강조합니다.
핵심 포인트
- AI 크롤러는 JavaScript를 실행하지 않아 GA4에 잡히지 않음
- LLMO 측정을 위해서는 원시 HTTP 액세스 로그 분석이 필수적임
- GPTBot, ClaudeBot 등 주요 AI User-Agent의 트래픽 비중 확인
- robots.txt 외에 서버 로그를 통한 능동적인 트래픽 모니터링 필요
나는 robots.txt가 경계선이라고 생각했다. 세 줄의 Disallow:만 적으면 AI 봇들에게 어디를 가도 되고 어디를 가면 안 되는지 알려준 것이라 믿었다. 그걸로 끝이었다. 나는 다시 LLMO 측정, 인용률(citation rates), 그리고 GA4에서의 AI 추천 트래픽(AI referral traffic)에 관한 글을 쓰러 돌아갔다.
그러다 내 사이트 세 곳의 액세스 로그(access logs)를 열어보았고, 내가 머릿속에 그리던 그림은 무너져 내렸다.
이것은 kenimoto.dev, kaoriq.com, 그리고 llmoframework.com의 30일 치 원시 서버 로그(raw server logs)를 읽으며 배운 내용이다. 다섯 개의 User-Agent 문자열이 모든 것을 지배하고 있었다. 각 User-Agent가 만들어낸 트래픽 패턴은 그 어떤 GA4 대시보드보다도 나의 LLMO 입지에 대해 더 많은 것을 말해주었다.
내가 애초에 로그를 읽기 시작한 이유
대부분의 LLMO 측정 조언은 아웃바운드(outbound) 측면을 추적하라고 말한다. 즉, ChatGPT가 나를 인용했는지, Perplexity가 나에게 링크를 걸었는지, Google AI Overviews가 나를 보여주었는지와 같은 것이다. 그것은 인용(citation) 측면이다.
AI 서비스가 실제로 내 서버에서 HTML을 가져가는 다른 한쪽 측면은 GA4에서 보이지 않는다. AI 크롤러(crawlers)는 JavaScript를 실행하지 않는다. 그들은 gtag를 트리거하지 않는다. 그들은 오직 원시 HTTP 액세스 로그(HTTP access logs)에만 나타나며 그 외의 어디에도 나타나지 않는다.
나는 몇 달 동안 LLMO 관련 글을 써왔지만, 내가 실제로 제어할 수 있는 퍼널(funnel)의 측면은 단 한 번도 살펴본 적이 없었다. 그래서 나는 Cloudflare(kenimoto.dev, kaoriq.com)와 Vercel(llmoframework.com)에서 30일 치 로그를 내보내고, 알려진 AI User-Agent를 grep으로 검색하여 숫자를 세기 시작했다.
총합: 30일 동안 세 사이트에서 발생한 AI 크롤러 히트(hits)는 14,300건이었다. 사이트당 하루 평균 약 477건이다. 예상보다 많았다. 하지만 향후 6개월 뒤에 나타날 수치보다는 적다고 생각한다.
나를 가장 많이 방문한 5개의 크롤러
다음은 순위별 목록이다. 캐시 재시도(cache retries)로 인해 수치가 부풀려지지 않도록 히트 수는 (timestamp, path, IP)를 기준으로 중복을 제거했다.
| 순위 | User-Agent | 30일간 히트 수 | 운영사 | 목적 |
|---|---|---|---|---|
| 1 | GPTBot | 4,212 | OpenAI | 학습 데이터 (Training data) |
| ... | ... | ... | ... | ... |
5개의 User-Agent. 13,540 히트. 이는 전체 AI 트래픽의 94.7%에 달합니다. 나머지 5.3%는 롱테일(long tail)이었습니다: Bytespider, Applebot-Extended, Meta-ExternalAgent, Amazonbot, cohere-ai, 소수의 Claude-User, 그리고 스스로를 anthropic-ai라고 부르는 무언가로부터 발생한 2번의 히트(이것은 Anthropic이 은퇴시켰다고 알려진 구형 UA입니다)였습니다. |
순위에 대해 너무 깊게 의미를 부여하기 전에: 이것은 저의 데이터이며, 주로 영어/일본어 기술 콘텐츠를 다루는 세 개의 작은 사이트들입니다. 여러분의 순위는 다르게 보일 것입니다. 하지만 그 형태(소수의 봇이 대부분의 히트를 차지하고, OpenAI와 Anthropic이 상위에 위치하는 모습)는 아마도 비슷할 것입니다.
각 봇이 실제로 수행하는 작업
순위보다 각 봇의 _목적(purpose)_이 더 중요한 이유는, LLMO(Large Language Model Optimization) 관점에서 이 세 가지 범주가 완전히 다르게 동작하기 때문입니다.
**학습 크롤러 (Training crawlers)**는 모델 가중치(model weights)를 업데이트할 가능성을 위해 귀하의 콘텐츠를 읽습니다. 이들은 지속적으로 나타나며, (보통) robots.txt를 준수하고, 귀하의 콘텐츠가
저는 이 모든 것들을 동일한 종류의 생명체로 취급해 왔습니다. 하지만 그렇지 않습니다. 만약 귀하의 목표가 "ChatGPT Search에서 인용되는 것"이라면, OAI-SearchBot의 방문은 중요하지만 GPTBot의 방문은 기본적으로 노이즈에 불과합니다. 만약 귀하의 목표가 "다음 Claude의 학습 데이터 세트(training set)에 포함되는 것"이라면, 상황은 정확히 그 반대가 됩니다.
실제로 robots.txt를 준수하는 주체
여기 robots.txt에 대한 저의 관점을 뒤집어 놓은 부분이 있습니다.
kenimoto.dev에서 저는 Disallow: /api/ 규칙을 설정해 두었습니다. 30일 동안의 결과는 다음과 같습니다:
GPTBot:/api/에 대한 방문 0회. 준수함.Google-Extended:/api/에 대한 방문 0회. 준수함.ClaudeBot:/api/에 대한 방문 0회. 준수함.OAI-SearchBot:/api/에 대한 방문 3회. 경계선에 있음. 규칙이 적용되기 전에 캐싱되었을 가능성도 있고, 혹은 수정된 준수 언어(revised compliance language)가 미묘한 역할을 하고 있을 가능성도 있습니다.PerplexityBot: 90초 동안의 폭발적인 접속 중/api/에 대한 방문 41회. 이번 실행에서는 준수하지 않음.
41회의 방문은 단일 표본이 아닙니다. 이 90초간의 폭발적인 패턴은 Perplexity가 활성 사용자 쿼리에 답변할 때 User-agent: PerplexityBot 차단을 무시하는 것이 관찰되었다는 공개 보고서와 일치합니다. PerplexityBot을 검색(retrieval)과 사용자 요청(user-initiated) 사이의 경계에 걸쳐 있는 존재로 생각한다면 이 동작은 더 이해가 쉽습니다. 평상시에는 검색 크롤러(retrieval crawler)처럼 작동하다가, 누군가 답변을 기다리고 있을 때는 사용자 요청에 의한 페치(user-initiated fetch)처럼 작동하는 것입니다.
제가 기록해 둔 결론은 다음과 같습니다: robots.txt는 자가 보고된 경계(self-reported boundary)입니다. 상위 5개 크롤러 중 3개는 제 데이터에서 이를 깔끔하게 준수했습니다. 하나는 불확실했고, 하나는 반대편에 인간이 있을 때 자신이 원하는 대로 행동했습니다. 이에 따라 계획을 세우십시오.
이를 통해 도출할 수 있는 세 가지 LLMO 신호
제가 이 글을 쓰는 이유는 크롤러 방문 데이터가 측정 가능한 LLMO 신호임에도 불구하고, 일반적인 인용률(citation-rate) 지표와 함께 논의되는 것을 많이 보지 못했기 때문입니다. 이제 제가 매주 확인하는 세 가지는 다음과 같습니다:
1. 크롤러 다양성 (Crawler diversity). 만약 GPTBot만 당신의 사이트에 접속하고 다른 것은 없다면, 당신의 검색 노출 범위(retrieval surface)는 OpenAI에만 국한됩니다. ChatGPT에서 인용되더라도 Claude, Perplexity, Gemini의 검색 경로(retrieval paths)에는 보이지 않게 됩니다. 건강한 크롤러 다양성 점수는 상위 5개 User-Agent 중 최소 3개가 정기적으로 접속하는 상태를 의미합니다.
2. 검색 대 학습 비율 (Retrieval-to-training ratio). 검색 측 접속 수(OAI-SearchBot + PerplexityBot + Claude-SearchBot + GoogleOther)를 합산한 뒤, 학습 측 접속 수(GPTBot + Google-Extended + anthropic-ai)로 나누면, AI 생태계가 당신을 "학습해야 할 콘텐츠"로 보는지 아니면 "지금 바로 인용해야 할 콘텐츠"로 보는지 알려주는 수치가 나옵니다. 제 수치는 0.81입니다. 0.5 미만은 당신의 콘텐츠가 실시간으로 검색될 만큼 충분히 최신 상태가 아님을 의미합니다. 1.5를 초과하면 답변에 활발하게 사용되고 있다는 뜻(좋은 신호)이지만, 학습 자료로서는 정체기에 접어들었을 가능성이 높습니다(주의 깊게 살펴볼 부분).
3. llms.txt 호출률 (fetch rate). 상위 5개 크롤러 중, 30일 동안 제 사이트에서 /llms.txt를 호출한 것은 PerplexityBot과 ClaudeBot뿐이었습니다. GPTBot, OAI-SearchBot, Google-Extended는 한 번도 호출하지 않았습니다. 이는 다른 운영자들이 관찰한 내용과 대략 일치하며, llms.txt를 유지 관리할 가치가 있는지 결정할 때 중요한 세부 사항입니다. (짧은 답변을 드리자면: 네, 하지만 주로 이를 읽는 두 개의 크롤러를 위해서입니다.) 이에 대한 더 자세한 내용은 llmoframework.com retrieval signals page에서 확인할 수 있습니다.
실제로 이 데이터를 추출하는 방법
이 부분은 제가 항상 읽고 싶었지만 좀처럼 찾을 수 없었던 내용이기에 정리해 드립니다:
Cloudflare (무료 플랜). AI 크롤 제어(AI Crawl Control) 대시보드(이전 명칭 AI Audit, 문서 링크)를 통해 별도의 설정 없이도 상위 AI 크롤러의 User-Agent를 확인할 수 있습니다. 가공되지 않은 로우 로그(raw logs)를 얻으려면 유료 서비스인 Logpush가 필요합니다. 무료 플랜에서 가장 쉬운 대안은 "AI Audit"을 활성화한 뒤, 알려진 AI User-Agent별로 Analytics를 필터링하는 것입니다. 무료 플랜에서는 요청별 경로(per-request paths)까지는 제공하지 않지만, 횟수와 추세는 확인할 수 있습니다.
Vercel. Project → Logs → User-Agent contains "Bot"로 필터링하세요. Vercel은 Pro 플랜에서 30일간의 에지 로그 (edge logs)를 보관합니다. Hobby 플랜에서는 보관 기간이 더 짧으므로, 본격적으로 관리하려면 로그 드레인 (log drain)으로 전달하는 것이 좋습니다.
Netlify / 자체 호스팅 Nginx. 액세스 로그 (access log)를 grep으로 검색하면 됩니다:
grep -E "GPTBot|ClaudeBot|PerplexityBot|OAI-SearchBot|Google-Extended" \
/var/log/nginx/access.log \
| awk '{print $14}' \
...
이렇게 하면 크롤러 횟수를 얻을 수 있습니다. URL 순위를 확인하려면 $14 대신 awk '{print $7}'를 추가하세요. 정확한 필드 번호는 로그 형식에 따라 다르므로, awk '{print NF}'를 한 줄에 실행하여 개수를 확인해 보세요.
이 모든 것을 확인한 후 내가 변경한 사항
30일간의 관찰 기간이 끝난 후 세 가지 구체적인 변경을 수행했습니다:
robots.txt를 분리하여OAI-SearchBot과Claude-SearchBot은 허용(검색 및 인용에 유용)하되,GPTBot(학습용, 해당 엔드포인트는 나에게 이득이 없음)에 대해서는Disallow: /api/를 엄격하게 유지했습니다.- 모든 블로그 포스트 경로에
Last-Modified헤더를 추가했습니다. 검색 크롤러 (retrieval crawlers)가 재수집 빈도를 결정할 때 이 헤더를 사용하는데, Vercel은 기본적으로 이를 전송하지 않았기 때문입니다. - 스프레드시트에 검색 대 학습 비율 (retrieval-to-training ratio)을 매주 기록하기 시작했습니다. 2주가 지난 시점에서 얻은 유일한 유용한 통찰은 이 수치가 안정적이라는 것입니다. 이는 내 크롤러 식단 (crawler diet)이 주마다 급격히 변하지 않는다는 것을 의미하며, 이전에는 없던 기준점 (baseline)을 갖게 된 것입니다.
나는 로그가 LLMO에 대해 내가 이미 믿고 있던 것들을 확인해 줄 것이라 예상했습니다. 하지만 대부분 그렇지 않았습니다. 인용 (citation)만이 지켜볼 가치가 있는 유일한 신호는 아닙니다. 누가 당신의 페이지를 가져가는가는 별개의 문제이며, 그 답은 당신이 이미 가지고 있을 로그 파일 안에 일반 텍스트로 기록되어 있습니다.
만약 전체적인 측정 프레임워크(인용 추적(citation tracking), GA4 추천(referrals), 그리고 시스템의 일부로서의 서버 로그 크롤러 분석)를 원하신다면, 이 책을 참고하십시오: LLMO: AI Search Optimization. 10장은 측정(measurement)에 관한 장이며, 이 포스트는 기본적으로 그 책에 담을 공간이 부족했던 누락된 일곱 번째 KPI입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기