티스토리 뷰

온톨로지를 단순히 개념이 아니라 사용할 수 있게 하려면 지식그래프를 구축해야한다.

다만, 그래프에 데이터를 어떻게 넣고, 어떻게 최신으로 유지할 것인가?

GraphRAG의 답변 품질은 결국 그래프가 현실을 얼마나 반영하느냐에 묶여 있기 때문이다. 어제 배치로 만든 그래프는 실시간이 아니다. 논리적으로 완벽하게 맞는 답이 사실은 오답일 수 있다. 인사 발령이 오늘 났는데 그래프가 지난주 상태라면, 아무리 SHACL 검증을 통과해도 틀린 답이 나간다.

 

내가 아는 한 이 문제에 대한

접근은 크게 세 갈래다. 정답이 있는 게 아니라 각자 다른 선택지들이라 이번 글은 셋을 나란히 놓고 비교해보려 한다.


경로 1. 변환 후 적재 (ETL/ELT)

가장 전통적이고, 지금도 대부분의 서비스가 쓰는 방식이다. 원천 데이터(RDB, CSV, API 응답 등)를 트리플로 변환해서 트리플스토어(또는 그래프 DB)에 적재한다. RDB라면 R2RML이나 RML 매핑으로 변환하고, CSV와 같은 파일이라면 python의 rdflib과 같은 라이브러리르 활용하여 변환-적재 사이클을 배치로 주기 실행한다.

 

구조만 보면 검색엔진과 비슷하다. 검색엔진이 원본 웹페이지를 크롤링해서 인덱스를 만들어 두듯이, 원본 데이터를 미리 그래프 형태로 "인덱싱"해 두는 것이다. 실제로 장점도 검색엔진의 장점과 같다.

  • 쿼리가 빠르다. 조회 시점에는 변환 비용이 없다. 그래프 탐색, 다중 홉 쿼리에 최적화된 저장소를 그대로 쓴다
  • 추론을 미리 돌릴 수 있다. 전이 속성, 상속 같은 OWL 추론 결과를 적재 시점에 물질화(materialize)해두면 조회는 더 빨라진다
  • 원천 시스템에 부하를 안 준다. 운영 DB는 배치 시점에만 읽는다

단점도 명확하다.

  • 데이터가 이중으로 생긴다. 원본 따로, 그래프 따로. 저장 비용은 둘째치고, 두 사본의 정합성을 관리하는 일 자체가 운영 업무가 된다
  • 시차(staleness)가 생긴다. 배치 주기가 하루면 최대 하루 낡은 데이터로 답한다. 주기를 줄이면 되지만, 줄일수록 파이프라인 비용이 올라간다
  • 파이프라인이 자산이자 부채다. 원천 스키마가 바뀔 때마다 매핑과 변환 코드를 따라 고쳐야 한다

정리하면, 변환 적재는 읽기 성능과 데이터 최신성을 맞바꾸는 선택이다. 마스터 데이터, 표준 분류체계, 규정처럼 잘 안 바뀌는 지식에는 사실 이걸로 충분하다.

경로 2. OBDA  가상 그래프로 실시간 질의

DB가 이미 잘 돌아가고 있다면 다른 선택지가 있다. OBDA(Ontology-Based Data Access)는 데이터를 옮기지 않는다.

대신 "RDB의 이 테이블·컬럼이 온톨로지의 이 클래스·속성에 해당한다"는 매핑(R2RML)을 선언해 두고, SPARQL 쿼리가 들어오면 그 자리에서 SQL로 재작성해 원천 DB에서 바로 실행한다. 그래프는 실체가 아니라 뷰(view)로만 존재한다. 대표 구현이 Ontop이고, 상용으로는 Stardog의 가상 그래프 기능 등이 있다.

 

- OBDA: https://milvus.io/ai-quick-reference/what-is-ontologybased-data-access-in-knowledge-graphs

- Ontop: https://ontop-vkg.org/guide/advanced/mapping-language.html

 

매핑이 어떻게 생겼는지 감만 잡자면 이런 식이다 (Ontop의 축약 문법)

mappingId   emp-mapping
target      :emp/{emp_id} a :Employee ; :worksIn :dept/{dept_id} .
source      SELECT emp_id, dept_id FROM employees

이렇게 선언해두면 ?e a :Employee ; :worksIn ?d 같은 SPARQL이 자동으로 SELECT ... FROM employees ... SQL로 바뀌어 실행된다.

 

장점은 변환 적재의 단점을 뒤집은 것이다.

  • 항상 최신이다. 조회 시점의 DB 상태를 그대로 본다. 인사 발령이 방금 났어도 다음 쿼리에 바로 반영된다. 변동이 잦은 트랜잭션·운영 데이터에 적합하다
  • 데이터 이중화가 없다. 원본만 관리하면 된다. 바뀌는 건 데이터가 아니라 매핑이다

