Files
AI/온톨로지플랫폼_통합설계서.md
2026-05-14 23:37:21 +09:00

54 KiB
Raw Blame History

범용 온톨로지 구축 플랫폼 통합 설계서

작성일: 2026-05-13 대상: 본 문서를 받아 실제 구현을 수행할 모든 AI 에이전트 및 개발자 근거 자료: C:\Users\lasta\MyProject\AI\오픈소스분석자료 의 8개 분석 명세 (Crawl4AI, Firecrawl, Guardrails, Knowledge Agent, Neo4j GraphRAG, OntoCast, OpenDeepResearcher, Trafilatura)


0. 본 문서의 사용 규칙 (Agent Instruction)

본 문서를 받는 AI 에이전트는 다음을 준수한다.

  1. 본 문서는 8개 분석 자료를 바탕으로 도출된 최종 통합 설계다. 개별 분석 자료와 본 문서가 충돌할 경우 본 문서가 우선한다.
  2. 본 문서가 "그대로 사용"이라고 명시한 모듈은 원본 소스를 가급적 수정하지 않고 라이브러리 또는 vendored copy 형태로 도입한다. "어댑터 작성"이라고 명시한 부분만 우리 코드로 만든다.
  3. "통합은 한 번에 하나씩"의 원칙을 지킨다. Phase N의 검수 게이트(Acceptance Gate)를 통과하기 전에는 Phase N+1로 진행하지 않는다.
  4. 코드 작성 시 어느 분석 자료의 어느 절을 근거로 했는지 PR 설명에 명시한다. 예: OntoCast 분석 §6 GraphUpdate 모델.
  5. 본 문서가 "제외(Excluded)"라고 명시한 프로젝트는 코드/의존성에 포함하지 않는다.

1. Executive Summary (한눈에 보는 결론) — 수정판

1.1 설계 변경 배경

초기 설계는 OntoCast를 Phase 0 Base로 사용하고, 이후 다른 컴포넌트를 순차 통합하는 구조였다.

그러나 Phase 0 실제 구현 및 테스트 결과, OntoCast의 전체 파이프라인(RDF/OWL 갱신, Renderer/Critic retry loop, Entity Aggregation)을 초기 단계부터 사용하면:

  • 처리 속도가 매우 느림 (테스트 분량 축소에도 불구하고)
  • 중간 결과 확인이 어려워 디버깅 복잡
  • 대량 크롤링 단계에 부적합
  • 비용 폭주 위험

따라서 설계를 전면 개정한다.

1.2 수정된 핵심 전략

항목 기존 설계 수정 설계
기본 엔진 OntoCast 중심 가벼운 JSON Extraction
OntoCast 역할 입력 → 처리 → RDF 출력 승인된 후보 → 정밀 RDF/OWL 갱신
처리 흐름 모든 문서 → OntoCast → RDF 문서 → 후보 추출 → 검수 → 선택적 OntoCast → RDF
Phase 0 목표 OntoCast 안정화 Fast Extraction MVP (RDF 없이)
총 Phase 수 6개 (Phase 0~5) 6개 (구조 변경)

한 문장 요약: OntoCast는 기본 엔진에서 정밀 갱신 엔진으로 역할을 낮춘다.

1.3 최종 구조

Trafilatura / Crawl4AI
→ Fast JSON Extraction (가벼움)
→ Candidate Store (SQLite/PostgreSQL)
→ Validation / Guardrails
→ Review Queue (사람 검수)
→ Optional OntoCast (고신뢰/승인된 후보만)
→ Fuseki RDF (Canonical)
→ Neo4j Projection (검색/RAG)
항목 결정
기본 수집 Trafilatura (정적, 빠름) + Crawl4AI (동적, 선택)
초기 추출 Lightweight LLM JSON Extractor (RDF 아님)
검증 Pydantic + Guardrails
정밀 RDF 갱신 OntoCast (batch 후보 단위, 선택적)
통합 대상 ① Trafilatura ② Crawl4AI ③ Guardrails ④ Neo4j GraphRAG ⑤ OntoCast (용도 변경)
제외 Firecrawl, OpenDeepResearcher (기존과 동일)

기존 설계 요약 (참고용) — Phase 0 문제 분석

기존 Phase 0: OntoCast Base 안정화 (⚠️ 폐기됨)

기존 설계에서는 다음과 같이 계획되었다:

1. OntoCast 저장소를 platform/core/ontocast/ 에 배치
2. select_ontology.py 버그 수정
3. convert_document.py 다중 파일 처리 확장
4. Robyn → FastAPI 재작성
5. 전체 파이프라인 end-to-end 테스트
→ RDF/OWL 생성 목표

실제 테스트 결과 발견된 문제:

  • 처리 속도: 단순 샘플도 5분 이상 소요 (목표: 30초)
  • 디버깅 어려움: RDF 중심이라 중간 상태 확인 곤란
  • 비용 폭주: Critic retry loop 반복될수록 LLM 호출 증가
  • 확장성 부족: 대량 문서 처리에 부적합

결론: OntoCast 중심 구조는 정밀도는 높지만 초기 단계에는 부적합. 따라서 기존 Phase 0을 폐기하고, 새로운 Phase 0 (Fast Extraction MVP)으로 변경.

기존 계획 중 여전히 유용한 부분:

  • OntoCast 버그 수정 (§9.1 참고) → Phase 4에서 활용
  • Pydantic Settings 패턴 → 현재 설계에 적용
  • BudgetTracker 개념 → Phase 4에서 재사용

2. 8개 오픈소스 강점 매트릭스 (Strength Matrix)

각 소스가 "가장 잘하는 영역" 하나씩만 추려서 기능 중복을 정리한 표.

# 프로젝트 카테고리 대체 불가 강점 라이선스 언어 채택 여부
1 OntoCast 온톨로지 코어 GraphUpdate 기반 SPARQL 증분 갱신 + Renderer/Critic retry loop + Entity aggregation(embedding + URI 정규화 + owl:sameAs) Apache 2.0 Python 3.12+ 선택적 Precision RDF/OWL Engine
2 Trafilatura 본문 추출 본문/메타데이터/날짜/저자/언어 추출의 산업 표준 정밀도. XML body tree 보존, SimHash fingerprint, feed/sitemap discovery Apache 2.0 Python 통합
3 Crawl4AI 크롤링 동적 페이지(Playwright)+LLM 친화 Markdown 변환의 결정판. Deep crawl(BFS/DFS/Best-First) + URL Seeder + Adaptive crawler + browser pool/dispatcher/cache Apache 2.0 Python 3.10+ 통합
4 Guardrails 검증 Pydantic 기반 LLM 출력 강제 + on_fail 정책(reask/fix/filter/refrain) + JSON path field validator Apache 2.0 Python 3.10+ 통합
5 Neo4j GraphRAG KG 저장/검색 GraphSchema + GraphPruning + Neo4jWriter + EntityResolver + Vector/Hybrid/Text2Cypher Retriever + GraphRAG Apache 2.0 Python 3.10+ 통합
6 Knowledge Agent 멀티에이전트 LangGraph 기반 Analyst→Researcher→Curator→Auditor→Fixer→Advisor 패턴 + LightRAG 엔티티/관계 추출 프롬프트 비명시 Python 패턴/프롬프트만 차용
7 Firecrawl 크롤링 API scrape/map/crawl/search/parse API 명세 우수, fire-engine fallback AGPL 의심 TypeScript 제외 (스택 분리 부담 + 라이선스 리스크 + Crawl4AI와 중복)
8 OpenDeepResearcher 검색 루프 LLM 기반 검색어 생성 + 자기확장 루프 + <done> 판단 MIT Python (notebook) 제외 (eval() 보안 문제 + Knowledge Agent의 Researcher가 더 구조화됨)

