지금까지의 벤치마크에서 속도 문제는 대부분 모델 추론(CPU 바운드 decode) 탓으로 돌렸다. 그런데 문득 이런 의문이 들었다. “Aider 자체는 병목이 아닐까? 모델한테 뭘 보내는지, 그 준비 과정 자체가 느린 건 아닐까?”

Aider가 매 턴마다 하는 추가 작업

Aider는 단순히 사용자 프롬프트만 모델에 던지지 않는다. 매 요청마다 다음과 같은 부가 작업이 들어간다.

1. repo-map 생성 프로젝트 전체 구조를 파악해서, 지금 대화와 관련 있을 법한 파일·함수 목록을 요약한 “지도"를 만든다. 이 작업은 tree-sitter라는 파서를 이용해 코드를 구문 분석하는 방식으로 이뤄진다. 프로젝트가 작을 땐(이번 테스트의 계산기 모듈처럼) 무시할 만한 수준이지만, 파일 수가 많은 대형 저장소에서는 이 repo-map 생성 자체에 시간이 걸릴 수 있다.

2. 컨텍스트(프롬프트) 크기 대화가 길어지거나, /add로 여러 파일을 채팅에 추가할수록 매 요청마다 모델에 보내는 프롬프트 크기가 커진다. 프롬프트가 커지면 prefill(입력 처리) 시간이 늘어난다 — CPU 환경에서는 decode보다는 빠르지만, 그래도 공짜는 아니다.

3. auto-test / auto-lint 재시도 루프 이미 다른 글에서 다뤘듯, 실패한 시도를 재시도(reflection)할 때마다 누적된 대화 컨텍스트를 통째로 다시 모델에 보내야 한다. 재시도가 반복될수록 이 컨텍스트가 계속 불어난다.

그래서 실제 병목은 어디였나

이번 계산기 테스트 규모(파일 2~3개, 짧은 프롬프트)에서는 이 세 가지 중 어느 것도 결정적인 병목이 아니었다. 실측 결과 대부분의 시간은 여전히 모델의 decode 속도에서 소모됐다. 다만 이건 테스트 규모가 작았기 때문이고, 실제로 수백-수천 개 파일이 있는 대형 저장소에서 작업한다면 얘기가 달라질 수 있다.

규모가 커지면 고려해야 할 튜닝 포인트

나중에 더 큰 프로젝트에 이 파이프라인을 적용하게 된다면 다음 옵션들을 먼저 점검할 계획이다.

  • --map-tokens: repo-map에 할당하는 토큰 예산을 제한해서, 관련 없는 파일 정보까지 프롬프트에 끼워 넣는 걸 막는다.
  • --map-refresh: repo-map을 매번 새로 계산할지, 캐시된 걸 재사용할지 조정한다.
  • 필요한 파일만 명시적으로 /add: 자동 탐색에 맡기지 않고, 작업에 꼭 필요한 파일만 채팅 컨텍스트에 넣어 프롬프트 크기를 직접 통제한다.

결론

이번 프로젝트 규모에서는 “Aider 자체가 병목"이라는 가설은 기각됐다 — 진짜 병목은 CPU 추론 속도였다. 하지만 이 분석 과정 자체는 의미가 있었다. 나중에 대형 저장소에 로컬 LLM 파이프라인을 다시 시도하게 된다면, 모델 교체보다 먼저 map-tokens나 파일 선택 범위 같은 Aider 자체 설정부터 점검하는 게 순서라는 걸 미리 알아둘 수 있었기 때문이다.