Skip to main content

Command Palette

Search for a command to run...

생성형 Ai는 당신의 엔지니어링 팀을 만들어주지 않습니다

코드를 생성하는 것은 쉽지만 좋은 코드를 생성하는 것은 그렇지 않습니다.

Published
생성형 Ai는 당신의 엔지니어링 팀을 만들어주지 않습니다

원문: Charity Majors, "Generative AI is not going to build your engineering team for you"

저는 19살 때 대학을 중퇴하고 샌프란시스코로 이사했습니다. Taos Consulting의 Unix 시스템 관리자로 일자리 제안을 받았죠. 하지만 첫 출근 전 도시에 있는 한 스타트업에 유인되었고 그곳에서 메일 서브시스템을 다루는 소프트웨어 엔지니어로 일하게 되었습니다.

일자리를 구할 수 있을지 고민한 적은 한 번도 없었습니다. 일자리는 넘쳐났죠. 무엇보다 채용 기준이 매우 낮았습니다. HTML을 조금 다룰 줄 알거나 명령줄 인터페이스로 작업할 수만 있다면, 당신을 고용할 누군가를 찾을 수 있었습니다.

제가 컴퓨터 키보드를 손에 쥐고 태어난 천재였냐고요? 전혀 그렇지 않습니다. 아이다호의 산골에서 홈스쿨링을 하다가 16살 때 대학에 간 후 처음 컴퓨터를 만져봤죠. 클래식 피아노 전공으로 장학금을 받고 대학에 입학했고, 나중에는 고전 라틴어와 그리스어, 음악 이론, 철학 같은 비기술 전공들을 공부하게 되었습니다. 컴퓨터는 대학교와 CS부서에서 시스템 관리자 일을 하며 배운 것이 다입니다.

돌이켜보면 그 시기에 IT업계에 들어온 것이 정말 행운이었습니다. 몇 년만 늦었어도 어떻게 됐을지 생각하면 아찔하죠. 친구들과 제가 업계에 진입하며 밟았던 모든 사다리는 이제 다 사라져 버렸습니다.

소프트웨어 산업은 성장하고 있습니다

어느 정도는 산업이 성숙해지면서 자연스럽게 일어나는 일입니다. 어떤 분야든 초기 단계는 마치 '서부 개척 시대'같습니다. 위험성은 낮고 규제는 전무하며 기초적 표준만 마련된 상태입니다. 의료나 영화, 라디오 같은 다른 산업들의 역사 초기를 살펴보면 매우 비슷한 점이 많습니다.

새로운 기술이 등장할 때는 어떤 마법 같은 순간이 있습니다. 역할 간 경계가 모호하여, 동기 부여가 되어 있고 호기심 많으며 열심히 일할 각오가 되어 있는 사람이라면 누구든 기회를 잡을 수 있죠.

그러나 그런 순간은 오래 지속되지 않습니다. 그럴 수도 없고, 그래서도 안 되죠. 산업에 진입하기 위해 요구되는 사전 지식과 경험의 양은 급격히 늘어납니다. 위험성이 증가하고 임무의 중요성이 커지며 실수에 따른 비용이 치솟습니다. 자격증, 교육, 표준, 법적 절차를 마련하게 됩니다. 그리고 소프트웨어 엔지니어가 진정으로 엔지니어인지에 대해 논쟁하게 되죠.

소프트웨어는 도제식 산업입니다

요즘은 제 경우처럼 10대 중퇴자가 바로 당신의 팀원으로 일하게 되는 것을 원하지 않을 겁니다. 산업에 진입하기 위해 필요한 사전 지식이 많아졌고 변화 속도는 더 빨라졌으며 위험성은 훨씬 더 커졌습니다. 그래서 예전에 제가 그랬던 것과 달리 직장에서 모든 것을 배울 수는 없습니다.

하지만 대학에서 필요한 모든 것을 배울 수 있는 것도 아닙니다. 컴퓨터 공학(CS) 학위 과정은 보통 실무의 소프트웨어 엔지니어로서의 커리어보다는 연구자로서의 커리어를 준비하는 데 더 적합합니다. 업계 진입에 더 실용적인 경로는 문제 해결과 최신 툴킷 학습을 중점적으로 가르치는 좋은 코딩 부트캠프일 수 있습니다. 어느 쪽이든 '일을 하는 방법'을 배우기보다는, '일을 배우기 위해 필요한 도구를 이해하고 사용하는 데 충분한 기본기'를 학습해야 합니다.

소프트웨어는 도제식 산업입니다. 책을 읽는 것만으로는 소프트웨어 엔지니어가 될 수 없습니다. 오직 실전에서 반복하며 배워야 합니다… 해보고 또 해보고, 더 많이 경험해야 합니다. 교육 프로그램이 어떻게 구성되어 있든 현장 직무 기간에 가장 많이 배울 수 있습니다. 그리고 배움은 절대 끝나지 않습니다! 배움과 가르침은 평생 지속되는 과정이며, 그래야만 합니다. 업계의 변화 속도가 아주 빠르기 때문에요.

일반적으로 (경력 단계에서 '시니어 소프트웨어 엔지니어'라고 부르는) 능숙한 소프트웨어 엔지니어를 양성하는 데는 7년 이상의 시간이 필요합니다. 이 기간 동안 더 경험 많은 엔지니어와 팀에서 함께 매일 코드 작성, 리뷰, 배포하는 시간이 필요합니다. 아주 오랜 시간이 걸리는 듯합니다.

'시니어 엔지니어'가 된다는 것은 무엇일까요?

이에 대해 종종 제 타임라인에 대해 다음과 같은 매우 분개한 반박을 받습니다.

