레거시 PHP 현대화 맡긴 LLM, 작동하던 코드를 더 많이 깨뜨렸다

Hacker News2026-11-02조회 1

레거시 PHP 파일 하나를 LLM에 붙여넣고 "현대화해줘"라고 요청하는 방식은 얼마나 안전할까. arXiv에 공개된 프리프린트 연구는 이 간편한 지름길에 대해 불편한 답을 내놓는다. WordPress 4.0 기반 PHP 파일 100개를 PHP 8.3으로 옮기는 단일 파일 작업에서, 다섯 개 LLM은 손대지 않은 원본보다 더 많은 동작을 망가뜨렸다.

실험 조건은 의도적으로 단순하다. 모델에게 파일 하나만 주고 프로젝트 컨텍스트나 실행 피드백 없이 동작 보존을 지시했다. 평가는 외부에 공개되지 않은 동작 검사 630개와 Rector가 탐지한 현대화 항목 511개로 이뤄졌다. 비교 대상은 아무것도 하지 않은 원본 파일과 규칙 기반 변환 도구인 Rector 두 가지다.

결과는 원본 쪽 손을 들어준다. 손대지 않은 상태에서 83개 파일이 이미 모든 동작 검사를 통과했는데, 가장 성능이 좋았던 모델도 59개만 통과시켰다. 모델별로 32~51개의 멀쩡한 파일을 깨뜨린 반면 고친 파일은 최대 10개에 그쳤다. 같은 조건에서 Rector는 7개를 깨뜨리고 6개를 고쳤다.

문제는 손상의 상당 부분이 애초에 필요 없다는 점이다. 탐지된 511개 항목 가운데 PHP 8.3에서 실제로 변경이 요구되는 것은 37개, 7%뿐이었다. 변경이 전혀 필요 없는 호환 파일만 따로 봐도 LLM은 36~60%를 깨뜨렸다. Rector의 같은 지표는 8%다. 즉 모델이 만들어낸 회귀는 현대화의 부산물이 아니라 그 자체로 추가된 손해다.

원인은 비교적 단순한 곳에서 나온다. 회귀한 검사의 대부분은 파일이 아예 로드되지 않으면서 발생했고, 그 이유는 PHP 자체가 거부하는 타입 선언이었다. 프로젝트 전체 맥락을 몰라도 충분히 피할 수 있는 종류의 오류다. 또한 현대화 점수가 가장 높았던 모델이 경쟁 모델보다 호환성이 뛰어난 것도 아니어서, '얼마나 현대적으로 바꿨는가'와 '얼마나 동작을 지켰는가'가 서로 다른 축임을 보여준다.

실무적으로 이 연구가 던지는 메시지는 분명하다. 파일 단위 프롬프트로 레거시를 정리하는 워크플로는 회귀 테스트 없이 도입하기 어렵다. 최소한 변경 전 코드를 베이스라인으로 두고 비교해야 하며, 동작 보존 여부를 별도 지표로 측정해야 한다. 타입 선언처럼 정적 검사로 걸러낼 수 있는 오류는 LLM 호출 전후 파이프라인에서 먼저 차단하는 편이 비용도 낮다.

한계도 있다. 6페이지 분량의 프리프린트이며, WordPress 4.0에서 PHP 8.3으로 가는 단일 파일 설정과 다섯 개 모델이라는 좁은 범위를 다룬다. 프로젝트 전체 맥락을 제공하거나 실행 피드백을 반복해서 주는 환경에서는 결과가 달라질 수 있다. 저자들은 LLM 기반 현대화 평가가 무변경 베이스라인을 포함하고, 현대화 성과와 동작 보존을 분리해 보고해야 한다고 제안한다.