본문으로 건너뛰기
프로젝트 목록

PF-06 · AI · FastAPI

AetherCrew: AI 직원 11명의 가상 회사

직접 만든 오케스트레이터로 AI 직원 11명의 업무 배정, 모델 선택, 비용 추적을 구현한 가상 회사입니다. 에이전트 작업은 시뮬레이션이며 언어 모델 API는 호출하지 않습니다.

역할
설계 · 구현
기간
개인 프로젝트 · 2026.11 공개
CSP
해당 없음
규모
AI 직원 11명 · 3개 부서 · 대시보드 8페이지
핵심 기술
Python · FastAPI · WebSocket · pytest · Slack · Jira · GitHub
GitHub
11
AI 직원
3
부서
8
웹 대시보드 페이지

한눈에 보기

CEO사용자 지시경영기술영업Emma비서/경영기획실장Mia재무Ava인사Sophia기술실장Noah시니어 엔지니어Luna엔지니어EthanDB 엔지니어LiamQA 엔지니어Chloe보안 엔지니어James기획·영업실장Olivia콘텐츠 마케터(기본비활성)모델 우선순위 · 예상 비용 기록시뮬레이션: 업무 배정, 모델 선택, 비용 기록만 수행합니다언어 모델 API는 호출하지 않습니다
공개 코드에서 에이전트 작업은 시뮬레이션이며 언어 모델 API는 호출하지 않습니다.

문제

여러 AI 직원이 역할별로 일을 나눠 맡으면 누가 어떤 모델을 쓰는지, 비용이 어디까지 갔는지, 외부 시스템에 무엇을 쓸 수 있는지 코드로 통제해야 합니다.

접근

CEO 지시를 비서(경영기획실장)가 받아 계획을 쓰고 역할별 Task로 나눕니다. 직원별로 Anthropic, OpenAI, Google, DeepSeek 모델의 우선순위를 두고 실패하면 다음 모델로 전환합니다. 예상 비용을 쌓아 80%와 95%에서 경고하고 100%에서 작업을 막습니다. 외부 쓰기는 기본 차단, 파일 접근은 프로젝트 루트로 제한합니다.

결과

FastAPI 웹 대시보드 8페이지에서 조직도, 비용, 로그, 픽셀 오피스 CCTV를 봅니다. API 키 없이 실행되고 언어 모델은 호출하지 않으므로 실제 작업 결과물은 나오지 않습니다. Slack, Jira, GitHub 클라이언트는 실제 코드이며 INTEGRATIONS_LIVE_WRITE를 켤 때만 동작합니다.

자세히 보기

직원별 모델 폴백우선순위 목록 앞에서부터 사용 가능한 모델을 고릅니다gpt-5OpenAIclaude-opus-4Anthropicgemini-2.5-proGoogledeepseek-v3DeepSeek1순위2순위3순위4순위선택됨agent.fallback 이벤트 기록예상 비용만 기록, 언어 모델 API 호출 없음
전환은 agent.fallback 이벤트로 기록됩니다. 모델 호출은 시뮬레이션입니다.
예산 정책80% 경고95% 경고100% 작업 차단작업 차단
100%에 도달하면 작업을 막습니다. 비용 조회는 일·주·월·직원별로 합니다.

모델 폴백

이 코드가 하는 일: 직원별 우선순위 목록에서 사용 가능한 첫 모델을 고릅니다.

class FallbackManager:
    """Selects next available agent with bounded fallback traversal."""

    def select(
        self,
        priority_list: list[str],
        unavailable_agents: set[str] | None = None,
    ) -> FallbackResult:
        if not priority_list:
            raise ValueError("priority_list must not be empty")
        blocked = unavailable_agents or set()
        fallbacks: list[str] = []
        for idx, model in enumerate(priority_list):
            if model in blocked:
                fallbacks.append(model)
                continue
            return FallbackResult(selected_agent=model, selected_index=idx, fallbacks=fallbacks)
        raise RuntimeError("All agents are unavailable; fallback exhausted")

예산 상태

이 코드가 하는 일: 누적 비용으로 예산 상태를 계산합니다. 100% 이상이면 작업을 막습니다.

    @property
    def total_cost(self) -> float:
        return round(sum(e.cost_usd for e in self.entries), 6)

    def percent_used(self) -> float:
        if self.budget_policy.total_budget <= 0:
            return 100.0
        return (self.total_cost / self.budget_policy.total_budget) * 100

    def budget_state(self) -> str:
        pct = self.percent_used()
        if pct >= self.budget_policy.hard_stop_at_pct:
            return "HARD_STOP"
        if pct >= self.budget_policy.warn_at_pct[1]:
            return "WARN_95"
        if pct >= self.budget_policy.warn_at_pct[0]:
            return "WARN_80"
        return "OK"

배운 점

실제로 에이전트끼리 일을 넘기게 해 보니, 한 에이전트의 잘못된 결과를 다음 에이전트가 검증 없이 그대로 믿었습니다. 신뢰 경계와 권한 범위가 코드 안에 있어야 한다는 것을 그때 체감했습니다.

다음에 개선할 점

언어 모델 호출은 아직 구현하지 않았습니다. 상태는 JSON 파일 하나에 저장해 단일 로컬 프로세스에만 맞습니다.

관련 현장 노트

Open to work · 클라우드 인프라/보안