한때 자랑스럽던 프로덕션 수준의 Rust 코드 3,000줄을 삭제한 이유와, AI 에이전트 시대에 언어 선택의 비용-편익이 어떻게 바뀌고 있는지에 대한 이야기.
지난 화요일, 나는 Rust 코드 3,000줄을 한꺼번에 삭제했다. 죽은 코드도 아니고, 기술 부채도 아니었다. 프로덕션급이고, 테스트도 잘 되어 있고, 빌림 검사기(borrow checker)도 통과한 코드였다. 나는 그 코드를 진심으로 자랑스러워했다.
그걸 지운 이유는, 나를 느리게 만들고 있었기 때문이다.
나는 생업으로 영지식 증명(Zero-Knowledge Proof) 인프라를 만든다. 블록체인. 암호학. 전부 다. 나는 대부분의 개발자가 평생 동안 다루게 될 것보다 훨씬 많은 Rust를 ‘대량으로’ 작성하고, 디버깅하고, 출시해 왔다. 나는 리팩터링을 위해서, 개선을 위해서, 더 타이트하게 만들기 위해서 Rust를 대량 삭제한 적도 있다.
하지만 이번은 달랐다. 이번에는 AI 에이전트가 그걸 전부 Go로 다시 써버렸다. 4분 만에.
나는 새로운 서비스 컴포넌트를 만들면서 AI 에이전트와 페어링하고 있었다. 특별할 것도 없었다 — RPC 핸들러, 직렬화 로직, 기본적인 상태 관리. 백엔드에서 늘 하는 밥벌이 업무.
Rust로라면 반나절은 잡았을 것이다. 로직이 어려워서가 아니다. 의식(세리머니) 때문이다. 라이프타임 애너테이션. 트레이트 바운드. async와 Pin<Box<dyn Future>>가 합쳐질 때 나타나는 흑마법. 그리고 내가 실수로 내 발등을 쏘지 않게 하려고 빌림 검사기가 거행하는 성스러운 의식.
에이전트는 Go로 작성했다. 4분. 컴파일 됐다. 테스트 통과. 배포 완료.
나는 터미널을 멍하니 바라보다가, Rust 버전을 봤다 — 이틀 동안 “거의 다 됐는데”라고 말하던 그 버전. 더 깔끔했나? 그렇다. 더 안전했나? 기술적으로는. 하지만 Go 버전은 이미 프로덕션에 올라가 있었다. 이미 요청을 처리하고 있었다. 이미 가치를 만들고 있었다.
나는 3,000줄을 드래그로 잡고, 삭제 키를 눌렀다. 아무 감정도 없었다.
아니 — 그건 거짓이다. 더 빨라진 느낌이 들었다.
Rust 커뮤니티에서 아무도 소리 내 말하고 싶어 하지 않는 사실이 있다:
Rust의 전체 가치 제안은 인간 프로그래머를 위해 설계됐다.
빌림 검사기는 인간이 메모리 해제를 까먹기 때문에 존재한다. 라이프타임은 인간이 참조를 추적하지 못하기 때문에 존재한다. 타입 시스템이 엄격한 건 인간이 새벽 2시에 레드불 세 캔을 마시고 멍청한 코드를 쓰기 때문이다.
AI 에이전트는 새벽 2시에 지치지 않는다. 메모리 해제를 잊지 않는다. 참조를 놓치지 않는다. Rust의 복잡성을 정당화해주던 정교한 안전망은, 코드를 쓰는 종(種)이 빠르게 ‘그 종’이 아니게 되어 가는 상황에서 인간을 위해 만들어진 것이다.
나는 Rust가 나쁘다고 말하는 게 아니다. Rust는 걸작이다. 내가 말하는 건 비용-편익 방정식이 근본적으로, 되돌릴 수 없게 바뀌었고 — 대부분의 Rust 개발자는 빌림 검사기와 대량으로 싸우느라 고개를 들어 주변을 볼 여유가 없다는 것이다.
AI 에이전트가 코드를 쓸 때, 무엇보다 중요한 건 세 가지다.
첫째, 반복(이터레이션) 속도. 아이디어에서 작동하는 코드, 배포 가능한 산출물까지 얼마나 빨리 갈 수 있나? 컴파일 에러 하나, 라이프타임 애너테이션 수정 하나, 트레이트 바운드 불일치 하나가 토큰을 태우고 시간을 태운다. Rust 컴파일러는 철저하고, 그래서 느리며, 피드백 루프가 느리고, 그래서 에이전트도 느려진다.
둘째, 패턴의 예측 가능성. AI 에이전트는 단순하고 반복 가능한 패턴을 가진 언어에서 놀라울 정도로 잘한다. Go는 키워드가 25개 정도다. Rust는 40개가 넘고, 타입 시스템은 튜링 완전(Turing complete)이라 할 만큼 표현력이 크다. 복잡성이 커질수록 에이전트가 환각(hallucination)을 일으키거나 길을 벗어나거나, 그럴듯해 보이지만 컴파일되지 않는 코드를 만들며 시간을 낭비할 표면적이 커진다.
셋째 — 그리고 이게 핵심이다 — 폐기 가능성(disposability). 에이전틱(agentic) 시대에는 코드가 점점 더 소모품이 된다. 더 이상 5년 동안 코드베이스를 애정을 담아 가꾸지 않는다. 원하는 걸 설명하면 에이전트가 생성하고, 배포하고, 다음 주 화요일 요구사항이 바뀌면 다시 생성한다. Rust는 장기적인 정합성에 집착할 정도로 최적화되어 있다. 하지만 대부분의 코드 수명은 ‘년’에서 ‘주’, ‘일’로 압축되고 있다. 렌터카를 타면서 페라리 정비 비용을 내는 셈이다.
나는 한 달 동안 추적해 봤다. 같은 작업, 같은 복잡도에서:
4배 느리다. Rust가 나쁜 언어라서가 아니다. Rust는 에이전트가 매번 토큰, 재시도, 낭비되는 컴파일 사이클로 비용을 치르게 만드는 의식을 요구하기 때문이다 — 매번, 예외 없이.
반론이 나올 걸 안다. 나도 Rust 세금을 정당화하려고 이런 주장을 수백 번 해 왔다. 메모리 안전성. 정합성 보장. 제로-코스트 추상화. 나는 그 피치를 외울 정도로 알고, 컨퍼런스에서 대량으로 전달해 왔다.
그래서 직설적으로 말하겠다. AI 에이전트가 메모리-불안전한 코드를 만든다면, 문제는 언어가 아니다. 문제는 에이전트다.
현대의 AI 에이전트가 Go나 TypeScript를 쓸 때 Rust가 막기 위해 만들어진 종류의 버그는 거의 만들지 않는다. 버퍼 오버플로. 해제 후 사용(use-after-free). 데이터 레이스. 이런 건 근본적으로 인간의 실수다 — 제한된 작업 기억, 피로, 산만함, 그리고 인간의 뇌가 단기 기억에 동시에 7개 정도밖에 못 담는다는 사실에서 비롯된다. AI 에이전트는 그런 제약이 없다. 산만해지지 않는다. 컨디션 난조도 없다.
AI 에이전트가 실제로 만들어내는 버그는 논리 오류다. 잘못된 비즈니스 룰. 오해한 요구사항. 도메인 추론에서의 엣지 케이스. 그리고 불편한 진실이 있다: Rust의 타입 시스템은 그중 정확히 ‘0개’를 잡아준다. 그걸 잡는 건 무엇인가? 빠른 반복이다. 빠른 피드백 루프다. 빠른 재배포다. 배포하고, 관찰하고, 고치고, 다시 배포하는 것. Rust가 느리게 만드는 모든 것들이다.
“Rust를 대량 삭제한다”는 말이 현실보다 더 드라마틱하게 들릴 수 있으니, 정확히 말하자.
나는 Rust를 핵심 암호 프리미티브에는 계속 쓸 것이다. ZK 회로 로직. 합의(컨센서스) 핵심 실행 경로. 단 하나의 버그가 API 엔드포인트의 500 에러가 아니라 — 블록체인에서 수백만 달러가 증발하는 의미가 되는 모든 것들. 이런 영역에서 Rust는 의식이 아니다. 생존이다.
나는 그 외의 모든 것을 Rust 밖으로 옮기고 있다. 서비스. 툴링. CLI. 오케스트레이션 레이어. API 서버. 데이터 파이프라인. 모니터링. Rust의 보장이 필요하지 않지만 매일 Rust 세금을 내고 있는 대부분의 코드들.
결과는? 내 Rust 코드는 오히려 더 좋아졌다. 왜냐면 더 적어졌기 때문이다. 남은 Rust는 진짜로, 실존적으로 Rust가 필요한 코드다. 어려운 암호. 영지식 회로. 빌림 검사기가 속도 방지턱이 아니라 — 절벽 가장자리의 가드레일인 경로들.
그 외의 것들은? 에이전트에게 맡겨라. 그들이 가장 빨라지는 언어로.
2년 안에, 새로운 백엔드 서비스의 기본 언어는 ‘언어’가 아닐 것이다. AI 에이전트가 가장 유창하게 구사하는 것이 될 것이다. 그리고 그건 거의 확실히 Rust가 아닐 것이다.
Rust는 살아남을 것이다. 오히려 자기 영역에서는 번성할 것이다 — 어셈블리가 펌웨어에서 번성하듯. COBOL이 은행에서 번성하듯. Fortran이 과학 컴퓨팅에서 번성하듯. 존중받고. 필수적이며. 그리고 점점 더 ‘액션이 있는 곳’은 아닐 것이다.
지금 대량 삭제하는 엔지니어들 — 좋아하는 언어에 대한 매몰 비용 애착을 내려놓고 에이전틱 워크플로를 최적화하는 사람들 — 은 그렇지 않은 사람들보다 4배 더 빠르게 배포할 것이다.
나는 Rust를 쓰는 걸 대량으로 사랑했다. 내가 사랑하던 Rust를 대량으로 삭제했다.
하지만 나는 배포하는 걸 더 사랑한다.
나는 블록체인을 위한 영지식 증명 시스템을 만드는 ZK 인프라 엔지니어다. 지금도 매일 Rust를 쓴다 — 다만 더 적게, 그리고 진짜로 중요한 곳에서만. 나머지는 에이전트에게 맡긴다.