00:00:00[음악]
00:00:21>> 여러분, 안녕하세요. 반갑습니다.
00:00:22오늘 강연은 제 고백으로 시작하려 합니다.
00:00:26제가 사실 완전히 이해하지 못한 코드를 배포한 적이 있습니다.
00:00:29코드를 생성하고, 테스트하고, 배포까지 했지만 어떻게 작동하는지 설명할 수 없었죠.
00:00:33그런데 말입니다, 장담하건대 여기 계신 여러분도 모두 그런 적이 있을 겁니다.
00:00:37>> [웃음]
00:00:40>> 이제 우리 모두 더 이상 이해하지 못하는 코드를 배포한다는 점을 인정했으니,
00:00:41어쩌다가 이런 상황에 이르게 되었는지,
00:00:44그 과정을 한번 살펴보려 합니다.
00:00:46먼저 역사를 되짚어보면, 역사는 반복되는 경향이 있다는 것을 알 수 있습니다.
00:00:50둘째로, 우리는 일종의 함정에 빠져 있습니다.
00:00:52우리는 '쉬운 것(easy)'과 '단순한 것(simple)'을 혼동해 왔습니다.
00:00:55마지막으로 해결책이 있긴 하지만, 그것은 사고를 외주화하지 않을 때만 가능합니다.
00:01:00저는 지난 몇 년간 넷플릭스에서 AI 도구의 도입을 추진하는 일을 도왔습니다.
00:01:05말씀드리자면, 그 가속도는 정말 대단합니다.
00:01:07예전에는 며칠씩 걸리던 백로그 항목들을 이제는 몇 시간 만에 처리합니다.
00:01:10수년간 미뤄왔던 대규모 리팩토링도 마침내 실행되고 있죠.
00:01:15하지만 문제가 있습니다.
00:01:16대규모 운영 시스템은 항상 예상치 못한 방식으로 고장이 납니다.
00:01:19최근 클라우드플레어(Cloudflare) 사태만 봐도 알 수 있죠.
00:01:21장애가 발생했을 때, 여러분은 디버깅하는 코드를 제대로 이해하고 있어야 합니다.
00:01:23그런데 문제는 우리가 코드를 너무 빠르고 방대한 양으로 생성하고 있다는 점입니다.
00:01:28우리의 이해 속도가 그 속도를 따라잡지 못하고 있습니다.
00:01:29저도 잘 압니다, 제가 직접 겪어봤으니까요.
00:01:34방대한 코드를 생성해놓고 들여다보며 '이게 대체 뭘 하는 건지 모르겠네'라고 생각한 적이 있습니다.
00:01:39하지만 테스트를 통과했고 작동하니까 그냥 배포해 버렸죠.
00:01:41사실 이런 현상이 아주 새로운 것은 아닙니다.
00:01:44모든 세대의 소프트웨어 엔지니어들은 결국 소프트웨어의 복잡성이
00:01:48자신의 관리 능력을 초과하는 한계점에 부딪혀 왔습니다.
00:01:50우리가 소프트웨어 위기를 처음 겪는 세대는 아닙니다.
00:01:52다만 무한한 생성의 시대에 이 위기를 맞이한 첫 세대일 뿐이죠.
00:01:56그럼 잠시 물러나서 이 모든 것이 어디서 시작되었는지 살펴보겠습니다.
00:01:5860년대 후반과 70년대 초반, 당시의 똑똑한 컴퓨터 과학자들이
00:02:03모여서 '우리는 지금 소프트웨어 위기에 처해 있다'라고 말했습니다.
00:02:06소프트웨어에 대한 수요는 엄청난데, 정작 우리는 그걸 감당하지 못하고 있다는 것이었죠.
00:02:11프로젝트 기간은 너무 길어지고, 진행 속도는 너무 느렸습니다.
00:02:15우리는 제대로 해내지 못하고 있었던 겁니다.
00:02:16그때 다익스트라(Dijkstra)가 아주 훌륭한 말을 남겼습니다.
00:02:20그의 긴 말을 조금 의역해보자면 이렇습니다.
00:02:23“컴퓨터 성능이 낮았을 때는 프로그래밍이 사소한 문제였지만,
00:02:26컴퓨터가 거대해지자 프로그래밍은 거대한 문제가 되었다.”
00:02:31그는 하드웨어의 성능이 1,000배 성장함에 따라
00:02:34사회가 요구하는 소프트웨어의 양도 그에 비례해 늘어났음을 설명했습니다.
00:02:37그 과정에서 프로그래머들은 방법과 수단을 찾아내어
00:02:41어떻게 이토록 방대한 소프트웨어를 뒷받침할지 고민해야 했습니다.
00:02:43이런 일은 주기적으로 계속 발생했습니다.
00:02:4770년대에는 더 큰 시스템을 구축하기 위해 C 언어가 등장했습니다.
00:02:5080년대에는 개인용 컴퓨터가 보급되어 누구나 소프트웨어를 짤 수 있게 되었죠.
00:02:5390년대에는 객체 지향 프로그래밍이 등장했습니다.
00:02:56자바 덕분에 지옥 같은 상속 구조도 생겨났고요.
00:03:002000년대에는 애자일이 도입되어 워터폴 방식 대신
00:03:03스프린트와 스크럼 마스터가 지시를 내리기 시작했습니다.
00:03:062010년대에는 클라우드, 모바일, 데브옵스 등 모든 것이 등장했고,
00:03:09그야말로 소프트웨어가 세상을 집어삼켰습니다.
00:03:10그리고 오늘날에는 AI, 코파일럿, 커서, 클로드, 코덱스, 제미나이 등이 있습니다.
00:03:17우리는 설명하는 속도만큼이나 빠르게 코드를 생성할 수 있습니다.
00:03:19패턴은 계속되지만, 그 규모가 무한해졌다는 점이 달라졌습니다.
00:03:23여러분은 '맨먼스 미신'의 저자 프레드 브룩스(Fred Brooks)를 아실 겁니다.
00:03:29그는 1986년에 '은탄환은 없다(No Silver Bullet)'라는 논문도 썼습니다.
00:03:32그는 논문에서 소프트웨어 생산성을 획기적으로 개선할 수 있는
00:03:36단 한 가지의 혁신은 존재하지 않을 것이라고 주장했습니다.
00:03:38왜일까요?
00:03:40그는 프로그래밍의 어려운 점은 코딩 기술, 문법, 타이핑,
00:03:44또는 반복적인 코드 작성이 아니라고 말했습니다.
00:03:45진짜 어려운 부분은 실제 문제를 이해하고 해결책을 설계하는 것이기 때문입니다.
00:03:49그 어떤 도구도 이 근본적인 어려움을 제거할 수는 없습니다.
00:03:52지금까지 우리가 만든 모든 도구와 기술은 코딩 기술을 더 쉽게 만들어줄 뿐입니다.
00:03:55하지만 핵심 과제인,
00:03:57무엇을 만들지, 어떻게 작동하게 할지를 이해하는 것은 여전히 똑같이 어렵습니다.
00:04:00문제가 코딩 기술에 있지 않다면, 왜 우리는 자꾸 기술적인 면만 최적화하려 할까요?
00:04:06경험 많은 엔지니어들이 어쩌다가 스스로 이해하지 못하는 코드를 갖게 되었을까요?
00:04:09그 답은 우리가 자주 혼동하는 두 단어인 '단순함(simple)'과 '쉬움(easy)'에 있다고 봅니다.
00:04:14우리는 보통 이 두 단어를 섞어서 사용하지만,
00:04:16사실 이 단어들은 완전히 다른 의미를 가지고 있습니다.
00:04:18제가 스피커 저녁 식사 자리에서 클로저(Clojure) 개발자라는 사실이 들통났는데요.
00:04:21여기서 그 차이가 명확해집니다.
00:04:23클로저 언어의 창시자인 리치 히키(Rich Hickey)는
00:04:252011년 'Simple Made Easy'라는 강연에서 이를 설명했습니다.
00:04:29그는 단순함(simple)을 '한 겹, 한 가닥, 얽히지 않음'으로 정의했습니다.
00:04:33각 조각이 한 가지 일만 하고 다른 것과 꼬이지 않은 상태죠.
00:04:36반면 쉬움(easy)은 '가까운 것, 손에 닿는 것'을 의미한다고 정의했습니다.
00:04:39노력 없이 접근할 수 있는 것은 무엇인가?
00:04:41복사하고, 붙여넣고, 배포하는 것이죠.
00:04:43단순함은 구조에 관한 것입니다.
00:04:45쉬움은 근접성에 관한 것이고요.
00:04:48문제는 우리가 바란다고 해서 무언가가 단순해지지는 않는다는 점입니다.
00:04:51단순함에는 사고와 설계, 그리고 엉킨 것을 푸는 과정이 필요합니다.
00:04:54하지만 무언가를 더 쉽게 만드는 것은 언제나 가능합니다.
00:04:56그냥 더 가까이 두면 되니까요.
00:04:57패키지를 설치하거나, AI로 생성하거나, 스택 오버플로우의 해결책을 복사하면 됩니다.
00:05:03쉬운 길을 선택하는 것은 인간의 본능입니다.
00:05:06우리는 그렇게 프로그래밍되어 있습니다.
00:05:07말씀드린 대로 스택 오버플로우에서 복사하는 건 아주 간단합니다.
00:05:10마법처럼 모든 걸 처리해주는 프레임워크를 설치하고 실행하면 끝이죠.
00:05:14하지만 쉽다고 해서 단순한 것은 아닙니다.
00:05:15쉬움은 시스템에 무언가를 빠르게 추가할 수 있다는 뜻입니다.
00:05:18단순함은 당신이 한 작업을 이해할 수 있다는 뜻입니다.
00:05:20쉬운 길을 택할 때마다 우리는 지금의 속도를 위해 미래의 복잡성을 담보로 잡는 셈입니다.
00:05:24솔직히 예전에는 그런 트레이드오프가 꽤 잘 통했습니다.
00:05:27코드베이스에 쌓이는 복잡도가 충분히 느려서 필요할 때마다
00:05:31리팩토링하고, 재검토하고, 다시 구축할 시간이 있었거든요.
00:05:34하지만 AI가 그 균형을 깨뜨렸다고 생각합니다.
00:05:36AI는 궁극의 '쉬움 버튼'이니까요.
00:05:37AI는 쉬운 길을 너무나도 매끄럽게 만들어서
00:05:38우리가 더 이상 단순한 길에 대해서는 고민조차 하지 않게 만듭니다.
00:05:41코드가 즉시 나타나는데 굳이 아키텍처를 고민할 필요가 있을까요?
00:05:44이런 일이 어떻게 일어나는지 보여드리겠습니다.
00:05:47우리가 좋아하는 대화형 인터페이스를 통해 어떻게
00:05:50단순한 작업이 복잡함의 늪으로 변해가는지 말이죠.
00:05:52가상의 예시이긴 하지만, 우리 앱에
00:05:55인증 기능을 추가한다고 가정해 봅시다.
00:05:57인증을 추가해달라고 하면 깔끔한 auth.js 파일이 생성됩니다.
00:06:01몇 번 수정을 거쳐 메시지가 5개 정도 쌓였다고 합시다.
00:06:02이제 OAuth도 추가하고 싶어집니다.
00:06:04그러면 auth.js와 OAuth.js 파일이 생기겠죠.
00:06:07계속 반복하다 보니 세션 기능이 고장 납니다.
00:06:11코드 충돌도 한가득 생기고요.
00:06:12질문이 20번쯤 오가면 더 이상 대화를 하는 게 아닙니다.
00:06:15자신이 추가한 제약 조건조차 기억하지 못할 정도로
00:06:18너무나 비대해진 컨텍스트를 간신히 관리하고 있는 처지가 되죠.
00:06:20버려진 방식에서 남겨진 죽은 코드들,
00:06:22그저 돌아가게만 만드느라 억지로 짜 맞춘 테스트들,
00:06:25세 가지 서로 다른 해결책의 파편들이 뒤섞여 버립니다.
00:06:28새로운 지시가 내려올 때마다 기존의 아키텍처 패턴은 덮어씌워 집니다.
00:06:31인증이 돌아가게 해달라고 하면 그렇게 해줍니다.
00:06:33에러를 고쳐달라고 하면 고쳐줍니다.
00:06:35잘못된 아키텍처 결정에 대한 어떤 저항도 없습니다.
00:06:38코드는 그저 최신 요청에 맞춰서 변형될 뿐입니다.
00:06:40상호작용이 일어날 때마다 단순함 대신 쉬움을 택하는 것이고,
00:06:43쉬움은 언제나 더 큰 복잡성을 의미합니다.
00:06:46우리도 머리로는 알지만, 쉬운 길이 너무나도 쉽다 보니 결국 그 길을 택하게 됩니다.
00:06:50그리고 복잡성은 손쓸 수 없을 때까지 계속해서 불어날 것입니다.
00:06:52AI는 '쉬움'을 논리적 극한까지 밀어붙입니다.
00:06:58원하는 것을 결정하기만 하면 즉시 코드를 얻을 수 있죠.
00:07:00하지만 여기에 위험이 도사리고 있습니다.
00:07:02생성된 코드는 코드베이스의 모든 패턴을 동일하게 취급합니다.
00:07:06에이전트가 코드베이스를 분석할 때, 모든 줄은 보존해야 할 패턴이 됩니다.
00:07:1047번 줄에 있는 인증 체크도 하나의 패턴입니다.
00:07:13제가 2019년에 추가했을지도 모를, GraphQL처럼 작동하는
00:07:18이상한 GRPC 코드도 똑같은 패턴으로 인식됩니다.
00:07:19기술 부채는 부채로 인식되지 않고 그저 또 다른 코드일 뿐이죠.
00:07:22진짜 문제는 복잡성입니다.
00:07:25강연 내내 이 단어를 정의도 내리지 않고 계속 썼는데요.
00:07:29복잡성을 생각하는 가장 좋은 방법은 그것이 단순함의 반대라는 것입니다.
00:07:31그저 '서로 얽혀 있음'을 의미하죠.
00:07:33무언가가 복잡해지면 모든 것이 다른 모든 것에 영향을 줍니다.
00:07:36하나를 바꾸면 연쇄적으로 열 군데에 영향을 미치게 됩니다.
00:07:41다시 프레드 브룩스의 '은탄환은 없다' 논문으로 돌아가 보죠.
00:07:43그는 모든 시스템에 두 가지 주요 복잡성이 존재한다고 보았습니다.
00:07:47첫째는 '본질적 복잡성(essential complexity)'으로,
00:07:51해결하려는 문제 자체에서 기인하는 근본적인 어려움입니다.
00:07:53사용자는 결제를 해야 하고 주문은 처리되어야 합니다.
00:07:56이것은 그 소프트웨어 시스템이 존재하는 근본적인 이유에서 오는 복잡성입니다.
00:08:00둘째는 '우연적 복잡성(accidental complexity)'입니다.
00:08:03개발 과정에서 추가된 임시방편, 방어적 코드,
00:08:06프레임워크, 그리고 한때는 유효했던 추상화 등을 말합니다.
00:08:09코드를 작동시키기 위해 우리가 덧붙인 모든 것들이죠.
00:08:11실제 코드베이스에서는 이 두 유형의 복잡성이 곳곳에 퍼져 있습니다.
00:08:16이것들이 너무 긴밀하게 엉켜 있어서 이를 분리해내려면
00:08:19맥락과 역사, 그리고 경험이 필요합니다.
00:08:20하지만 생성된 결과물은 이런 구분을 전혀 하지 못합니다.
00:08:24그래서 모든 패턴이 그저 그대로 유지되는 것이죠.
00:08:26넷플릭스에서 진행 중인 작업 중 실제 사례를 하나 들어보겠습니다.
00:08:32약 5년 전에 작성한 기존의 권한 부여 코드와
00:08:35새로운 중앙 집중식 인증 시스템 사이에 추상화 계층이 있는 시스템이 있습니다.
00:08:41앱 전체를 새로 만들 시간이 없어서
00:08:42그 사이에 '심(shim)'을 하나 끼워 넣었죠.
00:08:44이제 AI가 있으니 새로운 시스템을 직접 사용하도록
00:08:47코드를 리팩토링할 아주 좋은 기회입니다. 간단한 요청 같죠?
00:08:50전혀 아니었습니다. 기존 코드가 예전의 권한 부여 패턴과
00:08:56너무나도 단단히 결합되어 있었거든요. 권한 체크 로직이 비즈니스 로직에 스며들어 있었고,
00:08:59역할에 대한 가정이 데이터 모델에 박혀 있었으며, 인증 호출이 수백 개 파일에 흩어져 있었습니다.
00:09:03에이전트가 리팩토링을 시작했지만 몇 개 파일을 채 처리하기도 전에
00:09:07도저히 풀 수 없는 의존성에 부딪혔고, 결국 통제 불능 상태에 빠져 포기해 버렸습니다.
00:09:10더 최악인 상황은, 에이전트가 이전 시스템의 기존 로직을 보존하려고
00:09:16새로운 시스템을 사용해 이전 방식을 재현하려 했던 것이었는데, 이것 역시 좋지 않았습니다.
00:09:19문제는 AI가 '경계선'을 보지 못했다는 점입니다.
00:09:23비즈니스 로직이 어디서 끝나고 인증 로직이 어디서 시작되는지 파악하지 못했죠.
00:09:26모든 것이 너무 엉켜 있어서 완벽한 정보가 있어도
00:09:30AI는 깔끔한 경로를 찾아내지 못했습니다.
00:09:33우연적 복잡성이 이 정도로 얽혀버리면
00:09:35AI는 상황을 개선하는 데 별 도움이 되지 않습니다.
00:09:38오히려 그 위에 복잡성의 층을 더 쌓을 뿐이라는 걸 깨달았습니다.
00:09:40우리는 그 차이를 구별할 수 있습니다. 적어도 생각을 위해 충분히 속도를 줄인다면 말이죠.
00:09:45우리는 어떤 패턴이 본질적인 것인지,
00:09:47그리고 어떤 것이 단지 몇 년 전 누군가가 해결했던 방식일 뿐인지 알고 있습니다.
00:09:50우리는 AI가 추론할 수 없는 맥락을 가지고 있습니다. 하지만
00:09:53시작하기 전에 시간을 들여 이러한 구분을 명확히 할 때만 가능합니다.
00:09:56그렇다면 실제로 어떻게 해야 할까요?
00:10:01거대한 코드베이스를 마주한 상황에서 어떻게
00:10:04우연적 복잡성과 본질적 복잡성을 분리할 수 있을까요?
00:10:07제가 넷플릭스에서 다루는 코드베이스는 약 100만 줄의 자바 코드로 되어 있고,
00:10:10메인 서비스는 마지막으로 확인했을 때 약 500만 토큰 규모였습니다.
00:10:13제가 사용할 수 있는 어떤 컨텍스트 윈도우도 이를 다 담을 수 없었죠.
00:10:17그래서 처음에는 이런 생각을 했습니다.
00:10:19코드베이스의 방대한 부분을 컨텍스트에 복사해 넣으면
00:10:23패턴이 저절로 드러나지 않을까,
00:10:24무슨 일이 일어나고 있는지 AI가 스스로 알아내지 않을까 하고 말이죠.
00:10:26하지만 이전의 인증 리팩토링 사례와 마찬가지로,
00:10:29결국 출력물은 그 자체의 복잡함 속에 길을 잃고 말았습니다.
00:10:31그래서 저는 다른 방식을 취할 수밖에 없었죠.
00:10:34무엇을 포함할지 직접 선택해야 했습니다. 설계 문서, 아키텍처, 다이어그램,
00:10:37핵심 인터페이스 등 중요한 것들을 골라냈죠.
00:10:39그리고 컴포넌트들이 어떻게 상호작용해야 하는지, 어떤 패턴을 따라야 하는지
00:10:42요구사항을 작성하는 데 시간을 들였습니다.
00:10:43보시다시피, 저는 사양서를 쓰고 있었던 겁니다.
00:10:45500만 개의 토큰이 2,000단어 분량의 사양서가 되었습니다.
00:10:49그리고 더 나아가, 그 사양서를 바탕으로
00:10:52실행할 코드의 정확한 단계들을 생성했습니다.
00:10:55모호한 지시 없이, 그저 정밀한 작업 순서만을 담았죠.
00:10:58이 방식이 훨씬 더 깔끔하고 제가 이해할 수 있는 집중된 코드를 만든다는 것을 발견했습니다.
00:11:02즉, 먼저 정의를 내리고 실행 계획을 세운 것입니다.
00:11:05이것이 제가 얼마 전부터 '컨텍스트 압축'이라고 부르기 시작한 접근 방식입니다.
00:11:11여러분은 이를 컨텍스트 엔지니어링이라 부르든, 스펙 기반 개발이라 부르든,
00:11:13뭐라 부르셔도 상관없습니다.
00:11:15이름은 중요하지 않습니다.
00:11:16중요한 것은 사고와 계획이 업무의 대부분을 차지하게 된다는 점입니다.
00:11:20그럼 이 방식이 실제로 어떻게 작동하는지 단계별로 설명해 드리겠습니다.
00:11:22우선 1단계, 리서치 단계입니다.
00:11:26먼저 모든 정보를 입력합니다.
00:11:28아키텍처 다이어그램, 문서, 슬랙 대화 내용 등이죠.
00:11:31이미 여러 번 언급했던 내용들이지만,
00:11:32변경하려는 내용과 관련이 있는 가능한 한 많은 컨텍스트를
00:11:35가져오는 것이 정말 중요합니다.
00:11:36그런 다음 에이전트를 사용해 코드베이스를 분석하고
00:11:39컴포넌트와 의존 관계를 파악하게 합니다.
00:11:42이 과정은 한 번에 끝나서는 안 됩니다.
00:11:43저는 계속해서 질문을 던집니다. “캐싱은 어떻게 처리되지?”
00:11:46“장애 발생 시에는 어떻게 작동해?” 같은 식으로요.
00:11:47분석이 틀렸을 때는 제가 직접 바로잡아 줍니다.
00:11:49정보가 부족하다면 추가적인 컨텍스트를 제공하죠.
00:11:51반복할수록 분석의 정확도는 높아집니다.
00:11:55이 단계의 결과물은 단 하나의 리서치 문서입니다.
00:11:57무엇이 존재하고, 무엇이 어디에 연결되어 있으며,
00:11:59변경 사항이 어디에 영향을 줄지 정리된 문서죠.
00:12:01몇 시간의 탐색 과정이 단 몇 분의 읽을거리로 압축되는 것입니다.
00:12:03오늘 아침 덱스도 언급했지만, 여기서 '인간의 검토'가 핵심입니다.
00:12:09분석 내용이 실제와 맞는지 확인하는 이 순간이,
00:12:12전체 과정에서 가장 영향력이 큰 순간입니다.
00:12:15여기서 오류를 잡아내야 나중에 큰 재앙을 막을 수 있습니다.
00:12:17이제 2단계로 넘어갑니다.
00:12:20검증된 리서치 결과가 준비되었다면,
00:12:22상세한 구현 계획을 세웁니다. 실제 코드 구조,
00:12:25함수 시그니처, 타입 정의, 데이터 흐름 등을 포함해서요.
00:12:28어떤 개발자라도 따라 할 수 있을 만큼 상세해야 합니다.
00:12:30저는 이를 '번호대로 색칠하기'에 비유하곤 합니다.
00:12:32가장 주니어 엔지니어에게 건네주며 “이대로 해봐”라고 했을 때,
00:12:35줄 단위로 따라 하기만 해도 제대로 작동해야 합니다.
00:12:38이 단계에서 중요한 아키텍처적 결정을 많이 내리게 됩니다.
00:12:43복잡한 로직이 올바른지 확인하고,
00:12:45비즈니스 요구사항이 모범 사례를 따르고 있는지 점검합니다.
00:12:50서비스 경계가 확실한지, 깨끗하게 분리되었는지,
00:12:52불필요한 결합은 없는지 확인하죠.
00:12:54우리는 이미 경험해 봤기에 문제가 생기기 전에 미리 감지할 수 있습니다.
00:12:57AI에게는 그런 선택지가 없습니다.
00:12:59AI는 모든 패턴을 하나의 요구사항으로만 취급하니까요.
00:13:01이 단계의 진정한 마법은 검토 속도에 있습니다.
00:13:05우리는 몇 분 만에 계획을 검증하고 무엇이 만들어질지 정확히 알 수 있습니다.
00:13:10코드를 생성하려는 속도에 발을 맞추려면,
00:13:13우리가 무엇을 하고 있는지 그만큼 빠르게 파악할 수 있어야 합니다.
00:13:18마지막으로 구현 단계입니다. 명확한 계획과
00:13:22탄탄한 리서치가 뒷받침되었으므로, 이 단계는 아주 간단해야 합니다.
00:13:26그게 바로 핵심입니다.
00:13:28AI가 따라야 할 명확한 사양이 있을 때 컨텍스트는 깔끔하고
00:13:31집중된 상태를 유지합니다.
00:13:32긴 대화로 인해 복잡성이 꼬여버리는 상황을 방지한 것이죠.
00:13:3650개의 메시지를 주고받으며 점진적으로 코드를 고치는 대신,
00:13:38매번 검증을 거친 세 개의 집중된 결과물을 얻게 됩니다.
00:13:41중간에 포기한 방식도, 충돌하는 패턴도 없으며,
00:13:44“아, 잠깐만요” 하며 여기저기 쓰레기 코드를 남기는 일도 없습니다.
00:13:48제가 생각하는 이 방식의 진짜 보상은, 미리 고민하고 어려운 작업을 다 해두었기 때문에
00:13:52백그라운드 에이전트에게 많은 일을 맡길 수 있다는 점입니다.
00:13:56에이전트가 구현을 시작하면 여러분은 다른 일을 하다가
00:13:59돌아와서 검토만 하면 됩니다.
00:14:01계획대로 잘 만들어졌는지 확인하기만 하면 되므로
00:14:04검토도 아주 빠르게 끝납니다. 뭔가 멋대로 지어내지 않았는지 걱정할 필요가 없죠.
00:14:07중요한 점은 우리가 AI에게 생각을 맡기는 것이 아니라는 겁니다.
00:14:12우리는 시스템을 이해하는 능력을 유지하면서,
00:14:15기계적인 부분의 속도를 높이기 위해 AI를 활용하는 것입니다.
00:14:17리서치는 빨라지고, 계획은 철저해지며, 구현은 깔끔해집니다.
00:14:21하지만 사고, 종합, 그리고 판단은 여전히 우리의 몫입니다.
00:14:26자, 아까 AI가 감당하지 못했다던 권한 부여 리팩토링 기억하시나요?
00:14:34사실 지금은 그 작업을 진행 중이고
00:14:37꽤 좋은 성과를 내고 있습니다.
00:14:39더 나은 프롬프트를 찾았기 때문이 아닙니다.
00:14:42처음에는 리서치, 계획, 구현 단계를 시작조차 할 수 없다는 걸 깨달았습니다.
00:14:46실제로 이 변경 작업은 저희가 직접 손으로 해야 했습니다.
00:14:49AI 없이 직접 코드를 읽고 의존성을 파악하며,
00:14:52무엇이 깨지는지 확인하기 위해 코드를 직접 수정했습니다.
00:14:53솔직히 그 수동 마이그레이션 작업은 고통스러웠지만 필수적이었습니다.
00:14:59그 과정을 통해 숨겨진 제약 사항과 반드시 지켜져야 할 불변성,
00:15:02권한 로직이 바뀔 때 깨질 서비스들이 무엇인지 드러났습니다.
00:15:05단순한 코드 분석만으로는 절대 알 수 없었던 것들이죠.
00:15:09그 후 직접 작업한 풀 리퀘스트(PR)를 리서치 과정에
00:15:14입력값으로 넣어 앞으로의 모든 리서치의 씨앗으로 삼았습니다.
00:15:19그제야 AI는 제대로 된 마이그레이션이 어떤 모습인지 이해할 수 있었습니다.
00:15:23하지만 각각의 엔티티가 조금씩 다르기 때문에 계속해서
00:15:27질문을 던져야 했습니다. “이 부분은 어떻게 처리해야 하지?”라고요.
00:15:29어떤 것은 암호화되어 있고 어떤 것은 그렇지 않았죠.
00:15:32반복적인 과정을 통해 매번 추가적인 컨텍스트를 제공해야 했습니다.
00:15:35그렇게 하고 나서야 비로소 한 번에 작동할 만한 계획을 세울 수 있었습니다.
00:15:41여기서 핵심 단어는 '작동할 만한'입니다. 우리는 여전히 검증하고,
00:15:45조정하며, 예외 케이스를 찾아내고 있습니다.
00:15:47이 3단계 접근 방식은 마법이 아닙니다.
00:15:55저희가 한 번의 마이그레이션을 직접 손으로 했기 때문에 가능한 것입니다.
00:15:57이해도를 직접 쌓고 나서야 그것을 프로세스에 녹여낼 수 있었습니다.
00:16:01저는 여전히 만능 해결책은 없다고 생각합니다.
00:16:02더 나은 프롬프트나 모델, 심지어 더 나은 사양서를 쓰는 것이 답은 아닙니다.
00:16:06그저 시스템을 깊이 이해하여 안전하게 변경할 수 있도록
00:16:09노력하는 수밖에 없습니다.
00:16:11그렇다면 왜 굳이 이런 과정을 거쳐야 할까요?
00:16:15그냥 제대로 될 때까지 AI와 계속 반복하면 안 될까요?
00:16:18언젠가는 모델이 충분히 강력해져서 그냥 알아서 잘해줄 텐데 말이죠.
00:16:21제 생각에, 그저 '작동한다'는 것만으로는 부족합니다.
00:16:24단순히 테스트를 통과하는 코드와 실제 운영 환경에서 살아남는 코드는 다릅니다.
00:16:28오늘만 돌아가는 시스템과,
00:16:31미래에 다른 사람이 수정할 수 있는 시스템 사이에는 큰 차이가 있습니다.
00:16:34진짜 문제는 '지식의 격차'입니다.
00:16:38AI가 수천 줄의 코드를 몇 초 만에 생성할 때,
00:16:41그것을 이해하는 데는 몇 시간, 복잡하다면 며칠이 걸릴 수도 있습니다.
00:16:45어쩌면 너무 엉망이라 영영 이해하지 못할 수도 있죠.
00:16:48아직 많은 사람이 간과하고 있는 사실이 하나 있습니다.
00:16:52생성 속도를 따라잡기 위해 매번 생각을 건너뛸 때마다,
00:16:56우리는 단순히 이해하지 못하는 코드를 추가하는 데 그치지 않습니다.
00:16:58우리는 문제를 인식하는 능력 자체를 잃어가고 있습니다.
00:17:00“아, 이거 너무 복잡해지는데?”라는 본능적인 감각은,
00:17:03자신의 시스템을 이해하지 못할 때 퇴화해 버립니다.
00:17:09패턴 인식은 경험에서 나옵니다.
00:17:11제가 위험한 아키텍처를 알아채는 이유는,
00:17:12새벽 3시에 그 문제를 해결하기 위해 직접 고군분투해 봤기 때문입니다.
00:17:16제가 더 단순한 해결책을 고집하는 이유는,
00:17:17다른 사람이 만든 복잡한 대안을 직접 유지보수해 봤기 때문입니다.
00:17:21AI는 여러분이 요청하는 것을 생성할 뿐입니다.
00:17:23과거의 실패에서 얻은 교훈을 코드로 구현하지는 않습니다.
00:17:253단계 접근 방식은 이 간극을 메워줍니다.
00:17:29생성 속도에 맞춰 검토할 수 있도록 이해의 과정을 압축된 결과물로 만드는 것이죠.
00:17:33이 과정이 없다면 우리는 이해할 수 있는 속도보다 훨씬 빠르게
00:17:37복잡성을 쌓아 올리게 될 것입니다.
00:17:39AI가 코드를 작성하는 방식의 모든 것을 바꾸고 있지만,
00:17:44솔직히 소프트웨어가 실패하는 근본적인 원인은 바꾸지 못한다고 생각합니다.
00:17:47모든 세대는 각자의 소프트웨어 위기에 직면해 왔습니다.
00:17:50다익스트라 세대는 소프트웨어 공학이라는 규율을 만들어 그 위기에 맞섰고,
00:17:54이제 우리는 무한한 코드 생성이라는 위기에 직면해 있습니다.
00:17:56저는 그 해결책이 또 다른 도구나 방법론에 있다고 보지 않습니다.
00:18:01소프트웨어는 인간의 노력이라는 본질을 기억하는 것이 답입니다.
00:18:05어려운 부분은 코드를 타이핑하는 것이 아니었습니다.
00:18:06애초에 무엇을 타이핑해야 할지 아는 것이 어려운 것이었죠.
00:18:09앞으로 성공할 개발자는 단순히 코드를 가장 많이 생성하는 사람이 아닐 것입니다.
00:18:13자신이 무엇을 만들고 있는지 이해하고,
00:18:15구조의 이음새를 볼 수 있으며, 잘못된 문제를 풀고 있다는 걸
00:18:18알아챌 수 있는 사람일 것입니다.
00:18:19그것은 여전히 우리의 역할이며,
00:18:20오직 우리만이 할 수 있는 일입니다.
00:18:21마지막으로 질문 하나를 던지며 마치려 합니다. 질문은
00:18:25우리가 AI를 사용할 것인가 말 것인가가 아닙니다.
00:18:26그건 이미 결정된 일입니다.
00:18:28배는 이미 떠났습니다.
00:18:30제가 생각하는 진짜 질문은, AI가 우리 코드의 대부분을 작성할 때
00:18:33우리가 여전히 자신의 시스템을 이해할 수 있을 것인가 하는 점입니다.
00:18:35감사합니다.
00:18:37>> (박수)
00:18:39(음악)