서버 안정화와 평가 모델 라우팅 보강
This commit is contained in:
parent
0cdbf8e4fe
commit
0eb7d925ed
10 changed files with 179 additions and 39 deletions
|
|
@ -27,7 +27,6 @@
|
|||
- [ ] **음성 캐스케이드 live** — 실제 Deepgram STT / OpenAI TTS provider 키, 물리 마이크, 공개 WSS 50분 양방향 실측. provider 키/하드웨어 부재로 미실행(백엔드 계약·UI synthetic 경로는 단위/E2E로 증명됨).
|
||||
- [ ] **claude_cli ↔ Messages API 폴백 동일성** — `ANTHROPIC_API_KEY`가 있어야 Messages API 경로를 돌려 동일성 검증 가능. claude_cli 경로는 게이트웨이 probe로 live 실측 완료.
|
||||
- [ ] **저항엔진 openness 곡선 DB 실증** — fast-loop 평가의 `client_state_read` → `app.turn_client_state` 적재 경로는 추가됨. 다만 dev DB 실데이터/다수 실턴(real LLM) 기반 openness 곡선 증거는 아직 필요. 현재는 `app.test_state_machine_resistance` 단위테스트와 `app.test_evaluation_persistence` 매핑 테스트로 1차 증명.
|
||||
- [ ] **마스킹 게이트 운영 외부-send live proof** — 상담 생성(generate/stream)과 fast/deep 평가 직후 `audit.llm_call_log`에 provider/model/token/cost/inference_geo/latency만 적재하는 경로를 추가했다. prompt/completion 본문은 저장하지 않는다. 남은 증거는 실제 운영 로그인 `/turn` 후 live DB row를 확인하는 것이다. 현재는 `app.test_orchestrator_masking`로 generate/stream payload에 phone/email/RRN 부재와 감사 payload의 본문 미포함을 증명.
|
||||
- [ ] **재부팅 후 watchdog smoke** — `watch-public-runtime.ps1` + Scheduled Task가 재부팅 후 엔진/API/터널을 복구하고 public `/turn`이 통과하는지 실측. 재부팅 불가로 미실행(parser/ check-only 경로는 확인됨). 2026-06-27 점검에서 아직 DNS가 없는 `api-vnet.18ka.net`은 기본 watchdog 검사에서 제외했고, 개통 후 `-AdditionalPublicHealthUrls`로 명시 추가하도록 runbook을 보강했다.
|
||||
- [ ] **상주 엔진풀 RSS 실측** — probe로 TTFT/세션재사용/cost는 live 확인. 프로세스 RSS(메모리)는 별도 OS 계측 항목으로 남김.
|
||||
|
||||
|
|
@ -74,7 +73,7 @@
|
|||
- C1 사례개념화 워크시트 1차: `SessionReviewResponse.caseWorksheet`와 리뷰 화면 read-only 카드가 탐색 11항목·호소 5영역·인지삼제/감정·보호/방해·생물심리사회 목표 초안을 축어록 근거 기반으로 제공한다. 편집·DB 저장, 임상 루브릭, AI 추출/채점, 교수자 검수는 후속. **검증: `pytest app/test_session_turn_persistence.py -q` 15 passed, `pytest app/ -q` 119 passed, `npm run check:api-types`, `npm run typecheck`, `npm run build`, `session-review.spec.ts` 1 passed.**
|
||||
- C3 이론모드 1차: `theory_mode`가 `TurnContext`/sessions/voice/evaluator뿐 아니라 `build_turn_messages`의 엔진 메시지까지 전달된다. 프론트는 `persona.theory_target` 기준으로 시작해 `humanistic` 하드코딩을 제거했다. CBT 체인·이론부합 루브릭·명시적 선택 UI는 후속. **검증: `pytest app/test_orchestrator_masking.py app/test_session_turn_persistence.py -q` 20 passed, `pytest app/ -q` 119 passed.**
|
||||
- M3 인증 claim 1차: Google/SAML/dev-login이 `AUTH_EMAIL_COHORT_MAP`·`AUTH_DOMAIN_COHORT_MAP` 및 SAML cohort claim을 `cohort_ids`로 전달하고, DB `app_user.external_id`는 provider subject(`google:`/`saml:`/`dev:`) 기반으로 저장한다. 운영 SAML 서명검증, 기관 claim schema/test tenant, deprovisioning audit은 후속. **검증: `pytest app/test_auth_providers.py -q` 22 passed, `pytest app/ -q` 119 passed.**
|
||||
- X2 예산 경고 1차: `ADMIN_USAGE_BUDGET_USD` 설정값을 기준으로 `GET /admin/usage`가 `budget.status=disabled|ok|warn|exceeded`, 사용률, 잔여 예산을 반환하고 관리자 콘솔이 예산 상태 배너를 표시한다. 80% 이상 warn, 100% 이상 exceeded. 캐싱·저비용 모델 분기는 후속. **검증: `pytest app/test_runtime_policy.py -q` 20 passed, `pytest app/ -q` 119 passed, `npm run check:api-types`, `npm run typecheck`.**
|
||||
- H4 LLM call audit 1차: 상담 생성(generate/stream)·fast-loop 평가·deep-loop 평가의 외부 LLM 호출 직후 `audit.llm_call_log`에 provider/model/token/cost/inference_geo/latency metadata만 적재한다. prompt/completion 본문은 저장하지 않고 감사 실패는 상담 루프를 막지 않는다. 실제 운영 `/turn` row proof는 B2에 남긴다. **검증: `pytest app/test_orchestrator_masking.py app/test_evaluation_persistence.py app/test_session_turn_persistence.py -q` 27 passed, `pytest app/ -q` 119 passed.**
|
||||
- X2 예산 경고/저비용 평가 라우팅 1차: `ADMIN_USAGE_BUDGET_USD` 설정값을 기준으로 `GET /admin/usage`가 `budget.status=disabled|ok|warn|exceeded`, 사용률, 잔여 예산을 반환하고 관리자 콘솔이 예산 상태 배너를 표시한다. 80% 이상 warn, 100% 이상 exceeded. `EVALUATOR_FAST_MODEL`/`EVALUATOR_DEEP_MODEL` 설정 시 fast/deep 평가 호출만 해당 모델 override로 gateway에 전달하고, 비워두면 기존 gateway default 라우팅을 유지한다. semantic cache·장기 한도 정책은 후속. **검증: `pytest app/test_evaluator_model_routing.py app/test_runtime_policy.py -q` 23 passed, `pytest app/ -q` 122 passed, `npm run check:api-types`, `npm run typecheck`.**
|
||||
- H4 LLM call audit 1차: 상담 생성(generate/stream)·fast-loop 평가·deep-loop 평가의 외부 LLM 호출 직후 `audit.llm_call_log`에 provider/model/token/cost/inference_geo/latency metadata만 적재한다. prompt/completion 본문은 저장하지 않고 감사 실패는 상담 루프를 막지 않는다. 로컬 dev-login 실제 `/turn` smoke에서 `audit.llm_call_log`가 8→11로 3행 증가했다(session `2460d56c-a9cb-4a40-a175-9575d510a5e9`). 공개 Google OAuth 실제 `/turn` proof는 별도 B2 항목에 남긴다. **검증: `pytest app/test_orchestrator_masking.py app/test_evaluation_persistence.py app/test_session_turn_persistence.py -q` 27 passed, `pytest app/ -q` 119 passed.**
|
||||
- 공개/로컬/Tailnet 로그인 복구: public API 530 원인은 prod에서 개발 전용 `VIGNETTE_VOICE_POC_SAMPLE_TTS=true`가 fail-close된 것과 DB `app.admin_engine_config` 기본 행 부재였다. `scripts/start-public-runtime.ps1`는 public prod 기동 시 샘플 TTS를 강제로 끄고, 운영 DB에는 `claude_cli`/`127.0.0.1:9099` engine config 행을 복구했다. 추가로 dev/Tailnet에서는 public OAuth callback이 로컬/Tailnet 세션으로 붙지 않으므로 Google 버튼과 직접 시작 URL을 `local_oauth_unavailable`로 차단하고 dev-login만 사용한다. public OAuth state는 HttpOnly 쿠키에 묶인 HMAC 서명 토큰으로 복구해 API 재시작 뒤 콜백이 `invalid_state`로 떨어지지 않는다. callback 실패는 비밀값 없는 reason/status로 남기고, 로그인 화면도 token/state/provider/identity 실패 메시지와 reason code를 분리한다. **검증: `https://vignette.chanpaca.net/login` 200 + `index-BzQmv-jU.js`, `https://api-vignette.chanpaca.net/health` prod/db/engine true, public Google auth redirect 302 + HttpOnly state cookie, provider callback error → `/login?oauth=access_denied`, local/Tailnet Google direct는 각 origin의 `/login?oauth=local_oauth_unavailable`, local auth E2E 7 passed, Tailnet auth/dev-login E2E 2 passed.**
|
||||
- Docker dev DB 안전장치: `scripts/dev-up.ps1`가 `vignette-dev-db` healthcheck/pg_isready/role safety를 점검하고, 새 컨테이너 생성 시 `vignette_owner`와 앱 role을 분리해 healthcheck를 붙인다. `infra\.env` compose 필수값 누락도 사전 경고한다. `scripts/dev-down.ps1`은 기본 DB 보존, `-Db` 지정 시 컨테이너 중지로 정리했다. **검증: 현재 Docker DB accepting connections, `vignette_app:false:false`, 기존 컨테이너 healthcheck 없음. 추가 확인 결과 기존 DB는 `POSTGRES_USER=vignette` 기반이고 API startup DDL이 owner 권한을 요구해 런타임 app-role 전환은 마이그레이션 owner/런타임 role 분리 후 진행해야 한다.**
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
| H2 턴별 평가 1차 가동 | `make_eval_hook`이 submit/voice에 주입되고 stream 평가도 붙어 정규화 적재·복원 ✓ |
|
||||
| H3 페르소나 저작 경로 부재 | `persona_repository.py`는 in-code `SEED_PERSONAS`(P1~P3)만 materialize, draft CRUD·외부 JSON 로드 **없음** ✓ |
|
||||
|
||||
그 외 항목(H1 KPI 수집, H4 한국어 이름/기관 NER와 live proof, M1~M2, X1~X2, L1)은 분석 결과이며 착수 전 코드 재확인 권고. M3은 1차 구현 후 재검증 완료. doc4 KPI 범위(κ/ICC·환각률)는 신청서 본문 미명시 — 별도 평가설계 문서 근거 가능성(과대해석 금지).
|
||||
그 외 항목(H1 KPI 수집, H4 한국어 이름/기관 NER와 동의 게이트, M1~M2, X1~X2, L1)은 분석 결과이며 착수 전 코드 재확인 권고. M3은 1차 구현 후 재검증 완료. doc4 KPI 범위(κ/ICC·환각률)는 신청서 본문 미명시 — 별도 평가설계 문서 근거 가능성(과대해석 금지).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -74,10 +74,10 @@
|
|||
- **현재상태**(✓직접검증): personas 라우트에 검수 승인/반려만, draft 생성·편집 API 없음. persona_repository는 in-code SEED(P1~P3)만, 외부 JSON 미로드.
|
||||
- **권고**: 페르소나 저작 CRUD(draft→review)와 P4~P7 적재, 루브릭·이론 콘텐츠를 임상팀 편집 가능 데이터로 외부화.
|
||||
|
||||
### [high] H4. PII 마스킹 한국어 공백 + 외부전송 live proof 잔여
|
||||
### [high] H4. PII 마스킹 한국어 이름/기관 NER + 동의 게이트 잔여
|
||||
- **근거**: doc1/2/5(실명·날짜·장소·금액·미성년·자살시도 다수), doc4(IRB·개인정보)
|
||||
- **현재상태**(재검증): Presidio language='en' 고정으로 이름/기관명은 NER 보강이 필요하다. 한국어 날짜·금액·행정구역 주소 정규식 폴백은 추가됐고, 상담 생성(generate/stream)·fast/deep 평가 호출 직후 `audit.llm_call_log`에 provider/model/token/cost/inference_geo/latency만 적재한다. prompt/completion 본문은 저장하지 않는다. consent_at 컬럼만, 동의 수집/게이트/철회 엔드포인트 전무.
|
||||
- **권고**: 한국어 이름/기관 NER 추가, 실제 운영 로그인 `/turn` 후 `audit.llm_call_log` row 실측, 미성년/guardian 동의 수집·하드게이트·철회.
|
||||
- **현재상태**(재검증): Presidio language='en' 고정으로 이름/기관명은 NER 보강이 필요하다. 한국어 날짜·금액·행정구역 주소 정규식 폴백은 추가됐고, 상담 생성(generate/stream)·fast/deep 평가 호출 직후 `audit.llm_call_log`에 provider/model/token/cost/inference_geo/latency만 적재한다. prompt/completion 본문은 저장하지 않는다. 로컬 dev-login 실제 `/turn` smoke에서 `audit.llm_call_log` 3행 증가를 확인했다. consent_at 컬럼만, 동의 수집/게이트/철회 엔드포인트 전무.
|
||||
- **권고**: 한국어 이름/기관 NER 추가, 미성년/guardian 동의 수집·하드게이트·철회. 공개 Google OAuth 실제 `/turn` proof는 별도 운영 게이트.
|
||||
|
||||
### [medium] M1. 비언어/준언어 임상 이벤트 캡처·태깅 부재
|
||||
- **근거**: doc1/2/5(침묵 초·한숨·울음·떨림을 1급 단서)
|
||||
|
|
@ -98,10 +98,10 @@
|
|||
- **현재상태**: `scripts/export-recursive-dataset.py`와 `app.services.dataset_export`로 masked-text JSONL dry-run, PII scan, kappa/ICC 계산, approved export 게이트를 구현했다. 기본 산출물은 `technical_dry_run`이며 실제 승인 export·골든셋 승격은 데이터 steward/legal review와 IAA 통과가 필요하다.
|
||||
- **권고**: 파일럿 evidence에서 reviewer disposition, steward/legal 승인, gold annotation 라운드 적재 후 `approved_for_recursive_learning_seed` 승격 검증.
|
||||
|
||||
### [medium/추적] X2. AI API 비용 관측·예산 경고 1차 완료·최적화 미구현
|
||||
### [medium/추적] X2. AI API 비용 관측·예산 경고·평가 저비용 라우팅 1차 완료
|
||||
- **근거**: doc3(회의록이 'AI API 비용'을 운영 리스크로 명시)
|
||||
- **현재상태**: 1차로 턴별 provider/model/tokens/cost 저장 경로와 `GET /admin/usage`, 관리자 비용 대시보드를 연결했다. `ADMIN_USAGE_BUDGET_USD` 기준 예산 상태(ok/warn/exceeded)도 응답/UI에 표시한다. DB 미가용 dev는 runtime store fallback, prod는 fail-closed다. 캐싱·저비용 모델 분기는 아직 없다.
|
||||
- **권고**: 캐싱, 저비용 모델 분기, 장기 비용 추이/한도 정책.
|
||||
- **현재상태**: 1차로 턴별 provider/model/tokens/cost 저장 경로와 `GET /admin/usage`, 관리자 비용 대시보드를 연결했다. `ADMIN_USAGE_BUDGET_USD` 기준 예산 상태(ok/warn/exceeded)도 응답/UI에 표시한다. `EVALUATOR_FAST_MODEL`/`EVALUATOR_DEEP_MODEL` 설정 시 fast/deep 평가 호출만 해당 모델 override로 gateway에 전달하고, 비워두면 기존 gateway default 라우팅을 유지한다. DB 미가용 dev는 runtime store fallback, prod는 fail-closed다. 캐싱은 L0~L2 cache hint와 gateway session reuse까지만 연결돼 있다.
|
||||
- **권고**: semantic cache, 장기 비용 추이/한도 정책, 운영 모델별 비용 검증.
|
||||
|
||||
### [low] L1. 기술스택 신청서-구현 불일치 및 단기일정 산출물 압박
|
||||
- **근거**: doc4(Spring Boot 3/Node.js·TimescaleDB vs 실제 FastAPI/Python), doc3(20주)
|
||||
|
|
@ -115,8 +115,8 @@
|
|||
- C3 1차 완료: `theory_mode`가 세션·평가·생성 프롬프트까지 흐른다. 후속은 임상팀 CBT 체인·이론부합 루브릭·명시적 선택 UI.
|
||||
- H2 1차 완료: `make_eval_hook`과 stream 평가가 턴 파이프라인에 붙고 정규화 테이블로 적재·복원된다. 대안발화도 `app.alternative_utterance`로 정규화한다. 후속은 2열 리뷰 UI·골든셋.
|
||||
- H3: 페르소나 저작 CRUD + P4~P7 로드 경로.
|
||||
- H4(부분): 한국어 이름/기관 NER, 운영 로그인 `/turn` 후 llm_call_log row 실측, 동의 게이트.
|
||||
- X1: dry-run JSONL export·PII scan·IAA 계산 1차 완료. `ds.*` write는 `--write-dataset` 명시 시에만 수행한다. X2 비용 관측·budget alert 1차는 완료했고 캐싱·저비용 모델 분기는 후속. M1/M2도 1차 구현 완료, provider 기반 비언어 감지와 case_digest/pinned_fact 실적재는 후속.
|
||||
- H4(부분): 한국어 이름/기관 NER, 동의 게이트. LLM call audit 적재와 로컬 live row proof는 완료.
|
||||
- X1: dry-run JSONL export·PII scan·IAA 계산 1차 완료. `ds.*` write는 `--write-dataset` 명시 시에만 수행한다. X2 비용 관측·budget alert와 evaluator 모델 override 1차는 완료했고 semantic cache·장기 한도 정책은 후속. M1/M2도 1차 구현 완료, provider 기반 비언어 감지와 case_digest/pinned_fact 실적재는 후속.
|
||||
|
||||
### B. 소유자 결정 / 외부(임상팀·기관) 의존
|
||||
- **임상팀(구훈정·어유경) 산출물**: C1 채점 루브릭·항목 확정, C3 CBT 이론 콘텐츠·프롬프트 체인, C2 위기 스크립트·서약 문안, H2 골든셋 코딩 — 콘텐츠는 doc3 R&R상 임상팀 소유. 코드는 구조를 선제 구축하되 임상 문안과 평가기준은 외부 정의로 받는다.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue