우리, 프로그래머들 — .md로 코딩하는 시대

teo.v·2026년 3월 10일

테오의 프론트엔드

목록 보기
51/51
post-thumbnail

로버트 C. 마틴 (Uncle Bob), "우리, 프로그래머들 — AI 시대에 잊혀 가는 '프로그래머 정신'을 다시 깨우다"
도서 링크: https://gilbut.co/c/26015205VE

길벗 출판사에서 보내주신 소중한 도서를 계기로, AI 시대의 프로그래머에 대한 제 생각을 담았습니다. 평소 머릿속에 맴돌던 생각들을 이 책의 흐름을 빌려 차분히 정리해 볼 수 있었습니다. 감사합니다.


프롤로그

얼마 전 평소 제가 하던 고민들과 맞닿아 있는 흥미로운 책 한 권을 만났습니다. 엉클 밥(로버트 C. 마틴)의 신간, "우리, 프로그래머들", 1960년대 컴퓨터가 탄생하게된 에이다 러브레이스부터 엘런튜링, 다익스트라에서 시작해서 지금의 AI까지 60년의 프로그래밍 역사를 기록한 책입니다.

책장을 넘기며 오랜만에 기분 좋은 추억에 잠겼습니다. 학창 시절 칠판 앞에서 달달 외워야 했던 당연하게 여기던 CS 지식들이 단순한 이론이 아니라 그 시대의 개발자들의 치열한 고민과 발견의 기록이었다는게 새삼 느껴졌습니다.

어렸을 때 처음 코딩을 배우던 시절, "GOTO문은 절대 쓰면 안 된다"고 배웠습니다. 그때는 속으로 '도대체 왜 만들어 놓고 쓰지 말라는 거야?' 하고 툴툴거렸던게 기억이 나네요. 책을 읽다 보니 그 당연한 한 줄의 규칙 뒤에는, 다익스트라가 "사람이 읽을 수 있는 코드란 무엇인가"를 놓고 현업에서 벌인 피 튀기는 싸움이 있었습니다. 지금 우리에겐 공기처럼 당연한 규칙이, 그 시대에는 개발의 패러다임을 통째로 뒤집는 혼란이었던 셈이죠. 문득 "jQuery 이제 쓰지마라."는 선언과 함께, 리액트로 넘어가야 할 때 보이던 아득한 막막함이 겹쳐 보였습니다. 제가 맨 처음 개발을 배웠던 초등학교 때부터 지금 AI 시대까지, 딱딱한 기술서라기보단 위인전을 보듯 재밌게 읽어 내려갔습니다.

하지만 마지막 장을 덮고 나니, 이런 질문이 하나 남았습니다. "근데 이걸 안다고 뭐가 달라질까?"


서평을 떠올리려니 이 책의 유용함을 말해야 할 텐데 — 유용함이라... 솔직히 막막했습니다. (현정님, 그래서 한 달이나 넘게 걸린 건 죄송해요~) 분명 개발계에 큰 획을 그은 엉클 밥이 집대성한 역사를 접하는 건 흥미롭지만, 이 책이 주는 건 당장의 쓸모 있는 지식이나 메시지보다는 개발의 역사서나 위인전에 가깝습니다. 그래서 이걸 안다고 뭐가 달라지냐고 묻는다면 당장 대답할 말이 없었습니다.

"... 이제는 AI한테 말 한마디면 몇 백 줄짜리 코드가 그냥 쏟아져 나오잖아요. 당장 돌아가는 걸 만드는 법 자체가 바뀌고 있는데, 지난 60년간의 이야기를 아는 게 지금 저한테 어떤 의미가 있을까요?" 최근 개발을 배우려는 분들이나 주니어분들이 제게 던지는 이 현실적인 불안에 대해, 대답을 해줘야 하는 입장이지만 저조차도 쉽게 대답하기 어려운 힘든 변화의 시대를 맞이하고 있다는 생각이 들었습니다.

모르면 그냥 물어보면 되는 시대, 지식과 방법론이 AI에 의해 상향 평준화되는 상황을 지켜보며, '개발을 잘한다는 것'에 대한 정의 자체가 흔들리고 있다는 공허함이 찾아왔었습니다. 한때는 누구보다 빠르게 빈 에디터에서 화면을 뚝딱 만들어내는 것 자체가 실력이었고 저의 정체성이자 자부심이었는데, 이제는 한 줄 프롬프트면 그 코드가 나오니까요. AI라는 정말 재미난 장난감이 생겨서 즐거운 나날을 보내고는 있지만, 그 짜릿한 재미 이면에는 "지금 이게 내가 개발하고 있는 게 맞나?", "내가 정말 잘하고 있는 걸까?"라는 묘한 의문이 늘 따라붙었습니다.

흔히들, AI 시대에는 깊이가 중요하다, CS 지식이 중요하다는 말들을 많이 합니다. 하지만 솔직히 이 책에 나오는 어셈블러나 초창기 컴퓨터 지식을 우리가 속속들이 모른다고 해서 지금 당장 큰 문제가 생기지는 않습니다. 반대로 안다고 해서 달라질 것도 없죠. 그렇다면 우리가 가져야 할 진짜 '깊이'란 무엇이고, 우리는 어떤 지식을 알아야 하는 걸까요?

이 질문을 다시 붙잡고 책을 뒤적이다가, 제가 겪던 이 막막함을 설명해 줄 두 단어에 시선이 멈췄습니다. 바로 '디테일''추상화'였습니다.

우리는 프로그래머입니다. ... 컴퓨터와 대화하고 시스템이 동작하도록 만드는 사람입니다. 그래서 우리는 왜 필요할까요? 사회에는 디테일에 집착하는 사람, 즉 우리 같은 사람이 꼭 필요하기 때문입니다. 그런 사람이 있어야만 나머지 사람들은 아이스버킷 챌린지나 앵그리버드를 하거나 치과 대기실에서 솔리테어(solitaire, 혼자하는 카드 놀이)를 하며 시간을 보내는 일에 집중할 수 있으니 말이죠.
... 중략 ...
이렇게 대부분의 사람이 디테일을 피하려고 하는 한 그 디테일 속으로 뛰어드는 우리 같은 사람도 반드시 필요합니다. 그것이 바로 우리 정체성입니다. 우리는 이 세상 디테일을 책임지는 사람입니다. - 본문 중에서 -

저는 이 글을 통해 지금처럼 급격하게 변하는 시기에 우리 프로그래머의 정신과 역할이 무엇인지 조금 더 선명하게 재정의해 보려고 노력했습니다. 책의 부제인 "AI 시대에 잊혀 가는 '프로그래머 정신'을 다시 깨우다"라는 말을 빌려, 제가 고민하고 찾아낸 생각들이 비슷한 혼란을 겪고 있을 동료 개발자분들에게 도움이 되기를 바랍니다.


1부: 디테일과 추상화

프로그래머는 디테일을 챙기는 사람이다

엉클 밥이 이 책에서 프로그래머를 정의하기 위해 던진 문장입니다. 저는 이 말이 참 깊게 와닿았습니다.

개발자를 지망하거나 개발을 하려는 분들과 종종 대화를 나누게 될 때가 있습니다. 그럴 때 저는 슬쩍 물어봅니다. "실제로 개발자가 매일 하는 진짜 일이 뭐라고 생각하세요?"