대신 단점이 있다.

  • 데이터가 크고 쿼리가 복잡해질수록 느려진다. SPARQL의 다중 홉 탐색이 SQL로 재작성되면 다단계 JOIN이 되는데, 재작성된 SQL이 원천 DB에 그대로 부하로 꽂힌다. 온톨로지 계층이 깊으면 재작성 결과가 UNION 폭발을 일으키기도 한다
  • 추론 표현력이 제한된다. 실시간 재작성이 가능하려면 OWL 2 QL 프로파일 수준으로 공리를 제한해야 한다. 복잡한 공리는 못 쓴다(다만, 이정도 수준까지 요구할 정도의 복잡성이라면,,다른 방법을 고려하는게 좋다고 생각함)
  • 비정형 데이터는 처리할 수 없다. 매핑은 정형 스키마를 전제한다. 문서, 이메일, 회의록은 OBDA의 범위 밖이다

정리하면, OBDA는 최신성과 단일 원본 관리를 얻는 대신 조회 성능과 표현력을 내주는 선택이다.

경로 3. 비정형 문서에서 바로 트리플 추출

최근 하나의 축으로 떠오른 방식이다. LLM에게 문서를 주고 (주어, 술어, 목적어) 트리플을 직접 뽑게 한다. Microsoft GraphRAG의 인덱싱 단계가 이러한 방식이고, LlamaIndex의 KG 구축, 각종 오픈소스 KG builder들이 같은 축에 있다.

 

이 방식이 주목받는 이유는 단순하다. 기업 지식의 대부분은 정형 DB가 아니라 문서에 있다. 예:계약서, 보고서, 회의록, 위키

 

문제는 품질이다.

  • 환각 트리플. 문서에 없는 관계를 만들어내거나, 방향을 뒤집거나(A가 B를 인수 ↔ B가 A를 인수), 관계명을 제멋대로 짓는다
  • 엔티티 정규화(entity resolution). "삼성전자", "삼성전자(주)", "Samsung Electronics"가 서로 다른 노드로 들어간다. 온톨로지의 URI 고유 식별 원칙이 추출 단계에서 무너진다
  • 스키마 표류. 추출을 반복할수록 비슷한데 다른 술어들(worksAt, employedBy, memberOf)이 쌓인다

즉 경로 3은 지식의 커버리지를 극적으로 넓히는 대신 검증 부담을 후단으로 넘기는 선택이다.

그래서 뭘 골라야 하나

셋 중 하나를 고른다기보다는 데이터의 성격에 따라 적절히 활용해야한다고 생각한다.

 

  기준 변환 적재 (ETL) OBDA 가상화 LLM 직접 추출
데이터 형태 정형/반정형 정형 (RDB) 비정형 (문서)
최신성 배치 주기만큼 낡음 실시간 추출 시점 고정
조회 성능 빠름 데이터·쿼리 복잡도에 반비례 적재 후엔 빠름
데이터 사본 이중화 발생 없음 이중화 발생
추론 표현력 제한 없음 (사전 물질화 가능) OWL 2 QL 수준 그래프 적재 방식을 따름
주요 리스크 파이프라인 유지비, 시차 원천 DB 부하, 복잡 쿼리 성능 환각 트리플, 엔티티 정규화

 

그래서 내가 현실적이라고 보는 그림은 하이브리드다.

  • 잘 안 바뀌는 지식(표준 분류, 규정, 마스터 데이터) → 변환 적재로 트리플스토어에. 추론도 미리 계산
  • 계속 바뀌는 운영 데이터(트랜잭션, 배치 현황, 재고) → OBDA로 가상화해서 조회 시점에 결합
  • 문서 속 지식 → LLM 추출로 편입하되, 반드시 검증 계층을 거쳐서

그리고 SPARQL의 연합 질의(federated query, SERVICE 절)나 다른 코드 기반의 방식으로 이 셋을 한 쿼리에서 묶는 단계가 필요하다. 정적 그래프를 탐색하다가 실시간 속성이 필요한 지점에서만 OBDA 엔드포인트를 호출하는 식이다.

다음 글

이번 글은 그래프를 어떻게 만드는가에 대한 것이었다. 다음 문제는 "어떻게 추출하는가"이다. 자연어 질문을 SPARQL로 바꾸는 일은 text2SQL의 그래프판인데, LLM이 생성한 쿼리가 스키마를 무시하고 존재하지 않는 속성을 지어내는 문제가 그대로 있다.

 

다음편은 온톨로지 특성을 활용하기 위해 domain/range를 이용해 생성된 쿼리를 실행 전에 타입 검사하는 방법을 다룬다.

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함