3. OntoCast를 선택적 Precision RDF/OWL Engine으로 유지하는 근거

비교 항목 OntoCast Knowledge Agent Neo4j GraphRAG
사용자 목표 적합성("온톨로지 구축") ◎ RDF/OWL 중심 △ 지식그래프 보조 도구 ○ Property Graph 중심
핵심 자산의 대체 난이도 ◎ GraphUpdate 증분 갱신은 다른 어디서도 못 구함 △ LangGraph 패턴은 재작성 용이 ○ Library 형태로 갖다 쓰면 됨
Renderer/Critic retry loop ◎ 내장 △ Refiner 비슷한 개념만 × 없음
Entity Aggregation/URI 정규화 ◎ 내장 (tool/agg/) × 없음 △ Resolver 있으나 단순
LangGraph 워크플로우 ◎ 내장 (stategraph/) ◎ 내장 × 없음
Triple Store 추상화 (Fuseki/Neo4j/FS) ◎ 내장 × LightRAG에 종속 △ Neo4j만
ToolBox dependency container ◎ 내장 × ×
라이선스 명확성 ◎ Apache 2.0 × 비명시 ◎ Apache 2.0
코드 안정성 ○ 일부 버그 (§13.1) × 다수 버그 (Curator/Auditor/Fixer/Advisor) ◎ 테스트 광범위

결론: OntoCast의 "GraphUpdate 증분 갱신 + Renderer/Critic 루프 + Entity Aggregation"은 다른 소스로 대체 불가능한 차별 자산이다. 이를 선택적 Precision RDF/OWL Engine으로 유지하고, Fast Pipeline과 분리하여 사용한다.


4. 통합 아키텍처 (Layered Architecture) — 수정판

4.0 기존 vs 수정 아키텍처 비교

기존 설계 (Phase 0에서 발견된 문제):

입력(URL/File)
→ L4 OntoCast 전체 파이프라인 (Converter/Chunker/Renderer/Critic...)
→ RDF/OWL 생성
→ L1 Fuseki 저장

문제: 초기 단계부터 무거운 RDF 처리, 디버깅 어려움, 테스트 속도 느림

수정 설계 (분리된 두 경로):

Fast Path (대부분):          Precision Path (선택):
입력 → 본문 추출             승인 후보 → OntoCast
    → 가벼운 JSON 추출            → RDF/OWL 갱신
    → 검증 (Pydantic)            → Fuseki 저장
    → 후보 저장
    → 검수/자동승인

이점: 빠른 피드백, 명확한 단계, OntoCast는 필요할 때만

4.1 수정된 계층 구조

┌──────────────────────────────────────────────────────────────────┐
│  L7. UI Layer (Ontology Studio, Review Console, Search UI)       │
│      — 새로 작성 (React/Next.js 등 자유 선택)                      │
├──────────────────────────────────────────────────────────────────┤
│  L6. Platform API (FastAPI)                                       │
│      — 새로 작성. /projects, /jobs, /sources, /extract,           │
│        /candidates, /review, /search, /admin                      │
├──────────────────────────────────────────────────────────────────┤
│  L5. Job Orchestration (Job Queue + Worker)                       │
│      — 새로 작성. Arq/Celery, Redis/Postgres state                │
├──────────────────────────────────────────────────────────────────┤
│  L4a. Fast Extraction Engine (기본 경로)                          │
│      ★ Trafilatura (본문/메타 추출)                               │
│      ★ Crawl4AI (동적 크롤링, 선택)                               │
│      ★ Lightweight JSON Extractor (가벼운 entity/relation 추출)   │
│      — 입력: 정제 본문 → 출력: JSON (RDF 아님)                    │
├──────────────────────────────────────────────────────────────────┤
│  L4b. OntoCast RDF Engine (정밀 경로, 선택적)                     │
│      ★ OntoCast (승인 후보 → RDF/OWL 갱신, Batch 처리)           │
│      — Renderer/Critic retry loop, GraphUpdate, Entity Agg.      │
│      — 호출: batch 후보 단위 (문서 단위 아님)                      │
├──────────────────────────────────────────────────────────────────┤
│  L3. Quality & Validation Gate                                    │
│      ★ Pydantic (JSON 스키마 검증)                               │
│      ★ Guardrails (LLM 출력 강제 검증)                           │
│      — CandidateEntity/Relation 검증                              │
├──────────────────────────────────────────────────────────────────┤
│  L2. Temporary Knowledge Store                                    │
│      • SQLite / PostgreSQL (초기)                                  │
│      • CandidateEntity, CandidateRelation, ReviewStatus          │
│      — RDF 아님, 검수 전 임시 저장소                               │
│      — Neo4j draft graph (선택, Phase 3)                          │
├──────────────────────────────────────────────────────────────────┤
│  L1. Canonical Storage (검수/승인 후)                             │
│      • Fuseki (Canonical RDF Store)                               │
│      • Neo4j (Projection, Vector Index, Fulltext)                 │
│      ★ Neo4j GraphRAG (검색/RAG Retriever)                        │
│      • PostgreSQL (Job/User/Project 메타데이터)                   │
│      • Object Storage (raw HTML, PDF artifacts)                   │
└──────────────────────────────────────────────────────────────────┘

4.2 데이터 흐름 (수정판) — Fast Path + Precision Path

Fast Path (기본, 대부분의 문서)

[Source URL/File]
  → [L4a 수집] Trafilatura bare_extraction (본문 + metadata)
            또는 Crawl4AI (JS 필요 시)
  → [L4a 정제] 정제된 본문 텍스트 + title/author/date/language
  → [L4a 추출] Lightweight LLM JSON Extractor
       입력: 정제 본문
       출력: {entities, relations, claims, evidence, confidence}
  → [L3 검증] Pydantic + Guardrails
       EntityIdFormatValidator
       UniqueEntityIdValidator
       RelationEndpointExistsValidator
       ConfidenceRangeValidator
       EvidenceExistsValidator
  → [L2 저장] PostgreSQL / SQLite
       CandidateEntity (id, label, type, confidence, evidence_ids)
       CandidateRelation (source_id, predicate, target_id, confidence)
       EvidenceSpan (chunk_id, text, start_offset, end_offset)
       ReviewStatus (pending/approved/rejected)
  → [L6 API] /candidates 조회
       사람이 결과 확인 및 검수

특징:

  • 10~30초 내 처리 (OntoCast 없음)
  • JSON 기반 (RDF 아님)
  • 중간 결과 명확함
  • 대량 문서 적합

Precision Path (선택, 승인된 후보만)

[Approved CandidateEntity/Relation (Batch)]
  → [L4b OntoCast] OntoCast Adapter
       Candidate JSON → OntoCast internal format 변환
       batch_size: 10~50개 단위
  → [L4b 처리] OntoCast RENDER_ONTOLOGY_UPDATE + Critic
       GraphUpdate 생성
       Entity Aggregation (owl:sameAs)
  → [L3 검증] Guardrails (OntoCast 출력)
       최종 GraphUpdate schema 검증
  → [L1 저장]
       Fuseki: Canonical RDF (via GraphUpdate SPARQL)
       Postgres: Job metadata, processing time, cost
  → [L1 투영] Neo4j Async Worker
       Fuseki RDF → Neo4j Property Graph
       Chunk embedding + Vector index
       Lexical graph (Document/Chunk/Entity)
  → [L6 API] /search/{type} 호출 시 Neo4j GraphRAG의
       VectorRetriever + HybridRetriever + GraphRAG