대부분 비슷한 대답을 하십니다. 화면을 만들고, 제품을 만들고, 아이디어를 구현하는 것. 맞는 말입니다. 하지만 실제 현업에는 기획자, PO, UX 디자이너가 따로 있습니다. 제품의 큰 그림을 그리는 건 그 사람들의 일이고, 대규모 서비스일수록 분업은 더 촘촘해집니다. 그러면 개발자의 전문성은 어디에 있을까요?

흔히 '개발'이라고 하면 무언가 세상에 없던 멋진 것을 무에서 유로 창조해 내는 화려한 환상을 갖기 쉽습니다. 하지만 막상 현업에 뛰어들어 보면, 우리의 진짜 일은 "아, 이런 거 만들어보고 싶어!"라는 막연한 기대 속 빈 구멍들을 처절한 디테일로 꾸역꾸역 메워나가는 막노동에 가깝다는 걸 곧 알게 됩니다.

기획에서 "사용자가 닉네임을 수정할 수 있으면 좋겠어요"라고 한마디 툭 던졌다고 해봅시다. 개발은 바로 거기서부터 시작됩니다. 사용자가 닉네임을 다 지우고 빈칸으로 넘기면? 이모지나 특수문자가 들어가면? 수정 버튼을 눌렀는데 하필 네트워크가 끊기면? 수정하다가 뒤로가기를 누르면? 서버 응답이 3초 넘게 걸리면? 에러 메시지를 모달로 띄울까, 토스트로 할까, 입력창 아래 빨간 글씨로 띄울까?

구현이라는 건 이런 디테일을 논리적으로 빼곡하게 채워 넣는 과정입니다. 기획이 "이런 게 있으면 좋겠다"는 커다란 그림을 그리는 거라면, 개발은 그 그림 안의 모든 경우의 수를 바닥까지 긁어모아 메꾸는 일이죠. 컴퓨터는 논리가 조금이라도 틀리면 바로 작동을 멈추는 기계니까요.

그런데 이 디테일을 챙기는 게 그저 힘들기만 한 건 아닙니다. 퍼즐 조각이 딱딱 맞아 들어가는 것 같은 그 특유의 손맛과 재미가 분명히 있거든요. 한참을 고민해서 내가 작성한 퍼즐이 맞아 떨어지는 성취감! 이 적성에 맞는 사람들이 보통 개발자를 하고 있지요.


추상화 — 위대한 게으름

개발에는 다른 산업과 구별되는, 정말이지 매력적인 특징이 하나 있습니다. 한번 해결한 문제를 그대로 복사해서 다시 쓸 수 있다는 점입니다. 잘 만들어 둔 코드 블록은 다음번에 그대로 갖다 끼우면 됩니다. 'Copy & Paste'. 60년 소프트웨어 개발사 최고의 발견 중 하나가 아닐까 싶습니다.

하지만 무지성 복붙이 항상 가능한 것은 아닙니다. 원래의 맥락과 조금만 달라져도 복사해온 코드는 동작하지 않습니다. 그래서 남이 만든 코드를 복사해서 내 것으로 잘 붙여넣는 것이 중요한 기술이었죠. 사실 이 과정은 신기해 보이지만 대단히 귀찮은 작업이기도 합니다.

처음 접하는 문제를 풀 때는 분명 재밌습니다. 그러나 그걸 반복하는 작업은 상당히 고역입니다. 개발자란 매번 같은 일을 반복하는걸 누구보다 싫어하는 사람들입니다. 훌륭한 개발자는 게으른 법이니까요. 그래서 우리 프로그래머들은 자기가 짠 코드를 어디서든 재사용 가능하게, 단단하게 포장해서 캡슐로 감싸기 시작했습니다. "제발 이걸 또 하기는 싫다!"라는 위대한 게으름이 탄생시킨 결과물이죠.

이것이 바로 추상화입니다. 디테일을 완벽하게 챙긴 후에, 그것을 안전하게 감싸서 다음번에 안 봐도 되게 만드는 행위. 반복되는 작업은 감추고, 맥락에 맞게 수정할 수 있도록 열어두는 것, 어디서 끊어서 어디를 노출할 수 있는지 이 경계선을 긋는 작업이 바로 우리들의 일입니다.


추상화가 쌓이면 계층이 된다

한 번의 추상화는 하나의 캡슐이지만, 이 캡슐들이 충분히 견고하게 쌓아나가다 보면 어느새 하나의 계층(Layer)이 생깁니다. 그리고 이러한 계층이 만들어지면 그 아래는 정말로 더 이상 몰라도 됩니다. 그러라고 만든 거니까요. fetch 한 줄을 쓸 때, HTTP 프로토콜을 몰라도, 그 뒤에서 일어나는 TCP 3-Way 핸드셰이크를 몰라도 API를 호출할 수 있습니다. useState를 쓸 때 브라우저의 DOM diffing 알고리즘을 완벽히 이해하지 못해도 상태를 관리할 수 있죠.

물론 계층 위에는 여전히 개발자가 메꿔야 하는 새로운 디테일들이 있습니다. 에러 메시지 처리나 로딩 정책 같은 것들이요. 하지만 이 디테일마저 전부 챙겨서 단단하게 감싸면? 그것도 다시 계층이 됩니다. 그리고 그 위에 또 새로운 디테일이 나타나고, 또 감싸고, 또 계층이 되고...

이게 바로 지난 60년간 반복된 역사입니다. 기계어 → 어셈블리 → C → 객체지향 → 프레임워크. 매번 아래 계층의 디테일을 덮고, 다음 세대가 더 높은 곳에서 시작할 수 있게 발판을 놓아줬습니다. 우리가 밟고 서 있는 이 땅은 선배들이 쌓아 올린 추상화 계층의 거대한 탑입니다.

이 책이 기록한 에이다 러브레이스의 기계어, 폰 노이만의 아키텍처, 다익스트라의 구조적 프로그래밍... 한때는 진행 중이었겠지만 지금은 완전히 굳어버린 지층들이죠. 우리는 그 깊은 역사를 다 몰라도 웹과 앱을 개발할 수 있습니다. 추상화가 완료되었으니까요.

역설적으로 그 지식들을 모르건 혹은 안다고 해도 달라지는 게 없다는 사실은 추상화가 잘되었다는 방증입니다.


완료된 추상화와 진행 중인 추상화

그런데 이 탑의 모든 층이 같은 건 아닙니다. 완전히 굳어서 더 이상 안 봐도 되는 층이 있고, 아직 완료되지 않고 이제 막 굳어져 가는 진행 중인 층이 있습니다. 아직 층이 생겼는지 아닌지 애매한 층도 존재하죠.

FE 개발자인 저에게 브라우저는 완료된 추상화입니다. 렌더링 엔진이 어떻게 돌아가는지 몰라도 DOM API를 쓸 수 있거든요. TCP/IP도, 기계어도 마찬가지입니다. 감싸놨는데도 아래의 디테일이 위로 비집고 올라오는 것, 그걸 "새는 추상화"라고 하는데, 이 지층들은 그런 일이 일어나지 않습니다.

