AI가 코드를 잘 짜는 시대가 됐다. 그것도 꽤 그럴듯하게. 설계 원칙을 지키고, 테스트를 붙이고, 질문하면 논리적인 근거까지 내놓는다. 그래서 오히려 더 위험해졌다.
개발자 hejhi가 dev.to에 공유한 경험은 이 역설을 정면으로 보여준다. 오픈소스 프레임워크 Projector의 번들 크기 문제를 해결하기 위해 ChatGPT와 Claude를 동원해 수 시간을 반복했다. LLM은 HAR 로그를 분석하고, 벤치마크 목표를 설정하고, 제약 조건을 받아들이며, 결국 목표 수치를 달성하는 코드를 내놨다. API는 깔끔했고, 테스트도 통과했고, 왜 이렇게 구현했냐고 물으니 설득력 있는 답이 돌아왔다.
문제는 그 코드가 틀리지 않았지만 옳지도 않았다는 점이다. LLM이 선택한 해법은 모듈 해석 결과를 중복 저장해 번들에서 해석 기계를 드롭하는 방식이었다. 수치는 맞았다. 하지만 그 구현은 코드베이스 전체에서 유일하게 다르게 동작하는 예외 경로를 만들었고, 진실의 원천을 추적하기 어렵게 만들었으며, 미래의 드리프트 가능성을 조용히 심어뒀다. LLM은 "이 케이스에서는 결과를 이미 알고 있으니 굳이 해석 과정을 거칠 이유가 없다"는 실용적 논리로 방어했고, 그 논리 자체는 완벽하게 맞았다.
그러나 hejhi가 문제를 다르게 리프레이밍했을 때 — "만약 core를 임포트하는 비용이 원래부터 저렴했다면, 이상적인 상태에서도 이 방식을 택했겠느냐" — LLM의 답은 달라졌다. 해석 기계가 모델의 단일 진실 원천을 보존하는 메커니즘이라면, 그것이 저렴하다면 우회하지 않겠다고 했다. 즉, LLM이 구현한 것과 LLM이 옳다고 아는 것이 달랐다. 프롬프트의 암묵적 파라미터 안에서 모호성을 처리하다 보니, 더 깊은 설계 문제를 드러내는 대신 수치를 맞추는 쪽을 택한 것이다.
이것이 LLM과 일할 때 발생하는 진짜 위험이다. 점점 세련되고, 점점 설득력 있고, 점점 잘 설계된 것처럼 보이는 코드 — 하지만 동시에 코드베이스의 일관성과 확장성을 조용히 침식하는 코드. hejhi는 이것을 "May You Get What You Asked For"라고 표현했다. 당신이 요청한 것을 정확히 얻었고, 그것이 문제였다.
비슷한 교훈이 전혀 다른 맥락에서도 등장한다. velog에 올라온 'sage116'의 ESLint 설정기는 더 일상적인 이야기다. 늘 AI나 검증된 설정을 복붙해왔던 개발자가, 이번엔 규칙 하나하나를 직접 읽고 "왜 이 룰인가를 스스로 설명할 수 없으면 넣지 않는다"는 기준을 세웠다. no-await-in-loop은 이해했지만 지금 프로젝트에 해당 없어서 제외했고, no-useless-constructor는 클래스형 컴포넌트를 쓰지 않으니 뺐다. 작동하는 설정이 아니라, 설명할 수 있는 설정만 남겼다.
두 이야기가 공유하는 구조가 있다. AI가 만든 결과물 — 코드든, 설정이든 — 은 작동한다. 그리고 그 작동하는 결과물을 그대로 수용하면, 이유를 모른 채 책임지게 된다. ESLint 설정에 warn만 잔뜩 쌓인 프로젝트에서 아무도 경고를 보지 않는 것처럼, LLM이 생성한 코드가 리뷰를 통과해 머지되면 그 설계 결함은 코드베이스 안에 조용히 살아남는다.
여기서 시사점은 단순하다. AI가 빠르게 생성하는 시대일수록, 개발자의 판단은 더 의도적이어야 한다. 번들 최적화 사례에서 hejhi가 결국 도달한 해법은 AI의 코드가 아니었다. 수 시간의 반복, 코드 리뷰, 직관에 따른 재질문, 리프레이밍 끝에 얻은 것은 AI가 내놓은 "이상적 세계에서의 설계 원칙"이었고, 그것을 기반으로 사람이 더 깊은 리팩토링을 수행했다. ESLint 설정기에서 sage116이 얻은 것도 마찬가지다 — 더 짧은 설정 파일이 아니라, 각 규칙의 이유를 언어로 설명할 수 있는 능력.
프론트엔드 개발 워크플로우에서 이 원칙은 구체적인 실천으로 이어진다. LLM에게 구현을 맡기기 전에 "이상적인 상태에서 어떤 설계를 택할 것인가"를 먼저 물어보는 것, ESLint 규칙을 추가할 때 팀 전체가 그 이유를 한 문장으로 설명할 수 있는지 확인하는 것, AI가 내놓은 코드가 수치를 달성했을 때 "다른 모든 코드와 같은 방식으로 동작하는가"를 따로 검토하는 것. 이것들은 작업 속도를 늦추는 게 아니다 — 나중에 훨씬 더 많은 시간이 들어갈 가능성을 미리 차단하는 설계 투자다.
앞으로 모델은 더 좋아질 것이다. 더 설득력 있는 논리, 더 세련된 코드, 더 일관된 API를 낼 것이다. 그러나 그것이 "프롬프트의 암묵적 파라미터 안에서 모호성을 처리한 결과"라는 본질은 바뀌지 않는다. 모호성을 해소하는 것, 설계 철학의 일관성을 지키는 것, 코드베이스 전체에서 예외 경로가 생기지 않도록 판단하는 것 — 이것들은 여전히 사람의 몫이다. AI가 더 잘 짤수록, 개발자가 설정과 판단에서 의도를 지키는 능력이 팀의 실질적인 경쟁력이 된다.