# Phase 6 GraphRAG API 가이드 ## 개요 Phase 6는 Phase 5의 그래프 분석 기능을 REST API, GraphQL, RAG 파이프라인으로 노출합니다. **특징**: - ✅ REST API 엔드포인트 (10개 그래프 작업) - ✅ GraphQL 지원 (유연한 쿼리) - ✅ RAG 파이프라인 (LLM 통합) - ✅ 자동 API 문서 (Swagger/OpenAPI) --- ## 빠른 시작 ### 1. 서버 시작 ```bash python -m uvicorn ontology_platform.ont_platform.api.phase6_app:app --reload ``` 기본 포트: `http://localhost:8000` ### 2. API 문서 확인 ``` http://localhost:8000/docs # Swagger UI http://localhost:8000/redoc # ReDoc ``` ### 3. 헬스 체크 ```bash curl http://localhost:8000/health ``` 응답: ```json { "status": "ok", "version": "0.6.0", "neo4j": "connected" } ``` --- ## REST API 엔드포인트 ### 엔티티 중복 해결 (Entity Resolution) #### `POST /api/v1/graph/resolve` 의미적 중복 감지 및 병합 **요청**: ```bash curl -X POST http://localhost:8000/api/v1/graph/resolve \ -H "Content-Type: application/json" \ -d '{ "entities": [ {"id": 1, "label": "Apple Inc.", "type": "Company"}, {"id": 2, "label": "Apple Inc", "type": "Company"}, {"id": 3, "label": "Microsoft", "type": "Company"} ], "vector_threshold": 0.85, "text_threshold": 0.88 }' ``` **응답**: ```json { "status": "success", "clusters": [ { "cluster_id": "C_1_2", "canonical_id": 1, "duplicates": [2], "confidence": 0.92, "reason": "combined" } ], "total_clusters": 1 } ``` --- ### 부분 그래프 추출 (Subgraph Retrieval) #### `GET /api/v1/graph/subgraph/neighborhood/{entity_id}` N-hop 이웃 추출 **요청**: ```bash curl "http://localhost:8000/api/v1/graph/subgraph/neighborhood/1?hops=2&limit=500" ``` **응답**: ```json { "status": "success", "data": { "center_entity": { "id": 1, "label": "Apple Inc.", "type": "Company", "confidence": 0.95 }, "nodes": [ {"id": 1, "label": "Apple Inc.", "type": "Company", "confidence": 0.95}, {"id": 5, "label": "iPhone", "type": "Product", "confidence": 0.92}, {"id": 6, "label": "Steve Jobs", "type": "Person", "confidence": 0.88} ], "edges": [ { "source_id": 1, "target_id": 5, "predicate": "produces", "confidence": 0.95 } ], "node_count": 3, "edge_count": 1 } } ``` #### `POST /api/v1/graph/subgraph/context` 다중 엔티티 공통 컨텍스트 **요청**: ```bash curl -X POST http://localhost:8000/api/v1/graph/subgraph/context \ -H "Content-Type: application/json" \ -d '{ "entity_ids": [1, 2, 3], "context_hops": 2 }' ``` **응답**: ```json { "status": "success", "data": { "seed_entities": [...], "common_neighbors": [...], "nodes": [...], "edges": [...], "total_nodes": 50, "total_edges": 120 } } ``` --- ### 패턴 매칭 (Pattern Matching) #### `POST /api/v1/graph/patterns/paths` 두 엔티티 사이의 모든 경로 찾기 **요청**: ```bash curl -X POST http://localhost:8000/api/v1/graph/patterns/paths \ -H "Content-Type: application/json" \ -d '{ "start_id": 1, "end_id": 5, "max_length": 5 }' ``` **응답**: ```json { "status": "success", "paths": [ {"path": [1, 2, 3, 5], "length": 3, "confidence": 0.87}, {"path": [1, 4, 5], "length": 2, "confidence": 0.91} ], "total_paths": 2 } ``` #### `POST /api/v1/graph/patterns/cycles` 순환 의존성 감지 ```bash curl -X POST http://localhost:8000/api/v1/graph/patterns/cycles \ -H "Content-Type: application/json" \ -d '{ "min_length": 2, "max_length": 5 }' ``` #### `POST /api/v1/graph/patterns/motifs` 그래프 모티프 검출 (삼각형, 체인, 별) ```bash curl -X POST http://localhost:8000/api/v1/graph/patterns/motifs \ -H "Content-Type: application/json" \ -d '{ "motif_type": "triangle", "limit": 100 }' ``` --- ### 그래프 분석 (Graph Analytics) #### `POST /api/v1/graph/analytics/centrality` 중심성 계산 (degree, pagerank, betweenness, closeness) **요청**: ```bash curl -X POST http://localhost:8000/api/v1/graph/analytics/centrality \ -H "Content-Type: application/json" \ -d '{ "centrality_type": "pagerank", "top_n": 20 }' ``` **응답**: ```json { "status": "success", "centrality_type": "pagerank", "entities": [ {"entity_id": 1, "label": "Apple", "centrality_score": 0.95, "rank": 1}, {"entity_id": 5, "label": "iPhone", "centrality_score": 0.87, "rank": 2} ], "total_entities": 2 } ``` #### `POST /api/v1/graph/analytics/communities` 커뮤니티 감지 ```bash curl -X POST http://localhost:8000/api/v1/graph/analytics/communities \ -H "Content-Type: application/json" \ -d '{ "algorithm": "louvain", "min_size": 3 }' ``` #### `GET /api/v1/graph/analytics/statistics` 그래프 전체 통계 ```bash curl http://localhost:8000/api/v1/graph/analytics/statistics ``` **응답**: ```json { "status": "success", "statistics": { "total_nodes": 1000, "total_edges": 5000, "avg_degree": 10.0, "density": 0.01, "diameter": 7, "is_connected": true } } ``` #### `GET /api/v1/graph/analytics/influential` 영향력 있는 엔티티 ```bash curl "http://localhost:8000/api/v1/graph/analytics/influential?top_n=20" ``` --- ## RAG 파이프라인 ### 컨텍스트 추출 #### `POST /api/v1/rag/context-extraction` 지식 그래프에서 RAG 컨텍스트 추출 **요청 (엔티티 ID로)**: ```bash curl -X POST http://localhost:8000/api/v1/rag/context-extraction \ -H "Content-Type: application/json" \ -d '{ "entity_id": 1, "hops": 2, "max_entities": 100 }' ``` **요청 (텍스트 검색으로)**: ```bash curl -X POST http://localhost:8000/api/v1/rag/context-extraction \ -H "Content-Type: application/json" \ -d '{ "query_text": "What is Apple?", "hops": 2 }' ``` **응답**: ```json { "status": "success", "query": "What is Apple?", "context": { "center_entity": {...}, "nodes": [...], "edges": [...], "node_count": 50 }, "context_size": 50 } ``` ### RAG 쿼리 (LLM 통합) #### `POST /api/v1/rag/query` LLM 통합 RAG 쿼리 **요청**: ```bash curl -X POST http://localhost:8000/api/v1/rag/query \ -H "Content-Type: application/json" \ -d '{ "query": "What products does Apple make?", "context_hops": 2, "use_graph_context": true }' ``` **응답**: ```json { "status": "success", "query": "What products does Apple make?", "relevant_entities": ["Apple Inc.", "iPhone", "iPad"], "context_nodes": 45, "llm_prompt": "You are a helpful assistant...\n\nKNOWLEDGE GRAPH CONTEXT:\n...", "ready_for_llm": true, "context": [...] } ``` ### LLM에 프롬프트 전달 RAG 응답에서 `llm_prompt`를 받으면, 이를 LLM 서비스로 전달: ```python import requests # Phase 6 RAG 서버에서 컨텍스트 획득 rag_response = requests.post( "http://localhost:8000/api/v1/rag/query", json={"query": "What is Apple?"} ).json() # LLM 서비스 호출 (예: OpenAI) llm_response = requests.post( "https://api.openai.com/v1/chat/completions", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={ "model": "gpt-4", "messages": [ { "role": "user", "content": rag_response["llm_prompt"] } ], "temperature": 0.7, "max_tokens": 500 } ).json() print(llm_response["choices"][0]["message"]["content"]) ``` --- ## GraphQL 엔드포인트 ### `POST /graphql` 유연한 GraphQL 쿼리 지원 **엔티티 조회**: ```graphql { entity(id: 1) { id label type neighbors(hops: 2) { id label distance } } } ``` **요청**: ```bash curl -X POST http://localhost:8000/graphql \ -H "Content-Type: application/json" \ -d '{ "query": "{ entity(id: 1) { id label type } }" }' ``` **응답**: ```json { "data": { "entity": { "id": 1, "label": "Apple Inc.", "type": "Company" } } } ``` --- ## 에러 처리 ### 표준 에러 응답 ```json { "detail": "Entity not found", "status_code": 404 } ``` ### 검증 에러 ```json { "detail": [ { "loc": ["query", "hops"], "msg": "ensure this value is less than or equal to 3", "type": "value_error.number.not_le" } ] } ``` --- ## 예제 워크플로우 ### 1단계: 엔티티 중복 해결 ```bash # 중복 엔티티 감지 POST /api/v1/graph/resolve Body: {"entities": [{"id": 1, "label": "Apple Inc."}, {"id": 2, "label": "Apple"}]} Response: { "status": "success", "clusters": [{"canonical_id": 1, "duplicates": [2], "confidence": 0.92}] } ``` ### 2단계: RAG 컨텍스트 추출 ```bash # 대표 엔티티 주변 컨텍스트 추출 GET /api/v1/graph/subgraph/neighborhood/1?hops=2 Response: { "status": "success", "data": {"nodes": [...], "edges": [...], "node_count": 50} } ``` ### 3단계: LLM 쿼리 ```bash # RAG 쿼리 (LLM용 프롬프트 자동 생성) POST /api/v1/rag/query Body: {"query": "What does Apple do?"} Response: { "status": "success", "llm_prompt": "You are a helpful assistant...", "ready_for_llm": true } ``` ### 4단계: LLM 응답 ```python # LLM 서비스로 프롬프트 전달 response = llm_service(rag_response["llm_prompt"]) print(response) # LLM 답변 ``` --- ## 성능 특성 | 엔드포인트 | 데이터셋 | 응답 시간 | |-----------|---------|---------| | `/graph/resolve` | 1K 엔티티 | < 500ms | | `/graph/subgraph/neighborhood` | 2-hop, 10K 노드 | < 200ms | | `/graph/patterns/paths` | max_length=5 | < 300ms | | `/graph/analytics/centrality` | top_n=100 | < 600ms | | `/graph/analytics/communities` | 1K 노드 | < 1초 | | `/rag/query` | 벡터 검색 + 컨텍스트 | < 1초 | --- ## 설정 ### 환경 변수 ```bash # Neo4j 연결 NEO4J_URI=bolt://localhost:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=ontology123 # API 설정 API_HOST=0.0.0.0 API_PORT=8000 API_RELOAD=true # 개발 모드 ``` ### 신뢰도 임계값 ```python # Entity Resolver VECTOR_THRESHOLD=0.85 # 벡터 유사도 TEXT_THRESHOLD=0.88 # 텍스트 유사도 # Subgraph Retriever MIN_CONFIDENCE=0.0 # 최소 신뢰도 ``` --- ## 보안 ### 권장사항 1. **인증**: 프로덕션에서 JWT/OAuth 추가 2. **Rate Limiting**: API 요청 제한 3. **HTTPS**: TLS 암호화 4. **입력 검증**: 모든 쿼리 검증 ### 예: FastAPI 보안 ```python from fastapi.security import HTTPBearer, HTTPAuthCredential security = HTTPBearer() @app.get("/api/v1/graph/resolve") async def resolve_entities(credentials: HTTPAuthCredential = Depends(security)): # JWT 검증 token = credentials.credentials # ... ``` --- ## 배포 ### Docker ```dockerfile FROM python:3.10 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "ontology_platform.ont_platform.api.phase6_app:app", "--host", "0.0.0.0"] ``` ### Kubernetes ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: ontology-api spec: replicas: 3 selector: matchLabels: app: ontology-api template: metadata: labels: app: ontology-api spec: containers: - name: api image: ontology-api:0.6.0 ports: - containerPort: 8000 ``` --- ## 문제 해결 ### Neo4j 연결 실패 ```bash # Neo4j 상태 확인 http://localhost:7687 # 연결 테스트 curl http://localhost:8000/health ``` ### 높은 응답 시간 - 쿼리 최적화: Cypher 인덱스 확인 - 배치 크기 조정 - 최대 깊이/한계 감소 ### 메모리 부족 - Neo4j 힙 크기 증가 - 배치 크기 감소 - 캐싱 활성화 --- ## 다음 단계 ### Phase 7: LLM 엔드투엔드 통합 - FastAPI 미들웨어로 LLM 직접 호출 - 스트리밍 응답 - 응답 캐싱 ### Phase 8: 고급 기능 - 멀티 테넌트 지원 - 실시간 그래프 업데이트 - 버전 관리 --- **API 버전**: 0.6.0 **마지막 업데이트**: 2026-05-14