Files
AI/오픈소스분석자료/Neo4j_GraphRAG_분석_및_기능명세.md
LASTA_DEV01\lasta 9e88f4c7ad ontology
2026-05-13 19:57:34 +09:00

39 KiB

Neo4j GraphRAG Python 분석 및 기능명세

분석 대상: C:\Users\lasta\MyProject\AI\참고\neo4j-graphrag-python-main
분석일: 2026-05-13
프로젝트 버전: neo4j-graphrag 1.16.0
라이선스: Apache License 2.0 계열(LICENSE.APACHE2.txt, LICENSE.txt)
목표: 범용 온톨로지 구축 플랫폼의 기본 소스로 거의 변형 없이 재사용 가능한 기능과, 플랫폼 레이어에서 감싸야 할 기능을 식별한다.

1. 총평

neo4j-graphrag-python은 Neo4j가 공식 제공하는 GraphRAG Python 패키지이며, 단순 질의응답 RAG보다 “비정형 문서 → 스키마/온톨로지 후보 → 엔티티/관계 추출 → 그래프 정제 → Neo4j 저장 → 검색/질의응답” 흐름에 더 강하다.

우리 프로젝트가 지향하는 “범용 온톨로지 구축 플랫폼” 관점에서는 다음 모듈이 가장 중요하다.

