feat: 운영 안정성과 세션 음성 경험 개선

This commit is contained in:
Yun Chan 2026-07-31 00:13:08 +09:00
parent facc4ad2d9
commit c788343467
95 changed files with 8431 additions and 1785 deletions

View file

@ -15,20 +15,22 @@ docker compose up -d
## 2. 핵심 — "엔진"만 컨테이너 밖 (이식성의 열쇠)
우리 엔진은 로컬 `claude -p`(네 PC의 claude CLI/OAuth에 묶임)라, 컨테이너에 가두면 못 옮긴다. 그래서 **엔진은 어댑터 뒤에 두고 `ENGINE_URL`/`ENGINE_MODE`로 가리킨다.** 옮길 때 이 두 줄만 바꾸면 됨 — 코드 무수정.
AI provider는 모두 호스트 엔진 게이트웨이 뒤에 둔다. 게이트웨이가 Claude CLI·Anthropic API·Codex CLI·Agy CLI의 모델 탐색과 실행을 맡고, 컨테이너 API는 **`ENGINE_URL`/`ENGINE_MODE`로 게이트웨이와 provider를 선택한다.** CLI는 호스트 인증을 재사용하고 API 키는 게이트웨이 호스트에만 주입한다.
설정 경로 **3가지(사용자 선택)**:
1. **yml / .env**`infra/.env``ENGINE_URL`·`ENGINE_MODE` (기본·운영)
2. **docker compose**`docker compose run -e ENGINE_MODE=messages_api ...` 즉석 오버라이드
3. **설정 페이지(관리자 UI)** — 런타임에 엔진/모델 전환 (DB에 저장, 재기동 불필요)
2. **docker compose**`docker compose run -e ENGINE_MODE=claude_api ...` 즉석 오버라이드
3. **설정 페이지(관리자 UI)** — 런타임에 provider·연결 주소·사용 가능 모델·추론 강도를 선택한다. 게이트웨이가 확인하지 못한 조합은 저장하지 않는다.
| 시나리오 | ENGINE_MODE | ENGINE_URL |
|---|---|---|
| **네 PC 운영** (요구사항: 로컬 claude -p) | `claude_p` | `http://host.docker.internal:9099` (호스트의 claude -p 게이트웨이) |
| **클라우드/타호스트 이전** | `messages_api` | (불필요, ANTHROPIC_API_KEY 사용) |
| **원격 엔진 PC** | `claude_p` | `http://<엔진PC-IP>:9099` |
| **네 PC 운영** (Claude CLI) | `claude_cli` | `http://host.docker.internal:9099` |
| **네 PC 운영** (Codex CLI, 기본 Terra/Medium) | `codex_cli` | `http://host.docker.internal:9099` |
| **네 PC 운영** (Agy CLI, 기본 Gemini 3.6 Flash/High) | `agy_cli` | `http://host.docker.internal:9099` |
| **클라우드/타호스트 이전** | `claude_api` | `http://host.docker.internal:9099` (`ANTHROPIC_API_KEY`는 게이트웨이 호스트에 주입) |
| **원격 엔진 PC** | 위 provider 중 설치·인증된 항목 | `http://<엔진PC-IP>:9099` |
> 로컬 claude -p 게이트웨이 = 호스트에서 도는 작은 프로세스(상주 멀티턴 풀, `claude -p --input-format stream-json`). 컨테이너 api 가 `host.docker.internal:9099`로 호출. 이 게이트웨이는 `apps/api/engine_gateway/`에 둔다(호스트 실행, 컨테이너 밖).
> 호스트 게이트웨이는 `apps/api/engine_gateway/`에 있으며 컨테이너 밖에서 실행한다. Claude CLI는 상주 멀티턴 풀을, Codex/Agy는 각 CLI를, `claude_api`는 Anthropic API를 호출한다. 관리자 UI의 모델 목록은 이 게이트웨이의 `GET /v1/capabilities`가 소유한다.
## 3. 환경변수 (.env)
@ -39,8 +41,8 @@ docker compose up -d
| `AUTH_ALLOWED_EMAIL_DOMAINS` | Google 로그인 허용 이메일 도메인(JSON 배열). 기본 `["hs.ac.kr","twentyoz.kr"]`. Google Console authorized domains가 아니라 서버에서 `email`/`hd` claim으로 강제 |
| `FRONTEND_ORIGIN_MAP` | API callback host → frontend origin 매핑(JSON 객체). 기본 `api-vignette.chanpaca.net → vignette.chanpaca.net`, `api-vnet.18ka.net → vnet.18ka.net` |
| `OPENAI_API_KEY` | 음성(STT/TTS) |
| `ANTHROPIC_API_KEY` | 엔진 폴백/클라우드 모드 |
| `ENGINE_MODE` / `ENGINE_URL` | 엔진 위치(위 표) |
| `ANTHROPIC_API_KEY` | `claude_api` provider용. API 컨테이너가 아니라 엔진 게이트웨이 호스트에 주입 |
| `ENGINE_MODE` / `ENGINE_URL` | provider와 엔진 게이트웨이 위치(위 표) |
| `SITE_ADDRESS` | 외부노출 도메인(예: `vignette.chanpaca.net`). 비우면 로컬 :80 |
| `ACME_EMAIL` | 외부노출 시 Let's Encrypt 자동 TLS용 |
| `HTTP_PORT`/`HTTPS_PORT` | 호스트 포트 매핑 |
@ -66,7 +68,7 @@ docker compose up -d
- **수직**: compose 그대로, 호스트 사양만 키움.
- **수평**: `docker compose up --scale api=3` (api 무상태 설계 전제, 세션은 DB/Redis). proxy가 라운드로빈.
- **이전**: `pgdata`·`ragmodels` 볼륨만 새 호스트로 옮기고 `.env` 채워 `up`. (rag 모델 캐시 볼륨 덕에 재다운로드 0)
- **클라우드**: 동일 compose. 단 엔진을 `messages_api`로 바꾸거나 엔진 PC를 `ENGINE_URL`로 원격 지정.
- **클라우드**: 동일 compose. `ENGINE_MODE=claude_api`와 게이트웨이 주소를 지정하고 게이트웨이 호스트에 `ANTHROPIC_API_KEY`를 주입한다.
## 6. 데이터 주권 / 보안