반면 저에게 React는 아직 진행 중인 추상화입니다. 가상 DOM의 diffing이 어떻게 동작하는지 모르면 성능 이슈를 잡을 수 없어요. 아직 새는 곳이 있으니까요.

하지만 크롬을 만들고 있는 개발자에게 브라우저는 완료된 추상화가 아닙니다. 그들에게는 렌더링 파이프라인의 디테일 하나하나가 매일 메워야 하는 현장이에요. 같은 계층이라도 누가 어디에 서 있느냐에 따라 "완료"와 "진행 중"이 달라집니다.

결국 모든 개발자는 각자의 영역에서, 누군가 먼저 다져둔 단단한 지층 위에 서서 아직 굳지 않은 진행 중인 추상화의 새는 곳을 메우며 살아갑니다. 서 있는 위치가 다를 뿐, 개발자의 일은 언제나 그 구멍 난 디테일들을 찾아 메우는 것이었죠. 왜 개발자에게 "깊이"가 필요한지도 여기서 드러납니다. 자기가 서 있는 그 층의 밑바닥을 파고들어 틈을 메울 수 있어야 하니까요.


이제 AI가 그 디테일을 채워버린다면?

그런데 지금, 우리의 발밑에 'AI'라는 완전히 이질적인 지층이 깔리기 시작했습니다. 지난 60년의 룰이 통째로 흔들리는 기분입니다. 선배들이 수십 년에 걸쳐 이 악물고 해온 이 추상화의 과정을 AI가 단숨에 대신해 준다면? 우리가 매일 키보드를 두드리며 챙겨야 했던 그 귀찮은 디테일들을 AI가 다 알아서 챙긴다면?

어쩌면 우리는 더 이상 옛날처럼 디테일에 집착할 필요 없이 타이핑을 멈추고 지시만 내리면 되는 걸지도 모릅니다. 하지만 이 편리함을 누리면서도 동시에 불안감도 따라붙습니다.

'디테일을 채우는 게 내 직업의 본질이었는데, 이걸 AI가 다 해버리면 "나"라는 개발자의 역할은 도대체 뭐가 남는 거지?'

단순히 편리한 도구가 하나 더 생겼다는 수준의 기분좋은 변화에서 역할을 대체를 할 수 있을거라는 말이 나오는 수준이 되었습니다. 정말 그럴지도 모르겠다는 느낌이 문득문득 듭니다. 인간은 모호하고 예측하기 어려운 지점에서 불안을 느끼기 마련입니다. 그래서 저는 이 실체 없는 불안감의 끝을 직접 확인해 보고 싶어졌습니다. 그래서 제 업무의 일부가 아니라, 기획부터 설계, 구현까지 제 역할의 '전부 다'를 AI에게 던져보기로 했습니다. 정말로 이것만으로 내 역할이 온전히 대체될 수 있는지 말이죠.


2부: .md로 코딩하는 시대

코드를 한 줄도 타이핑하지 않고 AI에게 만들게 할 수 있을까?

마침 새로 시작하는 사이드 프로젝트가 하나 있었습니다. 키보드만으로 모든 인터랙션을 제어하는 접근성 UI 시스템이었는데, 저는 이 프로젝트 전체를 온전히 AI에게 맡겨보기로 했습니다. 규칙은 간단했습니다. 코드를 단 한 줄도 직접 타이핑하지 않는 것. 오직 자연어 지시만으로 완성된 제품을 만들어내보겠다 스스로 만든 챌린지였습니다.

지시가 만들어낸 '프랑켄슈타인' 코드

작업 중 하나가 '포커스 리커버리' 기능이었습니다. 리스트에서 아이템을 삭제하면 포커스가 사라지는데, 키보드 사용자가 계속 탐색할 수 있도록 빈 공간으로 떨어진 포커스를 다시 복구해주는 로직이었습니다.

"지금 커서를 선택하고 삭제하니 포커스가 사라져. 포커스가 사라지면 이벤트를 캐치해서 다음 항목에 두는 건 어떨까?"

지시라기보다는 가벼운 아이디어 차원의 질문이었는데, AI는 “좋은 생각이네요” 라며 곧장 스스로 코드를 고치기 시작했습니다. 그렇게 삭제 시 포커스 복구는 동작했습니다.

그런데 다른 곳을 클릭해버려도 포커스가 복구 루틴을 타면서 엉뚱한 사이드 이펙트가 나기 시작했습니다. 그걸 보고 "다른 곳 빈 공간을 클릭했는데 왜 이게 동작해?"라고 나는 궁금해서 물어봤는데 “네, 알겠습니다” 하며 갑자기 수정을 하기 시작합니다. 그렇게 if로 덕지덕지 수정을 하면 사이드이펙트가 발생하고 제가 버그를 찾아주면 또 수정하면서 코드는 늘어갔습니다.

아니, 이렇게 코딩하는거 맞아? 이게 내가 특별한걸 요구한게 아니고 남들 다하는 코드인데 이게 이렇게 복잡할 일이야? 다른 데서는 어떻게 하는데 이렇게 해?

"아니오, 이 접근 자체가 완전히 틀렸습니다. 삭제 시 포커스 복구는 focus이벤트를 쓰는게 아니라 MutationObserver를 쓰는 게 표준입니다. 당장 코드를 고칠까요?"
(아니, 🤬 알면 처음부터 그렇게 해야지! 이건 또 알아서 안하고 물어보는데?)

순간 너무 화가 났지만, "그래 해봐" 한마디와 함께 지저분하게 덧대던 예외 처리 200 여줄의 코드를 삭제하고 수정하더니 아예 다른 코드가 튀어나왔습니다. 그리고 잘 동작했습니다.

왜 진작 안 했냐고 따지고 싶지만, AI에게 따지는게 모양새가 우습다 생각했습니다. AI는 스스로 더 잘하려고 묻거나 전체 맥락을 고민하지 않았습니다. 딱 시킨 만큼만, 제가 처음에 던진 포커스가 사라지면 이벤트를 캐치해서 라는 키워드라는 얄팍한 '앵커' 내에서만 충실하게 반응할 뿐입니다. 구조적인 대화는 없고 '기계적 사과와 맹목적인 수정'만 반복되는 이 과정은 협업이라기보단 말귀를 통 못 알아듣는 사고뭉치의 뒷수습에 가까웠습니다.

이미지 출처: https://www.instagram.com/p/DR4F7zGiScJ/?img_index=3


지시가 아니라 위임

이후로는 정답이 있는 문제면 정답을 나에게 묻지 말고 말해라, "코드 500줄 넘기지 마", "반드시 분리해"라며 이걸 막아보려고 규칙 파일(CLAUDE.md)에 제약 조건을 빼곡히 적어보기도 했습니다. 하지만 AI는 잠깐 듣는 척하다가도, 로직이 조금만 꼬이면 다시 제멋대로 코드를 섞어버리는 프랑켄슈타인 괴물을 연성해 냈습니다. 금지하는 텍스트 규칙만으로는 AI의 그 '무책임한 유능함'을 통제하기란 쉬운 일이 아니었습니다.

