본문 바로가기
MegazoneCloud
← 전체 글
Claude Code

에이전트가 고칠 파일 수를 줄이는 애플리케이션 코드 규칙 세 개

고칠 파일 수가 곧 비용

PoC는 요구사항에 빨리 대응해야 합니다. 스키마와 워크플로우가 자주 바뀌고, 그때마다 애플리케이션 코드가 불어나고, 어느 순간 코드 리뷰가 불가능해집니다. 실제 사내 PoC 저장소에서는 화면 하나가 1,065줄까지 비대해져 있었습니다.

사람에게도 문제지만, 에이전트에게는 비용 구조 자체가 됩니다. 에이전트 세션 2,149턴을 조사해 보니 387건의 수정이 전부 “1턴에 1파일” 방식으로 처리됐고, 요청 1회당 평균 39만 토큰의 컨텍스트가 재전송되고 있었습니다.

에이전트는 파일 하나를 고칠 때마다 한 턴을 쓰고, 매 턴마다 대화 전체를 다시 보냅니다. 같은 수정이 5개 파일에 흩어져 있으면 토큰 비용도 5배가 됩니다.

필요한 것은 변경이 번지는 범위를 줄이는 작성 규칙이었습니다.

먼저 기각한 방법들

대안한계
전면 리팩토링재사용 지점이 적은 코드까지 다시 짜서 투자 회수가 안 되는 곳이 생김
코드 리뷰 강화코드만 읽어서는 못 잡고, 화면을 실행해 네트워크 탭까지 봐야 함
ESLint 강제 규칙“같이 바뀌는지” 판단엔 도메인 지식이 필요해 자동 탐지 정밀도 8~30%
“코드 정리” 지침막연해서 효과를 검증할 기준이 없음

공통 결론은 두 가지였습니다. 전부 고치지 말고 회수되는 곳만 고칠 것, 그리고 자동화는 후보를 찾는 데까지만 쓰고 판단은 사람이 할 것.

기준으로 삼은 원칙: Functional Core, Imperative Shell

규칙을 만들기 전에 기준으로 삼은 설계 원칙이 있습니다. Functional Core, Imperative Shell은 프로그램을 두 영역으로 나눕니다.

입력(API · 화면 · 이벤트)
        ↓
Imperative Shell: 입력을 정리하고 의존성을 준비한다
        ↓
Functional Core: 검증 · 계산 · 판단 · 새 상태 생성
        ↓
Imperative Shell: DB 저장 · API 호출 · 로그 · 응답

계산·검증·판단처럼 같은 입력에 같은 결과를 내야 하는 규칙은 순수 함수(Core)로 두고, HTTP·DB·시간·랜덤처럼 외부 세계와 닿는 부분은 셸(Shell)로 밀어냅니다. 핵심 규칙에 섞이지 않게 경계 밖으로 분리합니다.

이 구분은 에이전트에게 더 중요합니다. 순수한 코어는 서버도 브라우저도 없이 밀리초 단위 테스트로 검증되므로, 에이전트가 화면을 실행해보지 않고도 자기가 쓴 코드를 스스로 확인할 수 있습니다. 아래 규칙 세 개는 이 원칙을 애플리케이션 레이어에 옮긴 것입니다.

규칙 세 개

1. 공통 부품 우선 탐지

3곳 이상에서 같이 바뀌는 코드만 컴포넌트로 통합합니다. 두 곳에서 비슷한 코드는 우연일 수 있지만, 세 곳에서 같이 바뀌면 같은 부품입니다. 반대로 말하면, 재사용 지점이 두 곳뿐인 코드는 억지로 통합하지 않습니다.

2. 어댑터 패턴 강제

서버로 보낼 데이터를 화면 컴포넌트 안에서 조립하지 않습니다. 조립은 어댑터(화면과 서버 사이에서 데이터 형태를 변환하는 층)로 분리하고, 어댑터에는 계약 검사 테스트(서버가 기대하는 형태와 일치하는지 확인하는 테스트)를 필수로 둡니다.

