포스트

Multica로 코딩 Agent를 비동기 운영해도 될까: daemon, 작업 큐, 권한

Multica는 로컬의 AI CLI 실행을 daemon과 작업 보드에 연결해 코딩 과제를 비동기로 관리하려는 플랫폼입니다. 터미널을 계속 지켜보는 시간을 줄일 수 있지만, Agent가 “동료”가 되는 것은 아니며 작업 격리, 중단, 검토 책임은 운영자가 그대로 집니다. 작은 반복 작업에서 기존 대화형 CLI와 비교한 뒤 비동기 관리 비용보다 이득이 큰 경우에만 넓히는 편이 좋습니다.

Multica 저장소의 핵심 질문은 모델 성능보다 실행 수명 주기입니다. 이슈를 누가 가져갔는지, 어떤 workspace와 runtime에서 돌았는지, 어디서 막혔고 무엇을 변경했는지를 control plane에서 추적하려 합니다.

Control plane과 local daemon은 무엇을 나눌까

Multica는 작업 상태를 관리하는 control plane과 실제 코드를 만지는 local daemon을 분리합니다. 이 경계는 중앙 서비스가 소스 저장소 전체를 직접 실행할 필요를 줄이지만, daemon이 가진 로컬 권한과 외부 모델로 보내는 데이터까지 자동으로 제한하지는 않습니다.

기존 AI 코딩은 개발자의 IDE나 터미널 안에서 동기적으로 실행되었습니다. 반면 Multica는 중앙화된 대시보드(웹/PostgreSQL 기반)에서 작업 큐를 관리하고, 실제 코드가 실행되는 환경(로컬 PC나 클라우드 서버)에는 경량 데몬(Daemon)을 띄워 비동기적으로 통신합니다.

Runtime 감지는 sandbox를 뜻하지 않는다

multica daemon start 뒤 daemon이 PATH에서 사용 가능한 AI CLI를 찾아 실행한다는 구조로 설명됩니다. 여러 runtime을 같은 인터페이스로 다룰 수 있지만 실행 프로세스가 호스트의 기본 사용자 권한을 그대로 받으면 workspace 밖 파일, 자격 증명과 네트워크에도 닿을 수 있습니다. 별도 container나 제한 계정, 명시적 mount와 egress 정책이 필요합니다.

WebSocket 이벤트가 곧 신뢰할 수 있는 진행률은 아니다

에이전트에게 칸반 보드에서 이슈를 할당하면, 데몬은 해당 작업을 Polling하는 대신 WebSocket을 통해 실시간으로 스트리밍받습니다. 데몬 내부의 실행 루프를 의사 코드(Pseudo-code)로 상상해 보면 다음과 같은 구조를 가집니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// multica-daemon 내부의 작업 실행 루프 (의사 코드)
async function executeAgentTask(task: Task, workspace: Workspace) {
  // 1. 가용한 AI CLI 런타임 감지 (Claude Code, Codex 등)
  const runtime = detectAvailableRuntime(workspace.env);
  
  // 2. 에이전트를 위한 격리된 실행 프로세스 생성 (Headless 모드)
  const process = runtime.spawnCommand({
    instruction: task.description,
    cwd: workspace.path
  });

  // 3. stdout/stderr 스트림을 파싱하여 WebSocket으로 컨트롤 플레인에 전송
  for await (const logChunk of process.stdout) {
    const parsedEvent = parseAgentAction(logChunk);
    
    if (parsedEvent.type === 'BLOCKER') {
      // 에이전트가 막혔을 때 작업을 일시 정지하고 인간에게 알림
      await notifyHumanTeammate(task.id, parsedEvent.reason);
      process.pause(); 
    } else {
      // 실시간 진행률 업데이트
      await streamProgressToDashboard(task.id, parsedEvent.diff);
    }
  }
}

