docs: plan 문서 간결화 계속 (504줄 삭제)
This commit is contained in:
parent
4818ea13e3
commit
fc3406889f
@ -1,182 +1,59 @@
|
||||
# Workspace 테이블 통합 계획
|
||||
|
||||
## 작성일: 2025년 8월 31일
|
||||
**날짜**: 2025-08-31
|
||||
**목표**: company + workspaces → workspaces로 통합
|
||||
|
||||
## 🎯 목표
|
||||
`company` 테이블과 `workspaces` 테이블을 `workspaces`로 통합하여 DB 스키마 일관성 확보
|
||||
---
|
||||
|
||||
## 📊 현재 상황
|
||||
## 현재 문제
|
||||
|
||||
### 테이블 구조 비교
|
||||
| 구분 | company | workspaces |
|
||||
|------|-----------|------------|
|
||||
| **포트 컬럼** | `container_port` | `robeing_port` |
|
||||
| **FK 참조** | `slack_workspaces.company_id` | `workspace_member.workspace_id` |
|
||||
| **추가 컬럼** | - | `robeing_id`, `robeing_url`, `max_members`, `workspace_type` |
|
||||
| **데이터** | 4개 레코드 | 2개 레코드 |
|
||||
### 중복 데이터
|
||||
- Company-X가 양쪽 테이블에 존재
|
||||
- 컬럼명 불일치 (`container_port` vs `robeing_port`)
|
||||
- FK 관계 불일치 (slack_workspaces → company, workspace_member → workspaces)
|
||||
|
||||
### 문제점
|
||||
1. 중복 데이터 (Company-X가 양쪽 테이블에 존재)
|
||||
2. FK 관계 불일치 (slack_workspaces → company, workspace_member → workspaces)
|
||||
3. 코드에서 잘못된 참조 (`workspace.workspace`, `workspace.robeing_port`)
|
||||
### 코드 오류
|
||||
- `workspace.workspace` (잘못된 참조)
|
||||
- `workspace.robeing_port` (컬럼명 불일치)
|
||||
|
||||
## 🔧 작업 계획
|
||||
---
|
||||
|
||||
### Phase 1: DB 백업 및 준비
|
||||
## 마이그레이션 계획
|
||||
|
||||
### Phase 1: DB 백업
|
||||
```bash
|
||||
# 백업 생성
|
||||
sudo -u postgres pg_dump -t company -t workspaces -t slack_workspaces main_db > /home/admin/backup_workspace_$(date +%Y%m%d_%H%M%S).sql
|
||||
sudo -u postgres pg_dump -t company -t workspaces main_db > /backup/workspace.sql
|
||||
```
|
||||
|
||||
### Phase 2: DB 스키마 변경
|
||||
### Phase 2: 데이터 통합
|
||||
```sql
|
||||
-- 1. company 데이터를 workspaces로 이동
|
||||
INSERT INTO workspaces (id, name, subdomain, robeing_port, status, created_at, updated_at)
|
||||
SELECT id, name, subdomain, container_port, status, created_at, updated_at
|
||||
FROM company
|
||||
WHERE id NOT IN (SELECT id FROM workspaces);
|
||||
-- 1. company → workspaces 이동
|
||||
INSERT INTO workspaces (id, name, subdomain, robeing_port)
|
||||
SELECT id, name, subdomain, container_port FROM company;
|
||||
|
||||
-- 2. slack_workspaces 테이블 수정
|
||||
-- 2. slack_workspaces FK 수정
|
||||
ALTER TABLE slack_workspace
|
||||
ADD COLUMN workspace_id UUID;
|
||||
ADD COLUMN workspace_id UUID,
|
||||
DROP COLUMN company_id;
|
||||
|
||||
UPDATE slack_workspace
|
||||
SET workspace_id = company_id;
|
||||
|
||||
ALTER TABLE slack_workspace
|
||||
DROP COLUMN company_id,
|
||||
ADD CONSTRAINT slack_workspaces_workspace_id_fkey
|
||||
FOREIGN KEY (workspace_id) REFERENCES workspaces(id);
|
||||
|
||||
-- 3. company 테이블 제거
|
||||
-- 3. company 테이블 삭제
|
||||
DROP TABLE company CASCADE;
|
||||
```
|
||||
|
||||
### Phase 3: 코드 수정
|
||||
- `auth-server/app/models/workspace.py`: company_id → workspace_id
|
||||
- `auth-server/app/api/slack_router.py`: workspace.workspace 제거
|
||||
|
||||
#### 3.1 모델 파일 수정
|
||||
**파일**: `/home/admin/auth-server/app/models/workspace.py`
|
||||
---
|
||||
|
||||
```python
|
||||
# Line 44: company_id를 workspace_id로 변경
|
||||
workspace_id = Column(UUID(as_uuid=True), ForeignKey("workspaces.id"), nullable=False)
|
||||
## 검증
|
||||
|
||||
# Line 45 아래: relationship 추가
|
||||
workspace = relationship("Workspace", back_populates="slack_workspaces")
|
||||
1. 모든 workspace 조회 성공
|
||||
2. slack_workspaces FK 정상
|
||||
3. 기존 기능 정상 작동
|
||||
|
||||
# Workspace 클래스 (Line 35 아래): relationship 추가
|
||||
slack_workspaces = relationship("SlackWorkspace", back_populates="workspace")
|
||||
```
|
||||
---
|
||||
|
||||
#### 3.2 라우터 파일 수정
|
||||
**파일**: `/home/admin/auth-server/app/api/slack_router.py`
|
||||
## 참고
|
||||
|
||||
```python
|
||||
# Line 97: workspace 직접 참조로 변경
|
||||
workspace_obj = workspace # workspace.workspace 제거
|
||||
|
||||
# Line 123: 엔드포인트 경로 수정 (선택사항)
|
||||
container_url = f"http://localhost:{workspace.robeing_port}/api/slack/events"
|
||||
```
|
||||
|
||||
#### 3.3 Provider 파일 수정
|
||||
**파일**: `/home/admin/auth-server/app/providers/slack.py`
|
||||
|
||||
```python
|
||||
# Line 542: company_id를 workspace_id로 변경
|
||||
existing_workspace.workspace_id = workspace.id
|
||||
|
||||
# Line 557: company_id를 workspace_id로 변경
|
||||
workspace_id=workspace.id,
|
||||
```
|
||||
|
||||
### Phase 4: 테스트 및 검증
|
||||
|
||||
#### 4.1 DB 검증
|
||||
```sql
|
||||
-- workspace 통합 확인
|
||||
SELECT * FROM workspaces;
|
||||
|
||||
-- FK 관계 확인
|
||||
SELECT
|
||||
sw.team_name,
|
||||
w.name as workspace_name,
|
||||
w.robeing_port
|
||||
FROM slack_workspace sw
|
||||
JOIN workspaces w ON sw.workspace_id = w.id;
|
||||
```
|
||||
|
||||
#### 4.2 API 테스트
|
||||
```bash
|
||||
# Slack 로그인 테스트
|
||||
curl https://auth.ro-being.com/auth/slack/login/
|
||||
|
||||
# Event 라우팅 테스트
|
||||
curl -X POST https://auth.ro-being.com/slack/events/router \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"type":"url_verification","challenge":"test"}'
|
||||
```
|
||||
|
||||
### Phase 5: 배포
|
||||
|
||||
1. Git commit & push
|
||||
```bash
|
||||
cd /home/admin/auth-server
|
||||
git add -A
|
||||
git commit -m "refactor: company 테이블을 workspaces로 통합"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
2. Docker 재시작
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
## ⚠️ 주의사항
|
||||
|
||||
### 롤백 계획
|
||||
문제 발생 시 백업에서 복원:
|
||||
```bash
|
||||
sudo -u postgres psql main_db < /home/admin/backup_workspace_YYYYMMDD_HHMMSS.sql
|
||||
```
|
||||
|
||||
### 영향받는 서비스
|
||||
- auth-server: 모델 및 라우터 수정
|
||||
- rb8001: 영향 없음 (직접 연결 방식 사용 중)
|
||||
- frontend-customer: 영향 없음
|
||||
|
||||
### 예상 다운타임
|
||||
- DB 마이그레이션: 약 1-2분
|
||||
- 코드 배포: 약 2-3분
|
||||
- 총 예상 시간: 5분 이내
|
||||
|
||||
## 📝 체크리스트
|
||||
|
||||
- [ ] DB 백업 완료
|
||||
- [ ] company → workspaces 데이터 이동
|
||||
- [ ] slack_workspaces FK 변경
|
||||
- [ ] company 테이블 삭제
|
||||
- [ ] workspace.py 모델 수정
|
||||
- [ ] slack_router.py 수정
|
||||
- [ ] slack.py provider 수정
|
||||
- [ ] 테스트 완료
|
||||
- [ ] Git push
|
||||
- [ ] Docker 재배포
|
||||
|
||||
## 🎯 완료 후 상태
|
||||
|
||||
### 통합된 DB 구조
|
||||
- 단일 `workspaces` 테이블
|
||||
- 모든 FK가 `workspaces.id` 참조
|
||||
- 일관된 컬럼명 (`robeing_port`)
|
||||
|
||||
### 개선된 코드
|
||||
- 명확한 relationship 정의
|
||||
- 올바른 속성 참조
|
||||
- 통일된 엔드포인트
|
||||
|
||||
## 📚 참고 문서
|
||||
- `/home/heejae/DOCS/plans/250831_todo_and_tech_debt.md`
|
||||
- `/home/heejae/DOCS/300_architecture/380_authentication_system.md`
|
||||
- `/home/heejae/DOCS/300_architecture/database/tables.md`
|
||||
- `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md`
|
||||
|
||||
@ -1,117 +1,62 @@
|
||||
# main_db3 → main_db 마이그레이션 계획
|
||||
|
||||
## 작성일: 2025-09-11
|
||||
## 목적: main_db3 데이터를 main_db로 통합
|
||||
**날짜**: 2025-09-11
|
||||
**목적**: main_db3 데이터를 main_db로 통합
|
||||
|
||||
---
|
||||
|
||||
## 1. 현황 분석
|
||||
## 현황
|
||||
|
||||
### main_db3 (삭제 예정)
|
||||
- 총 13개 테이블, 614개 레코드
|
||||
- 주요 데이터: users(17), company(4), conversation_log(555)
|
||||
- Slack/Gmail 연동 데이터 보유
|
||||
- 13개 테이블, 614개 레코드
|
||||
- 주요: users(17), company(4), conversation_log(555)
|
||||
|
||||
### main_db (운영 DB)
|
||||
- 총 11개 테이블, 대부분 비어있음
|
||||
- 기존 데이터: company(2), team(2)
|
||||
- 11개 테이블, 대부분 비어있음
|
||||
- 기존: company(2), team(2)
|
||||
|
||||
---
|
||||
|
||||
## 2. 테이블 매핑
|
||||
## 테이블 매핑
|
||||
|
||||
| main_db3 | main_db | 비고 |
|
||||
|----------|---------|------|
|
||||
| company | company | 2개 중복 확인 필요 |
|
||||
| users | user | team_id 필수 추가 |
|
||||
| workspaces | team | 구조 변환 필요 |
|
||||
| workspace_member | workspace_member | user_id 매핑 |
|
||||
| slack_workspaces | slack_workspace | team_id 매핑 |
|
||||
| user_preference | user_preference | slack_user_id 제거됨 |
|
||||
| conversation_log | conversation_log | robeing_id 컬럼 없음 |
|
||||
| gmail_token | gmail_token | 구조 동일 |
|
||||
| robeing_stats | robeing | product_id, team_id 추가 |
|
||||
| slack_user_mapping | - | workspace_member로 통합 |
|
||||
| company | company | 중복 확인 |
|
||||
| users | user | team_id 필수 |
|
||||
| workspaces | team | 구조 변환 |
|
||||
| conversation_log | conversation_log | robeing_id 없음 |
|
||||
| gmail_token | gmail_token | 동일 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 마이그레이션 순서
|
||||
## 마이그레이션 순서
|
||||
|
||||
### Phase 1: 조직 구조 (필수 선행)
|
||||
### Phase 1: 조직 구조
|
||||
```sql
|
||||
-- 1. company → company (중복 제외)
|
||||
INSERT INTO company (id, name, url, created_at, updated_at)
|
||||
SELECT id, name, domain, created_at, updated_at
|
||||
FROM main_db3.company
|
||||
WHERE id NOT IN ('28f17b47-33f8-47ac-b1ae-100e77b37edb', '99d22d6b-d327-4fa4-bd2f-d228c11056e2');
|
||||
|
||||
-- 2. workspaces → team 변환
|
||||
INSERT INTO team (id, company_id, name, created_at, updated_at)
|
||||
SELECT id, company_id, name, created_at, updated_at FROM main_db3.workspaces;
|
||||
INSERT INTO company SELECT * FROM main_db3.company WHERE id NOT IN (...중복...);
|
||||
INSERT INTO team SELECT id, company_id, name FROM main_db3.workspaces;
|
||||
```
|
||||
|
||||
### Phase 2: 사용자 데이터
|
||||
```sql
|
||||
-- 3. users → user (기본 team_id 할당)
|
||||
INSERT INTO "user" (id, team_id, email, name, username, oauth_provider, oauth_id, is_active)
|
||||
SELECT u.id,
|
||||
COALESCE(wm.workspace_id, '38bdc27d-cb01-4960-867e-41733d2f3529'), -- 기본 팀
|
||||
u.email, u.name, u.username, u.oauth_provider, u.oauth_id, u.is_active
|
||||
FROM main_db3.users u
|
||||
LEFT JOIN main_db3.workspace_member wm ON u.id = wm.user_id;
|
||||
|
||||
-- 4. workspace_member → workspace_member (slack_user_id 추가 예정)
|
||||
INSERT INTO workspace_member (id, user_id, role, is_active, joined_at)
|
||||
SELECT id, user_id, role::user_role, is_active, joined_at FROM main_db3.workspace_member;
|
||||
INSERT INTO "user" (id, team_id, email, name)
|
||||
SELECT u.id, COALESCE(wm.workspace_id, '기본팀'), u.email, u.name
|
||||
FROM main_db3.users u;
|
||||
```
|
||||
|
||||
### Phase 3: 통합 데이터
|
||||
```sql
|
||||
-- 5. slack_workspaces → slack_workspace
|
||||
INSERT INTO slack_workspace (id, team_id, slack_team_id, bot_token, is_active)
|
||||
SELECT id, workspace_id, team_id, bot_token, is_active FROM main_db3.slack_workspaces;
|
||||
|
||||
-- 6. user_preference → user_preference (slack_user_id 제거)
|
||||
INSERT INTO user_preference (user_id, news_keywords, email_filter, briefing_enabled)
|
||||
SELECT user_id, news_keywords, email_filter, briefing_enabled FROM main_db3.user_preference;
|
||||
|
||||
-- 7. gmail_token → gmail_token
|
||||
INSERT INTO gmail_token SELECT * FROM main_db3.gmail_token;
|
||||
INSERT INTO conversation_log SELECT * FROM main_db3.conversation_log;
|
||||
```
|
||||
|
||||
### Phase 4: 대화 기록
|
||||
```sql
|
||||
-- 8. conversation_log → conversation_log (컬럼 매핑 주의)
|
||||
INSERT INTO conversation_log (user_id, channel_id, message, response, intent, confidence, timestamp)
|
||||
SELECT user_id, channel_id, message, response, intent, confidence, timestamp
|
||||
FROM main_db3.conversation_log WHERE user_id IS NOT NULL;
|
||||
```
|
||||
### Phase 4: 검증 및 정리
|
||||
- 데이터 개수 확인
|
||||
- FK 제약 검증
|
||||
- main_db3 삭제
|
||||
|
||||
---
|
||||
|
||||
## 4. 검증 및 롤백
|
||||
## 참고
|
||||
|
||||
### 검증
|
||||
- 레코드 수 대조
|
||||
- 외래키 무결성 확인
|
||||
- 주요 사용자 데이터 샘플 검증
|
||||
|
||||
### 롤백 계획
|
||||
- 마이그레이션 전 main_db 백업
|
||||
- 실패 시 TRUNCATE 후 백업 복원
|
||||
|
||||
---
|
||||
|
||||
## 5. 주의사항
|
||||
- **team_id 필수**: user 테이블 INSERT 시 NOT NULL
|
||||
- **UUID 타입**: 모든 ID는 UUID 타입 유지
|
||||
- **slack_user_id**: workspace_member로 이동 예정
|
||||
- **실행 시간**: 새벽 시간대 권장 (서비스 영향 최소화)
|
||||
|
||||
---
|
||||
|
||||
## 6. 실행 결과 (2025-09-11)
|
||||
|
||||
### User 테이블 마이그레이션 완료
|
||||
- main_db3에서 12명 이관 (총 14명 중 2명 중복 제외)
|
||||
- UUID 불일치: goeun2dc@gmail.com, info@company-x.partners (기존 main_db UUID 유지)
|
||||
- `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md`
|
||||
|
||||
@ -1,119 +1,95 @@
|
||||
# 의도 런타임(하이브리드) 설계: 임베딩 + 베이지안 + 동적학습 + LLM 재분석 + A/B/밴딧
|
||||
# 의도 런타임 하이브리드 설계
|
||||
|
||||
작성일: 2025-10-23
|
||||
작성자: happybell80
|
||||
대상 서비스: rb8001 (51124)
|
||||
**날짜**: 2025-10-23
|
||||
**목표**: 임베딩 + 베이지안 + 동적학습 통합 의도 파악 시스템
|
||||
|
||||
---
|
||||
|
||||
## 1) 개요
|
||||
- 목표: 룰/키워드 중심 의도 파악의 한계를 넘어, 의미 기반·불확실성 관리·지속 학습을 갖춘 “의도 런타임”으로 전환.
|
||||
- 접근: FastPath(규칙/NB) + 임베딩 Top‑K 후보축소 + LLM JSON 재분석 + Beta(α,β) 기반 동적 임계치/경로 최적화.
|
||||
- 기대: Unknown↓, 잘못된 실행<1%, LLM 호출≤30% 유지, 지연 관리(중앙값 < 800ms).
|
||||
## 개요
|
||||
|
||||
## 2) 아키텍처(Phase 1)
|
||||
- FastPath: 기존 `DecisionEngine`(정규식 + Naive Bayes). conf≥0.9 시 즉시 결정.
|
||||
- 임베딩 후보축소: intent 설명/예시 벡터와 코사인 유사도 Top‑K + 마진 기반 신뢰도.
|
||||
- LLM 재분석: Top‑K만 JSON 스키마(`{intent, slots, confidence, clarify}`)로 결정, conf<τ는 clarify.
|
||||
- 캘리브레이션: 유사도·마진 기반 conf를 온도/Isotonic 등으로 보정(과신 방지).
|
||||
**목표**: 룰 중심 의도 파악 → 의미 기반 + 불확실성 관리 + 지속 학습
|
||||
**접근**: FastPath + 임베딩 Top-K + LLM 재분석 + Beta(α,β) 동적 임계치
|
||||
|
||||
구현 파일(스캐폴드)
|
||||
- `rb8001/app/brain/intent_graph.py` — FastPath→Semantic→LLM 파이프(ENV: `INTENT_ENGINE=graph`)
|
||||
- `rb8001/app/brain/semantic_classifier.py` — intent_registry 기반 제로샷 후보축소
|
||||
- `rb8001/app/llm/intent_parser.py` — LLM 함수호출(JSON) 파서
|
||||
- `rb8001/app/brain/intent_registry.yaml` — intent 설명/슬롯 레지스트리
|
||||
|
||||
## 3) 임베딩 설계
|
||||
- 모델: 한국어 강건 다국어 SBERT/miniLM 계열(테스트 후 선정). 서비스는 HTTP 임베딩 사이드카 사용.
|
||||
- 프로토타입: intent별 centroid(설명+예시 임베딩 평균). DB 버전관리 → 성공 샘플 EMA 반영(온라인), outlier 감쇠.
|
||||
- 신뢰도: cos(top1)·마진(top1–top2) 합성 → 캘리브레이션으로 정규화.
|
||||
|
||||
## 4) 베이지안·동적 학습
|
||||
- 의도/경로별 성공률 Beta(α,β) 추적: 성공 α+=1, 실패 β+=1 → θ~Beta(α,β).
|
||||
- 경로 선택: Thompson Sampling으로 FastPath/LLM/clarify 임계치 τ 동적 최적화.
|
||||
- 로그 스키마(요지): intent_decision_log(user_id, message, candidates, chosen, confs, path, success, clarify, latency, ts), prototype_version(intent, centroid_hash, updated_at).
|
||||
|
||||
## 5) LLM 재분석 가드레일
|
||||
|
||||
### 5.1 기본 구조
|
||||
- 입력: Top‑K 후보명/설명 + 최근 컨텍스트 최소화 주입.
|
||||
- 출력: JSON 한 줄. OOS/불확실은 clarify true, 슬롯 미충족 시 되묻기 우선.
|
||||
|
||||
### 5.2 Chain-of-Thought (CoT) 적용 방안 (2025-11-18 추가)
|
||||
|
||||
**목적**: 복잡한 질문이나 확신도 낮은 경우 LLM이 단계별 추론을 통해 더 정확한 의도 분류를 수행하도록 개선.
|
||||
|
||||
**구현 방안**:
|
||||
1. **IntentParserLLM 프롬프트 수정**:
|
||||
- 현재: "JSON만 출력하세요"
|
||||
- 변경: "단계별로 추론한 후 JSON 출력하세요"
|
||||
- 추론 단계:
|
||||
- 1단계: 메시지에서 핵심 키워드/엔티티 추출
|
||||
- 2단계: 의도 후보 검토 및 컨텍스트 분석 (직전 대화, 슬롯 정보 등)
|
||||
- 3단계: 최종 의도 결정 및 신뢰도 평가
|
||||
|
||||
2. **조건부 CoT 활성화**:
|
||||
- 환경변수: `INTENT_USE_COT=true` (기본값: false)
|
||||
- 활성화 조건:
|
||||
- FastPath/Semantic에서 확신도 낮은 경우 (conf < 0.7)
|
||||
- 복잡한 질문 (키워드 3개 이상, 대명사 포함 등)
|
||||
- 컨텍스트 의존적 질문 ("이 기업", "그 회사" 등)
|
||||
- 비활성화 조건:
|
||||
- FastPath/Semantic에서 확신도 높은 경우 (conf ≥ 0.9) → CoT 생략하여 비용/지연 최소화
|
||||
|
||||
3. **추론 과정 로깅**:
|
||||
- LLM 출력에서 추론 단계는 로깅/디버깅용으로 저장
|
||||
- 최종 JSON만 파싱하여 기존 인터페이스 유지
|
||||
- Human-in-the-loop 리뷰 큐에서 추론 과정 검증 가능
|
||||
- 로그 스키마: `intent_cot_log(user_id, message, reasoning_steps, final_intent, timestamp)`
|
||||
|
||||
**예상 효과**:
|
||||
- 복잡한 질문 정확도 향상 (특히 "이 기업 대표 누구야?" 같은 컨텍스트 의존적 질문)
|
||||
- 의도 분류 오류 감소 (단계별 검증으로 잘못된 실행 방지)
|
||||
- 비용/지연 최소화 (조건부 활성화로 불필요한 CoT 호출 방지)
|
||||
|
||||
**구현 파일**:
|
||||
- `rb8001/app/llm/intent_parser.py` — CoT 프롬프트 추가 및 조건부 활성화 로직
|
||||
- `rb8001/app/core/config.py` — `INTENT_USE_COT` 환경변수 추가
|
||||
|
||||
## 6) 실험·배포 전략
|
||||
- A/B → 밴딧: 10%→30%→50% 점진 롤아웃, 지표(Unknown/Clarify/오실행/지연/비용) 모니터링.
|
||||
- 임계치/경로/모델 후보는 밴딧 “팔(Arm)”로 관리, Thompson Sampling으로 자동 최적.
|
||||
|
||||
## 7) 운영 지표
|
||||
- 정확도/Unknown/Clarify/오실행(<1%)
|
||||
- 비용/지연: LLM 호출율≤30%, 중앙 지연<800ms.
|
||||
- 사용자 피드백/수정률, 슬롯 부족 비율.
|
||||
|
||||
## 8) rb8001 적용 계획
|
||||
- Phase 1 (이번 배포): IntentGraph 플래그 경로 + Clarify UX(버튼 실패 시 숫자 선택 폴백) + 엔티티/패턴 보강.
|
||||
- Phase 2: Beta(α,β)·임계치/경로 동적화 + 프로토타입 DB버전 관리 + 캘리브레이션 모듈.
|
||||
- Phase 3: SetFit/경량 분류기 오프라인 재학습 + 개인화 사전(동의어/별칭) 자동 갱신.
|
||||
|
||||
활성화/헬스체크
|
||||
- 활성화: `INTENT_ENGINE=graph`
|
||||
- 헬스: `curl -sf http://localhost:8001/health`
|
||||
- 로그: `docker logs rb8001 --tail 200 | grep -iE "IntentGraph|web_search|CLARIFY_ENTITY|error|fail"`
|
||||
|
||||
## 9) 리스크·완화
|
||||
- LLM 비용/지연: FastPath/임베딩 우선, conf 게이트/Top‑K 축소로 절감.
|
||||
- 과신/오실행: 캘리브레이션+clarify 정책, Beta 기반 안전 임계치.
|
||||
- 데이터 드리프트: 주간 리트레이닝/프로토타입 갱신, 밴딧으로 자동 적응.
|
||||
|
||||
## 10) 검증·모니터링
|
||||
- 테스트: `rb8001/tests/test_intent_entity_skill_comprehensive.py` — 40/40 통과(의도/엔티티/스킬).
|
||||
- 리포트: `rb8001/tests/test_results_251023_final.md` — 100% 결과 기록.
|
||||
- 모니터: Unknown률/Clarify 비율/오실행/LLM 호출율/평균 지연, 슬랙 이슈는 즉시 로그 근거로 대응.
|
||||
|
||||
## 11) 참고(관련 구현 포인터)
|
||||
- `rb8001/app/router/router.py` — IntentGraph 게이트(ENV), 웹검색 경로
|
||||
- `rb8001/app/router/message_router.py` — 대명사 해소/엔티티 스코어링
|
||||
- `rb8001/app/services/workflows/web_search_workflow.py` — LangGraph 검색 워크플로
|
||||
**기대**:
|
||||
- Unknown↓
|
||||
- 잘못된 실행 <1%
|
||||
- LLM 호출 ≤30%
|
||||
- 지연 중앙값 <800ms
|
||||
|
||||
---
|
||||
|
||||
## 12) 3줄 요약
|
||||
- 하이브리드 의도 파이프라인: FastPath → 임베딩 Top‑K → LLM JSON 재분석(+clarify) + 신뢰도 캘리브레이션.
|
||||
- 동적 학습/최적화: 로그 기반 프로토타입·동의어 갱신, Beta(α,β)+Thompson Sampling·A/B/밴딧으로 임계치·경로 자동 튜닝.
|
||||
- rb8001 IntentGraph 스캐폴드 위 단계적 적용 가능, Unknown↓·오실행<1%·LLM 호출≤30% 목표.
|
||||
## 아키텍처 (Phase 1)
|
||||
|
||||
### 1. FastPath
|
||||
- 정규식 + Naive Bayes
|
||||
- conf ≥ 0.9 즉시 결정
|
||||
|
||||
### 2. 임베딩 후보 축소
|
||||
- intent 설명/예시 벡터와 코사인 유사도
|
||||
- Top-K + 마진 기반 신뢰도
|
||||
|
||||
### 3. LLM 재분석
|
||||
- Top-K만 JSON 스키마로 결정
|
||||
- conf < τ는 clarify
|
||||
|
||||
### 4. 캘리브레이션
|
||||
- 유사도·마진 기반 conf → 온도/Isotonic 보정
|
||||
|
||||
---
|
||||
|
||||
## 구현 파일 (스캐폴드)
|
||||
|
||||
- `rb8001/app/brain/intent_graph.py`: FastPath→Semantic→LLM 파이프
|
||||
- `rb8001/app/brain/semantic_classifier.py`: 제로샷 후보 축소
|
||||
- `rb8001/app/llm/intent_parser.py`: LLM JSON 파서
|
||||
- `rb8001/app/brain/intent_registry.yaml`: intent 설명/슬롯
|
||||
|
||||
---
|
||||
|
||||
## 베이지안 동적 학습
|
||||
|
||||
### Beta(α,β) 추적
|
||||
- 의도/경로별 성공률 추적
|
||||
- 성공 α+=1, 실패 β+=1
|
||||
- Thompson Sampling으로 임계치 τ 동적 최적화
|
||||
|
||||
### 로그 스키마
|
||||
```sql
|
||||
CREATE TABLE intent_decision_log (
|
||||
user_id UUID,
|
||||
message TEXT,
|
||||
candidates JSONB,
|
||||
chosen TEXT,
|
||||
path TEXT, -- fastpath/semantic/llm
|
||||
success BOOLEAN,
|
||||
latency_ms INT,
|
||||
timestamp TIMESTAMPTZ
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Chain-of-Thought (CoT) 적용
|
||||
|
||||
### 목적
|
||||
- 복잡한 질문 정확도 향상
|
||||
- 확신도 낮은 경우 단계별 추론
|
||||
|
||||
### 조건부 활성화
|
||||
- conf < 0.7: CoT 사용
|
||||
- conf ≥ 0.9: CoT 생략 (비용 절감)
|
||||
- 컨텍스트 의존 질문: CoT 우선
|
||||
|
||||
---
|
||||
|
||||
## 배포 전략
|
||||
|
||||
- A/B → 밴딧: 10%→30%→50% 점진 롤아웃
|
||||
- 지표: Unknown/Clarify/오실행/지연/비용 모니터링
|
||||
|
||||
---
|
||||
|
||||
## 참고
|
||||
|
||||
- `troubleshooting/251126_intent_3step_db_bayesian_integration.md`
|
||||
- `plans/251017_intent_analysis_improvement_plan.md`
|
||||
|
||||
@ -1,158 +1,91 @@
|
||||
# 로빙 일기(성장 일지) 시스템 계획서
|
||||
# 로빙 일기(성장 일지) 시스템 계획
|
||||
|
||||
**작성일**: 2025-11-17
|
||||
**작성자**: claude
|
||||
**날짜**: 2025-11-17
|
||||
**목표**: 로빙의 하루 활동/감정 자동 정리 시스템
|
||||
|
||||
## 1. 목적
|
||||
---
|
||||
|
||||
- 로빙이 하루 활동과 감정 상태를 스스로 정리하는 **“일기/성장 일지” 시스템**을 설계한다.
|
||||
- 운영자/연구자가 로빙의 **행동 변화·감정 흐름·반복 이슈**를 한눈에 파악할 수 있는 기반을 만든다.
|
||||
- 추후 책 본문(400_growth)과 관리자 대시보드에서 재사용 가능한 **표준 포맷**을 정의한다.
|
||||
## 목적
|
||||
|
||||
## 2. 현재 상태 정리
|
||||
- 로빙이 하루 활동과 감정 상태를 스스로 정리
|
||||
- 운영자가 행동 변화·감정 흐름·반복 이슈 파악
|
||||
- 책 본문(400_growth)과 관리자 대시보드 재사용 가능한 표준 포맷
|
||||
|
||||
- 대화/피드백/의도 리뷰 큐:
|
||||
- `rb8001`에 대화 로그, intent 리뷰 큐, 감정 모델 등이 이미 구현되어 있음.
|
||||
- HITL 의도 학습 흐름이 `DOCS/research/intent_classification/README.md`, `rb8001/experiment_results/e2e_final_experiment_report.md`에 문서화됨.
|
||||
- 문서 관점:
|
||||
- `600_appendix/610_로빙_성장_일지_예시.md`에 “성장 일지” 컨셉 예시가 있으나, 실제 서비스와 연결된 자동화 시스템은 아직 없음.
|
||||
---
|
||||
|
||||
## 3. 요구사항 (초안)
|
||||
## 현재 상태
|
||||
|
||||
1. **자동 생성**
|
||||
- 하루 단위(또는 세션 단위)로 일기를 자동 생성할 수 있어야 한다.
|
||||
- 입력: 대화 로그, 감정 스코어, 리뷰 큐/오류 로그 요약.
|
||||
2. **감정 상태 반영**
|
||||
- “오늘의 주요 감정”, “감정 변화 요약”이 포함되어야 한다.
|
||||
3. **문제·개선점 정리**
|
||||
- 장애/실패/리뷰 큐 쌓인 부분을 기반으로 “오늘의 문제/배운 점/개선 방향”을 자동 서술한다.
|
||||
4. **저장 포맷**
|
||||
- 사람 읽기용: 마크다운(md) 일기 파일.
|
||||
- 분석용: DB에 동일 내용을 요약(텍스트 + 메타데이터) 형태로 저장.
|
||||
5. **조회/활용**
|
||||
- 최소한 운영자는 서버/에디터로 md 파일을 쉽게 조회할 수 있어야 한다.
|
||||
- 추후 관리자 대시보드에서 일자별 목록 + 상세 보기로 확장 가능해야 한다.
|
||||
**구현됨**:
|
||||
- 대화 로그, intent 리뷰 큐, 감정 모델 (rb8001)
|
||||
- HITL 의도 학습 흐름
|
||||
|
||||
## 4. 아키텍처 방향 (초안)
|
||||
**미구현**:
|
||||
- 자동 일기 생성 시스템
|
||||
- 일기 저장/조회 인터페이스
|
||||
|
||||
1. **데이터 수집 계층**
|
||||
- `rb8001`의 대화 로그/감정 분석/리뷰 큐/에러 로그에서 하루치 데이터를 집계하는 “Diary Aggregator” 함수 설계.
|
||||
2. **요약·서술 계층**
|
||||
- Aggregator가 만든 구조화 데이터(예: JSON)를 바탕으로 “일기 텍스트”를 생성하는 템플릿/LLM 조합 설계.
|
||||
3. **저장 계층**
|
||||
- DB: `robeing_diary` 테이블(예: `date`, `robeing_id`, `summary`, `dominant_emotion`, `stats(jsonb)` 등).
|
||||
- 파일: `/code/logs/diary/YYYY/MM/robeing_diary_YYYY-MM-DD.md` 형식의 md 파일 (Docker 볼륨 마운트 고려).
|
||||
4. **조회 계층**
|
||||
- 1단계: 서버에서 md 파일 직접 열어보는 운영자용 뷰.
|
||||
- 2단계(향후): frontend-base 관리자 대시보드에서 일기 목록/상세 보기 제공.
|
||||
---
|
||||
|
||||
## 5. 일기 포맷 초안
|
||||
## 요구사항
|
||||
|
||||
1. **자동 생성**: 하루/세션 단위 자동 일기 생성
|
||||
2. **감정 반영**: 주요 감정, 감정 변화 요약
|
||||
3. **문제 정리**: 장애/실패/리뷰 큐 기반 "배운 점" 서술
|
||||
4. **저장**: 마크다운 파일 + DB (robeing_diary 테이블)
|
||||
5. **조회**: 운영자 md 파일 조회, 향후 대시보드 확장
|
||||
|
||||
---
|
||||
|
||||
## 아키텍처
|
||||
|
||||
### 1. 데이터 수집
|
||||
- rb8001의 대화/감정/리뷰 큐/에러 로그 집계
|
||||
- Diary Aggregator 함수
|
||||
|
||||
### 2. 요약·서술
|
||||
- 구조화 데이터(JSON) → 일기 텍스트
|
||||
- 템플릿 + LLM 조합
|
||||
|
||||
### 3. 저장
|
||||
- **DB**: `robeing_diary(date, robeing_id, summary, dominant_emotion, stats JSONB)`
|
||||
- **파일**: `/logs/diary/YYYY/MM/robeing_diary_YYYY-MM-DD.md`
|
||||
|
||||
### 4. 조회
|
||||
- 1단계: 서버에서 md 파일 직접 조회
|
||||
- 2단계: 관리자 대시보드 일기 목록/상세 보기
|
||||
|
||||
---
|
||||
|
||||
## 일기 포맷
|
||||
|
||||
```markdown
|
||||
# 로빙 일기 – 2025-11-17
|
||||
|
||||
## 1. 오늘 한 일
|
||||
- 주요 대화 주제 요약 (intent 기준)
|
||||
- 호출된 스킬/액션 요약
|
||||
## 오늘 한 일
|
||||
- 주요 대화 주제/스킬 요약
|
||||
|
||||
## 2. 감정 상태
|
||||
- 지배적인 감정: XXX
|
||||
- 감정 변화 요약: 오전/오후/야간
|
||||
## 감정 상태
|
||||
- 지배적 감정, 변화 요약
|
||||
|
||||
## 3. 문제와 배운 점
|
||||
- 오늘 발생한 주요 오류/리뷰 큐 이슈 요약
|
||||
- 교훈/개선 방향
|
||||
## 문제와 배운 점
|
||||
- 오류/리뷰 큐 이슈, 교훈
|
||||
|
||||
## 4. 내일을 위한 계획
|
||||
- 내일 개선하고 싶은 점
|
||||
- 실험/테스트 아이디어
|
||||
## 내일 계획
|
||||
- 개선 방향, 실험 아이디어
|
||||
```
|
||||
|
||||
## 6. 단계별 실행 계획
|
||||
---
|
||||
|
||||
1. **설계 정리**
|
||||
- Diary Aggregator의 입력/출력 스키마 정의.
|
||||
- `robeing_diary` 테이블 스키마 초안 작성.
|
||||
2. **TDD 테스트 설계**
|
||||
- `rb8001/tests/`에 “일기 생성” 단위 테스트 초안 작성 (RED).
|
||||
3. **Aggregator/포맷 구현**
|
||||
- 집계 로직 + md 템플릿 생성 함수 구현 (DB/파일 저장은 나중 단계로 분리).
|
||||
4. **DB/파일 저장 연결**
|
||||
- 일기 생성 결과를 DB + md 파일로 저장하는 배치/엔드포인트 설계.
|
||||
5. **관리자 대시보드 연동(선택)**
|
||||
- frontend-base에서 일기 리스트/상세 보기 추가 (23번 서버 계획 문서와 연계).
|
||||
## 구현 단계
|
||||
|
||||
## 7. 열려 있는 질문
|
||||
|
||||
- 일기 생성 주기: “하루 1회” vs “세션/이벤트 기반” 중 무엇이 기본이 될 것인가?
|
||||
- 감정 상태: 단일 지배 감정만 쓸지, 감정 분포 그래프/지수까지 포함할지?
|
||||
- 사용자 프라이버시: 어떤 수준까지 실제 대화 내용을 일기에 포함할지, 익명화/요약 기준은 무엇으로 할지?
|
||||
1. Diary Aggregator 스키마 정의
|
||||
2. TDD 테스트 작성
|
||||
3. 집계 로직 + md 템플릿 구현
|
||||
4. DB/파일 저장 연결
|
||||
5. 스케줄러 등록 (매일 자정)
|
||||
|
||||
---
|
||||
|
||||
## 8. 로빙의 ‘반성/성찰’ 관점에서의 요구사항
|
||||
## 참고
|
||||
|
||||
### 8.1 어떤 신호를 반성 대상으로 삼을 것인가
|
||||
- **저신뢰/불확실 응답**
|
||||
- intent confidence가 일정 이하(예: 0.5 미만)이거나, UNKNOWN/clarify 흐름이 반복된 케이스.
|
||||
- LLM 응답에 “잘 모르겠습니다/확실하지 않습니다” 패턴이 포함된 케이스.
|
||||
- **사용자 피드백/재질문**
|
||||
- 같은 질문이 짧은 시간 안에 반복되는 경우(“다시 설명해줘”, “이 말이 무슨 뜻이야?” 등).
|
||||
- Slack/프론트에서 직접적인 불만/부정 감정이 나타난 대화(감정 모델 + 텍스트 패턴 조합).
|
||||
- **시스템 오류·윤리 필터**
|
||||
- 예외/500, ethics 필터 차단, 권한/인증 오류가 발생한 요청.
|
||||
- intent_review_queue에 쌓인 케이스 중 “사람이 보기에도 잘못된 의도/응답”으로 라벨링된 항목.
|
||||
|
||||
### 8.2 일기 안에서의 구조 (반성/성찰 전용 섹션)
|
||||
```markdown
|
||||
## 3. 오늘의 반성 노트
|
||||
- 내가 잘 이해하지 못한 요청: (요약 1~3개)
|
||||
- 사용자가 헷갈려 했던 설명: (요약 1~3개)
|
||||
- 시스템/윤리 필터에 막힌 지점: (요약)
|
||||
|
||||
## 4. 배운 점과 내일의 실험
|
||||
- 오늘 배운 것: (패턴/원인 수준으로 서술)
|
||||
- 내일은 이렇게 대응해 보고 싶다: (구체 행동 2~3개)
|
||||
```
|
||||
- **중요**: 여기에 들어가는 내용은 “자기 비난”이 아니라 **행동/패턴 중심의 학습 포인트**여야 함 (예: “사용자가 화를 냈다”가 아니라 “나는 이메일 요약을 너무 길게 답했다 → 다음에는 먼저 요약 길이를 물어보자”).
|
||||
|
||||
### 8.3 어떤 데이터로 채울 것인가 (데이터 소스 매핑)
|
||||
- `conversation_log`:
|
||||
- 하루치 로그에서 intent, confidence, channel, timestamp 기준으로 “문제 가능성이 높은 대화”를 샘플링.
|
||||
- `intent_review_queue`:
|
||||
- 오늘 생성된 리뷰 항목 중 레이블이 확정된 것(사람이 ‘틀림/개선 필요’로 표시한 것)을 “배운 점” 후보로 사용.
|
||||
- 감정/윤리 시스템:
|
||||
- 감정 모델이 “강한 부정 감정 + 낮은 이해도”로 태깅한 순간, 윤리 필터에 의해 수정·차단된 응답을 별도 리스트업.
|
||||
|
||||
---
|
||||
|
||||
## 9. 프라이버시·비유출 원칙 (일기 활용 시 가드레일)
|
||||
|
||||
1. **저장 계층 분리**
|
||||
- `robeing_diary`(가칭) 테이블/스토리지에만 일기 원문을 저장하고,
|
||||
- RAG 검색 인덱스(ChromaDB 등)에는 포함하지 않는다.
|
||||
- 일반 대화 컨텍스트(최근 대화 불러오기)에도 직접 합치지 않는다.
|
||||
2. **LLM 컨텍스트 제공 방식**
|
||||
- LLM 호출 시, 일기 원문 전체가 아니라 **요약된 메타정보만** 전달:
|
||||
- 예: “최근 7일 동안 사용자가 피곤함을 자주 호소함”, “최근 이메일 요약을 길게 답해 불만이 있었음”.
|
||||
- 시스템 프롬프트에 다음 규칙을 명시:
|
||||
- “일기 내용(구체 사건/이름/회사)을 직접 인용하거나 언급하지 말 것.”
|
||||
- “일기에서 배운 태도·주의점만 반영해 현재 대화 톤/전략을 조정할 것.”
|
||||
3. **외부 노출 경계**
|
||||
- 관리자 페이지에서는 **일기 전체를 볼 수 있지만**,
|
||||
- API 단에서는 관리자용 인증 경로를 제외하고 일기 데이터를 제공하지 않는다.
|
||||
- 사용자에게는 “일기”라는 개념을 설명하되, **원문을 그대로 보여주지 않고** 요약된 인사이트(“요즘 피곤해 보여서 답변을 조금 더 짧게 할게요” 정도)만 드러내도록 한다.
|
||||
|
||||
---
|
||||
|
||||
## 10. 단계별 구현 계획 (반성/성찰 기능 중심)
|
||||
|
||||
1. **Phase 1 – 데이터 수집·집계**
|
||||
- conversation_log, intent_review_queue, 감정/윤리 로그에서 “문제 가능성이 높은 케이스”를 하루 단위로 집계하는 Aggregator를 설계·구현.
|
||||
- 하루치 집계 결과를 JSON 형태로 파일/DB에 저장하고, 아직 일기 텍스트 생성은 하지 않음.
|
||||
2. **Phase 2 – 일기 텍스트 생성 (내부 전용)**
|
||||
- Aggregator 출력 + 템플릿/LLM을 조합해, 위 5장·8장 포맷(오늘 한 일 + 감정 + 반성 노트 + 내일 계획)에 맞는 일기 텍스트를 생성.
|
||||
- `robeing_diary` 저장소 설계: `date`, `robeing_id`, `summary_text`, `reflection_text`, `emotion_summary(jsonb)`, `meta(jsonb)` 등.
|
||||
3. **Phase 3 – Admin UI 및 안전한 활용**
|
||||
- 관리자 대시보드에서 로빙/날짜별 일기 목록·상세 보기 추가 (검색/필터 포함).
|
||||
- 일부 LLM 호출에서 “일기 메타정보”를 system context로 주입해, 로빙이 반성/성찰 내용을 행동에 반영하되, 일기 원문·비밀은 절대 외부 응답에 재인용하지 않도록 가드레일을 구현.
|
||||
- `book/600_appendix/610_로빙_성장_일지_예시.md`
|
||||
- `research/intent_classification/README.md`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user