이제 개발자 다 없어지나요?

자연어로 코딩한다는 것

by 고래



1.


개발을 하다 보면 종종 그런 궁금증이 일곤 했다. 영어를 모국어로 하는 사람들은 프로그래밍 언어를 좀 더 쉽게 배우고, 문법도 쉽게 받아들이고, 코드를 쉽게 읽고, 쉽게 쓸까? 코드를 작성하는 것도 결국 매우 논리적인 글쓰기의 일종이라는 점에서 보면, 영어가 모국어인 경우 생각을 코드로 옮기거나, 코드를 생각으로 치환하는 게 좀 더 유리하리라고 본다. 대부분의 프로그래밍 언어가 영어 단어로 이루어져 있고, 프로그래밍 언어들의 문법은 그 개념을 설명할 수 있는 영단어와 영문법을 일부 차용해 만들어지기 때문이다.


반면 영어와 전혀 다른 언어체계를 가진 우리 한국인들은 프로그래밍 영역에서 필연적으로 손해를 볼 수밖에 없는데, 한국어로 한 논리적인 생각과 "영어적 표현"간의 변환이 필요하기 때문이다. "읽기 쉬운 코드"를 작성하기 위해서는 내 생각을 표현할 수 있는 적절한 영단어를 찾아야 하고, 이 코드가 영어로 어떻게 읽힐까도 같이 고민해야 하는데, 아무래도 모국어가 아니다 보니 적절하지 않은 단어와 문법적으로 맞지 않는 글을 쓰기 쉽다.


예를 들어, "산수 문항 계산이 맞으면 총 점수에다 10점을 더하고 틀리면 10점을 뺀다"를 코드로 옮긴다고 생각해 보자. 영어라는 언어에서 동사와 명사를 잘 구분하지 못하고, 정확한 단어를 사용하지 못한 채로 프로그래밍 언어로서의 문법만 적용하면 이런 코드를 짜게 된다.


if calculate == true {
pointAddition(point: 10, score: score)
} else {
pointSubtraction(point:10 score: score)
}


이러면 당연히 코드 읽기가 만만치 않다. 언어로서의 이점을 하나도 못 누리고 오로지 논리적인 구조에 기대어 작성된 코드이므로 읽기만 해서는 로직을 이해할 수 없다. 게다가 이 코드만 봐서는 이해가 안 되고 세부 함수 구현까지 찾아보고 로직을 분석해야 한다. 아마 이 코드를 이해하기 위해서는 이런 과정을 거칠 것이다.


분기조건이네, 만약 calculate == true 참이면 더하기를 수행하고, 아니면 빼기를 수행하네. calculate == true가 무슨 뜻이지? 계산을 했다는 건가? 아, 계산 값이 맞다는 뜻으로 썼나 보구나. 참이면 더하기 연산을 하네 10과 스코어를 넘겨주니까 두 개를 더하는 거겠지, 빼기는 10에서 스코어를 빼는 건가? 이상한데?, 함수로 가서 보자.. 아 스코어에서 10을 빼는 거구나... 스코어가 뭐지? 아 총 점수인가보다.. 아 그니까 계산이 맞으면 총점수에 10점 더하고 아니면 빼는 거구나.


반면 영어가 모국어라면, 프로그래밍 언어 자체가 영문법을 잘 녹일 수 있는 구조로 되어있으므로 생각이 곧 pseudocode가 되어 코드로 옮기기 쉽고, 코드를 읽어서 로직을 이해하기도 비교적 쉽다.


"if the calculation is correct, add ten points to the total score, otherwise subtract 10 points from the total score. "


if isCalculationCorrect {
add(10, to: totalScore)
} else {
subtract(10, from: totalScore).
}



2.


그러면 영어만 할 수 있으면 프로그래밍을 할 수 있는가? 그렇지 않다. (아니.. 제 말 뭔지 아시죠?) 프로그래밍 언어는 영어가 아니다. 영단어와 일부 문법을 차용했을 뿐 고유의 문법을 가진다. 프로그래밍 언어의 문법들은 주요 로직을 함축하고 있다. 그 함축된 로직을 하드웨어가 실행할 수 있도록 해석하는 게 바로 컴파일러다. 프로그래밍 언어는 하드웨어의 발전에 따라 그 하드웨어를 조작할 수 있는 로직을 함축하도록 진화해 왔다. 회로를 연결할지 말지(0 or 1)만 표현할 수 있던 기계어부터, 레지스터 단위의 간단한 연산을 표현할 수 있었던 어셈블리어, CPU나 메모리를 조작하는 로직을 작성할 수 있었던 저수준언어(C), 그리고 하드웨어를 직접 조작하는 것에서 벗어나 추상적인 로직을 표현할 수 있게 된 고수준 언어. 생각해 보면 프로그래밍 언어는 계속 자연어(주로 영어)에 가까워지고 있었다.


