AI가 함수형 프로그래밍에 어려움을 겪는 이유
요약
AI가 생성하는 코드는 함수를 분리하고 모듈화하려는 경향이 강하지만, 이는 실제 복잡성을 해결하기보다 얕은 추상화를 만드는 데 그친다는 분석입니다. 이로 인해 개발자는 코드의 흐름을 이해하기 위해 너무 많은 파일을 열어야 하는 비효율성이 발생합니다. 실제로 EMNLP 2024 연구 결과는 모듈성 자체가 코드 생성 성능 향상의 핵심 요소가 아님을 보여주었습니다.
핵심 포인트
- AI 코드는 함수 분리를 선호하나, 이는 깊은 추상화가 아닌 '얕은 추상화'에 가깝다.
- 모듈화된 코드가 반드시 복잡성을 제거하는 것은 아니며, 단지 이동시킬 뿐이다.
- 개발 과정에서 과도한 모듈성은 코드 이해도를 떨어뜨리고 탐색 비용을 증가시킨다.
- 최신 연구(EMNLP 2024)는 모듈성 자체가 코드 생성 성능의 핵심 요소가 아님을 시사한다.
AI가 생성한 코드에서 반복적으로 발견되는 패턴이 있습니다. 비교적 간단한 것을 구현하도록 요청하면 다음과 같은 코드를 받게 됩니다:
const result = await processRequest(request);
async function processRequest(request) {
...
모든 함수는 고립되어 있을 때는 완벽하게 합리적으로 보입니다. 하지만 그 함수들 대부분은 거의 아무것도 추가하지 않습니다. 우리는 두 개의 연산을 코드베이스를 안내하는 작은 투어로 만들었습니다.
매우 모듈화되어 있습니다. 벌써 지쳤습니다.
물론, AI가 함수형 프로그래밍에 문제가 있다고 말하는 것은 기술적으로는 공정하지 않습니다. 함수형 프로그래밍 자체가 문제는 아닙니다. 문제는 LLM이 **얕은 추상화(shallow abstractions)**를 만드는 데 비정상적으로 편안함을 느낀다는 것입니다. 즉, 다른 함수를 호출하는 것이 유일한 목적을 가진 함수들입니다.
그리고 추상화는 공짜가 아닙니다. 모든 함수는 또 다른 이름, 점프해야 할 또 다른 장소, 머릿속에 유지해야 하는 또 다른 인터페이스를 도입합니다. 데이터가 어디서 오는지 이해하고 싶었는데 이제 네 번째 파일을 열고 있습니다.
같은 작업. 열어야 할 문만 더 많다.
John Ousterhout는 _얕은 모듈(shallow modules)_과 유사한 문제를 설명합니다. 이는 인터페이스가 실제로 숨기는 복잡성에 비해 큰 추상화입니다. 그것들은 실제로 복잡성을 제거하지 않습니다. 단지 이동시킬 뿐입니다.
AI는 왜 이렇게 할까요?
LLM이 본질적으로 함수형 또는 모듈화된 코드를 _선호_한다는 증거는 많지 않습니다.
실제로 EMNLP 2024 연구에서는 여러 코드 모델에 걸쳐 기능적으로 동등한 코드의 모듈식 버전과 비모듈식 버전을 비교했습니다. 그들의 결론은 흥미로웠습니다. 모듈성 자체가 코드 생성 성능을 향상시키는 핵심 요소는 아니었습니다.
코드 생성 시 모듈성 추구의 영향 재검토 - ACL Anthology
따라서 문제는 모델이 무엇을 원하는지에 관한 것이라기보다는 우리가 그것에게 무엇을 생성하도록 요청하는지에 관한 것일 수 있습니다. 우리는 AI에게 끊임없이 다음과 같은 코드를 작성하라고 지시합니다:
- 깔끔한 (clean)
- 모듈성 있는 (modular)
- 재사용 가능한 (reusable)
- 유지보수성이 좋은 (maintainable)
- 단일 책임 원칙을 따르는 (single-responsibility)
이것들은 좋은 목표입니다. 하지만 기계적으로 충족하기는 믿을 수 없을 만큼 쉽습니다:
이 다섯 줄을 가져와 이름을 붙여주세요.
여기 있습니다. 깔끔한 코드입니다. 우리 모두 퇴근할 수 있겠네요.
모델은 또한 우리가 코드를 경험하는 방식대로 경험하지 않습니다. 또 다른 헬퍼 함수를 만드는 것은 모델에게 거의 비용이 들지 않습니다. 6개월 후에 그 결과를 유지보수해야 하는 인간은 그것을 탐색하고, 이 헬퍼가 특별한 작업을 수행하는지 알아내야 하며, 결국 아니요, 단지 다음 것을 호출한다는 것을 발견합니다.
그리고 우리는 기능적으로 올바른 LLM 코드가 여전히 구조적 품질 문제를 가질 수 있다는 실제 증거를 얻기 시작하고 있습니다.
두 불빛 모두 초록색입니다. 6개월 후에 디버깅하고 싶은 것은 어느 쪽일까요.
ICSE 2026 연구는 LLM이 생성한 코드가 코드 스멜(code smells)을 포함할 가능성을 측정했으며, 그 결과 생성 전략, 모델 아키텍처, 모델 크기, 그리고 중요하게도 **프롬프트 공식화(prompt formulation)**가 이러한 스멜에 영향을 미친다는 것을 발견했습니다.
LLM이 생성한 코드의 스멜 측정, 설명 및 완화를 위한 인과적 관점 - Microsoft Research
microsoft.com
또 다른 2026년 연구에서 실제 저장소(repositories)를 분석한 결과, AI가 생성했을 가능성이 높은 코드는 상당한 **저장소 내 코드 복제(intra-repository code cloning)**를 보이는 것으로 나타났습니다. 이는 기본적으로 동일한 저장소 내에 반복되는 코드입니다. 이는 로컬적으로 합리적인 코드를 생성하는 것이 반드시 전역적으로 더 깨끗한 시스템을 만든다는 것을 의미하지 않는 또 다른 신호입니다.
[arXiv:2607.01867] 코드 저장소 내 LLM 생성 코드 및 주석에 대한 탐색적 연구(An Exploratory Study on LLM-Generated Code and Comments in Code Repositories)
LLM을 소프트웨어 개발에 사용하는 것은 코드 생성 및 요약과 같은 작업에서 점점 더 광범위해지고 있습니다. 대형 기술 기업들의 보고서에 따르면, 이들 회사의 코드 중 약 20%에서 30%가 LLM에 의해 생성된 것으로 나타났습니다. 하지만, LLM이 생성한 코드와 주석의 실제 사용 가능성에 대해서는 여전히 의구심이 남아 있습니다. 예를 들어, 생성된 코드를 디버깅하는 데 더 많은 시간이 필요하다거나, 생성된 주석이 부자연스럽다는 등의 우려가 존재합니다. 본 논문에서는 LLM에 의해 생성되었을 가능성이 있는 코드와 주석 및 그 특성, 회사에서 관리하는 저장소와 커뮤니티에서 관리하는 저장소 간의 차이점, 그리고 LLM 생성 코드와 관련된 버그 발생 가능성을 연구합니다. 우리는 2021년부터 2025년까지 활동 중인 회사 및 커뮤니티 관리 저장소를 다양한 도구와 기법을 사용하여 광범위하게 실험했습니다. 이들 도구는 LLM에 의해 생성된 코드를 탐지하고 주석을 탐지하는 데 사용되었습니다. 저희의 탐지기 기반 대리 분석(detector-based proxy analysis) 결과, LLM이 생성했을 가능성이 있는 코드는 시간이 지남에 따라 감소했으며 테스트 케이스에서 자주 나타났으나, 주석은 비교적 안정적인 수준을 유지한다는 것을 시사합니다. 또한, 대리 결과는 LLM이 생성했을 가능성이 있는 코드가 상당한 저장소 내 코드 복제를 보이는 반면, 주석은 문법적으로 올바른 문장의 비율이 상대적으로 낮다는 것을 추가로 시사합니다.
게다가 회사에서 관리하는 저장소들은 LLM이 생성했을 가능성이 높은 코드와 주석의 비율이 더 높게 나타났으며, 사람이 라벨링한 버그 중 LLM이 생성한 코드와 관련 있을 가능성이 높은 것은 극히 일부에 불과했습니다.
![]()
유지보수성(Maintainability) 연구는 충분히 발전하여 이제 연구자들은 모델이 코드를 실제로 생성하기 전에 생성된 코드의 유지보수성과 코드 스멜(code-smell) 특성을 예측하려고 노력하고 있습니다. 2026년 10월에 발표된 PreMaQ라는 논문은 네 가지 모델을 대상으로 총 2,695개의 태스크를 평가했으며, 그 결과 이 예측치가 생성된 코드의 최종 유지보수성 지표와 의미 있게 상관관계가 있음을 발견했습니다.
[2610.05858] PreMaQ: 생성 전 LLM 생성 코드의 유지보수성 관련 품질 예측 (Predicting Maintainability-Related Quality of LLM-Generated Code Before Generation) (https://arxiv.org/abs/2610.05858)
대규모 언어 모델(LLMs)이 코드 생성 능력을 점점 더 갖추게 되면서, 소프트웨어 개발에 생성된 코드를 도입하려면 기능적 정확성뿐만 아니라 유지보수성 관련 품질도 평가해야 합니다. 만약 이러한 품질을 생성 전에 추정할 수 있다면, 개발자들은 낮은 품질의 코드를 생성하고, 검토하고, 폐기하는 비용을 피할 수 있을 것입니다. 이전 연구들에서 LLM이 생성한 코드의 기능적 정확성은 사전에 예측될 수 있음이 입증되었지만, 유지보수성 관련 품질 역시 유사하게 예측 가능한지에 대해서는 여전히 불분명합니다. 우리는 생성 전에 LLMs의 내부 표현으로부터 생성된 코드의 코드 스멜 점수(Code Smell Score, CSS)와 유지보수 지수(Maintainability Index, MI)를 예측하는 Pre-Generation Maintainability-Related Quality Prediction (PreMaQ)을 소개합니다. 우리의 평가는 네 가지 오픈 가중치 LLM과 총 2,695개의 태스크로 구성된 네 가지 Python 코드 생성 벤치마크를 다룹니다.
우리의 결과는 예측된 CSS와 MI가 모든 16가지 모델-벤치마크 조합에서 관찰된 값과 일관되게 상관관계가 있음을 보여주었으며, 각각 평균 스피어만 순위 상관계수(Spearman rank correlations) 0.57과 0.65를 달성했습니다. 모델 선택에 사용했을 때, PreMaQ는 여러 모델이 기능적으로 올바른 코드를 생성하는 작업에서 무작위 선택 대비 이상적인 유지보수 기반 선택기가 얻을 수 있는 유지보수 관련 품질 개선의 59.5%를 달성합니다. PreMaQ와 프롬프트 임베딩(prompt embeddings)의 예측값을 결합하면 이 비율이 60.7%로 증가하며, 이는 두 신호가 상호 보완적임을 나타냅니다. 이러한 발견은 PreMaQ가 LLM 생성 코드의 유지보수 관련 품질을 예측하고 개선하는 데 사용될 수 있음을 시사합니다.
![]()
이러한 연구들 중 어느 것도 AI가 한 줄짜리 래퍼(one-line wrappers)를 좋아한다는 것을 증명하지는 않습니다. 다만, '코드가 작동한다'는 것이 유지보수할 코드를 이해하는 데 모든 것을 알려주지는 않는다는 점을 보여줄 뿐입니다.
그렇다면 어떻게 막을까요?
AI에게 추상화(abstractions)도 임대료를 내야 한다고 알려주세요.
실제 워크숍이 뒤에 있는 경우, 작은 입구는 유용합니다.
저는 다음과 같은 지침에 더 선호하게 되었습니다:
단순히 다른 함수를 짧게 만들기 위해 함수를 추출하지 마세요. 추상화는 의미 있는 복잡성을 숨기거나, 도메인 개념을 나타내거나, 진정으로 재사용되는 경우에만 만드세요. 패스스루 함수(pass-through functions)와 한 줄짜리 래퍼는 피하세요. 더 적은 개념과 짧은 호출 경로를 선호하세요.
위의 ICSE 연구에서는 프롬프트 구성 방식이 모델이 생성하는 코드 스멜(code smells)의 종류에 실질적인 영향을 미치며, 목표 지향적 완화가 그 발생을 줄일 수 있음을 발견했습니다. 이것이 이 정확한 프롬프트가 과학적으로 검증되었다는 의미는 아닙니다. 이는 원하는 바를 구체적으로 명시하는 것이
제가 좋아하는 마지막 규칙이 하나 있습니다:
만약 함수의 이름이 본문(body)을 영어로 번역한 것에 불과하다면, 삭제를 고려해 보세요.
자동으로 삭제하라는 의미가 아니라, '고려'하는 것입니다. 실제 도메인 규칙을 표현하는 한 줄짜리 코드는 여전히 유용할 수 있습니다. 하지만 단지 다른 함수가 너무 길어져서 존재하는 이유가 전부라면, 아마도 그 함수는 필요 없을지도 모릅니다.
AI는 코드를 많이 생성하는 데 매우 능숙합니다. 이제 AI를 사용할 때 가장 중요한 기술 중 하나는 '더 적게' 생성하도록 요청하는 지점에 도달했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기