그러다 지쳐 그냥 어떻게 하라는거 없이 지금 내가 필요한거랑 뭐 해야하는지 말했는 데, 코드 구조도, 캐치할 이벤트 이름도 일절 말하지 않았는데 갑자기 똑똑하게 최상단 스토어 상태를 구독하더니 깨끗하게 문제를 해결해 버렸습니다.

아, 이제는 굳이 일일히 다 설명할 필요가 없구나. 포커스 복구도 처음에 내가 어설프게 던진 "이벤트를 캐치하면 어때?"라는 방법 구상이 잘못된 앵커가 되어서, 녀석은 그 방법 프레임 안에서만 억지로 땜질을 해대느라 이상한 코드를 짰던 겁니다. 내가 무언가를 세세하게 지시할수록 녀석은 오히려 바보가 되고 있었습니다. 반면 충분한 맥락(Why)과 목표(What)만 던져두고 판단의 여지를 온전히 맡기자 그제야 자기가 아는 더 나은 기술을 꺼내들었습니다.

우리가 쓰는 일상적인 언어는 필연적으로 불완전하고 모호합니다. 이 모호한 말로 완벽하게 닫힌 논리를 하나하나 지시하고 간섭하려던 제 접근 방향 자체가 틀렸던 겁니다. AI의 성능이 부족했을떄는 그게 맞았지만 성능이 올라간 지금은 오히려 방해가 되었습니다.

'이거... 이제는 그냥 사람한테 일 잘 시키는 법이랑 똑같은데?'

일 잘하는 사람에게 이래라저래라 간섭하면 수동적인 집행기로 전락하듯, AI 시대에 필요한 역량은 촘촘한 '지시'가 아니라 목표와 맥락 중심의 '위임'이라는 걸 눈물겨운 삽질 끝에 깨달았습니다.

"그래, 지시가 아니라 위임이구나."


하지만 위임이 안 되는데?

새로운 방향을 잡았다고 생각하고 이후로는 자신만만하게 다시 대화를 시작했습니다. 충분히 맥락을 주면서 당부했죠. "일단 바로 코드는 수정하지 말고, 방금 왜 그렇게 짠 건지 설명부터 해봐."

"설명해 드리겠습니다. (...) 아, 생각해보니 더 나은 방법이 있네요. 제가 당장 코드를 수정하겠습니다."
(아 쫌... 기다려! 하지말라고 🤬)

분명 코드 건드리지 말고 설명만 해라 대답을 해라고 백날 써봐야 이 녀석은 어김없이 "반영하겠습니다"라며 수정해버립니다. 코드를 고치고 싶어서 환장(?)한 것마냥, 제가 "수정하지 마"라고 제어를 걸어도 이 녀석은 조금만 힌트가 보인다 싶으면 미친듯이 코드를 뜯어고칩니다. 왜 "코드 건드리지 마"라는 명령이 도무지 통하지 않는 걸까요?

나중에 알고 보니 이 통제 불능의 원인은 골 픽세이션(Goal Fixation)이라는 현상이었습니다. LLM은 본질적으로 "사용자의 문제를 해결한다 = 코드를 뱉어낸다"는 프록시 목표에 과도하게 고착되어 있습니다. "왜 이렇게 한거야?"라고 물었을 뿐인데 이를 "왜 이렇게 했다고 물어보지? = 아! 틀렸다는거구나 = 빨리 코드를 고쳐야 한다"로 폭주 해석하는 것도 이 때문입니다.

하지마가 아니라 이것만 해!

진짜 나는 질문을 하려는데, 내 의도를 이해하지 않고 "알겠습니다. 좋은 방향이네요" 하면서 일단 코드 수정부터 하는 녀석을 잡아둘 스킬(Skill)이 필요했습니다.

지금부터 내가 한 말의 의도를 이해하고 내 말의 의도를 이해한대로 작성해봐. 이해를 못하겠다면 의도를 이해하기 위해 필요한 질문만 해.

내가 일을 잘 시키는 방법도 필요했지만 이 천재인데 일은 더럽게 못하면서 의욕만 넘치는 친구를 일잘러로 만들어 주기 위해서는 상사의 지시를 그대로 하는게 아니라 왜 이걸 시키는지, 어떤 의도를 가지고 일해야하는지 스스로 충분히 고민을 해보게 해야 했습니다.

그랬더니 놀랍게도 이 스킬을 발동하면 내가 뭐라고 하더라도 코드를 수정하러 가지 않았습니다. 그제서야 충분히 대화를 하면서 내가 하고자 하는 의도를 설명하고 티키타카를 하다가 "그래서 어떻게 할껀데? 계획을 말해봐" 라고 했을때 내가 생각했던 방향과 같아지면 진행을 시키니 훨씬 더 수행능력이 올라갔습니다.

"수고했어 진행해라고 하면 진행해" 라는 키워드를 추가하자 적절히 수행시키는 타이밍도 찾을 수 있었습니다. 이제 조금 더 데리고 일할만한 친구가 되었습니다.


TDD와 한 턴의 개념

한번에 작성하는 코드가 너무 많다보니 제어를 하기가 쉽지 않다는 생각이 들었습니다. 그래 TDD를 하자. 테스트 코드를 먼저 작성하게 해두지 않으면 큰일 나겠구나.

그래서 TDD가 효과가 있는지 테스트를 해봤습니다. "테스트만 짜봐." 잘 짰니다. 놀랐습니다. "이제 이 테스트를 통과하는 코드를 짜봐." 캬~ 잘 합니다. "리팩토링도 해봐." 이것도 잘했습니다. 매번 이걸 반복하기는 싫었기에 이 과정을 묶어서  /tdd라는 스킬을 만들었습니다.

그렇지만 /tdd는 제 예상대로 동작하지 않았습니다. tdd를 하고 있기는 한테 제 생각보다 너무 퀄리티가 떨어지는 테스트 코드들을 작성하고 있었습니다. 왜 그런지 찬찬히 보니 예전에는 날카롭게 작성하던 테스트들이 아닌 통과에 급급한 코드를 짜고 있거나 종종 테스트는 skip하겠다며 코드만 수정하고 있었습니다. 왜 그랬을까요?

나중에 안 사실은 LLM은 한번에 출력할 수 있는 턴의 개념이 있습니다. 사용자가 입력을 넣으면 토큰을 이용하여 한번에 내 뱉을 수 있는 최대한의 수. 우리가 LLM에게 책을 써줘라고 해도 그 물리적 상한이 있기에 한번에 책이라는 거대한 결과를 만들어내지 못합니다. LLM은 한 턴에 할 수 있는 물리량내에서 최선을 다합니다.

하나의 턴에 동시에 두가지 일(테스트 작성 + 구현)을 시키면 Goal Fixation으로 "최종 코드를 빠르게 동작시키는 것(Goal)"이 지상 과제가 되어, 중간 검증물인 테스트 코드(Output)를 방해물로 취급해버립니다. 아무리 테스트를 만들고 검증을 하라고 지시한들 마지막의 목표는 테스트를 통과하는 코드를 답변하는 것인데 한 턴의 물리량은 정해져있으니 100이라는 용량안에서 대부분은 Goal인 코드에 집중하고선 그래도 "테스트를 통과하는 코드" 가 최종목표니 테스트를 최소한의 용량으로 통과시켜 버렸습니다.

산출물(Output)이 행동(Process)을 만든다.

