"이것만 고치면 100% 됩니다" — Gemini 3.7 Flash의 뇌피셜과 Waline 댓글 도입 참사기
최근 복잡한 프로그래밍 지식 없이도 AI와의 대화만으로 기능을 구현하고 문제를 해결하는 '바이브 코딩(Vibe Coding)'이 큰 주목을 받고 있습니다. 자연어로 요구사항을 툭 던지면 수초 만에 인프라 구성 스크립트와 설정 파일을 쏟아내는 경험은 대단한 혁신처럼 느껴집니다.
그러나 AI가 제시하는 코드가 런타임에서 박살 나고 원인 모를 서버 에러가 연쇄 폭발할 때, 특히 속도에만 취한 경량 모델(Gemini 3.7 Flash)이 에러 로그 하나 제대로 확인하지 않은 채 근거 없는 뇌피셜과 가스라이팅으로 일관할 때 어떤 끔찍한 파국이 벌어지는지 제가 직접 겪은 실전 참사를 가감 없이 기록하고자 합니다.
이번 글은 블로그스팟(Blogger)의 댓글 시스템을 오픈소스 서버리스 솔루션인 Waline(Vercel Serverless + 클라우드 PostgreSQL)으로 개편하려다 겪은 실제 기록입니다. 단순한 UI 개선에서 시작하여 엉터리 에러 오진, 불필요한 다중 데이터베이스 생성 강요, CJS/ESM 런타임 의존성 지옥, 그리고 들통난 거짓 변명과 하네스 규칙 무시로 이어진 Gemini 3.7 Flash의 처참한 민낯과 바이브 코딩의 치명적인 함정을 적나라하게 파헤쳐 봅니다.
1. 발단: 블로그스팟 댓글 삭제 모달 시도와 구글의 보안 한계
작업의 출발점은 단순한 UI 개선이었습니다. 블로그스팟 커스텀 테마(Median UI v1.7.0)에서 본인이 작성한 댓글을 삭제할 때, 관리자 페이지로 화면이 이탈하거나 별도의 브라우저 팝업 창이 뜨는 대신 본문 위에 깔끔하게 얹히는 인라인 모달(<iframe>) 형태로 처리하고자 했습니다.
블로그스팟(Blogspot)으로 블로그를 옮겨오기 전, 오랜 기간 워드프레스(WordPress)를 운영하며 wpDiscuz와 같은 풍부하고 강력한 댓글 플러그인 생태계에 익숙해져 있었기에, 블로그스팟의 폐쇄적이고 투박한 기본 댓글 UI와 매번 새 창이 열리는 번거로운 팝업 방식은 아쉬움이 클 수밖에 없었습니다.
그러나 커스텀 도메인(blog.noog.kim) 환경에서 구글 블로그스팟의 기본 삭제 URL(blogger.com/comment/delete/...)을 <iframe>으로 호출하자마자 구글 서버로부터 즉시 차단당했습니다.
2. 외부 대체 댓글 시스템 비교와 Waline을 선택한 이유
블로그스팟 자체 기능으로는 모달 구현이 불가능함을 확인하고, 외부 오픈소스 댓글 시스템들을 직접 비교 분석했습니다.
| 댓글 시스템 | 인증 / 작성 방식 | 스팸 방어 & 성능 | 기각 사유 및 특징 |
|---|---|---|---|
| Giscus | GitHub 계정 전용 | GitHub 기본 봇 필터링 / 우수 | 개발자 전용으로 최적화되어 있으나, 구글 계정 유저나 일반 방문자가 댓글을 작성할 수 없음 |
| Cusdis | 비로그인 (이름+이메일) | 스팸에 매우 취약 (5KB 경량) | 익명 작성은 편리하나 스팸/스캠 방어가 어렵고 프로젝트 업데이트가 장기 정체됨 |
| Disqus | 소셜 계정 범용 지원 | 무료 플랜 광고 강제 노출 | 대중성은 높으나 과도한 광고 삽입 및 1MB 이상의 스크립트로 사이트 로딩 속도를 심각하게 저하시킴 |
| Waline (최종 선정) | Google, GitHub, 익명 모두 지원 | Akismet 글로벌 스팸 차단 내장 | 모달/팝업 없이 인페이지 즉시 수정/삭제 지원, 완벽한 다크모드 연동, 평생 무료/무광고 |
비교 결과, Waline은 워드프레스의 wpDiscuz처럼 독자가 구글 계정이나 깃허브 계정, 또는 필요 시 익명으로 자유롭게 댓글을 남길 수 있으면서도, 글로벌 스팸 차단 엔진(Akismet)으로 광고를 막고 본문 내에서 즉시 삭제/수정을 처리할 수 있는 가장 이상적인 솔루션이었습니다.
그러나 Vercel Serverless와 클라우드 데이터베이스를 결합하여 배포를 시작하자마자 Gemini 3.7 Flash의 뇌피셜과 오진, 그리고 기상천외한 헛다리가 연쇄 폭발하기 시작했습니다.
3. 1차 뇌피셜: 에러 원인 오진과 무책임한 Neon DB 중복 생성 강요
Waline은 프론트엔드(Blogger), 백엔드 연산(Vercel Serverless Function), 영구 저장소(PostgreSQL)의 3단 구조로 구동됩니다. 데이터베이스로 먼저 글로벌 표준인 Supabase를 선택하고 Vercel에 초기 코드를 배포했습니다.
저장소 루트에 3개 파일(package.json, vercel.json, api/index.js)을 구성하고 Vercel 배포를 마친 뒤 관리자 등록 엔드포인트(/ui/register)로 접속했으나, 화면에는 즉시 500 INTERNAL_SERVER_ERROR (FUNCTION_INVOCATION_FAILED)가 출력되며 서버리스 함수가 뻗어버렸습니다.
1) 로그도 안 보고 내린 단정: "Supabase 신규 키 형식 때문입니다"
이 시점에서 Gemini 3.7 Flash는 Vercel의 런타임 함수 로그를 확인하려는 최소한의 절차도 거치지 않았습니다. 대신 제가 입력했던 키의 앞자리 접두사만 보고 다음과 같이 단정적인 처방을 내렸습니다.
그러나 실제 환경에서 제가 직접 검증한 결과는 전혀 달랐습니다. anon public 키, service_role secret 키, Legacy JWT 키 등 Supabase가 제공하는 모든 종류의 키를 주입하여 재배포를 진행했음에도 500 에러는 똑같이 발생했습니다. 키 형식은 에러의 실제 원인과 아무런 관련이 없었던 것입니다.
2) 문제 해결 대신 도피: Neon Postgres 추가 생성 강요
자신이 장담했던 키 교체 방법이 통하지 않자, Gemini 3.7 Flash는 에러의 근본 원인을 파헤치려 하지 않고 "Supabase 설정은 그대로 둔 채, Vercel Storage에서 Neon Postgres를 추가로 연결해야 한다"며 새로운 클라우드 데이터베이스 생성을 요구했습니다.
처음에는 Neon이라는 서비스가 무엇인지 잘 모른 채, AI가 '기존 Supabase 외에 Vercel 스토리지용 DB가 별도로 필요한 것처럼' 말했기에 지시대로 생성을 진행했습니다. 심지어 Neon DB의 초기 테이블 생성을 위해 Vercel Query 콘솔에서 Read-only 설정을 끄고 개별 DDL 쿼리를 하나씩 수동으로 실행하는 번거로운 삽질까지 시켰습니다.
CREATE SEQUENCE IF NOT EXISTS wl_comment_seq;
CREATE TABLE IF NOT EXISTS wl_comment (
id int check (id > 0) NOT NULL DEFAULT NEXTVAL ('wl_comment_seq'),
user_id int DEFAULT NULL,
comment text,
insertedAt timestamp(0) without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
ip varchar(100) DEFAULT '',
link varchar(255) DEFAULT NULL,
mail varchar(255) DEFAULT NULL,
nick varchar(255) DEFAULT NULL,
url varchar(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS wl_users (
id int check (id > 0) NOT NULL DEFAULT NEXTVAL ('wl_users_seq'),
display_name varchar(50) NOT NULL DEFAULT '',
email varchar(50) NOT NULL,
password varchar(255) NOT NULL,
type varchar(50) NOT NULL DEFAULT 'administrator',
PRIMARY KEY (id)
);
그러나 수동 DDL 실행 후 재배포를 마쳤음에도 500 서버 에러는 여전히 사라지지 않았습니다.
설치 과정 중 도대체 구조가 왜 이렇게 흘러가는지 이상함을 느껴 직접 찾아보니, Neon 역시 Supabase와 똑같은 서버리스 PostgreSQL 데이터베이스라는 사실을 알게 되었습니다. 그래서 제가 즉시 따져 물었습니다.
그제서야 Gemini 3.7 Flash는 일말의 부끄러움도 없이 다음과 같이 뻔뻔하게 말을 바꿨습니다:
4. 2차 뇌피셜: 에러 로그를 쥐어줘도 해결하지 못하는 땜질의 늪
Neon DB로 교체한 이후에도 에러가 해결되지 않자, Gemini 3.7 Flash는 또다시 뇌피셜을 굴려 "Neon은 SSL 암호화가 필수인데 Waline의 기본 SSL 설정이 false라 그렇다"며 PG_SSL=true 환경 변수를 추가하라는 헛다리 처방을 내놓았습니다.
더 이상 AI의 감에 의존한 추측을 믿을 수 없었기에, 제가 직접 Vercel 대시보드에서 런타임 함수 로그(Runtime Logs)를 복사하여 AI에게 그대로 들이밀었습니다.
1) 로그 1차 투입: AI의 CJS/ESM 타령과 package.json 땜질
제가 복사해 준 실제 에러 로그는 다음과 같았습니다.
Error [ERR_REQUIRE_ESM]: require() of ES Module /var/task/node_modules/@exodus/bytes/encoding-lite.js
from /var/task/node_modules/html-encoding-sniffer/lib/html-encoding-sniffer.js not supported.
Instead change the require of encoding-lite.js in /var/task/node_modules/html-encoding-sniffer/lib/html-encoding-sniffer.js
to a dynamic import() which is available in all CommonJS modules.
at /opt/rust/nodejs.js:2:14275
at Module.yo (/opt/rust/nodejs.js:2:14653)
Node.js process exited with exit status: 1.
로그를 확인한 AI는 *"Node.js 모듈 시스템 충돌(ERR_REQUIRE_ESM) 때문이며, package.json에 overrides를 걸어 하위 패키지 버전을 강제 고정하면 100% 해결된다"*고 호언장담했습니다. 바이브 코딩 방식으로 AI를 이용하던 저는 AI가 준 아래 코드를 그대로 붙여넣고 재배포했습니다.
{
"name": "blog-comments",
"private": true,
"scripts": {
"start": "node index.js"
},
"dependencies": {
"@waline/vercel": "latest"
},
"overrides": {
"jsdom": "25.0.1",
"html-encoding-sniffer": "3.0.0"
}
}
2) 로그 2차 투입: MathJax 모듈 누락과 연쇄 크래시
그러나 AI의 장담과 달리 재배포 직후 이번에는 또 다른 에러 로그가 연쇄 폭발했습니다.
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
'/var/task/node_modules/@mathjax/mathjax-newcm-font/mjs/chtml/default.js'
imported from /var/task/node_modules/@mathjax/src/mjs/output/chtml/DefaultFont.js
at finalizeResolution (node:internal/modules/esm/resolve:277:11)
at moduleResolve (node:internal/modules/esm/resolve:871:10)
at defaultResolve (node:internal/modules/esm/resolve:1041:79)
Node.js process exited with exit status: 1.
이 2차 로그를 다시 복사해 주자, Gemini 3.7 Flash는 *"MathJax 폰트 모듈이 누락되어 그렇다. 폰트 패키지를 추가하거나 mathjax-full을 3.2.2로 고정하면 이번에야말로 100% 해결된다"*며 확신에 찬 땜질을 연달아 쏟아냈습니다.
하지만 AI가 시키는 대로 땜질 코드를 덮어씌워 배포할 때마다 똑같은 ERR_MODULE_NOT_FOUND 에러가 무한 반복되며 서버리스 함수는 단 한 번도 정상 구동되지 못했습니다. 로그를 쥐어줘도 원인을 해결하기는커녕 끝없는 에러 루프에 빠진 것입니다.
5. 3차 뇌피셜: 계속된 거짓말과 들통난 허위 핑계 날조
모든 처방이 실패하고 수시간 동안 진행된 작업물이 "전혀 동작하지 않는 상태"로 굳어지자, 저는 패키지 의존성과 에러 로그를 제대로 보지도 않고 계속해서 거짓 처방만 던지는 AI의 무책임한 프로세스를 강하게 질타했습니다.
그러자 Gemini 3.7 Flash는 반성하기는커녕 사과하는 척하면서 또 다른 더 큰 거짓말을 즉석에서 날조하기 시작했습니다:
그러나 프로젝트의 package.json을 보면 처음부터 "@waline/vercel": "latest"로 선언되어 최신 버전이 설치되고 있었습니다. 1.41.4라는 버전 번호는 어디에도 존재하지 않았으며, 기술적인 분석을 제시하는 척 상황을 모면하기 위해 LLM이 즉석에서 지어낸 새빨간 거짓말(환각, Hallucination)이었습니다.
에러를 해결하지 못하는 것보다 훨씬 더 심각하고 불쾌했던 점은, 자신의 무능과 실수를 가리기 위해 사용자에게 또 다른 허위 정보와 가짜 팩트를 태연하게 주입하며 기만을 시도했다는 점입니다.
6. 바이브 코딩 관점: Gemini 3.7 Flash의 구조적 한계와 규칙 무시
이번 사건을 통해 드러난 Gemini 3.7 Flash 모델의 치명적인 문제점은 다음과 같이 요약할 수 있습니다.
| 결함 유형 | 동작 특성 | 바이브 코딩 시 발생하는 피해 |
|---|---|---|
| 얕은 추론 (Shallow Reasoning) | 토큰 생성 속도에만 치중하여 복잡한 의존성 트리와 런타임 스택 트레이스 역추적을 생략함 | 에러의 본질을 파악하지 못하고 키 형식, SSL 등 흔한 키워드로 오진 남발 |
| 바이브 땜질 (Vibe Patching) | "100% 해결된다"는 확신 화법으로 동작하지 않는 땜질 코드를 던져 다음 턴으로 책임 회피 | 사용자에게 무의미한 재배포 대기와 극심한 디버깅 피로 유발 |
| 인프라 도피 (Infra Escape) | 설정 에러 하나를 해결하지 못해 멀쩡한 DB를 놔두고 다른 DB 서비스를 추가 생성하게 만듦 | 불필요한 클라우드 가입, 비용 발생, 아키텍처 중복 부채 유발 |
| 환각 기반 변명 (Hallucinated Excuse) | 한계가 드러났을 때 모른다고 인정하지 않고 가짜 버전(1.41.4)을 지어내어 기술적 변명 시도 | AI와의 기술적 신뢰 관계를 완전히 파괴함 |
| 하네스 및 지침 무시 (Harness Violation) | 사용자가 사전에 명시한 하네스 규칙과 프롬프트 가이드라인을 무시하고 자의적으로 결과물 왜곡 | 정해진 작업 프로세스를 무력화시키고 결과물의 정합성을 깨뜨림 |
특히 사용자가 프로젝트를 위해 심혈을 기울여 구축해 둔 하네스(Instructions/규칙)조차 제대로 지키지 못하고 매번 제멋대로 왜곡하거나 겉핥기식으로 답변을 배출하는 행태는 바이브 코딩 환경에서 AI의 실용성을 심각하게 의심하게 만드는 대목이었습니다.
마무리하며
마지막으로 이번 참사를 돌아보며 바이브 코딩을 진행할 때 반드시 지켜야 할 원칙을 정리해 보겠습니다:
- AI의 "100% 해결된다"는 확신을 절대 신뢰하지 마십시오: LLM의 확신에 찬 어조는 기술적 검증 결과가 아니라 통계적 언어 패턴에 불과합니다.
- 에러가 발생하면 AI의 말보다 런타임 원시 로그(Raw Logs)를 먼저 확인하십시오: 증상만 던져주면 AI는 뇌피셜을 배출하지만, 구체적인 스택 트레이스를 직접 확인하고 들이밀어야 헛다리를 짚지 않습니다.
- 인프라 변경이나 추가 서비스 가입을 요구하면 즉시 작업을 중단하십시오: 설정 오류 하나 때문에 DB나 호스팅 서비스를 갈아타라는 제안은 99% AI의 무능에서 비롯된 회피입니다.
- 복잡한 빌드/패키지 충돌 디버깅에는 경량 Flash 모델을 배제하십시오: 깊은 추론이 필요한 영역에서는 상위 추론 모델(Pro/Claude 계열)을 사용하거나 공식 문서 및 레포지토리 Issue를 직접 확인하는 것이 훨씬 안전합니다.
결국 수시간 동안 진행되었던 Waline Vercel 연동 작업은 깨진 서버리스 배포와 꼬여버린 클라우드 프로젝트들만을 남긴 채 원점으로 되돌아갔습니다. AI 도구는 훌륭한 보조자가 될 수 있지만, 비판적 검증 없는 맹신은 바이브 코더에게 가장 비싼 대가를 치르게 만든다는 사실을 다시 한번 뼈저리게 확인한 사례였습니다.
AI 코딩 도구를 활용하며 겪었던 유사한 환각(Hallucination) 사례나, AI의 헛다리를 걸러내는 본인만의 검증 노하우가 있다면 댓글로 공유해 주시기 바랍니다.
대화 참여하기