Agent-as-a-Router: 실행 피드백으로 진화하는 코딩 작업용 LLM 라우팅에 대한 연구

Agent-as-a-Router 소개

여러 명의 동료와 함께 일하는 팀을 떠올려 봅시다. 어떤 동료는 복잡한 알고리즘을 기막히게 잘 풀고, 어떤 동료는 지저분한 버그를 귀신같이 잡아내며, 또 다른 동료는 테스트 코드 작성에 일가견이 있습니다. 유능한 팀장이라면 모든 일을 한 사람에게 몰아주지 않고, 각 작업에 가장 잘 맞는 사람에게 일을 배분할 것입니다. 그런데 우리가 AI 코딩 도구를 쓸 때는 어떤가요? 대부분 하나의 모델에게 모든 일을 맡기고 있습니다.

이번에 살펴보는 Agent-as-a-Router 논문은 바로 이 문제를 다룹니다. 오늘날 개발자들은 Claude CodeCodex 같은 여러 코딩 에이전트를 동시에 구독하고, 강력한 오픈소스 모델을 로컬에서 직접 돌리기도 합니다. 문제는 어떤 모델도 모든 작업에서 최고가 아니라는 점입니다. 그렇다면 들어오는 각각의 작업을 어떤 모델에게 보낼 것인가(model routing) 라는 질문이 성능과 비용 모두에 결정적인 변수가 됩니다. 이 논문은 라우팅을 정적인 분류 문제가 아니라 실행 결과로부터 끊임없이 학습하는 에이전트의 의사결정 과정 으로 재정의하는 Agent-as-a-Router 프레임워크를 제안하고, 이를 ACRouter라는 시스템과 CodeRouterBench라는 평가 환경으로 구체화합니다.

이 연구는 싱가포르 국립대학교(NUS), 알리바바 DAMO Academy, UC 버클리, 저장대학교, 홍콩과기대(HKUST) 등이 함께 수행했으며, 대규모 분산 학습 연구로 잘 알려진 Yang You 교수 그룹이 참여했습니다. 흥미롭게도 이 논문은 벤치마크가 계속 갱신되는 "living technical report"를 표방하고 있어, 버전에 따라 일부 수치가 조금씩 업데이트됩니다(본문 수치는 arXiv v2 기준입니다).

여러 모델 시대의 새로운 고민: 어떤 모델에게 맡길 것인가

최근 AI 코딩 에이전트는 단순한 코드 생성기를 넘어, 계획 수립, 코드 검색, 편집, 실행, 자체 디버깅까지 수행하는 대화형 시스템으로 진화했습니다. 하지만 이런 에이전트의 대부분은 모든 작업을 동일한 하나의 LLM으로 처리 합니다. 이는 모델을 제공하는 회사 입장(provider-centric)에서는 합리적입니다. 자사 모델을 우선 사용하고 서빙 비용을 예측 가능하게 관리할 수 있기 때문입니다. 그러나 정작 사용자 입장(user-centric)에서는 서비스 제공자의 예측 가능성보다 작업별 품질과 비용 효율 이 더 중요합니다.

연구팀이 8개의 프론티어 모델을 다양한 코딩 작업에서 측정해 보니, 작업마다 가장 잘하는 모델이 제각각이었고, 항상 가장 강력한 단일 모델만 고르는 전략은 작업별 최적 선택(oracle)에 한참 못 미쳤습니다. 매번 사람이 손으로 최적 모델을 고르는 것은 대규모로는 불가능하므로, 자동 모델 라우팅이 에이전트 성능을 끌어올리는 핵심 장치로 떠오릅니다.

기존 라우터의 한계: 정적 분류 문제로 본 라우팅

기존 라우팅 연구는 대부분 이 문제를 정적인 분류(static classification) 문제 로 다뤘습니다. 즉, 들어온 작업을 한 번 보고 어떤 모델로 보낼지 한 번에 결정하는 방식입니다.

첫 번째 접근은 학습된 분류기를 쓰는 방식입니다. RouteLLM 은 라우팅을 선호 학습(preference learning) 문제로 보고, 두 모델 중 어느 쪽이 더 나은 답을 내는지를 사람의 선호 데이터로 학습한 분류기로 예측합니다. 다른 메타 모델링 방식들은 작업의 특징(feature)으로부터 모델 성능을 예측하도록 학습합니다. 이런 경량 분류기들은 학습 분포 안에서는 그럭저럭 작동하지만, 학습 시점에 정보 상태가 고정(frozen)되어 있다는 한계가 있습니다.

두 번째 접근은 강력한 LLM 자체를 라우터로 쓰는 방식(LLM-as-a-Router)입니다. 직관적으로는 똑똑한 모델이 라우팅도 잘할 것 같지만, 연구팀의 예비 실험은 정반대의 결과를 보여줍니다. Claude Sonnet 4.6처럼 매우 유능한 모델로 제로샷 라우터를 만들어도, 작업별 oracle과는 큰 격차를 보였습니다.

이 지점에서 연구팀은 핵심적인 질문을 던집니다. "라우터를 가로막는 것은 추론 능력(reasoning)인가, 아니면 정보 접근(information access)인가?"

진짜 병목은 '추론'이 아니라 '정보 부족'이었다

연구팀은 이 질문에 답하기 위해, LLM 라우터에게 주어지는 정보만 바꾸는 정교한 절제 실험(ablation)을 설계했습니다. 결과는 이 논문 전체의 출발점이 되는 발견으로 이어집니다.