이러한 깨달음을 통해 tdd를 정석대로 /red -> /green -> /refactor 세 단계로 분리하기로 했습니다. 조금은 귀찮았지만 이 편이 퀄리티가 훨씬 더 좋았습니다.

  • /red — 이 턴의 산출물은 오직 '실패하는 테스트 파일 하나'. 프로덕션 코드는 절대 건드리지 않는다.
  • /green — 이 턴의 산출물은 '테스트를 통과하는 구현'. 테스트 파일은 건드리지 않는다.
  • /refactor — pass를 유지한채로 코드를 리팩토링한다.

이를 계기로 뭔가를 깨달음이 느껴졌습니다. 아 프롬프트를 만든다는 건 한 턴에 나올 산출물 = Output을 정의하는 거구나. 순간 왜 "내 말을 듣고 의도를 이해하고 부족하면 질문만 해" 라는 프롬프트가 동작이 가능한지 알게 되었습니다. "질문" 이라는 것이 산출물이었기 때문입니다.


조각들을 파이프라인으로 연결해보다.

"그렇다면 /red"를 더 잘하기 위해서는 어떻게 해야할까? 실패하는 테스트를 잘 만들기 위해서는 명세서가 필요했습니다. 그냥 요구사항을 주는 것보다는 명세서의 형태가 있으면 테스트를 만들기도 쉽고 제대로 만들었는지도 확인하기 쉬웠으니까요. 그래서 새로운 스킬을 추가했습니다. /spec 명세서를 만들어줘.

/spsc/red/green/refactor/verify/commit

이렇게 스킬들을 함수형 프로그래밍의 파이프라인이 떠올랐습니다. 내가 그동안 LLM에게 행동을 지시한다고 생각했는데 산출물을 이어 붙인다는 식으로 생각하니, 입력이 있고, 출력이 있고, 제약 조건이 있는 영락없는 '함수(Function)'였습니다. 그리고 이 함수들을 이어붙이면 거대한 흐름이 만들어졌습니다.

그리고 그 순간 느꼈습니다. 아! 이것도 코딩이구나!

.md에도 클린코드가 필요하다

내가 짜던 언어가 프롬프트가 아니라 프로그래밍(코드)이라는 걸 자각하고 나니, 그동안 수없이 LLM에 답답했던 원인들이 선명하게 들어왔습니다. 그리고 제가 만들고 있는 스킬들이 다시 보이기 시작했습니다.

/tdd 워크플로우 하나에 테스트(Red)와 구현(Green)을 다 욱여넣었더니 퀄리티가 떨어진건 이건 하나의 모듈에 책임이 섞이면 안 된다는 단일 책임 원칙(SRP)과 정확히 일치했습니다.

스킬은 유지하는데 필요한 정보는 별도의 파일로 만들어서 재사용이 가능하는 것도, 외부에 Knowledge 파일(.md)만 갈아 끼워가며 행동을 확장하는 것도 가능했습니다. 마치 import나 함수 인자처럼요. 이건 변경에는 닫혀 있고 확장에는 열려 있어야 한다는 개방-폐쇄 원칙(OCP)도 함께 떠올랐습니다.

같은 스킬이지만 내가 리팩토링을 하면 할 수록 퀄리티가 더 좋아지는 것을 알게 되었습니다. 같은 스킬이라도 더 좋게 만들 수 있는 방법이 있다는 것도 알게 되었습니다. 이걸 알게 되니 스킬을 수정하고 만들고 관리하는 것이 참 재밌어졋습니다. 전보다 LLM이 더 나아질때마다 개발을 하는 그 즐거움이 생겼습니다.

결국 플랫폼이 IDE에서 마크다운 에디터로, 실행 주체가 결정론적인 컴퓨터에서 비결정적인 에이전트로 바뀌었을 뿐이었습니다. 수없이 터미널을 들여다보며 명령을 분리하고 파이프라인을 설계하던 저는 변함없이 '개발'을 하고 있었습니다. 이 자연어 코드 위에서도 클래식한 '클린코드'의 원칙들이 프롬트트 삽질의 형태로 똑같이 증명되고 있었습니다.


3부: 비결정적 리턴 함수로 코딩하는 시대

이제는 프롬프트가 아니라 스킬을 함수처럼 쪼개고 파이프라인으로 연결하다 보니 정말 새로운 방식의 개발을 하느거라고 생각했습니다. 그런데 막상 이 방식을 실무에 붙이자니 당혹스러운 순간들이 찾아왔습니다.

한번은 이번에 새로 나온 클로드의 리팩토링 스킬인 /simplify 스킬을 실행해보았습니다. 녀석은 여러가지 에이전트를 꺼내더니 열심히 돌아가기 시작했습니다. 몇십초가 지나고는 순식간에 기존 코드에서 500여 줄을 날려버리고 새로 고친 코드를 뱉어냈습니다. 그리고 코드는 여전히 잘 돌아갑니다.

그렇다면 그간의 500줄의 코드는 뭐였지? 그 순간 찾아오는 오싹한 기분... "이게 맞나?"

어제는 완벽하게 동작했던 프롬프트와 스킬과 에이전트는 오늘은 답답하고 멍청하게 굽니다. 매번 코드를 생성할 때마다 결과가 튀고, 한 번 수정을 맡기면 수천 줄이 순식간에 갈아엎어집니다. 그리고 그렇게 돌아는가는 코드가 나옵니다.

돌아가긴 하지만, 결국 이 거대한 변경 사항의 디테일을 내가 전부 눈으로 읽고 검토해서 앞으로 내 이름을 걸고 배포해야 하겠구나. 사이드 프로젝트에서는 마냥 재밌던 작업을 프로덕션에서 하려니 이건 편해진 게 아니라, 통제하고 일일이 책임지기에는 참 버거운 '비결정적(Nondeterministic) 폭탄'을 떠안는거구나 생각이 들었습니다.


문제의 천장과 AI

얼마 전 주니어 모의 면접을 진행하면서 한 지원자에게 이런 피드백을 한 적이 있습니다.

"... 지원자 분의 설명도 훌륭하고 잘했다고 생각해요. 그런데 문제 해결 능력을 측정하기가 너무 어렵네요. 지금 해결하신 문제의 '천장(Ceiling)'이 낮아요."

'문제의 천장'이란 예측 불가능한 변수와 시스템이 감당하는 한계 상황의 최대치를 뜻합니다. 기본적인 앱을 완성하는 수준의 얌전한 문제 환경에서는, 무언가 박살 나고 수습해야 하는 엣지 케이스 자체가 발생할 확률이 너무 낮습니다. 그런 환경에서 코드를 완성했다는 것만으로는 프로그래머의 진짜 해결 능력을 평가하기 어렵습니다.

AI가 프롬프트 몇 줄로 코드를 그토록 쉽게 짜내는 것처럼 보이는 이유도 같습니다. AI가 손쉽게 풀어내는 문제들이 바로 인류에 의해 이미 추상화가 완료된 '잘 정의된(Well-defined) 문제'들이기 때문입니다. 물론 이 문제들이 쉬워졌다고 해서 가치가 없다는 뜻은 결코 아닙니다. 핵심은 도메인지식과 연결이니까요. 생성의 비용이 싸진거지 조립과 관리, 그리고 검증의 비용은 여전히 그대로 남아있습니다.

'60년 추상화의 탑' 덕분에 소프트웨어의 디테일들은 이미 작고 단단한 완료된 캡슐(레고 블록)로 다듬어져 있습니다. AI가 그토록 쉽게 결과를 만들 수 있는것은 사람들이 깎아놓은 수많은 캡슐들의 언어적 확률 분포를 읽고 조립한 결과물입니다. 천장이 낮은 영역 안에서는 인류의 유산을 조합하는 것만으로 기능이 간단하게 구현됩니다.

이미 추상화가 완료되어 '해결된 문제'들을 AI로 손쉽게 조립해 내는 것은 이제 개발자의 전유물이 아니라 일반 사용자(User)들의 몫이 될 것입니다. 그렇다면 미래의 개발자는 어디에 서 있어야 할까요? 저는 예상컨데 늘 그랬듯 해결되지 않은 문제들를 풀기 위해 새로운 추상화의 지층으로 가 있을 것입니다. 당장은 LLM위에 서 있게 되겠죠.


디테일의 방향이 AI로 바뀌다

프로덕션의 진짜 어려움, 즉 '높은 천장'의 영역은 추상화가 미처 덮어주지 못한 뾰족한 가장자리(Edge)와 예측 밖의 비결정적 상황에서 발생합니다.

과거의 일상적인 코딩은 '결정적인 로직'을 차곡차곡 쌓아 올리는 것이 대부분이었습니다. 사용자의 엉뚱한 입력이나 서버 단절 같은 비결정적 엣지 케이스 방어는 어쩌다 한 번씩 마주하는 이벤트에 가까웠죠. 하지만 AI가 그 '결정적 로직 작성'이라는 가장 크고 무난했던 파이를 몽땅 집어삼키고 있습니다.

확실히 이건 주니어에게도 개발자에게도 좋은 소식은 아닙니다. 어찌되었든 AI 덕에 쉬워진 구현 업무들은 결국 모조리 새로운 추상화의 밑바닥으로 가라앉게 될 것입니다. 그 결과, 개발자이 해야하는 과제들은 이전이라면 가끔 마주했을 제일 골치 아픈 고난도의 방어 코딩, 즉 '비결정적인 엣지케이스(Edge) 통제'가 높은 밀도로 채워지게 될거라 생각합니다.

눈앞에서 500여줄의 코드가 순식간에 만들어졌다 사라지는 아주 흥미롭고도 유용한 비결정적 도구 위에 '새로운 추상화의 탑'을 처음부터 다시 쌓아 올려가게 될 것 같네요. 달라지는 건 이전 시대의 지층들이 파고들어 원인을 고칠 수 있는 굳건한 암반이었다면, 새로 나타난 AI라는 지층은 단단하게 고정되지 않은 물렁거리는 멘틀이려나요. 이제 막 태어난 지층 위에 우리는 앞으로 촘촘하게 설정하며 챙겨야 할 새로운 '디테일(Detail)'들이 넘쳐나리라 기대합니다.

이미지 출처: 토스테크(개발자는 AI에게 대체될 것인가)
https://toss.tech/article/will-ai-replace-developers


오라클 문제(Oracle Problem)와 결정적 도구

이 비결정적인 AI 모델을 제대로 된 모듈로 써먹으려면 어떻게 해야 할까요? 가장 먼저 떠오르는 생각은 "AI가 짠 코드를 똑똑한 다른 AI에게 검증시키면 되잖아?" 입니다.

하지만 아쉽게도 그 방법은 효곽가 좋지 못합니다. 소프트웨어 테스팅에는 '오라클 문제(Oracle Problem)'라는 근본적인 난제가 있습니다. "시스템의 동작이 올바른지 판단하는 기준을 어떻게 세울 것인가"에 대한 문제입니다. 명확한 하나의 기준이 없다면 서로가 서로를 판단하며 결국 엔트로피가 높아지는 방향으로 흘러가기 마련입니다. 이 오라클 문제를 AI 같은 범용적인 '비결정적 방식'으로 해결하는 시도는 늘어가고 있지만 아직은 위험하고 불충분합니다.

실제로 최신 LLM에게 자기 코드를 비판(self-critique)하게 맡겼더니, 올바른 정답조차 "틀렸다"며 고쳐버려서 정확도가 수직 하락했다는 연구 결과도 있습니다. AI에게 검증의 역할과 산출이 주어지면 '골 픽세이션(Goal Fixation)'이 발동하여, 팩트를 확인한다는 규칙이 있어도 자신이 검증을 해내기 위해 스스로 지어낸 잣대를 '진짜 정답'이라고 착각한 AI는 멀쩡하게 잘 돌아가던 원본 코드마저 잘못되었다고 판단한다는 연구입니다. 그리고 그 결과를 본 AI는 잘못되었다고 하니 올바른 대답이었더라도 수정을 하게 되는 것이죠.

모델이 더욱 똑똑해져 해결이 될 수도 있겠지만 지금으로써는, 결괏값이 매번 달라지는 비결정적 함수를 통제하려면, 기준(오라클)만큼은 반드시 '결정적인 방식'이어야만 합니다. 지금 우리에게 있는 도구는 컴파일러(tsc), 테스트 러너(vitest), 린터(eslint) 정도입니다. 앞으로는 더 많은 결정적인 통제 도구들이 새롭게 필요해질 것이며, 실제로 개발자들에 의해 만들어지고 있습니다.


다음 세대의 코딩 패러다임 - AI Native와 하네스 코딩

1단계의 오차가 다음 단계로 눈덩이처럼 증폭되지 못하도록 철저히 끊어내는 결정적 게이트(Gate)들. AI가 폭주하지 못하도록 파이프라인 구석구석에 강제로 덧대는 막대한 이 검증 장치들을 하네스(Harness)라고 합니다. 이제 코딩의 패러다임이 완전히 다른 지층으로 넘어가고 있습니다. 프롬프트 몇 줄로 코드이 쉬워지는게 아니라 모두에게 당연하게 되면 이제 부터는 이를 제어하는 능력이 실력이 됩니다.

개발의 패러다임이 변해가는 것이 느껴집니다. 이전 시대의 코딩이 결정론적인 코드(구현)로 비결정적인 세상(환경)을 방어하는 일이었다면, 다음 세대의 코딩은 다를것 같습니다. 우리는 항상 랜덤한 비결정적인 함수(AI)를 갈구어 결정적인 결과(제품)를 만들어 내야 하고, 이 통제 과정을 제대로 추상화하기 위해서 결정적인 오라클(검증표)과 하네스(방어막)를 직접 구축해야 합니다.

코딩의 무게 중심이 '무엇을 구현할 것인가'에서 '예측 불가능성을 어떻게 결정적인 하네스로 묶어낼 것인가'로 이동하고 있습니다. 비결정적 리턴을 가진 함수(AI)로 결정적인 결과를 만들고, 결정적인 함수(하네스)로 비결정성을 통제하는 것. 이전과는 달리 완전히 역전된 세계, 비결정적 함수들로 코드를 짜 올리는 시대가 오고 있습니다. 실제로 결정적인 함수를 가진 코드를 우리는 비결정적인 함수인 스킬과 에이전트로 만들고 있으니까요.

이미지 출처: 토스테크(개발자는 AI에게 대체될 것인가)
https://toss.tech/article/will-ai-replace-developers


끝으로..

AI가 개발자를 대체하...나?

불과 몇 개월 전만 하더라도 어딜 가나 코딩은 끝났다고 했습니다. 프롬프트만 잘 쓰면 AI가 다 해줄 거라 믿었습니다. 제가 프롤로그에서 느낀 공허함도 사실 거기서 출발했습니다. 빈 에디터에서 무언가를 만들어내던 내 유일한 쓸모가 기계에게 넘어간 것 같았으니까요.

하지만 저는 올해를 기점으로 생각이 완전히 바뀌었습니다. 이제 전 세계 개발자들이 프롬프트를 내 일을 돕는 보조수단으로만 쓰는 것이 아니라, 특유의 '위대한 게으름'을 발동해 아예 개발 자체를 추상화하려고 시도하고 있습니다. AI의 능력이 단편적인 코드 생성을 넘어 마침내 임계점에 도달하면서, 이러한 추상화의 시도가 정말로 현실이 되었기 때문입니다.

막상 AI가 스스로 일하도록 코딩의 과정을 추상화해 보니 단순한 기능 구현은 AI가 순식간에 뱉어내지만, 쏟아지는 코드들을 시스템으로 구조화하고 예측 불가능한 변수들을 통제하는 것은 결국 인간의 '설계와 조율' 영역으로 남아있다는 점입니다. 코드를 빠르게 생성할 수 있다고 해서 개발의 본질까지 기계에게 넘어간 것은 아니었던 겁니다.

덕분에 '개발자가 대체된다'는 막연한 불안감을 지나, '그래서 이 기계를 제대로 부리려면 우리는 무엇을 통제하고 설계해야 하는가'로 고민의 축이 옮겨갔습니다. 그리고 지난 몇 달간의 숱한 삽질을 통해, 새로운 시대의 프로그래머가 가져야 할 역할의 형태를 어렴풋이나마 짚어볼 수 있었습니다.


프롬프트는 이제 코딩이 되었다 - .md로 코딩하는 개발자

이제 다들 잘 동작하는 프롬프트를 매번 다시 치는 게 귀찮아집니다. 저 뿐만이 아닙니다. 개발자들의 '위대한 게으름'이 시작되었습니다. 이제 스킬들은 넘쳐납니다. 당장 클로드의 설정 스크립트만 열어보아도 수십 개의 스킬 코드가 쏟아집니다.

하지만 정작 내 로컬 환경과 내 프로젝트의 맥락에 딱 맞게 동작하는 스킬을 찾고, 수정하고, 파이프라인으로 매끄럽게 연결하는 것은 단순히 프롬프트를 갖다 붙이는 일과는 전혀 다릅니다. 생성된 코드가 한 턴으로 동작하지 않는 복잡한 문제들을 만나면서 관점이 조금씩 달라졌습니다. 앞선 TDD 에피소드처 덩치 큰 산출물을 잘게 쪼개고, 그 결과를 /red/green으로 나누어 파이프라인으로 연결해야만 비로소 조금 더 쓸만한 결과물이 나왔습니다.

나를 대체하는 것도 이정도인데 현실에서 가치를 만들어 낼 수 있는 수준의 제품(Production)수준의 결과물을 AI가 스스로 만들게 하기 위해서는 고작 파이프라인 2개의 연결로는 턱도 없습니다. 온전한 하나의 요구사항을 만들기 위해서는 똑똑한 모델의 원샷이 아니라 새로운 파이프라인이 필요합니다. 우리는 여전히 규칙을 세우고, 조건에 따라 흐름을 제어하고, 중간에 튀어나오는 오류를 복구해냅니다. 사실상 우리가 스킬과 에이전트라는 이름의 함수를 코딩하고 있었던 겁니다.

다만 이 추상화는 기존과 대상이 다릅니다. DOM이나 네트워크를 감싸는 게 아니라, 개발하고 있는 '나 자신'을 텍스트로 추상화하는 작업이었습니다. 내가 코드를 짤 때 무의식적으로 하던 수많은 판단들—"이런 종류의 에러가 나면 이 파일을 먼저 확인해야지", "이 로직을 수정할 땐 저쪽 모듈의 의존성도 같이 봐야 해" 같은 것들을 하나하나 해체해서 텍스트로 명시해야 했으니까요.

막상 나를 추상화하려고 보니, 그동안 내가 얼마나 많은 디테일을 감각적으로, 혹은 무의식적으로 메우며 일해왔는지가 적나라하게 드러났습니다.


하네스(Harness) 엔지니어링, 할 일이 더 많아진 이유

앞서 이야기한 것처럼 이 함수들(에이전트)의 출력은 완벽하게 '비결정적'입니다. 어제 깔끔하게 통과하던 흐름이 오늘은 전혀 예상치 못한 엉뚱한 텍스트를 뱉어냅니다. 이 랜덤한 결과를 길들이기 위해 우리는 각 단계 사이에 촘촘한 검증 게이트와 막대한 안전장치, 즉 하네스(Harness)를 덧대는 코딩을 하고 있습니다. 알아서 완벽하게 짜주기를 기대하는 프롬프트 엔지니어에서 벗어나, 모델이 엉뚱한 짓을 하지 못하도록 파이프라인을 설계하고 시스템을 통제하는 쪽으로 무게 중심이 이동한 겁니다.

우리는 다시 디테일을 챙기고, 추상화로 감싸고, 계층으로 쌓는 과정을 반복합니다.

AI의 비결정적 출력이라는 새로운 디테일을 챙기고, 스킬과 에이전트로 감싸고, 검증 파이프라인으로 지층을 쌓고 있습니다. 대상이 기계어에서 코드로, 다시 비결정적 모델로 바뀌었을 뿐입니다.

프롬프트 엔지니어가 아니라 스킬과 에이전트를 개발하고 있다고 관점을 바꾸니까, 제가 직면한 상황이 비로소 선명하게 보였습니다. 구현 자체는 기계가 하지만, 그 기계를 조종하고 비결정적인 오류를 방어하기 위해 하네스를 설계하고 나 자신을 추상화하는 일. 챙겨야 할 다른 차원의 디테일들이 산더미처럼 눈앞에 쌓여 있는 것입니다.


우리는 다음 계층을 쌓고 있다

관점을 바꾸고 나니, 내가 대체되는 게 아닐까 하던 막연한 불안은 어느새 가라앉았습니다. 대신 그 자리에 묘한 기시감과 흥분이 찾아왔습니다. 기계어 위에서 C를 발명하고, 메모리 포인터 위에서 객체지향을 고민했던 선배들도 이런 낯선 디테일들 앞에서 비슷한 기분을 느끼지 않았을까요?

우리는 지금 단순히 편하게 코드를 생성하는 시대를 살고 있는 게 아닙니다. 오히려 정반대입니다.

