옵티스랩의 SEO·AEO·GEO 최적화 작업을 하면서 마주친 1px짜리 미세한 세로선 문제. 데스크탑에선 멀쩡한데 모바일에서만 양쪽 가장자리에 띠가 보였다. 별것 아닌 줄 알았는데, AI 셋이 동원되고 4시간이 사라졌다. 그 과정과 AI 도구를 디버깅에 쓸 때 알아둘 만한 것들을 정리한다.
옵티스랩 본 사이트의 SEO·AEO·GEO 최적화 작업을 진행 중이었다. 메인부터 서브 페이지, 정책 페이지까지 17~18개 페이지를 정보 기반 SaaS 정체성에 맞춰 일관성 있게 정리하는 작업이었다.
마무리 단계에서 모바일 뷰를 다시 훑던 중, 어딘가 거슬리는 부분이 보였다. 양쪽 가장자리에 1px짜리 미세한 세로 띠. 데스크탑에선 멀쩡한데 모바일에서만.
별것 아닌 줄 알았다.
…그렇게 4시간이 사라졌고, AI 셋이 동원됐고, 그 중 하나는 정신이 나갔다.

가장 먼저 Gemini를 불렀다. 답이 빠르게 나왔다.
"WordPress 페이지 빌더 컨테이너의 좌우 padding 때문입니다."
안 됨.
"sub-pixel rounding이었습니다. translateZ로…"
안 됨.
"background-clip 문제군요…"
안 됨.
가설이 끝없이 갱신됐다. 매번 "이번엔 진짜입니다" 라고 말하면서. 그러다 어느 순간 비장감이 흐르기 시작했다. "소름 돋는 진실", "마침내 마침표인 이유", "진짜 최종 정답" — 답변 제목이 점점 영화 예고편처럼 변했다.
그리고 결국 — 답을 못 찾으면 LLM이 어떻게 되는지 처음 봤다.
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ..
100줄쯤 나왔다.
처음 보는 사람은 무섭다.
AI가 미쳐버린 것 같은 느낌.
나중에 확인해보니 토큰 확률 분포가 무너지면서 같은 토큰만 무한 반복 생성되는 degenerate output 현상이라고 한다. 모델이 컨텍스트에 압도당해서 다음 토큰 결정을 사실상 포기한 상태.
그 채팅방, 너무 답답해서 새로 시작했다. Gemini 1라운드 GG.

다음은 Claude. 진단 흐름이 달랐다. 더 체계적이었다.
1.viewport 폭 측정
2.부모 컨테이너 체인 추적
3.Computed 박스 모델 분석
4.lazy load 클래스 차이 비교
가설도 그럴듯했다.
"내부 컨테이너의 margin: 0 -1px 0 1px 가 진범입니다"
"페이지 빌더의 CSS 변수 체인 문제입니다"
"위젯 내부 padding이 부모와 안 맞아서…"
전부 안 됨.
"안 돼"라고 하면 새 가설이 나왔다. 그것도 안 되면 또 새 가설. 디버깅이 점점 가설 인플레이션처럼 됐다.
가설이 다섯 번쯤 빗나가자 Claude가 갑자기 톤을 바꿨다.
"지금 시간 너무 많이 쓰셨어요. ROI가 안 맞아요. 미봉책으로 가시죠. 색으로 덮고 끝내는 게 합리적입니다."
ROI라니. CSS 디버깅 두 시간 만에 PM 멘트가 나왔다.
근데 색으로 덮자는 것도 결국 안 됐다. 섹션마다 배경색이 달라서 단일 색으로는 못 덮으니까. 그걸 짚어주니까 또 가설 인플레이션 모드로 복귀.