특징:

  • RDF/OWL 정밀 반영 (OntoCast의 강점)
  • GraphUpdate 증분 갱신 (대체 불가 기능)
  • Entity Aggregation (중복 병합)
  • ⚠️ 처리 시간 길음 (batch 단위로 완화)
  • ⚠️ 비용 높음 (선택적 호출로 제어)

4.3 저장소 전략 (Fast Path vs Precision Path)

Fast Path 저장소

저장소 역할 특징
PostgreSQL / SQLite 임시 지식 저장소. Candidate 후보 보관 검수 전 상태, RDF 아님
CandidateEntity id, label, type, confidence, source_doc_id, evidence_ids 사람 검수 대기
CandidateRelation source_id, predicate, target_id, confidence, evidence 사람 검수 대기
ReviewStatus pending → approved/rejected/auto_approved 승인 상태 기록

Precision Path 저장소

저장소 역할 근거
Fuseki (Canonical RDF) 진실 원본 (source of truth). OntoCast의 GraphUpdate가 SPARQL UPDATE로 직접 반영. OWL/SHACL 추론 가능 OntoCast GraphUpdate는 SPARQL 기반
Neo4j (Projection) 검색/시각화/RAG 전용. Fuseki 변경 시 비동기로 동기화. Lexical graph(Document/Chunk) + Entity 노드 + embedding Neo4j GraphRAG + Vector search

중요 원칙:

  • Fast Path는 RDF를 생성하지 않음 (JSON만)
  • Precision Path만 RDF 생성 (OntoCast 호출 시)
  • RDF가 진실, Neo4j는 사본
  • Fuseki commit → Worker가 async로 Neo4j 동기화

5. 단계별 통합 로드맵 (Phased Integration Plan) — 수정판

각 Phase의 마지막에 Acceptance Gate(검수 게이트)가 있다. Gate를 통과해야 다음 Phase 진행.


Phase 0: Fast Extraction MVP (새로운 시작점)

목표: OntoCast를 붙이기 전에, 웹페이지나 파일에서 의미 있는 JSON 형태의 온톨로지 후보가 빠르게 추출되는지 검증한다. RDF/OWL, SPARQL, GraphUpdate, Critic loop를 사용하지 않는다.

배경: 기존 설계에서 OntoCast를 Phase 0 Base로 사용했으나, 실제 구현 결과 처리 속도가 지나치게 느렸다. 따라서 보다 가벼운 추출 엔진을 우선 구성하고, OntoCast는 선택적으로 호출하는 구조로 변경했다. (자세한 배경은 §1.1 참조)

작업:

  1. platform/core/extractors/web_extractor.py 작성

    • Trafilatura 기반 본문 추출
    • 출력: title, author, publish_date, language, canonical_url, fingerprint, body_text
    • 참고: 기존 설계 Phase 1 내용 일부 활용
  2. platform/core/crawler/crawl4ai_adapter.py 작성 (최소 버전)

    • 기본: HTTP fetch만 (Trafilatura로 후처리)
    • 선택: Crawl4AI dynamic profile (JS 렌더링 필요 시)
    • 참고: 기존 설계 Phase 2 내용 단순화
  3. platform/core/extraction/lightweight_extractor.py 작성

    • 입력: 정제된 본문 텍스트
    • 출력: JSON 형태
    {
      "entities": [
        {"id": "E1", "label": "...", "type": "...", "confidence": 0.9, "evidence_ids": ["EV1"]}
      ],
      "relations": [
        {"source_id": "E1", "predicate": "...", "target_id": "E2", "confidence": 0.85}
      ],
      "claims": [],
      "evidence": [
        {"id": "EV1", "text": "...", "start_offset": 100, "end_offset": 150}
      ],
      "warnings": []
    }
    
    • LLM: OpenAI/Claude (선택), 프롬프트는 간단한 JSON extraction만
  4. CandidateStore (SQLite 또는 PostgreSQL)

    • 테이블: CandidateEntity, CandidateRelation, EvidenceSpan, SourceDocument, ReviewStatus
    • RDF 변환 금지 (후보만 저장)
  5. 간단한 FastAPI 작성

    POST /extract/url           # URL 입력
    POST /extract/file          # 파일 업로드
    GET  /candidates            # 후보 목록 조회
    GET  /candidates/{id}       # 후보 상세
    

Acceptance Gate 0:

  • 단일 URL 입력 시 10~30초 이내 후보 JSON 생성 (기존 OntoCast 방식과 비교해 5배 이상 빠름)
  • 본문 추출 결과를 사람이 확인 가능 (metadata 포함)
  • entity/relation 후보가 SQLite/PostgreSQL에 저장됨
  • OntoCast 없이도 추출 품질을 평가할 수 있음
  • 동일 URL 재입력 시 fingerprint 기반 중복 감지 가능
  • Trafilatura + Crawl4AI (선택) 초기 통합 완료

Phase 1: Fast Pipeline 품질 개선

목표: 가벼운 추출 파이프라인의 결과 품질을 안정화하고, 무의미한 후보를 필터링한다.

작업:

  1. Pydantic 스키마 정의

    class CandidateEntity(BaseModel):
        id: str
        label: str
        type: Literal["concept", "person", "org", ...]  # 도메인별 설정
        description: str | None = None
        confidence: float  # 0.0 ~ 1.0
        evidence_ids: list[str]
    
    class CandidateRelation(BaseModel):
        source_id: str
        predicate: str
        target_id: str
        confidence: float
        evidence: list[str]
    
  2. Lightweight JSON 검증 강화

    • "value", "keyword" 같은 무의미한 label 필터링
    • confidence ≤ 0 또는 ≥ 1.0인 값 정정
    • evidence 없는 relation은 저장 금지
    • entity와 relation endpoint 매칭 검사
  3. 도메인별 entity type/predicate 설정

    • 프로젝트별 기본 타입 팩 정의
    • 사용자 정의 타입 추가 가능
    • 프롬프트에 반영
  4. Confidence 점수 부여 개선

    • 초기: LLM 직접 추출값
    • 개선: evidence 길이, 문맥 유사도, type 신뢰도 등 반영

Acceptance Gate 1:

  • "value", "keyword", 빈 문자열 같은 무의미한 후보가 저장되지 않음
  • evidence 없는 relation은 저장 금지
  • entity와 relation endpoint가 서로 일치함 (존재하는 entity만 참조)
  • 후보 품질을 사람이 빠르게 검토 가능 (metadata 포함)
  • Phase 0 성능 유지 (10~30초)

Phase 2: Guardrails 검증 강화

목표: Lightweight Extractor가 생성한 JSON 후보를 Guardrails로 강제 검증한다. 잘못된 값이 저장소에 들어가는 것을 방지한다.

배경: 기존 설계 Phase 3에서 OntoCast Renderer 출력을 Guardrails로 검증했으나, 여기서는 더 초기 단계인 Lightweight JSON extraction 결과를 검증한다.