영역 재사용 판단 핵심 소스
KG 구축 파이프라인 높음 experimental/pipeline/kg_builder.py, config/template_pipeline/simple_kg_builder.py
컴포넌트형 파이프라인 엔진 높음 experimental/pipeline/pipeline.py, component.py, orchestrator.py
온톨로지/그래프 스키마 모델 매우 높음 experimental/components/schema.py
스키마 자동 추출 높음 experimental/components/schema.py, graph_schema_extraction.py
엔티티/관계 추출 높음 experimental/components/entity_relation_extractor.py
그래프 정제/스키마 준수 높음 experimental/components/graph_pruning.py
Neo4j 저장 높음 experimental/components/kg_writer.py, neo4j_queries.py
엔티티 중복 해소 중간~높음 experimental/components/resolver.py
검색/RAG 높음 retrievers/*, generation/graphrag.py
LLM/임베딩 어댑터 높음 llm/*, embeddings/*
문서 로더 중간 experimental/components/data_loader.py
외부 벡터DB 연동 선택 retrievers/external/*

단, experimental 네임스페이스의 KG 구축 기능은 공식 문서상 API 변경 가능성이 있는 실험 기능이다. “그대로 복사”보다는 패키지 의존성으로 고정 버전을 사용하고, 우리 플랫폼의 안정 API를 별도 래퍼로 제공하는 방식이 안전하다.

2. 프로젝트 구조

src/neo4j_graphrag/
  embeddings/                 # OpenAI, Azure OpenAI, Ollama, VertexAI, Cohere, Bedrock, Mistral, SentenceTransformer 임베딩
  llm/                        # OpenAI, Azure, Ollama, VertexAI, Anthropic, Cohere, Bedrock, Mistral LLM
  retrievers/                 # Vector, Hybrid, Text2Cypher, Tools, Vector+Cypher 검색기
  generation/                 # GraphRAG, 프롬프트 템플릿, RAG 결과 타입
  experimental/
    components/               # KG 구축 컴포넌트: loader, splitter, schema, extractor, pruner, writer, resolver
    pipeline/                 # 비동기 DAG 파이프라인 엔진, 설정 파일 실행기
  indexes.py                  # Neo4j 벡터/풀텍스트 인덱스 생성, 벡터 upsert
  schema.py                   # 기존 Neo4j DB 스키마 조회/포맷팅/Text2Cypher용 스키마 생성
  filters.py                  # 검색 필터 DSL → Cypher 변환
  message_history.py          # InMemory/Neo4j 대화 기록
  tool.py                     # LLM tool schema 추상화

테스트 구조는 tests/unit, tests/e2e가 분리되어 있고, Neo4j/Weaviate/Pinecone/Qdrant 연동 E2E가 있다. 핵심 동작은 테스트가 비교적 넓게 잡혀 있어 베이스 소스로 신뢰도가 높다.

3. 의존성 및 실행 조건

3.1 기본 요구사항

  • Python: >=3.10,<3.15
  • Neo4j Python driver: neo4j>=5.17,<7
  • Pydantic v2
  • pypdf, fsspec, json-repair, pyyaml, numpy, scipy, tenacity

3.2 Neo4j 요구사항

  • Neo4j >=5.18.1
  • Neo4j Aura >=5.18.0
  • Neo4j 2026.01+: SEARCH clause 기반 in-index filtering 지원
  • KG writer 및 entity resolver 일부 기능은 APOC 필요
    • README의 KG construction 예시는 APOC core 설치를 요구한다.
    • SinglePropertyExactMatchResolver, similarity resolver는 apoc.refactor.mergeNodes를 사용한다.

3.3 선택 의존성

Extra 용도
openai OpenAI/Azure OpenAI LLM 및 임베딩
ollama 로컬 Ollama LLM/임베딩
google Vertex AI
cohere Cohere
anthropic Anthropic
mistralai Mistral AI
bedrock AWS Bedrock
sentence-transformers 로컬 임베딩
experimental KG 구축 파이프라인, LlamaIndex/LangChain splitter, Parquet
nlp spaCy resolver. Python 3.14에서는 미지원
fuzzy-matching RapidFuzz 기반 중복 해소
weaviate, pinecone, qdrant 외부 벡터DB retriever

4. 핵심 아키텍처

4.1 전체 흐름

flowchart LR
    A["문서/텍스트 입력"] --> B["DataLoader"]
    B --> C["TextSplitter"]
    C --> D["TextChunkEmbedder"]
    C --> E["SchemaBuilder 또는 SchemaFromTextExtractor"]
    E --> F["LLMEntityRelationExtractor"]
    C --> F
    F --> G["GraphPruning"]
    G --> H["KGWriter: Neo4jWriter 또는 ParquetWriter"]
    H --> I["EntityResolver"]
    I --> J["Neo4j Knowledge Graph"]
    J --> K["Retriever: Vector/Hybrid/Text2Cypher"]
    K --> L["GraphRAG"]

4.2 설계 철학

이 프로젝트는 “하나의 거대한 KG builder”가 아니라 비동기 컴포넌트 DAG를 조립하는 방식이다.

  • 각 컴포넌트는 Component를 상속한다.
  • 컴포넌트의 run은 Pydantic DataModel을 반환한다.
  • Pipeline.connect()로 이전 컴포넌트 출력 필드를 다음 컴포넌트 입력으로 매핑한다.
  • PipelineRunner는 JSON/YAML 설정 파일로 파이프라인을 복원하고 실행한다.
  • SimpleKGPipeline은 대표적인 템플릿 파이프라인이다.

우리 플랫폼에서는 이 구조를 그대로 “워크플로우 엔진”으로 활용할 수 있다. 별도 GUI나 API 서버에서는 SimpleKGPipeline 설정을 생성하고 실행 결과를 추적하는 레이어를 만들면 된다.

5. 데이터 모델 명세

5.1 문서 모델

DocumentInfo

필드 타입 설명
path str 파일 경로 또는 inline text 식별자
metadata dict[str,str] | None 문서 메타데이터. Document 노드 property로 저장
uid str UUID 기본 생성. Document id
document_type pdf, markdown, inline_text 문서 유형

LoadedDocument

필드 타입 설명
text str 추출된 원문
document_info DocumentInfo 문서 식별/메타데이터

5.2 텍스트 청크 모델

TextChunk

필드 타입 설명
text str 청크 텍스트
index int 원문 내 순서
metadata dict[str,Any] | None 청크 메타데이터. embedding이 있으면 별도 embedding property로 분리
uid str UUID 기본 생성

TextChunks

필드 타입 설명
chunks list[TextChunk] 청크 목록

5.3 그래프 모델

Neo4jNode

필드 타입 설명
id str 내부 관계 연결용 id
label str Neo4j label
properties dict[str, PropertyValue] Neo4j property
embedding_properties dict[str, list[float]] 벡터 property

Neo4jRelationship

필드 타입 설명
start_node_id str 시작 노드 id
end_node_id str 끝 노드 id
type str relationship type
properties dict[str, PropertyValue] relationship property
embedding_properties dict[str, list[float]] relationship vector property

Neo4jGraph

필드 타입 설명
nodes list[Neo4jNode] 노드 목록
relationships list[Neo4jRelationship] 관계 목록

5.4 Lexical graph 설정

LexicalGraphConfig 기본값:

설정 기본값 의미
document_node_label Document 문서 노드 label
chunk_node_label Chunk 청크 노드 label
chunk_to_document_relationship_type FROM_DOCUMENT Chunk → Document
next_chunk_relationship_type NEXT_CHUNK Chunk → 다음 Chunk
node_to_chunk_relationship_type FROM_CHUNK Entity → Chunk
chunk_id_property id chunk id property
chunk_index_property index chunk 순서 property
chunk_text_property text chunk 본문 property
chunk_embedding_property embedding chunk embedding property

온톨로지 플랫폼에서는 이 설정을 테넌트/프로젝트 단위로 고정하거나, 사용자가 “문서 그래프 모델”을 커스터마이즈할 수 있게 노출하면 된다.

6. 온톨로지/스키마 모델 명세

핵심 파일: src/neo4j_graphrag/experimental/components/schema.py

6.1 PropertyType

필드 타입 설명
name str property 이름
type Neo4j property type literal STRING, INTEGER, FLOAT, BOOLEAN, DATE, LOCAL_DATETIME, POINT, LIST
description str LLM 추출 가이드
required bool deprecated. 존재 제약은 ConstraintType(EXISTENCE) 권장

6.2 NodeType

필드 타입 설명
label str 노드 label
description str 의미 설명
properties list[PropertyType] 허용 property. 최소 1개
additional_properties bool 스키마 외 property 허용 여부

특이 동작:

  • 문자열 "Person"으로 입력하면 {label:"Person", properties:[{name:"name", type:"STRING"}], additional_properties:true}로 자동 변환된다.
  • label이 __로 시작하거나 끝나면 내부 예약 label로 보고 거부한다.

6.3 RelationshipType

필드 타입 설명
label str relationship type
description str 의미 설명
properties list[PropertyType] 관계 property
additional_properties bool 스키마 외 property 허용 여부

문자열 "WORKS_AT" 입력도 허용된다.

6.4 ConstraintType

지원 제약:

타입 의미
UNIQUENESS 노드 property unique. 복합 가능
EXISTENCE 노드/관계 property 필수. 단일 property
KEY Neo4j node key/relationship key. 필수 + unique. 복합 가능

범용 온톨로지 플랫폼에서는 이 모델을 “온톨로지 제약조건”의 기본 표현으로 재사용할 수 있다. 다만 OWL/RDFS의 class hierarchy, domain/range, cardinality, inverse property, equivalent class 같은 의미론적 제약은 별도 확장이 필요하다.

6.5 Pattern

Pattern(source node label, relationship label, target node label) 구조를 표현한다. 예:

("Person", "WORKS_AT", "Organization")

이것은 ontology의 relationship domain/range 후보로 직접 매핑 가능하다.

6.6 GraphSchema

GraphSchema는 다음 정보를 묶는다.

  • node_types
  • relationship_types
  • patterns
  • constraints
  • additional_node_types
  • additional_relationship_types
  • additional_patterns

스키마가 제공되면 LLM 추출 프롬프트의 grounding 정보가 되고, 이후 GraphPruning이 이 스키마에 맞지 않는 노드/관계/property를 제거한다.

7. KG 구축 기능명세

7.1 SimpleKGPipeline

파일: experimental/pipeline/kg_builder.py

SimpleKGPipeline은 비정형 텍스트나 PDF/Markdown 파일에서 KG를 만들기 위한 고수준 API이다.

생성자 입력

파라미터 필수 설명
llm 엔티티/관계 추출용 LLM
driver Neo4j driver
embedder chunk embedding 생성기
schema 아니오 GraphSchema, dict, "FREE", "EXTRACTED", None
from_file 아니오 True: file path 입력. False: text 입력
text_splitter 아니오 기본 FixedSizeSplitter
file_loader 아니오 기본 extension 기반 PDF/Markdown loader
kg_writer 아니오 기본 Neo4jWriter
on_error 아니오 "IGNORE" 또는 "RAISE"
perform_entity_resolution 아니오 기본 True
prompt_template 아니오 추출 프롬프트 템플릿
lexical_graph_config 아니오 Document/Chunk 그래프 label/relationship 커스터마이즈
neo4j_database 아니오 Neo4j database 이름

실행 입력

run_async(file_path=None, text=None, document_metadata=None)

입력 조건 설명
file_path from_file=True일 때 필요 PDF/Markdown 파일 경로
text from_file=False일 때 필요 직접 입력 텍스트
document_metadata 선택 Document node property로 저장

스키마 모드

모드 설정 동작
자동 추출 schema=None 또는 "EXTRACTED" 입력 텍스트에서 LLM으로 스키마를 한 번 추출한 뒤 전체 chunk 추출에 사용
자유 추출 schema="FREE" 또는 empty schema 스키마 없이 엔티티/관계 추출
고정 스키마 dict 또는 GraphSchema 사용자가 정의한 온톨로지 구조에 맞춰 추출

범용 온톨로지 플랫폼에서는 세 모드를 다음 UI/API로 제공하는 것이 적합하다.

  • “자동 온톨로지 초안 생성”
  • “스키마 없이 자유 그래프 생성”
  • “승인된 온톨로지에 맞춰 인스턴스 추출”

7.2 DataLoader

파일: experimental/components/data_loader.py

제공 구현:

  • PdfLoader: PDF 텍스트 추출
  • MarkdownLoader: Markdown 텍스트 로드
  • 내부 extension 기반 loader: .pdf, .md, .markdown

기능명세:

기능 입력 출력 비고
PDF 로드 filepath, metadata LoadedDocument pypdf 사용
Markdown 로드 filepath, metadata LoadedDocument plain text로 처리
문서 메타데이터 생성 path, metadata DocumentInfo Document node에 연결

확장 필요:

  • HTML, DOCX, PPTX, XLSX, CSV, 웹 크롤링 결과, API 문서 등 우리 프로젝트 입력 소스에 맞춘 loader 추가
  • 이미 우리 프로젝트에 crawler가 있으므로 crawler output을 LoadedDocument로 변환하는 adapter 필요

7.3 TextSplitter

제공 구현:

  • FixedSizeSplitter
  • LangChainTextSplitterAdapter
  • LlamaIndexTextSplitterAdapter

기능명세:

기능 입력 출력 비고
고정 길이 chunking text, chunk_size, overlap TextChunks approximate=True이면 단어 중간 절단 회피
LangChain splitter 감싸기 LangChain splitter TextChunks 기존 생태계 활용
LlamaIndex splitter 감싸기 LlamaIndex splitter TextChunks 기존 생태계 활용

온톨로지 플랫폼에서는 도메인별 chunking 전략이 중요하다.

  • 법령/규정: 조문 단위
  • 논문: section/paragraph 단위
  • 사내 문서: heading hierarchy 유지
  • 웹 문서: URL, heading, DOM 경로 메타데이터 유지

따라서 기본 splitter는 재사용하되, “구조 보존 splitter”를 별도 컴포넌트로 추가하는 것이 좋다.

7.4 TextChunkEmbedder

파일: experimental/components/embedder.py

기능:

  • TextChunks의 각 chunk text를 embedder로 임베딩한다.
  • 임베딩을 chunk metadata의 embedding에 저장한다.
  • LexicalGraphBuilderembedding metadata를 chunk node의 embedding_properties로 분리한다.

재사용 판단: 높음. 단, 대량 문서 처리에서는 batch embedding, rate limit, retry, cache가 플랫폼 레이어에 필요하다.

7.5 SchemaBuilder / SchemaFromTextExtractor

파일: experimental/components/schema.py, graph_schema_extraction.py

기능:

  • 수동 schema dict 또는 GraphSchema를 검증한다.
  • 텍스트에서 자동으로 node type, relationship type, pattern, constraint 후보를 추출한다.
  • OpenAI/VertexAI 등 structured output 지원 LLM에서는 JSON schema 기반 구조화 출력을 사용한다.
  • 기존 Neo4j graph에서 schema를 읽어 schema 후보로 만들 수 있다.

기능명세:

기능 입력 출력
수동 스키마 검증 node types, relationship types, patterns, constraints GraphSchema
자동 스키마 추출 text/chunks, LLM, prompt GraphSchema
기존 graph 스키마 추출 Neo4j driver GraphSchema 후보
schema visualization GraphSchema 시각화 graph

우리 플랫폼 확장 포인트:

  • 스키마 버전 관리
  • 자동 추출 schema의 승인/반려 workflow
  • label/property 표준화 규칙
  • 한국어 label/영문 label alias 관리
  • 온톨로지 class hierarchy 확장

7.6 LLMEntityRelationExtractor

파일: experimental/components/entity_relation_extractor.py

기능:

  • 각 chunk에 대해 LLM으로 Neo4jGraph(nodes, relationships)를 추출한다.
  • chunk별 node id에 chunk UUID prefix를 붙여 충돌을 방지한다.
  • create_lexical_graph=True이면 Document/Chunk graph와 Entity → Chunk provenance 관계를 함께 생성한다.
  • JSON repair를 사용해 깨진 JSON 응답을 복구한다.
  • on_error=IGNORE이면 실패 chunk는 빈 graph로 처리한다.
  • on_error=RAISE이면 LLM/JSON 오류를 예외로 올린다.
  • max_concurrency로 LLM 호출 동시성을 제한한다.
  • structured output 지원 LLM이면 Neo4jGraph Pydantic 모델을 response schema로 사용할 수 있다.

기능명세:

기능 입력 출력 중요 옵션
chunk별 엔티티/관계 추출 TextChunks, GraphSchema, examples Neo4jGraph max_concurrency
lexical graph 생성 chunks, document_info Document/Chunk 포함 graph create_lexical_graph
출처 연결 extracted entity, chunk FROM_CHUNK 관계 provenance 핵심
오류 처리 LLM JSON 오류 빈 graph 또는 예외 on_error

온톨로지 플랫폼에서 매우 중요한 특성:

  • 모든 추출 엔티티가 chunk와 연결되므로 근거 추적이 가능하다.
  • 추출 결과를 바로 DB에 쓰기 전에 GraphPruning으로 스키마 위반을 제거할 수 있다.
  • 추출 결과를 사용자가 승인하는 “검수 큐”를 만들려면 Neo4jWriter 이전에 graph를 저장/표시하는 컴포넌트를 끼우면 된다.

7.7 GraphPruning

파일: experimental/components/graph_pruning.py

기능:

  • 추출 graph가 GraphSchema를 준수하도록 노드/관계/property를 제거한다.
  • lexical graph(Document/Chunk)는 별도로 보존한다.
  • pruning 통계를 반환한다.

제거 사유:

사유 의미
NOT_IN_SCHEMA 스키마에 없는 node/relationship/property
MISSING_REQUIRED_PROPERTY 필수 property 누락
NO_PROPERTY_LEFT 유효 property가 하나도 없음
INVALID_START_OR_END_NODE 관계의 양 끝 노드가 유효하지 않음
INVALID_PATTERN 허용 pattern이 아님
MISSING_LABEL label 없음

기능명세:

기능 입력 출력
노드 정제 graph, schema 유효 node 목록
관계 정제 graph, schema, valid nodes 유효 relationship 목록
property 정제 node/relationship properties 스키마에 맞는 property만 유지
통계 생성 pruning 결과 PruningStats

우리 플랫폼에서는 pruning 결과를 “자동 폐기”만 하지 말고, 사용자에게 “추출됐지만 온톨로지에서 거부된 후보”로 보여주는 기능이 필요하다. 이것이 온톨로지 개선 루프의 핵심 데이터가 된다.

7.8 LexicalGraphBuilder

파일: experimental/components/lexical_graph.py

생성 그래프:

flowchart LR
    C1["Chunk 0"] -->|FROM_DOCUMENT| D["Document"]
    C2["Chunk 1"] -->|FROM_DOCUMENT| D
    C1 -->|NEXT_CHUNK| C2
    E1["Entity"] -->|FROM_CHUNK| C1

기능명세:

기능 생성물 설명
Document node Document path, createdAt, metadata, document_type
Chunk node Chunk text, index, metadata, embedding
Chunk → Document FROM_DOCUMENT 문서 소속
Chunk → Chunk NEXT_CHUNK 원문 순서
Entity → Chunk FROM_CHUNK 추출 근거

온톨로지 플랫폼에서는 이 provenance 구조를 거의 그대로 사용하면 된다. 다만 문서 소스가 crawler/web이면 Document node에 url, crawl_job_id, source_type, retrieved_at, content_hash 같은 property를 추가하는 것이 좋다.

7.9 KGWriter

파일: experimental/components/kg_writer.py

제공 구현:

  • Neo4jWriter
  • ParquetWriter

Neo4jWriter

기능:

  • node batch upsert
  • relationship batch upsert
  • non-lexical node에 __Entity__ label 추가
  • 임시 내부 id index 생성
  • write 이후 임시 label/property 정리
  • Neo4j 버전에 따라 dynamic label 및 variable scope clause 지원 여부 분기

중요 파라미터:

파라미터 기본값 설명
driver 필수 Neo4j driver
neo4j_database None DB 이름
batch_size 1000 batch write 크기
clean_db True writer 내부 임시 데이터 정리

출력:

{
  "status": "SUCCESS",
  "metadata": {
    "statistics": {
      "node_count": 0,
      "relationship_count": 0,
      "nodes_per_label": {},
      "rel_per_type": {},
      "input_files_count": 0,
      "input_files_total_size_bytes": 0
    },
    "files": []
  }
}

ParquetWriter

기능:

  • node label별 Parquet 파일 생성
  • (head_label, relationship_type, tail_label)별 relationship Parquet 파일 생성
  • schema constraints를 metadata로 반영
  • Neo4j bulk import 또는 데이터 레이크 연계를 위한 중간 산출물 생성

재사용 판단:

  • 실시간/소규모 구축: Neo4jWriter
  • 대량 batch/검수/승인 workflow: ParquetWriter 또는 custom writer 권장

7.10 EntityResolver

파일: experimental/components/resolver.py

제공 구현:

Resolver 방식 의존성
SinglePropertyExactMatchResolver 같은 label + 같은 property 값이면 merge APOC
SpaCySemanticMatchResolver property text embedding cosine similarity spaCy, numpy, APOC
FuzzyMatchResolver RapidFuzz string similarity rapidfuzz, APOC

기능명세:

기능 설명
대상 선택 기본 MATCH (entity:__Entity__), filter_query로 scope 축소
label별 그룹화 __Entity__, __KGBuilder__ 제외
property 비교 기본 name, 다중 property 가능
merge apoc.refactor.mergeNodes(..., {properties:'discard', mergeRels:true})
통계 resolve 대상 수, 생성/merge 결과 수

주의:

  • 기본 merge 정책은 property 충돌 시 discard이다.
  • 온톨로지 플랫폼에서는 자동 merge 전 “후보 그룹 검수” 기능이 필요하다.
  • 한국어/영문 alias, 약어, 조직명 변형 처리에는 custom resolver가 필요하다.

8. RAG 및 검색 기능명세

8.1 VectorRetriever

파일: retrievers/vector.py

기능:

  • Neo4j vector index 기반 ANN 검색
  • query_text 입력 시 embedder로 vector 생성
  • query_vector 직접 입력 가능
  • top_k, effective_search_ratio, metadata filters 지원
  • return_properties 또는 result_formatter로 반환 형식 커스터마이즈
  • Neo4j 2026.01+에서는 SEARCH clause와 filterable properties 활용 가능

8.2 VectorCypherRetriever

기능:

  • vector 검색 결과를 시작점으로 custom Cypher traversal 수행
  • “유사 chunk 검색 후 주변 entity/관계 확장” 패턴에 적합

온톨로지 플랫폼에서 매우 유용한 검색:

  • 특정 문장과 유사한 chunk를 찾고, 해당 chunk에서 추출된 entity와 ontology class를 함께 반환
  • 사용자의 질의와 관련된 provenance, source document, neighbor graph를 함께 표시

8.3 HybridRetriever / HybridCypherRetriever

기능:

  • vector search + fulltext search 결합
  • ranker 지원
  • Cypher 확장형 retriever 제공

사용처:

  • 고유명사/코드/제품명은 fulltext가 강하고, 의미 검색은 vector가 강하다.
  • 온톨로지 탐색 UI에서는 hybrid 검색을 기본으로 두는 것이 좋다.

8.4 Text2CypherRetriever

파일: retrievers/text2cypher.py

기능:

  • 자연어 질의를 LLM으로 Cypher로 변환
  • 기존 Neo4j schema를 자동 조회하거나 수동 schema 입력
  • few-shot examples 제공 가능
  • 생성 Cypher에서 코드블록 추출, 공백 포함 label/property/type backtick 보정
  • read-only query type만 허용하는 안전장치가 있다.

주의:

  • 운영 환경에서는 사용자 권한별 schema 제한, allowlist, query timeout, result limit이 필요하다.
  • ontology 관리 기능에 직접 연결할 경우 쓰기 쿼리는 별도 승인된 API로만 처리해야 한다.

8.5 ToolsRetriever

기능:

  • 여러 tool/retriever를 LLM tool calling 방식으로 선택하게 한다.
  • 질의 유형별로 vector/hybrid/text2cypher/custom tool을 라우팅하는 데 적합하다.

8.6 External Retriever

지원:

  • Weaviate
  • Pinecone
  • Qdrant

패턴:

  • 외부 vector DB에서 vector 검색
  • 검색 결과 id를 Neo4j graph와 join

우리 프로젝트가 Neo4j 중심이면 초기에는 보류 가능하다. 다만 대규모 벡터 검색을 별도 인프라로 분리할 가능성이 있으면 adapter 구조는 참고 가치가 높다.

8.7 GraphRAG

파일: generation/graphrag.py

기능:

  1. retriever로 context 검색
  2. prompt template에 query/context/examples 주입
  3. LLM 호출
  4. answer 반환
  5. 옵션으로 retriever context 포함 반환
  6. message history가 있으면 질의에 대화 요약을 결합

입력:

파라미터 설명
query_text 사용자 질문
message_history 대화 기록
examples few-shot 예시
retriever_config retriever별 옵션. 예: top_k
return_context 검색 결과 포함 여부
response_fallback 검색 결과가 없을 때 fallback 답변

우리 플랫폼 적용:

  • “온톨로지 기반 질의응답”
  • “이 entity가 어디서 나왔는가?”
  • “이 class와 관련된 문서/근거/관계는?”
  • “스키마에 맞지 않아 버려진 후보는?”

9. LLM 및 임베딩 어댑터

9.1 LLM

지원 구현:

  • OpenAILLM, AzureOpenAILLM
  • OllamaLLM
  • VertexAILLM
  • AnthropicLLM
  • CohereLLM
  • MistralAILLM
  • BedrockLLM

공통 특성:

  • LLMInterface, LLMInterfaceV2, LLMBase
  • sync/async invoke
  • structured output 일부 지원
  • rate limit retry 기본 내장
    • max attempts: 3
    • min wait: 1s
    • max wait: 60s
    • multiplier: 2

9.2 임베딩

지원 구현:

  • OpenAIEmbeddings, AzureOpenAIEmbeddings
  • OllamaEmbeddings
  • VertexAIEmbeddings
  • CohereEmbeddings
  • MistralAIEmbeddings
  • BedrockEmbeddings
  • SentenceTransformerEmbeddings

우리 프로젝트는 provider 독립성이 중요하므로 이 어댑터 계층은 거의 그대로 사용 가능하다. 플랫폼 설정에는 “LLM profile”, “Embedding profile” 개념을 두고, pipeline 실행 시 profile을 주입하는 구조가 좋다.

10. 설정 파일 기반 실행

PipelineRunner.from_config_file(file_path)로 JSON/YAML 파이프라인 실행이 가능하다.

기본 SimpleKGPipeline 설정 예:

version_: 1
template_: SimpleKGPipeline
neo4j_config:
  params_:
    uri: bolt://localhost:7687
    user: neo4j
    password:
      resolver_: ENV
      var_: NEO4J_PASSWORD
llm_config:
  class_: OpenAILLM
  params_:
    model_name: gpt-5
    api_key:
      resolver_: ENV
      var_: OPENAI_API_KEY
    model_params:
      temperature: 0
      max_tokens: 2000
embedder_config:
  class_: OpenAIEmbeddings
  params_:
    model: text-embedding-3-large
schema:
  node_types:
    - Person
    - label: Organization
      properties:
        - name: name
          type: STRING
  relationship_types:
    - WORKS_AT
  patterns:
    - ["Person", "WORKS_AT", "Organization"]
from_file: true
perform_entity_resolution: true
on_error: IGNORE

우리 플랫폼에서는 이 설정을 DB에 저장하고, GUI/API에서 생성/수정/버전 관리하도록 만들면 된다.

11. 범용 온톨로지 구축 플랫폼 적용 설계

11.1 그대로 재사용할 1차 기반

플랫폼 기능 사용할 소스
문서 → KG 실행 SimpleKGPipeline
커스텀 워크플로우 Pipeline, Component
온톨로지 스키마 표현 GraphSchema, NodeType, RelationshipType, Pattern, ConstraintType
자동 온톨로지 초안 SchemaFromTextExtractor
엔티티/관계 추출 LLMEntityRelationExtractor
스키마 정합성 검증 GraphPruning
Neo4j 저장 Neo4jWriter
출처 그래프 LexicalGraphBuilder
중복 엔티티 병합 SinglePropertyExactMatchResolver, FuzzyMatchResolver
검색/QA VectorRetriever, HybridRetriever, Text2CypherRetriever, GraphRAG

11.2 플랫폼에서 추가해야 할 레이어

A. 프로젝트/테넌트 관리

  • 온톨로지 프로젝트 생성
  • 데이터소스 연결
  • Neo4j database 또는 namespace 매핑
  • LLM/embedding profile 매핑

B. 온톨로지 버전 관리

현재 GraphSchema는 schema 객체일 뿐 버전 관리 기능은 없다.

필요 기능:

  • schema draft/published 상태
  • version number
  • 변경 diff
  • migration plan
  • label/property rename 이력
  • 이전 버전 추출 결과와 새 버전 비교

C. 추출 결과 검수

현재 pipeline은 추출 후 pruning/write까지 자동으로 갈 수 있다.

필요 기능:

  • 추출 graph 임시 저장
  • node/relationship/property 단위 승인/반려
  • pruning된 후보 복원/스키마 반영
  • confidence score 또는 LLM rationale 저장
  • 근거 chunk 하이라이트

D. 도메인별 document loader

추가 대상:

  • crawler output loader
  • HTML loader
  • DOCX/PPTX/XLSX loader
  • CSV/DB table loader
  • API response loader
  • code/documentation loader

E. Ontology semantics 확장

GraphSchema는 property graph schema에 가깝다. 범용 온톨로지 플랫폼이면 다음 개념이 필요할 수 있다.

온톨로지 개념 현재 지원 확장 필요
Class/Entity type 지원 class hierarchy 추가
Object property relationship type으로 지원 inverse/symmetric/transitive 추가
Data property property type으로 지원 domain/range 강화
Domain/Range pattern으로 부분 지원 다중 domain/range, inheritance 반영
Cardinality 미지원 min/max/exact cardinality
Equivalent class/property 미지원 alias/equivalence 모델
Disjoint class 미지원 validation rule
SKOS concept 미지원 concept scheme, broader/narrower

F. 운영 안정성

  • LLM call budget 관리
  • chunk/embedding cache
  • 재시도/중단/재개
  • job progress DB 저장
  • 대량 batch queue
  • Neo4j transaction timeout 설정
  • Text2Cypher query sandbox

11.3 권장 내부 모듈 구조

우리 프로젝트에 통합할 때는 원본 소스를 직접 수정하기보다 다음 형태가 좋다.

crawler_platform/
  ontology/
    schemas.py              # GraphSchema 래퍼, 버전/상태/소유자 메타데이터
    pipeline_profiles.py    # LLM/embedding/Neo4j profile
    jobs.py                 # KG build job 상태
    adapters/
      documents.py          # crawler output → LoadedDocument
      schema.py             # 우리 온톨로지 모델 ↔ GraphSchema
    services/
      kg_builder.py         # SimpleKGPipeline 실행 래퍼
      review.py             # 추출 결과 검수
      search.py             # GraphRAG/Text2Cypher 래퍼
      resolver.py           # merge 후보/실행

12. 상세 기능명세

12.1 온톨로지 프로젝트 관리

ID 기능 설명 우선순위
ONT-PROJ-001 프로젝트 생성 이름, 설명, Neo4j DB/profile, 기본 언어 설정 P0
ONT-PROJ-002 데이터소스 연결 파일, 크롤링 결과, URL, DB table 등록 P0
ONT-PROJ-003 LLM profile 선택 provider/model/key/params 선택 P0
ONT-PROJ-004 Embedding profile 선택 provider/model/dimension 설정 P0
ONT-PROJ-005 실행 이력 조회 pipeline run 상태/시간/token/비용/오류 P1

12.2 온톨로지 스키마 관리

ID 기능 설명 우선순위
ONT-SCH-001 수동 schema 작성 node type, relationship type, property, pattern 작성 P0
ONT-SCH-002 자동 schema 추출 문서 샘플에서 SchemaFromTextExtractor 실행 P0
ONT-SCH-003 schema 검증 GraphSchema Pydantic validation + custom rule P0
ONT-SCH-004 schema 버전 발행 draft → published P0
ONT-SCH-005 schema diff version 간 label/property/pattern 변경 비교 P1
ONT-SCH-006 constraint 관리 uniqueness/key/existence 제약 관리 P1
ONT-SCH-007 class hierarchy 상위/하위 class 정의 P2

12.3 KG 구축

ID 기능 설명 우선순위
ONT-KG-001 파일 기반 KG 구축 PDF/Markdown → SimpleKGPipeline P0
ONT-KG-002 텍스트 기반 KG 구축 crawler text 또는 inline text → SimpleKGPipeline P0
ONT-KG-003 lexical graph 생성 Document/Chunk/provenance graph 생성 P0
ONT-KG-004 chunk embedding Chunk embedding property 저장 P0
ONT-KG-005 스키마 기반 추출 published GraphSchema로 LLM 추출 P0
ONT-KG-006 자동 스키마 추출 후 KG 구축 schema="EXTRACTED" 사용 P1
ONT-KG-007 자유 추출 schema="FREE" 사용 P1
ONT-KG-008 pruning 통계 저장 제거 노드/관계/property 기록 P0
ONT-KG-009 추출 결과 임시 저장 writer 전 검수용 graph 저장 P1
ONT-KG-010 Parquet export 대량 import 또는 검수 산출물 P2

12.4 검수 및 승인

ID 기능 설명 우선순위
ONT-REV-001 추출 후보 목록 node/relationship/property 후보 조회 P1
ONT-REV-002 근거 chunk 표시 FROM_CHUNK 관계 기반 원문 근거 표시 P1
ONT-REV-003 승인/반려 후보 단위 상태 변경 P1
ONT-REV-004 pruning 후보 검토 스키마 위반으로 제거된 후보 검토 P1
ONT-REV-005 schema 개선 제안 반복 pruning된 후보를 schema 후보로 제안 P2

12.5 엔티티 해소

ID 기능 설명 우선순위
ONT-RES-001 exact match merge label + name exact match P0
ONT-RES-002 fuzzy merge 후보 RapidFuzz로 후보 계산 P1
ONT-RES-003 semantic merge 후보 spaCy 또는 embedding similarity P2
ONT-RES-004 merge 검수 후보 그룹 승인 후 APOC merge P1
ONT-RES-005 merge 이력 병합 전후 node id, property 충돌 기록 P1

12.6 검색 및 질의응답

ID 기능 설명 우선순위
ONT-SEA-001 vector 검색 Chunk vector index 검색 P0
ONT-SEA-002 hybrid 검색 vector + fulltext P1
ONT-SEA-003 graph 확장 검색 VectorCypher/HybridCypher로 주변 graph 반환 P0
ONT-SEA-004 Text2Cypher 자연어 → read-only Cypher P1
ONT-SEA-005 GraphRAG 답변 검색 context 기반 답변 생성 P1
ONT-SEA-006 provenance 포함 답변 답변에 문서/chunk 근거 포함 P1

13. 통합 시 주의사항

13.1 원본 코드를 직접 수정하지 않는 것이 좋다

이 프로젝트의 KG builder는 experimental이다. 원본을 직접 수정하면 upstream 반영이 어려워진다. 권장 방식:

  1. neo4j-graphrag==1.16.0으로 버전 고정
  2. 우리 프로젝트에 adapter/wrapper 작성
  3. 필요한 custom component만 우리 namespace에 구현
  4. 원본 API 변경 시 wrapper만 수정

13.2 LLM JSON 품질

json-repair와 structured output이 있더라도 LLM 추출은 완전하지 않다.

필수 보완:

  • 스키마 grounding prompt 강화
  • examples few-shot 관리
  • chunk별 실패율 기록
  • pruning 결과 분석
  • 사람이 승인하는 workflow

13.3 Neo4j/APOC 의존성

KG writer와 resolver는 Neo4j 버전/APOC에 민감하다.

운영 체크:

  • Neo4j 버전 확인
  • APOC core 설치 확인
  • apoc.refactor.mergeNodes 사용 가능 여부 확인
  • vector/fulltext index 생성 권한 확인
  • multi database 사용 시 neo4j_database 일관성 유지

13.4 Text2Cypher 보안

Text2CypherRetriever는 read-only 검사를 갖지만, 운영 서비스에서는 추가 안전장치가 필요하다.

  • 허용 schema 제한
  • query timeout
  • result limit
  • 금지 키워드 검사
  • 사용자별 권한 필터
  • 쓰기/삭제/관리 명령 차단

14. 초기 적용 로드맵

Phase 1: 최소 KG 구축

목표: crawler 결과 또는 텍스트를 Neo4j KG로 저장.

작업:

  1. neo4j-graphrag[openai,experimental] 의존성 추가
  2. Neo4j 연결 profile 모델 추가
  3. LLM/embedding profile 모델 추가
  4. crawler output → LoadedDocument adapter 작성
  5. SimpleKGPipeline(from_file=False) 실행 service 작성
  6. GraphSchema 수동 입력 API 작성
  7. Neo4jWriter 결과 통계 저장

Phase 2: 온톨로지 초안/검수

목표: 자동 schema 추출과 추출 결과 검수.

작업:

  1. schema="EXTRACTED" 실행 지원
  2. 추출 schema draft 저장
  3. GraphPruning 결과 저장
  4. pruned item 검토 화면/API
  5. 승인된 schema version 발행

Phase 3: 검색/질의응답

목표: 구축된 KG를 탐색하고 질의응답.

작업:

  1. Chunk vector index 생성 자동화
  2. VectorCypherRetriever로 chunk → entity/provenance 검색
  3. HybridRetriever 도입
  4. GraphRAG service 작성
  5. Text2Cypher read-only 질의 API 추가

Phase 4: 엔티티 해소/품질관리

목표: 중복 entity와 schema 품질 개선.

작업:

  1. exact match resolver 실행
  2. fuzzy 후보 생성
  3. merge 후보 검수
  4. merge 이력 저장
  5. 반복 pruning 기반 schema 개선 추천

15. 결론

neo4j-graphrag-python은 우리 범용 온톨로지 구축 플랫폼의 “KG 생성 엔진”과 “GraphRAG 검색 엔진”으로 매우 적합하다. 특히 GraphSchema, SimpleKGPipeline, LLMEntityRelationExtractor, GraphPruning, Neo4jWriter, VectorCypherRetriever, Text2CypherRetriever는 거의 그대로 가져다 쓸 수 있다.

다만 이 프로젝트가 제공하는 것은 “라이브러리/엔진”이지 “플랫폼”은 아니다. 우리 프로젝트의 핵심 차별점은 다음 레이어에서 만들어야 한다.

  • 온톨로지 프로젝트/버전 관리
  • schema draft/publish workflow
  • 추출 결과 검수 및 provenance UI
  • crawler 결과와의 자연스러운 연결
  • 대량 실행 job 관리
  • entity merge 후보 검수
  • Text2Cypher 보안/권한 레이어

따라서 권장 전략은 원본 소스를 복사해 수정하기보다, neo4j-graphrag를 고정 버전 의존성으로 두고 우리 플랫폼 서비스가 이 라이브러리를 orchestration하는 방식이다. 필요한 경우 custom loader, custom splitter, custom resolver, custom writer만 우리 코드베이스에 추가한다.