Ais1on/CTI-RAG
요약
ThreatRAG는 사이버 위협 인텔리전스(CTI) 분석을 위해 설계된 통합 RAG 시스템입니다. 지식 그래프, 하이브리드 검색, 멀티 모델 라우팅 및 세션 관리를 결합하여 보안 분석가가 복잡한 위협 관계를 멀티 홉으로 추적할 수 있도록 지원합니다.
핵심 포인트
- Neo4j 기반 지식 그래프를 활용한 엔티티 중심의 멀티 홉 분석 지원
- 벡터 검색과 그래프 쿼리를 결합한 하이브리드 검색 엔진 구현
- OpenAI, DeepSeek 등 다양한 모델을 지원하는 멀티 모델 라우팅 및 서킷 브레이커 기능
- RabbitMQ와 Worker 구조를 통한 비동기 백그라운드 작업 처리 및 확장성 확보
- MySQL과 Redis를 활용한 안정적인 세션 관리 및 데이터 영속성 제공
ThreatRAG는 사이버 위협 인텔리전스 (Cyber Threat Intelligence, CTI)를 위한 RAG 시스템입니다. 단순히 텍스트 질의응답을 수행하는 것에 그치지 않고, 지식 베이스 검색, 지식 그래프 (Knowledge Graph), 멀티 모델 라우팅 (Multi-model Routing), 하이브리드 검색 (Hybrid Search), 세션 관리 및 백그라운드 작업을 하나의 배포 가능한 위협 인텔리전스 분석 백엔드로 통합했습니다.
프로젝트의 목표는 보안 분석가가 단순히 유사한 텍스트 몇 단락을 반환받는 것이 아니라, 공격 조직, 악성코드, 취약점, 인프라, 공격 활동 등의 엔티티 (Entity)를 중심으로 추적 가능한 멀티 홉 (Multi-hop) 분석을 수행할 수 있도록 하는 것입니다.
-
지식 베이스 기반의 위협 인텔리전스 질의응답을 지원합니다.
-
파일 업로드, 텍스트 청킹 (Chunking), 벡터화 (Vectorization) 및 유사도 검색을 지원합니다.
-
프론트엔드에서 실시간 답변을 표시하기 적합한 스트리밍 채팅 인터페이스를 지원합니다.
-
meta.db_id,meta.model_provider,meta.model_name등의 파라미터를 통해 지식 베이스와 모델을 제어할 수 있습니다. -
CTI 텍스트에서 엔티티와 관계를 추출하여 쿼리 가능한 그래프 구조로 축적합니다.
-
Neo4j를 사용하여 위협 엔티티, 관계 및 인덱스 결과를 저장합니다.
-
그래프 인덱서 시작, 중지, 상태 조회 및 즉시 실행 인터페이스를 제공합니다.
-
파일 엔티티 추출 작업을 지원하여 위협 보고서를 그래프 데이터로 대량 변환하기에 적합합니다.
-
벡터 검색, 그래프 쿼리, 쿼리 재작성 (Query Rewriting) 및 리랭크 (Rerank) 능력을 결합합니다.
-
멀티 홉 문제에 직면했을 때, 구조화된 관계와 텍스트 증거를 답변 컨텍스트로 함께 사용할 수 있습니다.
-
"특정 공격 조직이 어떤 취약점을 사용했는가", "특정 IP 주변 2-hop 이내에 어떤 위협 엔티티가 있는가"와 같은 관계형 질문에 답변하기에 적합합니다.
-
OpenAI, DeepSeek, Ollama, SiliconFlow 등 다양한 모델 소스의 접속 설정을 지원합니다.
-
기본 모델, 폴백 체인 (Fallback Chain), 요청 타임아웃, 스트리밍 타임아웃 및 단일 모델 재시도 횟수를 지원합니다.
-
모델 장애 시 예비 모델로 강등(Degradation)될 수 있도록 모델 서킷 브레이커 (Circuit Breaker) 설정을 지원합니다.
-
채팅 응답은 실제 사용된 모델과 강등 발생 여부를 판단하기 용이하도록 라우팅 메타데이터를 반환합니다.
-
자동 세션 생성 및 명시적 세션 생성 후 대화 지속을 모두 지원합니다.
-
세션은
user_id와 바인딩되어 사용자 수준의 격리가 용이합니다. -
MySQL을 사용하여 세션과 메시지를 영구 저장하며, Redis를 사용하여 런타임 읽기 속도를 가속화합니다.
-
세션 목록, 세션 상세 정보, 세션 업데이트, 세션 삭제 및 메시지 삭제 인터페이스를 제공합니다.
-
RabbitMQ를 사용하여 백그라운드 작업을 전달합니다.
-
threatrag-worker가 독립적으로 실행되어 비동기 작업 및 런타임 상태 확인 처리에 적합합니다. -
API 이미지와 worker 이미지를 분리하여 프로덕션 환경에서 독립적인 확장 및 축소가 용이합니다.
flowchart LR
Frontend["프론트엔드 / API Client"] --> API["ThreatRAG FastAPI"]
API --> MySQL["MySQL\n세션 및 지식 베이스 메타데이터"]
...
현재 Docker Compose 배포 구성은 다음과 같습니다:
| 서비스 | 역할 | 기본 포트 |
|---|---|---|
threatrag | FastAPI 백엔드 | 8006:8000 |
threatrag-worker | 백그라운드 작업 worker | 외부 포트 없음 |
mysql | 세션 및 메타데이터 저장소 | 3309:3306 |
redis | 캐시 및 런타임 상태 | 6379:6379 |
rabbitmq | 작업 큐 및 관리 백엔드 | 5672:5672 , 15672:15672 |
neo4j | 지식 그래프 데이터베이스 | 7475:7474 , 7688:7687 |
milvus-standalone | 벡터 데이터베이스 | 19530:19530 , 9091:9091 |
minio | Milvus 오브젝트 스토리지 의존성 | 9000:9000 , 9001:9001 |
etcd | Milvus 메타데이터 의존성 | 컨테이너 내부 접속 |
ollama | 로컬 모델 서비스 | 11434:11434 |
ThreatRAG/
├── rag/
│ ├── api/routers/ # FastAPI 라우터: chat/data/graph/auth
...
전체 환경을 시작하려면 Docker Compose 사용을 권장합니다. 이를 통해 API, worker, MySQL, Redis, RabbitMQ, Neo4j, Milvus, MinIO, Etcd 및 Ollama를 동시에 실행할 수 있습니다.
git clone https://github.com/Ais1on/CTI-RAG.git
cd CTI-RAG
저장소 루트 디렉토리에 .env 파일을 생성하고, 최소한 사용할 모델 키를 설정해야 합니다.
# 실행 환경
FASTAPI_ENV=production
# 클라우드 모델 키, 필요에 따라 작성
...
Ollama 로컬 모델만 사용하는 경우, 클라우드 모델 키를 먼저 작성하지 않아도 되지만, Ollama 컨테이너 내에서 해당 모델을 미리 pull 해야 합니다.
docker compose build threatrag threatrag-worker
docker compose up -d
서비스 상태 확인:
docker compose ps
API 로그 확인:
docker compose logs -f threatrag
API 검증:
curl http://localhost:8006/health
예상 반환값:
{"message":"status","status":"ok"}
로컬 모델을 사용하는 경우, 실행 후 Ollama 컨테이너에 진입하여 모델을 pull 하세요:
docker exec -it threatrag-ollama ollama pull qwen3:30b
docker exec -it threatrag-ollama ollama pull qwen2.5:7b
모델 목록 확인:
docker exec -it threatrag-ollama ollama list
로컬 개발 시에는 여전히 Docker Compose로 인프라를 먼저 실행한 후, 호스트 머신에서 API를 실행하는 것을 권장합니다. 주의사항: docker-compose.yml의 서비스 주소는 컨테이너 네트워크를 대상으로 합니다. 호스트 머신에서 직접 python ./main.py를 실행할 때는 환경에 따라 Redis, MySQL, Neo4j, Milvus, Ollama 등의 주소를 접근 가능한 호스트 이름이나 포트가 매핑된 localhost로 조정해야 합니다.
pip install -r requirements.txt
docker compose up -d mysql redis rabbitmq neo4j etcd minio milvus-standalone ollama
python ./main.py
config.yaml의 주요 스위치:
enable_reranker: true
enable_knowledge_base: true
enable_knowledge_graph: true
...
호스트 머신이나 컨테이너에 GPU가 올바르게 마운트되지 않은 경우, 우선 config.yaml의 device와 rl_device를 cpu로 유지하세요.
API는 기본적으로 Docker Compose를 통해 http://localhost:8006에 노출됩니다.
curl http://localhost:8006/health 호출 시 thread_id를 전달하지 않으면 자동으로 세션이 생성됩니다:
curl -X POST http://localhost:8006/chat/stream \
-H "Content-Type: application/json" \
-d '{
...
기존 세션 계속하기:
curl -X POST http://localhost:8006/chat/stream \
-H "Content-Type: application/json" \
-d '{
...
| 메서드 | 경로 | 설명 |
|---|---|---|
POST | /chat/sessions/create | 세션 생성 |
GET | /chat/sessions | 사용자 세션 목록 조회 |
GET | /chat/sessions/{thread_id} | 세션 상세 조회 |
PUT | /chat/sessions/{thread_id} | 세션 업데이트 |
DELETE | /chat/sessions/{thread_id} | 세션 삭제 |
GET | /chat/sessions/{thread_id}/messages | 메시지 히스토리 조회 |
DELETE | /chat/sessions/{thread_id}/messages/{message_id} | 메시지 삭제 |
| 메서드 | 경로 | 설명 |
|---|---|---|
POST | /data/upload | 파일 업로드 |
POST | /data/add-by-file | 파일을 통한 지식 베이스(Knowledge Base) 쓰기 |
POST | /data/add-by-chunks | 텍스트 청크(Chunks)를 통한 지식 베이스(Knowledge Base) 쓰기 |
GET | /data/files | 파일 목록 조회 |
GET | /data/user-knowledge-bases | 사용자 지식 베이스(Knowledge Base) 조회 |
DELETE | /data/document | 문서 삭제 |
| 방법 | 경로 | 설명 |
|---|---|---|
GET | /graph/info | 그래프 상태 조회 |
POST | /graph/start-indexer | 그래프 인덱서 (Indexer) 시작 |
POST | /graph/stop-indexer | 그래프 인덱서 (Indexer) 중지 |
GET | /graph/indexer-status | 인덱서 (Indexer) 상태 조회 |
POST | /graph/run-indexer-now | 인덱서 (Indexer) 즉시 실행 |
POST | /graph/extract-entities-from-file | 파일로부터 엔티티 (Entities) 추출 |
POST | /graph/extract-entities-task | 엔티티 (Entities) 추출 작업 생성 |
GET | /graph/extract-entities-task/status | 추출 작업 상태 조회 |
GET | /graph/extract-entities-task/result | 추출 작업 결과 조회 |
| 방법 | 경로 | 설명 |
|---|---|---|
POST | /auth/register | 사용자 등록 |
POST | /auth/token | 로그인 및 토큰 (Token) 획득 |
GET | /auth/me | 현재 사용자 조회 |
GET | /auth/users | 사용자 목록 조회 |
더 자세한 인터페이스 설명은 다음을 참조하세요:
Docker Compose는 기본적으로 상태 데이터를 저장소의 data/ 디렉토리에 마운트합니다:
data/
├── mysql/ # MySQL 데이터
├── redis/ # Redis 데이터
...
백업 시 data/ 디렉토리 전체를 백업할 수 있습니다:
tar -czf threatrag-data-backup.tar.gz data/
이전 버전에서 Docker volumes를 사용하는 경우, 데이터 저장 설명의 마이그레이션 설명을 참조하십시오.
최초 실행 시 MySQL, Redis, RabbitMQ, Neo4j, Milvus 및 Ollama의 상태 확인 (Health Check)이 완료될 때까지 기다려야 합니다. 다음 명령어를 사용하여 의존성 상태를 확인할 수 있습니다:
docker compose ps
docker compose logs -f threatrag
컨테이너에 접속하여 모델을 가져옵니다:
docker exec -it threatrag-ollama ollama pull qwen2.5:7b
그 다음 .env 또는 config.yaml의 모델명이 ollama list와 일치하는지 확인하십시오.
호스트 머신에 NVIDIA Container Toolkit이 없는 경우, Ollama GPU 컨테이너를 정상적으로 사용할 수 없을 수 있습니다. 먼저 CPU 모드를 사용하거나 다음 스크립트를 참조하십시오:
bash scripts/setup-nvidia-docker.sh
Docker Compose에서 Neo4j HTTP 포트 매핑은 7475:7474이며, 브라우저 접속 주소는 다음과 같습니다:
http://localhost:7475
Bolt 주소:
bolt://localhost:7688
기본 계정 및 비밀번호:
neo4j / 12345678
프론트엔드 프로젝트 저장소:
프론트엔드 연동 시 먼저 프론트엔드 인터페이스 문서를 읽는 것을 권장하며, 특히 /chat/stream의 라인별 JSON 스트리밍 응답과 thread_id 저장 로직에 주의를 기울여야 합니다.
본 프로젝트는 MIT License를 채택하고 있으며, 자세한 내용은 LICENSE를 참조하십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub AI Tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기