- CLAUDE.md: Task Runner VM 샌드박스 제약사항 문서화
- docker-compose.yml: NODE_FUNCTION_ALLOW_BUILTIN 환경변수 추가
- main-chat-pipeline.json: require('http/https/url') 방식으로 전환된 워크플로우 반영
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.6 KiB
5.6 KiB
syn-chat-bot
Synology Chat + n8n + Claude API 기반 RAG 챗봇 시스템. 3단계 모델 라우팅(local/api_light/api_heavy) + 멀티-컬렉션 RAG + 선택적 메모리.
아키텍처
Synology Chat (NAS 192.168.1.227)
↕ 웹훅
bot-n8n (맥미니 Docker)
│
├─⓪ 토큰 검증 + Rate Limit (10초/5건)
├─① 규칙 기반 프리필터 (인사/감사 → 하드코딩 local 응답)
│
├─② GPU Qwen 9B (192.168.1.186) — 분류 v2
│ 출력: {intent, response_tier, needs_rag, rag_target, ...}
│ 타임아웃 10초 → fallback: api_light
│
├─③ [needs_rag=true] 멀티-컬렉션 RAG
│ documents + tk_company + chat_memory
│ bge-m3 임베딩 → Qdrant 검색 → reranker → top-3
│
├─④ response_tier 기반 3단계 라우팅
│ ├─ local → Qwen 9B 직접 답변 (무료)
│ ├─ api_light → Claude Haiku (저비용)
│ └─ api_heavy → Claude Opus (예산 초과 시 → Haiku 다운그레이드)
│
├── bot-postgres (설정/로그/라우팅/분류기로그/API사용량)
└── Qdrant (벡터 검색, 3컬렉션)
⑤ 응답 전송 + chat_logs 저장 + API 사용량 UPSERT
⑥ [비동기] 선택적 메모리 (Qwen 판단 → 가치 있으면 벡터화)
인프라
| 구성 요소 | 위치 | 포트 | 비고 |
|---|---|---|---|
| bot-n8n | Docker (맥미니) | 5678 | 워크플로우 엔진 |
| bot-postgres | Docker (맥미니) | 127.0.0.1:15478 | 설정/로그 DB |
| Qdrant | Docker (맥미니, 기존) | 127.0.0.1:6333 | 벡터 DB (3컬렉션) |
| Ollama (맥미니) | 네이티브 (기존) | 11434 | bge-m3, bge-reranker-v2-m3, minicpm-v:8b(Phase 5) |
| Ollama (GPU) | 192.168.1.186 (RTX 4070Ti Super) | 11434 | qwen3.5:9b-q8_0 (분류+local응답) |
| Synology Chat | NAS (192.168.1.227) | — | 사용자 인터페이스 |
3단계 라우팅
| tier | 모델 | 비용 | 대상 |
|---|---|---|---|
| local | Qwen 9B (GPU) | 무료 | 인사, 잡담, 단순 확인 |
| api_light | Claude Haiku | 저비용 | 요약, 번역, RAG 정리 |
| api_heavy | Claude Opus | 고비용 | 법률 해석, 복잡한 추론 |
3-컬렉션 RAG
| 컬렉션 | 용도 |
|---|---|
documents |
개인/일반 문서 + 메일 요약 |
tk_company |
TechnicalKorea 회사 문서 + 현장 리포트 |
chat_memory |
가치 있는 대화 기억 (선택적 저장) |
DB 스키마 (bot-postgres)
기존: ai_configs, routing_rules, prompts, chat_logs, mail_accounts
신규: document_ingestion_log, field_reports, classification_logs, mail_logs, calendar_events, report_cache, api_usage_monthly
상세 스키마는 docs/architecture.md 참조.
Synology Chat 명령어
/모델 <모델명> → 기본 모델 변경
/성격 <설명> → 시스템 프롬프트 변경
/설정 → 현재 설정 확인
/문서등록 [부서] [유형] [제목] → 회사 문서 등록 (Phase 4)
/보고서 [영역] [년월] → 월간 보고서 생성 (Phase 5)
안전장치
- 웹훅 토큰 검증: SYNOLOGY_CHAT_TOKEN 불일치 → reject
- Rate Limit: username별 10초 내 5건 → 거부
- 명령어 권한 체크: ADMIN_USERNAMES allowlist
- 프리필터: 인사/감사 정규식 → GPU 미호출
- 분류기 fallback: Qwen 10초 타임아웃 → api_light
- 예산 상한: api_heavy 월간 예산 초과 → api_light 다운그레이드
- 선택적 메모리: Qwen 판단으로 가치 있는 대화만 벡터화
- classification_logs: input 200자 제한, 90일 배치 정리
페르소나: 이드
모든 모델에 공통 적용되는 통합 페르소나.
- local tier: 경량 프롬프트 (
chat_localfeature) - api_light/api_heavy: 전체 프롬프트 (
chatfeature)
개발 규칙
- docker-compose.yml로 컨테이너 관리
- DB 포트는 127.0.0.1로 바인딩 (외부 노출 금지)
- 시크릿(API 키 등)은 .env 파일로 관리, git에 포함하지 않음
- 커밋 전 docker-compose config로 문법 검증
- 세션 시작 시 Plan 모드로 계획 → 확정 후 구현
- 구현 완료 후
/verify로 검증,/simplify로 코드 리뷰
슬래시 명령어
/simplify— 변경 코드 리뷰 및 단순화/verify— 전체 검증 (docker, env, sql, 헬스체크)/status— 프로젝트 상태 확인
참고 문서
- Architecture — 아키텍처, DB 스키마, 파이프라인 상세
- Claude Code Playbook — 활용 패턴 상세 정리
실수 방지 (Claude가 틀릴 때마다 여기에 추가)
- "오픈클로(OpenClaw)"를 Claude Code로 착각하지 말 것. OpenClaw은 별도의 오픈소스 AI 에이전트 프로젝트임
- tk-mp-postgres는 테스트 서버 전용 DB. 챗봇 인프라와 혼용하지 말 것
- GPU 서버(192.168.1.186)의 Ollama는 분류 + local 응답용. 임베딩/리랭킹은 맥미니 Ollama 사용
- response_tier는 Qwen v2 분류기 출력. 기존 complexity 기반 라우팅은 레거시 호환
- n8n v2.11+ Code 노드는 Task Runner 샌드박스(VM)에서 실행됨.
$http.request()/this.helpers.httpRequest()/fetch()/AbortController/URL사용 불가.require('http')/require('https')/require('url')사용 (NODE_FUNCTION_ALLOW_BUILTIN=crypto,http,https,url). 각 Code 노드에httpPost/httpPut헬퍼 함수 인라인 정의 - 샌드박스 사용 가능:
Buffer,setTimeout,TextEncoder,FormData,$env,$input,$(),$getWorkflowStaticData(),$json,require('url').parse()(new URL 불가),console