"7년?! 뭐래 난 2년 만에 끝냈어!"
"난 5년도 안 걸려서 시니어 소프트웨어 엔지니어로 승진했어!"

잘됐네요. 사실 7년이라는 시간에 특별한 의미가 있는 건 아닙니다. 하지만 경험을 쌓고 팀의 중심이 될 수 있는 능숙한 엔지니어로 성장하는 데는 시간과 경험이 필요하다는 말이죠. 무엇보다도 실전 경험이 필요합니다.

언젠가부터 '시니어 소프트웨어 엔지니어'라는 용어를 코드를 완결하여 배포하고 생산성 면에서 순이익을 낼 수 있는 엔지니어를 의미하는 약어로 사용하게 된 것 같습니다. 개인적으로는 아주 잘못되었다고 생각합니다. 이는 경험이 부족한 엔지니어가 생산성 측면에서 순손실을 낸다는 암시를 주는데, 사실이 아닙니다. 게다가 소프트웨어 엔지니어링의 본질을 흐릴 수 있습니다. 코드 작성은 소프트웨어 엔지니어링 업무의 작은 부분에 불과합니다.

제 생각에 시니어 엔지니어가 된다는 것은 코드를 작성하는 능력만으로 결정되는 것이 아닙니다. 오히려 큰 규모의 소프트웨어를 오랜 시간 동안 운영해 오면서 이해하고 유지보수하며 설명하고 관리하는 능력, 그리고 비즈니스 요구 사항을 기술적 구현으로 변환하는 능력과 더 관련이 있습니다. 업무의 대부분은 크고 복잡한 사회기술 시스템을 만들고 관리하는 것이며, 코드는 그 시스템을 표현하는 하나의 수단일 뿐입니다.

시니어 엔지니어가 된다는 것은 무엇일까요? 그것은 무엇보다도 먼저 배우는 방법을 익혔고 가르치는 방법 또한 배웠다는 것을 의미합니다. 또한 시스템의 개념적 모델들을 머릿속에 담아 두고 이성적으로 판단할 수 있는 방법, 시간이 지나도 시스템을 유지하고 확장하며 운영할 수 있는 방법을 아는 것입니다. 나아가 신뢰할만한 좋은 판단력과 직관을 가지고 있다는 것입니다.

여기서 AI에 대한 이야기를 시작해 보죠.

스스로 미래를 잠식하는 것을 멈춰야 합니다

엔지니어로서 첫 직장을 얻는 것은 정말, 정말 어려운 일입니다. 제 여동생 (훌륭한 성적으로 갓 졸업하고 약간의 실무 경험도 있는 엄청나게 성실한 사람)이 거의 2년 동안 자신의 분야에서 제대로 된 직장을 구하려고 고군분투하는 것을 보고 나서야 얼마나 힘든지 비로소 깨달았습니다. 그 일이 몇 년 전이었으니 지금은 훨씬 더 어려워진 것 같습니다.

지난해 여러 산업에서 신입 직급의 일자리가 AI로 대체되고 있다는 기사를 꾸준히 읽었습니다. 그중 일부는 분명 일리가 있습니다. 문서를 한 형식에서 다른 형식으로 변환하거나, 많은 텍스트를 읽고 요약하는 일, 아이콘 세트를 다른 세트로 교체하는 일 등의 단순한 반복 작업은 분명 취약해 보입니다. 이러한 대체는 개인적으로 딱히 혁신적으로 느껴지지 않습니다. 단지 기존의 자동화 붐이 텍스트 자료뿐만 아니라 수치 자료까지 확장된 것일 뿐입니다.

그러나 최근 많은 임원들과 테크 분야의 이른바 '사고 리더(thought leaders)'들은 생성형 AI가 주니어 엔지니어들이 하는 모든 일을 곧 대체할 것이라고 진심으로 믿는 것 같습니다. 주니어 엔지니어의 일이 완전히 자동화되어 사라지고 있다거나 그 수요가 급격히 줄어들고 있다는 기사들을 너무 많이 읽었고, 이제는 정신이 나갈 것 같습니다.

이 모든 것은 엔지니어들이 실제로 하는 일을 깊이 오해하고 있음을 시사합니다. 주니어 엔지니어를 고용하고 훈련시키지 않는 것은 우리 스스로 우리의 미래를 갉아먹는 것입니다. 이제는 그러지 말아야 합니다.

코드를 작성하는 것은 쉬운 부분입니다

사람들은 소프트웨어에서 코드를 작성하는 것이 가장 어려운 부분이라고 생각하는 것 같습니다. 그렇지 않습니다. 그랬던 적도 없고 앞으로도 그럴 일은 없습니다. 코드 작성은 소프트웨어 엔지니어링에서 가장 쉬운 부분이며 날이 갈수록 더 쉬워지고 있습니다. 진짜 어려운 부분은 그 코드로 하는 일입니다. 코드를 운영하고 이해하며 확장하고 전 생애 주기에 걸쳐 관리하는 것이 어렵습니다.

주니어 엔지니어는 한 줄의 코드, 함수, 또는 코드 스니펫을 작성하고 디버깅하는 것부터 익히기 시작합니다. 경험을 거듭하고 시니어 엔지니어로 성장해 가면서, 소프트웨어로 시스템을 구성하는 방법과 시스템을 변경과 변환의 흐름 속에서 다루는 방법을 배우게 됩니다.

