트러블슈팅
This commit is contained in:
parent
30908c2cab
commit
41d79a9e16
31
troubleshooting/250803_ChromaDB_UUID_충돌_해결.md
Normal file
31
troubleshooting/250803_ChromaDB_UUID_충돌_해결.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# ChromaDB UUID 충돌 문제 해결
|
||||||
|
|
||||||
|
## 문제 상황
|
||||||
|
사용자가 ChromaDB에서 UUID 충돌이 발생할 수 있다는 우려를 제기했습니다.
|
||||||
|
|
||||||
|
## 원인 분석
|
||||||
|
ChromaDB에서 각 로빙의 메모리를 저장할 때, 컬렉션 이름 생성 방식을 확인한 결과:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# /home/heejae/rb10408_test/app/state/memory_manager.py
|
||||||
|
self.collection_name = f"robing_{robing_id}_memories"
|
||||||
|
```
|
||||||
|
|
||||||
|
각 로빙은 고유한 ID를 가지고 있어 (`rb10408_test`, `rb10508_test` 등), 컬렉션 이름이 중복될 가능성이 없었습니다.
|
||||||
|
|
||||||
|
## 추가 확인 사항
|
||||||
|
메모리 ID 생성 로직:
|
||||||
|
```python
|
||||||
|
def generate_id(self, content: str, timestamp: str) -> str:
|
||||||
|
"""고유 ID 생성"""
|
||||||
|
unique_string = f"{self.robing_id}_{content}_{timestamp}"
|
||||||
|
return hashlib.md5(unique_string.encode()).hexdigest()
|
||||||
|
```
|
||||||
|
|
||||||
|
로빙 ID, 콘텐츠, 타임스탬프를 조합하여 MD5 해시를 생성하므로 충돌 가능성이 극히 낮습니다.
|
||||||
|
|
||||||
|
## 결론
|
||||||
|
이미 적절한 UUID 충돌 방지 메커니즘이 구현되어 있어 추가 조치가 필요하지 않았습니다.
|
||||||
|
|
||||||
|
## 관련 파일
|
||||||
|
- `/home/heejae/rb10408_test/app/state/memory_manager.py`
|
||||||
58
troubleshooting/250803_LLM_서비스_연결_문제_해결.md
Normal file
58
troubleshooting/250803_LLM_서비스_연결_문제_해결.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# LLM 서비스 연결 문제 해결
|
||||||
|
|
||||||
|
## 문제 상황들
|
||||||
|
|
||||||
|
### 1. LLM 서비스 응답 속도 문제
|
||||||
|
- **증상**: "넌 누구니" 같은 간단한 질문에도 타임아웃 발생
|
||||||
|
- **원인**: Gemini CLI 모드 사용으로 인한 subprocess 오버헤드
|
||||||
|
|
||||||
|
### 2. 422 Unprocessable Entity 에러
|
||||||
|
- **증상 1**: 멘션이 포함된 메시지에서 에러 발생
|
||||||
|
- **증상 2**: execution_plan 필드가 포함되어 에러 발생
|
||||||
|
- **원인**: LLM 서비스가 예상하지 않은 필드 전달
|
||||||
|
|
||||||
|
### 3. 일반 대화 실패
|
||||||
|
- **증상**: "죄송합니다. 현재 해당 기능을 사용할 수 없습니다." 메시지 반환
|
||||||
|
- **원인**: LLM 서비스 호출 실패 시 폴백 메시지
|
||||||
|
|
||||||
|
## 해결 방법
|
||||||
|
|
||||||
|
### 1. Gemini API 모드로 전환 (권장)
|
||||||
|
```python
|
||||||
|
# /home/heejae/robing-llm-service/.env
|
||||||
|
GEMINI_USE_CLI=false # true -> false 변경
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. LLM 서비스 payload 최적화
|
||||||
|
```python
|
||||||
|
# /home/heejae/rb10408_test/app/router/router.py
|
||||||
|
if skill_type_enum != SkillType.LLM:
|
||||||
|
payload["action"] = skill.get("action")
|
||||||
|
payload["execution_plan"] = execution_plan
|
||||||
|
```
|
||||||
|
|
||||||
|
LLM 서비스에는 필수 필드만 전송:
|
||||||
|
- `message`
|
||||||
|
- `user_id`
|
||||||
|
- `channel`
|
||||||
|
- `robing_id`
|
||||||
|
|
||||||
|
### 3. 서비스 상태 확인
|
||||||
|
```bash
|
||||||
|
# LLM 서비스 실행 확인
|
||||||
|
ps aux | grep -E "(llm|8003)"
|
||||||
|
|
||||||
|
# 헬스체크
|
||||||
|
curl http://localhost:8003/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 기술적 세부사항
|
||||||
|
- LLM 서비스 위치: `/home/heejae/robing-llm-service/`
|
||||||
|
- 포트: 8003
|
||||||
|
- 기본 모델: gemini-flash
|
||||||
|
- CLI 타임아웃: 15초 (느린 원인)
|
||||||
|
|
||||||
|
## 관련 파일
|
||||||
|
- `/home/heejae/robing-llm-service/app/llm/gemini_handler.py`
|
||||||
|
- `/home/heejae/robing-llm-service/app/core/config.py`
|
||||||
|
- `/home/heejae/rb10408_test/app/router/router.py`
|
||||||
48
troubleshooting/250803_PostgreSQL_SSH_터널_연결.md
Normal file
48
troubleshooting/250803_PostgreSQL_SSH_터널_연결.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# PostgreSQL SSH 터널 연결 설정
|
||||||
|
|
||||||
|
## 문제 상황
|
||||||
|
State Service가 원격 서버(124.55.18.179)의 PostgreSQL에 연결해야 하는데, 직접 연결이 실패했습니다.
|
||||||
|
|
||||||
|
## 해결 방법
|
||||||
|
|
||||||
|
### 1. SSH 터널 생성
|
||||||
|
```bash
|
||||||
|
# SSH 터널 생성 (로컬 5433 포트 → 원격 5432 포트)
|
||||||
|
sshpass -p '19800508' ssh -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51123 &
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. .env 파일 설정
|
||||||
|
```bash
|
||||||
|
# /home/heejae/robing-state-service/.env
|
||||||
|
DATABASE_URL=postgresql://robeings:robeings@localhost:5433/auth_db
|
||||||
|
SERVICE_NAME=state
|
||||||
|
PORT=8002
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 연결 확인
|
||||||
|
```bash
|
||||||
|
# psql로 테스트
|
||||||
|
psql postgresql://robeings:robeings@localhost:5433/auth_db -c "SELECT 1"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 연결 정보
|
||||||
|
- **원격 서버**: 124.55.18.179
|
||||||
|
- **SSH 포트**: 51123
|
||||||
|
- **SSH 사용자**: admin
|
||||||
|
- **SSH 비밀번호**: 19800508
|
||||||
|
- **PostgreSQL 사용자**: robeings
|
||||||
|
- **PostgreSQL 비밀번호**: robeings
|
||||||
|
- **데이터베이스**: auth_db
|
||||||
|
|
||||||
|
## 주의사항
|
||||||
|
1. SSH 터널은 백그라운드에서 실행되므로 시스템 재시작 시 다시 생성 필요
|
||||||
|
2. 보안을 위해 SSH 키 기반 인증 권장
|
||||||
|
3. 방화벽 설정과 무관하게 SSH 터널을 통해 안전하게 연결
|
||||||
|
|
||||||
|
## 영구적인 해결 방안
|
||||||
|
systemd 서비스로 SSH 터널을 관리하거나, autossh 사용을 고려할 수 있습니다.
|
||||||
|
|
||||||
|
## 관련 파일
|
||||||
|
- `/home/heejae/robing-state-service/.env`
|
||||||
|
- `/home/heejae/robing-state-service/app/core/config.py`
|
||||||
57
troubleshooting/250803_Slack_메시지_처리_문제_해결.md
Normal file
57
troubleshooting/250803_Slack_메시지_처리_문제_해결.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Slack 메시지 처리 문제 해결
|
||||||
|
|
||||||
|
## 문제 상황들
|
||||||
|
|
||||||
|
### 1. 일반 채널에서 멘션 없이도 응답하는 문제
|
||||||
|
- **증상**: 채널에서 멘션 없이 "안녕"이라고 해도 로빙이 응답
|
||||||
|
- **원인**: Slack 이벤트 핸들러가 모든 메시지에 반응하도록 설정됨
|
||||||
|
|
||||||
|
### 2. 멘션 포함 메시지 처리 시 422 에러
|
||||||
|
- **증상**: "@로빙 넌 누구니" 같은 메시지에서 LLM 서비스 422 에러 발생
|
||||||
|
- **원인**: 멘션(`<@U096JGL9011>`)이 포함된 채로 LLM 서비스로 전송됨
|
||||||
|
|
||||||
|
### 3. Slack 메시지 전송 실패 (404 Not Found)
|
||||||
|
- **증상**: 응답 생성 후 Slack으로 전송 시 404 에러
|
||||||
|
- **원인**: 잘못된 API 엔드포인트 사용
|
||||||
|
|
||||||
|
## 해결 방법
|
||||||
|
|
||||||
|
### 1. DM 전용 처리로 변경
|
||||||
|
```python
|
||||||
|
# /home/heejae/rb10408_test/app/router/slack_handler.py
|
||||||
|
@slack_app.event("message")
|
||||||
|
async def handle_message_events(event, say, ack):
|
||||||
|
await ack()
|
||||||
|
|
||||||
|
# DM이 아닌 경우 무시
|
||||||
|
if event.get("channel_type") != "im":
|
||||||
|
return
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 멘션 제거 로직 추가
|
||||||
|
```python
|
||||||
|
# /home/heejae/rb10408_test/main.py
|
||||||
|
message = event.get("text", "")
|
||||||
|
# 멘션 제거 (예: <@U123ABC> 형식)
|
||||||
|
import re
|
||||||
|
message = re.sub(r'<@[A-Z0-9]+>', '', message).strip()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Slack API 엔드포인트 수정
|
||||||
|
```python
|
||||||
|
# 변경 전
|
||||||
|
"http://localhost:8502/send"
|
||||||
|
|
||||||
|
# 변경 후
|
||||||
|
"http://localhost:8502/api/v1/send"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 추가 발견 사항
|
||||||
|
- Slack 스킬 서비스는 포트 8502 사용 (8503 아님)
|
||||||
|
- API는 `/api/v1` prefix 필요
|
||||||
|
- 서비스 위치: `/home/heejae/skill-slack/`
|
||||||
|
|
||||||
|
## 관련 파일
|
||||||
|
- `/home/heejae/rb10408_test/app/router/slack_handler.py`
|
||||||
|
- `/home/heejae/rb10408_test/main.py`
|
||||||
|
- `/home/heejae/rb10408_test/app/core/config.py`
|
||||||
93
troubleshooting/250803_로빙_명령어_구현_가이드.md
Normal file
93
troubleshooting/250803_로빙_명령어_구현_가이드.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# 로빙 명령어 구현 가이드
|
||||||
|
|
||||||
|
## 배경
|
||||||
|
- rb10408_test는 경량화 버전으로 명령어 미구현 상태
|
||||||
|
- rb10508_test는 일부 명령어 구현됨
|
||||||
|
- 공통 명령어를 경량화를 유지하면서 구현해야 함
|
||||||
|
|
||||||
|
## 구현된 명령어 (rb10508_test)
|
||||||
|
- `/memory` - 메모리 통계 조회
|
||||||
|
- `/digest` - 요약 생성
|
||||||
|
- `/news` - 뉴스 검색
|
||||||
|
- `/email` - 이메일 관련 기능
|
||||||
|
|
||||||
|
## 하이브리드 명령어 처리 아키텍처
|
||||||
|
|
||||||
|
### 1. 로컬 처리 명령어
|
||||||
|
빠른 응답이 필요하거나 로컬 데이터만 필요한 경우:
|
||||||
|
```python
|
||||||
|
# /memory - ChromaDB 직접 조회
|
||||||
|
async def _handle_memory(self, user_id: str) -> Dict[str, Any]:
|
||||||
|
memory_stats = await self.memory_manager.get_memory_stats()
|
||||||
|
return {"type": "memory_stats", "data": memory_stats}
|
||||||
|
|
||||||
|
# /help - 정적 응답
|
||||||
|
async def _handle_help(self) -> Dict[str, Any]:
|
||||||
|
return {"type": "help", "data": HELP_TEXT}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 외부 서비스 호출 명령어
|
||||||
|
복잡한 처리나 외부 데이터가 필요한 경우:
|
||||||
|
```python
|
||||||
|
# /news - News 스킬 서비스 호출
|
||||||
|
async def _handle_news(self, query: str) -> Dict[str, Any]:
|
||||||
|
return await self._call_external_service(
|
||||||
|
self.skill_endpoints["news"],
|
||||||
|
{"query": query}
|
||||||
|
)
|
||||||
|
|
||||||
|
# /digest - Slack 스킬 서비스 호출
|
||||||
|
async def _handle_digest(self, channel: str) -> Dict[str, Any]:
|
||||||
|
return await self._call_external_service(
|
||||||
|
self.skill_endpoints["slack"] + "/digest",
|
||||||
|
{"channel": channel}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 명령어 라우팅 구조
|
||||||
|
```python
|
||||||
|
class CommandHandler:
|
||||||
|
def __init__(self):
|
||||||
|
self.local_commands = {
|
||||||
|
"/help": self._handle_help,
|
||||||
|
"/stats": self._handle_stats,
|
||||||
|
"/memory": self._handle_memory
|
||||||
|
}
|
||||||
|
|
||||||
|
self.external_commands = {
|
||||||
|
"/news": ("news", self._handle_news),
|
||||||
|
"/digest": ("slack", self._handle_digest),
|
||||||
|
"/email": ("email", self._handle_email)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 구현 시 고려사항
|
||||||
|
|
||||||
|
### 1. 메모리 효율성
|
||||||
|
- 로컬 명령어는 최소한의 메모리 사용
|
||||||
|
- 캐싱은 필요시에만 선택적 적용
|
||||||
|
|
||||||
|
### 2. 응답 속도
|
||||||
|
- 로컬 명령어: < 100ms
|
||||||
|
- 외부 서비스: Slack 3초 룰 준수
|
||||||
|
|
||||||
|
### 3. 에러 처리
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
result = await handler(params)
|
||||||
|
except ServiceUnavailable:
|
||||||
|
return {"error": "서비스를 일시적으로 사용할 수 없습니다."}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Command error: {e}")
|
||||||
|
return {"error": "명령어 처리 중 오류가 발생했습니다."}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 추가 구현 필요 명령어
|
||||||
|
- `/remind` - 리마인더 설정
|
||||||
|
- `/search` - 메모리 검색
|
||||||
|
- `/report` - 일일/주간 리포트
|
||||||
|
|
||||||
|
## 관련 파일
|
||||||
|
- `/home/heejae/rb10408_test/app/commands/handler.py` (생성 필요)
|
||||||
|
- `/home/heejae/rb10508_test/app/commands/` (참고용)
|
||||||
|
- `/home/heejae/DOCS/skills-and-commands.md`
|
||||||
Loading…
x
Reference in New Issue
Block a user