라우터 설정 해석 AvgPerf% 비용 효율(Perf/$)
Oracle 작업마다 최적 모델을 고르는 이론적 상한 57.00 8.20
DimensionBest 사전 통계로 차원별 최고 모델 선택 (휴리스틱) 47.50 3.69
Vanilla 표준 제로샷 LLM 라우터 41.41 1.97
+Dimension 작업 차원(dimension) 설명 추가 41.18 1.81
+Perf stats 차원별 사전 성능 통계 추가 47.74 1.71

모든 변형은 동일한 Claude Sonnet 4.6 모델을 사용했고, 2{,}919 개의 작업에서 측정했습니다. 표를 보면, 단순히 작업 차원이 무엇인지 알려주는 것(+Dimension)만으로는 거의 변화가 없습니다(41.41 \to 41.18 ). 그런데 별도의 탐침 집합(probing set)에서 수집한 차원별 성능 통계 를 주입하자(+Perf stats), 점수가 41.41 에서 47.74 로 상대적으로 15.3\% 나 뛰어올랐습니다. 더 놀라운 점은, 이 값이 동일한 통계 정보를 규칙으로 박아 넣은 최고의 휴리스틱(DimensionBest, 47.50 )마저 앞질렀다 는 것입니다.

이 실험이 시사하는 바는 분명합니다. LLM 라우터의 진짜 병목은 추론 실패가 아니라 정보 부족(information deficit) 이라는 것입니다. 똑똑한 모델에게 좋은 정보를 주면, 똑똑한 모델은 그 정보를 규칙 기반 시스템보다 더 잘 활용합니다.

이 진단에서 두 가지 설계 원칙이 도출됩니다. 첫째, 라우터는 정적인 사전 정보나 모델의 자기 평가에 의존하지 말고, 선택한 모델의 출력을 실제로 샌드박스에서 실행해 새로운 실행 기반 정보를 획득(verification)해야 한다. 둘째, 라우터는 이 정보를 작업 스트림 전체에 걸쳐 누적(memory)하여 이후 결정이 과거의 결과를 조건으로 삼게 해야 한다. 정적 라우터는 정보 상태가 얼어붙어 있어 이 두 가지를 구조적으로 할 수 없습니다. 바로 여기서 스스로 진화하는 새로운 종류의 라우터가 필요해집니다.

C-A-F 루프: 라우팅을 학습하는 에이전트로 재정의하기

연구팀은 위 진단을 Context-Action-Feedback(C-A-F) 루프 라는 형식으로 정형화합니다. 핵심 아이디어는 라우팅을 한 번의 분류가 아니라, 매 작업마다 검증된 결과가 다음 결정의 맥락으로 흘러 들어가는 순환 과정 으로 보는 것입니다.

Context-Action-Feedback 순환 구조

모델 풀 \mathcal{M} = \{m_1, \dots, m_M\}N 개의 작업으로 이루어진 스트림 \mathcal{T} = (t_1, \dots, t_N) 이 주어졌을 때, 라우터는 각 작업 t_i 에서 다음 순환을 수행합니다.

c_i \xrightarrow{\text{Decide}} a_i \xrightarrow{\text{Execute}} f_i \xrightarrow{\text{Memorize}} c_{i+1}

각 구성 요소는 다음과 같습니다.

  • Context c_i = (p_i, d_i, \mathcal{H}_{<i}) : 작업의 입력 프롬프트 p_i, 선택적 메타데이터 d_i (설명, 난이도, 언어), 그리고 이전 모든 루프에서 누적된 Memory 상태 \mathcal{H}_{<i} 로 구성됩니다.
  • Action a_i \in [M] : 모델 풀에서 선택한 모델 m_{a_i} 의 인덱스입니다.
  • Feedback f_i = (\hat{s}_i, \hat{\kappa}_i) : 선택된 모델에 대해 검증기가 관측한 점수 \hat{s}_i \in [0,1] 와 토큰 소비량 및 공식 가격으로 계산한 비용 \hat{\kappa}_i 입니다. 이것이 바로 Memory가 누적하는 실행 기반 피드백입니다.

마치 과학자가 가설을 세우고(Context), 실험을 수행하며(Action), 그 결과를 관찰해(Feedback) 다음 가설에 반영하는 과정과 같습니다. 각 루프가 완료될 때마다 다음 루프는 더 많은 정보를 갖게 됩니다.

컨텍스트 밴딧과 누적 후회(Cumulative Regret)

C-A-F 형식화의 우아한 점은, 이것이 잘 알려진 컨텍스트 멀티암드 밴딧(contextual multi-armed bandit) 문제와 자연스럽게 연결된다는 것입니다. c_i 는 부가 정보(side information), a_i 는 팔 당기기(arm pull), f_i 는 피드백에 해당합니다. 각 작업의 보상은 성능과 비용을 사용자가 정한 가중치로 결합합니다.

r_i(a_i) = \epsilon_1 \, s_i(a_i) + \epsilon_2 \, \kappa_i(a_i)

여기서 \epsilon_1 > 0 은 성능에 보상을 주고, \epsilon_2 < 0 은 비용에 벌점을 줍니다(논문 전체에서 (\epsilon_1, \epsilon_2) = (1, -0.1) 을 사용합니다).

밴딧 문제로 보면, 자연스러운 평가 지표는 누적 후회(Cumulative Regret) 가 됩니다. 작업별 oracle은 전체 결과 행렬을 미리 알고 매 작업마다 보상이 가장 높은 모델을 독립적으로 고르는 가상의 상한입니다. 누적 후회는 라우터가 이 oracle과 매 작업에서 벌린 보상 격차를 모두 더한 값입니다.

