요약
AI 에이전트가 코드를 대신 써 줘도 설계 판단과 비판적 사고는 여전히 사람의 몫입니다.
개발자 피오트르 사르나츠키의 글입니다. Ruby on Rails를 만든 데이비드 하이네마이어 핸슨(DHH)은 코드를 직접 읽지 않고 AI 에이전트에게 Campfire Once를 Rust, Elixir, Go로 다시 짜게 했습니다. 저자는 그 결과물과 벤치마크를 하나씩 뜯어봤습니다.
왜 중요한가
- 프롬프트에 적지 않은 설계 결정은 AI가 동전 던지기처럼 임의로 정합니다.
- 그래서 언어별 성능 차이가 언어 때문인지, AI가 고른 설계 때문인지 가릴 수 없게 됩니다.
- 지표 하나만 보고 "Elixir가 동시성에 더 낫다"고 결론 내리는 흐름에 대한 경고이기도 합니다.
핵심 내용
- Rust 판은 하위 호환을 일부 버리고 CSRF 토큰(위조 요청을 막는 값)을 없앴으며, Redis 대신 프로세스 내부 큐를 썼습니다.
- Rust 판은 비동기 작업 안에서 블로킹 DB 호출을 써서 같은 스레드의 다른 작업까지 멈추게 했습니다.
- 응답을 받아야 다음 요청을 보내는 기존 벤치마크로는 사용자가 한꺼번에 몰리는 상황을 볼 수 없다고 지적했습니다.
- 초당 100건을 꾸준히 보내자 전달률은 Rust 약 14%, Elixir 약 60%였지만 Elixir는 POST 요청의 약 23%가 시간 초과됐습니다.
- Rust 채널 용량을 256에서 16384로 늘리면 전달률은 약 90%로 오르지만, 최대 지연은 11초에서 130초 넘게 늘었습니다.
HN 반응
- 기존 시스템을 옮기는 작업이라 생각의 90%는 이미 끝난 셈이고 AI에 가장 유리한 경우라는 지적에, 남은 10%가 가장 어렵다는 반론이 붙었습니다.
- 컴파일러 결과물을 안 읽게 됐듯 AI 코드도 안 읽게 될 것이라는 의견에는, LLM은 컴파일러와 달리 같은 결과를 보장하지 않는다는 반박이 이어졌습니다.
이 글을 보니 workslop(그럴듯해 보이지만 알맹이 없는 AI 결과물)은 맞서기가 참 어렵다는 생각이 또 듭니다. 만드는 데는 힘이 하나도 안 들고, 틀렸다는 걸 입증하는 데는 엄청난 노력이 드니까요.
"코드"에만 너무 초점이 맞춰져 있을 때가 있습니다. 이건 코드나 수치 문제만이 아닙니다. LLM이 내놓는 모든 "답"에 똑같이 적용됩니다. 전문가들은 자기 계보, 즉 어떤 스승 밑에서 배웠는지를 꼽는 경우가 아주 많습니다. 배운 내용의 세부와 관점이 사고방식을 이끌고, 문제를 붙잡을 때 쓰는 "손잡이"를 정해 주기 때문입니다. 대부분의 일에는 "올바른 방식"이 없고, 접근하는 방식들이 있을 뿐입니다. 자신은 어디에도 얽매이지 않고 자유롭게 흘러간다고 상상하는 건 초보나 하는 실수입니다! 이런 사고방식을 부추기는 건 사소한 예절을 깐깐하게 단속하는 사람과 같습니다. "팔꿈치!" 하면서 식탁에 팔꿈치를 올리지 말라는 게 곧 도리라고 굳어지는 식이죠. 말씀하신 대로 "만드는 데는 힘이 안 들고 반박하는 데는 엄청난 노력이 든다"는 점에, 걸린 게 큰 경우도 있습니다. 저는 예를 들어 인종차별이 정확히 이렇게 작동한다고 확신합니다. 마찰은 0이고, 흐름에 몸을 맡기고, 그게 자연스러운 거라고 우기는 식으로요...
이른바 https://en.wikipedia.org/wiki/Brandolini%27s_law 입니다.
브란돌리니가 신발을 신고 있을 때 마크 트웨인은 이미 지구 반대편에 가 있죠.
그 인용구의 출처 문제야말로 말 그대로 지구 반대편까지 가 있습니다: https://quoteinvestigator.com/2014/07/13/truth/
workslop을 만든 건 Claude가 아니라 커밋한 사람이라는 점을 분명히 하세요. 사람에게는 평판이 있고, 이런 결과물은 그 평판을 깎아 먹습니다.
전문가답게 하되, 그 사람이 뒷수습을 해야 하는 다른 사람들의 생산성을 훔치고 있다는 요지는 전달할 수 있습니다.
커밋이 너무 크거나 너무 빽빽하면 쪼개게 하고, 주석도 정리하게 하세요. 그러지 않으면 그냥 일을 못하는 겁니다. Claude가 아니라 그 사람이요.
두 마리 토끼를 다 잡을 순 없죠.
나비에-스토크스 방정식과 수학을 "푼다"는 물건이라면서, 이런 허드렛일 정도는 알아서 처리해야 하는 거 아닌가요?
이 경우엔 '인 로코 파렌티스'(in loco parentis, 부모를 대신하는 지위)를 들먹이는 게 맞다고 봅니다.
미안하지만 회사 방침이 그걸 AI로 하라는 거라서요.
기업 코드는 원래 대체로 형편없습니다. 저는 (LLM 이전부터) 오래도록 우리 은행 앱의 뻔한 버그를 곁눈질로 보면서, 눈에 안 띄는 버그는 얼마나 될까 궁금해했습니다. 옛날부터 이랬던 건 아닙니다(60년대 SABRE를 생각해 보세요).
하지만 그게 종형 곡선의 불룩한 중간입니다. 기업 코드 바깥에는 훨씬 더 심한 쓰레기가 널려 있습니다. 곡선 오른쪽 끝에는 깊이 고민해 만들고 오래 유지보수한 끝에 이 우주에서 가능한 만큼 방탄에 가까워진 것들이 있습니다. OS의 일부, 네트워킹 스택, 시계 같은 것들이요.
그런 것들이 그만큼 견고하고 충분히 범용적이기 때문에, 나머지 세상의 김이 펄펄 나는 쓰레기 더미 같은 코드가 어쨌든 돌아가는 겁니다.
여기서 맥락은 LLM이 번역한 시스템이라는 점, 그러니까 LLM에게 이상적인 사용 사례라는 점을 짚어 둘 만합니다. 생각의 90%는 이미 기존 시스템 개발자들이 해 놓은 상태였으니까요.
네, AI의 성공 사례는 대부분 포팅이거나, 구조를 이해하는 사람이 의도적으로 아키텍처를 깔아 놓고 AI는 그 위에 기능을 얹는 프로젝트에서 나오는 것 같습니다. 리눅스 배포판에 기능이나 드라이버를 추가하는 일은 토대가 이미 깔려 있어서 AI가 유독 가치를 내기 좋은 자리 같고요. 얼마 전에 에이전트 코드도 이런 아키텍처 토대가 없으면 엉킨 난장판이 된다는 글을 썼습니다. 관심 있는 분이 계실지도 모르겠네요: https://ljtn.github.io/epiq/blog/the-soft-fabric-of-agentic-code.html
LLM은 번역을 아주 잘합니다. 그래서 번역가가 AI 때문에 가장 먼저 일자리를 잃은 직업군에 들었던 거고요.
시나 예술적인 산문 번역은 분명히 형편없을 겁니다.
제 경험담인데, 이게 제 프로젝트에 엄청난 도움이 됐습니다. AI가 한 라이브러리나 프레임워크에서 다른 쪽으로 포팅하는 걸 거의 손 안 대고 한 번에 해내는 걸 보고 있어요. 예전에는 나중에 바꾸기 어려웠기 때문에 이런 결정을 아주 신중하게 따져 봐야 했습니다.
끝없이 토대 위의 토대입니다. 다만 차이는 사람에게는 현실이 강화학습 환경이라는 점이죠.
정말 좋은 지적입니다. 먼저 테스트로 현재 동작을 문서화해 두고, 그다음 하나씩 살펴보면서 방금 테스트 케이스에 박제해 버린 버그가 뭔지 가려내는 식으로 시작할 수도 있죠…
"이상적인 사용 사례"라니 참 대담한 소리네요. "10%"(글에서 지적한 문제를 말씀하시는 거라면)가 가장 시간과 노력이 많이 드는 부분이고(아니면 지금 고쳐야 하는 부분이고), "번역"의 "90%"를 이해하고 고치지 않고서는 그걸 할 수가 없습니다.
그쪽은 다른 분이 이상적인 사용 사례라고 한 곳에 여전히 과제가 남아 있다고 짚었을 뿐이고, 그게 바로 그분 요지였습니다. 동의하지 않으시니 하는 말인데, 그럼 이상적인 사용 사례는 뭐라고 보시나요?
지금 작업하는 시스템의 현재와 앞으로의 상태에 대해 충분한 정보에 바탕한 결정을 내릴 수 있을 만큼은 그 시스템을 이해해야 합니다.
코드를 읽지 않고도 넘어갈 수 있는 경우가 있고, 앞으로는 그런 경우가 더 흔해질지도 모릅니다. 하지만 지금은 저라면 코드를 읽거나(최소한 훑어보거나) 하고, AI에게 전부 떠넘기지는 않겠습니다.
"코드를 이해해야 한다"는 이 모든 논의를 보면 학부생 때가 떠오릅니다. 저는 꽤 나이 많은 분과 같이 컴퓨터 일을 했는데, 그분은 천공카드 시스템까지 다뤄 보신 분이었어요. 옛날 무용담을 언제나 기꺼이 들려주셨고, 우리는 그 얘기를 넙죽넙죽 받아 들었습니다.
그분이 제일 즐겨 늘어놓는 불만은 우리 세대가 컴파일러를 너무 믿는다는 거였어요. "컴파일된다고 끝난 게 아니야. 실제 어셈블리를 봐야 해. 컴파일러는 정말 비효율적일 수 있거든."
90년대 얘기입니다. 그 말에도 일리는 있었죠.
그런데 오늘날은요? 자바스크립트를 쓰는 사람 중에 실제로 실행되는 어셈블리 코드를 보는 사람이 몇이나 됩니까? 별로 없죠.
지금의 "코드를 이해해야 한다"가 그때와 똑같은 일의 반복은 아닐지 자꾸 생각하게 됩니다. 몇 년 뒤에는 생성된 Python이나 Ruby 같은 코드를 들여다보는 사람이 거의 없을지도 모르고요.
컴파일러는 어떤 LLM보다도 훨씬 결정적입니다. 이 두 상황이 정말 비교할 만한지 저는 회의적입니다.
LLM을 컴파일러에 비교하지 마세요. 사람들이 당신 의견을 바로 무시하길 바라는 게 아니라면요.
안 보는 거고, 봐야 합니다.
맞아요, AI는 빠진 부분을 그냥 지어냅니다. 이건 AI만 그런 게 아니라 우리도 마찬가지예요. 경험이 쌓여서 모호한 요구사항을 좁히려면 어떤 질문을 해야 하는지 알게 될 때까지는요.
저도 피곤하면 더 허술한 코드를 쓰고, 생각을 덜 하게 되고, AI한테 "그냥 해"라고 말하고 싶은 유혹이 더 커집니다. 그건 달라진 게 없어요. 이 새로운 "코드를 읽지 마라" 부류가 어디서 나왔는지 모르겠습니다. 그것도 실제 소프트웨어 엔지니어들이 하는 말이라니요. 그냥 지나친 흥분이라서 (바라건대) 곧 잠잠해질지도 모르겠고요.
아니면 그냥 지나친 단순화일 수도 있어요. 저도 이제는 코드를 전부 읽지는 않지만, 그래도 일부는 읽습니다. AI 에이전트에게 코드 리뷰 워크숍을 한다고 말하고, 파일 열 개를 무작위로 골라 하나씩 같이 살펴보자고 해 보세요. 흔한 안티패턴을 검토해서 코딩 표준에 넣어 달라고 하고요. 그러고 나면 그 표준에 맞춰 코드를 리뷰하고 고치는 걸 1차로 AI에게 시킬 수 있습니다. 코드를 점검하려면 여전히 직접 리뷰해야 하겠지만, 리뷰를 AI와 적극적으로 협업하면 적어도 부담은 좀 덜고 조금은 더 재미있게 할 수 있죠.
저는 이게 그냥 '다른 종류의 피곤함'이라는 걸 배우는 중입니다. AI 덕분에 어떤 일은 훨씬 효율적이 됐고, 효율과 신중함 사이에서 고르는 일도 마찬가지입니다. 이제는 원하면 아주 미시적인 수준에서 그 선택을 아주 빠르게 할 수 있습니다. 그래도 피로는 있어요. 그냥 다른 종류의 피로일 뿐입니다. 여전히 생각을 많이 해서 지칩니다. 노력을 들일지 말지는 여전히 선택할 수 있고, 그 선택은 여전히 차이를 만듭니다. 그저 다른 종류의 어려움일 뿐이에요. 그렇다고 두 손 들고 내 일은 이제 어렵거나 힘든 노동이 포함되면 안 된다고 선언하는 게 답은 아니고요.
코드를 읽는 건 AI 기업들의 수익에 좋지 않죠. 코드를 읽어야 하는 프로그래머가 필요하다면, 노동을 완전히 대체한다는 서사를 만들 수 없으니까요. 그렇다고 LLM 출력을 리뷰가 필요 없을 만큼 좋게 만들 진짜 해법이 있는 것도 아니고, 그래서 지금 이 상황이 된 겁니다.
아, 그건 저도 충분히 압니다. 제가 이해가 안 되는 건 DHH 같은 사람이 정말로 코드를 읽을 필요가 없다고 생각하느냐는 거예요. 그게 진심이라면요. 그 사람은 세상 물정 모르는 경영진이 아니잖아요.
글 대부분은 제게 어려웠지만, 핵심은 이거라고 생각합니다:
프롬프트가 충분히 구체적이지 않으면 많은 결정이 동전 던지기가 된다.
AI를 쓰더라도 무엇을 시키고 싶은지는 여전히 알아야 합니다. 프로젝트 매니저가 팀에 불완전한 요구사항을 주면 결과가 이와 비슷할 수 있습니다.
동전 던지기를 전부 없앨 만큼 구체적인 프롬프트를 쓰는 건 그냥 코드를 직접 쓰는 겁니다.
그 둘 사이에는 천 리 길이 있습니다. "zig 스타일의 평탄한 AST를 쓰는 레지스터 기반 VM을 작성해"는 실제로 그걸 짜는 것보다 훨씬 적은 일입니다. 필요한 건 그런 종류의 지시예요.