AI가 코드를 작성하는 시대에 코딩을 배우는 법
요약
AI가 코드를 대신 작성해 주는 시대에 개발자가 가져야 할 학습 태도에 대해 다룹니다. 단순히 작동하는 코드를 '수집'하는 것에 그치지 않고, 실패의 과정을 통해 원리를 '배우는' 능력이 중요함을 강조합니다.
핵심 포인트
- AI가 제안한 코드를 이해 없이 사용하는 것은 위험한 기본값임
- 에러를 즉시 해결해 주는 AI 환경에서 실패를 통한 학습 기회가 줄어듦
- 이해하지 못한 코드는 나중에 요구사항 변경이나 엣지 케이스에서 조용히 실패함
- 작동하는 코드를 넘어 원리를 파악하기 위해 의도적으로 멈춰 서는 기술이 필요함
작동은 하는데 왜 그런지는 모르겠습니다.
이것은 내 코드에 대해 내가 할 수 있는 가장 위험한 말이며, 이 말을 하기가 매우 쉬워졌습니다. 저는 AI가 대부분의 코드를 대신 작성해 줄 수 있을 정도로 발전한 해인 2025년에 소프트웨어 작성을 시작했습니다. 저는 AI 없이 코딩을 배워본 적이 없습니다.
이 주제에 대해 제가 읽은 대부분의 글은 먼저 배우고 나서 도구를 접한 사람들이 쓴 것입니다. 그들에게 AI는 톨게이트를 없애준 것과 같습니다. 그들은 이미 길을 알고 있었고, 이제는 그 길을 달리는 데 비용을 덜 지불하게 된 것입니다. 저는 톨게이트 비용을 지불해 본 적이 없습니다. 그것이 사라진 후에 도착했으니까요.
그것은 다른 상황이며, 다른 유혹을 동반합니다. 만약 기계가 이미 무언가를 작성할 수 있을 때 시작했다면, 그것을 이해하는 단계를 건너뛰는 것은 누군가 설득해야 할 위험한 경사로가 아닙니다. 그것은 기본값입니다. 더 빠르고, 작동하며, 외부에서는 소프트웨어 측면에서 아무도 알 수 없습니다.
그래서 제가 관심을 두는 질문은 AI가 나를 더 나쁜 프로그래머로 만드느냐가 아닙니다. 도구는 여기에 있고, 저는 매일 그것을 사용하며, 그것 없이는 더 느리고 더 가난해질 것입니다. 질문은 더 좁습니다. 기계가 작동하는 코드를 건네줄 때, 무언가를 '배우는 것'과 무언가를 '수집하는 것'을 가르는 차이는 무엇일까요?
가르침을 주는 실패와 그렇지 않은 실패
고장 난 코드는 요란하게 실패합니다. 스택 트레이스 (stack trace), 빨간색 테스트 결과, 로드되지 않는 페이지를 마주하게 됩니다. 그것을 수정하면, 수정하는 과정에서 자신이 어디서 틀렸는지 배우게 됩니다. 그것이 과거의 방식이었습니다. 버그는 수업료였습니다.
그 방식은 여전히 유효하지만, 그 기회의 창은 훨씬 짧아졌습니다. 에러를 다시 붙여넣으면, 해결책이 내려오고, 페이지가 로드되며, 무엇이 잘못되었는지에 대한 이론을 형성하기도 전에 40초 만에 상황을 넘길 수 있습니다. 실패는 여전히 일어납니다. 그것이 지금 무언가를 가르쳐줄지는 전적으로 당신이 멈춰서 살펴보느냐에 달려 있으며, 멈추지 말아야 한다는 엄청난 압박이 존재합니다.
저는 이것이 이 시대가 요구하는 실제 기술이라고 생각하게 되었습니다. 코드를 처음부터 작성하는 것이 아니라, 건너뛸 수 있었던 실패에 시간을 쓰기로 반복해서 선택하는 것 말입니다.
왜냐하면 다른 종류의 실패는 그러한 선택권을 주지 않기 때문입니다. 이해하지 못한 채 작동하는 코드는 조용히 실패하며, 나중에 실패합니다. 코드가 작성된 당일이 아니라, 요구사항이 변경되는 날, 혹은 엣지 케이스 (edge case)가 마침내 프로덕션 (production) 환경에서 나타나는 날, 또는 누군가 왜 이렇게 작성했느냐고 물었을 때 정직한 답변이 "모델이 제안했고 테스트가 통과(green)했기 때문입니다"라고 말해야 하는 날에 실패합니다.
이 점이 저를 가장 두렵게 만드는 부분은 멀티 테넌시 (multi-tenancy) 환경입니다. 제가 운영하는 SaaS에서는 각 기업의 데이터가 Postgres의 행 수준 보안 (row-level security) 정책에 의해 분리됩니다. 그 코드는 짧습니다. 마치 당연한 것처럼 읽힙니다. 그리고 만약 그 코드가 미묘하게 잘못되었다 하더라도 아무것도 깨지지 않습니다. 앱은 계속 작동하고, 테스트는 계속 통과하며, 한 기업이 다른 기업의 고객을 보게 될 뿐입니다. 그런 상황에 대한 스택 트레이스 (stack trace)는 존재하지 않습니다. 오직 제가 배포한 정책을 이해했는지 여부만이 남을 뿐입니다.
마케팅에서 이와 유사한 사례를 본 적이 있습니다
8년 동안 디지털 마케팅 에이전시를 운영했을 때, 동일한 실패가 다른 모습으로 나타나곤 했습니다.
누군가 경쟁사의 퍼널 (funnel)을 찾아내어 그대로 복제하곤 했습니다. 동일한 제안 구조, 동일한 광고 각도, 동일한 이메일 시퀀스, 동일한 랜딩 페이지까지 말입니다. 때로는 이것이 한동안 효과를 보기도 했는데, 이는 최악의 결과였습니다. 왜냐하면 그 방식이 옳다는 것을 확인시켜 주기 때문입니다.
그러다 무언가 변합니다. 트래픽 소스 (traffic source)가 더 비싸지거나, 타겟 오디언스 (audience)가 이동하거나, 경쟁사가 가격을 내립니다. 그러면 할 수 있는 일이 아무것도 없게 됩니다. 애초에 왜 그런 방식으로 구축되었는지에 대한 모델 (model)이 없기 때문입니다. 소유하고 있지 않은 전략은 조정할 수 없습니다. 그저 더 최신의 것을 복제하러 갈 수 있을 뿐입니다.
복제된 전략은 전략이 아닙니다. 그것은 타인의 것을 캡처한 스크린샷일 뿐입니다.
AI가 생성한 코드도 마찬가지입니다. 종종 제가 평생 읽을 코드베이스보다 더 많은 코드베이스로부터 추출된 매우 훌륭한 결과물이기도 합니다. 하지만 제가 왜 이것이 다른 것이 아닌 바로 이것이어야 하는지를 말할 수 있을 때까지, 그리고 그때까지 저는 스크린샷을 들고 있는 것에 불과합니다. 그 스크린샷은 무언가 변하기 직전까지만 작동합니다.
이해가 구체적으로 당신에게 가져다주는 것
느리게 진행하는 이유는 미덕을 쌓기 위해서가 아닙니다. 이해(understanding)가 레버리지(leverage)로 돌아오며, 그것이 매우 빠르게 돌아오기 때문입니다.
제가 실제로 직접 씨름하며 해결한 모든 문제는 다음번에 더 나은 지시어(instruction)로 변합니다. 기능의 첫 번째 버전은 제가 원하는 것이 무엇인지로 설명됩니다. 두 번째 버전은 제가 원하는 것이 무엇인지에서, 이제는 무엇이 잘못될지 알게 된 네 가지 사항을 제외한 상태로 설명됩니다. 그 두 번째 설명은 첫 번째 버전에서 나온 코드보다 더 가치가 있으며, 이는 모델이 저에게 건네줄 수 있는 것이 아닙니다. 그것은 무언가 망가지는 것을 지켜보고 왜 그런지 알아내려고 애쓴 결과물(residue)입니다.
이것이 복리 루프(compounding loop)이며, 이는 특히 이해(understanding)를 바탕으로 작동합니다. 단순히 코드를 직접 타이핑했느냐의 문제가 아닙니다. 모델은 그것을 조종하는 사람만큼만 정밀할 수 있으며, 정밀함은 당신이 고된 과정을 통해 배운 것들로 만들어집니다.
두 번째로, 타임시트(timesheet)에 정당화하기는 더 어려운 것이 있습니다. 기계적인 부분이 처리되면, 구문(syntax) 대신 도메인(domain)에 대해 호기심을 가질 여유가 생깁니다. 저는 언어와 싸우느라 머리를 처박고 있었을 때보다, Postgres가 실제로 정책을 어떻게 평가하는지, 또는 큐(queue)가 무엇을 보장하고 무엇을 보장하지 않는지에 대해 더 많이 읽었습니다. 여유 공간(headroom)은 실재합니다. 그것은 단지 무언가에 소비되어야 하며, 당신이 아무것도 하지 않는 것을 포함하여 당신이 향하는 곳 어디로든 흘러가게 될 것입니다.
제가 실제로 하는 일
이 중 그 어떤 것도 제가 다른 사람에게 권장하는 워크플로우(workflow)는 아닙니다. 이것은 제가 어떤 실수를 저지르기 쉬운지 정확히 알고 있기 때문에 제가 하는 방식입니다.
-
코드보다 추론 과정을 먼저 물어보세요. 대안은 무엇이었는지, 그리고 왜 이 방식이 선택되었는지 물어보세요. 저는 그것을 먼저 읽습니다. 만약 답변이 일반적(generic)이라면, 코드 역시 일반적일 가능성이 높으며, 이는 모델의 문제라기보다 프롬프트(prompt)의 문제라는 신호입니다.
-
병합(merge)하기 전에 소리 내어 설명하세요. 특별히 누구에게 하는 것은 아닙니다. 특정 코드 블록이 무엇을 하는지, 그리고 그것이 없으면 무엇이 망가질지 말할 수 없다면, 저는 코드를 읽은 것이 아니라 훑어본 것입니다.
-
계속 다뤄야 할 부분은 삭제하고 다시 작성하세요. 기능의 핵심 부분에 대해서는 제안(suggestion)을 닫고 기억을 되살려 다시 작성합니다. 속도는 느리지만, 나중에 다시 돌아와서 작업하게 될 코드에 대해서만 이 방식을 사용합니다. 만약 재현할 수 없다면, 저는 그것을 배운 것이 아니라 그저 구경한 것입니다.
-
이유를 기록하세요. create-mvp에는 35개의 아키텍처 결정 기록(architecture decision records)이 포함되어 있습니다. 그 가치는 문서화 그 자체에 있었던 것이 아닙니다. "Z 때문에 Y 대신 X를 선택했다"라는 문장은 Z를 모를 때는 쓰는 것이 불가능하기 때문에, 그 간극을 제가 확인할 수 있도록 겉으로 드러나게 만드는 데 있었습니다.
-
의도적으로 망가뜨려 보세요. 값을 바꾸거나, 가드(guard)를 제거하거나, 한 줄을 삭제한 뒤 무엇이 실패하는지 지켜보세요. 아무것도 실패하지 않는다면, 코드가 아무 일도 하지 않거나 테스트가 해당 부분을 커버하지 못하는 것이며, 이 두 가지 모두 운영 환경(production)이 아닌 화요일에 찾아내야 할 가치가 있는 일들입니다.
솔직한 불확실성
이 방식이 계속 유효할지는 아직 모르겠습니다.
제가 떨쳐낼 수 없는 우려는, 더 빠르게 반복(iterating)한다는 것이 시간당 더 많은 문제에 직면하면서도 각 문제를 이해하는 깊이는 줄어든다는 것을 의미할 수도 있다는 점입니다. 좁고 깊은 대신 넓고 얕은 지식이 되는 것이죠. 저는 빠르게 해결된 실패를 통해 단 한 번 접해본 많은 것들에 대해 의견을 가지고 있지만, 그중 무엇을 실제로 알고 있는 것이고 무엇을 단순히 인지(recognize)하고 있는 것인지 내부에서는 진심으로 구별할 수 없습니다.
제가 말할 수 있는 것은, 그 격차는 결국 나타나며, 그것은 특정한 종류의 침묵으로 나타난다는 것입니다. 즉, 이미 실행 중인 코드에 대해 제가 답할 수 없는 질문으로 나타납니다. 저는 그런 질문들을 몇 가지 수집해 왔습니다. 그것들은 제가 가진 가장 유용한 것들인데, 왜냐하면 그것들이 스크린샷(screenshot)이 끝나는 지점이 어디인지를 알려주는 유일하고 신뢰할 수 있는 신호이기 때문입니다.
목표는 결코 도움 없이 코드를 작성하는 것이 아니었습니다. 목표는 어떤 것이 작동하는 유일한 이유가 단지 모델(model)이 그렇게 말했기 때문인 상황에 결코 처하지 않는 것입니다. 이 시대에 시작한다는 것은 아무도 저에게 그 대가를 미리 치르게 하지 않는다는 것을 의미합니다. 저는 계속해서 스스로 그 대가를 치르기로 선택해야만 합니다.
저는 이 모든 것이 제 직업이 되기 전에 제가 어떻게 이곳에 도달했는지, 그리고 왜 이 사이트가 존재하는지에 대해 글을 썼습니다. 만약 제가 틀렸다고 생각하신다면, 여러분의 의견을 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기