\mathrm{CumReg}_N(\pi) = \sum_{i=1}^{N} \left[ \max_{j \in [M]} R_{ij} - R_{i, a_i} \right]

값이 작을수록 라우팅이 최적에 가깝다는 뜻입니다. 중요한 점은, 이 oracle이 하나의 전역 최적 모델을 고정해서 쓰는 정책과는 다르다 는 것입니다. oracle은 작업마다 매번 최적 모델을 다시 고르기 때문에, 단일 최강 모델을 항상 쓰는 전략보다 훨씬 높습니다. 정적인 단일 지표(정확도)만 재던 기존 라우팅 벤치마크와 달리, 누적 후회는 시간이 흐르며 라우터가 학습하는 모습을 포착할 수 있는 스트리밍 지표라는 점에서 이 논문의 핵심 평가 도구가 됩니다.

ACRouter: C-A-F 루프의 실제 구현

C-A-F 루프는 추상적인 형식입니다. 연구팀은 이를 ACRouter(Agentic Coding Router) 라는 구체적인 시스템으로 구현합니다. 앞서 도출한 세 가지 설계 원칙(정보 통합, 정보 생성, 정보 누적)이 각각 Orchestrator, Verifier, Memory 라는 세 모듈로 대응됩니다.

Orchestrator: 정보를 통합해 결정하기

Orchestrator 는 현재 작업을 어떤 모델로 보낼지 최종 결정을 내리는 중앙 조정자입니다. 한 가지 신호에만 의존하지 않고 여러 정보원을 종합합니다. 구체적으로는 DimensionBest 사전 정보, Memory에서 코사인 kNN으로 검색한 상위 10 개의 과거 이웃 작업, 그리고 작업 메타데이터를 입력으로 받습니다.

핵심 정책 모델로는 거대한 모델 대신 CodeRouterBench 탐침 집합으로 미세조정(fine-tuning)한 비용 효율적인 Qwen3.5-0.8B 모델 을 사용하고, 여기에 휴리스틱 규칙을 가중 투표(weighted voting)로 결합합니다. 라우터 자체가 무겁고 비싸면 배보다 배꼽이 커지므로, 작지만 충분히 똑똑한 정책 모델을 쓴 것입니다.

Verifier: 실행으로 새 정보를 생성하기

Verifier 는 이 프레임워크의 심장에 해당합니다. 정적 라우터가 결코 할 수 없는 일, 즉 선택한 모델의 출력을 실제로 실행해 새로운 정보를 만들어내는 역할을 합니다. Verifier는 여러 신호 계층을 하나의 통합 점수 u_i \in [0,1] 로 집계합니다.

u_i = \sum_{k \in \mathcal{K}_{d(t_i)}} w_{d(t_i),k} \cdot \hat{s}_k(a_i, t_i)

여기서 \mathcal{K}_{d(t_i)} 는 작업 유형에 맞는 검증 도구들의 집합이고, w_{d(t_i),k} 는 유형별 가중치로 \sum_k w_{d(t_i),k} = 1 을 만족합니다. 검증 도구에는 추상 구문 트리(AST) 파싱, 샌드박스 실행, 프롬프트에 내장된 테스트 케이스, 규칙 기반 신호 등이 포함됩니다. 중요한 것은 이 모든 신호가 정답 테스트(ground-truth oracle test)에 의존하지 않고 도 품질 신호를 만들어낸다는 점입니다. 마치 정답지를 보지 않고도 학생의 풀이 과정과 검산을 통해 답의 신뢰도를 가늠하는 것과 같습니다.

Memory: 경험을 누적하기

Memory 는 작업 임베딩(embedding)을 키로 사용하는 온라인 벡터 저장소입니다. 임베딩 인코더로는 코드 특화 API인 voyage-code-3 또는 오픈소스 모델 BGE-large를 쓸 수 있습니다. 각 항목의 값에는 선택된 모델, 관측된 성능, 비용, 그리고 Verifier의 검증 흔적(trace)이 기록됩니다.

검색 시에는 코사인 kNN으로 유사도 임계값 0.5 이상인 상위 10 개 이웃을 가져와 Orchestrator에 전달합니다. 저장소는 FIFO 방식으로 최대 20\text{K} 개 항목으로 제한되며, 매 시도 후 즉시 갱신됩니다. 차원 단위로 거칠게 해싱하는 정적 라우팅과 달리, 이 임베딩 기반 저장소는 세밀하고 맥락을 인식하는(context-aware) 의사결정을 가능하게 합니다. 어떤 후보 모델이 비슷한 작업에서 과거에 성공했는지, 혹은 최근에 실패했는지를 Orchestrator가 다음 결정 시점에 모두 볼 수 있게 되는 것입니다.

C-A-F 관점으로 본 기존 라우터 분류