작업:

  1. 의존성 추가: guardrails-ai>=0.x (Hub/telemetry 비활성화 필수)

  2. Validator 작성 (Guardrails 분석 §15.4 참고, 단순화)

    • EntityIdFormatValidator: id는 알파벳+숫자만
    • UniqueEntityIdValidator: 동일 id 중복 없음
    • RelationEndpointExistsValidator: source/target entity 존재 확인
    • ConfidenceRangeValidator: confidence는 0.0~1.0
    • EvidenceExistsValidator: evidence_ids가 실제로 존재하는 지 확인
    • NoSelfRelationValidator: source ≠ target
  3. Guardrails Guard 설정

    guard = Guard.for_pydantic(
        CandidateEntity,
        validators=[...],
        num_reasks=1,
        on_fail=OnFailAction.FILTER
    )
    
  4. Lightweight Extractor 후 검증 적용

    • LLM JSON 출력 → Guardrails Guard → CandidateStore
    • 검증 실패 시: fix/filter/refrain 정책 적용
    • 실패 후보는 review queue로 이동 (삭제 금지)

Acceptance Gate 2:

  • confidence > 1.0 같은 오류 자동 fix 또는 filter
  • 존재하지 않는 entity를 참조하는 relation 차단
  • evidence 없는 후보 자동 필터링
  • 검증 실패 결과도 감사 로그에 기록됨
  • Guardrails Hub/telemetry 외부 통신 없음 (환경변수 확인)
  • Phase 0~1 성능 유지

Phase 3: Review & Approval 시스템

목표: 검증된 후보에 대해 사람이 검수하고, 자동 승인 정책을 적용할 수 있도록 한다.

작업:

  1. Review UI (간단한 버전)

    • 후보 목록 표시
    • entity/relation별 evidence 하이라이트 (원문으로부터)
    • 승인/반려/수정 버튼
  2. 자동 승인 정책 정의

    if confidence >= 0.95 and source_trust >= 0.9:
        status = "auto_approved"
    else:
        status = "pending"  # 사람 검수 대기
    
  3. ReviewStatus 테이블 관리

    • pending: 사람 검수 대기
    • approved: 사람이 승인
    • auto_approved: 정책으로 자동 승인
    • rejected: 반려
  4. 승인된 후보만 다음 단계로

    • Precision Path (OntoCast) 또는
    • 최종 저장소 (RDF/Neo4j)로 전달

Acceptance Gate 3:

  • Review 큐에 100개 후보를 5분 내 표시
  • evidence 원문 추적 가능
  • 자동 승인 정책이 정확히 작동
  • 승인/반려 이력이 저장됨
  • Phase 0~2 기능 회귀 없음

Phase 4: OntoCast 선택적 통합 (역할 변경)

목표: OntoCast를 전체 파이프라인의 Base에서 승인된 후보를 RDF/OWL로 정밀 반영하는 선택적 엔진으로 통합한다.

배경: Phase 0 테스트 결과, OntoCast 전체 파이프라인을 초기부터 사용하는 것은 비효율적임. 따라서 검증된 후보만 batch 단위로 OntoCast에 전달하여 처리한다.

처리 흐름:

Approved CandidateEntity/Relation (batch)
→ OntoCast Adapter (JSON → internal format 변환)
→ OntoCast RENDER_ONTOLOGY_UPDATE + Critic loop
→ GraphUpdate 생성
→ Guardrails (최종 검증)
→ Fuseki RDF 저장 (SPARQL UPDATE)

작업:

  1. platform/core/ontocast_adapter.py 작성

    • CandidateEntity/Relation → OntoCast 입력 포맷 변환
    • batch_size: 10~50개 단위 (문서 단위 아님)
    • 처리 실패 시 후보는 보존, review queue로 이동
  2. OntoCast 호출 원칙

    • 모든 문서를 직접 OntoCast에 보내지 않음
    • 검수된 후보 또는 고신뢰 후보만 전달
    • batch 단위로 묶어 호출 (문서 단위 호출 금지)
    • 실패해도 Fast Pipeline은 계속 동작
  3. OntoCast 처리 선택지

    • 필수 OntoCast: confidence ≥ 0.95 + approved by human
    • 선택 OntoCast: 신뢰도 낮은 후보 batch 처리 (비용 증가)
    • Skip OntoCast: 임시 저장소(Neo4j draft)에만 유지
  4. GraphUpdate 결과 처리

    • OntoCast GraphUpdate → SPARQL 문장
    • Fuseki에 commit
    • Worker가 async로 Neo4j projection 갱신
  5. Cost & Time Tracking

    • OntoCast 호출당 비용/시간 기록
    • BudgetTracker에 반영
    • 운영자가 비용 제어 가능

Acceptance Gate 5:

  • 승인된 후보 10~50개를 batch로 OntoCast 처리 가능
  • 처리 시간: 각 batch마다 1~5분 (문서 단위 처리보다 효율)
  • 처리 실패 시 후보 데이터는 보존됨 (손실 없음)
  • OntoCast 없이도 Fast Pipeline은 계속 독립 동작
  • OntoCast 처리 결과가 RDF/OWL로 Fuseki에 저장됨
  • GraphUpdate는 SPARQL이므로 증분 갱신 가능 (기존 RDF와 merge)

Phase 5: Neo4j GraphRAG 통합 (Projection + 검색/RAG)

목표: Fuseki에 commit된 RDF를 Neo4j Property Graph로 projection하고, Neo4j GraphRAG의 Retriever/GraphRAG로 검색/QA 기능을 추가한다.

작업:

  1. 의존성 추가: neo4j-graphrag[openai,experimental]==1.16.0 (버전 고정)
  2. APOC core 설치된 Neo4j 5.18.1+ 배포 (Docker compose 추가)
  3. platform/core/projection/rdf_to_neo4j.py 신설:
    • Fuseki의 Ontology + Facts graph → Neo4jGraph(nodes, relationships) 변환
    • KGWriterNeo4jWriter 사용해 upsert
    • Lexical graph(Document/Chunk) + Entity 노드를 LexicalGraphBuilder 표준에 맞춰 생성
  4. Chunk embedding:
    • OntoCast의 청킹 결과(ContentUnit.text)에 OpenAIEmbeddings 또는 SentenceTransformerEmbeddings 적용
    • Neo4j chunk vector index 자동 생성 (indexes.py)
  5. 검색 API 신설:
    • POST /search/vectorVectorRetriever
    • POST /search/hybridHybridRetriever
    • POST /search/text2cypherText2CypherRetriever (read-only 강제)
    • POST /search/graphragGraphRAG 답변 생성
  6. Text2Cypher 보안 (Neo4j GraphRAG 분석 §13.4):
    • read-only 검사 + 허용 schema 제한 + query timeout + result limit
  7. Entity Resolver:
    • SinglePropertyExactMatchResolver 기본 활성화
    • OntoCast Entity Aggregation 결과(owl:sameAs)와 함께 사용해 중복 병합

Acceptance Gate 4:

  • Fuseki commit 후 5초 이내 Neo4j projection 동기화 완료
  • Lexical graph(Document/Chunk/Entity)와 provenance(FROM_CHUNK) 정상 생성
  • Vector 검색 결과의 chunk → entity provenance 추적 가능
  • Text2Cypher가 write/delete 쿼리를 차단
  • GraphRAG 답변에 evidence chunk URL 포함
  • Phase 0~3 기능 회귀 없음

Phase 5: Neo4j GraphRAG 통합 & 검색/RAG

