123 lines
9.7 KiB
Markdown
123 lines
9.7 KiB
Markdown
# Multi-Agent Mux: Skill Features and Architecture
|
|
|
|
이 문서는 `multi-agent-mux` 워크스페이스 내에 구현된 6개의 개별 스킬 및 공통 라이브러리의 핵심 기능, 상태 머신, CLI 사양, 그리고 상호 연동 방식을 종합 정리한 명세입니다. 스킬 최적화 및 팩토링 작업의 기준서로 사용됩니다.
|
|
|
|
---
|
|
|
|
## 1. 아키텍처 개요 (Architecture Overview)
|
|
|
|
`multi-agent-mux`는 다중 자율 에이전트(Claude, Agy, Cline, Hermes 등)를 격리된 Tmux 세션 환경에서 관리하고 상호 통신할 수 있게 돕는 시스템입니다.
|
|
* **중앙 상태 레지스트리**: `.mam/agent-sessions.yaml` 및 동기화된 `.mam/agent-sessions.db` (SQLite3)
|
|
* **격리 소켓**: 독립된 tmux 서버 소켓 지정 구동 가능 (예: `multi-agent-mux` 서버)
|
|
* **이벤트 버스**: MQTT 프로토콜 기반의 실시간 작업 상태 비동기 관찰 (`multi-agent-mux-delegate-job`)
|
|
|
|
---
|
|
|
|
## 2. 공통 라이브러리: `lib.sh` (Common Library)
|
|
|
|
모든 스킬 스크립트가 로드하여 사용하는 핵심 공유 헬퍼 라이브러리입니다.
|
|
|
|
* **상태 파일 원자적 덤프 (`atomic_dump_yaml`)**:
|
|
* NFS(네트워크 파일 시스템) 감지 시 SQLite `PRAGMA journal_mode=DELETE` 폴백, 로컬 환경에서는 `PRAGMA journal_mode=WAL` 설정.
|
|
* 독점 잠금(`BEGIN IMMEDIATE`)을 활성화해 멀티프로세스 환경에서 Read-Modify-Write 데이터 유실(lost update race condition) 방지.
|
|
* 트랜잭션 커밋 완료 후 `.bak` 백업 파일 생성 및 임시파일 생성 후 `os.replace` 원자적 대체 기법 적용.
|
|
* **에이전트 세션 실재성 판단 (`*_exists` 함수군)**:
|
|
* `claude`: 프로젝트 디렉터리 하위 `<uuid>.jsonl` 존재성
|
|
* `agy`: `.gemini/antigravity-cli/conversations/<uuid>.db` 존재성
|
|
* `hermes`: `~/.hermes/state.db`의 `sessions` 테이블 내 존재성 (SQLite 쿼리 검증)
|
|
* `cline`: `.cline/data/sessions/<uuid>/<uuid>.json` 존재성
|
|
* **세션 ID 해석 엔진 (`find_workspace_uuid` 분기 구조)**:
|
|
* **Tier 1 (YAML 직접 조회)**: YAML 내 기록된 에이전트별 전용 필드(`claude_session_id_own` 등) 조회.
|
|
* **Tier 2 (디스크 잔해 스캔)**: 워크스페이스 디렉터리(`cwd` / `workspace_root`)와 매칭되는 디스크 상의 세션 로그 중 가장 최근 수정일(`mtime`) 기준 정렬 후 최신 UUID 반환.
|
|
* **Tier 3 (아이덴티티 캐시)**: 레지스트리 상단 `agent_identities` 캐시 데이터 연동.
|
|
|
|
---
|
|
|
|
## 3. 스킬별 상세 핵심 기능 (Skill Specifications)
|
|
|
|
### 3.1. `multi-agent-mux-create` (생성 스킬)
|
|
* **용도**: 신규 에이전트 동작용 격리된 Tmux 컨테이너 생성 및 레지스트리 신규 등록.
|
|
* **핵심 기능**:
|
|
* **사전 기능 검증 (Preflight Check)**:
|
|
* `claude`: `claude auth status`를 통한 로그인 상태(`"loggedIn": true`) 검증
|
|
* `agy`: `agy models`를 통한 API 연동 정상 상태 검증
|
|
* `hermes`: `hermes status`를 통한 연동 상태 검증
|
|
* `cline`: `cline history --json` 동작 및 설정 상태 사전 검증
|
|
* **Tmux 세션 생성 및 초기화**: 에이전트별 최적화된 화면 크기(`-x 140 -y 40`) 및 작업 디렉터리(`-c`)를 적용해 세션 백그라운드 생성.
|
|
* **초기 상태 YAML 등록**: 사용자 필수 지정 역할(`--role`), `status: running`, `pane` 세부정보(인덱스, PID, CWD, CMD_FULL), 시작 명령 및 `mcp_attachments` 기록.
|
|
* **역할 불변성 보장**: 에이전트 생성 시 부여된 역할(`role`)은 사후 수정이 불가하며, 임의 변경 시도 시 데이터 검증(`atomic_dump_yaml`) 단계에서 예외 처리되어 방어됨.
|
|
|
|
### 3.2. `multi-agent-mux-resume` (재개 스킬)
|
|
* **용도**: 중지되었거나 유실된 에이전트의 이전 컨텍스트 그대로 Tmux 세션 및 TUI 연결 복원.
|
|
* **핵심 기능**:
|
|
* **세션 ID 해석 위임**: `lib.sh::find_workspace_uuid`을 구동하여 대상 워크스페이스의 UUID 확인.
|
|
* **세션 복원 기동**:
|
|
* `claude`: `claude --dangerously-skip-permissions -r <UUID>`
|
|
* `agy`: `agy --dangerously-skip-permissions --conversation <UUID>`
|
|
* `hermes`: `hermes --resume <UUID>`
|
|
* `cline`: `cline -i --id <UUID>`
|
|
* **TUI 바이패스 자동화 (Claude)**: 기동 직후 백그라운드에서 `Enter` ➔ `Down` ➔ `Enter` 키스트로크를 주입하여 권한 우회 및 복구 확인 대화상자 자동 수락.
|
|
* **동기화**: `update_yaml_resumed.sh`를 구동해 상태를 `running`으로 전이하고 기동 시점에 맞춘 하위 자식 PID 갱신 및 기존 종료 메타데이터 제거.
|
|
|
|
### 3.3. `multi-agent-mux-stop` (종료 스킬)
|
|
* **용도**: 세션을 안전하게 정리하고, 상태 및 UUID를 안전하게 저장 및 동기화.
|
|
* **핵심 기능**:
|
|
* **종료 전 TUI 스냅숏 저장**: `tmux capture-pane`을 수행해 최종 화면 상태를 `last_visible_status_at_termination` 필드에 보존.
|
|
* **다단계 Graceful 종료 프로토콜**:
|
|
1. TUI 안전 종료 키스트로크 주입 (`/exit` 또는 `Exit`) 후 3초 대기.
|
|
2. 생존 시 `tmux kill-session` 전송 및 5초 대기.
|
|
3. 최후 수단으로 감지된 자식 PID에 `kill -9` 전송.
|
|
* **디스크 소거 (--purge-conversation)**:
|
|
* `resumable`을 `false`로 설정하고 상태를 `terminated`로 기록.
|
|
* 에이전트별 데이터 경로에 접근해 해당 세션 파일 파쇄.
|
|
* `claude`: `<proj-key>/<uuid>.jsonl` 삭제
|
|
* `agy`: `conversations/<uuid>.db` 및 `brain/<uuid>` 폴더 삭제
|
|
* `hermes`: `sessions/session_<uuid>.json` 삭제 및 `state.db` 내 이력 삭제 (내부 독자 커넥션 `hconn` 사용으로 상위 YAML DB 충돌 차단)
|
|
* `cline`: `~/.cline/data/sessions/<uuid>` 폴더 소거
|
|
|
|
### 3.4. `multi-agent-mux-delegate-job` (위임 스킬)
|
|
* **용도**: 타 에이전트에게 비동기적으로 작업을 위임하고, MQTT 이벤트로 실행 상태 관찰.
|
|
* **핵심 기능**:
|
|
* **작업 지시 유형 (Delegation Types)**:
|
|
* `direct` (기본값): 단일 타겟 세션 기동 후 작업 전달 및 대기.
|
|
* `loop` (협업 루프): 구현자(Worker)의 작업 완료 후 검토자(Reviewer)가 코드 검수를 수행하여 `"PASS"` 의견이 나올 때까지 작업 수정을 자동 반복 지시.
|
|
* `discuss` (토론/합의): 두 에이전트 간 공동 토론을 추진하여 최종 기획 및 계획 합의 도출.
|
|
* **MQTT 이벤트 규격**: `publish_event.py`와 `job_subscriber.py`를 매핑하여 `started` ➔ `permission_required` ➔ `progress` ➔ `completed`/`error` 상태 전이 추적 및 자동 이중 타임아웃 검사 (전체 실행 예산 3600초 + 120초 유휴 타임아웃).
|
|
* **감사 로그 기록**: `.mam/delegate_job_logs/<job_id>/`에 `meta.json`, `status.json` 및 원시 NDJSON 형식의 `events.ndjson`을 영속 기록.
|
|
|
|
### 3.5. `multi-agent-mux-status` (현황 스킬)
|
|
* **용도**: 레지스트리를 읽어와 실행 중인 모든 에이전트의 구동 세션 현황을 즉시 표기.
|
|
* **핵심 기능**:
|
|
* **읽기 전용 안정성**: DB 수정이나 상태 전이 유발 없이 순수 조회만 수행.
|
|
* 실시간 tmux 프로세스 상태 정보와 YAML 간의 이름 매핑 정합성을 검증하여 콘솔에 요약 출력.
|
|
|
|
### 3.6. `multi-agent-mux-monitor` (화해 스킬)
|
|
* **용도**: 운영체제 Tmux 런타임과 YAML 레지스트리 데이터 불일치를 백그라운드 루프로 감지해 자동 화해(Reconciliation) 처리.
|
|
* **핵심 기능**:
|
|
* **Drift 감지 및 복구 매뉴얼**:
|
|
* **Drift A (Crash/죽은 세션)**: YAML 상 `running`이나 실제 tmux 프로세스가 죽은 경우 감지 ➔ 상태를 `terminated`로 격하 조정.
|
|
* **Drift B (새 세션 감지)**: YAML에 없으나 tmux 상에 임의로 떠 있는 `*-creator-*` 세션을 레지스트리에 자동 등록 및 자식 PID 정보 갱신.
|
|
* **Drift C (실시간 UUID 갱신)**: 새로 시작된 에이전트가 첫 명령을 받아 세션 ID를 생성했을 때, 디스크 상의 세션 로그 중 가장 수정시간이 일치하는 최신 UUID를 찾아 `*_conversation_id_own` 필드에 주입.
|
|
* **Drift D (캐시 정합성 점검)**: 레지스트리 및 캐시 상의 세션 UUID가 실제 디스크에 존재하는지 검사하여 소거된 세션을 리포트.
|
|
|
|
---
|
|
|
|
## 4. 에이전트 상태 머신 (Agent State Machine)
|
|
|
|
시스템 전반에 걸쳐 에이전트 세션은 아래 흐름을 따라 전이됩니다.
|
|
|
|
```mermaid
|
|
stateDiagram-v2
|
|
[*] --> running : multi-agent-mux-create / Drift B
|
|
running --> stopped : multi-agent-mux-stop (default)
|
|
running --> terminated : multi-agent-mux-stop (--purge-conversation) / Drift A
|
|
stopped --> running : multi-agent-mux-resume
|
|
terminated --> [*]
|
|
```
|
|
|
|
## 5. 최적화 및 팩토링 작업 시 주의 사항
|
|
|
|
1. **원자적 쓰기 무력화 금지**: `lib.sh`에 설정된 `atomic_dump_yaml`은 다중 에이전트 병렬 기동 시 데이터 꼬임을 막는 중추 역할을 합니다. DB 잠금 및 트랜잭션 흐름을 훼손하지 않아야 합니다.
|
|
2. **Cline 및 Claude의 TUI 입력 바인딩 유지**: 세션 재개나 중지 시, 각 에이전트가 내부적으로 사용하는 프롬프트 제어 명령어(예: `/exit`, `--id <session>`)의 세세한 차이를 유지해야 예외 없이 동작합니다.
|
|
3. **데이터베이스 변수 충돌 주의**: 서브셸 또는 인라인 Python 스크립트 실행 시 전역 SQLite 커넥션(`conn`)의 이름 공간을 절대 오염시키지 마십시오. (예: `stop_session.sh` 버그 재발 방지).
|