C-A-F 루프의 또 다른 장점은, 기존의 다양한 라우팅 전략을 세 모듈 중 어떤 것을 켜고 끄느냐 로 일목요연하게 분류할 수 있다는 것입니다. 이는 자연스럽게 절제 실험의 설계가 됩니다.

  • Single-Model (Always-m ): Orchestrator, Verifier, Memory 모두 없음. 무조건 고정된 한 모델로 보냅니다. 성능 하한 기준선입니다.
  • Static: Heuristic (DimensionBest, kNN Retrieval): 탐침 집합 통계로 만든 얼어붙은(frozen) Memory에서 규칙으로 모델을 고릅니다. Orchestrator 정책도 Verifier도 없습니다.
  • Static: Trained Policy (LogReg, TF-IDF+MLP, RouteLLM, Qwen3.5-FT): 학습된 분류기가 작업 특징을 모델 선택으로 직접 매핑합니다. Memory도 Verifier도 없습니다.
  • Dynamic: Online Bandit (LinUCB, LinTS): 팔 별로 파라미터 사후 분포를 두고 \arg\max 규칙으로 선택합니다. 보상만 보는 Verifier와 파라미터형 Memory를 갖습니다.
  • ACRouter (loop-complete): 세 모듈을 모두 활성화한 완전한 C-A-F 루프입니다.

이 분류 체계는 ACRouter의 각 모듈이 정말로 기여하는지를 검증하는 절제 실험의 골격이 됩니다.

CodeRouterBench: 스트리밍 라우팅 평가 환경

누적 후회를 측정하려면, 작업별, 모델별 결과가 미리 수집된 통제된 환경이 필요합니다. 기존 라우팅 벤치마크는 단발성 정확도만 재기 때문에 이런 평가를 지원하지 못합니다. 그래서 연구팀은 CodeRouterBench 를 새로 구축했습니다.

벤치마크 구성

CodeRouterBench는 15 개 이상의 널리 쓰이는 고품질 벤치마크(HumanEval+, MBPP, BigCodeBench, LiveCodeBench, DS-1000, CRUXEval, SWE-bench 등)를 하나의 평가 프로토콜로 통합한 것입니다. 총 10{,}111 개의 작업을 10 개의 코딩 차원으로 나누고, 세 가지 역할로 분할했습니다.

위 그림은 벤치마크 구축의 3단계 파이프라인을 보여줍니다. 1단계에서 흩어진 벤치마크들을 통일된 작업 집합으로 모으고, 2단계에서 8 개 모델로 각 작업에 대한 점수와 비용을 담은 관측 행렬(observation matrix)을 만들며, 3단계에서 이 행렬 위에서 여러 라우팅 방법을 스트리밍 방식으로 비교합니다.

통계
코딩 차원 수 10
소스 벤치마크 15+
탐침 집합(Probing Set) 7{,}080
분포 내(In-Distribution) 테스트 2{,}919
분포 밖(OOD) 테스트 176

9 개의 단일 턴(single-turn) 차원(코드 생성, 알고리즘 설계, 버그 수정, 코드 완성, 리팩토링, 데이터 과학, 다중 언어, 코드 이해, 테스트 생성)은 분포 내 평가에 쓰입니다. 이 중 7 개 차원은 샌드박스 실행 기반 채점(pass@1)을 쓰고, 나머지 3 개는 프록시 지표와 LLM-as-Judge를 함께 사용합니다.

특히 주목할 것은 10 번째 차원인 에이전트형 프로그래밍(Agentic Programming) 입니다. 이는 C-A-F 형식화의 첫 OOD 검증 으로 설정되었습니다. 다단계 계획, 파일 탐색, 반복적 디버깅이 필요한 이 작업들은 단일 턴 코딩과 질적으로 완전히 다릅니다. SWE-bench Verified, LongCLI-Bench, FeatureBench, SWE-CI에서 탐침 집합과 유사도가 높은 작업을 걸러내고 추출한 176 개 작업으로 구성되며, Docker 기반 샌드박스(mini-swe-agent 와 SWE-Bench Docker 하니스)로 평가합니다. 라우터가 학습 분포에서 완전히 벗어난 새로운 유형의 작업에도 일반화되는지를 시험하는 무대인 셈입니다.

모델 풀과 상호 보완성

평가에 쓰인 8 개의 프론티어 모델은 Claude Opus 4.6, Claude Sonnet 4.6, GPT-5.4, Qwen3-Max, Qwen3.5-Plus, GLM-5, Kimi-K2.5, MiniMax-M2.7입니다. 그리고 이 논문의 두 번째 핵심 발견이 여기서 나옵니다. 어떤 단일 모델도 모든 코딩 차원을 지배하지 못한다 는 것입니다.

Claude Opus 4.6이 평균 성능(42.9\% )으로 가장 높지만, 세부 차원으로 들어가면 이야기가 달라집니다.

  • 알고리즘 설계에서는 GLM-5가 Opus를 앞섭니다(47.2\%25.4\% , 상대적으로 86\% 향상).
  • 테스트 생성에서는 Qwen3-Max가 압도적입니다(82.7\%39.2\% , 111\% 향상).
  • 데이터 과학에서는 Kimi-K2.5가 더 낫습니다(18.4\%14.2\% , 30\% 향상).

9 개 차원에서 5 개의 서로 다른 모델 이 각 차원의 최강자 자리를 나눠 가졌습니다. 좀 더 구체적으로 보면, Claude Opus 4.6은 코드 완성(0.837 )과 버그 수정(0.722 )에서 강하지만 알고리즘 설계(0.275 )에서는 중위권이고, GLM-5는 정반대로 알고리즘 설계와 버그 수정에 강합니다. Qwen3-Max는 테스트 생성(0.789 )을 지배하고, Kimi-K2.5는 가장 호출 단가가 싼 두 차원(데이터 과학, 코드 이해)에서 비용 대비 최고의 효율을 냅니다. 각 모델의 강점 프로파일이 원형이 아니라 뾰족뾰족한 별 모양이라는 것, 이것이 바로 라우팅이 파고드는 빈틈입니다.