사회기술적 시스템은 소프트웨어, 도구, 사람들로 이루어져 있습니다. 따라서 시스템을 이해하려면 소프트웨어, 사용자, 프로덕션, 인프라, 그리고 지속적인 변화들 간의 상호작용에 대해 정통해져야 합니다. 이러한 시스템들은 엄청나게 복잡하고, 혼란과 비결정성 그리고 예상치 못한 동작에 영향을 받습니다. 만약 누군가 자신이 개발하고 운영하는 시스템을 완전히 이해한다고 주장한다면, 그 시스템이 매우 작거나 (높은 확률로) 자신이 모른다는 것을 모를 정도로 모르는 것입니다. 다시 말해 코드는 쉽지만, 시스템은 어렵습니다.

현재의 생성형 AI 도구들은 아주 빠르게 많은 양의 코드를 생성하는 데 큰 도움을 주고 있습니다. 쉬운 부분이 점점 더 놀라운 속도로 쉬워지고 있는 것입니다. 하지만 그 코드를 관리하고 이해하며 운영하는 작업에는 전혀 도움을 주지 못했습니다. 오히려 어려운 작업들을 더 어렵게 만들었습니다.

코드 생성은 쉽지만, 좋은 코드 생성은 어렵습니다

과장된 사설을 수없이 읽다 보면, 소프트웨어 엔지니어들이 기쁜 마음으로 ChatGPT에 프롬프트를 입력하거나 Copilot을 사용해 대량의 코드를 생성하여 GitHub에 커밋하고 신경 쓰지 않는 모습을 상상할 수 있을 겁니다. 하지만 이는 현실과 다릅니다.

Copilot 같은 도구를 받아들이는 올바른 방법은 매우 정교한 자동 완성 기능이나 복사-붙여 넣기 기능으로 보는 것입니다. 혹은 Stack Overflow 검색 결과와 구글의 'I'm Feeling Lucky' 기능의 끔찍한 혼종이라고 볼 수 있습니다. 사용할 때마다 주사위를 굴리는 것이죠.

이러한 도구들은 파일 내에 이미 유사한 코드가 존재하고, 그것을 약간 수정하여 복사-붙여 넣기 할 때 가장 유용합니다. 또는 테스트 작성 시, 상당히 반복적인 YAML 블록이 있어 마치 자동화 템플릿처럼 패턴을 반복하면서 자동으로 적절한 컬럼명과 필드명을 넣어줄 때도 유용하죠.

그러나 생성된 코드를 신뢰할 수는 없습니다. 이 점이 정말로 중요합니다. AI가 생성한 코드는 항상 그럴듯해 보이지만 '작동'하는 것처럼 보일 때조차도 요구사항을 충족시키지 못하는 경우가 대부분입니다. AI는 파싱되지 않는 코드나 컴파일되지 않는 코드를 웃으며 생성합니다. 존재하지 않는 변수, 메서드명, 함수, 필드 등을 날조하는 허위 정보를 만들어냅니다. 생성된 코드는 당신의 코딩 관습이나 규칙 역시 따르지 않습니다. 리팩토링을 하거나 지능적인 추상화를 고안해 주지도 않죠. 코드가 중요하고 복잡하며 의미가 있을수록 AI로부터 유용한 결과물을 얻기는 더욱 어렵습니다.

처음부터 코드를 직접 작성하지 않아도 되기 때문에 시간을 절약할 수 있을지 모르지만, 출력된 결과물을 한 줄 한 줄 검토하고 수정해야 합니다. 그러고 나서야 코드를 커밋하거나 프로덕션에 배포할 수 있습니다. 많은 경우 이 과정은 단순히 코드를 직접 작성하는 것만큼이나 시간이 걸리며 심지어는 더 오래 걸릴 수도 있습니다. 특히 요즘처럼 자동 완성이 매우 똑똑하고 정교해진 시대에는 더 그렇죠. AI가 생성한 코드를 코드베이스의 일관성을 따르도록 수정하는 데는 엄청난 노력이 필요할 수 있으며, 솔직히 그만한 가치가 있는 것 같지 않습니다.

컴파일되고 실행 가능하며 테스트를 통과할 수 있는 코드를 생성하는 것은 그리 어렵지 않습니다. 어려운 것은 여러 사람과 팀, 그리고 후속 팀들이 수년 동안 탐색하고 수정해 나가며 논리적으로 이해할 수 있게끔 코드베이스를 구축하는 일입니다.

실제 엔지니어들은 생성형 AI를 어떻게 사용할까요

세 줄 요약하자면 다음과 같습니다. 생성형 AI를 사용하면 아주 빠르게 많은 양의 코드를 생성할 수 있지만, 그 결과를 신뢰할 수 없습니다. 전혀요. 그러나 생성형 AI가 꾸준히 빛을 발하는 몇 가지 용례가 있습니다.

예를 들어 익숙하지 않은 API를 사용할 때 API 문서를 읽는 것보다 ChatGPT에 예제 코드를 생성해 달라고 요청하는 것이 종종 더 편리합니다. 어쨌든 AI 모델은 API가 사용되는 실제 업무의 리포지토리에서 수집된 데이터 집합 학습했기 때문입니다.

생성형 AI는 쓰기 번거롭거나 지루한 코드를 생성하는 데에도 꽤 능숙합니다. 범위가 명확하고 설명하기 쉬운 코드일 때 말이죠. 시나리오가 예측 가능할수록 더 좋은 코드를 작성해 줍니다. 가령 템플릿 기반으로 효율적으로 코드를 복사-붙여 넣기하고 싶은 상황이라면, 즉 sed/awk나 vi 매크로를 사용해 원하는 코드를 생성할 수 있는 경우에 생성형 AI가 아주 유용합니다.

