코드는 더 싸졌다
(htmx.org)- AI 코딩 도구 확산으로 코드 작성 비용은 급격히 낮아졌지만, 정작 생성된 코드를 이해하는 비용은 더 커진 현실
- LLM은 비결정적이고 원본 소스를 보존하지 않으며 출력 범위가 일반 소프트웨어 전체로 넓어, 컴파일러 출력과 동일시할 수 없음
- LLM은 사람이 이해할 수 있는 속도보다 훨씬 빠르게 코드를 생성하므로, 아무도 이해 못 하는 대규모 변경을 막기 위한 점진적(incremental) 사용 권장
- 코드가 저렴해질 때의 핵심 위험은 복잡성(complexity) 이며, 시스템 규모에 따라 최소 기하급수적으로 증가하는 반면 LLM은 복잡성에 대한 두려움이 없는 다작 코더
- 해법으로 코드를 더하기보다 제거·단순화하는 빼는 엔지니어(subtractive engineer) 를 제시하며, 컴퓨터 프로그래밍의 기예 유지 강조
코드가 저렴해진 시대
- 지난 1년간 AI가 상당히 괜찮은 품질의 코드를 매우 빠르게 대량 생성하면서, 코드 생성 비용이 크게 낮아짐
- "코딩은 애초에 문제가 아니었다"는 주장에 대해, 코딩 역시 문제의 일부였으며 그 부분이 AI 코딩 도구로 크게 줄었다고 반박
- 과거 코딩 능력으로 자부심을 느끼던 개발자에게, 순수 코딩의 중요도 하락이 어떤 의미인지 질문 제기
이해 비용의 상승 (Understanding is Expensive(er))
- 코드가 프로그래머의 손에서 힘겹게 나오는 대신 대량 생성될 때, 그 코드에 대한 이해 자체가 존재하지 않음
- 이해가 필요하다면 코드 작성 이후 코드를 읽어서 확보해야 함
- 통념상 남이 쓴 코드를 읽는 것은 자기 코드를 쓰는 것보다 더 어려움
- "컴파일러 출력도 이해하지 못하지 않느냐"는 AI 옹호론을 범주 오류(category error) 로 규정
- 컴파일러는 결정적이지만 LLM은 설계상 비결정적
- 컴파일러 워크플로는 원본 소스 코드를 보존하지만 LLM 워크플로는 대개 보존하지 않음
- 컴파일러 출력은 기계어라는 좁은 도메인에 한정되지만 LLM 출력은 일반화된 소프트웨어로 한정되지 않음
- 대부분의 경우, 특히 미션 크리티컬 소프트웨어에서는 LLM 생성 코드라도 개발자가 기저 코드를 이해해야 함
- LLM은 누구도 따라잡지 못할 속도로 코드를 생산할 수 있어, 이해 속도를 추월하는 위험 존재
- 따라서 거대한 변경 목록을 한꺼번에 생성하기보다 점진적 사용 권장
- 기계적 리팩토링에는 적절할 수 있으나, 코드베이스에 새로운 의미(semantics)를 도입할 때는 극히 위험
마법사의 제자 함정 (The Sorcerer's Apprentice Trap)
- Disney 영화 Fantasia 의 "The Sorcerer's Apprentice" 장면을 AI 시대의 적절한 비유로 제시
- 제자가 청소의 고역을 덜려고 빗자루에 마법을 걸자, 빗자루가 점점 격렬하게 청소하며 상황이 통제 불능에 빠짐
- 결국 마법사(Sorcerer)가 다시 나타나 상황을 장악하고 제자의 어리석음을 질책하며 혼란 수습
- 이 비유의 교훈은 제자가 아니라 마법사가 되어야 함이며, 마법사는 코드를 이해해야 함
복잡성은 여전히 나쁨 (Complexity: Still Bad)
- 인간은 기하급수·지수 곡선을 잘 파악하지 못하며, 복리(compound interest) 같은 것을 동화처럼 믿음
- 코드가 저렴해질 때의 핵심 위험은 복잡성(complexity) 이며, 시스템 규모에 따라 최소 기하급수적, 종종 지수적으로 증가한다고 (증명 없이) 주장
- LLM 이전에도 다작 코더(prolific coder) 가 존재
- 복잡성에 대한 두려움이 없는 다작 코더는 기존 문제 위에 코드를 계속 쌓아, 어떤 변경이든 고치는 만큼 버그를 만드는 수정 불가능한 정체 상태로 시스템을 붕괴시킴
- LLM은 복잡성에 대한 두려움이 없으면서 동시에 다작 코더이므로 위험
빼는, 제약하는 엔지니어 (The Subtractive, Constraining Engineer)
- LLM 생성 코드의 위험에 대응하기 위해 빼는·제약하는 엔지니어(subtractive, constraining engineer) 제안
- 이 엔지니어는 "아니오"라고 말하고, LLM 출력을 면밀히 검토하며, 단순화를 제안하고, 단호하게 통제력 유지
- 자신이 만든 코드가 아니라 시스템에서 제거하거나 진입을 막은 코드(및 레이어) 에 자부심을 둠
- 이 태도는 건축가(builder)보다 조각가(sculptor) 에 가까움
- 건축가(builder)적 태도는 시스템 설계 수준에서 여전히 유효
- 좋은 엔지니어는 컴포넌트를 효과적으로 조합해 시스템을 구성할 줄 알아야 함
- 다만 이 수준에서도 불필요한 컴포넌트와 시스템 경계를 제거해 배포·상호작용을 단순화하는 빼는 사고방식이 유용
- 빼는 엔지니어는 과거 대다수 코더와 다른 유형이며, "아니오" 말하기와 영웅적 재작성 대신 기존 시스템 다듬기를 선호하는 태도와 친화적
- 이 접근은 코드는 저렴해졌고 복잡성은 여전히 최상위 포식자(apex predator) 라는 이중 현실을 인정하며, 컴퓨터 프로그래밍의 기예를 지키는 생산적 방식
댓글과 토론
Lobste.rs 의견들
-
Peter Naur의 1985년 글 Programming as Theory Building는 요즘 몇 번 더 다시 읽을 가치가 있어 보임
-
“LLM은 복잡성을 두려워하지 못한다”는 표현은 과장에 가깝다고 봄
실패 양상 자체는 실제로 있음. 지시를 넓게 주면 LLM은 계층을 추가하고, 추상화를 만들어내고, 문제에 비해 과한 코드를 자주 냄. 하지만 그 행동은 관찰하기 쉽고, 리뷰하기 쉽고, 의외로 방향을 틀기도 쉬움. AGENTS/CLAUDE.md 파일로 원하는 소프트웨어 스타일을 맞추면 됨
가장 작은 변경을 요구하고, 무엇을 지울 수 있는지 묻고, 그 추상화가 제값을 하는지 물어보면 됨. 불변조건, 결합 지점, 인지 부담도 물어보고, 영리함을 제거하는 2차 패스를 요청하면 대체로 그 압력을 따라감. 프롬프트에 넣어두면 처음부터 피하게 만들 수 있음
위험은 LLM이 복잡성을 절대 존중하지 못한다는 데 있지 않고, 주변 프로세스가 보상하는 코드 형태를 기꺼이 만들어낸다는 데 있음. 양을 보상하는 팀은 양을 받고, 단순성을 보상하는 팀은 대체로 그것도 받을 수 있음
요즘 모델은 대부분의 인간보다 낫고 앞으로 더 좋아질 것임. 코드가 좋지 않으면 AI 연구소에 피드백으로 압박해야 함. 예를 들어 GPT 계열은 좋은 문서 작성에는 형편없다고 봄- 맞기도 하고 아니기도 함. 핵심은 능력이라기보다 훈련 방식과 목표에 가까워 보임. 지금 유행하는 건 “프로젝트 전체를 바이브 코딩했다”는 식이고, LLM은 처음부터 만드는 것에 비해 기존 코드를 바꾸는 데 매우 약함. 훈련 방식 때문일 가능성이 크고, 통계적 편향도 있어 보임. 크고 복잡한 코드베이스의 코드가 작고 단순한 프로젝트보다 훨씬 많으니 학습에서 더 큰 비중을 차지했을 것임
그래서 “불가능하다”는 표현은 최선이 아닐 수 있지만, 기본값으로는 복잡성 쪽으로 기우는 여러 편향이 있다고 봄
또 무언가를 하지 않는 것보다 무언가를 하는 쪽의 편향도 있음. 좋은 프로그래머는 특정 요청을 던지는 관리자보다 훨씬 많은 맥락을 쓰고, 대안을 제시하기도 함. LLM도 가능은 하겠지만, 현재 LLM은 “계획 중 질문하기”나 반복 감지 코드가 있어도 올바른 질문을 던지는 데 능숙하지 않음. 그런 학습 데이터도 흔하지 않을 가능성이 큼
어떤 면에서 프롬프트 엔지니어링은 이 문제 묶음을 둘러싼 끔찍한 해킹에 가까움 - 그 표현에 완전히 동의하는지는 모르겠지만, 분명 뭔가는 있음. 한편으로는 단일 대상 Makefile이면 충분한데도 거대한 CMake 프로젝트를 기본으로 만들어내는 식의 “흔한 복잡성”을 본 적이 있음
다른 한편으로는 “이건 한 달짜리 프로젝트라 추천하지 않습니다. 이 상태로 커밋하고 데모로 남기는 건 어떨까요” 같은 답을 받은 뒤 LLM을 설득하고 안심시켜야 했음. 둘 다 한 시간 이하로 끝날 걸 알고 있는데도 그랬음. 그런데 “그래, 완전히 새로운 걸 해봐. 방법은 네가 찾아”라고 하면 시도하긴 하니, 그런 의미에서는 두려움이 없다고도 볼 수 있음 - Lobsters에서 “바이브 코딩”에 대한 뉘앙스 있는 얘기라니, 지옥이 얼어붙었나 봄 /s
농담은 제쳐두고 동의함. 내 경험과도 맞음
- 맞기도 하고 아니기도 함. 핵심은 능력이라기보다 훈련 방식과 목표에 가까워 보임. 지금 유행하는 건 “프로젝트 전체를 바이브 코딩했다”는 식이고, LLM은 처음부터 만드는 것에 비해 기존 코드를 바꾸는 데 매우 약함. 훈련 방식 때문일 가능성이 크고, 통계적 편향도 있어 보임. 크고 복잡한 코드베이스의 코드가 작고 단순한 프로젝트보다 훨씬 많으니 학습에서 더 큰 비중을 차지했을 것임
-
“코드를 이해하는 비용이 더 비싸졌다”는 말에는 일반적으로는 잘 동의하지 않음
생각 없이 생성된 LLM 코드라면 맞을 수 있지만, 적절히 안내하면 LLM도 읽기 쉽고 계층이 잘 나뉜 코드를 만들 수 있음. 물론 그 경우 아키텍처 선택의 대부분은 사람이 하는데, 애초에 그래야 한다고 봄
반례로, 익숙하지 않은 사람이 작성한 코드를 이해하는 데 LLM이 매우 뛰어나다고 느꼈음. Claude Code에게 특정 코드를 깊이 분석해 각 부분을 설명하는 Markdown 문서를 만들게 하고, 내가 리뷰하거나 이해하기 시작할 순서까지 제안받을 수 있음
이건 정말 가치가 큼- 익숙하지 않은 코드에서 LLM을 쓰는 경험은 대체로 좋았지만, 관례에서 벗어난 부분에서 창의적으로 지어내고 거짓말하는 경우가 있음. 문제는 코드가 낯설기 때문에 둘을 구분하기 어렵다는 점임
-
“인간은 대체로 기하급수 곡선을 잘 이해하지 못한다. 그래서 복리 같은 동화를 믿는다”라니, 복리가 동화라는 뜻인가? 내가 뭔가 오해한 건가?