목표: 최종 RDF (또는 검증된 후보)를 Neo4j에 projection하고, Neo4j GraphRAG의 retriever/QA 기능으로 검색/RAG을 제공한다.

작업:

  1. 의존성 추가: neo4j-graphrag==1.16.0 (버전 고정)

  2. Projection 어댑터 (platform/core/projection/rdf_to_neo4j.py)

    • Fuseki RDF → Neo4j Property Graph 변환
    • Node: Entity (label, type, confidence)
    • Relationship: Predicate (confidence, evidence)
    • Chunk/Document: Lexical graph builder 활용
  3. Embedding & Vector Index

    • 최종 chunk → OpenAI/SentenceTransformer embedding
    • Neo4j vector index 자동 생성
  4. 검색 API 추가

    POST /search/vector         # Vector 검색
    POST /search/hybrid         # Vector + fulltext
    POST /search/graphrag       # QA (답변 + evidence)
    
  5. Text2Cypher 보안 (Phase 4 기존 내용 적용)

    • read-only 강제
    • allowlist schema
    • timeout + result limit

Acceptance Gate 5:

  • Fuseki commit 후 5초 이내 Neo4j projection 동기화
  • Vector 검색으로 chunk 찾고, entity/predicate 추적 가능
  • GraphRAG 답변에 evidence chunk + URL 포함
  • Text2Cypher가 write/delete 차단
  • Phase 0~4 기능 회귀 없음

6. 성능 최적화 전략

6.1 Fast Path vs Precision Path 분리

단계 Fast Path Precision Path (Optional)
추출 엔진 Lightweight JSON OntoCast RDF
처리 속도 10~30초 1~5분 (batch)
저장소 PostgreSQL/SQLite Fuseki RDF
용도 초벌 후보, 사람 검수 최종 canonical graph
비용 낮음 (LLM 1회) 높음 (Critic loop)

6.2 OntoCast 호출 최적화

❌ 하지 말아야 할 것:
- 모든 문서를 OntoCast에 넣기
- 문서 단위 호출
- 저신뢰 후보도 OntoCast 처리

✅ 해야 할 것:
- 검증된 후보만 선택
- batch 단위 호출 (10~50개)
- 사람 검수를 거친 데이터
- 병렬 배치 처리로 대기 시간 단축

6.3 메모리/비용 관리

  • LLM 캐싱: OntoCast의 기존 Cacher 활용
  • BudgetTracker: 월간/일일 한도 + 자동 차단
  • Worker 풀: Arq/Celery로 병렬 처리 (느린 OntoCast는 background로)

7. 이전 설계와의 차이점 요약

항목 기존 설계 수정 설계
Phase 0 OntoCast 전체 파이프라인 Fast JSON Extraction
초기 결과 RDF/OWL JSON (후보)
중간 단계 RDF → Fuseki 직접 저장 JSON → 사람 검수 → 선택적 OntoCast
OntoCast 역할 입력 처리의 중심 정밀 RDF 갱신의 선택지
처리 속도 느림 (전체 파이프라인) 빠름 (Phase 0~2)
실패 시 영향 전체 job 실패 Fast Pipeline은 계속 동작
테스트 용이성 어려움 (RDF 중심) 쉬움 (JSON 중간결과 명확)
대량 처리 부적합 적합 (비동기, 배치)

6. 상용 제품 수준 기능 명세 (Functional Spec)

기능 ID 체계: [영역코드]-[순번]. 영역코드: PROJ, ACQ, ONT, REV, SRCH, OPS, GOV.

6.1 프로젝트/멀티테넌트 관리 (PROJ)

ID 기능명 설명 우선순위
PROJ-001 온톨로지 프로젝트 생성 이름, 도메인, 기본 언어, 기본 타입 팩, Neo4j DB/Fuseki dataset 매핑 P0
PROJ-002 멤버/권한 관리 Owner/Admin/Editor/Reviewer/Viewer 역할 P0
PROJ-003 LLM Profile 선택 provider/model/api_key/temperature/max_tokens (Neo4j GraphRAG LLMConfig 차용) P0
PROJ-004 Embedding Profile 선택 provider/model/dimension (cohere/openai/sentence-transformers) P0
PROJ-005 비용 예산 설정 LLM call/token/검색 호출 일일·월간 한도 (OntoCast BudgetTracker 확장) P1
PROJ-006 프로젝트 fork/복제 기존 프로젝트의 스키마/설정만 복제 P2
PROJ-007 프로젝트 export/import 전체 RDF + 설정을 zip으로 export, import P1

6.2 데이터 수집 (ACQ)

ID 기능명 사용 컴포넌트 우선순위
ACQ-001 단일 URL scrape Crawl4AI fast_static + Trafilatura P0
ACQ-002 동적 페이지 scrape Crawl4AI dynamic_page P0
ACQ-003 사이트 deep crawl Crawl4AI deep_discovery (BFS/DFS/Best-First) P1
ACQ-004 sitemap/feed 발견 Trafilatura sitemap_search, find_feed_urls P1
ACQ-005 URL seeding 미리보기 Crawl4AI AsyncUrlSeeder P1
ACQ-006 파일 업로드 (PDF/DOCX/MD) Lightweight Extractor + docling (선택적 OntoCast 후처리 가능) P0
ACQ-007 배치 URL import (CSV) URL 목록 업로드 → 큐잉 P1
ACQ-008 중복 문서 dedup Trafilatura SimHash fingerprint P0
ACQ-009 도메인 allow/block list 프로젝트별 정책 DB P0
ACQ-010 robots.txt 준수 모드 strict/respect/ignore (감사 로그 필수) P0
ACQ-011 변경 감지 (changeTracking) 주기 재크롤 + fingerprint 비교 P2
ACQ-012 screenshot/PDF archive Crawl4AI full_capture Profile P2

6.3 온톨로지 구축 (ONT)

ID 기능명 사용 컴포넌트 우선순위
ONT-001 수동 스키마 작성 Neo4j GraphRAG GraphSchema 모델 그대로 사용 + UI P0
ONT-002 자동 스키마 추출 Neo4j GraphRAG SchemaFromTextExtractor 기반 + 선택적 OntoCast 보조 P0
ONT-003 자유 추출 OntoCast schema="FREE" 모드 P1
ONT-004 온톨로지 증분 갱신 OntoCast GraphUpdate SPARQL (핵심 차별 기능) P0
ONT-005 온톨로지 비평/재시도 OntoCast Critic loop + Guardrails P0
ONT-006 사실(facts) 추출 OntoCast RENDER_FACTS + Guardrails P0
ONT-007 Entity Aggregation OntoCast tool/agg/ (embedding clustering + URI 정규화 + owl:sameAs) P0
ONT-008 Entity Resolver (사후) Neo4j GraphRAG FuzzyMatchResolver + 검수 큐 P1
ONT-009 스키마 버전 관리 OntoCast GraphVersionManager + draft/published/deprecated P1
ONT-010 스키마 diff 뷰어 버전 간 class/property/pattern 변경 P1
ONT-011 스키마 마이그레이션 rename/merge/split + facts auto-migration P2
ONT-012 SHACL/OWL 검증 rdflib + owlready2 P2
ONT-013 다국어 label 관리 rdfs:label + lang tag (ko/en/...) P1

6.4 검수/승인 (REV)