내가 이 시점에 갑자기 왜 이런 이야기를 하게 되었냐면.. 그러니까 결국 요즘 돌아가는 상황을 보면.. LLM의 발전으로 프로그래밍 언어의 추상화 정도가 아주 높아져서 누군가의 농담처럼 진짜 영어/한국어 같은 자연어가 프로그래밍 언어가 된 것 같아서다. 프로그래밍 언어가 발전하면서 그에 맞는 문법을 해석할 수 있는 컴파일러들이 새로 만들어진 것처럼. 결국 LLM 모델들은 각 회사들이 나름대로 만들어본 자연어용 컴파일러나 다름없는 것이다. 그리고 C언어용 IDE, Java용 IDE가 나왔던 것처럼, 자연어용 IDE가 나온 것이 클로드 코드, Codex, Antigravity, Kiro인 셈이고.


LLM은 기본적으로 거대한 가중치의 모음과 확률게임을 섞어놓은 구조다. 그러니까 결국 수학적 정의에 기반해 그래프를 그린 게 아니라, 데이터 기반으로 점을 다 찍어서 그래프의 전체 형상을 유추하고 있다는 말이며, 약간의 확률(이걸 인간들의 예상치 못한 상상력이라고 봐야 할까?)을 더해서 다양성을 부여하고, 오차를 줄여나가고 있다는 말이다. 다시 말해서 정확한 컴파일 규칙을 찾은 게 아니라 데이터 기반으로 컴파일 규칙을 때려 맞추고 있는 것이다.. 그니까 좀 더 수치적 접근인데 데이터 양이 어마어마해서 실제 그래프와 거의 유사한 거지..



3.


이쯤에서 한국인 개발자들이 유독 신이 난 이유도 좀 생각해 보게 되는데.. 이제야 한국인들은 우리의 언어체계에 맞는 프로그래밍 언어와 컴파일러가 생긴 셈이다. 내 생각을 그대로 코드로 옮겨줄 수 있는 도구가 생겼으니 신나지 않을 수가... ㅠㅠ 생각을 바로 쓰기만 하면 된다니(아님)... 최고 아니냐. 물론 LLM 모델 학습은 대부분 영어로 되었을 테니 내부적으로는 한국어와 영어 간 번역 계층이 있을 거고, 그래서 완벽한 네이티브 컴파일러로 볼 수는 없겠지만 그래도 이게 어디야. 정말 비약적인 발전이다. 솔직히 변수명 정하는 게 제일 짜증 나잖아요..


물론 프로그래밍 언어를 순수한 영어와 비교하기에는 무리가 있듯이, 프로그래밍 언어로서의 자연어도 우리가 일상에서 쓰는 순수한 자연어와는 좀 거리가 있을 것이다. 영어가 모국어면 코드 쓰기가 쉬워 보이는 것처럼 이제 "언어"를 쓰는 사람이라면 누구나 프로그래밍을 할 수 있을 것 같다고 착각할 수 있는데 (물론 상당히 좋은 데이터기반 컴파일러(LLM)를 갖게 되었으므로 일부 사실이긴 하지만) 프로그래밍 언어는 필연적으로 하드웨어가 실행할 수 있는 로직을 함축해야만 한다. 따라서 소프트웨어가 복잡해질수록 더 논리적인 구조가 필요하고, 자연어가 가진 모호함을 잘 정제하는 작업이 필요하다. 이는 LLM이 여타 컴파일러들과 달리 결정론적이지 않기 때문에 더 중요하다.


그래, 그게 흥미로운 포인트다. 기존 컴파일러들에서는 같은 입력에 같은 출력이 나오지 않으면 버그다. 디버깅 대상이 명확하다. 코드가 틀렸거나, 컴파일러가 틀렸거나. 코드가 틀렸으면 내가 고쳐야 되고, 컴파일러가 틀렸으면 언어 문법을 수정해야 한다. 근데 LLM은? LLM은 같은 입력에 대해 항상 같은 출력이 나오지 않는다. 이건 버그일까? 지금은 그럴 수도 있고 아닐 수도 있다. 확률이 들어가니까. 그러니까 최대한 확률에 영향을 받지 않는 결정론적인 코드를 얻고 싶다면 내 의도를 아주 정교하게 전달할 수 있어야 한다. 의심의 여지가 없도록. 지금 다들 그런 자연어 문법이 어떤 형식일까를 탐색하는 중인 것 같고. 그러니까 지금 전 세계 프로그래머들이 자연어 코딩컨벤션을 정하고 있는 셈이다.



4.


결국 원하는 게 명확해야 한다. 아주 명확하고 상세한 spec을 글로 정의하고, 요구사항에 모순이 없는지 체크해서 문서로 남겨야만 LLM이 버그 없는 코드를 뱉어낼 수 있다. 명세를 아주 상세화 하고.. 아주 작은 단위의 명세로 나눠서 AI에게 작은 책임범위의 명세를 던져서 코드를 만들게 해야 할 거다. 그래서 명세가 의미하는 바를 적확하게 기술하고..