WebSocket은 stdout, stderr와 상태 이벤트를 빠르게 전달할 수 있지만 CLI 출력 형식이 바뀌면 BLOCKER 감지가 누락될 수 있습니다. 일정 시간 출력이 없을 때의 timeout, 최대 명령, 토큰, 비용, test 실패 횟수와 사람 승인이 필요한 명령을 daemon 자체의 정책으로 둬야 합니다.

비교표는 운영 책임의 위치를 보여 준다

비교 항목기존 AI 코딩 (Cursor, Copilot)Claude Managed AgentsMultica (Open-Source)
인터랙션 방식1:1 동기식 프롬프팅 (채팅/인라인)비동기 작업 할당비동기 작업 할당 (칸반 보드)
실행 환경로컬 IDE 종속Anthropic 클라우드 인프라로컬 데몬 + 클라우드 런타임 (선택 가능)
벤더 종속성특정 모델 혹은 IDE 종속Claude 독점Vendor-Neutral (Claude, Codex 등 지원)
지식 축적채팅 히스토리 (휘발성)프로젝트 컨텍스트Reusable Skills (팀 단위 영구 축적)

어떤 작업부터 비동기로 맡길까

첫 시험 과제는 기대 diff와 자동 test가 분명하고 운영 자격 증명이 필요 없는 작업이어야 합니다. 여러 저장소를 병렬로 바꾸는 일은 처리량을 높일 수 있지만 같은 실수를 동시에 복제할 수 있으므로 한 저장소에서 결과를 검토한 뒤 넓힙니다.

여러 저장소의 ORM 변경

레거시 ORM을 바꾸는 작업이라면 저장소마다 이슈와 독립 workspace를 만들 수 있습니다. 하지만 migration 순서, 공유 schema와 호환 버전을 먼저 고정해야 합니다. Review 상태는 완료가 아니라 diff, test, migration rollback을 사람이 확인할 준비가 됐다는 뜻으로 정의합니다.

사내 인증 연동 Skill 재사용

성공한 해결 과정을 Skill로 남길 때는 자연어 요약만 저장하지 않습니다. 지원 API 버전, 필요한 환경 변수의 이름, 허용 명령, test와 더 이상 적용되지 않는 조건을 함께 버전화해야 합니다. 한번 성공한 로그에는 우연한 workaround나 비밀 값이 섞일 수 있으므로 게시 전 검토와 마스킹이 필요합니다.


실패 조건은 어디에서 생길까

비동기 실행의 실패는 모델 답변뿐 아니라 CLI parser, workspace 격리와 운영 절차에서 생깁니다.

CLI 출력 parser가 바뀔 수 있다

외부 CLI의 stdout을 해석한다면 버전 변경이나 대화형 prompt 추가로 이벤트 파싱이 깨질 수 있습니다. 지원 버전을 고정하고 대표 출력 fixture로 contract test를 돌리며, 알 수 없는 이벤트가 오면 계속 실행하지 말고 중단해야 합니다.

daemon 권한이 작업 경계를 넘을 수 있다

multica daemon을 root나 일상 개발 계정으로 띄우면 잘못된 명령이 workspace 밖 파일과 .env에 닿을 수 있습니다. 버릴 수 있는 clone, 최소 권한 계정과 네트워크 제한을 사용하고 배포, 삭제, secret 접근은 사람 승인 없이는 실행되지 않게 해야 합니다.

작은 수정에는 관리 절차가 더 비쌀 수 있다

작은 스크립트에도 workspace 생성, 이슈 발행과 review 상태 변경이 필요하면 대화형 도구보다 오래 걸립니다. 작업당 준비 시간, 사람 개입 횟수, merge까지 걸린 시간과 되돌린 비율을 기존 방식과 비교해야 합니다.


도입은 완료율보다 안전한 인계율로 판단한다

