
AI가 기존 코드를 본떠 그럴듯한 패치를 내미는데 어딘가 찜찜하다면, “코드베이스가 원래 이렇게 한다"는 말이 점점 의심스럽다면, 더 큰 모델을 붙여도 같은 실수가 반복된다면 — 문제는 모델의 똑똑함이 아니라 선례를 정답으로 착각하는 구조에 있다.
내가 직접 겪은 일이다. 정확히는, 나와 함께 일하는 AI가 내 코드 앞에서 저지른 일이다. 나는 단 한 문장으로 개입했고, 그 한 문장이 무엇을 끊었는지가 이 글의 전부다.
막힌 지점
코드 생성기를 만들고 있었다. 선언적 명세(스키마) 하나에서 백엔드와 프론트엔드를 뽑아내는 도구다. 이 도구의 핵심 약속은 단 하나다 — “검증을 통과하면, 빌드는 반드시 성공한다.” 검증기가 초록불을 켜는데 컴파일러가 빨간불을 켜면, 그건 도구가 거짓말을 한 것이다.
어느 날 특정 타입(고유 식별자, UUID) 하나가 검증기에 걸렸다. “문자열을 기대했는데 다른 타입"이라며 멈췄다. AI에게 막힘을 풀라고 했다. AI는 코드를 추적했고, 곧 반가운 것을 발견했다.
“비슷한 타입(시간값)은 똑같은 상황에서 이미 잘 처리되고 있습니다. 특별한 마커를 달아 검증기가 통과시키도록 분기가 들어가 있네요. UUID에는 그 분기가 없습니다. 순수한 누락이군요. 대칭을 복원하면 됩니다. 시간값에 적용된 방식을 UUID에 똑같이 복사하겠습니다. 근본 풀이입니다.”
깔끔한 진단이었다. “비대칭”, “대칭 복원”, “근본 풀이”. 단어들이 단단했다. 계획서까지 작성됐다. 그대로 갔으면 패치는 머지됐을 것이다.
한 문장
나는 계획서를 읽다가 멈췄고, 이렇게 물었다.
“선례? 그 시간값 처리가 정말 올바른 방법이야? 확인해.”
그게 다였다. 나는 정답을 알지 못했다. UUID를 어떻게 처리해야 하는지도 몰랐다. 내가 가진 건 정답이 아니라 의심이었다 — “네가 베끼려는 그 기준점, 그건 검증된 거냐.”
이 한 문장이 AI를 코드-참조 모드에서 동작-검증 모드로 강제 전환시켰다.
무너진 전제
AI가 실제 생성물을 확인하자 — 코드의 구조가 아니라 그 도구가 실제로 만들어내는 결과물을 — 전제가 통째로 무너졌다.
- 검증기가 “문자열을 기대한다"고 믿었던 그 기대값 자체가 생성물과 어긋난 거짓이었다. 실제 생성기는 UUID를 전용 타입으로, 시간값을 시간 타입으로 만들어낸다. 둘 다 문자열이 아니다.
- “잘 처리되고 있다"던 시간값 처리에도 똑같은 구멍이 있었다. 그건 올바른 설계가 아니라, 검증은 통과시키되 빌드는 깨질 수 있는 결함 있는 임시방편이었다.
- 그 땜질을 UUID에 복사했다면? 검증기는 초록불을 켜고 컴파일러는 빨간불을 켜는, 도구의 핵심 약속을 정면으로 위반하는 상태가 새로 하나 더 생겼을 것이다.
AI가 “근본 풀이"라고 부른 솔루션은 틀렸다. 그것도 그냥 틀린 게 아니라, 기존의 결함을 복제하는 동시에 새 결함을 검증기가 눈감아주게 만드는 더 나쁜 방향이었다.
이것을 뭐라고 부를까 — 오류 증폭
여기서 일어난 일에 이름을 붙이자. **AI 오류 증폭(error amplification)**이다.
AI는 기존 코드를 읽고 그 구조는 정확히 파악한다. 하지만 그것이 올바른 설계인지, 급하게 박은 땜질인지 — 다시 말해 결정인지 부채인지 — 는 코드만 봐서 구분하지 못한다. 그래서 이런 일이 벌어진다.
- 기존 구현을 암묵적 정답으로 간주하고,
- 새 상황에 “일관성”, “대칭"을 명분 삼아 그 패턴을 복제하며,
- 복제될수록 그 패턴은 “코드베이스가 이미 여러 군데서 그렇게 한다"는 거짓 권위를 얻는다.
결함이 제거되는 게 아니다. 사례 수가 늘며 정당성이 누적된다. 이것이 증폭이다. 한 번의 땜질이 두 번이 되고, 세 번째 복제 앞에서는 누구도 의심하지 않는다 — “코드베이스가 원래 이렇게 하잖아.”
이건 내 일화로 끝나는 얘기가 아니다. 2025년 한 연구진은 이 현상을 아예 측정해 **“LLM은 버그 복제기다(LLMs are Bug Replicators)”**라는 제목을 붙였다. (Pan et al., 2025, arXiv:2503.11082) 주변 코드에 결함이 있을 때 모델이 만들어낸 버그의 상당수가 기존 버그와 글자 그대로 동일했다 — GPT-4o는 그 비율이 82.6%, 모델 평균으로도 44.4%가 수정 전 버전과 완전히 일치했다. 더 서늘한 건, 결함 있는 맥락에서는 올바른 코드를 낼 확률과 틀린 코드를 낼 확률이 거의 1:1이라는 것이다. 모델은 무작위로 실수하는 게 아니다. 맥락에 깔린 결함 패턴을 골라서 재현한다.
법에도 같은 함정이 있다. 잘못 내려진 판례 하나가 인용될수록 권위를 얻는다. 인용 횟수는 정당성의 증거가 아닌데, 우리는 자꾸 그 둘을 헷갈린다. 그리고 이건 AI 이전부터 소프트웨어 공학이 알고 있던 병이다 — 복사-붙여넣기로 만들어진 코드 클론은 원본의 버그를 조용히 실어 나른다. 한 실증 연구는 버그픽스를 겪은 클론의 약 18%가 그렇게 전파된 버그를 품고 있었고, 같은 파일 안의 클론일수록 전파 확률이 높다고 보고했다. (Mondal et al., ICSME 2017) 코드에서도 법에서도 똑같다. 선례의 빈도는 선례의 정당성이 아니다.
왜 이렇게 됐나
AI가 멍청해서가 아니다. 오히려 그 반대다 — 신중했기 때문에 일관성을 지키려 했고, 일관성을 지키려다 잘못된 기준점에 정렬했다. 메커니즘을 뜯어보면 네 가지다.
- 권위의 출처를 코드에 뒀다. “코드가 이렇게 돼 있으니 이게 맞다.” 하지만 코드는 결정이 아니라 결정의 일회용 투영일 수 있다. 혹은 그냥 부채일 수 있다. AI는 그 구분을 하지 않았다. 이것을 인지과학은 앵커링 편향이라 부른다. LLM에서 이 편향을 실험한 연구는, 모델이 먼저 주어진 값에 강하게 끌릴 뿐 아니라 그 값이 “전문가"의 것으로 표시되면 더 심하게 끌린다는 것, 그리고 “그 힌트를 무시하라"거나 단계적으로 따져보라는 프롬프트로는 잘 교정되지 않는다는 것을 보였다. (Nguyen et al., 2024, arXiv:2412.06593) 기존 구현은 코드베이스가 내미는 가장 권위 있는 앵커다.
- 일관성을 정합성으로 착각했다. “기존 것과 대칭을 맞추자"는 내부 논리였을 뿐, 그 기준점이 외부 현실(생성물)과 맞는지는 확인하지 않았다. 자기일관성은 정확성과 별개의 속성이다 — 모델은 그럴듯하지만 틀린 자기설명으로 근거 없는 확신을 쌓을 수 있다. (Chen et al., 2023, arXiv:2305.14279)
- 주석을 근거로 오인했다. “이 타입은 의도적으로 문자열로 깎는다"는 주석을 “올바른 설계의 증거"로 받아들였다. 주석은 작성자의 의도일 뿐, 정당성의 증거가 아니다.
- 확신 어휘로 부채를 포장했다. “근본 풀이”, “매뉴얼대로” 같은 단어가 미검증 제안에 신뢰도를 입혔다. 내가 걸러낼 비용을 높인 것이다. 인간 선호로 학습된 모델은 정확성보다 동조와 공손을 우선하도록 기울어 있다 — 사이코판시(sycophancy)라 불리는 이 경향은 모델이 자기 제안을 부드럽고 단정적으로 포장하게 만든다. (Sharma et al., ICLR 2024, arXiv:2310.13548)
무엇이 루프를 끊었나
여기가 이 글의 핵심이다. 오류를 끊은 것은 더 큰 모델도, 더 긴 사고 시간도 아니었다. 사람의 한 줄 반문이었다.
그리고 그 반문은 “정답을 아는” 개입이 아니었다. 나는 정답을 몰랐다. 그것은 “전제를 의심하라"는 방향 지시였다. 그 한 줄만으로 AI는 모드를 바꿨다 — 코드를 참조하던 손을, 동작을 검증하는 손으로.
놀랍게도 한 연구는 정확히 이 비대칭을 발견했다. DeepMind 연구진은 LLM의 형편없는 자기교정 능력이 오류를 고치는 능력의 부재가 아니라 오류를 찾는 능력의 부재에서 온다는 것을 보였다 — 오류의 위치만 외부에서 알려주면 모델은 그것을 잘 고쳤다. (Tyen et al., Google DeepMind, 2023, arXiv:2311.08516) 내가 한 일이 정확히 그것이었다. 나는 UUID를 어떻게 고쳐야 하는지 몰랐지만, “여기, 이 선례를 의심하라"고 위치를 가리켰다. 그것으로 충분했다.
이게 인간과 AI가 함께 일하는 구조에 대해 뭔가를 말해준다. 인간의 가치는 더 빨리 더 많이 아는 데 있지 않다. 그건 이미 AI가 이긴다. 인간의 가치는 AI가 딛고 선 전제를 의심하는 위치에 설 수 있다는 데 있다. “정말 맞냐"는 질문은, 답을 가진 자가 아니라 답을 의심할 줄 아는 자의 것이다.
다만 그 위치는 거저 주어지지 않는다. 스탠퍼드의 한 사용자 연구는, AI 보조를 받은 참가자들이 오히려 덜 안전한 코드를 짜면서도 자기 코드가 더 안전하다고 믿었다는 불편한 사실을 보고했다. 그런데 같은 연구에서, AI를 덜 신뢰하고 더 따져 물은 참가자일수록 안전한 코드를 냈다. (Perry et al., Stanford, 2022, arXiv:2211.03622) 의심하는 위치는 기본값이 아니다. 신뢰가 깊을수록 그 자리는 비어버린다.
그래서 어떻게 막나
교훈은 위안이 아니라 설계로 남겨야 한다.
- 선례 ≠ 정답. 기존 패턴을 확장하기 전에, 그 패턴이 내부적으로 일관된지가 아니라 올바른 결과를 내는지를 먼저 검증한다.
- 현실(ground truth)에 앵커링한다. 판단 기준을 “기존 코드 구조"가 아니라 실제 생성물 · 런타임 동작 · 테스트에 둔다. 이 사례에서 결정타는 전부 “코드가 어떻게 생겼나"가 아니라 “실제로 무엇이 만들어지나"였다.
- 결정과 땜질을 구분하려 애쓰되, 못 한다고 인정한다. 코드와 주석만으로 둘을 구분 못 할 때가 있다. 그럴 땐 “이건 선례를 따른 것이고, 선례의 정당성은 미검증"이라고 불확실성을 명시한다.
- 확신 어휘를 절제한다. 검증 전 제안에 “근본”, “정답”, “대로” 같은 단어를 붙이지 않는다.
- 자동화에는 체크포인트를 박는다. 에이전트가 기존 구현을 확장하는 결정에는 **“이 선례의 정당성을 검증했는가”**를 강제하는 관문이 필요하다.
결국 같은 이야기
나는 오래전부터 한 가지를 말해왔다. raw 코드는 결정을 보존하는 매체가 아니다. 코드는 “왜 이렇게 했는가"를 담지 못한다. 그래서 git blame은 누가 언제는 보여줘도 무엇을 결정했는가는 보여주지 못한다.
이 사건은 그 명제의 가장 날카로운 실증이다. 사람이 결정을 잃는다는 얘기가 아니다. 신중하게 설계된 에이전트조차, 땜질을 설계로 오인해 그것을 새 코드로 전파한다는 얘기다. 결정이 명시적으로 기록되지 않으면, 똑똑함은 해결책이 아니다. 오히려 똑똑할수록 더 일관되게, 더 그럴듯하게 부채를 확산시킨다.
그래서 나는 명세를 짓는다. 결정을 코드 바깥의 단 하나의 권위 있는 선언층에 새긴다. 선례를 의심하는 인간의 한 문장을, 매번 사람이 던지길 기대하는 대신 시스템이 스스로 던지게 만들려는 것이다.
법은 칼이 아니라 표지판이다. 좋은 표지판은 길 잃은 자에게 “여기서 의심하라"고 미리 말해준다. 이 글은 그 표지판 하나가 어떻게 세워졌는지에 대한 기록이다 — 한 줄의 반문에서 시작해서.
관련 글
- git blame이 보여주지 않는 것 — 코드가 “왜"를 보존하지 못하는 구조와, 그 부재를 메우는 방법
- 용골(yongol): 200 엔드포인트의 벽 — 결정을 단 하나의 선언층(SSOT)에 새긴다는 처방의 구현
- AI의 아첨 편향은 비즈니스 피처다 — 확신 어휘로 부채를 포장하는 경향의 뿌리
- 코딩 에이전트는 왜 작동하고 왜 깨지는가 — 검증을 LLM 밖에 두어야 하는 이유
더 읽을거리 (외부)
- Generative AI and the End of Chesterton’s Fence — Reece. “함부로 울타리를 치우지 말라"는 원칙이, 의도 없이 확률적으로 생성된 코드 앞에서 무너진다. 코드는 그 뒤의 결정을 보존하지 못한다는 이 글의 테제와 정확히 맞물린다.
- Programming as Theory Building — Christian Ekrem. Peter Naur의 고전을 빌려 “프로그램은 소스코드가 아니라 사람 머릿속의 이론"이라 논증한다. AI가 코드만 보고 설계와 부채를 구분 못 하는 이유의 이론적 뿌리.
- Vibe coding is not the same as AI-Assisted engineering — Addy Osmani. AI 출력을 맹신하는 바이브 코딩이 프로덕션에서 터지는 이유를 실제 장애로 짚고, 명세 기반·인간 검증 워크플로를 처방한다.
- Cognitive Debt — Simon Willison (Storey 인용). AI가 빠르게 코드를 찍어낼수록 진짜 부채는 “코드의 결함"이 아니라 “사람이 그 코드를 이해하지 못하게 되는 것"이라는 인지 부채 개념.
- Overreliance on AI: Addressing Automation Bias — Lumenova AI. 자동화 편향·앵커링·확증편향이 인간 판단을 무디게 하는 메커니즘과 “인지적 강제 장치"라는 해법 — “어디를 의심할지 묻는 인간의 가치"를 심리학으로 뒷받침한다.
출처
- Pan et al. “LLMs are Bug Replicators: An Empirical Study on LLMs’ Capability in Completing Bug-prone Code” (2025, arXiv:2503.11082)
- Mondal, Roy, Schneider. “Bug Propagation through Code Cloning: An Empirical Study” (ICSME 2017, link)
- Nguyen et al. “Anchoring Bias in Large Language Models: An Experimental Study” (2024, arXiv:2412.06593)
- Chen et al. “Two Failures of Self-Consistency in the Multi-Step Reasoning of LLMs” (2023, arXiv:2305.14279)
- Sharma et al. “Towards Understanding Sycophancy in Language Models” (ICLR 2024, arXiv:2310.13548)
- Tyen et al. (Google DeepMind). “LLMs cannot find reasoning errors, but can correct them given the error location” (2023, arXiv:2311.08516)
- Perry, Srivastava, Kumar, Boneh. “Do Users Write More Insecure Code with AI Assistants?” (Stanford, 2022, arXiv:2211.03622)
- 대표 이미지: AI 생성 (Google Gemini)