ID 기능명 설명 우선순위
REV-001 추출 후보 큐 Renderer 결과를 Fuseki commit 전 검토용으로 저장 P0
REV-002 Evidence 하이라이트 entity/relation → FROM_CHUNK → 원문 텍스트 표시 (Neo4j GraphRAG lexical graph) P0
REV-003 단위 승인/반려 node/relationship/property 단위 P0
REV-004 Pruned 후보 검토 Neo4j GraphRAG GraphPruning에서 제거된 후보를 schema 후보로 제안 P1
REV-005 Merge 후보 검토 Resolver 후보 그룹의 시각화 + 승인/반려 P1
REV-006 일괄 승인 정책 confidence ≥ X + source 신뢰도 ≥ Y → 자동 승인 P1
REV-007 변경 이력 (audit) 누가/언제/무엇을/왜 변경 (RDF reification 또는 별도 audit log) P0
REV-008 롤백 특정 시점의 RDF graph로 복원 P2

6.5 검색/RAG (SRCH)

ID 기능명 사용 컴포넌트 우선순위
SRCH-001 Vector 검색 Neo4j GraphRAG VectorRetriever P0
SRCH-002 Hybrid 검색 (vector+fulltext) HybridRetriever P0
SRCH-003 Graph 확장 검색 VectorCypherRetriever (chunk → entity → neighbor) P0
SRCH-004 Text2Cypher (NL → Cypher) Text2CypherRetriever (read-only) P1
SRCH-005 SPARQL 직접 질의 Fuseki SPARQL endpoint (관리자 권한) P1
SRCH-006 GraphRAG QA GraphRAG + evidence URL 포함 P0
SRCH-007 Faceted 탐색 entity type/predicate별 filter P1
SRCH-008 Entity 상세 페이지 모든 property + 인입/인출 relation + evidence P0
SRCH-009 Subgraph 시각화 Neo4j Browser embed 또는 Cytoscape.js P1
SRCH-010 저장된 질의 (saved query) 즐겨찾기 + 알림 P2

6.6 운영/관측 (OPS)

ID 기능명 설명 우선순위
OPS-001 Job Queue/Worker 모든 비동기 작업의 큐잉/재시도/취소 P0
OPS-002 Job 진행률 스트리밍 WebSocket/SSE로 실시간 진행 P0
OPS-003 BudgetTracker LLM call/token/검색/크롤 호출 비용 추적 P0
OPS-004 LLM Response Cache OntoCast Cacher 그대로 사용 P0
OPS-005 Prometheus metrics Crawl4AI 분석 §16.4 패턴 P1
OPS-006 감사 로그 모든 RDF 변경 + 사용자 액션 P0
OPS-007 에러 알림 webhook + email + slack P1
OPS-008 백업/복구 Fuseki + Neo4j + Postgres 일관성 있는 백업 P1
OPS-009 멀티 환경 dev/staging/prod 분리 P0

6.7 거버넌스/보안 (GOV)

ID 기능명 설명 우선순위
GOV-001 인증 (OAuth2/OIDC) Google/GitHub/Azure AD P0
GOV-002 RBAC 프로젝트별 역할 (PROJ-002) P0
GOV-003 API Key 외부 시스템 연동용 P0
GOV-004 Rate Limiting 사용자별/IP별 P0
GOV-005 Text2Cypher 샌드박스 read-only + timeout + result limit + allowlist P0
GOV-006 비밀(secret) vault LLM API key 암호화 저장 P0
GOV-007 데이터 보존 정책 raw HTML/PDF 보존 기간 + zero-retention 모드 P1
GOV-008 라이선스/출처 표기 source별 license metadata 저장 + 결과에 노출 P1

7. 데이터 모델 표준 (Canonical Data Models)

본 절은 5개 소스를 잇기 위한 공통 데이터 계약이다. 모든 어댑터는 이 모델로 변환한다.

7.1 ContentUnit (문서 청크의 표준 표현)

class ContentUnit(BaseModel):
    id: str                       # UUID
    project_id: str
    source_id: str
    source_url: str | None        # canonical URL (Trafilatura)
    file_path: str | None
    document_type: Literal["html","pdf","markdown","docx","inline_text"]
    
    text: str                     # 정제된 본문
    body_xml: bytes | None        # Trafilatura Document.body (lxml serialized)
    markdown: str | None          # Crawl4AI markdown 또는 변환본
    
    chunk_index: int
    total_chunks: int
    
    title: str | None
    author: str | None
    publish_date: str | None      # ISO-8601
    language: str | None
    sitename: str | None
    
    fingerprint: str | None       # Trafilatura SimHash
    content_hash: str             # SHA-256 of text
    
    metadata: dict                # raw provider metadata
    retrieved_at: str             # ISO-8601
    extracted_by: str             # "crawl4ai+trafilatura"

7.2 OntologyExtractionResult (Guardrails 검증 대상)

Guardrails §15.5 그대로 채택. 위 §5 Phase 3 참조.

7.3 GraphUpdate (OntoCast 그대로)

OntoCast sparql_models.GraphUpdate를 그대로 사용. 변경 금지.

7.4 Job

class Job(BaseModel):
    id: str
    project_id: str
    type: Literal["scrape","crawl","extract","project","resolve","maintenance"]
    status: Literal["queued","running","paused","completed","failed","cancelled"]
    progress: float               # 0.0 ~ 1.0
    
    input: dict                   # 작업 입력 (URL, options, etc.)
    output: dict | None           # 결과 요약
    
    started_at: str | None
    finished_at: str | None
    
    budget: BudgetTracker         # OntoCast 그대로
    error: str | None
    audit_log_id: str

7.5 ReviewItem

class ReviewItem(BaseModel):
    id: str
    project_id: str
    job_id: str
    
    target_type: Literal["entity","relation","property","merge_group","prune_candidate"]
    target_data: dict             # 후보 데이터
    evidence: list[dict]          # chunk_id + text span
    
    confidence: float
    source_trust: float
    
    status: Literal["pending","approved","rejected","auto_approved"]
    decided_by: str | None        # user_id
    decided_at: str | None
    reason: str | None

8. API 표준 (RESTful, 일부 WebSocket)

전체는 OpenAPI 3.1 spec으로 별도 관리. 여기서는 핵심 endpoint만 명시.

Method Path 설명 인용 근거
POST /projects 프로젝트 생성 PROJ-001
GET /projects/{id} 프로젝트 조회 -
POST /projects/{id}/sources 데이터 소스 등록 ACQ
POST /projects/{id}/sources/{sid}/scrape 단일 URL scrape ACQ-001
POST /projects/{id}/sources/{sid}/crawl deep crawl ACQ-003
POST /projects/{id}/sources/{sid}/seed URL seeding preview ACQ-005
POST /projects/{id}/upload 파일 업로드 ACQ-006
GET /projects/{id}/schemas 스키마 목록 ONT-001
POST /projects/{id}/schemas 스키마 작성 ONT-001
POST /projects/{id}/schemas/extract 자동 스키마 추출 ONT-002
POST /projects/{id}/schemas/{sid}/publish 스키마 발행 ONT-009
POST /projects/{id}/process 문서 처리 (전체 OntoCast 워크플로우) OntoCast §13.3
GET /jobs/{job_id} Job 조회 OPS-001
GET /jobs/{job_id}/progress (WS) 진행률 스트리밍 OPS-002
POST /jobs/{job_id}/cancel Job 취소 OPS-001
GET /projects/{id}/review 검수 큐 REV-001
POST /projects/{id}/review/{rid}/approve 승인 REV-003
POST /projects/{id}/review/{rid}/reject 반려 REV-003
POST /projects/{id}/search/vector Vector 검색 SRCH-001
POST /projects/{id}/search/hybrid Hybrid 검색 SRCH-002
POST /projects/{id}/search/text2cypher NL → Cypher SRCH-004
POST /projects/{id}/search/graphrag QA SRCH-006
GET /projects/{id}/entities/{eid} Entity 상세 SRCH-008
POST /projects/{id}/maintenance/run 유지보수 루프 Phase 5

