핵심 통찰 — 통신을 latent space로
표준 MAS의 비효율은 "agent 출력 → 텍스트화 → 다음 agent 입력" 사이클에서 온다. 자연어로 바꿀 때 정보가 손실되고 토큰도 폭주. RecursiveMAS는 이 변환 자체를 제거 — agent 간 latent state를 직접 전달.
"표준 멀티 에이전트의 가장 큰 병목은 에이전트끼리 주고받는 텍스트 메시지였다. 그 통신을 latent vector로 바꾸자 — 토큰은 최대 75% 줄고 정확도는 8% 올랐다."
Standard 멀티 에이전트는 에이전트끼리 자연어 텍스트로 대화한다 — 그게 가장 큰 토큰 비용이자 지연 원인이었다. RecursiveMAS는 그 통신을 latent vector로 바꾸고, 협업 자체를 recursion으로 모델링해서 9개 벤치마크에서 토큰 -75%, 속도 2.4x, 정확도 +8.3%를 동시에 달성했다.
표준 MAS의 비효율은 "agent 출력 → 텍스트화 → 다음 agent 입력" 사이클에서 온다. 자연어로 바꿀 때 정보가 손실되고 토큰도 폭주. RecursiveMAS는 이 변환 자체를 제거 — agent 간 latent state를 직접 전달.
멀티 에이전트 시스템을 단일 통합 latent-space recursive computation으로 캐스팅. 각 agent는 재귀 함수의 한 step. 라운드를 거듭할수록 latent state가 정제되는 구조.
이종(heterogeneous) agent들을 잇는 lightweight 연결 모듈. agent 출력의 latent representation을 다음 agent의 입력 공간으로 매핑. 텍스트로 떨어뜨리지 않고 "latent thought"를 그대로 전달.
Inner: 각 agent 내부 step의 forward/backward. Outer: 시스템 전체에 걸친 gradient-based credit assignment. 한 agent의 실수가 어디서 발생했는지 전체 recursion 라운드에 거꾸로 전파되어 co-optimize.
9개 벤치마크 (math · science · medicine · search · code 등)에서 정확도 평균 +8.3%, 추론 속도 1.2~2.4x, 토큰 사용 −34.6~−75.6%. 토큰 ↓ 정확도 ↑ 동시 달성이 핵심.
장점만 있는 건 아님. end-to-end 학습이 필수 (사전학습 LLM만 조립해서는 불가). 그리고 통신이 latent라 중간 trace를 사람이 읽을 수 없음 — 디버깅·해석 비용이 크게 늘어난다.
표준 MAS에서는 agent A의 출력이 토큰 시퀀스로 디코딩된 뒤 agent B의 프롬프트에 다시 인코딩된다. 이 왕복에서 정보가 평탄화되고, 매 turn마다 system prompt · tool 정의가 반복 전송된다.
RecursiveMAS는 디코딩을 건너뛰고 hidden state(latent vector)를 직접 전달한다. 토큰 수는 통신 차원만큼만, 정보 손실은 사실상 없음.
"agent 간 통신 자체가 토큰 비용의 주범"이라는 진단. 통신을 latent로 보내면 비용·지연 동시 해결.
N개의 이종 agent들이 RecursiveLink 모듈로 연결된다. 한 라운드에서 각 agent는 입력 latent state를 받아 처리한 뒤, 다음 agent로 전달할 latent을 출력 — 모든 출력이 다시 입력으로 돌아오는 recursion.
라운드 수는 작업 복잡도에 따라 적응적으로 결정. 깊을수록 latent state가 정제되지만 비용도 증가.
RecursiveLink는 latent representation을 다음 agent의 입력 차원으로 projection. lightweight (작은 MLP 수준)이라 추가 비용 미미.
agent 각각을 따로 학습하면 시스템 차원의 최적화가 되지 않는다. RecursiveMAS는 두 단계 gradient propagation으로 이를 해결.
Inner는 한 step 안에서 agent 출력 손실에 대한 local gradient, Outer는 모든 라운드에 걸친 시스템 출력 손실의 shared credit assignment. 한 agent가 잘못한 결과가 어디서 시작됐는지 전체 recursion에 거꾸로 전파된다.
저자들은 학습 stability에 대한 이론 분석도 제시. 일반 RNN처럼 unrolled gradient가 폭주하지 않게 normalization 적용.
대부분의 efficiency 논문은 품질 약간 손실하고 비용 크게 줄이는 트레이드오프를 보여준다. RecursiveMAS는 그 패턴을 깬다 — 토큰을 줄이면서 정확도가 함께 올라간다.
9개 벤치마크 (수학 · 과학 · 의료 · 검색 · 코드 생성) 전반에서 일관된 개선. 특히 토큰 절감 폭이 크다 (최저 -34.6%, 최고 -75.6%).
"통신 토큰이 본질적으로 낭비였다"는 가설을 지지하는 증거. agent들이 자연어로 서로 설명할 필요가 없는 영역이었던 셈.
가장 반직관적인 주장 — "agent들이 자연어로 서로에게 설명할 필요가 없다". 사람이 이해할 수 있게 만들기 위해 그동안 모든 통신을 텍스트로 강제해왔지만, agent 입장에서는 latent로 충분했고 오히려 정보 손실이 줄어 정확도까지 올랐다는 발견.
논문의 핵심 아이디어를 PyTorch 스타일로 재구성한 참고 구현. 실제 논문 코드와 다를 수 있고, 단순화한 의사 코드에 가깝다. 핵심은 — RecursiveLink로 latent 전달 + inner-outer gradient propagation.
import torch import torch.nn as nn class LatentAgent(nn.Module): """각 agent는 latent state z를 입력받아 새 z를 출력. 텍스트 디코딩 없이 다음 agent로 그대로 전달된다.""" def __init__(self, d_in: int, d_hidden: int, d_out: int): super().__init__() self.backbone = build_transformer(d_in, d_hidden) # 사전학습 LM self.out_proj = nn.Linear(d_hidden, d_out) def forward(self, z: torch.Tensor) -> torch.Tensor: # z: (batch, seq_len, d_in) — 텍스트 대신 latent로 입력 h = self.backbone(z) # latent space 안에서 reasoning return self.out_proj(h) # 다음 agent로 보낼 z'
encode → reason → decode_text 사이클. 여기서는 decode_text를 생략하고 hidden state를 그대로 다음 agent로 흘려보낸다. 사전학습 backbone은 그대로 쓰되 입출력 인터페이스만 바꾼 것.class RecursiveLink(nn.Module): """agent A의 출력 latent을 agent B의 입력 공간으로 매핑. 이종(heterogeneous) backbone 간 차원 차이를 흡수한다.""" def __init__(self, d_from: int, d_to: int): super().__init__() self.proj = nn.Sequential( nn.Linear(d_from, d_to), nn.LayerNorm(d_to), nn.GELU(), nn.Linear(d_to, d_to), ) def forward(self, z: torch.Tensor) -> torch.Tensor: return self.proj(z)
class RecursiveMAS(nn.Module): def __init__(self, agents: list[LatentAgent], links: list[RecursiveLink], max_rounds: int = 4): super().__init__() self.agents = nn.ModuleList(agents) self.links = nn.ModuleList(links) # len = len(agents) self.max_rounds = max_rounds self.halt = nn.Linear(agents[0].d_in, 1) # 라운드 정지 신호 def forward(self, z_init: torch.Tensor) -> torch.Tensor: z = z_init for k in range(self.max_rounds): # 한 라운드: 모든 agent를 순환 통과 for agent, link in zip(self.agents, self.links): z = agent(z) z = link(z) # 적응적 halt — 더 정제할 필요 없으면 종료 if torch.sigmoid(self.halt(z.mean(dim=1))).mean() > 0.9: break return z
def train_step(model: RecursiveMAS, batch, criterion, optimizer): z_init, target = batch optimizer.zero_grad() # Outer: 전체 시스템 forward — 모든 agent · 모든 라운드 z_final = model(z_init) outer_loss = criterion(z_final, target) # 핵심: backward가 모든 라운드에 걸쳐 흐른다. # 한 agent의 출력 오류가 어느 round · 어느 agent에서 시작됐는지 # gradient-based credit assignment으로 자동 추적. outer_loss.backward() # gradient clipping — recursion으로 인한 폭주 방지 nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step() return outer_loss.item()
class RecursiveMASPipeline: """사용자는 텍스트로 input/output하지만, 내부에서는 latent로 작동.""" def __init__(self, model: RecursiveMAS, tokenizer, encoder, decoder): self.model = model self.tok = tokenizer self.enc = encoder # 텍스트 → latent self.dec = decoder # latent → 텍스트 def __call__(self, prompt: str) -> str: # 1) 진입: 텍스트를 latent로 한 번만 인코딩 tokens = self.tok(prompt, return_tensors="pt") z = self.enc(tokens.input_ids) # 2) 내부 협업: 전부 latent space에서. 디코딩 없음. z_out = self.model(z) # 3) 최종 출구에서만 텍스트로 디코딩 ids = self.dec(z_out) return self.tok.decode(ids[0], skip_special_tokens=True)
위 코드는 아이디어를 보이기 위한 단순화다. 논문 본문에는 RecursiveLink의 더 정교한 구조 · halt mechanism · gradient stability proof · 9개 벤치마크별 ablation이 자세히 다뤄진다. 실제 구현은 저자들이 공개할 코드를 기다리는 게 좋다.