Rust로 구축하는 ZeroClaw: LLM 기반 멀티 에이전트 런타임 아키텍처

Rust로 구축하는 ZeroClaw: LLM 기반 멀티 에이전트 런타임 아키텍처

최근 LLM(Large Language Model)을 활용한 자동화와 에이전트 시스템에 대한 관심이 뜨겁습니다. 하지만 단일 에이전트로 복잡한 작업을 처리하는 데에는 한계가 있으며, 이를 해결하기 위해 **멀티 에이전트 시스템(Multi-Agent System)**이 주목받고 있습니다. 이번 포스트에서는 고성능과 안정성을 위해 Rust로 작성된 에이전트 런타임인 ZeroClaw의 아키텍처를 소개하고, 실제로 에이전트 간 통신을 어떻게 구조화하는지 살펴보겠습니다.

1. 왜 Rust인가? (Performance & Safety)

LLM 애플리케이션은 대부분 Python으로 작성되곤 합니다. 하지만 여러 에이전트가 동시에 실행되고 각자 독립된 메모리 공간이나 파일 시스템을 제어해야 하는 ‘런타임’ 환경에서는 Rust의 강력한 병렬 처리 능력과 메모리 안전성이 큰 무기가 됩니다.

특히, 최근 Hacker News에서 논의된 것처럼 “LLM 에이전트의 백엔드 코드 생성 취약점(Constraint Decay)” 문제가 대두되고 있습니다. LLM이 생성한 코드가 의도치 않게 시스템 제약을 무너뜨리는 상황에서, Rust의 타입 시스템과 소유권(Ownership) 모델은 런타임 차원에서 안전망을 제공할 수 있습니다.

2. ZeroClaw의 핵심 아키텍처

ZeroClaw는 단순한 LLM 래퍼가 아니라, 에이전트의 생명주기를 관리하고 메시지를 중계하는 런타임 엔진입니다.

2.1. 파일 기반 상태 관리 (File-Based State Management)

복잡한 데이터베이스 없이 에이전트의 상태와 컨텍스트를 파일 시스템에 기반하여 관리하는 아키텍처를 채택했습니다. 이는 휴대성(Portability)과 디버깅 용이성을 높여줍니다.

// 에이전트 상태를 저장하는 구조체 예시
#[derive(Serialize, Deserialize, Debug)]
pub struct AgentState {
    pub id: String,
    pub role: AgentRole,
    pub status: ExecutionStatus,
    pub last_heartbeat: u64,
}

impl AgentState {
    pub fn save_to_file(&self, path: &Path) -> io::Result<()> {
        let json = serde_json::to_string_pretty(self)?;
        fs::write(path, json)?;
        Ok(())
    }
}

이 접근 방식은 Multi-Agent: 파일 기반 아키텍처 설계 논의에서 언급된 바와 같이, 각 에이전트가 자신의 상태를 투명하게 기록하게 하여 시스템 전체의 예측 가능성을 높입니다.

2.2. 이벤트 기반 통신 (Event-Driven Communication)

ZeroClaw의 에이전트들은 서로 직접 호출하지 않고, 중앙의 **이벤트 버스(Event Bus)**나 Pub/Sub 메커니즘을 통해 통신합니다. 이는 결합도(Coupling)를 낮추고 확장성을 확보합니다.

// 통신 프로토콜 메시지 정의
#[derive(Debug, Clone)]
pub enum AgentMessage {
    TaskRequest { task_id: String, payload: String },
    TaskResponse { task_id: String, result: String },
    StatusUpdate { agent_id: String, status: String },
}

// 간단한 채널 기반 메시지 라우터 (tokio::sync::mpsc 사용)
pub struct MessageRouter {
    // sender: HashMap<AgentId, Sender<AgentMessage>>
    // 실제 구현 시 에이전트별 채널을 관리
}

이러한 구조는 Claude Code 팀 에이전트 통신 아키텍처멀티 에이전트 통신 프로토콜 설계에서 고민되었던 ‘메시지 큐의 신뢰성’ 이슈를 Rust의 강력한 비동기 런타임(tokio)으로 해결하는 기반이 됩니다.

3. MCP(Model Context Protocol)와의 연동

ZeroClaw는 MCP 서버와 클라이언트 역할을 수행하여 외부 도구(예: 블로그 API, Discord Gateway)와 연동됩니다. 최근 blog-api-server에 추가된 언어 파라미터나 로깅 개선 사항들은 ZeroClaw 에이전트가 외부 시스템과 상호작용할 때 컨텍스트를 잃지 않도록 돕습니다.

에이전트가 MCP 도구를 호출하는 과정을 안전하게 래핑(Wrapping)하는 것은 중요합니다.

// MCP 도구 호출을 위한 안전한 래퍼
pub async fn invoke_mcp_tool(tool_name: &str, params: serde_json::Value) -> Result<String, AgentError> {
    // 1. 파라미터 검증 (Validation)
    if !validate_params(tool_name, &params) {
        return Err(AgentError::InvalidInput);
    }

    // 2. 실제 호출 (HTTP or IPC)
    let response = reqwest::Client::new()
        .post("http://localhost:8080/mcp/call")
        .json(&json!({
            "tool": tool_name,
            "args": params
        }))
        .send()
        .await?;

    // 3. 응답 파싱 및 로깅
    tracing::info!("MCP Tool {} called successfully", tool_name);
    Ok(response.text().await?)
}

4. 결론: 2026 상반기 발전 방향

ZeroClaw는 단순한 실험적 프로젝트를 넘어, 2026 상반기 발전방향 회의록에서 언급된 바와 같이 ‘고성능 에이전트 런타임’으로 진화하고 있습니다.

Rust의 성능을 바탕으로 LLM의 생성성(Creativity)과 시스템의 안전성(Safety)을 동시에 확보하는 것이 목표입니다. 특히, 최근 트렌드인 DeepSeek와 같은 효율적인 모델을 통합하여 비용 효율성까지 개선할 계획입니다.

다음 포스트에서는 ZeroClaw 에이전트가 실제로 코드를 생성하고 배포하는 CI/CD 파이프라인 연동 사례를 다루겠습니다.

참고 링크

Hugo로 만듦
JimmyStack 테마 사용 중