게다가 비용 격차도 큽니다. 모델 풀의 공식 API 단가는 네 개의 티어로 나뉩니다.

모델 입력 ($/M) 출력 ($/M) 티어
Claude Opus 4.6 5.00 25.00 premium
Claude Sonnet 4.6 3.00 15.00 high
GPT-5.4 2.50 15.00 high
Qwen3-Max 1.20 6.00 mid
GLM-5 0.88 3.22 mid
Kimi-K2.5 0.60 3.07 mid
Qwen3.5-Plus 0.40 2.40 low
MiniMax-M2.7 0.30 1.20 low

가장 비싼 Claude Opus 4.6의 출력 토큰 가격(25/\text{M} )은 가장 싼 MiniMax-M2.7(1.20/\text{M} )의 20 배가 넘고, 총비용 기준으로 Opus는 Kimi-K2.5의 약 12\times 에 달합니다. 위 히트맵의 (c)를 보면, 비싼 모델이 늘 비용 효율적인 것은 아님이 분명히 드러납니다. 성능과 비용 양쪽에서 라우팅의 가치가 정당화되는 것입니다. 참고로 ACRouter의 Orchestrator처럼 직접 호스팅하는 라우터 측 토큰은 별도로, H100 GPU 대여 비용(6.88 /GPU-시간)을 측정된 처리량으로 환산한 0.054/\text{M} 단가를 적용해 백엔드 모델 비용과 분리해서 계산했습니다.

실험 결과

이제 핵심 질문으로 돌아갑니다. 완전한 C-A-F 루프인 ACRouter는 정말로 정적 라우터들보다 나은가?

분포 내(ID) 결과: 후회가 점점 줄어드는 유일한 라우터

분포 내 테스트(n = 2{,}919 )에서 ACRouter는 가장 높은 평균 성능(49.98\% )과 가장 낮은 누적 후회(205.5 )를 동시에 달성했습니다. 완전한 차원 단위 사전 정보를 가진 DimensionBest(47.50\% )조차 2.48 포인트 차이로 앞섰습니다.

분류 라우터 ID AvgPerf% ID CumReg OOD AvgPerf% OOD CumReg
상한 Oracle 57.00 0 75.89 0
Agent-as-a-Router ACRouter (제안) \mathbf{49.98} \mathbf{205.5} \mathbf{62.50} \mathbf{17.0}
Online Bandit LinUCB 46.84 296.9 49.82 31.1
Online Bandit LinTS 46.48 307.4 46.43 35.9
Heuristic DimensionBest 47.50 277.4 -- --
Heuristic kNN Retrieval 47.18 286.7 14.29 66.7
Trained Policy LogReg 47.26 284.4 19.64 61.8
Trained Policy RouteLLM-BERT 47.22 285.5 21.43 59.4
Trained Policy Qwen3.5-0.8B-FT 46.41 309.1 55.36 27.2
Single-Model Always-Opus 4.6 43.83 387.1 57.14 26.7
Single-Model Random 38.75 533.6 31.25 50.4

아래 그림은 작업 스트림이 진행됨에 따라 누적 후회가 어떻게 쌓이는지를 보여줍니다. 정적 라우터들은 후회가 가파르게 증가하는 반면(경량 분류기는 284 ~ 317 , 밴딧은 297 ~ 307 ), ACRouter만이 Memory에 검증된 경험이 쌓이면서 후회 곡선의 기울기가 눈에 띄게 완만해집니다. 정보 격차를 배포 중에 능동적으로 메워나가는 모습이 그대로 드러납니다.

그런데 한 가지 의문이 남습니다. ACRouter는 어떻게 차원별 최적 모델을 완벽히 아는 DimensionBest마저 앞설 수 있었을까요? 연구팀은 변동 분해(variance decomposition) 분석으로 답을 제시합니다. oracle이 고른 최적 모델과 작업 차원 사이의 상호 정보량(mutual information)을 측정해 보니, 차원 정보는 oracle 결정의 엔트로피 중 약 27\% 만 설명 했습니다. 이 27\% 가 DimensionBest가 0.475 수준의 성능에 도달하는 이유이지만, 동시에 0.570 의 작업별 oracle에는 한참 못 미치는 이유이기도 합니다. 나머지 라우팅 신호는 차원 같은 거친 분류가 아니라 개별 작업의 내용(알고리즘 선택, API 패턴, 엣지 케이스 처리)에 숨어 있습니다. ACRouter의 작업 임베딩 기반 Memory는 바로 이 세밀한 신호를 키로 삼기 때문에, 차원 해시에 의존하는 DimensionBest가 도달할 수 없는 영역까지 파고들 수 있는 것입니다.

OOD 일반화: 정적 라우터의 붕괴

진짜 시험대는 분포 밖(OOD) 에이전트형 프로그래밍 작업입니다. 이 작업들은 라우터를 보정한 9 개의 단일 턴 차원과 거의 겹치지 않아, 실제 현실 환경에 훨씬 가깝습니다. 여기서 정적 라우터들의 민낯이 드러납니다.

경량 분류기들(LogReg, TF-IDF+MLP, RouteLLM-MF, RouteLLM-BERT)은 분포 내에서는 DimensionBest와 1.3\% 이내의 작은 격차를 보였지만, OOD에서는 평균 성능이 8.93\% ~ 21.43\% 로 급락했습니다. 무작위 선택(Random, 31.25\% )보다도 낮은 수치입니다. 학습 집합의 분포에 심하게 과적합(overfit)되어, 큰 분포 이동(distribution shift) 앞에서 일반화에 실패한 것입니다.