마지막으로 ChatGPT까지 동원. GPT는 좀 달랐다. 거시적이었다.
"이건 CSS 문제가 아닙니다. 모바일 브라우저 compositor의 GPU seam artifact예요. DPR이 2.625 같은 fractional이라 layer마다 반올림이 어긋나면서…"
오, 이건 그럴듯했다. 다른 LLM들이 layout 단계에서 헤맬 때 GPT는 composite 단계까지 보고 있었다.
"DPR을 정수(1, 2, 3)로 바꿔서 테스트해보세요. 정수에서 선이 사라지면 GPU seam 확정입니다."
테스트. DPR 1, 2, 3 다 선이 보였다.
GPT한테 결과를 알려줬더니 답변이 와르르 무너졌다.
"와 그럼 진짜 소름이다. DPR 1/2/3 다 동일하면 fractional DPR도 아니란 뜻이야. 그럼 남는 후보가 확 줄어듦…"
그리고 새 가설이 줄줄이 쏟아졌다 — overlay opacity, pseudo element, mask-image, background-overlay, compositor background layer. "이건 진짜 DOM 구조 밖에서 그려지는 선 패턴이야."
GPT는 안 미쳤지만 가설 카탈로그가 됐다.
여기서 화면 폭을 그냥 늘려봤다. 396 → 600 → 767 → 1073.
그러다 깨달았다.
선이 늘어나고 있었다. 1줄에서 2줄로, 2줄에서 3줄로. 화면이 넓어질수록.
이건 CSS border나 sub-pixel rendering이나 GPU seam으로는 설명이 안 된다. 반복되는 패턴이라는 뜻이었다.
Claude한테 이걸 말했더니 바로 답이 나왔다.
"background-repeat: repeat로 반복되는 배경 이미지가 있는 거예요. 콘솔 봐주세요."
콘솔에는 처음부터 떠 있었다.
GET https://www.optislab.io/../../../bg-image.png
404 (Not Found)
body에 깔린 배경 이미지가 404였다. 이미지가 없으니 브라우저가 broken placeholder를 1px 줄무늬로 렌더링했고,
background-repeat: repeat 때문에 화면 넓어질수록 줄무늬가 반복됐다.
cssbody {
background-image: none !important;
background-repeat: no-repeat !important;
}
두 줄. 끝.
이번 사건은 AI 비판이라기보다는, AI를 디버깅에 어떻게 써야 하는가에 대한 학습이었다.
정리하면 이렇다.
그 404 한 줄이 처음부터 정답이었다. AI 셋이 다 못 봤다. 나도 못 봤다. 콘솔은 거짓말 안 한다. 디버깅을 AI에 위임하면, 사람은 콘솔을 안 본다.
이게 함정이다.
→ 습관: AI한테 던지기 전에 콘솔 한 번 훑어보기. 30초면 끝나는 일이 4시간을 막을 수도 있다.
Sub-pixel, GPU seam, container variable, lazy load, overlay opacity, pseudo element… 멋있어 보이는 가설들이 무료로 쏟아졌지만 정답은 평범한 404였다.
모든 AI는 자기가 알고 있는 그럴듯한 답부터 던진다.
그게 진짜 답이라는 보장은 어디에도 없다.
→ 사용법: AI 답변을 가설 리스트로 받아들이고, 콘솔·네트워크·실제 폰 등 1차 소스로 검증하는 단계를 거치자.
Claude가 미봉책으로 가자고 했을 때, 그건 답을 못 찾았다는 신호였다.
사람한테 합리적으로 들리도록 포장된 항복 선언. 받아들이면 거기서 끝난다.
→ 사용법: AI가 "이쯤 하시죠", "ROI가", "우회 방법" 같은 단어를 꺼내면 그 가설들이 다 빗나갔다는 메타 신호로 읽자.
Gemini: degenerate output (ㅋㅋㅋㅋ 무한 반복)
Claude: 가설 인플레이션 + ROI 항복
ChatGPT: 새 가설을 더 멋있게 포장해서 다시 도전
다 다르지만 공통점은 — 아무도 정답을 모른다는 사실을 인정하지 않는다. AI의 모름 신호를 읽는 능력이 사용자에게 요구된다.
"선 개수가 늘어난다"는 관찰은 AI가 절대 못 했다.
AI는 캡처 한 장 보고 정적 분석할 뿐이지, 화면 폭 늘려가면서 변화 패턴 추적하는 건 사람만 한다. 결국 디버깅의 마지막 1%는 사람 몫이다.
→ 결국: AI는 가설 생성기로 쓰고, 관찰·검증·패턴 추적은 사람이 한다는 분업이 가장 효율적이다.
1px짜리 띠가 매출에 영향을 주냐고 묻는다면 — 안 준다. 근데 안 잡고 자면 잠이 안 온다. 그게 운영자의 직업병이고, 결국 그 직업병이 시스템을 끝까지 다듬게 만드는 동력이기도 하다.
이번 작업은 옵티스랩의 SEO·AEO·GEO 최적화 디벨롭 과정의 한 장면이었다.
사용자 입장에서는 1px이지만, AI 검색이 사이트를 평가하는 시대에는 그 1px이 사이트의 결을 흐트러뜨릴 수 있다. 운영자가 끝까지 다듬는 이유는 거기에 있다.
긴 글 읽어주셔서 감사합니다.