Agent Router · Intent-based routing
에이전트 라우터 — 의도 기반 라우팅
맥락
시스템이 저마다 다른 역량을 가진 전문 에이전트 묶음을 갖고 있다. 사용자는 자연어로 상호작용하는데, 그 자연어는 흔히 모호하고 표현이 제각각이며 무관한 잡음을 포함한다.
문제와 힘
구조화되지 않고 변동이 큰 자연어 요청을, 역량을 환각하지 않고 취약한 키워드 매칭에도 기대지 않으면서, 그 일에 가장 적합한 에이전트에 어떻게 정확히 대응시킬 것인가.
- 모호함 대 정밀함 — 사용자 입력은 막연하고 비구조적인데, 에이전트 실행은 정밀하고 구조화된 명령을 요구한다.
- 확장성 대 유지보수 — 새 에이전트를 더한다고 중앙 라우팅 로직을 다시 써야 해서는 안 된다.
- 안전 대 환각 — 처리할 수 없는 에이전트로 요청이 가는 일은 결코 없어야 한다. 가드레일 밖의 일을 시도하는 위험을 피해야 한다.
해법
두 단계로 나눈다. 첫째, 엄격한 스키마를 강제한 LLM으로 의미 기반 의도 추출을 수행해 원시 질의를 표준화된 동작(동사)과 자원(명사)을 담은 “의도 객체”로 옮긴다. 둘째, 그래프 제약 라우팅으로 조회표나 지식 그래프에 질의해, 그 특정 자원에 그 특정 동작을 수행할 역량을 주장하는 에이전트를 찾는다. 그래프에 유효한 경로가 있으면 라우팅하고, 없으면 미지원으로 거부한다.
사례 — 규제 준수 요청 라우팅
"3분기 재무 프로젝트의 최신 보안 감사는 어디에 있나?"
구현 예시 · Python
# 1. 시스템의 "어휘"를 정의한다 ActionType = Literal["find", "analyze", "create"] ResourceType = Literal["sales_report", "server_log", "document"] class RoutingIntent(BaseModel): action: ActionType resource: ResourceType parameters: dict class AgentRouter: def __init__(self): # 역량 그래프: (동작, 자원) → 에이전트 self.capability_graph = { ("find", "sales_report"): "SalesAgent", ("analyze", "sales_report"): "SalesAgent", ("find", "document"): "ComplianceAgent", ("create", "server_log"): "DevOpsAgent" } def route_request(self, intent: RoutingIntent): key = (intent.action, intent.resource) target = self.capability_graph.get(key) # 안전 점검: 그래프에 연결이 없으면 요청을 차단한다 if not target: return f"Error: No agent can '{intent.action}' a '{intent.resource}'." return self.dispatch_to_agent(target, intent.parameters)
장점
- 결합 해체 — 추출 계층은 에이전트 이름을 몰라도 되고, 에이전트는 자연어를 파싱하지 않아도 된다. 구조화된 “의도 객체”로 소통한다.
- 확장성 — 새 에이전트를 더하려면 역량을 그래프에 등록하기만 하면 된다. 라우팅 로직은 그대로다.
- 안전 — 그래프가 화이트리스트 노릇을 한다. 그래프에 명시적으로 정의되지 않은 이상 라우터는 “데이터베이스 삭제” 명령을 물리적으로 보낼 수 없다.
단점
- 지연 — 의도 추출 단계가 LLM 호출을 요구해, 실제 작업 전에 지연이 붙는다.
- 스키마 경직성 — 사용자가 사전 정의된 동작·자원 열거형에 맞지 않는 것을 요청하면 추출이 실패하거나 품질이 떨어진다.
구현 지침
성패는 스키마 정의의 품질에 크게 달렸다. 동작과 자원을 정할 때 “골디락스” 수준의 추상화를 노려야 한다. 너무 잘게 쪼개면(FindPDF, FindWordDoc) 라우팅 그래프가 비대해져 유지가 어렵고, 너무 넓으면(DoWork) 에이전트를 구별하는 능력을 잃는다. 대개 정규화된 동작과 자원 10~20개면 충분하다.
의미 기반 의도 추출에는 단순 프롬프트 엔지니어링보다 함수 호출 모드를 강력히 권한다. 엄격한 JSON 출력 구조를 강제해, 자유 텍스트 응답에서 흔한 파싱 오류를 없앤다.
마지막으로 라우팅 계층에 의미 캐시를 두는 것을 고려하라. 기업 환경에서는 비슷한 질문이 반복된다. 사용자 질의를 임베딩해 벡터 DB에서 유사 요청을 확인하면 반복 질의에 대해 LLM 추출 단계를 통째로 건너뛸 수 있어 지연과 비용이 크게 준다.