docs(readme): rewrite as accurate project summary (selfbot receive + DAVE gate 1)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
107
README.md
107
README.md
@@ -1,61 +1,104 @@
|
|||||||
# watch_sceen_ai
|
# watch_sceen_ai
|
||||||
|
|
||||||
디스코드 화면공유를 **실시간으로 함께 보면서 대화하는 AI**의 골격(skeleton).
|
디스코드 화면공유를 **AI가 실시간으로 보면서 음성으로 함께 대화하는** 봇.
|
||||||
|
|
||||||
지금 단계는 "틀": 파이프라인 구조와 교체 가능한 인터페이스를 먼저 세우고,
|
사용자가 디스코드에서 화면공유(Go Live)를 켜면, AI가 그 화면을 실시간으로 이해하고,
|
||||||
의존성/키/마이크 없이 mock 모드로 전체 흐름이 도는 걸 검증한다.
|
사용자의 음성 질문에 최대한 빠르게 답한다. 필요하면 화면이 크게 바뀔 때 먼저 말을 걸기도 한다.
|
||||||
|
|
||||||
## 구조
|
- 실행 위치: 이 리눅스 호스트(.9, RTX 5050)
|
||||||
|
- 상태: 1단계(눈: 화면공유 스트림 수신) 진행 중 — 관문 1(E2EE 합류) 통과
|
||||||
|
|
||||||
```
|
## 전체 구조
|
||||||
FrameSource ──frames──▶ VisionBackend ──observations──▶ [SharedScreenContext]
|
|
||||||
│
|
|
||||||
STT / TextChannel ──utterances──▶ Brain(LLM) ◀───────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
TextToSpeech / TextChannel
|
|
||||||
```
|
|
||||||
|
|
||||||
두 개의 async 루프가 동시에 돈다.
|
두 개의 async 루프가 동시에 돈다.
|
||||||
|
|
||||||
|
```
|
||||||
|
[인지 루프] 화면공유 수신 ──frames──▶ 비전 이해 ──▶ [최신 화면 맥락 저장소]
|
||||||
|
│
|
||||||
|
[대화 루프] STT(음성) ──utterances──▶ Brain(LLM) ◀────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
TTS(음성 응답)
|
||||||
|
```
|
||||||
|
|
||||||
- 인지 루프: 화면 캡처 → 비전 이해 → 최신 화면 맥락 저장
|
- 인지 루프: 화면 캡처 → 비전 이해 → 최신 화면 맥락 저장
|
||||||
- 대화 루프: 음성/텍스트 입력 → 두뇌(LLM, 화면맥락 + 대화이력) → 음성/텍스트 출력
|
- 대화 루프: 음성/텍스트 입력 → 두뇌(LLM, 화면맥락 + 대화이력) → 음성/텍스트 출력
|
||||||
|
|
||||||
모든 단계는 `wsai/interfaces.py`의 Protocol이라, 백엔드(mock / 로컬GPU / 클라우드 /
|
모든 컴포넌트는 `wsai/interfaces.py`의 Protocol이라, 백엔드(mock / 로컬GPU / 클라우드 등)를
|
||||||
디스코드 웹캡처 …)를 config에서 바꿔 끼우면 오케스트레이터는 그대로다.
|
config에서 바꿔 끼워도 오케스트레이터는 그대로다.
|
||||||
|
|
||||||
|
## 채택한 방식 (2026-08-09 확정)
|
||||||
|
|
||||||
|
### 눈 — 화면공유 스트림 직접 수신
|
||||||
|
스크린샷·브라우저 캡처는 **거부**. 실제 화면공유 스트림 자체를 진짜 클라이언트처럼 수신한다.
|
||||||
|
|
||||||
|
- 공식 디스코드 봇 API는 비디오(화면공유) 수신을 완전 차단 → 봇으로는 불가.
|
||||||
|
- 그래서 **셀프봇(유저 토큰)** 으로 프로토콜 레벨에서 비디오 RTP를 직접 수신·디코딩한다.
|
||||||
|
- 수신 파이프: 셀프봇 음성채널 join → 상대 Go Live 스트림 "watch" 구독(비디오 SSRC 획득)
|
||||||
|
→ 암호화 비디오 RTP 수신 → DAVE(E2EE) 복호화 → 전송암호(aead_aes256_gcm_rtpsize) 복호
|
||||||
|
→ VP8/H264 depayload → ffmpeg 디코드 → 프레임.
|
||||||
|
- 라이브러리: `discord.js-selfbot` 계열(werift-rtp), DAVE 복호화는 `@snazzah/davey`(Rust NAPI).
|
||||||
|
- 계정: 전용 버너 계정 "클로드봇"(tkrmagid_bot). 토큰은 `.env`(gitignore).
|
||||||
|
|
||||||
|
### 귀 — STT
|
||||||
|
`faster-whisper` 스트리밍/부분 전사로 사용자의 음성을 빠르게 텍스트화.
|
||||||
|
|
||||||
|
### 두뇌 — 하이브리드 비전 + LLM
|
||||||
|
이 호스트 RTX 5050(8GB)으로 소형 로컬 VLM(moondream2 / Qwen2-VL-2B)이 매 프레임 1차 이해 +
|
||||||
|
화면 변화 감지를 값싸게 처리하고, 어려운 화면만 Claude OAuth(Haiku 계열)로 에스컬레이션.
|
||||||
|
|
||||||
|
### 입 — TTS
|
||||||
|
MeloTTS 등(이 호스트에 기존 자산 있음)으로 음성 응답. 말 끊기 인터럽트 지원, 지연 최소화.
|
||||||
|
|
||||||
|
## 진행 상황
|
||||||
|
|
||||||
|
### 완료
|
||||||
|
- 파이프라인 스켈레톤(`wsai/`) — 의존성/키 없이 mock 모드로 전체 흐름 검증됨.
|
||||||
|
- 캡처 방식 결정 확정: 셀프봇 프로토콜 레벨 비디오 RTP 수신.
|
||||||
|
- 버너 계정 + 토큰 확보, ToS/밴 위험 수용 확인.
|
||||||
|
- **관문 1 통과 (DAVE/MLS E2EE 합류)** — `dave/gate.mjs` 실측 검증:
|
||||||
|
- 셀프봇 유저토큰 메인 GW IDENTIFY → 음성채널 join → 보이스 GW v8 IDENTIFY(`max_dave_protocol_version=1`).
|
||||||
|
- close 4017 없음. `SESSION_DESCRIPTION`에서 `dave_protocol_version=1` 협상됨(채널 E2EE 활성).
|
||||||
|
- `@snazzah/davey`로 MLS 멤버십 핸드셰이크 완주(op25~op29) → MLS session ready=true, voicePrivacyCode 산출.
|
||||||
|
- 결론: 셀프봇이 E2EE 보이스 그룹에 정식 멤버로 합류 가능 → 직접 수신 방식 실현 가능 확정.
|
||||||
|
|
||||||
|
### 다음 (1단계 마무리)
|
||||||
|
- 상대 Go Live 스트림 구독으로 비디오 SSRC 확보 → UDP SRTP 비디오 패킷 수신 → RTP 파싱
|
||||||
|
→ `daveSession.decrypt` E2EE 복호 → 전송암호 복호 → VP8/H264 depayload → ffmpeg 디코드
|
||||||
|
→ 실제 공유화면 프레임 추출 PoC. (검증하려면 실제 Go Live 중인 소스 필요)
|
||||||
|
- 프레임 변화 감지(동일 화면 반복 전송 방지) + 소스 인터페이스.
|
||||||
|
|
||||||
|
### 이후 단계
|
||||||
|
- 3단계 · 두뇌: 로컬 VLM 1차 이해 + 변화 감지, Claude(Haiku) 에스컬레이션, 화면 맥락 저장소.
|
||||||
|
- 4단계 · 음성 대화: STT + 대화 브레인 + TTS + 인터럽트/지연 최적화.
|
||||||
|
- 5단계 · 통합·운영: 인지/대화 루프 동시 실행, proactive(화면 크게 바뀌면 먼저 말 걸기), 끊김 복구, 비용 모니터링, 서비스화.
|
||||||
|
|
||||||
## 실행
|
## 실행
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m wsai # mock 데모 (의존성·키 불필요, 몇 프레임 돌고 종료)
|
python -m wsai # mock 데모 (의존성·키 불필요, 몇 프레임 돌고 종료)
|
||||||
python -m wsai --live # 이 PC 화면 캡처 + Claude 눈/두뇌 (Ctrl-C 종료)
|
|
||||||
python -m wsai --env # WSAI_* 환경변수로 조립
|
python -m wsai --env # WSAI_* 환경변수로 조립
|
||||||
pytest # 스모크 테스트
|
pytest # 스모크 테스트
|
||||||
```
|
```
|
||||||
|
|
||||||
`--live`에 필요한 것: `pip install mss pillow anthropic`, 그리고 `ANTHROPIC_API_KEY`.
|
## 파일 / 디렉터리
|
||||||
|
|
||||||
## 파일
|
| 경로 | 역할 |
|
||||||
|
|
||||||
| 파일 | 역할 |
|
|
||||||
|------|------|
|
|------|------|
|
||||||
| `wsai/interfaces.py` | 데이터 타입 + 컴포넌트 Protocol |
|
| `wsai/interfaces.py` | 데이터 타입 + 컴포넌트 Protocol |
|
||||||
| `wsai/pipeline.py` | 오케스트레이터(인지/대화 루프) |
|
| `wsai/pipeline.py` | 오케스트레이터(인지/대화 루프) |
|
||||||
| `wsai/state.py` | 최신 화면 맥락 공유 저장소 |
|
| `wsai/state.py` | 최신 화면 맥락 공유 저장소 |
|
||||||
| `wsai/config.py` / `factory.py` | 설정 → 백엔드 조립 |
|
| `wsai/config.py` / `factory.py` | 설정 → 백엔드 조립 |
|
||||||
| `wsai/backends/mock.py` | 무의존성 mock 전 계열 |
|
| `wsai/backends/mock.py` | 무의존성 mock 전 계열 |
|
||||||
| `wsai/backends/capture_mss.py` | 로컬 화면 캡처(눈) |
|
| `wsai/backends/capture_mss.py` | 로컬 화면 캡처(폴백용) |
|
||||||
| `wsai/backends/claude.py` | Claude 비전 + 두뇌 |
|
| `wsai/backends/claude.py` | Claude 비전 + 두뇌 |
|
||||||
|
| `dave/gate.mjs` | DAVE/MLS E2EE 합류 관문 검증(관문 1 통과 증거) |
|
||||||
|
| `poc/` | Xvfb+Chromium 프레임 캡처 실험 — **폐기**(참고 폴백으로만 보존) |
|
||||||
|
| `PLAN.md` | 단계별 착수 계획(확정본) |
|
||||||
|
|
||||||
## 아직 안 된 것 (다음 단계 후보)
|
## 리스크 메모
|
||||||
|
|
||||||
- STT 실제 백엔드(faster-whisper) + 마이크 캡처(sounddevice)
|
- 셀프봇(유저 토큰) 자동화는 디스코드 ToS 회색지대 → 계정 밴 위험. 반드시 버리는 전용 계정만 사용.
|
||||||
- TTS 실제 백엔드(MeloTTS 등) — 이 호스트에 기존 자산 있음
|
- 완성형 "수신→프레임" 라이브러리는 없음(직접 조립 필요). 셀프봇 라이브러리는 프로토콜 변경 시 깨질 수 있음.
|
||||||
- 디스코드 텍스트 채널 I/O (`factory._text`가 아직 NotImplemented)
|
- 리스크를 완전히 없애려면 대안: (a) 디스코드 클라이언트 렌더 화면 로컬 캡처, (b) 디스코드 대신 WebRTC/OBS/Janus/mediasoup 기반 수신 구조. 다만 둘 다 "실제 화면공유 스트림을 진짜로 수신"하려던 원래 요구와는 타협이 있음.
|
||||||
- 화면 변화 감지 → AI가 먼저 말 거는 proactive 모드
|
- 로컬 GPU 8GB VRAM 제약 → 소형 VLM만. 큰 이해는 클라우드(Claude).
|
||||||
- 캡처 방식 선택: 로컬 화면 vs 디스코드 웹 캡처(Playwright)
|
|
||||||
|
|
||||||
## 캡처 방식에 대한 메모
|
|
||||||
|
|
||||||
디스코드 봇이 화면공유 **영상 스트림을 직접 수신**하는 건 공식 API 미지원(유저봇은 ToS 위반).
|
|
||||||
그래서 현실적 방식은 "통화에 참여해 공유화면을 보는 상태의 화면을 로컬 캡처"하는 것.
|
|
||||||
`MSSFrameSource`가 그 기본 구현이고, 필요하면 웹 캡처 소스로 교체 가능.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user