fix(anime): 파이프라인 5건 수정 — 에피소드 정규식(v2/S01E), 릴리스 그룹 필터, 자막 보호, 배치 다운로드, 타임아웃

This commit is contained in:
2026-03-15 08:27:08 +09:00
parent 63818999d9
commit 9f74812710
40 changed files with 2759 additions and 815 deletions

View File

@@ -1,75 +1,80 @@
# Architecture
> Variet Agent — Gemini CLI 기반 AI Agent Team 시스템
> Variet Agent — Hybrid Skill-Based AI Agent (v3)
## 프로젝트 개요
사용자가 디스코드에서 자연어 명령 → AI Agent Team이 코드 분석/분해/실행 → Gitea CI로 PR/빌드/배포.
Gemini CLI를 서브프로세스(`asyncio.create_subprocess_exec`)로 래핑하여 역할별 독립 컨텍스트로 호출.
사용자가 디스코드에서 자연어 명령 → Orchestrator NLU 분류 → 도구 실행 또는 Agent 통합 실행.
Gemini CLI를 subprocess(`asyncio.create_subprocess_exec`)로 호출. **SDK/API 전환 금지.**
## 디렉토리 구조
```
variet-agent/
├── main.py # 진입점 (FastAPI + Discord Bot 동시 실행)
├── config.py # .env 기반 설정 관리
├── main.py # 진입점 (FastAPI + Discord Bot)
├── config.py # .env 기반 설정 관리
├── api/
│ ├── server.py # FastAPI REST 서버
│ ├── discord_bot.py # Discord Bot (NLU + PCRS 파이프라인 + 애니 핸들러)
│ └── models.py # 요청/응답 모델
│ ├── server.py # FastAPI REST 서버
│ ├── discord_bot.py # Discord Bot (이벤트 핸들러 + 라우팅, ~310줄)
│ └── models.py # 요청/응답 모델
├── core/
│ ├── task_pipeline.py # PCRS: Plan → Code → Review → Summarize
│ ├── gemini_caller.py # Gemini CLI 래퍼 (text/agent 모드)
│ ├── context_manager.py # 관련 파일 선별 + 토큰 예산 제어
│ ├── project_indexer.py # 프로젝트 구조 스캔/캐시
│ ├── workspace.py # 워크스페이스 관리 (채널 ↔ 프로젝트 매핑)
│ ├── file_applier.py # 코드 변경 적용
── docs_manager.py # 문서/세션 기록
├── tools/ # 자동화 도구 (애니메이션 파이프라인)
├── anime_pipeline.py # 통합 파이프라인 (검색/다운/자막/상태)
│ ├── anissia_client.py # Anissia 편성표 API
│ ├── nyaa_client.py # Nyaa 토렌트 검색
│ ├── qbit_client.py # qBittorrent 제어
── nas_scanner.py # NAS 파일 스캔
├── title_matcher.py # 제목 매칭 (로마지/퍼지)
── subtitle_downloader.py # 자막 다운로더
├── integrations/
│ ├── gitea_client.py # Gitea API (PR/이슈)
│ ├── vikunja_client.py # Vikunja 태스크 관리
│ └── ci_monitor.py # CI 결과 모니터링
── prompts/ # AI 역할별 프롬프트
── unified.md # NLU 분류 (chat/task/anime/clarify)
├── planner.md # 태스크 분해
├── coder.md # 코드 구현
├── reviewer.md # 코드 리뷰
── summarizer.md # 총평 생성
│ ├── orchestrator.py # NLU 분류 + 도구 라우팅
│ ├── task_pipeline.py # ★ execute() 1회 호출 + 선택적 review()
│ ├── gemini_caller.py # Gemini CLI 래퍼 (text/agent 모드)
│ ├── context_manager.py # 관련 파일 선별 + 토큰 예산
│ ├── project_indexer.py # 프로젝트 구조 스캔
│ ├── workspace.py # 워크스페이스 관리
── file_applier.py # 코드 변경 적용
│ └── docs_manager.py # 문서/세션 기록
├── handlers/ # Discord 핸들러
│ ├── anime_handler.py # 애니 NLU + /anime 슬래시
│ ├── task_handler.py # ★ Agent 1회 실행 + 결과 임베드 (~110줄)
│ ├── commands.py # /workspace, /task 슬래시
── renderer.py # ToolResult → Discord Embed
├── tools/ # 자동화 도구 (Plugin 패턴)
── base.py # BaseTool 추상 기반
│ ├── registry.py # ToolRegistry 자동 발견
│ ├── anime_tool.py # AnimeTool(BaseTool)
│ ├── anime_pipeline.py # 통합 파이프라인
│ └── ... # 개별 클라이언트들
── .gemini/
── skills/ # ★ Gemini CLI Skill v2
└── anime/
│ └── SKILL.md # 도구 설명 + 사용법
├── prompts/
── unified.md # NLU 분류
│ ├── agent.md # ★ 통합 에이전트 (plan+code+verify)
│ └── reviewer.md # 독립 리뷰 (선택적)
└── logs/
└── variet.log
```
## 핵심 모듈
| 모듈 | 역할 | 의존성 |
|------|------|--------|
| `discord_bot.py` | 사용자 인터페이스 + NLU 분류 | `workspace.py`, `gemini_caller.py`, `task_pipeline.py` |
| `task_pipeline.py` | PCRS 오케스트레이션 (Inner/Outer 루프) | `gemini_caller.py`, `context_manager.py`, `project_indexer.py` |
| `gemini_caller.py` | Gemini CLI 서브프로세스 호출 (text/agent) | `prompts/` |
| `context_manager.py` | 태스크 기반 파일 선별 + 토큰 예산 | `project_indexer.py` |
| `workspace.py` | 채널 ↔ 프로젝트 경로 매핑, workspaces.json 관리 | — |
| `anime_pipeline.py` | 애니 자동화 통합 | `anissia_client.py`, `nyaa_client.py`, `qbit_client.py`, `nas_scanner.py` |
## 데이터 흐름
```
Discord 메시지
on_message()
→ _unified_call() — NLU 분류 (chat/task/anime/clarify)
├─ chat즉답
├─ clarify → 질문 임베드
├─ anime → _handle_anime() → AnimePipeline
└─ task → _handle_task()
→ TaskPipeline.plan() — Planner (태스크 분해)
→ TaskPipeline.code_parallel() — Coder (에이전트 모드, cwd=프로젝트)
→ TaskPipeline.planner_verify() — 내부 자가검증 (Inner Loop)
→ TaskPipeline.batch_review() — Reviewer (Outer Loop)
→ TaskPipeline.summarize() — 총평
→ Discord Embed 보고
Orchestrator.classify() — NLU 분류
├── chat → 즉답
├── clarify질문
├── anime → AnimeTool + renderer
└── task → TaskPipeline.execute() ← Agent 1회
→ Gemini agent 모드 (plan+code+verify 통합)
→ JSON 보고서 → Discord Embed
```
## vs 이전 버전 (PCRS)
```
v2: NLU → Planner → Coder×N → PlannerVerify → Reviewer → Summarizer (5~7 호출)
v3: NLU → Agent 1회 (plan+code+verify 통합) → 선택적 Review (1~2 호출)
```
## 새 도구 추가
1. `tools/``BaseTool` 상속 클래스 생성 → 자동 등록
2. `.gemini/skills/`에 SKILL.md 생성 → Gemini CLI가 자동 발견
## 아키텍처 결정 (변경 불가)
- **Gemini CLI subprocess 영구 유지** (SDK/API 금지)
- 상세: `.agents/references/conventions.md` 참조