리포트 페이지 CTA 버튼, 왜 한 종류로만 보였나?
SGK 스튜디오는 기업 데이터를 정리해 공개하는 사업 리포트를 90편 운영한다. 각 리포트는 마지막 화면에 버튼을 두고 방문자를 다음 자리로 데려가는데, 그 버튼이 실제로 몇 종류이고 어디로 연결되는지는 사람이 매번 열어 확인하지 않고 프로그램이 자동으로 세도록 짜 두었다.
리포트는 특정 업종이나 상황에 놓인 기업의 비용 구조·시장 데이터를 정리해 무료로 공개하는 글이다. 검색을 거쳐 리포트를 읽으러 온 방문자가 그 자리에서 곧바로 서비스로 넘어가지 않더라도, 화면 어딘가에 다음 걸음을 안내하는 버튼이 있어야 방문이 헛수고로 끝나지 않는다. 그래서 이 회사는 리포트가 늘어날 때마다 버튼 구성이 그대로 유지되는지를 사람이 아니라 프로그램으로 확인해 왔다.
그 자동 검사가 내놓은 결과는 한 가지를 가리켰다. 리포트 90편의 마지막 화면에는 '견적 문의' 버튼 하나만 있고 다른 버튼은 없다는 결과였다. 이 결과는 그대로 다음 작업의 근거가 됐다 — 방문자를 좀 더 적극적으로 서비스 쪽으로 안내할 버튼이 하나뿐이니, 절감액을 즉석에서 계산해 주는 도구로 연결되는 버튼을 리포트 90편 전부에 새로 추가하자는 계획이었다.
계획을 실행에 옮기기 전, 검사 결과를 문장으로 정리해 봤다. '이 리포트 화면에는 견적 문의 버튼 하나만 있습니다.' 여기서부터 되짚어 본 확인 작업이 이번 사건의 전부다.
처음 의심한 것 — 견적 문의 버튼 하나가 전부라는 가정
검사 결과를 그대로 읽으면 자연스러운 결론이었다. 화면을 자동으로 훑은 결과가 '견적 문의' 한 줄과 카카오톡 상담 한 줄, 이렇게 두 줄만 내놓았고, 그중 방문자를 서비스로 직접 연결하는 줄은 견적 문의뿐이었다. 남은 한 줄은 상담 채널이지 서비스로 바로 이어지는 버튼이 아니었으니, 남는 결론은 하나였다 — '견적 문의 버튼이 유일한 연결 지점이다.'
이 결론이 그럴듯했던 이유는 검사 자체가 실제 화면을 대상으로 돌았기 때문이다. 코드를 읽고 짐작한 결과가 아니라, 리포트 90편이 실제로 떠 있는 화면의 HTML을 프로그램이 직접 열어 만든 결과였다. 실제로 열어서 얻은 근거는 쉽게 의심하기 어려웠다.
게다가 90편 전부를 사람이 일일이 여는 건 시간이 많이 든다. 자동 검사가 있는 이유도 거기에 있었고, 그 검사가 정직하게 두 줄만 찾아 온 이상 결과를 믿지 않을 이유가 딱히 없었다.
그것을 확인하는 데 쓴 수단 — 정규식으로 실제 화면을 훑었다
이 검사는 사람이 리포트 90편을 일일이 열어 보는 대신, 리포트 페이지의 실제 HTML을 내려받아 미리 정해 둔 URL 형식과 대조하는 방식으로 짜여 있었다. 어떤 버튼이 이 형식 중 하나와 맞으면 '이 종류의 버튼이 있다'로 집계하고, 맞지 않으면 집계에서 아예 빠지는 구조였다. 이때 쓰인 검사 규칙은 아래 네 가지 URL 형식이었다.
- 절감액을 즉석에서 계산해 주는 진단 도구 링크
- 일반 문의 페이지 링크
- 특정 서비스 소개 페이지로 바로 연결되는 링크
- 카카오톡 상담 채널 링크
리포트 90편을 이 네 가지 형식으로 훑은 결과, 걸린 것은 카카오톡 상담 링크와 문의 페이지 링크 두 가지뿐이었다. 나머지 두 형식은 한 번도 걸리지 않았고, 검사는 정직하게 '이 두 가지만 있다'고 보고했다. 검사 프로그램 입장에서는 거짓을 말한 적이 없었다 — 찾아보라고 지시받은 네 가지 안에서는 정말로 두 가지만 걸렸으니까.
이 방식을 고른 이유는 속도였다. 리포트 90편을 사람이 하나씩 열어 버튼을 세면 시간이 오래 걸리지만, 화면 HTML을 내려받아 미리 정한 URL 형식과 맞춰 보는 방식은 몇 초 안에 전체를 훑는다. 문제는 이 빠른 방식이 '미리 알고 있는 항목만 찾는다'는 전제 위에서만 정확하다는 점이었고, 그 전제가 이번에는 깨졌다.
왜 그 결론이 틀렸나? 검사 규칙에 없는 버튼은 결과에서 통째로 빠졌다
결론을 실행에 옮기기 전, 검사 결과를 실제 화면과 한 번 더 맞춰 보기로 했다. 표본으로 리포트 1편을 직접 열어 화면을 만드는 코드까지 들여다봤다. 실제 화면에는 처음부터 버튼이 두 종류 있었다 — 그 리포트의 주제에 맞는 서비스 페이지로 곧장 연결되는 주 버튼 하나와, 견적 문의로 가는 보조 버튼 하나였다. 주 버튼은 리포트 주제에 따라 홈페이지 제작·업무 자동화·AI 챗봇·콜드메일 대행, 이렇게 네 개 서비스 페이지 중 하나로 연결됐고, 화면 맨 아래에는 다른 서비스로 가는 링크가 5개 더 있었다.

