에이전트 코드베이스에서 리팩터링이 돈이 되는 이유
이 글은 Giles Edwards-Alexander의 글을 읽고, 개인적인 해석과 생각을 덧붙여 정리했습니다.
요즘 Claude Code나 Cursor로 기능을 붙이다 보면, 코드는 생각보다 빨리 늘어난다.
구현 초안은 나오고, 테스트도 돌아가고, 배포까지 이어지기도 한다. 그런데 어느 순간 한 파일이 수천 줄을 넘기고, 비슷한 HTTP 설정과 JSON 변환이 여기저기 반복되기 시작한다. 사람 개발자라면 중간에 한 번쯤 손을 대겠지만, 에이전트는 당장 동작하는 쪽으로 계속 쌓아 올린다.
Giles Edwards-Alexander의 글은 이 상황을 감으로만 걱정하지 않는다. 대신 질문을 실험으로 바꾼다.
리팩터링에 지금 토큰을 쓰면, 이후 변경에 드는 토큰은 줄어드는가?
이 질문은 에이전트 시대의 리팩터링을 조금 다르게 보이게 만든다. 가독성이나 취향의 문제가 아니라, 반복되는 작업의 단가를 낮추는 투자인지 묻는 쪽에 가깝다.
에이전트가 만든 17,155줄짜리 파일
저자는 자신의 업무를 돕는 앱을 에이전트만으로 만들었다. Claude Code가 주력이고, Cursor도 일부 썼다. 대략 15만 줄, 대부분 Rust다. 웹 UI, 외부 연동, 머신러닝, 백그라운드 잡, 자동 배포까지 갖춘 꽤 큰 앱이다. 코드를 거의 읽지도, 리뷰하지도 않았다고 한다.
문제는 데이터 접근 계층에서 드러났다. 쿼리마다 같은 HTTP 설정, 같은 JSON 인코딩/디코딩이 반복됐고, 파일이 계속 커졌다. 결국 한 Rust 파일이 17,155줄이 됐다.
흥미로운 점은 그래도 경계는 남아 있었다는 것이다. 인터페이스는 비교적 명확했고, 그래서 리팩터링 대상으로는 좋았다. 겉으로는 동작하고, 안으로는 중복이 쌓이며, 경계만 간신히 남아 있는 상태. 에이전트가 만든 코드베이스에서 자주 보게 되는 패턴이기도 하다.
실험이 가능한 이유: 에이전트는 이전 단계를 기억하지 않는다
이 실험의 설계는 단순하다.
- Fowler식 엄격한 리팩터링 계획을 만든다.
- 대표 변경 하나를 프롬프트로 고정한다.
- 서브 에이전트에게 그 변경을 시키고, 토큰 비용을 잰다.
- 변경은 버린다.
- 리팩터링을 한 단계 적용한 뒤, 같은 변경을 다시 시키고 비용을 잰다.
- 이를 반복한다.
사람을 대상으로 하면 이 실험은 오염된다. 한 번 고쳐본 사람은 다음에도 더 잘한다. 에이전트는 매번 새로 시작하면 이전 단계를 기억하지 않는다. 그래서 같은 프롬프트를 반복해도, 구조 변화의 효과만 비교적 깨끗하게 볼 수 있다.
여기서 에이전트 코드베이스의 리팩터링 목표가 분명해진다.
지금 토큰을 써서 구조를 정리하고, 이후 변경의 토큰 단가를 낮춘다.
줄 수는 거의 그대로인데, 입력 토큰은 83% 줄었다
대표 변경은 데이터 접근 계층에 새로운 store 기능을 기존 패턴대로 추가하는 작업이었다. 리팩터링 전후의 입력 토큰은 대략 이랬다.
- 기준선: 159,564 입력 토큰
- 최종 단계: 27,360 입력 토큰
- 절감: 약 83%
출력 토큰은 크게 변하지 않았다. 쓸 코드의 양은 비슷하기 때문이다. 줄어든 것은 읽어야 하는 양이다.
더 중요한 관찰은 이것이다. 데이터 접근 계층 전체 줄 수는 거의 그대로였다. 절약은 “코드가 줄어서”가 아니라, 에이전트가 관련 있는 작은 파일 집합만 골라 읽을 수 있어서 생겼다.
파일을 아무렇게나 쪼개면 이런 효과가 나기 어렵다. 에이전트가 여러 파일을 헤매며 읽을 수 있기 때문이다. 효과가 커진 지점은, 중복을 걷어내고 내부 언어가 드러난 뒤 모듈을 나눈 단계였다. 전형적인 리팩터링 순서와 같다. 먼저 중복을 추출하고, 중심이 보이면 파일을 나눈다.
한 번 절약한 비용은 일회성이 아니다. 이 계층을 건드리는 이후의 모든 변경이 싸진다. 글에서는 Sonnet 기준 한 변경당 수십 센트 수준이라고 말한다. 단독으로는 작아 보일 수 있다. 하지만 같은 영역을 반복해서 고치는 팀에서는 누적된다. 디버깅이나 더 복잡한 기능, 코드베이스 전반으로 확장하면 이야기는 달라질 수 있다.
리팩터링은 가독성만이 아니라 컨텍스트 비용의 문제다
이전에는 리팩터링의 이득을 설명하기가 어려웠다. 가독성, 변경 용이성, 버그 가능성 감소 같은 말은 맞지만 측정이 애매했다. 에이전트 시대에는 적어도 한 축이 더 선명해진다.
구조가 나쁘면 에이전트가 더 많이 읽어야 하고, 더 많이 읽으면 더 많은 토큰을 쓴다.
이건 비용 문제이기도 하고, 품질 문제이기도 하다. 컨텍스트가 커질수록 에이전트는 관련 없는 코드까지 끌어들이고, 잘못된 패턴을 복제할 가능성도 커진다. 토큰 절약은 청구서만 줄이는 일이 아니라, 변경의 초점도 좁혀줄 수 있다.
개인적으로 Claude Code나 Cursor에게 큰 파일을 맡길 때도 비슷한 느낌이 있다. 파일이 크면 일단 통째로 읽고, 비슷한 구현을 옆에 또 붙이는 경우가 많다. 반대로 책임이 나뉜 작은 모듈에서는 기존 패턴을 찾아 그 자리에 끼워 넣는 비율이 높다. “읽기 좋은 코드”와 “에이전트가 더 싸게 일할 수 있는 코드”가 생각보다 많이 겹친다.
그렇다고 파일 수를 늘리는 것 자체가 목표는 아니다. 에이전트가 필요한 최소 범위를 식별할 수 있도록, 의미 있는 경계를 만드는 일이 핵심이다.
그렇다고 에이전트가 리팩터링을 잘한다는 뜻은 아니다
실험에서 또 하나 인상적이었던 점은, Claude가 리팩터링 자체에는 약했다는 사실이다.
계획을 세울 때도 사람이 강하게 가이드해야 했다. 코드를 보고 어떤 리팩터링이 적합한지 스스로 고르는 능력은 부족했다. 적용 과정도 매끄럽지 않았다. 기계적 수정을 Python 스크립트와 grep/sed로 처리하다가 들여쓰기에서 자주 헷갈렸고, 가장 가치 큰 분리 작업은 첫 패스에서 빠져 나중에 다시 넣어야 했다.
개발 하네스에 리팩터링 단계가 있어도, 그 단계만으로는 이 17K 파일이 정리되지 않았다. 에이전트에게 “리팩터링해”라고 맡긴다고 구조가 좋아지지 않는다는 이야기다.
이 지점이 중요하다고 생각한다.
에이전트 시대에도 리팩터링의 방향 설정은 사람의 일이다. 무엇을 추출할지, 어떤 경계를 살릴지, 어떤 중복이 진짜 중복인지 판단하는 일은 여전히 설계 판단이다. 에이전트는 그 판단을 실행하는 노동력을 싸게 제공할 수 있지만, 판단을 대체하지는 않는다.
이전 글들에서 반복해서 느꼈던 것과 같다. 병목은 코드 작성이 아니라 검토와 판단이다. 리팩터링도 마찬가지다. 실행은 에이전트가 도울 수 있어도, “이 구조가 이후 변경을 싸게 만드는가”를 결정하는 일은 사람이 해야 한다.
내가 가져가고 싶은 원칙
에이전트와 함께 코드를 쌓을 때, 이 실험에서 가져가고 싶은 원칙은 이렇다.
첫째, 리팩터링을 미학적 정리로만 보지 않는다.
에이전트 코드베이스에서 리팩터링은 이후 작업의 단가를 낮추는 투자일 수 있다. “나중에 해도 된다”보다, “지금 안 하면 이후 변경마다 더 비싸게 읽힌다”에 가깝다.
둘째, 줄 수를 줄이는 것이 아니라 탐색 범위를 줄인다.
전체 LoC가 비슷해도, 관련 코드가 작은 파일에 모여 있으면 에이전트는 더 싸게 일할 수 있다. 의미 있는 모듈 경계, 중복 제거, 내부 언어 추출이 핵심이다.
셋째, 리팩터링 계획은 사람이 잡는다.
에이전트에게 알아서 정리하라고 맡기기보다, Extract Function / Extract Class / Move Function처럼 검증 가능한 단계로 쪼개고, 각 단계마다 테스트를 통과시키며 진행하는 편이 낫다.
넷째, 한 번 절약한 비용이 반복되는지 본다.
토큰 절약이 일회성이면 의미가 작다. 같은 영역을 앞으로 몇 번 더 건드릴지를 기준으로 투자 회수를 생각해야 한다. 자주 바뀌는 계층일수록 리팩터링의 경제성은 커진다.
결론
이 실험이 모든 코드베이스에 일반화된다고 보기는 어렵다. 아직 그린필드에 가깝고, 단일 개발자가 유지하는 앱이며, 측정한 변경도 하나다. 리팩터링 자체에 든 정확한 토큰 비용도 사후에 잡지 못했다.
그래도 방향은 분명하다고 생각한다.
에이전트가 코드를 싸게 쓰게 해주면, 나쁜 구조도 더 싸게 쌓일 수 있다. 그 구조는 이후의 모든 읽기 비용을 끌어올린다. 리팩터링은 그 궤도를 꺾는 일이다. 코드를 예쁘게 만드는 일이 아니라, 앞으로의 변경이 더 적은 컨텍스트로 끝나게 만드는 일에 가깝다.
그래서 에이전트 시대의 리팩터링은 이런 질문으로 다시 써야 할지도 모른다.
지금 쓰는 토큰이, 이후의 토큰을 줄이는가?
그 답이 yes라면, 리팩터링은 더 이상 여유 있을 때 하는 정리가 아니다. 반복 작업의 단가를 낮추는 공학적 투자다.
에이전트는 코드를 빨리 쓸 수 있다.
테스트는 리팩터링의 안전장치를 도와줄 수 있다.
토큰 사용량은 그 효과를 조금 더 측정 가능하게 만들어준다.
하지만 어떤 경계를 남기고, 어떤 중복을 걷어내며, 어떤 구조를 이후의 기본값으로 삼을지는 여전히 사람의 판단에 달려 있다.
참고한 글
-
The Economic Benefit of Refactoring — Giles Edwards-Alexander
martinfowler.com에이전트가 만든 17K 줄 데이터 접근 계층을 Fowler식 리팩터링으로 나누고, 동일 변경을 단계마다 다시 시켜 토큰 비용을 측정한 실험. 전체 코드량은 크게 줄지 않았지만, 관련 파일만 읽게 되면서 입력 토큰이 약 83% 감소했다. 리팩터링을 이후 변경 단가를 낮추는 경제적 투자로 볼 수 있다는 관점.