SKILL.md — Agha 액터 모델: 동시성 에이전트 시스템 설계
결정 포인트
작업 유형에 따른 액터 생성 전략 선택
IF 작업에 순차적 종속성이 있음:
├─ 고객 패턴 사용: 응답 주소로 하위 액터 생성
├─ 하위 액터에 고객 주소를 매개변수로 전달
└─ 하위 액터가 결과를 직접 고객에게 전송(부모에게 아님)
IF 작업에 긴 계산이 필요함:
├─ 계산용 둔감 액터 생성
├─ 들어오는 메시지를 버퍼 액터로 전달
└─ 계산 완료 시 버퍼에서 다시 시작
IF 동적 자원 할당이 필요한 작업:
├─ 필요에 따라 자원 관리자 액터 생성
├─ 기능(주소)을 메시지 데이터로 전달
└─ 중앙 레지스트리 없음 - 주소가 시스템을 통해 흐름
IF 실패 격리 요구 사항이 있는 작업:
├─ 위험한 작업을 위해 감독 하위 액터 생성
├─ 감독자는 누락된 응답을 통해 실패 감지
└─ 다른 액터에 영향을 주지 않고 실패한 액터 교체
IF 기존 에이전트 시스템을 구성하는 경우:
├─ 인터페이스가 인과 구조를 보존하는지 확인
├─ (고립뿐만 아니라) 구성 하의 동작 테스트
└─ (공유 상태가 아닌) 메시지 프로토콜을 경계로 사용
메시지 전송 대 상태 교체 의사 결정 트리
IF 다른 에이전트와의 조정이 필요함:
├─ 메시지 전송(먼저 로컬 상태를 수정하지 않음)
├─ 응답이 예상되면 응답 주소 포함
└─ 메시지 순서를 가정하지 않음
IF 로컬 계산이 필요함:
├─ 대체 행동 지정
├─ 새 상태 캡슐화(내부 노출하지 않음)
└─ 한 번에 하나의 메시지 처리를 보장
IF 동적 확장이 필요함:
├─ 특정 동작을 가진 새 액터 생성
├─ 필요한 주소를 새 액터에게 전달
└─ 공유된 초기화 상태 없음
실패 모드
1. 중앙 오케스트레이터 안티패턴
감지: 하나의 액터가 모든 메시지를 라우팅하거나 모든 시스템 상태를 보유하는 경우 증상: 단일 장애점, 부하 시 병목 현상, 무한 회귀 문제 해결 방법: 액터 커뮤니티로 분해, 각 액터는 로컬 컨텍스트만 인식, 기능 라우팅 사용
2. 동기 블로킹 오류
감지: 액터가 대체 행동을 지정하는 대신 응답을 기다리거나 차단하는 경우 증상: 부하 시 교착 상태, 숨겨진 타이밍 가정, 동시성 감소 해결 방법: 요청-응답 메시지 쌍으로 모델링, 의존성에 고객 패턴 사용, 둔감 액터 패턴 적용
3. 공유 상태 오염
감지: 여러 액터가 동일한 데이터 구조를 읽거나 쓰는 경우(잠금이 있더라도) 증상: 경합 조건, 순차적 병목 현상, 숨겨진 전역 상태 해결 방법: 단일 액터에 상태 캡슐화, 조정에 메시지 전달 사용, 상호 배제는 무료
4. 출력 전용 검증
감지: 상호 작용 패턴을 확인하지 않고 최종 출력만 비교하는 경우 증상: 브록-애커먼 이상 현상 - 동일한 출력이지만 다른 구성 동작 해결 방법: 인과 구조 보존 확인, 구성 하의 동작 테스트, 관찰 동등성 사용
5. 정적 토폴로지 가정
감지: 통신 그래프가 시작 시 고정되어 있고 런타임 재구성이 없는 경우 증상: 개방형 시스템 처리 불가, 동적 자원 관리 없음, 변경에 취약 해결 방법: 주소를 일급 데이터로 취급, 기능 라우팅 구현, 런타임 토폴로지 변경 지원
작업 예제
예제 1: 고객 패턴을 사용한 작업 분해
시나리오: 에이전트가 순차적 하위 작업 A → B → C가 필요한 복잡한 요청을 처리해야 하지만, 다른 메시지에도 응답을 유지해야 합니다.
초보자 접근법:
요청 수신 →
하위 작업 A를 호출하는 동안 차단
하위 작업 B를 호출하는 동안 차단
하위 작업 C를 호출하는 동안 차단
최종 결과 전송
액터 모델 전문가 적용:
요청 수신 →
B, C 및 최종 수신자 주소를 가진 customer_BC 액터 생성
하위 작업 A 요청을 A_processor에 customer_BC를 응답 주소로 전송
대체 행동 지정: 다음 요청 준비
customer_BC가 A 결과 수신 →
결과를 B_processor에 customer_C를 응답 주소로 전송
customer_C가 B 결과 수신 →
결과를 C_processor에 final_recipient를 응답 주소로 전송
내려진 주요 결정:
- 차단을 피하기 위해 고객 패턴 사용
- 각 단계가 체인의 다음 고객 생성
- 원래 에이전트는 전체 과정에서 응답 유지
- 하위 작업 실패는 해당 체인에만 영향
예제 2: 감독을 통한 실패 복구
시나리오: 시스템이 전체 시스템으로 확산되지 않고 에이전트 실패를 처리해야 합니다.
초보자 접근법: 에이전트 호출 주위에 try-catch, 실패 시 모든 것 재시작.
전문가 적용:
감독자가 worker_actor 생성 →
응답 타임아웃으로 작업을 worker에게 전송
대체 행동 지정: "응답 대기 중"
IF 타임아웃 내에 응답 수신 →
결과를 클라이언트에게 전달
대체 행동 지정: "준비"
IF 타임아웃 만료 →
새 worker_actor 생성(이전 것은 실패)
새 worker에게 작업 재전송
대체 행동 지정: "응답 대기 중"
탐색된 절충점:
- 감독은 비즈니스 로직과 별개의 관심사
- 실패한 액터는 수리되지 않고 격리되어 교체됨
- 타임아웃 감지와 보장된 전달 간의 균형
- 감독자와 작업자 간의 공유 상태 없음
품질 게이트
- 어떤 액터도 메시지 처리 루프를 차단하지 않음(필요한 곳에 둔감 액터 패턴 적용)
- 모든 조정은 메시지 전달 사용(액터 간 공유 가변 상태 없음)
- 메시지 전달은 보장되지만 순서는 가정되지 않음
- 주소는 기능 라우팅을 위해 일급 데이터로 취급됨
- 각 액터는 모든 메시지 유형에 대해 대체 행동을 지정함
- 액터 생성은 계산 필요에 따라 동적으로 발생함
- 실패 격리가 액터 경계를 넘는 연쇄 실패를 방지함
- 시스템 토폴로지는 중앙 레지스트리 없이 런타임에 재구성 가능
- 구성 동작이 확인됨, 고립된 구성 요소 동작만이 아님
- 동기 작업은 요청-응답 메시지 쌍으로 모델링됨
사용 금지 경계
이 스킬은 다음에 사용하면 안 됨:
- 간단한 순차 계산 → 대신 함수형 프로그래밍 사용
- 공유 메모리가 물리적으로 필요한 시스템 → 대신 잠금 기반 동시성 패턴 사용
- 엄격한 시간 제약이 있는 실시간 시스템 → 대신 공식 시간 분석과 함께 동기 메시지 전달 사용
- 조정이 없는 수학 계산 → 대신 순수 함수형 접근법 사용
다른 스킬에 위임할 때:
- 특정 액터 프레임워크 구현 → 플랫폼별 구현 가이드 사용
- 액터 시스템 성능 튜닝 → [성능 최적화] 스킬 사용
- 액터 속성의 공식 검증 → [공식 방법] 스킬 사용
- 액터 지속성을 위한 데이터베이스 설계 → [데이터 아키텍처] 스킬 사용
범위에 대한 일반적인 오해:
- 액터는 단지 "비동기 메서드가 있는 객체"가 아닙니다. 전체 3-튜플 응답이 필요합니다.
- 액터 모델은 분산 시스템 전용이 아닙니다. 모든 동시성 계산에 적용됩니다.
- 주로 성능 최적화가 아닙니다. 정확성과 구성 가능성에 관한 프레임워크입니다.