[REST API] - 10개 그래프 작업 엔드포인트 * /graph/resolve (Entity 중복 해결) * /graph/subgraph/* (부분 그래프 추출) * /graph/patterns/* (경로/순환/모티프) * /graph/analytics/* (중심성/커뮤니티/통계) * /rag/context-extraction (RAG 컨텍스트) * /rag/query (RAG 쿼리) [GraphQL] - 유연한 쿼리 지원 - Entity 조회 - Aggregate 쿼리 (communities, stats) [RAG 파이프라인] - 벡터 검색 → 컨텍스트 추출 → LLM 프롬프트 생성 - LLM 통합 준비 (프롬프트 형식 표준화) - 자동 문서화 (Swagger/OpenAPI) [테스트] - test_phase6_api.py (7/7 통과) - API 응답 구조 검증 - RAG 워크플로우 검증 - 에러 처리 검증 [문서] - PHASE_6_API_GUIDE.md (완전 레퍼런스) - 예제 코드 (Python, cURL) - 배포 가이드 (Docker, Kubernetes) 다음: Phase 7 - LLM 엔드투엔드 통합 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
12 KiB
12 KiB
Phase 6 GraphRAG API 가이드
개요
Phase 6는 Phase 5의 그래프 분석 기능을 REST API, GraphQL, RAG 파이프라인으로 노출합니다.
특징:
- ✅ REST API 엔드포인트 (10개 그래프 작업)
- ✅ GraphQL 지원 (유연한 쿼리)
- ✅ RAG 파이프라인 (LLM 통합)
- ✅ 자동 API 문서 (Swagger/OpenAPI)
빠른 시작
1. 서버 시작
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. 헬스 체크
curl http://localhost:8000/health
응답:
{
"status": "ok",
"version": "0.6.0",
"neo4j": "connected"
}
REST API 엔드포인트
엔티티 중복 해결 (Entity Resolution)
POST /api/v1/graph/resolve
의미적 중복 감지 및 병합
요청:
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
}'
응답:
{
"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 이웃 추출
요청:
curl "http://localhost:8000/api/v1/graph/subgraph/neighborhood/1?hops=2&limit=500"
응답:
{
"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
다중 엔티티 공통 컨텍스트
요청:
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
}'
응답:
{
"status": "success",
"data": {
"seed_entities": [...],
"common_neighbors": [...],
"nodes": [...],
"edges": [...],
"total_nodes": 50,
"total_edges": 120
}
}
패턴 매칭 (Pattern Matching)
POST /api/v1/graph/patterns/paths
두 엔티티 사이의 모든 경로 찾기
요청:
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
}'
응답:
{
"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
순환 의존성 감지
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
그래프 모티프 검출 (삼각형, 체인, 별)
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)
요청:
curl -X POST http://localhost:8000/api/v1/graph/analytics/centrality \
-H "Content-Type: application/json" \
-d '{
"centrality_type": "pagerank",
"top_n": 20
}'
응답:
{
"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
커뮤니티 감지
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
그래프 전체 통계
curl http://localhost:8000/api/v1/graph/analytics/statistics
응답:
{
"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
영향력 있는 엔티티
curl "http://localhost:8000/api/v1/graph/analytics/influential?top_n=20"
RAG 파이프라인
컨텍스트 추출
POST /api/v1/rag/context-extraction
지식 그래프에서 RAG 컨텍스트 추출
요청 (엔티티 ID로):
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
}'
요청 (텍스트 검색으로):
curl -X POST http://localhost:8000/api/v1/rag/context-extraction \
-H "Content-Type: application/json" \
-d '{
"query_text": "What is Apple?",
"hops": 2
}'
응답:
{
"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 쿼리
요청:
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
}'
응답:
{
"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 서비스로 전달:
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 쿼리 지원
엔티티 조회:
{
entity(id: 1) {
id
label
type
neighbors(hops: 2) {
id
label
distance
}
}
}
요청:
curl -X POST http://localhost:8000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ entity(id: 1) { id label type } }"
}'
응답:
{
"data": {
"entity": {
"id": 1,
"label": "Apple Inc.",
"type": "Company"
}
}
}
에러 처리
표준 에러 응답
{
"detail": "Entity not found",
"status_code": 404
}
검증 에러
{
"detail": [
{
"loc": ["query", "hops"],
"msg": "ensure this value is less than or equal to 3",
"type": "value_error.number.not_le"
}
]
}
예제 워크플로우
1단계: 엔티티 중복 해결
# 중복 엔티티 감지
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 컨텍스트 추출
# 대표 엔티티 주변 컨텍스트 추출
GET /api/v1/graph/subgraph/neighborhood/1?hops=2
Response:
{
"status": "success",
"data": {"nodes": [...], "edges": [...], "node_count": 50}
}
3단계: LLM 쿼리
# 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 응답
# 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초 |
설정
환경 변수
# 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 # 개발 모드
신뢰도 임계값
# Entity Resolver
VECTOR_THRESHOLD=0.85 # 벡터 유사도
TEXT_THRESHOLD=0.88 # 텍스트 유사도
# Subgraph Retriever
MIN_CONFIDENCE=0.0 # 최소 신뢰도
보안
권장사항
- 인증: 프로덕션에서 JWT/OAuth 추가
- Rate Limiting: API 요청 제한
- HTTPS: TLS 암호화
- 입력 검증: 모든 쿼리 검증
예: FastAPI 보안
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
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
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 연결 실패
# 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