온라인 밴딧(LinUCB, LinTS)은 계속 온라인으로 갱신되는 덕에 좀 더 잘 버텨(49.82\% / 46.43\% ) 살아남았지만, 여전히 ACRouter에는 못 미쳤습니다. 팔 별 선형 모델만으로는 Orchestrator와 Memory가 제공하는 맥락 인식 추론을 따라갈 수 없기 때문입니다.

반면 ACRouter는 OOD에서 62.50\% 의 평균 성능 으로, 가장 강력한 단일 모델 전략인 Always-Opus(57.14\% )와 미세조정한 Qwen3.5-0.8B(55.36\% )를 모두 앞섰습니다. 참고로 갱신된 GPT-5.4 백엔드를 단독으로 돌리면 동일한 OOD 작업의 75.00\% 를 해결하는데, 이는 이 OOD 설정이 백엔드 수준의 강력한 성능 향상까지 드러낼 수 있는 무대임을 보여줍니다.

OOD에서 한 가지 흥미로운 구조적 차이가 나타납니다. 분포 내에서는 5 개 모델이 차원별 최강자 자리를 나눠 가질 만큼 강점이 분산되어 있었지만, 에이전트형 프로그래밍이라는 단일 OOD 차원에서는 성능이 기본 코딩 능력 순서로 더 강하게 정렬 됩니다. 백엔드별 해결률(resolved-rate)을 보면 GPT-5.4가 75.00\% (132/176 ), Opus 4.6이 57.14\% , Sonnet 4.6이 49.11\% 이고, 나머지는 30\% 아래로 떨어집니다. 즉 단일 턴 코딩에서 빛나던 모델 상호 보완성이 장기 호흡(long-horizon) 작업에서는 약해지고, 다단계 계획과 반복 디버깅을 끝까지 해내는 근본 역량이 더 중요해진다는 뜻입니다. 또한 OOD 점수는 패치가 깔끔하게 적용되는지만 보는 느슨한 지표(apply_ok)가 아니라, 저장소의 테스트가 실제로 통과하는지를 채점하는 엄격한 해결률을 사용해 정직하게 측정했습니다.

비용 대비 성능 프론티어

ACRouter는 Memory와 Verifier를 돌리는 만큼 추가 비용을 치릅니다. 그럼에도 비용 효율(성능을 비용으로 나눈 값)이 ID에서 3.79 , OOD에서 1.18 로, 항상 Opus만 쓰는 전략(ID 1.29 , OOD 0.64 )을 모두 능가합니다. 즉, 더 비싼 단일 프리미엄 모델을 고집하는 것보다 ACRouter가 더 높은 성능을 더 적은 비용으로 달성합니다.

위 파레토 프론티어 그림에서 ACRouter(분홍색 다이아몬드)는 배포 가능한 라우터들의 최적 절충선을 위쪽으로 확장하며, oracle(검은 별)과의 격차를 가장 크게 좁힌 위치에 자리합니다.

분포 내 비용을 좀 더 뜯어보면, 라우터들은 세 가지 배포 비용 구간으로 나뉩니다. 저렴한 구간(학습된 분류기, 총 7 ~ 8 달러대)은 라우터 토큰 부담이 거의 없고 상당수 작업을 중간 티어 모델로 보내 DimensionBest에 근접한 성능을 최소 비용으로 얻습니다. 중간 구간(DimensionBest 12.89 , ACRouter 13.21 , 온라인 밴딧 10 ~ 11 달러)은 비싼 모델과 싼 모델을 정보에 기반해 섞어 쓰는 대가로 더 높은 품질을 얻으며, ACRouter는 여기에 Memory와 Verifier 비용을 추가로 지불합니다. 프리미엄 구간(Always-Opus 34.02 , Random 15.64 등)은 비싼 기본 모델에 모든 것을 거는 방식입니다. Always-Opus는 34.02 달러를 쓰고도 43.83\% 에 그치는 반면, ACRouter는 13.21 달러로 49.98\% 를 달성합니다. 가장 싼 단일 모델인 Always-Kimi-K2.5는 2.90 달러로 비용 하한선을 긋지만(36.66\% ), 성능을 크게 희생합니다.

흥미로운 발견: 코딩 실력 ≠ 라우팅 실력

앞서 본 정보 부족 진단이 특정 모델(Claude Sonnet 4.6)에만 해당하는 것은 아닌지 확인하기 위해, 연구팀은 8 개 모델 전부를 LLM 라우터 자리에 세워 비교했습니다. 결과는 코딩을 잘하는 것과 라우팅을 잘하는 것은 별개 라는 점을 분명히 보여줍니다. 8 개 LLM 라우터 모두 단순한 DimensionBest 휴리스틱에 못 미쳤고, 제로샷에서 그나마 가장 나은 라우터는 의외로 저가 모델인 Qwen3.5-Plus(46.87\% )였습니다. 반대로 개별 코딩 실력이 가장 강한 Claude Opus 4.6(39.27\% )과 Sonnet 4.6(41.41\% )은 라우터로서는 바닥권 을 기록했습니다. 3-shot 예시를 줘도 이 순위는 크게 바뀌지 않았습니다.

왜 강력한 모델이 라우터로는 약할까요? 보조 분석에 따르면, Vanilla LLM 라우터의 모델 선택 분포는 차원별 구조를 제대로 활용하지 못했습니다. 아래 그림은 작업별 oracle, DimensionBest, 그리고 LLM 라우터(0-shot, 3-shot)가 각 모델을 얼마나 자주 선택했는지를 보여줍니다.

oracle(초록)은 작업 특성에 따라 여러 모델에 고르게 표를 던지지만, LLM 라우터(주황, 보라)는 sonnet, opus, kimi 같은 익숙한 모델로 선택이 쏠립니다. 강력한 코더라도 어떤 모델이 어떤 작업에 강한지에 대한 사전 통계가 없으면, 차원별 구조를 활용하지 못하고 자신이 아는 모델로 편향되는 셈입니다. 좋은 코더가 반드시 좋은 작업 배분자는 아니며, 라우팅은 추론력이 아니라 적절한 정보 구조(검증과 메모리)를 갖춰야 풀리는 별개의 문제라는 것이 다시 한번 확인됩니다.

라우터의 크기보다 미세조정이 관건

그렇다면 Orchestrator의 정책 모델을 더 키우면 라우팅이 나아질까요? 연구팀은 Qwen3.5를 0.8\text{B} 부터 27\text{B} 까지 다섯 가지 크기로 동일한 LoRA 설정으로 미세조정해 비교했습니다. 결과는 명확합니다. 크기는 거의 무관하고, 미세조정 여부가 관건 이었습니다. 약 30\times 의 파라미터 범위에 걸쳐 평균 성능은 46.21\% 에서 46.74\% 로 단 0.5 포인트 정도만 움직였습니다. 라우팅 신호가 27\text{B} 보다 훨씬 작은 모델에서 이미 포화되는 것입니다.

반면 미세조정을 하지 않으면 큰 베이스 모델조차 형식에 맞지 않는 출력을 내뱉어 파서가 기본 모델(claude-sonnet-4-6)로 폴백하고, 성능이 항상 Sonnet만 쓰는 수준(0.4131 )으로 주저앉았습니다. 이것이 ACRouter가 거대한 라우터 대신 미세조정한 0.8\text{B} 모델을 핵심 정책으로 채택한 근거입니다. 가장 비용 효율적이면서도 더 큰 모델과 성능 차이가 사실상 없기 때문입니다.

한계점 및 시사점

연구팀은 몇 가지 한계를 솔직하게 밝힙니다.

첫째, 가장 중요한 한계는 비용 추정의 불확실성 입니다. 모델 제공자 측의 캐시 적중률(cache hit rate)은 관측할 수 없으므로, 비용은 공개된 토큰 단가와 측정된 토큰 사용량으로 계산한 추정치입니다. 따라서 논문은 "비용은 절대적 지표가 아니라 상대 비교를 위한 보조 지표로만 사용한다" 고 명시합니다.

둘째, 에이전트형 프로그래밍 평가는 예산을 감당하기 위해 표준 250 스텝 대신 40 스텝 제한을 사용했습니다(라우터 간 상대 비교에는 영향이 없습니다).

셋째, 현재 C-A-F 구현은 LLM 정책과 메모리 kNN 앙상블을 사용합니다. 파라미터 수준의 고급 메모리 기법 같은 다른 형태의 구현은 앞으로의 과제로 남아 있습니다.

이런 한계에도 불구하고, 이 연구가 던지는 메시지는 분명합니다. 라우팅을 한 번의 분류로 보는 정적 관점에서 벗어나, 실행 기반 피드백으로 정보 격차를 능동적으로 메워나가는 에이전트 로 재정의한 것이 핵심입니다. 연구팀이 결론에서 강조하듯, "실행 기반 피드백을 통해 정보 격차를 능동적으로 메우는 것"은 비단 모델 라우팅뿐 아니라, 이질적인 도구나 모델 사이를 오가야 하는 모든 에이전트 시스템을 구축하는 일반 원리가 될 수 있습니다.

실제로 C-A-F 루프(맥락 관찰, 행동, 피드백 수신, 맥락 갱신)는 모델 라우팅에만 묶이지 않습니다. 연구팀은 같은 패러다임이 도구 선택, API 엔드포인트 선택, 프롬프트 전략 선택, 추론 노력(thinking-effort) 배분 에도 그대로 적용된다고 봅니다. 이들은 모두 "여러 선택지 중 무엇을 고를지를 실행 결과로부터 학습한다"는 동일한 구조를 갖기 때문입니다. 코딩 작업 라우팅은 더 넓은 에이전트 의사결정 패러다임의 첫 구체적 사례인 셈이며, 향후 스킬 라우팅, 서브 에이전트 라우팅, 메모리 라우팅 등으로 확장될 수 있습니다.

CodeRouterBench 자체도 살아있는 프로토콜을 지향합니다. 현재 V1은 10 개 차원, 8 개 모델, 약 80\text{K} 개의 실행 검증된 응답을 제공하며, 새 모델은 기존 작업 집합에 응답을 생성하는 것만으로(모델당 약 11\text{K} 회 호출), 새 차원은 C-A-F 삼중항과 채점 함수를 제공하는 것만으로 추가할 수 있도록 설계되었습니다.