한 개의 버릴 수 있는 저장소에서 읽기, 수정 범위가 좁은 작업 10개로 시작합니다. daemon이 스스로 완료했다고 표시한 비율뿐 아니라 사람이 추가 수정 없이 승인한 비율, 잘못된 파일 접근, 중단 이후 복구 시간과 로그 누락을 기록합니다. 비동기 실행이 사람의 관찰 시간을 줄이면서도 review 부담을 늘리지 않을 때 범위를 넓힐 수 있습니다.

Multica의 실질적 가치는 Agent를 사람처럼 부르는 데 있지 않고 실행 상태와 인계물을 중앙에서 추적하는 데 있습니다. control plane과 daemon 사이의 연결이 끊겨도 안전하게 멈추고, 어떤 runtime, prompt, commit이 결과를 만들었는지 재현할 수 있어야 관리 플랫폼의 이점이 생깁니다.

평가표에는 과제별 시작 commit, 허용 파일, 성공 test와 최대 실행 시간을 적습니다. Agent가 다른 파일을 건드리거나 test를 삭제해 녹색 결과를 만든 경우에는 완료로 세지 않습니다. 결과 branch는 사람이 merge하기 전 보호하고, 동시에 수행한 작업들이 같은 dependency 파일을 수정하면 자동으로 후속 작업을 멈춰 충돌이 연쇄되지 않게 합니다.

control plane 장애도 연습해야 합니다. 연결이 끊겼을 때 daemon이 이전 명령을 계속 실행하는지, 재접속 후 같은 task를 두 번 가져오는지, 중단 요청이 실제 자식 process까지 전달되는지 확인합니다. heartbeat가 사라진 실행은 상태만 “실패”로 바꾸는 데 그치지 말고 process와 workspace를 확인한 뒤 재할당해야 합니다.

관측 로그에는 자연어 진행률만 두지 말고 실행한 명령, exit code, 변경 파일, test 결과와 승인 사건을 시간순으로 연결합니다. 다만 stdout에는 secret이나 고객 데이터가 포함될 수 있으므로 업로드 전 마스킹하고, control plane에서 누가 어느 task 로그를 열람할 수 있는지 제한해야 합니다. 이 기록이 있어야 “Review” 카드가 실제로 무엇을 했는지 재현할 수 있습니다.

작업 보드가 유용하려면 사람이 개입해야 할 상태를 너무 넓게 잡지 않습니다. dependency 선택, 범위 확장, 외부 접근처럼 결정이 필요한 blocker와 일시적 lint 실패처럼 Agent가 정해진 횟수 안에서 고칠 오류를 구분합니다. 모든 경고가 알림이 되면 운영자는 결국 dashboard를 계속 바라보게 되어 비동기화의 이점이 사라집니다.

원문과 버전 확인

함께 읽으면 이해가 이어지는 글

자주 묻는 질문

Multica를 쓰면 코딩 Agent를 지켜보지 않아도 되나요?

완전히 맡길 수는 없습니다. 실행 중단 조건, diff, test 검토, 권한 요청과 실패 알림을 설계해야 비동기 실행이 안전해집니다.

로컬 daemon이면 코드와 비밀정보가 자동으로 안전한가요?

아닙니다. daemon의 사용자 권한, 연결된 모델의 전송 경로, 작업 디렉터리와 로그를 별도로 격리하고 제한해야 합니다.

재사용 Skill은 어떻게 검증해야 하나요?

생성 근거와 적용 조건, 허용 명령, 테스트를 버전과 함께 저장하고 다른 저장소에서 쓰기 전 사람의 검토를 거쳐야 합니다.

THE END / OPSOAI

여기까지 읽었습니다

핵심 장면을 한 번 더 떠올려 보세요. 이해가 남았다면 이 책은 제 역할을 다했습니다.

다른 책 고르기
표지 1 —

←→ 키와 좌우 스와이프를 지원합니다. 읽던 페이지는 이 기기에 저장됩니다.

CONTENTS

이 책의 목차

    8개 장 17 분읽는 시간