또한 생소한 언어나 시나리오에서 사소한 함수를 작성하는 데에도 아주 좋습니다. 예컨대 파이썬 코드 스니펫이 있고, 이를 자바로 변환해야 하는데 자바에 익숙하지 않다면, 생성형 AI가 도움을 줄 수 있습니다.

다시 한번 강조하지만 결과가 완전히 엉터리일 확률은 50대 50입니다. 항상 결과물이 틀렸을 것이라고 가정하고 직접 검증할 때까지는 신뢰해서는 안 됩니다. 하지만 이러한 도구를 통해 다양한 방식으로 작업 속도를 훨씬 가속할 수 있습니다.

생성형 AI는 조금 주니어 엔지니어 같습니다

함께 일하는 엔지니어 중 한 명인 Kent Quirk는 생성형 AI를 '정말 빨리 타이핑하는 흥분한 주니어 엔지니어'라고 묘사했습니다. 저는 그 표현이 마음에 듭니다. 지울 수 없는 생생한 이미지를 떠올리게 하죠.

생성형 AI는 코드를 바로 프로덕션에 적용할 수 없다는 점에서 주니어 엔지니어와 비슷합니다. 그 코드에 대해 법적, 윤리적, 실질적인 책임을 져야 하니까요. 시간을 들여 그 코드를 이해하고 테스트하고 도구를 적용하며 코드베이스의 나머지 부분과 스타일 및 내용면에서 일관되게 맞춰야 합니다. 그리고 팀원들이 그 코드를 이해하고 유지 관리할 수 있도록 해야 합니다.

이 비유가 적절하다고 볼 수도 있지만, 코드가 일회용이고 자체적으로 완결된 경우에 한해서만 그렇습니다. 다시 말해 더 큰 작업에 통합될 필요가 없거나, 장기적으로 유지되거나, 다른 사람이 읽고 수정할 필요가 없는 코드일 때만 말이 됩니다.

그런데 산업의 일각에서는 정말로 이런 경우가 있습니다. 대부분의 코드가 단순히 작성만 하고 버려지는 일회용 코드인 경우요. 일부 에이전시는 특정 론칭이나 마케팅 이벤트를 위해 매년 수십 개의 일회용 앱을 만들다 방치합니다. 하지만 대부분의 소프트웨어는 그렇지 않죠. 일회용 코드는 드물며, 장기적으로 작동해야 하는 코드가 일반적입니다. 심지어 어떤 코드를 일회용으로 간주할 때조차도, 종종 그 판단이 틀리곤 합니다. 쳇…

하지만 생성형 AI는 당신의 팀원이 아닙니다

생성형 AI가 신뢰할 수 없는 코드를 생성한다는 점에서 주니어 엔지니어와 비슷할 수 있습니다. 하지만 그 외의 모든 측면에서 맞지 않는 비유입니다. 팀에 코드를 작성하는 사람을 합류시키는 것과 코드를 자동으로 생성하는 것은 완전히 다르기 때문입니다. 그 코드는 어디에서 왔는지 모릅니다. Stack Overflow, Copilot, 그 밖에 어디든 될 수 있죠. 중요한 건 출처를 알 수 없고, 사실 별로 중요하지도 않다는 점입니다. 피드백 루프가 없고, 반대편에서 반복적으로 배우고 개선하려는 사람도 없습니다. 팀의 분위기나 문화에 미치는 영향 또한 없죠.

매우 자명한 사실을 말하자면, 주니어 엔지니어에게 코드 리뷰 피드백을 주는 것과 AI가 생성한 코드를 수정하는 것은 다릅니다. 당신의 노력이 다른 사람의 수습 과정에 투자될 때 그 가치는 훨씬 더 큽니다. 자신의 커리어에서 배운 교훈을 전할 기회입니다. 피드백을 구성하고 메시지를 전달하는 그 과정만으로도 문제에 대해 숙고하게 만들며, 그 과정에서 더 깊이 이해할 수 있게 됩니다.

또한 주니어 엔지니어가 팀에 합류하면 팀 역학이 즉시 변합니다. 질문을 하는 것이 정상화되고 장려되는 환경이 조성되며, 가르침과 배움이 지속적으로 이루어지는 상태가 됩니다. 팀 역학에 대해서는 잠시 후에 더 이야기할 것입니다.

주니어 엔지니어가 성장할 수 있도록 돕는 데 투자한 시간은 놀라울 정도로 빠르게 결실을 맺을 수 있습니다. 시간이 금방 지나가죠. 😊 고용에 있어 우리는 시니어 엔지니어를 과대평가하는 동시에 주니어 엔지니어를 과소평가하는 경향이 있습니다. 두 고정관념 모두 도움이 되지 않습니다.

시니어 고용 비용은 과소평가하고, 주니어 고용 비용은 과대평가합니다

사람들은 시니어 엔지니어를 고용하면 팀에 바로 투입되어 즉시 생산성을 발휘할 것이고, 주니어 엔지니어를 고용하면 팀의 성과에 영원히 짐이 될 것이라고 생각하는 것 같습니다. 둘 다 사실이 아닙니다. 솔직히 대부분의 팀이 처리하는 대부분의 작업은 세부 작업으로 나누기만 하면 그리 어렵지 않습니다. 보다 낮은 수준의 엔지니어들이 충분히 수행하고 성장할 수 있는 여지가 많습니다.

회계사가 지나치게 단순하게 사안을 본다면 이렇게 생각할 겁니다. '$100k로 주니어 엔지니어를 고용해서 일을 지체시키느니, 차라리 $200k를 들여 시니어 엔지니어를 고용해 일을 빠르게 진행시키는 게 낫지 않겠어?' 말도 안 되는 소리!

하지만 당신도 알고 나도 알듯이 엔지니어링이 작동하는 방식은 그렇지 않습니다. 소프트웨어 개발은 도제 산업이며, 생산성은 각 개인이 아니라 팀 전체의 산출물과 처리 능력으로 정의됩니다.

한 사람이 팀의 속도 전반에 기여하는 방식에는 여러 가지가 있으며, 반대로 팀의 에너지를 고갈시키거나 주변을 껄끄럽게 하여 방해가 되는 방식도 여러 가지입니다. 이러한 요소들은 사람의 직급과 늘 상관되지는 않으며, 적어도 사람들이 흔히 생각하는 방향으로 일치하지는 않습니다. 코드 작성은 기여 방식 중 하나일 뿐입니다.

게다가 고용하는 모든 엔지니어는 적응 시간과 투자가 필요합니다. 엔지니어를 고용하고 훈련하는 것은 그들이 어떤 직급이든 간에 비용이 많이 드는 일입니다. 시니어 엔지니어도 시스템에 대한 내면적 모델을 구축하고 도구와 기술에 익숙해지며, 속도를 내기까지 시간이 걸립니다. 얼마나 걸릴까요? 이는 코드베이스가 얼마나 깔끔하고 체계적인지, 그들이 과거에 사용했던 도구와 기술과 얼마나 관련 있는지, 새로운 엔지니어를 온보딩하는 데 얼마나 능숙한지 등에 따라 달라지지만, 보통 6~9개월 정도 걸릴 것입니다. 완전히 궤도에 오르기까지는 아마 약 1년 정도 걸릴 거예요.

주니어 엔지니어의 경우 적응 시간이 더 길고 팀 차원에서 더 많은 투자가 필요할 것입니다. 하지만 그 기간이 무한정 이어지지는 않습니다. 주니어 엔지니어는 6개월에서 1년 안에 순이익을 낼 수 있어야 하며, 그들의 발전 속도는 시니어 엔지니어들보다 훨씬 빠릅니다. (그리고 그들의 기여는 그들이 직접 작성한 코드의 양을 훨씬 넘어설 수도 있다는 점을 잊지 마세요.)

시니어 엔지니어만 가치를 더할 수 있는 것은 아닙니다

기능을 작성하고 배포하는 측면에서, 가장 생산적인 엔지니어들 중 일부는 중급 엔지니어였습니다. 이들은 아직 수많은 회의, 코드 리뷰, 멘토링, 조언, 아키텍처 작업에 발목 잡히지 않았고, 일정이 여러 방해 요소로 가득 차 있지도 않아서 그저 작업에만 몰두할 수 있습니다. 아침에 헤드폰을 끼고 하루 종일 코드를 작성한 뒤, 저녁이 되면 엄청난 진척을 이룬 채 퇴근합니다.

중급 엔지니어들은 프로그래밍에 충분히 능숙해 생산성이 매우 높은 상태에 도달했지만, 여전히 시스템을 구축하고 관리하는 법을 배우는 과정에 있습니다. 이들은 오로지 코드를 작성합니다. 끝없이 많은 코드를요.

그리고 그들은 열정적이고… 몰입되어 있습니다. 즐거움을 느끼죠! 웹 폼이나 로그인 페이지를 1000번이나 작성하는 일에도 지루해하지 않습니다. 모든 것이 새롭고 흥미롭고 신나기 때문에 이들은 더 나은 결과를 내며, 특히 더 경험이 많은 사람의 가벼운 지도 아래에서는 더욱 그렇습니다. 팀에 중급 엔지니어가 있다는 건 놀라운 일입니다. 그들을 얻는 유일한 방법은 주니어 엔지니어를 고용하는 것입니다.

주니어와 중급 엔지니어들이 팀에 있다는 것은 과도한 엔지니어링과 성급한 복잡성을 방지하는 놀라울 정도로 좋은 예방책이 됩니다. 이들은 아직 문제에 대해 충분히 알지 못하여 모든 가능한 에지 케이스를 상상하며 해결하려고 하지 않기 때문에, 시스템을 단순하게 유지하는 데 도움을 줍니다. 단순함을 유지하는 것은 가장 어려운 일 중 하나죠.

장기적 관점에서 주니어 엔지니어를 고용해야 하는 이유

거의 모든 사람이 주니어 엔지니어를 고용하는 것이 좋은 일이라는 데 전적으로 동의할 것입니다… 하지만 그 일을 다른 누군가가 해야 한다고 말할 겁니다. 이는 주니어 엔지니어를 고용해야 하는 장기적인 이유가 충분히 설득력 있고 잘 이해되고 있기 때문입니다.

  • 우리는 업계에 더 많은 시니어 엔지니어가 필요합니다.

  • 누군가는 그들을 훈련시켜야 합니다.

  • 주니어 엔지니어는 비용이 더 저렴합니다.

  • 꼭 필요한 다양성을 더해줄 수 있습니다.

  • 그들을 교육한 회사에 매우 충성심을 가지며, 이직하지 않고 오래 머무르는 경우가 많습니다.

  • 누군가가 해야 한다는 점을 이미 언급했었나요?

하지만 장기적인 사고는 대체로 회사나 자본주의가 일반적으로 잘하는 일이 아닙니다. 이런 식으로 생각하면, 주니어 엔지니어를 고용하는 것이 마치 공공의 이익을 위한 이타적인 행위처럼 보이면서도 자신에게는 큰 비용이 드는 일로 느껴집니다. 기업은 이런 비용을 외부화하려는 경향이 훨씬 크며, 그래서 우리가 현재 이런 상황에 처하게 된 것입니다.

단기적 관점에서 주니어 엔지니어를 고용해야 하는 이유

그러나 주니어 엔지니어를 고용해야 하는 단기적인 이유도 충분히 많습니다. 팀과 회사에 이익이 되는 이기적이고 실질적이며, 수익성 있는 이유들이죠. 시각을 개인에서 팀으로 약간만 바꾸면 그 이유가 명확해집니다.

우선 엔지니어를 고용하는 것은 '일에 가장 적합한 사람을 선택'하는 과정이 아니라는 점부터 시작해 보겠습니다. 엔지니어를 고용하는 것은 팀을 구성하는 과정입니다. 소프트웨어 오너십의 가장 작은 단위는 개인이 아니라 팀입니다. 오직 팀만이 소프트웨어의 전체를 가지고 구축하며 유지할 수 있습니다. 이는 본질적으로 협력적이고 협동적인 활동입니다.

엔지니어를 고용하는 것이 '가장 뛰어난 사람'을 선택하는 문제라면, 주어진 예산으로 가능한 한 가장 시니어이자 경험이 많은 사람을 고용하는 것이 합리적일 겁니다. 왜냐하면 '시니어'와 '경험'을 '생산성'의 지표로 사용하기 때문이죠. (이 부분에 의문이 드실 수 있겠지만 여기서는 논쟁하지 않겠습니다.) 그러나 각 개인의 생산성은 우리가 최적화해야 할 것이 아닙니다. 중요한 것은 의 생산성이죠.

그리고 최고의 팀은 항상 다양한 강점과 관점 그리고 전문성 수준을 가진 팀입니다. 단일한 문화로 이루어진 팀은 단기적으로는 아주 성공적일 수 있습니다. 때로는 다양한 팀을 능가할 수도 있죠. 하지만 이런 팀은 잘 확장되지 않으며, 익숙하지 않은 난관에 대한 적응력이 떨어집니다. 다양화를 늦출수록, 다양성을 확보는 더 어려워집니다.

우리는 주니어 엔지니어를 단 한 번만이 아니라 꾸준히 고용해야 합니다. 아래에서부터 계속 인재를 유입시켜야 합니다. 주니어 엔지니어는 몇 년간만 주니어로 남아 있고, 중급 엔지니어는 곧 시니어 엔지니어로 성장합니다. 슈퍼 시니어 엔지니어들은 실제로 주니어 엔지니어를 멘토링하기에 가장 적합한 사람은 아닙니다. 가장 효과적인 멘토는 보통 바로 한 단계 위에 있는 사람으로, 주니어의 입장이 어떤 지 생생하게 기억하고 있는 사람입니다.

높은 성과를 내는 건강한 팀은 구성원 수준이 다양합니다

건강한 팀은 하나의 생태계입니다. 제품 엔지니어링 팀을 구성할 때 DB 전문가 6명과 모바일 개발자 1명만으로 구성하지 않을 겁니다. 마찬가지로 시니어 엔지니어 6명과 주니어 엔지니어 1명만으로 팀을 구성해서도 안 됩니다. 좋은 팀은 다양한 기술과 수준을 가진 사람들로 이루어져 있습니다.

혹시 스태프 엔지니어나 주요 엔지니어들로만 꽉 찬 팀에 있어본 적 있나요? 재미없습니다. 그것은 제대로 기능하는 팀이 아닙니다. 고급 아키텍처와 설계 작업뿐이고, 중대한 의사결정들만이 기다리고 있죠. 엔지니어들은 일하는 내내 지루함과 반복되는 느낌을 받습니다. 그 결과 과도하게 복잡한 해결책을 만들거나, 때로는 동시에 코드를 대충 처리하기도 합니다. 그들은 '재미있는' 작업을 두고 경쟁하며, 서로 기술적 논쟁을 벌일 구실을 찾습니다. 결과적으로 시스템을 단순하고 관리 가능하게 만드는 작업에 대해 문서화도 부족하고, 충분한 투자 자체가 이루어지지 않는 경향이 있습니다.

중급 엔지니어들만 있는 팀도 각기 다른 문제와 맹점을 겪습니다. (초급, 시니어 등 어떤 레벨이든) 하나의 레벨로만 구성된 팀이라면 마찬가지입니다. 작업의 복잡성과 난이도는 매우 다양합니다. 간단하고 명확하게 정의된 기능에서부터 복잡하고 중요한 아키텍처를 결정하는 것까지 포함하죠. 다양한 범위의 능력과 수준을 가진 팀이 작업을 하는 것이 더 합리적입니다.

최고의 팀은 아무도 지루해하지 않는 팀입니다. 팀의 모든 구성원이 각자에게 도전이 되는 일을 하며 자신의 경계를 넓힐 수 있기 때문입니다. 이를 위해서는 팀에 다양한 기술 수준을 가진 사람들을 포함시키는 것이 유일한 방법입니다.

우리가 직면한 병목 현상은 고용이지 훈련이 아닙니다

현재 우리가 직면한 병목은 새로운 주니어 엔지니어를 훈련시키고 그들에게 기술을 가르치는 능력이 아닙니다. 또한 주니어들이 더 열심히 노력해야 한다는 차원의 문제도 아닙니다. 이 주제에 대해 잘 정리된, 좋은 의도의 조언들이 많지만, 그건 문제를 해결하지 못합니다. 병목 현상은 그들에게 첫 직장을 제공하는 데 있습니다. 병목은 주니어들을 회사의 미래에 대한 투자로 보지 않고, 외부화 비용 대상으로 여기는 기업들로부터 비롯됩니다.

첫 직장을 구하고 나면 엔지니어는 대개 일자리를 찾을 수 있습니다. 하지만 제가 보기에 첫 직장을 얻는 것이 살인적입니다. 사실상 불가능합니다. 만약 당신이 명문대 출신이 아니고 빅테크의 채용 루트에 들어가 있지 않다면, 완전히 주사위를 던지는 것과 같으며 운이나 인맥에 달려 있는 문제입니다. '생성형 AI가 주니어 엔지니어를 대체할 수 있다'는 허상이 등장하기 에도 이미 힘든 상황이었죠. 그리고 지금은… 어휴.

당신이 그때 기술 업계에 발 들이지 못했더라면, 지금 어디에 있을까요?

저는 제가 어디에 있을지 알고 있습니다. 여기는 아니겠죠.

인터넷에서는 베이비붐 세대를 자주 조롱합니다. 이 세대는 손쉽게 대학에 다니고 집을 사고 은퇴한 후 여태 밟아온 사다리를 치워버리면서 젊은 세대를 ‘온실 속 화초’라며 비웃었죠. "네 다음 베이비붐 세대(Ok, Boomer)"라는 밈은 아마 계속 남아 있을 겁니다. 하지만 "네 다음 스태프 엔지니어(Ok, Staff Engineer)"가 새로운 밈이 되는 일만큼은 막아야 하지 않을까요?

시니어 엔지니어가 더 적게 필요하다고 생각하는 사람은 없습니다

많은 사람들이 주니어 엔지니어는 필요 없다고 생각하는 것 같지만, 시니어 엔지니어가 더 적게 필요하다고 주장하는 사람은 없습니다. 가까운 미래에 시니어 엔지니어가 덜 필요하게 될 것이라고 주장하는 사람 또한 없습니다.

결정론적이고 자동화할 수 있는 것은 결국 자동화된다고 가정하는 것이 안전하다고 생각합니다. 소프트웨어 엔지니어링도 예외는 아니죠. 우리는 그 중심에 있습니다! 당연히 항상 효율성을 개선하고 자동화할 방법을 찾고 있습니다. 그래야 하니까요.

하지만 대규모 소프트웨어 시스템은 예측할 수 없고 비결정론적이며 예상치 못한 동작이 나타납니다. 사용자들이 존재하는 것만으로도 시스템에 혼란을 야기합니다. 구성 요소는 자동화할 수 있지만 복잡성은 관리할 수 있을 뿐입니다.

설령 시스템이 AI에 의해 완전히 자동화되어 관리될 수 있다고 하더라도, 우리가 AI의 의사결정 방식을 이해할 수 없다는 사실은 극복하기 어려운, 어쩌면 해결할 수 없는 문제일 것입니다. 인간이 디버깅할 수 없거나 이해할 수 없는 시스템으로 비즈니스를 운영하는 것은 보안이나 법률, 재무 팀이 결코 승인하지 않을 만한 막대한 본질적 위험으로 보입니다. 언젠가 이런 미래가 실현될지도 모르지만, 지금으로서는 그 가능성을 보기 어렵네요. 저라면 제 경력이나 회사를 그런 위험에 걸진 않을 겁니다.

그동안은 여전히 더 많은 시니어 엔지니어가 필요합니다. 그들을 길러내는 유일한 방법은 인재 유입 경로를 바로잡는 것이고요.

모든 회사가 주니어 엔지니어를 고용해야 할까요?

아닙니다. 성공할 수 있는 환경을 제공할 수 있어야 합니다. 다음은 주니어 엔지니어를 고용할 수 없는 몇 가지 요인들입니다.

  • 회사의 자금이 2년 미만으로 유지되는 경우

  • 팀이 끊임없이 긴급 상황에 대응하고 있거나, 여유가 없는 경우

  • 경험이 풍부한 매니저가 없거나 매니저가 형편없거나 아예 매니저가 없는 경우

  • 제품 로드맵이 없는 경우

  • 팀 내에 멘토나 담당자가 될 사람이 전혀 없는 경우

주니어 엔지니어를 전혀 고용하지 않는 것보다 더 나쁜 유일한 경우는 그들이 아무것도 배울 수 없는 형편없는 환경에 고용되는 것입니다. (이 글에서 Cindy가 제시한 기준만큼 높게 설정하지는 않겠지만 그녀의 관점이 일면에서는 이해됩니다. 솔직히 대부분의 주니어 엔지니어가 아무런 직업이 없는 것보다는 형편없는 첫 직장을 택할 것이라고 생각합니다. 두 번째 직장을 구하는 것이 첫 번째 직장을 구하는 것보다 훨씬 쉽기 때문에요.)

완전히 원격 근무하는 회사라고 해서 무조건 문제가 되는 것은 아니지만, 상황을 더욱 어렵게 만들 수 있습니다. 주니어 엔지니어들에게는 가능한 한 오피스에서 일하는 직장을 찾으라고 권하고 싶습니다. 비공식적인 대화나 기술적인 잡담에서 많은 것을 배우기 때문입니다. 재택근무를 하고 있다면 이를 보완하기 위해 더 많은 노력이 필요하며 이를 성공적으로 해결한 사람들과 연락하여 조언을 구하는 것을 추천합니다. (그들은 분명히 존재합니다!)

또한 회사가 주니어 엔지니어를 고용할 때 단 한 명으로 시작하지 말 것을 권장합니다. 한 명을 고용할 거라면 두세 명을 고용하세요. 동료들과 함께 일한다면 고립감이나 두려움을 덜 느낄 수 있습니다.

우리 문제를 해결해 줄 사람은 아무도 없습니다

업계 전반에서 엔지니어들과 엔지니어링 매니저들이 이 문제를 자신의 일처럼 여겨 직접 나서서 해결하는 것이 상황을 바꾸는 유일한 방법이라고 믿습니다.

제가 아는 대부분의 회사에서 신입 엔지니어를 고용하고 훈련하는 프로그램을 운영하는 것은 누군가의 노력 덕분이었습니다. 엔지니어들 혹은 엔지니어링 매니저들이 필요성을 주장하고 자원을 확보하기 위해 노력했습니다. 그 후 프로그램을 설계하고 주니어 엔지니어들을 인터뷰하여 고용하며 그들에게 멘토를 붙여준 것이죠. 이는 특별한 프로젝트가 아니라 동기 부여된 경험 많은 엔지니어들이 충분히 할 수 있는 일이며, 그들의 경력에도 좋은 영향을 미칩니다.

재무 부서는 여기에 애쓰지 않을 것이고, 경영진도 개입할 가능성은 낮습니다. 엔지니어를 교체 가능한 자원으로 여기는 경향이 강할수록, 이러한 문제가 왜 중요한지 이해할 가능성은 낮아집니다.

AI는 우리의 모든 문제를 해결하고, 우리 대신 코드를 작성해 주지 않습니다. 설령 그렇다 하더라도 중요하지 않습니다. 코드 작성은 전문 소프트웨어 엔지니어가 하는 일의 극히 일부에 불과하며, 어쩌면 가장 쉬운 부분일지도 모릅니다. 훌륭한 팀과 우수한 엔지니어링의 기반을 이루는 변화를 이끌어 갈 수 있는 맥락과 신뢰는 오직 우리만 알고 있습니다.

훌륭한 팀이 곧 훌륭한 엔지니어를 만드는 방법입니다. 이를 엔지니어들과 엔지니어링 매니저들만큼 잘 아는 사람은 없습니다. 이제 우리가 나서서 그 중요성을 주장하고, 실제로 변화를 이루어야 할 때입니다.

October 2024

Part 3 of 6

개발자 생존 설명서 (feat. AI) Developer's Survival Guide (feat. AI)

Up next

소프트웨어 엔지니어로서 Ai 혁명에서 살아남기

희망이 아직 남아 있을까요?

More from this blog

나의 오픈 소스 시작 이야기

원문: TkDoDo, “My Open Source Origin Story“ 가끔씩 제가 받는 질문이 하나 있는데, 바로 오픈 소스와 리액트 쿼리(React Query)를 어떻게 시작하게 되었는지입니다. 저의 기본 원칙은 어떤 질문을 세 번 받으면 더 이상 답변할 필요가 없도록 질문에 대해 글로 쓴다는 것입니다. 하지만 이 질문은 주로 직접 만났을 때 받는 질문이라 글로 작성할 생각을 한 적이 없었습니다. 최근에 오프라인 컨퍼런스에 더 많이 참...

Jul 30, 2025
나의 오픈 소스 시작 이야기

이더넷이란?

원문: baeldung, “What Is Ethernet?“ 1. 소개 이 튜토리얼에서는 이더넷(Ethernet)과 이를 통해 이루어지는 데이터 전송에 대해 알아보겠습니다. 2. 이더넷이란? 이더넷은 근거리 통신망(LAN) 또는 광역 네트워크(WAN) 내에서 장치들이 데이터를 주고받고 통신하기 쉽게 만들어 주는 널리 사용되는 기술입니다. 컴퓨터, 프린터, 서버는 물론 스마트 홈 기기까지도 이더넷으로 연결됩니다. 가정이나 사무실처럼 제한된 공간...

Jul 20, 2025
이더넷이란?

포스트 개발자 시대

원문: Josh W. Comeau, "The Post-Developer Era" 2년 전 2023년 3월, "프런트엔드 개발의 종말"이라는 제목의 블로그 글을 발행했습니다. 이는 OpenAI가 GPT-4 쇼케이스를 발표한 직후였고, 당시 업계 분위기는 머지않아 인간 소프트웨어 개발자는 필요 없어지고 앞으로는 소프트웨어 개발을 AI가 전담하게 될 것이라는 전망이 지배적이었습니다. 저는 이런 주장에 회의적이었고 그 블로그 글에서 소프트웨어 개발...

Jul 10, 2025
포스트 개발자 시대

널리 사용되는 네트워크 프로토콜

원문: Subham Datta, "Popular Network Protocols" 1. 개요 이 튜토리얼에서는 가장 널리 사용되고 인기 있는 네트워크 프로토콜들을 소개합니다. 2. 네트워크 프로토콜 소개 의사소통과 정보 교환은 현대 사회에서 가장 중요하고 강력한 역량입니다. 컴퓨터 네트워킹이란 여러 대의 컴퓨터와 장치를 케이블이나 위성을 통해 서로 연결하여, 거리와 상관없이 정보·자원·데이터베이스 등을 공유할 수 있게 하는 것을 말합니다. 네...

Jun 20, 2025
널리 사용되는 네트워크 프로토콜

커맨드 라인에 편해지는 법

원문: Julia Evans, "What helps people get comfortable on the command line?" 가끔 커맨드 라인을 써야 하는 친구들과 이야기하다 보면 많은 이들이 여전히 터미널을 두려워하고 있다는 걸 느낍니다. 그럴 때마다 어떤 조언을 할지 잘 모르겠더라고요. 저는 워낙 오래전부터 터미널을 써왔기 때문이죠. 그래서 Mastodon에 이렇게 물어봤습니다. 최근 1~3년 사이에 터미널 공포(?)를 극복한 분...

Jun 10, 2025
커맨드 라인에 편해지는 법
C

CodeSnap

84 posts

한국어로 전달하는 웹 개발 번역 매거진