docs: 콜드메일 IR 분석 오류 문서 및 문서 작성 원칙 추가
- troubleshooting/251013_coldmail_ir_analyzer_fix.md: 3가지 에러 분석 및 해결 방안 - 300_architecture/312_문서_작성_원칙.md: 트러블슈팅/아키텍처 문서 작성 규칙 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
05f2d5ce5f
commit
61082a7027
205
300_architecture/312_문서_작성_원칙.md
Normal file
205
300_architecture/312_문서_작성_원칙.md
Normal file
@ -0,0 +1,205 @@
|
||||
# 문서 작성 원칙
|
||||
|
||||
**작성일**: 2025-10-13
|
||||
**참고**: CLAUDE.md, 311_FastAPI_구조_원칙.md
|
||||
|
||||
---
|
||||
|
||||
## 1. 문서 종류별 규칙
|
||||
|
||||
### 트러블슈팅 문서
|
||||
|
||||
**경로**: `DOCS/troubleshooting/`
|
||||
**파일명**: `yymmdd_주제.md` (예: 251013_coldmail_ir_analyzer_fix.md)
|
||||
**규칙**:
|
||||
- 주제별 파일 분리 (날짜 중복 허용)
|
||||
- 시간순 작성
|
||||
- 교훈 섹션 필수
|
||||
- 100줄 이하 유지
|
||||
|
||||
**필수 헤더**:
|
||||
```markdown
|
||||
# 제목
|
||||
|
||||
**날짜**: 2025-10-13
|
||||
**작성자**: happybell80
|
||||
**관련 파일**: `경로/파일명.py`
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
### 아키텍처 문서
|
||||
|
||||
**경로**: `DOCS/300_architecture/`
|
||||
**파일명**: `3NN_주제.md` (예: 311_FastAPI_구조_원칙.md)
|
||||
**규칙**:
|
||||
- 작성일/수정일 명시
|
||||
- 섹션 번호 사용
|
||||
- 표, 다이어그램 권장
|
||||
- 코드 예시 (올바름/금지) 포함
|
||||
|
||||
### 계획 문서
|
||||
|
||||
**경로**: `DOCS/plans/`
|
||||
**규칙**:
|
||||
- 미래 계획, 아이디어
|
||||
- 구현 완료 시 troubleshooting으로 이동
|
||||
|
||||
---
|
||||
|
||||
## 2. 작성 규칙
|
||||
|
||||
### 절대 금지 사항
|
||||
|
||||
| 금지 | 이유 |
|
||||
|------|------|
|
||||
| 의사코드, 추측, 예측 | 실제 동작하는 코드만 작성 |
|
||||
| "아마", "것 같다", "추정" | 확인된 사실만 기록 |
|
||||
| 불필요한 코드 블록 | 파일명:줄번호만 명시 |
|
||||
| 이모지 사용 | 명시적 요청 시만 허용 |
|
||||
|
||||
### 파일 참조 형식
|
||||
|
||||
**올바름**:
|
||||
```markdown
|
||||
- naverworks_briefing.py:58-74: 폴백 제거
|
||||
- ir_analyzer.py:28: /api/query → /api/search
|
||||
```
|
||||
|
||||
**금지**:
|
||||
```markdown
|
||||
- naverworks_briefing.py에서 폴백 제거
|
||||
- ir_analyzer.py 파일 수정
|
||||
```
|
||||
|
||||
### 코드 블록 최소화
|
||||
|
||||
**올바름** (파일명:줄번호 + 간단 설명):
|
||||
```markdown
|
||||
**수정 필요:**
|
||||
- ir_analyzer.py:28: url = f"{SKILL_RAG_FILE_URL}/api/search"
|
||||
- ir_analyzer.py:29-32: payload에 team_id 추가
|
||||
```
|
||||
|
||||
**금지** (전체 코드 복사):
|
||||
```markdown
|
||||
**수정 필요:**
|
||||
```python
|
||||
# ir_analyzer.py 전체 함수 코드 50줄 복사...
|
||||
```
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 문서 구조
|
||||
|
||||
### 트러블슈팅 문서 구조
|
||||
|
||||
```markdown
|
||||
# 제목
|
||||
|
||||
**날짜**, **작성자**, **관련 파일**
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- 현상, 에러 메시지
|
||||
|
||||
## 해결 방안
|
||||
- 파일명:줄번호 명시
|
||||
- 수정 내용 간결히
|
||||
|
||||
## 구현 완료 (선택)
|
||||
- 커밋 해시, 날짜
|
||||
|
||||
## 교훈 (필수)
|
||||
- 왜 발생했는가
|
||||
- 다음에 어떻게 방지할 것인가
|
||||
```
|
||||
|
||||
### 아키텍처 문서 구조
|
||||
|
||||
```markdown
|
||||
# 제목
|
||||
|
||||
**작성일**: 2025-10-13
|
||||
**수정일**: 2025-10-13 (수정 이유)
|
||||
|
||||
## 1. 원칙
|
||||
## 2. 규칙
|
||||
## 3. 예시
|
||||
## 4. 체크리스트
|
||||
## 5. 참고
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 파일 크기 제한
|
||||
|
||||
### 규칙
|
||||
- 모든 문서: 100줄 이하
|
||||
- 초과 시: 주제별 분리 또는 참고/실행용 분리
|
||||
|
||||
### 예외
|
||||
- 아키텍처 문서: 200줄까지 허용 (섹션 많은 경우)
|
||||
- 단, 분리 가능하면 분리 우선
|
||||
|
||||
---
|
||||
|
||||
## 5. 교훈 작성 규칙
|
||||
|
||||
### 필수 항목
|
||||
1. **원인**: 왜 문제가 발생했는가
|
||||
2. **교훈**: 다음에 어떻게 방지할 것인가
|
||||
3. **원칙**: 위반한 원칙이 있는가
|
||||
|
||||
### 올바른 예시
|
||||
```markdown
|
||||
## 교훈
|
||||
|
||||
### API 엔드포인트 검증 부족
|
||||
- 구현 시 skill-rag-file API 스펙 미확인
|
||||
- 추측으로 /api/query 사용, 실제는 /api/search
|
||||
- 교훈: 스킬 통합 전 API 문서 또는 코드 직접 확인 필수
|
||||
```
|
||||
|
||||
### 금지 예시
|
||||
```markdown
|
||||
## 교훈
|
||||
|
||||
에러가 발생했습니다. 다음에 조심하겠습니다.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 비난조 문장 금지
|
||||
|
||||
### 금지 표현
|
||||
- "잘못 작성됨"
|
||||
- "버그가 많음"
|
||||
- "엉망진창"
|
||||
|
||||
### 권장 표현
|
||||
- "수정 필요"
|
||||
- "개선 가능"
|
||||
- "리팩토링 대상"
|
||||
|
||||
---
|
||||
|
||||
## 7. 체크리스트
|
||||
|
||||
문서 작성 전:
|
||||
- [ ] 파일명 형식 준수 (yymmdd_주제.md)
|
||||
- [ ] 파일명:줄번호로 위치 명시
|
||||
- [ ] 의사코드/추측 제거
|
||||
- [ ] 100줄 이하 확인
|
||||
- [ ] 교훈 섹션 작성 (트러블슈팅)
|
||||
- [ ] 이모지 제거 (명시 요청 없으면)
|
||||
|
||||
---
|
||||
|
||||
## 8. 참고 문서
|
||||
|
||||
- CLAUDE.md: 전체 개발 가이드
|
||||
- 311_FastAPI_구조_원칙.md: 코드 구조 원칙
|
||||
- troubleshooting/ 폴더: 트러블슈팅 예시
|
||||
116
troubleshooting/251013_coldmail_ir_analyzer_fix.md
Normal file
116
troubleshooting/251013_coldmail_ir_analyzer_fix.md
Normal file
@ -0,0 +1,116 @@
|
||||
# 콜드메일 IR 분석 시스템 오류 수정
|
||||
|
||||
**날짜**: 2025-10-13
|
||||
**작성자**: happybell80
|
||||
**관련 파일**: `rb8001/app/services/ir_analyzer.py`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
|
||||
### 테스트 실행
|
||||
- 경로: rb8001/tests/test_coldmail_briefing.py --test scheduler
|
||||
- 결과: 3가지 에러 발생, Slack 전송 도달 실패
|
||||
|
||||
### 성공한 부분
|
||||
1. 콜드메일 필터링: 30개 중 1건 탐지 (굿베이션 투자제안서, 확률 0.7755)
|
||||
2. 첨부파일 다운로드: skill-email에서 PDF 다운로드 성공
|
||||
3. skill-rag-file 업로드: document_id c9c9a7a8-18d3-475a-b14e-746e14c9e55c, 14 chunks 생성
|
||||
|
||||
---
|
||||
|
||||
## 에러 분석
|
||||
|
||||
### 에러 1: RAG 쿼리 404 (6회 발생)
|
||||
|
||||
**에러 메시지:**
|
||||
```
|
||||
ERROR:app.services.ir_analyzer:RAG query failed: 404
|
||||
```
|
||||
|
||||
**원인:**
|
||||
- ir_analyzer.py:28 - `/api/query` 엔드포인트 호출
|
||||
- skill-rag-file은 POST `/api/search` 제공 (search.py:19)
|
||||
- 엔드포인트 불일치
|
||||
|
||||
**수정 필요:**
|
||||
- ir_analyzer.py:28: `/api/query` → `/api/search`
|
||||
- ir_analyzer.py:29-32: payload 구조 변경 (document_id 제거, team_id 추가)
|
||||
|
||||
### 에러 2: LLM 연결 실패
|
||||
|
||||
**에러 메시지:**
|
||||
```
|
||||
ERROR:app.services.ir_analyzer:Error calling LLM: Cannot connect to host localhost:8080
|
||||
```
|
||||
|
||||
**원인:**
|
||||
- ir_analyzer.py:15: LLM_API_URL = http://localhost:8080/api/llm
|
||||
- rb8001 컨테이너 내부에 localhost:8080 LLM 서비스 없음
|
||||
- rb8001은 자체 LLM 서비스 사용 (app/llm/llm_service.py)
|
||||
|
||||
**수정 필요:**
|
||||
- ir_analyzer.py:48-74: call_llm() 함수를 rb8001 LLM 서비스 사용으로 변경
|
||||
- app/llm/llm_service.py의 LLMService, LLMRequest 사용
|
||||
|
||||
### 에러 3: DB 제약조건 없음
|
||||
|
||||
**에러 메시지:**
|
||||
```
|
||||
asyncpg.exceptions.InvalidColumnReferenceError: there is no unique or exclusion constraint
|
||||
```
|
||||
|
||||
**원인:**
|
||||
- startup_valuation.py:249: ON CONFLICT 절 사용
|
||||
- startup_valuation 테이블에 UNIQUE 제약조건 미설정
|
||||
|
||||
**수정 필요:**
|
||||
- 51123 서버 DB: startup_valuation 테이블에 UNIQUE 제약조건 추가
|
||||
|
||||
---
|
||||
|
||||
## 해결 방안
|
||||
|
||||
### 우선순위 1: ir_analyzer.py 수정
|
||||
|
||||
**query_rag() 함수 (18-45줄):**
|
||||
- 28줄: url = f"{SKILL_RAG_FILE_URL}/api/search"
|
||||
- 29-35줄: payload 변경
|
||||
```
|
||||
기존: {"document_id": document_id, "query": query}
|
||||
변경: {"query": query, "team_id": team_id, "limit": 10, "threshold": 0.5}
|
||||
```
|
||||
- team_id 파라미터 추가 필요
|
||||
|
||||
**call_llm() 함수 (48-74줄):**
|
||||
- rb8001 LLM 서비스 사용으로 전체 변경
|
||||
- from app.llm.llm_service import LLMService, LLMRequest
|
||||
- LLMRequest(message=prompt, user_id="system", robeing_id="rb8001", model="gemini-2.5-flash-lite")
|
||||
|
||||
### 우선순위 2: DB 제약조건 추가
|
||||
|
||||
**51123 서버 DB 작업:**
|
||||
- startup_valuation 테이블에 UNIQUE 제약조건 추가
|
||||
- 중복 방지 컬럼 조합 확인 필요
|
||||
|
||||
### 우선순위 3: 테스트 재실행
|
||||
|
||||
**배포 프로세스:**
|
||||
1. 로컬 수정 완료
|
||||
2. git push
|
||||
3. Gitea Actions 배포 대기
|
||||
4. docker exec -it rb8001 python tests/test_coldmail_briefing.py --test scheduler
|
||||
|
||||
---
|
||||
|
||||
## 교훈
|
||||
|
||||
### API 엔드포인트 검증 부족
|
||||
- 구현 시 skill-rag-file API 스펙 미확인
|
||||
- 추측으로 /api/query 사용, 실제는 /api/search
|
||||
- 교훈: 스킬 통합 전 API 문서 또는 코드 직접 확인 필수
|
||||
|
||||
### LLM 서비스 중복 구현
|
||||
- ir_analyzer가 독립 LLM 서비스 가정
|
||||
- rb8001은 이미 LLM 서비스 내장
|
||||
- 교훈: 기존 서비스 재사용 우선, 새 의존성 추가 지양
|
||||
Loading…
x
Reference in New Issue
Block a user