아니 이거 근데 이거 익숙하지 않나? 이게 코딩 아닌가..? 사실 매일 하던 일이다. 기획 의도를 정교하게 파악해서 코드로 담아내던 거.. 그동안 문서화를 하지 않고 머리로만 대충 이해하고 넘어갔던 그거. 그래서 버그의 원인이 되는 그거. 대충 이해하고 짜면 대충 짠 코드가 나오는 거지 머.. 그니까 결국 자연어의 탈을 쓴 프로그래밍 언어로 코딩을 해야 하는 셈이지.. 생각해 보면 너무 당연한.. 원래도 잘하던 사람들은 그걸 잘했다. 기획자랑 디자이너랑 대화해가면서 원하는 게 뭔지 구체화하고, 구현할 때는 함수를 잘게 쪼개고 코드만 읽어도 의도를 명확하게 알 수 있게 하고.. 근데 이제 그게 자연어 레벨로 추상화된 거지. 자연어 레벨로 디버깅을 잘할 줄 알아야 되는 상황이 온 거고.


지금 무수히 등장하는 기능들과 노하우 같은 정보들에 FOMO가 오기 쉬운데.. 자세히 들여다보면 개발자라면 사실 다 익숙한 개념들이지 않나 싶다.

우리는 언제나 공통된 규격(like mcp)으로 다른 서비스를 연결해서 써왔고, 누군가 잘 만들어놓은 함수 셋을 모아둔 library(skills)를 임포트 해서 쓰곤 했으며, 각 로직이 담당하는 역할을 명확히 나누어 책임을 분리했고(agents), 처리량이 많은 경우엔 async 하게 병렬로 로직이 돌아가게 만들었고(multi-agents), main thread가 busy 하지 않게 관리하면서 주요 로직을 관리했다.(orchestration)


context 관리는 물론 내 머리통의 기억력 관리나 다름없고.... 까먹으면 일 누락하는 거지 뭐.. 세션 바뀌면 완전히 잊는다는 게 좀 뼈아프긴 하지만.. 그래서 안 까먹게 메모를 남겨두는 거고.. 자연어로 작성되었다는 게 다를 뿐이지.. 코드레벨에서는 사실 늘 하던 것 아닌가 싶은.. 느낌.. 대신 이제.. 굉장히 많은 오픈소스가 있는.. 근데 쓰레기 오픈소스도 너무 많은... ^^.. 이 춘추전국시대가 좀 지나고 나면 이 전쟁에서 이긴 진시황이 누군지 알게 될 것임.



5.


그래서 이제 개발자 다 사라지나요?


글쎄, 프로그래밍 언어의 진화과정에서 항상 그래왔듯, LLM의 발전이 이 분야의 완전한 종말을 의미하지는 않을 것 같다. 본질은 바뀌지 않았으므로.. 추상화 계층이 높아져 문법의 허들이 낮아질 때마다, 그 프로그래밍 언어 사용자들은 폭발적으로 늘고 서비스 수도 어마무시하게 많아졌지만, 그 모두가 좋은 프로그래머가 되고 좋은 서비스가 되지는 않았다. 언제나 중요한 것은 문제가 뭔지 아는 능력이었다. 비즈니스 도메인에서 진짜 풀어야 하는 문제를 찾아내는 능력. 그리고 문제를 해결하기 위해 논리적으로 문제를 풀어나갈 수 있는 능력. 이건 변하지 않았고 변하지 않을 거다. 개발 진입장벽이 더 낮아졌지만, 아이러니하게도 좋은 개발자를 찾는 건 더 어려워질 것이다. 코드를 직접 작성하는 사람이 줄어들수록 자연어 디버깅만으로 해결되지 않는 문제를 시스템 레벨로 진짜 디버깅할 수 있는 사람들은 더 희소해지겠지.


아무튼 다시 처음으로 돌아와서. AI 툴들을 쓰다 보니 확실해졌다. 영어를 모국어로 했던 사람들은 개발하기가 더 수월했을 것이다. 이걸 지네들만 누리고 있었다니. 부럽기 그지없다. 급변하는 시대를 따라잡을 수 없을까 봐 두려우면서도 얼른 LLM이 더 발전해서 한국어 뉘앙스 하나까지 다 알아먹으면 좋겠기도 하다.


나중엔 진짜 한마디로 해결될지도 모르지.


ㅎ ㅐ 주 ㅓ




+

아니 그러고 보니 높으신 분들은 이미 자연어 프로그래밍 하고 있었네. 해조! 한마디 하면 휴우먼 인텔리전스가 알아서 맥락 파악하고, 모호한 부분은 스스로 추론해서 채우고, 결과물 뱉어냈자너. 물론 가끔 hallucination도 하고, context window 초과하면 앞에 말한 거 까먹기도 하고, 같은 프롬프트에 다른 결과물 내놓기도 하고..ㅋㅋㅋㅋ

아 내가 그들의 AI였다니…


모호하게 시키면 돈 더내게 해야 됨