9. 어떤 코드를 어디서 가져오는가 (Module Map)

각 5개 소스에서 가져올 모듈을 정확히 명시. "그대로"=수정 금지, "어댑터"=얇은 래퍼만 작성.

9.1 OntoCast (Optional Precision RDF/OWL Engine)

가져올 모듈 방식 수정 사항
ontocast/onto/state.py (AgentState) 그대로 -
ontocast/onto/unit_states.py 그대로 -
ontocast/onto/sparql_models.py (GraphUpdate) 그대로 -
ontocast/onto/rdfgraph.py 그대로 -
ontocast/onto/ontology.py 그대로 -
ontocast/stategraph/ 그대로 Phase 5에서 노드 추가만
ontocast/agent/render_*.py 그대로 -
ontocast/agent/criticise_*.py 그대로 -
ontocast/agent/select_ontology.py 버그 수정 None index 불일치 (분석 §13.1)
ontocast/agent/convert_document.py 확장 다중 파일 처리 (분석 §13.1)
ontocast/tool/agg/ 그대로 -
ontocast/tool/triple_manager/ 그대로 -
ontocast/tool/llm.py 래핑 Guardrails Guard 통과 (Phase 3)
ontocast/tool/cache.py 그대로 -
ontocast/toolbox.py 그대로 -
ontocast/cli/serve.py (Robyn) 재작성 FastAPI로 (Phase 0)

9.2 Trafilatura

가져올 함수 방식
bare_extraction(output_format="python") 그대로 import
extract_metadata 그대로 import
sitemap_search 그대로 import
find_feed_urls 그대로 import
content_fingerprint, Simhash 그대로 import
trafilatura.meta.reset_caches 그대로 import (배치 종료 시 호출)

신규 어댑터: platform/core/extractors/web_extractor.py (§17 Trafilatura 분석의 extract_for_ontology 그대로)

9.3 Crawl4AI

가져올 클래스 방식
AsyncWebCrawler 그대로
BrowserConfig, CrawlerRunConfig, CacheMode 그대로
CrawlResult 그대로
LLMExtractionStrategy, JsonCssExtractionStrategy 그대로
BFSDeepCrawlStrategy, BestFirstCrawlingStrategy 그대로
AsyncUrlSeeder, SeedingConfig 그대로
MemoryAdaptiveDispatcher 그대로
Docker FastAPI 서버 코드 사용 안 함 (자체 FastAPI 사용)

신규 어댑터: platform/core/crawler/crawl4ai_adapter.py (Crawl4AI 분석 §21.1의 권장 계층 구조)

9.4 Guardrails

가져올 모듈 방식
guardrails.Guard.for_pydantic 그대로
guardrails.AsyncGuard 그대로
guardrails.classes.validation_outcome.ValidationOutcome 그대로
guardrails.actions.* 그대로
guardrails.types.on_fail.OnFailAction 그대로
guardrails.validator_base.Validator (커스텀 validator 작성용 base) 그대로
guardrails.hub.* 사용 안 함 (외부 통신 차단)
guardrails.telemetry.* 사용 안 함
guardrails.cli.* 사용 안 함

신규 작성: platform/core/validation/validators.py (Guardrails 분석 §15.4의 12개 validator)

9.5 Neo4j GraphRAG

