1220 lines
38 KiB
Markdown
1220 lines
38 KiB
Markdown
|
|
# OntoCast 분석 및 기능명세
|
||
|
|
|
||
|
|
분석 대상: `C:\Users\lasta\MyProject\AI\참고\ontocast-main`
|
||
|
|
분석 기준일: 2026-05-13
|
||
|
|
라이선스: Apache License 2.0
|
||
|
|
프로젝트 성격: 문서에서 RDF 지식그래프를 생성하기 위한 에이전트형 온톨로지 보조 triple extraction 프레임워크
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. 결론 요약
|
||
|
|
이 오픈소스코드는 사용자 직접 데이터를 입력해서 온톨로지 구축하는 기능을 추가하고 그 용도로 사용하는 것으로 한다.
|
||
|
|
OntoCast는 범용 온톨로지 구축 플랫폼의 기본 소스로 재사용 가치가 높다. 특히 다음 영역은 거의 원형 그대로 가져와도 된다.
|
||
|
|
|
||
|
|
- `AgentState`, `UnitFactsState`, `UnitOntologyState` 기반 상태 모델
|
||
|
|
- LangGraph 기반 문서 처리 워크플로우
|
||
|
|
- 온톨로지 선택, 생성, 갱신, 비평, 재시도 루프
|
||
|
|
- GraphUpdate 기반 SPARQL 증분 갱신 구조
|
||
|
|
- RDFGraph, Ontology, ContentUnit 도메인 모델
|
||
|
|
- LLM 응답 캐싱 및 budget tracking
|
||
|
|
- Fuseki, Neo4j, filesystem triple store 추상화
|
||
|
|
- embedding 기반 entity aggregation, URI 정규화, owl:sameAs 생성
|
||
|
|
|
||
|
|
다만 OntoCast는 “완성된 범용 온톨로지 구축 플랫폼”이라기보다 “문서 입력 → 온톨로지/팩트 RDF 생성 → 저장”에 집중된 코어 엔진이다. 앞으로 만들 플랫폼에서는 사용자/프로젝트/작업 관리, 온톨로지 편집 UI, 검수 워크플로우, 권한, 배치 운영, 데이터셋 카탈로그, 품질 지표 대시보드가 별도 상위 계층으로 필요하다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. 프로젝트 개요
|
||
|
|
|
||
|
|
### 2.1 목적
|
||
|
|
|
||
|
|
OntoCast는 비정형 문서 또는 JSON/text 입력을 받아 다음 산출물을 만든다.
|
||
|
|
|
||
|
|
- 도메인 온톨로지 RDF/Turtle
|
||
|
|
- 문서에서 추출된 사실 triple RDF/Turtle
|
||
|
|
- 문서 단위 aggregated facts graph
|
||
|
|
- 온톨로지 버전/해시/lineage metadata
|
||
|
|
- LLM 사용량과 triple 생성량 budget metadata
|
||
|
|
|
||
|
|
핵심 아이디어는 온톨로지를 먼저 선택하거나 새로 만들고, 그 온톨로지를 기준으로 문서의 사실 정보를 RDF triple로 추출하는 것이다.
|
||
|
|
|
||
|
|
### 2.2 기술 스택
|
||
|
|
|
||
|
|
`pyproject.toml` 기준 주요 의존성은 다음과 같다.
|
||
|
|
|
||
|
|
| 영역 | 사용 기술 |
|
||
|
|
|---|---|
|
||
|
|
| 언어 | Python 3.12 이상 |
|
||
|
|
| 워크플로우 | LangGraph |
|
||
|
|
| LLM 연동 | LangChain, OpenAI, Ollama |
|
||
|
|
| API 서버 | Robyn |
|
||
|
|
| RDF 처리 | rdflib, pyld, oxrdflib, owlready2 |
|
||
|
|
| 그래프 저장소 | Fuseki, Neo4j n10s, filesystem |
|
||
|
|
| 문서 처리 옵션 | docling, easyocr |
|
||
|
|
| 청킹/임베딩 | langchain-experimental, sentence-transformers, simsimd |
|
||
|
|
| 군집화 | hdbscan, umap-learn, rapidfuzz |
|
||
|
|
| 설정 | pydantic-settings |
|
||
|
|
| CLI | click |
|
||
|
|
|
||
|
|
### 2.3 실행 형태
|
||
|
|
|
||
|
|
OntoCast는 두 가지 모드로 동작한다.
|
||
|
|
|
||
|
|
1. API 서버 모드
|
||
|
|
- 엔트리포인트: `ontocast.cli.serve:run`
|
||
|
|
- 명령: `ontocast --env-file .env`
|
||
|
|
- 주요 엔드포인트: `/health`, `/info`, `/process`, `/flush`
|
||
|
|
|
||
|
|
2. 파일 배치 처리 모드
|
||
|
|
- 명령: `ontocast --env-file .env --input-path ./docs`
|
||
|
|
- 입력 경로의 JSON/PDF/지원 문서를 순회 처리
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 디렉터리 구조 분석
|
||
|
|
|
||
|
|
| 경로 | 역할 |
|
||
|
|
|---|---|
|
||
|
|
| `ontocast/config.py` | Pydantic 기반 전체 설정 모델 |
|
||
|
|
| `ontocast/cli/serve.py` | Robyn API 서버와 CLI 엔트리포인트 |
|
||
|
|
| `ontocast/stategraph/` | LangGraph 워크플로우 정의, 라우팅, 병렬 node factory |
|
||
|
|
| `ontocast/agent/` | 문서 변환, 청킹, 온톨로지 선택/생성/비평, facts 생성/비평 agent |
|
||
|
|
| `ontocast/onto/` | RDFGraph, Ontology, AgentState, SPARQL model 등 핵심 도메인 모델 |
|
||
|
|
| `ontocast/tool/` | LLM, converter, chunker, cache, SPARQL, triple store 등 도구 |
|
||
|
|
| `ontocast/tool/agg/` | entity disambiguation 및 graph aggregation |
|
||
|
|
| `ontocast/tool/triple_manager/` | Fuseki, Neo4j, filesystem 저장소 구현 |
|
||
|
|
| `ontocast/prompt/` | LLM prompt template |
|
||
|
|
| `docs/` | 사용자 가이드와 API reference |
|
||
|
|
| `test/` | 단위/통합 테스트 |
|
||
|
|
| `data/` | 예시 ontology, PDF, JSON, chunk 데이터 |
|
||
|
|
| `docker/` | Fuseki, Neo4j, Qdrant docker-compose |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. 전체 처리 흐름
|
||
|
|
|
||
|
|
코드 기준 핵심 워크플로우는 `ontocast/stategraph/create.py`의 `create_agent_graph()`에 정의되어 있다.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
START([START]) --> CONVERT[CONVERT_TO_MD]
|
||
|
|
CONVERT --> CHUNK[CHUNK]
|
||
|
|
CHUNK --> SELECT[SELECT_ONTOLOGY]
|
||
|
|
SELECT -->|기존 온톨로지 없음| BOOTSTRAP[BOOTSTRAP_ONTOLOGY]
|
||
|
|
SELECT -->|온톨로지 생성/갱신 필요| RENDER_ONTO[RENDER_ONTOLOGY_UPDATE]
|
||
|
|
SELECT -->|facts만 생성| RENDER_FACTS[RENDER_FACTS]
|
||
|
|
BOOTSTRAP --> RENDER_ONTO
|
||
|
|
RENDER_ONTO --> NORMALIZE[NORMALIZE_ONTOLOGY_UPDATES]
|
||
|
|
NORMALIZE --> CONSOLIDATE[CONSOLIDATE_ONTOLOGY]
|
||
|
|
CONSOLIDATE -->|facts 생성 필요| RENDER_FACTS
|
||
|
|
CONSOLIDATE -->|ontology only| SERIALIZE[SERIALIZE]
|
||
|
|
RENDER_FACTS --> MERGE[MERGE_FACTS]
|
||
|
|
MERGE --> SERIALIZE
|
||
|
|
SERIALIZE --> END([END])
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4.1 단계별 설명
|
||
|
|
|
||
|
|
| 단계 | 구현 위치 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| 문서 변환 | `agent/convert_document.py` | PDF/지원 문서를 markdown/text로 변환하거나 JSON/text를 파싱 |
|
||
|
|
| 청킹 | `agent/chunk_text.py`, `tool/chunk/` | 긴 문서를 semantic chunk 또는 fallback chunk로 분할 |
|
||
|
|
| 온톨로지 선택 | `agent/select_ontology.py` | 기존 ontology 목록을 LLM에 제시하고 문서에 맞는 ontology를 선택 |
|
||
|
|
| 온톨로지 부트스트랩 | `stategraph/node_factories.py` | 기존 ontology가 없으면 문서 발췌문으로 seed ontology 생성 |
|
||
|
|
| 온톨로지 map | `stategraph/atomic.py`, `agent/render_ontology.py` | content unit별 ontology delta 또는 fresh ontology 생성 |
|
||
|
|
| 온톨로지 critic | `agent/criticise_ontology.py` | ontology 품질을 평가하고 개선 suggestions 생성 |
|
||
|
|
| 온톨로지 normalize | `agent/normalize_ontology.py` | per-unit ontology delta를 GraphUpdate로 병합, provenance 제거 |
|
||
|
|
| 선택적 consolidation | `stategraph/node_factories.py` | 중복 class/property 정리, hierarchy 일관성 개선 |
|
||
|
|
| facts map | `agent/render_facts.py` | ontology를 기준으로 content unit별 facts graph 생성 |
|
||
|
|
| facts critic | `agent/criticise_facts.py` | facts triple이 원문과 ontology에 맞는지 평가 |
|
||
|
|
| facts merge | `stategraph/node_factories.py`, `tool/agg/` | content unit별 graph를 entity aggregation 후 병합 |
|
||
|
|
| 저장 | `agent/serialize.py`, `toolbox.py` | filesystem/Fuseki/Neo4j에 ontology와 facts 저장 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. 핵심 아키텍처
|
||
|
|
|
||
|
|
### 5.1 ToolBox
|
||
|
|
|
||
|
|
구현 위치: `ontocast/toolbox.py`
|
||
|
|
|
||
|
|
`ToolBox`는 시스템의 dependency container이다. 서버 시작 시 `Config`를 받아 다음 객체를 초기화한다.
|
||
|
|
|
||
|
|
- `LLMTool`
|
||
|
|
- `Cacher`
|
||
|
|
- `AtomicToolBox`
|
||
|
|
- `FilesystemTripleStoreManager`
|
||
|
|
- `FusekiTripleStoreManager`
|
||
|
|
- `Neo4jTripleStoreManager`
|
||
|
|
- `OntologyManager`
|
||
|
|
- `ConverterTool`
|
||
|
|
- `ChunkerTool`
|
||
|
|
- `EmbeddingBasedAggregator`
|
||
|
|
- `SPARQLTool`
|
||
|
|
- `GraphVersionManager`
|
||
|
|
- `DiffTool`
|
||
|
|
|
||
|
|
재사용 판단: 매우 높음.
|
||
|
|
범용 플랫폼에서는 ToolBox를 application service container로 삼되, 사용자별/프로젝트별 설정 주입이 가능하도록 확장하면 된다.
|
||
|
|
|
||
|
|
### 5.2 Config
|
||
|
|
|
||
|
|
구현 위치: `ontocast/config.py`
|
||
|
|
|
||
|
|
설정은 다음 계층으로 나뉜다.
|
||
|
|
|
||
|
|
- `LLMConfig`: provider, model, temperature, base_url, api_key
|
||
|
|
- `ChunkConfig`: semantic chunk threshold, min/max chunk size
|
||
|
|
- `ServerConfig`: port, recursion limit, render mode, parallel worker, retry 횟수
|
||
|
|
- `Neo4jConfig`
|
||
|
|
- `FusekiConfig`
|
||
|
|
- `DomainConfig`
|
||
|
|
- `PathConfig`
|
||
|
|
- `WebSearchConfig`
|
||
|
|
- `AggregationConfig`
|
||
|
|
- `ToolConfig`
|
||
|
|
- `Config`
|
||
|
|
|
||
|
|
재사용 판단: 높음.
|
||
|
|
다만 플랫폼형 서비스에서는 `.env` 중심 설정 외에 DB 저장형 프로젝트 설정, 사용자별 secret 관리가 필요하다.
|
||
|
|
|
||
|
|
### 5.3 AgentState
|
||
|
|
|
||
|
|
구현 위치: `ontocast/onto/state.py`
|
||
|
|
|
||
|
|
`AgentState`는 전체 문서 처리 상태를 담는 중앙 모델이다.
|
||
|
|
|
||
|
|
주요 필드:
|
||
|
|
|
||
|
|
- `input_text`
|
||
|
|
- `files`
|
||
|
|
- `content_units`
|
||
|
|
- `current_content_unit`
|
||
|
|
- `current_ontology`
|
||
|
|
- `aggregated_facts`
|
||
|
|
- `ontology_user_instruction`
|
||
|
|
- `facts_user_instruction`
|
||
|
|
- `dataset`
|
||
|
|
- `source_url`
|
||
|
|
- `ontology_updates`, `ontology_updates_applied`
|
||
|
|
- `facts_updates`, `facts_updates_applied`
|
||
|
|
- `parallel_facts_units`
|
||
|
|
- `ontology_units`
|
||
|
|
- `ontology_provenance_artifact`
|
||
|
|
- `failure_stage`, `failure_reason`
|
||
|
|
- `status`, `statuses`
|
||
|
|
- `node_visits`, `max_visits`
|
||
|
|
- `render_mode`
|
||
|
|
- `ontology_max_triples`
|
||
|
|
- `context_manager`
|
||
|
|
- `suggestions`
|
||
|
|
- `budget_tracker`
|
||
|
|
|
||
|
|
중요 메서드:
|
||
|
|
|
||
|
|
- `render_updated_graph()`: GraphUpdate를 RDFGraph에 적용
|
||
|
|
- `update_ontology()`: pending ontology update 적용
|
||
|
|
- `update_facts()`: pending facts update 적용
|
||
|
|
- `doc_iri`, `doc_namespace`, `graph_uri`: 문서 기반 IRI 생성
|
||
|
|
- `get_context_for_agent()`, `update_context_for_agent()`: agent 간 context 관리
|
||
|
|
|
||
|
|
재사용 판단: 매우 높음.
|
||
|
|
범용 플랫폼에서는 이 모델이 “작업 실행 상태”의 기본 스키마가 될 수 있다.
|
||
|
|
|
||
|
|
### 5.4 Unit State
|
||
|
|
|
||
|
|
구현 위치: `ontocast/onto/unit_states.py`
|
||
|
|
|
||
|
|
병렬 map 단계에서 content unit 하나를 독립 처리하기 위한 상태 모델이다.
|
||
|
|
|
||
|
|
- `UnitState`
|
||
|
|
- `UnitFactsState`
|
||
|
|
- `UnitOntologyState`
|
||
|
|
|
||
|
|
이 구조 덕분에 전체 문서 상태를 매번 공유하지 않고 unit별 renderer/critic loop를 병렬 실행할 수 있다.
|
||
|
|
|
||
|
|
재사용 판단: 높음.
|
||
|
|
대규모 문서, 웹 크롤링 문서, 다중 파일 ingestion에 유리하다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. GraphUpdate / SPARQL 증분 갱신 구조
|
||
|
|
|
||
|
|
구현 위치:
|
||
|
|
|
||
|
|
- `ontocast/onto/sparql_models.py`
|
||
|
|
- `ontocast/onto/state.py`
|
||
|
|
- `agent/render_ontology.py`
|
||
|
|
- `agent/render_facts.py`
|
||
|
|
|
||
|
|
OntoCast의 중요한 장점은 LLM이 매번 전체 Turtle graph를 다시 생성하지 않고, 변경분만 `GraphUpdate`로 출력하게 하는 구조이다.
|
||
|
|
|
||
|
|
### 6.1 주요 모델
|
||
|
|
|
||
|
|
| 모델 | 역할 |
|
||
|
|
|---|---|
|
||
|
|
| `TripleOp` | insert/delete triple operation |
|
||
|
|
| `GenericSparqlQuery` | 직접 SPARQL update query |
|
||
|
|
| `GraphUpdate` | 여러 `TripleOp` 또는 custom query 묶음 |
|
||
|
|
| `GraphUpdateRenderReport` | LLM renderer의 구조화 출력 |
|
||
|
|
|
||
|
|
### 6.2 동작 방식
|
||
|
|
|
||
|
|
1. 현재 ontology 또는 facts graph를 prompt에 포함한다.
|
||
|
|
2. LLM은 전체 TTL 대신 `GraphUpdate`를 반환한다.
|
||
|
|
3. `GraphUpdate.generate_sparql_queries()`가 SPARQL update query로 변환한다.
|
||
|
|
4. `AgentState.render_updated_graph()`가 rdflib graph에 update를 적용한다.
|
||
|
|
5. max triple 제한을 넘으면 ontology update를 건너뛴다.
|
||
|
|
|
||
|
|
### 6.3 장점
|
||
|
|
|
||
|
|
- 출력 토큰 절감
|
||
|
|
- 변경 이력 추적 용이
|
||
|
|
- ontology versioning과 연결 가능
|
||
|
|
- LLM이 기존 graph를 파괴하는 위험 감소
|
||
|
|
- critic feedback을 update operation으로 재적용 가능
|
||
|
|
|
||
|
|
재사용 판단: 최상.
|
||
|
|
범용 온톨로지 구축 플랫폼의 핵심 기능으로 삼는 것이 좋다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. 온톨로지 관리 기능
|
||
|
|
|
||
|
|
### 7.1 Ontology 모델
|
||
|
|
|
||
|
|
구현 위치: `ontocast/onto/ontology.py`
|
||
|
|
|
||
|
|
Ontology는 RDF graph와 메타데이터를 함께 들고 있다.
|
||
|
|
|
||
|
|
주요 속성:
|
||
|
|
|
||
|
|
- `ontology_id`
|
||
|
|
- `title`
|
||
|
|
- `description`
|
||
|
|
- `version`
|
||
|
|
- `iri`
|
||
|
|
- `graph`
|
||
|
|
- `hash`
|
||
|
|
- `parent_hashes`
|
||
|
|
- `created_at`
|
||
|
|
- `updated_at`
|
||
|
|
- `initial_version`
|
||
|
|
|
||
|
|
주요 기능:
|
||
|
|
|
||
|
|
- RDF graph와 object property 동기화
|
||
|
|
- version/hash lineage 관리
|
||
|
|
- ontology 변경 시 updated version 파생
|
||
|
|
- null ontology 판별
|
||
|
|
- ontology 설명 문자열 생성
|
||
|
|
|
||
|
|
### 7.2 OntologyManager
|
||
|
|
|
||
|
|
구현 위치: `ontocast/tool/ontology_manager.py`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- ontology 목록 보관
|
||
|
|
- ontology 추가
|
||
|
|
- 사용 가능한 ontology 존재 여부 확인
|
||
|
|
- ontology selection agent에 목록 제공
|
||
|
|
|
||
|
|
현재는 단순 in-memory manager에 가깝다. 플랫폼에서는 DB 기반 registry로 확장해야 한다.
|
||
|
|
|
||
|
|
### 7.3 Versioning
|
||
|
|
|
||
|
|
구현 위치: `ontocast/tool/graph_version_manager.py`
|
||
|
|
|
||
|
|
문서와 README 기준 제공 기능:
|
||
|
|
|
||
|
|
- semantic version increment
|
||
|
|
- hash-based lineage
|
||
|
|
- parent hash 추적
|
||
|
|
- ontology graph diff 분석
|
||
|
|
- version statistics
|
||
|
|
|
||
|
|
도입 시 유의점:
|
||
|
|
|
||
|
|
- 플랫폼에서는 ontology version을 “초안, 검수중, 승인, 폐기” 같은 lifecycle과 연결해야 한다.
|
||
|
|
- hash lineage는 내부 무결성 관리에 유용하지만 사용자 UI에서는 semantic version과 변경 요약을 앞세우는 편이 좋다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. 문서 입력 및 청킹
|
||
|
|
|
||
|
|
### 8.1 Document Conversion
|
||
|
|
|
||
|
|
구현 위치:
|
||
|
|
|
||
|
|
- `agent/convert_document.py`
|
||
|
|
- `tool/converter.py`
|
||
|
|
|
||
|
|
지원 입력:
|
||
|
|
|
||
|
|
- JSON
|
||
|
|
- TXT
|
||
|
|
- docling이 지원하는 문서 포맷
|
||
|
|
- README 기준 PDF, Markdown 등
|
||
|
|
|
||
|
|
JSON 입력의 특수 필드:
|
||
|
|
|
||
|
|
- `text`: 처리 대상 텍스트
|
||
|
|
- `ontology_user_instruction`: ontology 생성/갱신 지시
|
||
|
|
- `facts_user_instruction`: facts 추출 지시
|
||
|
|
- `url`: provenance용 source URL
|
||
|
|
|
||
|
|
주의점:
|
||
|
|
|
||
|
|
- `convert_document()`는 주석상 “processing only one file”이라고 되어 있으며, 루프 구조도 마지막 파일 기준 상태 갱신에 가깝다.
|
||
|
|
- 플랫폼에서 다중 파일을 하나의 corpus로 처리하려면 이 부분은 확장해야 한다.
|
||
|
|
|
||
|
|
### 8.2 Chunking
|
||
|
|
|
||
|
|
구현 위치:
|
||
|
|
|
||
|
|
- `agent/chunk_text.py`
|
||
|
|
- `tool/chunk/chunker.py`
|
||
|
|
- `tool/chunk/util.py`
|
||
|
|
|
||
|
|
설정:
|
||
|
|
|
||
|
|
- `CHUNK_BREAKPOINT_THRESHOLD_TYPE`
|
||
|
|
- `CHUNK_BREAKPOINT_THRESHOLD_AMOUNT`
|
||
|
|
- `CHUNK_MIN_SIZE`
|
||
|
|
- `CHUNK_MAX_SIZE`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- 입력 텍스트를 content unit으로 분할
|
||
|
|
- 각 content unit에 index와 doc IRI 부여
|
||
|
|
- `max_chunks`로 앞부분 일부만 처리 가능
|
||
|
|
|
||
|
|
도입 의견:
|
||
|
|
|
||
|
|
- 웹 크롤러/문서 수집 플랫폼과 결합할 경우, 문서 단위 chunk metadata를 더 풍부하게 만들어야 한다.
|
||
|
|
- 예: section title, page number, source URL, crawl timestamp, MIME type, language.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. LLM Agent 상세
|
||
|
|
|
||
|
|
### 9.1 Ontology Selection Agent
|
||
|
|
|
||
|
|
구현 위치: `agent/select_ontology.py`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- 현재 `OntologyManager`가 가진 ontology 목록을 번호 목록으로 구성
|
||
|
|
- 문서의 first/middle/last chunk 일부를 발췌해 대표 excerpt 생성
|
||
|
|
- LLM이 적절한 ontology index를 선택
|
||
|
|
- 없으면 null ontology로 진행
|
||
|
|
|
||
|
|
명세:
|
||
|
|
|
||
|
|
- 입력: `AgentState.content_units`, ontology 목록
|
||
|
|
- 출력: `AgentState.current_ontology`
|
||
|
|
- 실패 처리: ontology가 없으면 `NULL_ONTOLOGY`
|
||
|
|
|
||
|
|
개선 필요:
|
||
|
|
|
||
|
|
- 코드 주석은 `answer_index == 0`을 None으로 설명하지만 dynamic model은 `1..num_ontologies+1` 범위를 사용한다. 실제 None 선택은 `num_ontologies + 1`이어야 자연스럽다. 이 부분은 가져오기 전에 테스트와 함께 수정하는 것이 좋다.
|
||
|
|
|
||
|
|
### 9.2 Ontology Renderer
|
||
|
|
|
||
|
|
구현 위치: `agent/render_ontology.py`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- fresh ontology 생성
|
||
|
|
- 기존 ontology에 대한 GraphUpdate 생성
|
||
|
|
- known prefix를 추출해 RDFGraph parser context에 제공
|
||
|
|
- user instruction과 critic suggestions 반영
|
||
|
|
- optional external evidence 반영
|
||
|
|
|
||
|
|
모드:
|
||
|
|
|
||
|
|
| 상황 | 출력 |
|
||
|
|
|---|---|
|
||
|
|
| seed ontology 없음 | `OntologyRenderReport` 안의 fresh `Ontology` |
|
||
|
|
| seed ontology 있음 | `GraphUpdateRenderReport` 안의 `GraphUpdate` |
|
||
|
|
|
||
|
|
### 9.3 Ontology Critic
|
||
|
|
|
||
|
|
구현 위치: `agent/criticise_ontology.py`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- ontology가 문서 domain을 잘 표현하는지 평가
|
||
|
|
- score와 success 반환
|
||
|
|
- 실패 시 actionable fixes와 systemic critique summary를 `Suggestions`로 변환
|
||
|
|
- score > 90이면 success로 간주
|
||
|
|
|
||
|
|
출력 모델:
|
||
|
|
|
||
|
|
- `OntologyCritiqueReport`
|
||
|
|
- `TripleFix`
|
||
|
|
- `Suggestions`
|
||
|
|
|
||
|
|
### 9.4 Facts Renderer
|
||
|
|
|
||
|
|
구현 위치: `agent/render_facts.py`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- ontology graph를 기준으로 source text에서 facts RDF 생성
|
||
|
|
- fresh facts graph가 비어 있으면 Turtle 생성
|
||
|
|
- 기존 facts graph가 있으면 GraphUpdate 생성
|
||
|
|
- ontology prefix와 namespace를 prompt에 포함
|
||
|
|
- facts user instruction 반영
|
||
|
|
|
||
|
|
출력:
|
||
|
|
|
||
|
|
- fresh: `FactsRenderReport`
|
||
|
|
- update: `GraphUpdateRenderReport`
|
||
|
|
|
||
|
|
### 9.5 Facts Critic
|
||
|
|
|
||
|
|
구현 위치: `agent/criticise_facts.py`
|
||
|
|
|
||
|
|
기능:
|
||
|
|
|
||
|
|
- facts graph가 원문을 충분히 표현하는지 평가
|
||
|
|
- ontology와 facts graph의 정합성 확인
|
||
|
|
- score > 90 또는 success면 통과
|
||
|
|
- 실패 시 `Suggestions` 생성
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 10. Retry Loop 및 외부 근거 검색
|
||
|
|
|
||
|
|
구현 위치:
|
||
|
|
|
||
|
|
- `stategraph/atomic.py`
|
||
|
|
- `agent/external_evidence.py`
|
||
|
|
- `tool/web_search.py`
|
||
|
|
|
||
|
|
### 10.1 Atomic Loop
|
||
|
|
|
||
|
|
`facts_loop()`와 `ontology_loop()`는 다음 패턴을 따른다.
|
||
|
|
|
||
|
|
1. renderer 실행
|
||
|
|
2. renderer 실패 시 external evidence request 확인
|
||
|
|
3. 필요하면 검색 계획 수립
|
||
|
|
4. 검색 실행
|
||
|
|
5. renderer 재실행
|
||
|
|
6. critic 실행
|
||
|
|
7. critic 실패 시 suggestions 저장
|
||
|
|
8. critic이 external evidence를 요청하면 검색 후 critic 재실행
|
||
|
|
9. retry budget 소진 시 마지막 상태 반환
|
||
|
|
|
||
|
|
### 10.2 Web Search
|
||
|
|
|
||
|
|
설정 위치: `WebSearchConfig`
|
||
|
|
|
||
|
|
지원 provider:
|
||
|
|
|
||
|
|
- DuckDuckGo
|
||
|
|
|
||
|
|
주요 옵션:
|
||
|
|
|
||
|
|
- `WEB_SEARCH_ENABLED`
|
||
|
|
- `WEB_SEARCH_TOP_K`
|
||
|
|
- `WEB_SEARCH_TIMEOUT_SECONDS`
|
||
|
|
- `WEB_SEARCH_ALLOWED_DOMAINS`
|
||
|
|
- `WEB_SEARCH_BLOCKED_DOMAINS`
|
||
|
|
- ontology/facts renderer/critic별 enable flag
|
||
|
|
|
||
|
|
도입 의견:
|
||
|
|
|
||
|
|
- 범용 플랫폼에서 외부 근거 검색은 매우 유용하나, 운영 환경에서는 검색 결과 provenance와 source trust policy가 필요하다.
|
||
|
|
- allowed/blocked domain 설정은 프로젝트별 정책으로 승격해야 한다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 11. Facts Aggregation / Entity Disambiguation
|
||
|
|
|
||
|
|
구현 위치:
|
||
|
|
|
||
|
|
- `tool/aggregate.py`
|
||
|
|
- `tool/agg/aggregate.py`
|
||
|
|
- `tool/agg/normalizer.py`
|
||
|
|
- `tool/agg/clustering.py`
|
||
|
|
- `tool/agg/rewriter.py`
|
||
|
|
- `tool/agg/uri_builder.py`
|
||
|
|
|
||
|
|
### 11.1 목적
|
||
|
|
|
||
|
|
각 content unit에서 독립 생성된 facts graph는 같은 entity를 서로 다른 URI로 표현할 수 있다. Aggregator는 이를 정규화하고 병합한다.
|
||
|
|
|
||
|
|
### 11.2 파이프라인
|
||
|
|
|
||
|
|
1. content unit별 entity 수집
|
||
|
|
2. entity를 semantic context가 포함된 representation으로 정규화
|
||
|
|
3. sentence-transformers embedding 생성
|
||
|
|
4. cosine similarity 기반 candidate clustering
|
||
|
|
5. symbolic identity check로 부적절한 merge 방지
|
||
|
|
6. canonical representative 선택
|
||
|
|
7. URI policy에 따라 최종 URI 생성
|
||
|
|
8. graph rewrite 수행
|
||
|
|
9. 필요 시 `owl:sameAs` 링크 추가
|
||
|
|
|
||
|
|
### 11.3 Entity 분류
|
||
|
|
|
||
|
|
`EntityClassification`:
|
||
|
|
|
||
|
|
- `fact`
|
||
|
|
- `known_ontology`
|
||
|
|
- `tentative_ontology`
|
||
|
|
|
||
|
|
표준 RDF/OWL/RDFS/XSD/Schema/PROV namespace는 built-in vocabulary로 취급한다.
|
||
|
|
|
||
|
|
### 11.4 URI 정책
|
||
|
|
|
||
|
|
`URIBuilder`는 role에 따라 URI local name을 정규화한다.
|
||
|
|
|
||
|
|
- class: PascalCase
|
||
|
|
- property: lowerCamelCase
|
||
|
|
- instance: normalized name 또는 structured id 유지
|
||
|
|
|
||
|
|
도입 판단: 높음.
|
||
|
|
범용 플랫폼에서 문서/크롤링 단위별 entity 중복 문제를 줄이는 핵심 기능이다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 12. Triple Store 통합
|
||
|
|
|
||
|
|
구현 위치: `tool/triple_manager/`
|
||
|
|
|
||
|
|
### 12.1 공통 인터페이스
|
||
|
|
|
||
|
|
`TripleStoreManager`가 정의하는 핵심 메서드:
|
||
|
|
|
||
|
|
- `fetch_ontologies() -> list[Ontology]`
|
||
|
|
- `serialize_graph(graph, **kwargs)`
|
||
|
|
- `serialize(o: Ontology | RDFGraph, **kwargs)`
|
||
|
|
- `clean(dataset: str | None = None)`
|
||
|
|
|
||
|
|
### 12.2 FilesystemTripleStoreManager
|
||
|
|
|
||
|
|
역할:
|
||
|
|
|
||
|
|
- 로컬 디렉터리에 ontology/facts graph 저장
|
||
|
|
- 개발/테스트/간단 배치에 적합
|
||
|
|
|
||
|
|
### 12.3 FusekiTripleStoreManager
|
||
|
|
|
||
|
|
역할:
|
||
|
|
|
||
|
|
- Apache Jena Fuseki dataset에 RDF 저장
|
||
|
|
- ontology와 facts dataset 분리 지원
|
||
|
|
- named graph 기반 저장에 적합
|
||
|
|
- `/flush?dataset=...` 동작과 연결
|
||
|
|
|
||
|
|
### 12.4 Neo4jTripleStoreManager
|
||
|
|
|
||
|
|
역할:
|
||
|
|
|
||
|
|
- Neo4j/n10s 기반 RDF graph 저장
|
||
|
|
- GraphRAG나 graph query UI와 연결하기 좋음
|
||
|
|
|
||
|
|
도입 의견:
|
||
|
|
|
||
|
|
- 범용 온톨로지 플랫폼의 canonical store는 Fuseki/RDF store가 더 자연스럽다.
|
||
|
|
- Neo4j는 분석/시각화/GraphRAG projection store로 병행하는 구성이 좋다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 13. API 기능명세
|
||
|
|
|
||
|
|
구현 위치: `ontocast/cli/serve.py`
|
||
|
|
|
||
|
|
### 13.1 GET `/health`
|
||
|
|
|
||
|
|
목적: 서비스 상태 확인
|
||
|
|
|
||
|
|
성공 응답:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "healthy",
|
||
|
|
"version": "0.1.1",
|
||
|
|
"llm_provider": "openai"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
실패 조건:
|
||
|
|
|
||
|
|
- LLM 미초기화
|
||
|
|
- 내부 예외
|
||
|
|
|
||
|
|
### 13.2 GET `/info`
|
||
|
|
|
||
|
|
목적: 서비스 metadata 및 capability 제공
|
||
|
|
|
||
|
|
응답 필드:
|
||
|
|
|
||
|
|
- `name`
|
||
|
|
- `version`
|
||
|
|
- `description`
|
||
|
|
- `capabilities`
|
||
|
|
- `input_types`
|
||
|
|
- `output_types`
|
||
|
|
|
||
|
|
### 13.3 POST `/process`
|
||
|
|
|
||
|
|
목적: 문서를 처리해 ontology/facts RDF를 생성
|
||
|
|
|
||
|
|
지원 Content-Type:
|
||
|
|
|
||
|
|
- `application/json`
|
||
|
|
- `multipart/form-data`
|
||
|
|
|
||
|
|
Query Parameters:
|
||
|
|
|
||
|
|
| 이름 | 설명 |
|
||
|
|
|---|---|
|
||
|
|
| `dataset` | Fuseki dataset override |
|
||
|
|
| `render_mode` | `ontology`, `facts`, `ontology_and_facts` |
|
||
|
|
| `ontology_user_instruction` | ontology 추출 지시 |
|
||
|
|
| `facts_user_instruction` | facts 추출 지시 |
|
||
|
|
|
||
|
|
Form fields:
|
||
|
|
|
||
|
|
- file
|
||
|
|
- `ontology_user_instruction`
|
||
|
|
- `facts_user_instruction`
|
||
|
|
|
||
|
|
JSON body:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"text": "처리할 텍스트",
|
||
|
|
"url": "https://source.example/doc",
|
||
|
|
"ontology_user_instruction": "장소와 조직 중심으로 온톨로지를 구성",
|
||
|
|
"facts_user_instruction": "인물-조직 관계를 우선 추출"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
성공 응답:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "success",
|
||
|
|
"data": {
|
||
|
|
"facts": "... turtle ...",
|
||
|
|
"ontology": "... turtle ..."
|
||
|
|
},
|
||
|
|
"metadata": {
|
||
|
|
"status": "success",
|
||
|
|
"chunks_processed": 10,
|
||
|
|
"chunks_remaining": 0,
|
||
|
|
"budget": {
|
||
|
|
"chars_sent": 12345,
|
||
|
|
"chars_received": 6789,
|
||
|
|
"calls_count": 12,
|
||
|
|
"ontology_triples_generated": 50,
|
||
|
|
"facts_triples_generated": 300,
|
||
|
|
"ontology_operations_count": 5,
|
||
|
|
"facts_operations_count": 10
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
실패 응답:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "error",
|
||
|
|
"error": "오류 메시지",
|
||
|
|
"error_type": "ExceptionType",
|
||
|
|
"error_details": {
|
||
|
|
"stage": "failure stage",
|
||
|
|
"reason": "failure reason"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 13.4 POST `/flush`
|
||
|
|
|
||
|
|
목적: triple store 데이터 삭제
|
||
|
|
|
||
|
|
Query Parameters:
|
||
|
|
|
||
|
|
| 이름 | 설명 |
|
||
|
|
|---|---|
|
||
|
|
| `dataset` | Fuseki에서 특정 dataset만 삭제 |
|
||
|
|
|
||
|
|
주의:
|
||
|
|
|
||
|
|
- irreversible operation
|
||
|
|
- Neo4j/filesystem에서는 dataset parameter 무시
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 14. CLI 기능명세
|
||
|
|
|
||
|
|
`pyproject.toml`의 `[project.scripts]` 기준 공개 CLI:
|
||
|
|
|
||
|
|
| 명령 | 엔트리포인트 | 기능 |
|
||
|
|
|---|---|---|
|
||
|
|
| `ontocast` | `ontocast.cli.serve:run` | API 서버 실행 또는 input path 배치 처리 |
|
||
|
|
| `cmp-states` | `ontocast.cli.cmp_states:main` | 저장된 AgentState 비교 |
|
||
|
|
| `pdfs-to-markdown` | `ontocast.cli.pdfs_to_markdown:main` | PDF를 markdown으로 변환 |
|
||
|
|
| `plot-graph` | `ontocast.cli.plot_graph:main` | graph 시각화/문서 내 mermaid 갱신 |
|
||
|
|
| `test-api` | `ontocast.cli.test_api:main` | API 호출 테스트 |
|
||
|
|
|
||
|
|
추가 CLI 파일:
|
||
|
|
|
||
|
|
- `batch_process.py`: 비동기 파일 배치 처리
|
||
|
|
- `merge_ontologies.py`: ontology 병합
|
||
|
|
- `split_chunks.py`: JSON을 markdown으로 변환 후 chunk 분할
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 15. 설정 기능명세
|
||
|
|
|
||
|
|
### 15.1 필수 설정
|
||
|
|
|
||
|
|
OpenAI 사용 시:
|
||
|
|
|
||
|
|
| 변수 | 설명 |
|
||
|
|
|---|---|
|
||
|
|
| `LLM_PROVIDER=openai` | LLM provider |
|
||
|
|
| `LLM_API_KEY` | OpenAI API key |
|
||
|
|
| `ONTOCAST_WORKING_DIRECTORY` | 작업 디렉터리 |
|
||
|
|
|
||
|
|
### 15.2 LLM 설정
|
||
|
|
|
||
|
|
| 변수 | 기본값 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| `LLM_PROVIDER` | `openai` | `openai`, `ollama` |
|
||
|
|
| `LLM_MODEL_NAME` | `gpt-4o-mini` | 모델명 |
|
||
|
|
| `LLM_TEMPERATURE` | `0.0` | temperature |
|
||
|
|
| `LLM_BASE_URL` | `None` | Ollama 등 custom endpoint |
|
||
|
|
| `LLM_API_KEY` | `None` | provider API key |
|
||
|
|
|
||
|
|
### 15.3 서버 설정
|
||
|
|
|
||
|
|
| 변수/필드 | 기본값 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| `PORT` | `8999` | API server port |
|
||
|
|
| `base_recursion_limit` | `1000` | LangGraph recursion limit base |
|
||
|
|
| `estimated_chunks` | `30` | chunk 수 추정 |
|
||
|
|
| `max_visits_per_node` | `1` | renderer/critic 재시도 횟수 |
|
||
|
|
| `render_mode` | `ontology_and_facts` | 처리 모드 |
|
||
|
|
| `ontology_max_triples` | `50000` | ontology graph 최대 triple |
|
||
|
|
| `parallel_workers` | `4` | content unit 병렬 worker |
|
||
|
|
| `enable_ontology_consolidation` | `false` | 후처리 consolidation |
|
||
|
|
|
||
|
|
### 15.4 Triple Store 설정
|
||
|
|
|
||
|
|
Fuseki:
|
||
|
|
|
||
|
|
| 변수 | 설명 |
|
||
|
|
|---|---|
|
||
|
|
| `FUSEKI_URI` | Fuseki endpoint |
|
||
|
|
| `FUSEKI_AUTH` | 인증 정보 |
|
||
|
|
| `FUSEKI_DATASET` | facts dataset |
|
||
|
|
| `FUSEKI_ONTOLOGIES_DATASET` | ontology dataset |
|
||
|
|
|
||
|
|
Neo4j:
|
||
|
|
|
||
|
|
| 변수 | 설명 |
|
||
|
|
|---|---|
|
||
|
|
| `NEO4J_URI` | Neo4j URI |
|
||
|
|
| `NEO4J_AUTH` | 인증 정보 |
|
||
|
|
| `NEO4J_PORT` | HTTP port |
|
||
|
|
| `NEO4J_BOLT_PORT` | Bolt port |
|
||
|
|
|
||
|
|
Filesystem:
|
||
|
|
|
||
|
|
| 변수 | 설명 |
|
||
|
|
|---|---|
|
||
|
|
| `ONTOCAST_WORKING_DIRECTORY` | graph 저장/작업 디렉터리 |
|
||
|
|
| `ONTOCAST_ONTOLOGY_DIRECTORY` | ontology 파일 디렉터리 |
|
||
|
|
|
||
|
|
### 15.5 Aggregation 설정
|
||
|
|
|
||
|
|
| 변수 | 기본값 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| `AGG_EMBEDDING_MODEL` | `paraphrase-multilingual-MiniLM-L12-v2` | entity embedding 모델 |
|
||
|
|
| `AGG_SIMILARITY_THRESHOLD` | `0.80` | clustering threshold |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 16. 데이터 모델 명세
|
||
|
|
|
||
|
|
### 16.1 ContentUnit
|
||
|
|
|
||
|
|
구현 위치: `onto/content_unit.py`
|
||
|
|
|
||
|
|
역할: 문서 chunk 또는 ontology/facts unit 표현
|
||
|
|
|
||
|
|
핵심 필드:
|
||
|
|
|
||
|
|
- `text`
|
||
|
|
- `index`
|
||
|
|
- `doc_iri`
|
||
|
|
- `graph`
|
||
|
|
- `type`
|
||
|
|
- `iri`
|
||
|
|
|
||
|
|
### 16.2 RDFGraph
|
||
|
|
|
||
|
|
구현 위치: `onto/rdfgraph.py`
|
||
|
|
|
||
|
|
역할: rdflib Graph 확장
|
||
|
|
|
||
|
|
주요 기능:
|
||
|
|
|
||
|
|
- Turtle parse/serialize
|
||
|
|
- prefix/namespace sanitize
|
||
|
|
- known prefix patching
|
||
|
|
- `+=` 연산 지원 테스트 존재
|
||
|
|
|
||
|
|
### 16.3 Ontology
|
||
|
|
|
||
|
|
구현 위치: `onto/ontology.py`
|
||
|
|
|
||
|
|
역할: RDFGraph + ontology metadata + version lineage
|
||
|
|
|
||
|
|
### 16.4 BudgetTracker
|
||
|
|
|
||
|
|
구현 위치: `onto/state.py`
|
||
|
|
|
||
|
|
역할:
|
||
|
|
|
||
|
|
- LLM call 수
|
||
|
|
- 송수신 문자 수
|
||
|
|
- ontology/facts triple 생성 수
|
||
|
|
- ontology/facts operation 수
|
||
|
|
|
||
|
|
### 16.5 Suggestions / TripleFix
|
||
|
|
|
||
|
|
구현 위치: `onto/model.py`
|
||
|
|
|
||
|
|
역할:
|
||
|
|
|
||
|
|
- critic output을 renderer 재시도 prompt에 연결
|
||
|
|
- source text evidence 기반 개선 지시 저장
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 17. 테스트 분석
|
||
|
|
|
||
|
|
테스트 폴더 기준 주요 검증 영역:
|
||
|
|
|
||
|
|
| 테스트 | 검증 대상 |
|
||
|
|
|---|---|
|
||
|
|
| `test_pipeline.py` | 전체 pipeline 흐름 |
|
||
|
|
| `test_agent_facts.py` | facts agent |
|
||
|
|
| `test_ontology_manager.py` | ontology manager |
|
||
|
|
| `test_ontology_lineage_refresh.py` | ontology lineage/hash |
|
||
|
|
| `test_graph_update.py` | GraphUpdate 적용 |
|
||
|
|
| `test_merge_ontologies.py` | ontology merge |
|
||
|
|
| `test_semantic_chunker.py` | semantic chunking |
|
||
|
|
| `test_rdfgraph_iadd.py` | RDFGraph 연산 |
|
||
|
|
| `aggregation/test_*.py` | entity clustering, normalizer, rewriter, provenance, URI builder |
|
||
|
|
|
||
|
|
품질 판단:
|
||
|
|
|
||
|
|
- 핵심 단위 테스트는 존재한다.
|
||
|
|
- 플랫폼에 가져올 때는 API contract test, storage integration test, 대용량 batch test, Korean document extraction test를 추가해야 한다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 18. 범용 온톨로지 구축 플랫폼에 가져올 기능
|
||
|
|
|
||
|
|
### 18.1 1순위: 거의 원형 유지
|
||
|
|
|
||
|
|
| 기능 | 가져올 모듈 | 이유 |
|
||
|
|
|---|---|---|
|
||
|
|
| RDF graph/ontology 모델 | `onto/rdfgraph.py`, `onto/ontology.py` | 플랫폼 핵심 domain model |
|
||
|
|
| AgentState/UnitState | `onto/state.py`, `onto/unit_states.py` | workflow state 표준화 |
|
||
|
|
| GraphUpdate/SPARQL 모델 | `onto/sparql_models.py` | LLM 기반 증분 갱신의 핵심 |
|
||
|
|
| LangGraph workflow | `stategraph/` | 문서 처리 pipeline 기본 골격 |
|
||
|
|
| ontology/facts renderer/critic | `agent/render_*`, `agent/criticise_*` | LLM agent 핵심 기능 |
|
||
|
|
| ToolBox | `toolbox.py` | dependency wiring |
|
||
|
|
| triple manager interface | `tool/triple_manager/` | storage abstraction |
|
||
|
|
| aggregation | `tool/agg/` | entity disambiguation |
|
||
|
|
| cache/budget | `tool/cache.py`, `tool/llm.py`, `BudgetTracker` | 운영 비용 관리 |
|
||
|
|
|
||
|
|
### 18.2 2순위: 수정 후 도입
|
||
|
|
|
||
|
|
| 기능 | 수정 필요 |
|
||
|
|
|---|---|
|
||
|
|
| `select_ontology.py` | None 선택 index 버그 가능성 수정 |
|
||
|
|
| `convert_document.py` | 다중 파일/corpus 처리 모델로 확장 |
|
||
|
|
| API 서버 | 인증, 작업 ID, 비동기 job queue, progress endpoint 추가 |
|
||
|
|
| Config | 프로젝트별 저장 설정, secret vault, UI 설정과 통합 |
|
||
|
|
| External evidence | source trust policy, 검색 provenance 저장 |
|
||
|
|
| Versioning | approval workflow, diff UI, rollback 기능 연결 |
|
||
|
|
|
||
|
|
### 18.3 3순위: 참고만 할 기능
|
||
|
|
|
||
|
|
| 기능 | 이유 |
|
||
|
|
|---|---|
|
||
|
|
| Robyn 서버 구조 | FastAPI 기반 기존 플랫폼이면 API layer는 재작성 가능 |
|
||
|
|
| CLI 일부 | 플랫폼 관리 CLI로 재설계 필요 |
|
||
|
|
| docs auto-generation | 당장 핵심 기능은 아님 |
|
||
|
|
| Docker 예시 | 운영 환경에 맞춰 재구성 필요 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 19. 플랫폼 확장 설계 제안
|
||
|
|
|
||
|
|
### 19.1 목표 플랫폼 모듈
|
||
|
|
|
||
|
|
범용 온톨로지 구축 플랫폼은 OntoCast 코어 위에 다음 계층을 추가하는 형태가 적합하다.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TB
|
||
|
|
UI[Ontology Studio UI] --> API[Platform API]
|
||
|
|
API --> JOB[Job Queue / Worker]
|
||
|
|
API --> PROJECT[Project & Dataset Manager]
|
||
|
|
JOB --> ONTOCAST[OntoCast Core Engine]
|
||
|
|
ONTOCAST --> RDF[RDF Store / Fuseki]
|
||
|
|
ONTOCAST --> NEO[Neo4j Projection]
|
||
|
|
ONTOCAST --> FS[Artifact Storage]
|
||
|
|
API --> REVIEW[Human Review Workflow]
|
||
|
|
REVIEW --> RDF
|
||
|
|
```
|
||
|
|
|
||
|
|
### 19.2 추가해야 할 상위 기능
|
||
|
|
|
||
|
|
| 영역 | 필요 기능 |
|
||
|
|
|---|---|
|
||
|
|
| 프로젝트 관리 | ontology project, dataset, namespace, domain policy |
|
||
|
|
| 문서 수집 | 파일 업로드, 웹 크롤링, URL ingestion, batch import |
|
||
|
|
| 작업 관리 | job 생성, 상태 조회, 취소, 재시도, 로그 |
|
||
|
|
| 온톨로지 스튜디오 | class/property/entity 편집, graph diff, 승인 |
|
||
|
|
| 품질 검수 | critic report UI, human feedback, source evidence 확인 |
|
||
|
|
| 버전 관리 | semantic version, hash lineage, rollback, release |
|
||
|
|
| 저장소 | Fuseki canonical RDF, Neo4j projection, artifact store |
|
||
|
|
| 검색/RAG | SPARQL query, graph search, GraphRAG endpoint |
|
||
|
|
| 운영 | 비용 추적, LLM call audit, cache 관리 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 20. 정확한 기능명세
|
||
|
|
|
||
|
|
### 20.1 문서 처리 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | 설명 | 입력 | 출력 |
|
||
|
|
|---|---|---|---|---|
|
||
|
|
| DOC-001 | 문서 업로드 처리 | API로 받은 JSON/multipart 파일을 처리 대상으로 등록 | file 또는 JSON body | AgentState.files |
|
||
|
|
| DOC-002 | 문서 변환 | PDF/지원 파일을 markdown/text로 변환 | bytes | text |
|
||
|
|
| DOC-003 | JSON 문서 파싱 | JSON의 `text`, `url`, instruction 필드를 추출 | JSON bytes | input_text, source_url, instructions |
|
||
|
|
| DOC-004 | 텍스트 청킹 | 입력 텍스트를 content unit 목록으로 분할 | input_text | list[ContentUnit] |
|
||
|
|
| DOC-005 | 청크 수 제한 | head chunks만 처리 | max_chunks | 제한된 content_units |
|
||
|
|
|
||
|
|
### 20.2 온톨로지 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | 설명 | 입력 | 출력 |
|
||
|
|
|---|---|---|---|---|
|
||
|
|
| ONT-001 | 온톨로지 목록 로드 | filesystem/triple store에서 ontology 목록 로드 | ontology directory/store | OntologyManager.ontologies |
|
||
|
|
| ONT-002 | 온톨로지 속성 보강 | title/id/description 누락 시 LLM으로 요약 | RDF graph | OntologyProperties |
|
||
|
|
| ONT-003 | 온톨로지 선택 | 문서 excerpt와 ontology 목록을 보고 적합 ontology 선택 | content_units, ontologies | current_ontology |
|
||
|
|
| ONT-004 | 신규 온톨로지 생성 | 기존 ontology가 없으면 fresh ontology 생성 | text chunk | Ontology |
|
||
|
|
| ONT-005 | 온톨로지 증분 갱신 | 기존 ontology에 필요한 class/property 변경 생성 | ontology graph, text | GraphUpdate |
|
||
|
|
| ONT-006 | 온톨로지 비평 | ontology 품질 평가 및 개선안 생성 | ontology, text | OntologyCritiqueReport |
|
||
|
|
| ONT-007 | 온톨로지 재시도 | critic suggestions를 renderer에 반영해 재생성 | Suggestions | updated ontology/update |
|
||
|
|
| ONT-008 | 온톨로지 delta 병합 | unit별 ontology delta를 하나의 graph로 병합 | ontology_units | normalized ontology |
|
||
|
|
| ONT-009 | provenance 분리 | reification/provenance triple을 ontology graph에서 side graph로 분리 | RDFGraph | clean graph, provenance graph |
|
||
|
|
| ONT-010 | 온톨로지 consolidation | 중복/겹침 class/property를 정리 | ontology, excerpt | consolidated ontology |
|
||
|
|
| ONT-011 | 온톨로지 versioning | 변경 graph에서 새 version/hash 생성 | old ontology, new graph | updated ontology |
|
||
|
|
| ONT-012 | 온톨로지 저장 | ontology를 filesystem/Fuseki/Neo4j에 저장 | Ontology | persisted graph |
|
||
|
|
|
||
|
|
### 20.3 Facts 추출 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | 설명 | 입력 | 출력 |
|
||
|
|
|---|---|---|---|---|
|
||
|
|
| FACT-001 | Fresh facts 생성 | 빈 content unit graph에 facts Turtle 생성 | ontology, text | RDFGraph |
|
||
|
|
| FACT-002 | Facts 증분 갱신 | 기존 facts graph에 SPARQL update 생성 | facts graph, ontology, text | GraphUpdate |
|
||
|
|
| FACT-003 | Facts 비평 | facts graph가 원문을 잘 반영하는지 평가 | facts graph, ontology, text | FactsCritiqueReport |
|
||
|
|
| FACT-004 | Facts 재시도 | critic suggestions 반영 후 renderer 재실행 | Suggestions | revised facts graph |
|
||
|
|
| FACT-005 | 병렬 facts 처리 | content unit별 facts loop 병렬 실행 | content_units | parallel_facts_units |
|
||
|
|
| FACT-006 | Facts 병합 | unit graph를 entity disambiguation 후 통합 | parallel_facts_units | aggregated_facts |
|
||
|
|
| FACT-007 | Facts 저장 | aggregated facts를 store에 저장 | RDFGraph | persisted facts graph |
|
||
|
|
|
||
|
|
### 20.4 Entity Aggregation 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| AGG-001 | entity 수집 | graph 내 URIRef entity 수집 |
|
||
|
|
| AGG-002 | entity representation 생성 | label, type, graph context를 이용해 정규화 표현 생성 |
|
||
|
|
| AGG-003 | embedding 생성 | sentence-transformers로 entity vector 생성 |
|
||
|
|
| AGG-004 | candidate clustering | similarity threshold 기반 cluster 후보 생성 |
|
||
|
|
| AGG-005 | symbolic validation | role/type/lexical alias 기준으로 잘못된 merge 방지 |
|
||
|
|
| AGG-006 | canonical 선택 | ontology entity 우선, 단순 URI 우선 등 기준으로 대표 선택 |
|
||
|
|
| AGG-007 | URI 정규화 | role별 PascalCase/camelCase/instance URI 생성 |
|
||
|
|
| AGG-008 | graph rewrite | old entity URI를 canonical URI로 치환 |
|
||
|
|
| AGG-009 | sameAs 생성 | 병합 관계를 `owl:sameAs`로 보존 |
|
||
|
|
|
||
|
|
### 20.5 저장소 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| STORE-001 | ontology fetch | 저장소에서 ontology 목록 조회 |
|
||
|
|
| STORE-002 | graph serialize | RDFGraph 저장 |
|
||
|
|
| STORE-003 | ontology serialize | Ontology 저장 |
|
||
|
|
| STORE-004 | dataset flush | 저장소 데이터 삭제 |
|
||
|
|
| STORE-005 | Fuseki dataset switching | 요청별 dataset 변경 |
|
||
|
|
| STORE-006 | filesystem sync | filesystem ontology를 triple store로 동기화 |
|
||
|
|
|
||
|
|
### 20.6 API 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | Endpoint |
|
||
|
|
|---|---|---|
|
||
|
|
| API-001 | health check | `GET /health` |
|
||
|
|
| API-002 | service info | `GET /info` |
|
||
|
|
| API-003 | document process | `POST /process` |
|
||
|
|
| API-004 | triple store flush | `POST /flush` |
|
||
|
|
|
||
|
|
### 20.7 운영/관측 기능
|
||
|
|
|
||
|
|
| ID | 기능명 | 설명 |
|
||
|
|
|---|---|---|
|
||
|
|
| OBS-001 | LLM usage tracking | call 수, 송수신 문자 수 추적 |
|
||
|
|
| OBS-002 | triple generation tracking | ontology/facts triple 수 추적 |
|
||
|
|
| OBS-003 | operation tracking | GraphUpdate operation 수 추적 |
|
||
|
|
| OBS-004 | failure stage tracking | 실패 단계와 원인 저장 |
|
||
|
|
| OBS-005 | LLM cache | 동일 prompt/config 응답 캐싱 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 21. 발견된 리스크 및 보완점
|
||
|
|
|
||
|
|
### 21.1 코드상 주의점
|
||
|
|
|
||
|
|
1. `select_ontology.py`의 None 선택 index 불일치 가능성
|
||
|
|
- dynamic model은 `1..num_ontologies+1`을 허용하지만 코드에는 `answer_index == 0` 처리 분기가 있다.
|
||
|
|
- 도입 전 수정 필요.
|
||
|
|
|
||
|
|
2. API version 표기 불일치
|
||
|
|
- `pyproject.toml` 버전은 `0.3.0`인데 `/health`, `/info`는 `0.1.1`을 반환한다.
|
||
|
|
- 플랫폼에서는 package version을 단일 source of truth로 연결해야 한다.
|
||
|
|
|
||
|
|
3. `convert_document()`의 다중 파일 처리 한계
|
||
|
|
- 내부 주석상 one file 처리.
|
||
|
|
- 다중 문서 corpus ingestion에는 부적합.
|
||
|
|
|
||
|
|
4. 서버 API가 동기적인 긴 처리에 가까움
|
||
|
|
- `/process`가 workflow 완료 후 응답한다.
|
||
|
|
- 대용량 문서/다중 파일에서는 job queue와 progress endpoint가 필요하다.
|
||
|
|
|
||
|
|
5. 인증/권한 없음
|
||
|
|
- 오픈소스 코어 서버이므로 플랫폼 운영에는 인증, tenant, 프로젝트 권한이 필요하다.
|
||
|
|
|
||
|
|
6. `/flush` 위험성
|
||
|
|
- 인증 없이 연결하면 전체 triple store 삭제 가능.
|
||
|
|
- 운영 API에서는 관리자 권한과 confirmation token이 필요하다.
|
||
|
|
|
||
|
|
### 21.2 기능적 한계
|
||
|
|
|
||
|
|
- ontology 편집 UI 없음
|
||
|
|
- human-in-the-loop 승인 흐름 없음
|
||
|
|
- ontology schema constraint/SHACL 검증은 핵심 흐름에 보이지 않음
|
||
|
|
- 작업 이력/감사 로그 부족
|
||
|
|
- Korean domain 문서에 대한 prompt/평가 최적화는 별도 필요
|
||
|
|
- 다국어 embedding 모델은 기본값이 multilingual이지만 ontology term naming policy는 영어 중심으로 보임
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 22. 도입 로드맵 제안
|
||
|
|
|
||
|
|
### Phase 1. 코어 이식
|
||
|
|
|
||
|
|
- `onto/`, `agent/`, `stategraph/`, `tool/` 핵심 모듈을 별도 package로 이식
|
||
|
|
- Apache 2.0 license notice 유지
|
||
|
|
- `select_ontology` index bug 수정
|
||
|
|
- package version/API version 정리
|
||
|
|
- Korean prompt profile 추가
|
||
|
|
|
||
|
|
### Phase 2. 플랫폼 API 래핑
|
||
|
|
|
||
|
|
- 기존 Robyn API를 직접 쓰기보다 현재 프로젝트 API framework에 service layer로 연결
|
||
|
|
- `/jobs` 기반 비동기 실행 구조 도입
|
||
|
|
- 작업 상태, 로그, budget, output artifact 저장
|
||
|
|
|
||
|
|
### Phase 3. 저장소 전략 확정
|
||
|
|
|
||
|
|
- Fuseki를 canonical RDF store로 사용
|
||
|
|
- Neo4j는 projection/search/RAG용 선택 저장소로 사용
|
||
|
|
- filesystem은 artifact/debug output으로 사용
|
||
|
|
|
||
|
|
### Phase 4. 검수/편집 UI
|
||
|
|
|
||
|
|
- ontology graph viewer
|
||
|
|
- class/property/entity editor
|
||
|
|
- GraphUpdate diff viewer
|
||
|
|
- critic suggestion accept/reject
|
||
|
|
- source text evidence 연결
|
||
|
|
|
||
|
|
### Phase 5. 운영 고도화
|
||
|
|
|
||
|
|
- project/tenant/permission
|
||
|
|
- cache 관리
|
||
|
|
- LLM cost dashboard
|
||
|
|
- batch ingestion
|
||
|
|
- rollback/release workflow
|
||
|
|
- SHACL/OWL reasoning validation
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 23. 권장 아키텍처 명세
|
||
|
|
|
||
|
|
범용 온톨로지 구축 플랫폼에서 OntoCast를 다음처럼 배치한다.
|
||
|
|
|
||
|
|
| 계층 | 구현 |
|
||
|
|
|---|---|
|
||
|
|
| Core Engine | OntoCast의 `agent`, `stategraph`, `onto`, `tool` |
|
||
|
|
| Platform Service | 작업 생성/조회/검수/승인 API |
|
||
|
|
| Storage | Fuseki canonical RDF, Neo4j projection, artifact filesystem/S3 |
|
||
|
|
| UI | ontology studio, extraction review, graph diff |
|
||
|
|
| Worker | OntoCast workflow 실행, batch 처리 |
|
||
|
|
| Governance | versioning, approval, lineage, audit |
|
||
|
|
|
||
|
|
Core Engine의 public interface는 다음 정도로 단순화하는 것이 좋다.
|
||
|
|
|
||
|
|
```python
|
||
|
|
class OntologyBuildService:
|
||
|
|
async def process_document(
|
||
|
|
self,
|
||
|
|
project_id: str,
|
||
|
|
dataset_id: str,
|
||
|
|
text: str,
|
||
|
|
source_url: str | None,
|
||
|
|
render_mode: str,
|
||
|
|
ontology_instruction: str,
|
||
|
|
facts_instruction: str,
|
||
|
|
) -> OntologyBuildResult:
|
||
|
|
...
|
||
|
|
```
|
||
|
|
|
||
|
|
반환 모델:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class OntologyBuildResult:
|
||
|
|
status: str
|
||
|
|
ontology_ttl: str
|
||
|
|
facts_ttl: str
|
||
|
|
ontology_version: str | None
|
||
|
|
ontology_hash: str | None
|
||
|
|
graph_uri: str
|
||
|
|
chunks_processed: int
|
||
|
|
budget: dict
|
||
|
|
warnings: list[str]
|
||
|
|
critique_summary: str | None
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 24. 최종 평가
|
||
|
|
|
||
|
|
OntoCast는 “문서 기반 온톨로지/지식그래프 자동 구축 엔진”으로 매우 직접적인 참고 가치가 있다. 특히 GraphUpdate 기반 증분 갱신, renderer/critic retry loop, content unit 병렬 처리, entity aggregation은 앞으로 만들 범용 온톨로지 구축 플랫폼의 핵심 엔진으로 적합하다.
|
||
|
|
|
||
|
|
가져갈 때의 전략은 “API 서버까지 그대로 제품화”가 아니라 “core package를 거의 원형 유지하면서 플랫폼 서비스 계층으로 감싸기”가 가장 좋다. 이렇게 하면 오픈소스의 검증된 처리 흐름은 살리고, 우리 프로젝트에 필요한 프로젝트 관리, 검수 UI, 저장소 정책, 권한, 배치 운영은 별도로 안정적으로 얹을 수 있다.
|