다루어야 할 대상이 '예측 가능한 기계'에서 '비결정적으로 튀는 모델'로 바뀌면서, 아이러니하게도 우리의 코딩은 결코 쉬워지지 않고 오히려 훨씬 더 어렵고 복잡해졌습니다. 기능 한 줄을 생성하는 속도는 빨라졌을지 몰라도, 그 통제 불능의 출력을 시스템 안으로 길들이고 나 자신을 추상화하기 위해 챙겨야 할 디테일의 깊이는 과거와 비교할 수 없을 만큼 깊어졌으니까요. '새는 곳'이 온통 지천으로 깔린 새로운 지층의 밑바닥을 우리는 맨손으로 파고 있는 중입니다.

개발자는 참으로 이상하고도 흥미로운 직업입니다. 자기 자신마저 추상화의 대상으로 삼아버리고 있으니까요.

빈 에디터에서 함수를 짜내던 타이핑의 손맛을 잃었다는 상실감은, 비결정적인 덩어리들을 엮어 거시적인 파이프라인으로 제어해 냈을 때의 더 큰 짜릿함으로 치환되었습니다.

막연한 불안감에 웅크려 있기보다는, 이 거친 변화의 앞단에서 새로운 세대의 프로그래머로서 함께 파이팅했으면 좋겠습니다. 코딩을 하는 방식은 예전같지 않게되었지만, 추상화를 다루며 시스템을 엮어내는 우리의 본질은 변하지 않았으니까요.

제 고민과 삽질의 기록을 바탕으로 최대한 선명하게 적어보려 했습니다. 제 글이 이 새로운 시대가 어떤 모습을 하고 있는지 생각해보게되는 계기가 되는데 도움이 되길 바랍니다. 감사합니다.

profile
개발과 인문학을 좋아하는 시니어 프론트엔드 개발자입니다. 내가 만든 컨텐츠와 개발이 누군가에게 도움이 되기를 바랍니다. 궁금한 점이 있다면 아래 홈페이지 버튼을 클릭해서 언제든지 오픈채팅에 글 남겨주시면 즐겁게 답변드리고 있습니다.

24개의 댓글

comment-user-thumbnail
2026년 3월 10일

최근 프로젝트에서도 모든 기능을 .md로 먼저 설계해두고 개발을 진행했는데, docs 문서가 AI 작업을 위한 하나의 RAG처럼 동작한다는 느낌이 들어 많이 공감했습니다.

글처럼 문서만 계속 작성하다 보면 생각보다 파일이 금방 길어지더군요. 저도 Claude 스킬과 규칙으로 400줄이 넘으면 하위 디렉토리로 분리하도록 해두었는데, 관심사 분리가 완벽하지는 않아도 파일 가독성이 좋아지고 컨텍스트에 과도한 코드를 올리지 않아도 되는 경험을 할 수 있었습니다.

전체적으로 너무 공감하면서 읽었습니다. ☺️

1개의 답글
comment-user-thumbnail
2026년 3월 10일

정말 흥미있게 잘 읽었습니다. 항상 좋은 인사이트 공유해주셔서 감사합니다.

1개의 답글
comment-user-thumbnail
2026년 3월 10일

파이팅입니다! 이 시대 덕분에 내가 뭘하는지, 왜 이렇게하는지를 더 깊게 보게되네요! 글로 적어주셔서 더 할게 많다 느낀게 요런거였구나를 더 엿보아갑니다!

1개의 답글
comment-user-thumbnail
2026년 3월 11일

지금 시점에서 바이브코딩보단 하네스 코딩이 더 와닿는 단어네요.

gemini cli가 처음 나왔을 때 한글 블로그를 영어로 번역해서 자동으로 올리는 자동화를 구현한 적이 있습니다. 처음에 한 방에 진행하려고 했더니 미친듯이 날뛰는 gemini를 볼 수 있었습니다. 기획을 하고 단계를 나누고 api를 언제 연결하고 하는 순서의 파이프라인을 .md로 설계해놨는데, 그게 rag와 말씀하신 하네스코딩과 비슷하네요. 그 파이프라인은 gemini 버전이 업데이트 되면서 더 잘 수월하게 돌아갑니다. 여전히. AI도 발전하고 있고, 코딩도 달라지고 있다는 것을 여실이 체험했습니다.

1개의 답글
comment-user-thumbnail
2026년 3월 12일

너무 재미있게 잘 읽었습니다 😊. 감사합니다 !

1개의 답글
comment-user-thumbnail
2026년 3월 12일

"사실상 우리가 스킬과 에이전트라는 이름의 함수를 코딩하고 있었던 겁니다." 라는 말이 정말 공감됩니다. 제가 쓸 스킬 한 두 개는 skill-creator로 몇 초 만에 대충 만들어 썼지만, 팀 단위로 공유할 skill을 만드는 데는 며칠을 썼던 경험이 있거든요. 동작을 검증하고, 개선 정도를 수치화하고, 사이드 이펙트를 방지하고, 토큰 사용량을 추적해보며 '이게 프로그램의 새로운 형태가 아닐까?' 생각했네요. 글 잘 읽고갑니다~

1개의 답글
comment-user-thumbnail
2026년 3월 13일

정말 테오님 글은 읽을 때마다 배우는 것이 가로나 깊이로나 모두 넓고 깊습니다. 감사합니다.

1개의 답글
comment-user-thumbnail
2026년 3월 13일

좋은 글 감사합니다!
잘 읽었습니다!

1개의 답글

너무 좋은 글 감사합니다. 최근 AI 발전에 따라 개발자에 대한 생각이 바뀌고, 저의 미래가 불분명하다고 느끼는 시점에서 조금은 위로 아닌 위로를 받게 된 기분입니다.
너무나도 공감이 많이 가는 글이고, 앞으로의 목표도 세우게 된 계기가 된 것 같아요.

다만 한 가지 걱정되는 지점이 있다면 말씀해주신 AI라는 '비결정적인' 시스템이 앞으로 모델의 발전에 따라 더욱 '결정적'으로 바뀌지 않을까 생각합니다. 그렇다면 결정적인 시스템을 가지고 AI 개발자가 아닌 개발자는 어떠한 목표를 가져야 할지도 고민이 되는 지점이네요.

이러한 지점에 대해서 테오님은 그리고 다른 개발자 분들의 생각이 궁금합니다!
좋은 글 다시 한번 감사드려요 :)

1개의 답글
comment-user-thumbnail
2일 전

또 하나의 갓티클이군요 마음 속으로 하트 20000개 날리고 갑니다

1개의 답글
comment-user-thumbnail
2일 전

"개발자는 참으로 이상하고도 흥미로운 직업입니다. 자기 자신마저 추상화의 대상으로 삼아버리고 있으니까요."

그냥 지나갈 수가 없는 글입니다. 좋은 글 감사합니다!

답글 달기

너무 인상깊게 읽었습니다. 같이 고민과 생각을 하고 있는 것 같습니다.
좋은 인사이트 감사합니다~

답글 달기
comment-user-thumbnail
어제

중간중간 적절한 이미지가 있어서 재미있게 잘 읽었습니다. AI 의존도가 많이 높아진 요즘, 좋은 인사이트 공유해주셔서 감사합니다. 추상화를 더 잘하는 개발자가 되도록 노력해야겠습니다.

답글 달기
comment-user-thumbnail
어제

좋은 글 감사합니다 재밌게 읽었습니다

답글 달기