가져올 클래스 방식
GraphSchema, NodeType, RelationshipType, Pattern, ConstraintType 그대로
SimpleKGPipeline 사용 안 함 (OntoCast 워크플로우가 우선)
LLMEntityRelationExtractor 사용 안 함 (OntoCast Renderer가 우선)
Neo4jWriter, Neo4jGraph, Neo4jNode, Neo4jRelationship 그대로 (Projection 용)
LexicalGraphBuilder 그대로
SinglePropertyExactMatchResolver, FuzzyMatchResolver 그대로
VectorRetriever, HybridRetriever, VectorCypherRetriever 그대로
Text2CypherRetriever 그대로 (read-only 강제)
GraphRAG 그대로
embeddings/*, llm/* 그대로 (선택적)

신규 어댑터: platform/core/projection/rdf_to_neo4j.py (Fuseki RDF → Neo4jGraph 변환)

9.6 Knowledge Agent (패턴/프롬프트만)

가져올 자산 방식
prompts/analyst_prompt.txt 수정 후 사용 (OntoCast OntologyExtractionResult 스키마에 맞춤)
prompts/planner_prompt.txt 수정 후 사용
prompts/refiner_prompt.txt 수정 후 사용
prompts/summarizer_prompt.txt 수정 후 사용
prompts/search_ranker_prompt.txt 수정 후 사용
prompts/ingester_prompt.txt 수정 후 사용
lightrag/prompt.py (엔티티/관계 추출 프롬프트) 참고만 (OntoCast Renderer가 이미 있음)
코드 전체 사용 안 함 (다수 버그 — 분석 §9.1)

10. 예상 리스크와 대응

리스크 영향 대응
OntoCast select_ontology.py 버그 워크플로우 실패 Phase 0에서 즉시 수정
Crawl4AI/Playwright 메모리 누수 운영 장애 max_pages_before_recycle 설정 + browser pool monitor
Trafilatura 전역 LRU cache 충돌 다중 테넌트에서 결과 오염 작업 단위 reset_caches()
Guardrails Hub 외부 통신 보안/네트워크 의존 Hub/telemetry 비활성화 환경변수 강제
Neo4j GraphRAG experimental API 변경 upstream 호환성 버전 고정 (==1.16.0) + 우리 코드는 어댑터로만 접근
Fuseki ↔ Neo4j 동기화 지연 검색 결과와 진실 불일치 "Last sync at" 표시 + 강제 동기화 API
LLM 비용 폭주 운영 비용 OPS-003 BudgetTracker 한도 + 자동 차단
Text2Cypher 인젝션 보안 read-only 강제 + allowlist + timeout (GOV-005)
robots.txt 위반 법적 리스크 ACQ-010 strict 모드 기본 + 감사 로그
라이선스 (특히 AGPL 회피) 배포 제약 Apache/MIT만 채택. Firecrawl 제외 결정 근거

11. 기술 스택 요약 (전체)

영역 선택
언어 Python 3.12+ (OntoCast 요구사항이 가장 높음)
API FastAPI (모든 통합 소스가 OpenAPI 친화)
LangGraph 워크플로우 OntoCast 기존 사용
Validation Pydantic v2 + Guardrails
비동기 asyncio (Crawl4AI/Trafilatura 모두 지원)
Job Queue Arq (Redis 기반, 가벼움) 또는 Celery (대규모)
메타데이터 DB PostgreSQL 16+
Canonical RDF Store Apache Jena Fuseki 5+
Property Graph Neo4j 5.18.1+ with APOC core
Object Storage S3 호환 (MinIO 로컬, AWS S3 운영)
캐시 Redis 7+
관측 OpenTelemetry + Prometheus + Grafana
컨테이너 Docker Compose (개발) / Kubernetes (운영)
인증 Authlib + OAuth2/OIDC
프론트엔드 (자유 선택, 권장 Next.js 14 + shadcn/ui)

12. 작업 단위 분해 (PR 단위)

각 Phase 내부에서 PR 단위로 쪼갠 예시.

Phase 0: Fast Extraction MVP

  • 0.1 Trafilatura 의존성 + web_extractor.py (본문/메타 추출)
  • 0.2 Crawl4AI 최소 adapter (정적 수집 우선)
  • 0.3 lightweight_extractor.py + 프롬프트 (JSON 출력)
  • 0.4 CandidateStore 테이블 정의 (PostgreSQL/SQLite)
  • 0.5 FastAPI /extract/url, /extract/file, /candidates endpoint
  • 0.6 단일 URL 테스트 (10~30초 내 결과)
  • 0.7 Acceptance Gate 0 확인

Phase 1: Fast Pipeline 품질 개선

  • 1.1 Pydantic 스키마 정의 (CandidateEntity/Relation)
  • 1.2 무의미한 후보 필터링 로직
  • 1.3 confidence/evidence 검증
  • 1.4 entity/relation endpoint 매칭 검사
  • 1.5 도메인별 type/predicate 설정 지원
  • 1.6 한국어 페이지 3종 테스트 (뉴스/블로그/쇼핑)
  • 1.7 Acceptance Gate 1 확인

Phase 2: Guardrails 검증 강화

  • 2.1 guardrails-ai 의존성 + 환경변수 설정 (Hub/telemetry 비활성화)
  • 2.2 Validator 작성 6종 (EntityIdFormat, UniqueEntityId, RelationEndpoint, ConfidenceRange, Evidence, NoSelfRelation)
  • 2.3 Guardrails Guard 통합 (Lightweight Extractor 후 검증)
  • 2.4 검증 실패 후보 → review queue로 이동
  • 2.5 Guardrails 로그 + 감사 기록
  • 2.6 Acceptance Gate 2 확인

Phase 3: Review & Approval 시스템

  • 3.1 Review UI (후보 목록 + evidence 하이라이트)
  • 3.2 승인/반려/수정 버튼
  • 3.3 ReviewStatus 테이블 관리
  • 3.4 자동 승인 정책 정의 (confidence ≥ 0.95)
  • 3.5 승인 이력 저장 (감사 로그)
  • 3.6 Acceptance Gate 3 확인

Phase 4: OntoCast 선택적 통합

  • 4.1 ontocast_adapter.py (Candidate JSON → OntoCast 입력 포맷)
  • 4.2 batch 단위 호출 (10~50개)
  • 4.3 OntoCast 처리 실패 → review queue (보존, 손실 없음)
  • 4.4 GraphUpdate → Fuseki commit (SPARQL UPDATE)
  • 4.5 BudgetTracker 연동 (OntoCast 호출 비용/시간 기록)
  • 4.6 Fast Pipeline 독립 검증 (OntoCast 없이도 동작)
  • 4.7 Acceptance Gate 4 확인

Phase 5: Neo4j GraphRAG & 검색

  • 5.1 neo4j-graphrag==1.16.0 + Docker compose
  • 5.2 rdf_to_neo4j.py (Fuseki RDF → Neo4j projection)
  • 5.3 Embedding + Vector index
  • 5.4 /search/vector, /search/hybrid endpoint
  • 5.5 /search/graphrag (QA + evidence)
  • 5.6 Text2Cypher 보안 (read-only)
  • 5.7 Fuseki commit hook → Neo4j async 동기화
  • 5.8 Acceptance Gate 5 확인

13. 다른 AI 에이전트를 위한 체크리스트

본 설계서를 받은 AI 에이전트가 작업을 시작하기 전 확인할 항목.

필수 확인

  • 본 문서의 §1~§12를 모두 읽었는가?
  • 설계 변경 배경 (§1.1)을 이해했는가? — OntoCast를 Phase 0 Base에서 선택적 엔진으로 변경한 이유
  • 작업할 Phase의 Acceptance Gate를 명확히 이해했는가?
  • Fast Path와 Precision Path의 차이를 이해했는가?

Phase별 확인

Phase 0: Fast Extraction MVP

  • OntoCast를 사용하지 않는다는 것을 확인했는가?
  • RDF/OWL 변환을 하지 않고 JSON만 생성하는 것을 확인했는가?
  • 처리 속도 목표 (10~30초)를 이해했는가?

Phase 1~3: Fast Pipeline 안정화

  • 이 단계에서도 OntoCast는 사용하지 않는가?
  • JSON 검증 및 사람 검수 과정을 이해했는가?

Phase 4: OntoCast 통합

  • OntoCast는 batch 후보 단위로 호출한다는 것을 확인했는가?
  • OntoCast 처리 실패 시에도 Fast Pipeline이 계속 동작한다는 것을 확인했는가?
  • GraphUpdate → Fuseki commit이 SPARQL 기반임을 확인했는가?

Phase 5: 검색/RAG

  • Neo4j는 Fuseki의 projection이라는 것을 확인했는가?
  • Text2Cypher는 read-only만 허용한다는 것을 확인했는가?

일반 원칙

  • "그대로 사용" 모듈을 수정하려 하고 있지 않은가?
  • "제외(Excluded)" 프로젝트의 코드를 가져오려 하고 있지 않은가? (Firecrawl, OpenDeepResearcher)
  • PR 설명에 어느 분석 자료의 어느 절을 근거로 했는지 명시할 준비가 되었는가?
  • 이전 Phase의 회귀 테스트가 통과하는지 확인할 계획이 있는가?
  • License 고지(Apache 2.0, MIT 등)가 포함되는가?

14. 마지막 한 마디

이번 설계 수정의 핵심

기존 설계는 이론적으로 완벽했지만, 실제 구현 결과는 다음 문제가 있었다:

OntoCast 중심 아키텍처
→ 처리 속도 느림 (초기 테스트부터 지연)
→ 중간 결과 확인 어려움 (RDF 중심)
→ 대량 처리에 부적합 (비용 폭주)
→ 버그 가능성 높음 (무거운 파이프라인)

따라서 설계를 다음과 같이 수정했다:

Fast Path (기본)         Precision Path (선택)
가벼운 JSON 추출    →    승인된 후보만
Pydantic 검증     →    OntoCast 정밀화
사람 검수         →    RDF/OWL 저장

최종 구조 한 문장

OntoCast는 입력 처리 엔진이 아니라, 검증된 후보를 RDF로 정밀 반영하는 고급 엔진이다.

이점

기존 수정
모든 문서 → OntoCast 검증된 후보만 → OntoCast
초기부터 느림 Fast Path로 빠른 피드백
중간 과정 불명확 JSON 후보로 명확한 단계
OntoCast 실패 = 전체 실패 Fast Pipeline은 독립 동작
대량 처리 어려움 batch 단위 + 비동기 처리

작업 방향

다음 Phase부터 이 수정된 설계를 따른다. 특히:

  1. Phase 0에서 OntoCast를 사용하지 않는다.
  2. JSON 기반 후보 추출에 집중한다.
  3. 검증된 후보만 OntoCast에 전달한다.
  4. 각 Phase는 이전 Phase 없이 독립적으로 테스트 가능해야 한다.

이 원칙을 지키면, 더 안정적이고, 빠르고, 확장 가능한 온톨로지 구축 플랫폼을 만들 수 있다.