모델 생태계가 오픈소스, 도메인 특화, 추론 특화 모델로 계속 확장될수록, 각 모델의 강점은 더 다양해지고 비용 격차는 지속될 것입니다. 그렇다면 라우팅은 일시적 유행이 아니라 에이전트 시스템의 영구적인 구성 요소 로 자리 잡을 가능성이 높습니다. 한 명의 만능 천재에게 모든 일을 맡기는 시대에서, 각자의 강점을 아는 유능한 팀장이 일을 배분하는 시대로 넘어가고 있는 셈입니다.

실전 가이드: 나만의 에이전트 라우터 만들기

이 논문의 진짜 산출물은 순위표가 아니라 조립 키트(construction kit) 라는 점이 인상적입니다. 연구팀은 자신의 환경에서 라우터를 점진적으로 구축하는 단계별 레시피를 제시합니다.

  1. 도구 계층부터 세팅: 후보 모델들을 연결하고 실행 샌드박스를 구성합니다.
  2. 탐침 집합으로 프로파일링: CodeRouterBench나 자신의 작업으로 차원 \times 모델 성능 행렬을 만듭니다.
  3. DimensionBest로 시작: 정적 Memory와 룩업 테이블만으로도 oracle 평균 성능의 약 83\% 를 거의 비용 없이 달성합니다. 이것이 기준선입니다.
  4. 분류기 추가: 라우팅 도구를 학습된 분류기(LogReg, RouteLLM)로 교체하면 DimensionBest와 비슷한 성능을 더 저렴하게 배포할 수 있습니다.
  5. C-A-F 루프 완성(ACRouter): 새로운 분포에 배포할 때는 세 모듈을 모두 켜서 피드백 루프를 닫습니다. 가진 사전 정보로 Memory를 초기화하면, 루프가 돌면서 수렴해 갑니다.
  6. 도구 커스터마이징: Verifier의 평가 도구를 도메인 특화 테스트로 교체하거나, 맞춤 라우팅 도구를 추가합니다.
  7. 벤치마크 확장: C-A-F 삼중항으로 새 작업을 추가합니다. 새 모델은 응답과 채점이, 새 차원은 작업 집합과 채점 함수가 필요합니다.

핵심은 비싼 라우터를 처음부터 만들 필요가 없다는 점입니다. 정적 룩업으로 oracle의 83\% 까지 거의 공짜로 올린 뒤, 분포 이동이 우려되는 실제 배포 환경에서만 검증과 메모리를 켜서 C-A-F 루프를 완성하면 됩니다.

ACRouter 사용해보기

ACRouter는 GitHub 저장소를 통해 재현 가능한 구현과 CodeRouterBench 데이터, 참조 출력, 그리고 자신의 워크플로우에 라우터를 붙일 수 있는 데모를 함께 공개합니다. 오프라인 재현은 API 키나 실제 모델 호출 없이도 캐시된 결과로 동작합니다.

cd open-source-acrouter

conda create -n acrouter python=3.11 -y
conda activate acrouter

python -m pip install --upgrade pip setuptools wheel
python -m pip install -r requirements.txt
python -m pip install -e .

python -m unittest discover -s tests

주요 결과를 재현하려면 아래 스크립트를 실행합니다.

# 분포 내(ID) 테스트 재생
python scripts/run_id.py --output-dir outputs/tmp/id

# OOD176에서 ACRouter 실행
python scripts/run_acrouter_ood176.py --output-dir outputs/tmp/acrouter_ood176

# OOD176 베이스라인과 논문 스타일 표 생성
python scripts/run_baselines_ood176.py --output-dir outputs/tmp/baselines_ood176

추론 시점에 라우터를 직접 통합하려면 ACRouter 클래스를 가져와 사용합니다.

from acrouter_repro.inference import ACRouter

router = ACRouter(
    candidate_models=["cheap-model", "strong-model"],
    cheap_chain=["cheap-model"],
    escalate_to="strong-model",
    k=1,
)

decision = router.run_with_verifier(
    task={"task_id": "task_001", "dimension": "bug_fixing", "prompt": "..."},
    call_model=lambda model, task: call_your_backend(model, task),
    verify=lambda response, task, model: run_your_checks(response, task),
)

print(decision.chosen_model, decision.final_response)

이 외에도 OpenRouter 호환 모델 목록을 검증기가 통과할 때까지 순회하는 API 코딩 솔버 데모와, 로컬 Codex, Claude Code, opencode CLI로 프롬프트를 라우팅하는 데모가 포함되어 있습니다.

:scroll: Agent-as-a-Router: Agentic Model Routing for Coding Tasks 논문

:house: Agent-as-a-Router 프로젝트 홈페이지

:github: agent-as-a-router GitHub 저장소

ACRouter의 공식 구현과 CodeRouterBench 데이터, 참조 출력, 라우터 연동 데모를 담은 저장소입니다.

:hugs: CodeRouterBench 데이터셋 (Hugging Face)

:hugs: ACRouter Qwen3.5-0.8B 라우터 어댑터 (Hugging Face)




이 글은 GPT 모델로 정리한 글을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 덧글로 알려주시기를 부탁드립니다. :hugs:

:pytorch:파이토치 한국 사용자 모임:south_korea:이 정리한 이 글이 유용하셨나요? 회원으로 가입하시면 주요 글들을 이메일:love_letter:로 보내드립니다!
텔레그램(Telegram)이나 Slack/Discord/Teams/Dooray/GoogleChat 등으로도 새 글 알림을 받으실 수 있습니다. :smiley:

:wrapped_gift: 아래:down_right_arrow:쪽에 좋아요:+1:를 눌러주시면 새로운 소식들을 정리하고 공유하는데 힘이 됩니다~ :star_struck: