주니어 개발자가 '어떻게 코드가 잘못되었는지 알았냐'고 물었을 때, 나는 대답할 수 없었다.
요약
주니어 개발자가 AI 생성 코드를 제시했을 때, 작성자는 단순한 버그가 아닌 '형태'의 이상함을 감지하여 배포를 막았다. 이 경험을 통해 시니어 개발자의 지식은 명시적인 규칙(Knowledge)뿐 아니라, 모든 검증이 통과했음에도 무언가 잘못되었다고 느끼는 직관적 판단력(Judgment)에 기반한다는 것을 깨달았다.
핵심 포인트
- 시니어의 가치는 단순한 지식이 아닌 '판단력'이다.
- 규칙을 넘어선 직관적인 오류 감지 능력이 핵심 역량이다.
- 이러한 판단력은 교육이나 과정으로 전달되기 어렵다.
- 실제 경험과 실패를 통해 체득되는 것이 가장 중요하다.
우리는 목요일에 페어 프로그래밍을 하고 있었다. 특별할 것 없는 날이었다. 우리 팀의 주니어 개발자였는데, 아마 8개월 정도 되었고, 똑똑해서 코드를 붙여넣기만 하는 사람이 아니라 실제로 읽는 타입이었다. 우리가 AI에게 로직 일부를 요청했고, 몇 초 만에 깔끔하고 타이핑된 코드와 이미 그가 작성한 테스트를 통과하는 결과물이 돌아왔다.
그가 그것을 수락하려 했다. 나는 "안 돼, 그거 배포하지 마."라고 말했다.
그는 멈췄다. 코드를 다시 봤다. 나를 바라봤다. 그리고 세상에서 가장 합리적인 질문을 던졌다.
"잠깐만요—어떻게 그걸 틀렸는지 아셨어요?"
나는 입을 열어 설명하려 했지만, 아무 말도 나오지 않았다.
내가 알았지만, 어떻게는 말할 수 없었다.
나를 당황하게 만든 것은 바로 이 점이었다. 드라마틱한 버그가 아니었고, 드라마틱한 이야기도 아니다. 디프(diff)가 틀렸다. 내가 그것이 틀렸다는 것은 맞았고, 10분 후에 우리는 그것을 증명했다. 그 부분은 괜찮았다.
문제가 된 것은 내가 무엇을 했는지 어떻게 설명해야 할지 전혀 알 수 없었다는 것이다. 나는 체크리스트를 돌리지 않았다. 특정 라인을 발견하고 규칙과 일치시킨 것도 아니었다. 그것의 형태(shape) 같은 무언가가 내 목덜미를 차갑게 만들었고, 나는 수많은 세월을 거치며 그 정확한 느낌을 신뢰하는 법을 배웠다. 하지만 "목덜미에서 느껴지는 차가운 감각을 믿으라"는 것은 아직 목이 자라지 않은 사람에게 건넬 수 있는 조언이 아니다.
그래도 시도해봤다. 나는 그것이 어딘가 이상하게(off) 느껴진다고, 에러 경로가 너무 편리해 보인다고, 만약 이것이 두 번 호출되면 어떻게 되는지 알고 싶다고 말했다. 모두 사실이었다. 하지만 그에게는 쓸모없는 이야기였다. 왜냐하면 이 모든 것은 결론이었고, 그는 _방법(method)_을 묻고 있었는데, 나에게는 방법이 없었기 때문이다. 나는 읽기를 끝내기도 전에 발동하는 흉터 같은 것이 있었다.
그것이 내가 계속 곱씹어 온 부분이다. 그가 배울 수 없다는 것이 아니다. 내가 하루 종일 하는 가장 가치 있는 일이 바로 그것을 전달할 방법을 나 자신이 모른다는 것이다.
'시니어'라는 단어에는 두 가지가 포함되어 있다
수년 동안 나는 시니어 개발자라는 것이 지식의 더미라고 생각했다. 그리고 그 부분이 맞기도 하고, 내가 가르칠 수 있는 부분도 있다. '경계에서 유효성 검사(Validate at the boundary)를 하라.' '클라이언트가 제공한 타임스탬프를 신뢰하지 마라.' '외부 호출은 래핑(Wrap)하라.' 규칙들이다. 나는 그것들을 화이트보드에 적을 수 있고, 그는 금요일까지 그것들을 갖게 될 것이다. 그리고 솔직히 말해서, AI는 이미 이 모든 것을 가지고 있으며 나보다 더 일관성 있게 적용한다.
하지만 내가 목요일에 한 것은 규칙이 아니었다. 그것은 규칙의 반대였다. 우리 둘 중 누구도 지목할 수 있는 모든 규칙을 만족시키는 깔끔한 diff(변경 사항)에도 불구하고, 여전히 무언가 잘못되었다는 것을 아는 것이었다. 규칙은 무엇을 확인해야 하는지 알려준다. 다른 것은 모든 확인이 통과했음에도 계속 찾아보라고 말한다. 하나는 지식이고, 다른 하나는 판단력(judgment)이다. 그리고 나는 그것을 그 가치를 인정받지 못한 사람에게 전달할 수 있는 말로 단 한 번도 표현해 본 적이 없다.
당신은 판단력을 배우지 않는다. 당신은 그것 속으로 살아남는다 — 그리고 이것이 내가 그것을 그에게 넘겨줄 수 없었던 정확한 이유이다.
나에게 목요일에 했던 일을 가르쳐 준 사람은 아무도 없었다. 과정(course)도, 인증서(cert)도, 나를 앉혀놓고 알려준 시니어 개발자도 없었다. 나는 내가 생각하는 모든 사람이 얻는 유일한 방식으로 그것을 배웠다. 중요한 무언가에 대해 자신감 있게 틀렸다는 것을 깨달았고, 비용을 지불하는 사람 앞에서 그랬으며, 그 교훈이 용접되듯 내게 각인되었다.
실제로 차가운 느낌이 온 곳
내가 정확히 어디서 움찔했는지 출처를 추적할 수 있도록 구체적으로 말해보겠다.
몇 년 전 나는 클라이언트에게 행(row)을 실제로 저장하기 전에 '알았다'고 알려주는 쓰기 경로(write path)를 구현했다. 코드는 깔끔했다. 진정으로 깔끔했다 — 관용적이고, 타입이 지정되었으며, 테스트가 둘러싸여 있고, 오류 처리가 완벽하게 되어 있었다. 내가 신중했기 때문에 누군가 조심스럽게 쓴 것처럼 보였다. 당시 내가 알던 모든 규칙에 따라 그것은 올바른 것이었다.
그러다가 어느 평범한 날 재시도(retry)가 정확히 잘못된 순간에 도착했다. '알았다'는 메시지가 나갔지만, 저장은 일어나지 않았고, 비용을 지불하는 고객은 로그에 자신이 거기에 있었다는 기록조차 없이 자신의 계정에서 잠겨버렸다. 먼저 확인하고 나중에 영구 저장(Ack before persist). 나는 아직도 그 전화 통화가 느껴진다.
그것이 근원이다. 목요일의 diff를 봤을 때 등골이 서늘해졌는데, 나는 알고리즘을 돌리고 있던 게 아니었다. 그 고객에게서 패턴 매칭을 하고 있었던 것이다. AI가 만든 깨끗한 코드는 내가 작성했던 깨끗한 코드만큼 정확해 보였고, 그러다가 누군가가 계정을 잃게 만들 때까지는 그랬다. 움찔거림(the flinch)은 바로 그 고객이며, 그것이 반 초 만에 압축되어 그 해 최악의 밤에 내 신경계에 용접된 것이다.
그래서 주니어가 '어떻게 알았냐'고 물었을 때, 솔직하고 완벽한 대답은 이랬다. 내가 4년 전 새벽 2시에 잠가버린 한 사람에게서 배웠고, 그 사람 없이는 어떻게 설명해야 할지 모르겠다. 움찔거림(the flinch)은 강의를 듣는다고 생기지 않는다. 오직 불운하게도 여러 번 경험하면서 스스로 자라나게 하는 것뿐이다.
그리고 실제로 나를 겁먹게 하는 부분은 이것이다
20년 동안, 움찔거림(the flinch)은 믿을 만한 공급망을 가지고 있었다. 그건 '노가다'를 함으로써 얻었다. 즉, 프로덕션 코드를 직접 작성하고, 배포하고, 그것이 고장 났을 때 현장에 있는 것이다. 작은 실패들이 원하든 원하지 않든 판단력(judgment)으로 쌓였다. 노가다를 건너뛸 수 없었기 때문에, 상처(scars)도 건너뛸 수 없었다.
우리가 방금 그 공급망에 무슨 일을 했는지 봐라.
주니어는 더 이상 프로덕션 코드를 작성하지 않는다. AI가 한다. 그리고 그것을 잘한다. 나는 기쁘다. 타이핑은 결코 어려운 부분이 아니었기 때문이다. 하지만 타이핑, 배포, 고장, 새벽 2시의 전화: 이것이 주니어를 나로 만들었던 '전체 메커니즘'이었다. 우리는 단지 지루한 부분만 자동화한 것이 아니다. 우리는 그 용광로(forge) 자체를 자동화했다. 나는 AI가 지금 그에게 하는 정확한 일을, 그가 잘못되었다고 느끼기 전에 손으로 직접 해야 했기에 판단력을 얻었다. 그는 첫날부터 깨끗한 결과물을 받고, '목'을 가질 필요조차 없다.
그래서 AI가 살아남긴 유일한 기술 — 바로
저는 고통을 낭만화하는 것이 아니며, AI를 끌어다 놓고 그가 피 흘릴 때까지 CRUD(Create, Read, Update, Delete) 작업을 손으로 쓰게 만들자는 이야기도 아닙니다. 그것은 '짐꾼 문화적 멘토링(cargo-cult mentorship)'입니다. 고통 자체가 목적이 아니라, 그 결과가 목적이었던 거죠. 저는 AI를 하루 종일 사용하고 있으며, 결코 돌아갈 수 없을 겁니다. 문제는 그에게 일이 쉽다는 것이 아닙니다. 문제는 그것보다 더 좁고 이상합니다. 우리는 예전에 판단을 내리게 하던 것을 제거했고, 아무것도 대체하지 않았습니다.
따라서 지금의 실제 업무는 이것이며, 이는 분위기(vibes) 문제가 아니라 설계 문제입니다. 저는 그에게 움찔거림(flinch)을 줄 수 없습니다. 하지만 제가 움찔거리게 했던 한 가지 것—쉽게 틀릴 수 있는 곳에서 잘못된 것을 발견하는 경험—을 의도적으로, 더 빠르고, 실제 고객이 비싼 방식으로 하기를 기다리는 대신에 제공할 수는 있습니다.
제가 지금 그와 실제로 하는 몇 가지 일은 다음과 같습니다:
그를 저자가 아닌 회의론자로 만듭니다. AI가 diff(차이점)를 작성합니다. 그의 임무는 더 나은 것을 쓰는 것이 아니라, 우리가 받은 것을 망가뜨리는 것입니다. 무언가를 받아들이기 전에, 그는
저는 에이전트 플랫폼을 다루고 있는데, 현재 업계 전체가 결과물을 생산하는 것에 열광합니다. 얼마나 많이 배포했는지, 얼마나 깔끔한지 보세요. 하지만 무언가를 생산한다는 것은 희소성이 사라진 기술을 수행하는 것일 뿐입니다. 게다가 더 나쁜 점은, 그것이 스스로의 작업에 승인 도장을 찍는다는 것입니다. 걸작과 재앙 모두에 똑같이 자신감 넘치는 '정상적이다'라는 낙인을요. 이건 주니어 개발자 같은 AI 버전입니다. 빠르고 유창하지만, 자기 자신을 전혀 믿지 못하는 능력이 없습니다.
그래서 저는 코드를 작성하는 것과 그것을 승인하는 것을 분리시켰습니다. 차이점(diff)을 생산하는 저자가 있습니다. 싸고 무한하게요. 그리고 그 차이점을 불신하고 부수려고 하는 것이 전업으로 직업인 회의론자(skeptic)가 있습니다. 스스로에게 '주저함'이라는 자리를 마련해 준 것입니다. 그래서 누군가가 운 좋게 그것을 키워낼 필요가 없도록 말이죠. 그리고 병합 버튼(merge button)에 사람이 존재합니다. 왜냐하면 여전히 누군가가 그 결정을 책임져야 하기 때문이고, 그 인간이 진짜 상처를 쌓는 사람입니다. 저자, 회의론자, 인간. 이것이 바로 xenition 전체의 형태이며, 주니어 개발자의 질문에 대한 저의 실제 답변입니다. '주저함'은 가르칠 수 없으니, 그 역할을 수행하는 자리를 만들고 그 사람을 그 안에 배치하여 스스로 갖게 할 수 있다는 것입니다.
저는 여전히 그에게 제가 어떻게 알았는지 말해줄 수는 없습니다. 제가 할 수 있는 것은 그를 저처럼 깨닫게 될 곳에 두는 것뿐입니다. 잘못된 방식으로, 일찍, 그리고 교훈의 비용이 고객이 아닌 카나리아 정도만 들 만큼 충분히 저렴한 곳에요. '아는 것'은 결코 가르칠 수 없습니다. 하지만 '잘못하는 경험'은 가능합니다. 그것만이 제가 실제로 그에게 건네줄 수 있는 부분입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기