48 lines
3.9 KiB
Markdown
48 lines
3.9 KiB
Markdown
# 251114_admin_dynamic_intent_runtime_tests
|
|
|
|
## 개요
|
|
- **작성자**: admin
|
|
- **작성일**: 2025-11-14
|
|
- **관련 서비스**: rb8001 (51124), PostgreSQL(main_db on 51123), DOCS
|
|
- **목표**: 의도 레지스트리를 DB에서 동적으로 불러오도록 코드/문서 수정 후 `/api/test/router-message` 10건 시나리오 테스트
|
|
|
|
## 문제 요약
|
|
- SemanticIntentClassifier가 YAML에만 의존해 신규 intent 추가 시 코드 변경과 재배포가 필요했고, 실제 로그 패턴을 DB에 넣어도 즉시 반영되지 않음.
|
|
- 테스트 엔드포인트 `/api/test/router-message`로 주요 시나리오를 검증할 때 intent 필드가 항상 null로 표기되어 흐름 확인이 어려웠음.
|
|
|
|
## 해결/변경 사항
|
|
1. **코드**
|
|
- `app/brain/intent_store.py`: `load_intents_db()` 추가로 `intents` 테이블에서 name/description을 로드 (inactive=FALSE 제외)하고, 프로토타입/threshold 없이도 안전한 폴백 구현.
|
|
- `app/brain/semantic_classifier.py`: DB 레지스트리를 우선 사용하고, 프로토타입이 없으면 해당 registry에 맞춰 즉시 임베딩 생성. YAML은 완전한 폴백으로만 사용.
|
|
- `tests/test_semantic_classifier_dynamic.py`: DB/폴백 경로를 각각 검증하는 단위 테스트 추가.
|
|
2. **문서**
|
|
- `DOCS/300_architecture/database/tables.md`: `intents`, `intent_prototypes`, `intent_thresholds`, `intent_path_stats` 설명과 SemanticIntentClassifier가 이를 활용하는 흐름 추가.
|
|
3. **DB 확인**
|
|
- 51123 PostgreSQL(main_db)에 접속해 intent 관련 테이블 스키마/데이터 확인 (`SELECT table_name FROM information_schema.tables WHERE table_schema='public'` 등).
|
|
4. **배포**
|
|
- rb8001 / DOCS 각각 `main`에 푸시하여 자동 배포 → `docker ps`, `docker logs rb8001 --tail 50` 로 새 컨테이너 정상 기동 확인.
|
|
|
|
## 테스트 (`/api/test/router-message`)
|
|
|
|
| # | 입력 | 응답 요약 | 비고 |
|
|
|---|------|-----------|------|
|
|
|1|“메일함이 엉망… 정리”|“응답을 생성할 수 없습니다.”|intent null (아직 스킬 미구현)|
|
|
|2|“김팀장에게 일정 확인 메일 작성…”|“응답을 생성할 수 없습니다.”|intent null|
|
|
|3|“며칠째 수신함 확인…”|“응답을 생성할 수 없습니다.”|intent null|
|
|
|4|“요즘 테크 업계 소식…”|“응답을 생성할 수 없습니다.”|intent null|
|
|
|5|“어제 공유한 기사 두 개만 요약…”|“어떤 기사였는지 다시 알려달라”|뉴스 요약 프롬프트|
|
|
|6|“회의록에서 해야 할 일만 체크리스트…”|“어떤 회사를 말씀하시나요?”|액션 추출 스킬이 추가 정보 요청|
|
|
|7|“이 계약 초안에서 위험한 조항…”|“어떤 계약 초안을 분석해 드릴까요?”|문서 분석 프롬프트|
|
|
|8|“11월 22일 오전 10시 강남역…”|일정 확인/등록 유도|calendar_confirm 흐름 정상|
|
|
|9|“좋아, 등록해줘”|“구글 캘린더에 등록했습니다”|calendar_approval → create_event 성공|
|
|
|10|“그냥 이야기 좀 하자”|“무엇에 대해 이야기하고 싶으신가요?”|general chat 응답|
|
|
|
|
- 모든 요청이 HTTP 200, router 전체 플로우를 통과.
|
|
- intent 필드는 router 응답에 포함되지 않아 null로 표시되지만, 스킬별 프롬프트/승인 로직은 정상 작동.
|
|
|
|
## 교훈
|
|
1. **동적 레지스트리**: intent를 DB에서 관리하도록 해도 실제 정확도를 높이려면 의도 정의/임베딩/threshold를 주기적으로 정제해야 하며, 로그 기반 라벨링 루틴이 필요하다.
|
|
2. **테스트 커버리지**: `/api/test/router-message` 엔드포인트로 실제 플로우를 검증할 수 있으나 intent 값이 응답에 노출되지 않아 디버깅이 어려우므로 추후 intent/skill 정보 노출 검토 필요.
|
|
3. **자동 배포 확인**: 코드/문서 각각 별도 레포라서 변경 후 두 리포 모두 push + rb8001 컨테이너 로그 확인까지 해야 안전하다.
|
|
|