원인은 검사 규칙에 있었다. 네 가지 형식 중 어느 것도 이 주 버튼의 URL과 맞지 않았다. 검사는 정직하게 돌았지만, '이런 것도 찾아봐'라는 지시를 애초에 받은 적이 없는 버튼이었다. 그러니 결과에는 보조 버튼과 상담 채널 두 줄만 남았고, 그 두 줄만 보고 있으면 '이게 전부구나'라는 판단이 자연스럽게 따라온다. 정말 없어서 안 보인 것이 아니라, 찾아볼 목록에 애초에 없어서 안 보인 것이었다.
진짜 원인 — 없다는 것과 안 보인다는 것은 다르다
여기서 진짜 원인이 갈린다. 검사 프로그램이 잘못 작동한 게 아니었다. 짜인 그대로 정직하게 실행됐다. 문제는 '검사 결과에 두 가지만 있다'를 '실제로 두 가지만 있다'로 읽은 지점이었다. 검사 결과가 알려 주는 정보는 '찾아보라고 지시받은 것 중에서 실제로 걸린 것'이지, 화면에 있는 전부가 아니다. 이 둘 사이의 거리가 이번 오판의 정확한 크기였다.

이 착각이 위험했던 이유는 단순하다. '없다'는 결론은 곧바로 다음 행동을 정한다. 있는데 검사에 안 걸린 경우와 정말 없는 경우는 그다음에 해야 할 일이 완전히 다르다. 이번에는 '주 버튼이 없다'는 잘못된 전제 위에 '그러니 새로 하나 추가하자'는 계획이 이미 올라가 있었다.
이 거리는 검사 규칙을 짤 때는 잘 보이지 않는다. 규칙을 만드는 사람은 자신이 아는 URL 형식만 목록에 넣고, 그 목록이 전체를 대표한다고 무의식적으로 전제한다. 실제 화면은 시간이 지나며 계속 바뀌는데, 검사 규칙은 만든 시점의 화면 구조에 고정된 채로 남는다. 화면이 새 버튼을 추가하거나 구조를 바꿔도 검사 규칙이 따라서 넓어지지 않으면, 새로 생긴 것은 처음부터 없었던 것처럼 취급된다.
고친 방법 — 계획을 철회하고 실제 화면을 전수로 다시 셌다
먼저 리포트 90편 전부에 새 버튼을 추가하려던 계획을 철회했다. 그 계획의 전제 자체가 틀렸으니 그대로 실행할 이유가 없었다. 대신 검사 규칙을 네 가지 URL 형식에만 의존하지 않고, 실제 버튼 구조를 코드에서 직접 확인하는 방식으로 다시 짰다. 정규식으로 화면을 훑는 검사는 빠르지만, 화면을 만드는 코드 자체를 읽는 확인은 느린 대신 놓치는 항목이 없다.

다시 센 결과는 계획을 철회한 판단이 옳았음을 한 번 더 보여 줬다. 주 버튼의 목적지인 서비스 페이지 4개 가운데 3개는 방문자가 도착하자마자 이미 절감액 계산 도구로 가는 버튼을 갖고 있었다. 방문자는 리포트에서 서비스 페이지로 한 번, 서비스 페이지에서 계산 도구로 또 한 번, 두 번의 클릭이면 닿는 구조였다. 여기에 버튼을 또 추가하면 이미 작동하는 길 위에 같은 표지판을 하나 더 세우는 셈이었다.
나머지 한 곳, 홈페이지 제작 서비스 페이지에만 이 계산 도구로 가는 링크가 없었는데, 이것도 확인해 보니 결함이 아니라 애초에 의도한 설계였다. 그 계산 도구는 업무 자동화로 절감되는 금액을 계산해 주는 도구라 홈페이지 제작이라는 서비스와는 처음부터 맞지 않았다. 실제로 화면을 만드는 코드 안에는 '이 계산 도구가 맞지 않는 서비스는 화면에서 숨긴다'는 설명까지 이미 남아 있었다. 빠진 링크를 발견하고 '이것도 놓친 자리'라고 오판할 뻔했다가, 코드를 직접 읽고서야 의도된 설계임을 확인했다.
검사 규칙 자체도 다시 손봤다. 네 가지 URL 형식에 주 버튼이 실제로 연결되는 서비스 페이지 4개의 형식을 추가해, 다음부터는 이 버튼도 자동 검사에 걸리도록 했다. 규칙을 늘리는 쪽이 코드를 매번 직접 읽는 쪽보다 느리게라도 다시 자동화할 수 있는 길이었다.
무엇이 남았나 — 다른 판단 세 가지는 이 오류와 무관했다
같은 조사에서 함께 확인했던 다른 판단이 전부 틀린 건 아니었다. 이 오류는 '주 버튼이 없다'는 한 가지 결론에서만 일어났고, 같은 조사가 내놓은 다른 세 가지 판단은 서로 다른 근거로 확인했기 때문에 이번 오류와 무관하게 유효했다.
| 판단 | 근거 | 이번 오류의 영향 |
|---|---|---|
| 리포트에 주 버튼이 없다 | 검사 규칙 4가지 URL 형식 대조 | 틀림 — 철회 |
| 계산 도구로 가는 전역 진입점이 0개다 | 사이트 상단 메뉴·머리말·꼬리말 직접 확인 | 무관 — 유효 |
| 실제 문의는 계산 도구 쪽이 더 많다(5 대 2) | 실제 접수 건수 집계 | 무관 — 유효 |
같은 조사 안에서도 무엇을 근거로 삼았는지가 다르면, 한쪽이 틀렸다고 다른 쪽까지 같이 틀리지는 않는다.
이 구분을 남겨 두는 이유는 단순하다. 오류 하나를 발견했다고 그 조사 전체를 폐기하면, 맞았던 판단까지 다시 확인하는 데 시간을 또 써야 한다. 무엇이 같은 근거를 공유하고 무엇이 독립된 근거를 가졌는지 미리 구분해 두면, 고칠 자리만 정확히 고치고 나머지는 그대로 둘 수 있다.
이번 사건을 겪고 나서 정리한 기준은 하나다. 오류를 발견하면 그 오류가 정확히 어느 결론까지 미치는지 먼저 경계를 그은 뒤에 수습한다. 경계를 안 긋고 전부 다시 확인하면 시간이 두 배로 든다.
같은 실수를 막는 장치 — '없다'는 결론 앞에서 한 번 더 확인한다
이 오류가 남긴 결과물은 버튼 하나를 더 센 것보다 오래 쓸 규칙이었다. 조사 대상을 미리 정해 두고 그 안에서만 찾은 다음 '없다'고 결론 내리는 방식은, 정말 없어서 못 찾은 경우와 찾아볼 목록에 애초에 빠져 있어서 못 찾은 경우를 구분하지 못한다. 그래서 이후로는 무언가가 '없다'는 결론을 내릴 때 먼저 스스로에게 묻기로 했다 — 지금 이 결론은 전체를 보고 낸 결론인가, 아니면 미리 정해 둔 목록 안에서만 찾아보고 낸 결론인가.
이 확인 습관은 특별한 도구를 요구하지 않는다. 자동 검사 결과를 '전체'로 읽기 전에, 그 검사가 애초에 무엇을 찾아보라고 설정되어 있었는지 목록을 한 번 펼쳐 보면 충분하다. 목록에 없는 항목은 결과에도 나타나지 않고, 결과에 안 나타난다고 해서 화면에도 없다는 뜻은 아니다. 이 한 줄만 매번 되새겨도, 검사 규칙을 넓히지 않은 채로 '없다'는 결론을 성급하게 실행에 옮기는 일은 줄어든다.
같은 종류의 오판은 이번이 처음이 아니었다. 설정 화면 하나만 보고 '공식적으로 위임할 방법이 없다'고 결론 내렸다가, 실제로는 계정 종류를 하나 더 확인했어야 했던 사례도 있었다. 두 사례 모두 '내가 확인한 자리에 없었다'와 '전체에 없다'를 같은 말로 취급한 지점에서 갈렸다. 그 사례는 AI 에이전트 오판, 원인은 계정 레이어 확인 누락이었다에 그대로 적어 뒀다.
랜딩페이지 CTA 버튼처럼 사람이 매번 눈으로 확인하기 번거로운 화면일수록 검사를 자동화하고 싶어진다. 다만 그 검사가 미리 정한 규칙 안에서만 찾는 방식이라면, '이만큼 찾았다'와 '이게 전부다' 사이에는 언제나 거리가 있을 수 있다는 사실을 검사 결과와 함께 기억해 둘 필요가 있다. 화면 구조를 직접 점검하는 작업이 필요하면 무료 진단 상담에서 실제 화면을 함께 확인할 수 있다.