// 화면 안에서 조립하지 않고, 순수 함수로 분리한다
function buildOrder({ cart, orderId, createdAt }) {
  return { id: orderId, createdAt, total: calculateTotal(cart) };
}

// 저장·전송 같은 부작용은 바깥에서
async function createOrder(cart, { idGenerator, clock, orderRepository }) {
  const order = buildOrder({
    cart,
    orderId: idGenerator.generate(),
    createdAt: clock.now().toISOString(),
  });

  await orderRepository.save(order);
  return order;
}

buildOrder는 같은 입력에 항상 같은 결과를 내는 순수 함수라, 서버 없이 테스트할 수 있습니다. 앞의 원칙으로 말하면 조립은 Core, 저장과 전송은 Shell입니다.

3. 컴포넌트 경량화

서로 다른 관심사(한 컴포넌트가 떠안은 역할의 종류) 4종 이상이면서 300줄을 넘는 컴포넌트를 분리 대상으로 봅니다. 고칠 자리를 빨리 찾게 하는 규칙입니다.

임계값은 중앙이 아니라 꼬리에

“관심사 4종”이라는 숫자는 감이 아니라 분포에서 나왔습니다. 커트라인별로 걸리는 파일 수를 세어 봤습니다.

커트라인걸리는 파일 수
1종 이상 (중앙값)204개 (61%)
2종 이상111개 (33%)
3종 이상84개 (25%)
4종 이상29개 (9%)
5종 이상20개 (6%)

커트라인을 중앙값(1종)에 두면 정의상 절반 이상이 걸립니다. 감사의 목적은 보통 파일이 아니라 보통에서 한참 벗어난 꼬리를 잡는 것이므로, 한 사람이 검토할 수 있는 수가 되는 지점(4종, 29개)에 커트라인을 뒀습니다.

실측 결과

2026년 6월부터 8월까지 React 19 + TypeScript 실 저장소에서 측정했습니다.

중복 통합 6건의 수정 지점 변화입니다.

같은 문구 하나를 바꾸는 데 22곳을 고치던 에러 배너가 1곳이 됐고, 합계로는 13.1배 줄었습니다.

어댑터 도입 효과는 따로 측정했습니다. 도입 전에는 잘못된 페이로드 코드 8건 중 1건만 잡혔지만, 도입 후에는 8건 전부 계약 테스트에서 차단됐고, 화면을 실행해 네트워크 탭을 열어보는 대신 196ms짜리 테스트 한 번으로 확인이 끝났습니다. 서버 계약이 전면 개편됐을 때 화면 코드 변경량은 0줄이었습니다.

적용 범위와 한계

이 규칙은 애플리케이션 레이어(화면 컴포넌트, API 어댑터 등 바깥과 도메인의 연결부)에만 적용합니다. 도메인 코어는 변경이 번지는 방식이 달라 같은 기준을 쓰지 않습니다.

수치의 한계도 남겨둡니다. 동일 작업을 두 구조에서 비교 실험한 것이 아니라 통합 전후의 “고쳐야 할 파일 집합”을 계산한 것이고, 사례 6건, 저장소 1개, TypeScript 한정이라 저장소마다 수치는 다를 수 있습니다. 공통 부품 자동 탐지도 정밀도 8~30%의 후보 목록일 뿐이라 사람의 필터링이 필요합니다.

Claude Code 스킬

세 규칙을 Claude Code 스킬로 만들어 공개했습니다. 화면 컴포넌트를 쓰거나 고칠 때, UI에서 서버로 데이터를 보낼 때 에이전트가 스킬을 읽고 규칙을 적용합니다.

구성은 이렇습니다.

파일내용
SKILL.md, SKILL.ko.md규칙 세 개
references/evidence.md이 글의 수치와 측정 방법
references/audit.md감사 절차
scripts/audit_readiness.py컴포넌트별 관심사 종수를 세는 스크립트

agent-change-cost (MIT)

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다