AI가 온 게 아니라 ChatGPT만 왔다
메모리와 트래픽이 뛰었는데 분석 도구에는 아무것도 안 잡혔다. 서버 로그를 User-Agent로 세니 세 시간 15,001건 중 11,321건이 백링크 도구 봇 하나였다. 봇 일곱을 막고 나서 분석 도구를 다시 봤더니, "AI 어시스턴트 53세션"의 정체는 ChatGPT 한 곳이었다
공시 요약 서비스의 프론트는 Railway에서 돈다. 어느 새벽에 메모리와 시간당 전송량이 같이 뛰었는데, 마지막 배포는 이틀 전이었고 분석 도구에는 아무 변화도 안 잡혔다. 트래픽은 늘었는데 방문자는 없는 조합이었다.
하려던 것
새벽에 Railway 사용량이 뛰었다. 공시 요약 서비스의 프론트가 메모리 0.35GB에서 0.65~0.9GB로, 시간당 전송량이 0.02GB에서 0.11GB로 올라갔다. 마지막 배포는 이틀 전이라 코드 변경과는 무관했다.
저녁에 물었다.
어제 부터 레일웨이의 사용량 중이 dartbrief-web 의 메모리 와 network 사용량이 늘어났는데.. GA 에는 전혀 안잡히는데 실시간으로.. 뭘까?? SEO 이려나??
트래픽은 뛰었는데 분석 도구에는 아무것도 없다. 이 조합이 힌트였다. 분석 도구는 브라우저에서 스크립트가 돌아야 세션을 남긴다. 스크립트를 안 돌리는 손님은 통째로 안 보인다.
어떻게 시켰나
그러니 봐야 할 건 분석 도구가 아니라 서버가 받은 요청 자체였다. Railway의 HTTP 로그를 세 시간치 받아서 User-Agent로 묶게 했다.
15,001건이 이렇게 나뉘었다.
| User-Agent | 요청 수 |
|---|---|
| AhrefsBot | 11,321 |
| meta-externalagent | 1,607 |
| 사람으로 보이는 것 전부 | 479 |
| SemrushBot | 350 |
| MJ12bot | 150 |
| PetalBot | 107 |
| Bytespider | 78 |
| DotBot | 1 |
백링크 조사 도구의 봇 하나가 전체의 75%였다. 사람은 3%였다. 분석 도구에 아무것도 안 잡힌 게 당연했다. 손님의 97%가 스크립트를 안 돌리는 쪽이었다.
숫자를 보고 내가 물은 건 하나였다.
AhrefsBot 크롤링이 되면은 나한테 뭐가좋아?
답은 없다는 것이었다. 그 도구를 구독하는 건 우리가 아니다. 우리 사이트를 긁어서 남의 리포트를 만들고, 비용은 우리가 낸다.
사용자 실제 유입에 실제 도움이 안되는 크롤러들 다 차단할까?
어디서 막혔나
차단 목록을 만들고 나서, 뭔가 찝찝해서 하나 더 시켰다.
그리고 실제 구글 애널리틱스의 데이터를 보고 한번더 판단해줘..데이터 얼마 있지도 않은데..
순서를 적어 두면, 차단 커밋이 21시 15분이고 이 재측정이 21시 27분이다. 막고 나서 12분 뒤에 쟀다. 순서가 거꾸로였다.
그리고 그 12분 늦은 측정에서 다른 게 걸렸다. 차단 목록이 아니라 내가 그동안 봐 온 지표 쪽이었다.
28일 기준 채널 집계는 이렇게 보였다.
| 채널 | 세션 |
|---|---|
| Direct | 114 |
| AI Assistant | 53 |
| Cross-network | 13 |
| Organic Search | 6 |
검색보다 AI가 아홉 배다. 이 화면만 보면 “AI 유입이 이제 주요 채널”이라는 결론밖에 안 나온다. 나도 그렇게 알고 있었다.
90일을 소스 단위로 다시 뽑으니 그 덩어리가 풀렸다.
| 소스 | 세션 |
|---|---|
| direct | 144 |
| chatgpt.com | 90 |
| bing organic | 6 |
| copilot.com | 2 |
| google organic | 0 |
| Meta AI · Perplexity · Claude | 0 |
“AI 어시스턴트”라는 한 칸의 내용물은 사실상 ChatGPT 한 곳이었다. Copilot이 둘, 나머지는 한 세션도 없었다. 구글 검색 유입은 90일 동안 0이었다. 노출은 448회 있었는데 클릭이 0이다.
집계 단위 하나가 판단을 통째로 바꿔 놓고 있었다. 채널로 보면 “AI 전반이 온다”이고, 소스로 보면 “ChatGPT만 온다”이다. 앞의 문장으로는 AI 크롤러를 일괄 차단하는 결정이 자연스럽다. 뒤의 문장으로는 그게 자살이다. ChatGPT의 검색 색인 크롤러와 사용자 질문 시 실시간으로 가져가는 크롤러를 막으면, 이 서비스에 사람이 도달하는 거의 유일한 경로가 끊긴다.
어떻게 풀었나
측정 결과가 차단 목록을 바꾸지는 않았다. 막은 일곱은 전부 유입 기여가 0인 것들이었고 그건 측정 후에도 그대로였다. 대신 판정 기준이 바뀌었다.
처음 기준은 “분석 도구 세션이 0이면 막는다”였다. 이 기준은 틀렸다. 구글 검색 봇도 세션이 0이다. 봇은 스크립트를 안 돌리니까 당연히 0이다. 그 기준대로면 검색 봇도 막아야 한다.
바뀐 기준은 “사람이 따라올 경로를 만드는가”다. 검색 결과에 실리거나, 답변의 출처로 붙거나, 공유 카드를 만들거나. 셋 중 하나라도 하면 남긴다. 아무것도 안 하고 긁기만 하면 막는다.
이 기준으로 보면 같은 회사의 크롤러도 갈린다. 학습용으로만 긁어가는 것은 막고, 사용자가 링크를 던졌을 때 실시간으로 가져오는 것은 남긴다. 뒤에 사람이 있기 때문이다. 백링크 도구도 마찬가지다. 남의 리포트용으로 긁는 봇은 막았지만 우리 사이트 감사를 돌려주는 쪽은 남겼다.
그러고 나서 테스트에서 둘이 더 나왔다.
첫째, 테스트가 대소문자를 가렸다. robots.txt의 User-Agent 매칭은 대소문자를 안 가린다. 그런데 검증 테스트는 문자열을 그대로 비교하고 있었다. 목록에 소문자로 gptbot이라고 적으면 실제로는 GPTBot이 통째로 차단되는데, 테스트는 “차단 목록에 없다”며 통과한다. 실수로 한 줄 잘못 적으면 유입 경로를 끊어 놓고도 초록불을 본다.
둘째, 차단을 세는 방식이 헐거웠다. 전체 대상이 아닌 그룹을 전부 차단으로 세고 있었다. 그러면 금지 규칙이 통째로 지워져도 테스트가 통과하고, 특정 봇만 예외로 허용하는 그룹이 생기면 차단으로 오판한다. 금지 목록에 루트가 들어 있는 그룹만 세도록 고쳤다.
마지막으로 커밋에 한계를 적어 뒀다. 90일 전체가 250세션이다. 이 데이터로 말할 수 있는 건 “막은 것들은 사람을 보낼 경로 자체가 없다”까지고, “AI 어시스턴트가 전략적으로 2위”같은 일반화는 못 한다. 되돌리는 비용이 목록에서 한 줄 빼는 것뿐이라 그 위험을 감수한 결정이다.
배운 점
- 분석 도구에 안 잡히는 트래픽이 트래픽의 대부분일 수 있다. 사람이 3%였다. 서버가 받은 요청을 직접 세기 전까지는 안 보였다.
- 집계 단위 하나가 결론을 뒤집는다. 채널로 뭉치면 “AI가 온다”이고 소스로 풀면 “ChatGPT만 온다”이다. 뭉친 칸은 항상 한 번 풀어 본다.
- 막기 전에 재는 게 맞다. 이번엔 12분 늦었고 결과적으로 목록은 안 바뀌었지만, 바뀌었다면 이미 배포된 뒤였다.
- 판정 기준을 지표로 쓰면 안 된다. “세션 0이면 차단”은 구글 검색 봇도 차단한다. 기준은 “사람이 따라올 길이 있는가”여야 한다.
- 매칭 규칙과 테스트의 비교 규칙을 맞춘다. 대소문자를 안 가리는 규칙을 대소문자를 가리는 테스트로 검증하면 초록불이 거짓말을 한다.
- 표본이 작으면 작다고 적는다. 250세션으로 채널 전략을 말할 수는 없다. 되돌리는 비용이 싸서 감수한 것뿐이다.