AIA 보험 온톨로지 설계 - 보고서

AIA 보험 온톨로지 설계 - 보고서

대상 도메인: 계약정보 (parse/ 폴더, 21개 문서)

1. 현재까지 구현해본 방법론과 새로 알게 된 내용

기존 벡터 DB 기반 RAG(청크 임베딩 → 코사인 유사도 검색)로 AIA 보험 업무 매뉴얼 질의응답을 구현했다. 구현해보며 약할 것 이라고 생각한 부분 -> 멀티홉 추론 검색 (여러 사실을 순서대로 연결해야 답이 나오는 질문) 벡터 유사도는 질문과 의미상 가까운 텍스트를 찾는다. A->B, B->C일때 A->C와 같은 구조화된 다단계 추론을 DB단에서 못한다. 멀티홉을 구현해 매번 LLM이 텍스트를 다시 읽고 그 자리에서 재구성해야 했다.

  1. 질문마다 반복되는 비용
  2. 확률적 추론이라 매번 다른 답이 나올 위험
  3. 홉이 늘어날수록 하나만 잘못 읽어도 전체가 틀리는 취약성

이 멀티홉 구조를 매번 LLM이 새로 추론하게 두지 않고, 설계 시점에 그래프 구조로 한 번 고정해두면, 질의 시점에는 LLM이 아니라 그래프 엔진이 정해진 경로를 탐색하기만 하면 된다. ex. Neo4j의 인덱스프리 인접성(각 노드가 이웃으로 가는포인터를 물리적으로 갖고 있는 구조) 또한 RDB의 JOIN처럼 데이터가 늘어날수록 느려지지 않는다.

다만 멀티홉이 필요 없는 롱테일 예외 질문(자유 의미 검색)에는 벡터 검색이 여전히 유리하다고 생각이 된다. 그래서 최종적으로는 벡터 검색 + 그래프 검색 하이브리드가 목표 구조다. 어떻게할까? 저장 기술은 Neo4j(LPG)로 정하고 문서자체가 스키마 관계 속성(허용여부/채널/적용역할/효과유형 등)을 많이 쓰는 구조라 RDF의 순수 트리플 모델보다는 프로퍼티식 LPG 형식으로 진행했다..


2. 설계 방법론 — Middle-out (Top-down + Bottom-up)

2.1 왜 순수 Bottom-up이 아닌가

문서에 등장하는 명사를 그대로 클래스로 만드는 방식(순수 bottom-up)은 그 문서 하나만 보면 정확하지만, 문서가 많아지면(현재 21개, 최종 92개) 문제가 생긴다 — 같은 업무를 부서/작성자/시점마다 다르게 표현하기 때문에, 표현 차이를 걸러줄 기준점이 없으면 같은 개념이 계속 다른 이름의 클래스/데이터로 쪼개지는 치명적인 오류가 생긴다.(파편화).

2.2 실제 진행 순서

  1. Competency Question(CQ) 먼저 정의: 문서를 관찰해서 질문을 뽑는 게 아니라, 실무자가 이 업무를 처리할 때 반드시 판단해야 하는 지점(의사결정 포인트)에서 질문을 연역한다. 최종적으로 14개를 산출했다. 예: “이 계약이 지금 감액 가능한 상태인가?”, “누가 신청하고 서류는 뭐가 필요한가?”
  2. CQ에서 최소 클래스 역산: 질문에 답하는 데 최소한 필요한 개체 종류가 무엇인지 LLM과 함께 거꾸로 추적한다. 문서의 모든 명사를 후보로 올리지 않는다.
  3. 관계 domain/range 정의: 관계마다 주체(domain)/대상(range) 클래스를 명시해, 이후 LLM 추출 단계에서 잘못된 관계가 생성되는 걸 원천 차단한다. (시작노드와 끝노드를 정해준 느낌)
  4. 샘플 문서로 검증(bottom-up은 검증 트랙): 대표 문서를 뼈대에 매핑해보고, 안 맞는 게 나올 때만 뼈대를 보강한다. 이 검증은 현재 진행 중이며, 지금까지 21개 문서 중 1개를 검토한 시점에서도 스키마 보강이 필요할 것으로 보인다. 이 현상은 초기 CQ가 모든 걸 다 담지 못하는 것으로 이 반복 자체가 방법론의 일부라고 생각하고 진행중이다.

2.3 효과

클래스 개수를 CQ 기준으로 먼저 고정하면(현재 11개), 문서마다 표현이 달라도 새 클래스가 계속 생기지 않고 기존 클래스 안의 값으로 흡수될 것으로 생각한다. 92개 문서 전체를 넣어도 클래스 개수 자체는 크게 늘지 않을 것으로 예상한다.

이 방법론 자체는 LLM 도메인 지식 없이도 수행 가능한 엔지니어링/설계 프로세스지만 이 표현이 실무상 정확히 무엇을 의미하는가 같은 판단은 도메인 지식이 필요하며, 현재는 LLM의 추론에 의존하며 개발중이다.


3. 확정된 스키마 (계약정보 도메인)

3.1 최상위 클래스 (11개)

계약, 당사자, 계약상태, 업무유형, 신청채널, 구비서류, 규정조건, 재무처리, 통지유형, 전달매체, 계약구성요소

각 클래스는 Pydantic 모델로 엄격하게 정의되도록 설계했다. 값 종류가 제한적인 필드는 Literal로 닫아두고 (예: 신청채널.이름 = 전화/내방/우편/AIA+/이메일/팩스/LMS/ARS 8종 고정)-> Literal에서만 선택을 해야함, 업무유형/구비서류/규정조건.유형/계약구성요소처럼 계속 늘어나는 성격의 필드는 자유문자열로 둔다 -> 정해진 선택지 없이 선택.

3.2 관계 / domain-range (20개)

관계 domain range 비고
계약자이다/피보험자이다/수익자이다/대리인이다/예금주이다 계약 당사자 역할별 관계명. 당사자 노드 자체엔 역할 고정 안 함
현재상태이다 계약 계약상태  
포함한다 계약 계약구성요소  
요구조건 업무유형 규정조건 허브 관계. 규정조건.유형 속성으로 세분화
허용상태 규정조건 계약상태 관계 속성 허용여부(bool)
허용채널 규정조건 신청채널 관계 속성 허용여부(bool)
접수채널 업무유형 신청채널 관계 속성 구분(통신채널/대면채널/셀프보험몰/디지털다이렉트)
요구서류 업무유형 구비서류 관계 속성 채널, 적용역할
추가서류 규정조건 구비서류 이벤트·조건 기반 추가서류(반제금발생, FATCA/CRS 등)
발생시킨다 업무유형 재무처리  
지급조건 재무처리 규정조건  
파급효과 업무유형 계약구성요소 관계 속성 효과유형(감소/소멸/중지/재개)
필요통지 업무유형 통지유형  
진행하지않는다 업무유형 업무유형 업무유형끼리 직접 연결되는 유일한 관계. 방향성 있음(한쪽만 확인됨)
유효매체 통지유형 전달매체 관계 속성 수신자유형
유효성조건 통지유형 규정조건  

역할 조건(미성년자/법인/외국인 등)은 별도 노드 없이 규정조건.적용역할 / 요구서류.적용역할속성으로 처리한다. 원칙: 값(변주가 많은 것)은 속성으로, 여러 노드가 공유·재사용하는 실체는노드로 승격한다.

3.3 Competency Questions

현재 14개 확정(+1개 검토 중). 예를 들어서

  • 특정 계약이 특정 계약변경을 신청 가능한 상태인가?
  • 이 계약변경을 신청하려면 누가, 어떤 서류를, 어떤 채널로 제출해야 하는가?
  • 특정 통지가 어떤 수신자·전달매체를 거쳤을 때 법적으로 유효한 수령으로 인정되는가?
  • (검토 중) 특정 업무를 처리하려는 시점에, 동시 진행 중이면 보류해야 하는 다른 업무가 있는가?

4. 파이프라인 구조

4.1 인입(Ingestion)

문서(.md) → 청킹(헤더 계층형) → LLM 추출(스키마 제약) → Pydantic 검증 → Neo4j 적재

  • 청킹: 페이지 경계 → ##/### 헤더 경계로 재분할. 청크당 사실 밀도를 낮춰 추출 누락을 줄임.
  • 추출: LLM에게 “이 스키마에 맞춰 값을 채워 넣어라”는 매핑 작업만 맡긴다. 클래스명·관계명은 LLM이 새로 만들 수 없다 — 스키마 밖 이름은 검증 단계에서 버린다.
  • 검증: 엔티티는 Pydantic 모델 인스턴스화로 검증(Literal 위반 시 자동 거부). 관계는 이름/domain-range 일치 여부 + 관계 대상 노드의 key 값이 대상 클래스의 타입 제약(Literal)을 만족하는지까지 검증한다.
  • 적재: 동일 키 값은 MERGE로 재사용(중복 노드 생성 안 함). Chunk 노드는 원문+메타데이터를 저장하고 MENTIONS 관계로 실제 인용한 엔티티를 직접 가리킨다 — 출처 추적용(디버깅용).

4.2 질의(Query)

자연어 질문 → LLM이 Cypher 생성(스키마+실제값 목록 주입) → 그래프 실행 → 결과로 답변 생성

  • 시스템 프롬프트에 클래스/관계 정의뿐 아니라 그래프에 실제로 존재하는 값 목록을 주입해, LLM이 이름을 추측하지 않고 정확한 값으로 매칭하게 한다.
  • 생성 쿼리는 읽기 전용(MATCH/WHERE/RETURN 등)만 허용, CREATE/DELETE 등은 차단.
  • LLM은 질문을 정해진 스키마 문법으로 번역만 하고, 실제 멀티홉 탐색은 그래프 엔진이 수행(Neo4j는 인덱스프리 인접성)한다.

5. 엔티티 리졸루션

5.1 문제

NER(추출)과 별개로, 이미 추출된 두 개체가 같은 실체인지 판단하는 단계가 없어서 동일 개념이 표현 차이로 다른 노드로 쪼개지는 문제가 있었다. 특히 빠르게 개발하기위해서 청크를 병렬 처리할 때, 완전히 새로 등장하는 이름을 여러 청크가 동시에 처리하다 서로 다르게 명명하는 경우가 발견됐다 (예: “직무직종/운전차종변경” vs “직종/직무 및 운전차종변경”).

5.2 해결 — 3단계 자동화 파이프라인

  1. 후보 추리기 (로컬 계산, LLM/임베딩 미사용): Kiwi로 형태소 분석해 명사만 추출하고, 전체 이름 집합에서 흔한 단어는 낮은 가중치, 드문 단어는 높은 가중치를 주는 IDF 가중 자카드 유사도로 후보 쌍을 추린다.
    • 벡터 임베딩 대신 이 방식을 택한 이유: 업무 이름처럼 짧은 텍스트는 굳이 의미 벡터가없어도 핵심 단어 중복으로 충분히 잡히고, API 호출 비용이 없으며, 어떤 단어가 겹쳐서 유사하다고 판단했는지 사람이 바로 확인 가능(해석 가능성)하다는 장점이 있다.
    • 그치만 kiwi로 쪼개진다면 다른 의미인데 비슷한 단어가 생겨서 혼동이 올 수도 있을 것이라고 생각한다.
  2. LLM 최종 확인: 후보 쌍마다 “진짜 같은 개념이 맞는가”를 LLM에게 확인시킨다. 확실하지 않으면 병합하지 않는다(틀리게 합치는 것보다 안 합치는 게 안전하다고 판단했다).

  3. 클러스터 병합(union-find): A~B, B~C가 각각 확정된 경우, 쌍을 순서대로 하나씩 병합하면 중간 노드가 먼저 삭제된 뒤 다음 병합이 그 노드를 찾지 못해 데이터가 유실되는 버그가 있었다. union-find로 먼저 전체 그룹(A/B/C)을 파악한 뒤, 그룹 전체를 하나의 캐노니컬 이름으로 한 번에 병합하도록 수정했다.

5.3 결과

업무유형 43→41개, 규정조건 484→467개, 구비서류 163→124개, 계약구성요소 20→18개로 중복 정리.


6. 품질 검증 결과

6.1 업무매뉴얼 Q&A 134개 자동 평가 (자연어→Cypher→답변→LLM judge)

  1차 평가 개선 후
CORRECT 37건 (27.6%) 63건 (47.0%)
PARTIAL 16건 (11.9%) 17건 (12.7%)
WRONG 79건 (59.0%) 54건 (40.3%)
ERROR 2건 (1.5%) 0건 (0%)

1차 평가에서 원인을 분석한 결과, 스키마 설계 문제가 아니라 대부분 실행 단계(추출 품질,Cypher 생성 정확도) 문제로 확인됐다 즉 온톨로지 뼈대 자체는 초기부터 크게 틀리진 않았지만 개념적인 부분이 부족하다고 생각이 들었다

6.2 그래프 탐색 정확도 별도 분석

“정답 문장이 맞았는가”보다 “그래프가 진짜 출처(청크)를 정확히 찾아갔는가”가 온톨로지 검증의 본질에 더 부합한다고 판단해 별도 분석을 수행했다. 결과는 75.4%가 그래프 탐색 성공을 했다. 문장 표현 차이로 WRONG 판정된 것 중에도 63%는 실제로는 그래프가 정확한 개체를 찾은 경우였다(자동 채점 오탐).

6.3 전체 그래프 QC (구조적 무결성)

domain/range 위반 0건, 스키마 밖 라벨/관계 0건, 키 필드 중복 0건, 완전 고립 노드 0건, 관계 boolean 속성 일관성 100%. 스키마(11개 클래스+20개 관계) CQ구조 자체를 다시 만들까라고 생각했지만 아직 확정은 못내리겠다.


7. 발견된 이슈와 해결 (진행 중 트러블슈팅)

설계가 “한 번 정하고 끝”이 아니라 실제 데이터로 계속 검증하며 보강되는 과정이라는 점을 보여주기 위해, 발견 순서대로 정리했다.

7.1 초기 파이프라인 품질 문제 (1차 평가 원인)

  • 계약상태 노드 중복: MERGE 키를 코드로 잡아 같은 “해지” 상태가 코드값이 문서마다 달라 5개 노드로 쪼개짐 → 키를 으로 변경, 코드값은 코드목록 속성으로 통합.
  • Cypher 생성이 그래프에 실제 있는 이름을 모르고 추측 → 실제 값 목록을 프롬프트에 주입.
  • 청크 하나에 여러 규정이 섞여있을 때 LLM이 일부만 추출 → 청킹을 헤더 단위로 세분화 + “사실 먼저 나열 후 매핑” 방식 도입.

7.2 Pydantic 검증 우회 버그 (구조적 결함, 2026-07-10 발견)

관계를 적재하는 코드 경로가 MERGE (b:{class} {key: $value}) 형태로 노드를 생성하는데, 이 경로가 Pydantic 검증을 전혀 거치지 않았었다. 엔티티로 직접 추출된 값은 Pydantic 모델 인스턴스화(Literal 검증 포함)를 거치게 생각했는데, 관계의 from_key/to_key로만 등장하는 값이 검증 없이 그대로 노드가 생성되는 경우가 발생했다.

사례 : 신청채널.이름은 8종으로 닫힌 Literal인데, 신청채널: "통신채널"이라는 스키마 밖 값이 그래프에 존재했다. 확인 결과 이 노드는 MENTIONS(청크 출처) 관계가 없었다 — 즉 정식 추출 경로를 거친 적이 없고, 관계 적재 시 이 우회 경로로만 생성된 것이었다.

조치: 관계의 from_key/to_key 값도 대상 클래스의 key 필드 타입 제약(Literal)을 검증하는 valid_key_value() 함수를 추가했고 전체 Literal 클래스(계약상태/신청채널/재무처리/통지유형/전달매체) 스캔 결과, 위반은 이 1건뿐이었다.

계약정보의 원문 pdf를 확인해본 결과 “통신채널” 값은 노이즈가 아니라, 원문에서 “대면채널/통신채널/셀프보험몰/디지털다이렉트”라는 채널 상위 분류로 실제 사용되는 개념이었다. 같은 구체적ㅍ채널(“전화”)이 통신채널/대면채널 두 분류에 동시에 속하는 사례를 원문에서 확인해, 이를신청채널 노드 속성이 아니라 접수채널 관계의 구분 속성으로 재설계했다.

7.3 당사자 클래스 오염 (추출 프롬프트 설계 문제)

당사자(실제 인물) 클래스에 “계약자”, “예금주” 같은 역할 명칭이 실존 인물처럼 잘못 들어간 사례를 발견했다. 원문(“▪ 신청인 : 계약자”)은 “신청인은 계약자 본인이어야 한다”는 규칙 설명이었는데, LLM이 이를 실제 인물 개체로 잘못 추출했다. 이게 실제로 나올 오류는 “이 계약의 계약자가 누구인가?” 같은 질문에 사람 이름이 아니라 역할명 자체가 나왔을 것 같다.

추출 프롬프트에 “역할을 지칭하는 표현은 당사자 엔티티로 만들지 않는다(규정조건. 적용역할로 표현한다)”는 규칙을 명시적으로 추가했다.

7.4 계약 클래스 필수 필드 과다로 인한 우회 생성

계약 클래스가 상품명/계약일자/보험료/납입주기를 전부 필수로 요구했는데, 매뉴얼의 예시는 그 규칙 설명에 필요한 값만 언급하고 나머지는 생략하는 경우가 많아(예: “예시증번: 10002634, 계약일: 1999.04.01”), 정식 엔티티 경로를 못 타고 관계의 from_key로만 우회 생성되는 문제가 있었다. 계약번호(key) 외 필드를 Optional로 완화하는 방법을 생각해보았다.


8. 한계와 다음 단계

8.1 도메인 전문가 검증이 필요한 지점

스키마 설계 방법론(CQ→클래스 역산, 검증 파이프라인) 자체는 도메인 지식 없이도 진행 가능하지만, 문서에 나온 특정 표현이 실무상 정확히 무엇을 의미하는지, 업무 간 우선순위 규칙이 실무와 일치하는지 등은 판단이 애매한 지점이 반복적으로 발견되고 있다. LLM은 그럴듯한 해석을 내놓지만 실제 업무 시스템과 일치하는지 지금 현재로썬 확인하며 개발할 방법이 없다고 판단된다.

8.2 남은 작업

  • 계약정보 도메인 21개 문서 중 1개만 상세 리뷰 완료(20개 남음) — 리뷰할 때마다 스키마 보강이 발생하고 있어(3.2 진행하지않는다 관계가 1개 문서 리뷰에서 나옴), 나머지 문서에서도 추가 보강을 해야할 가능성이 높다.

  • 규정조건(467개)/구비서류(124개) 파편화 추가 점검(현재 threshold 0.4, 더 낮춰서 재검토 여지).
  • Cypher 생성 품질 개선(Kiwi 키워드 확장 검색, 또는 사람이 검증한 템플릿 기반 Cypher로점진 전환) — 아직 시작 전.
  • 벡터 임베딩(Chunk 레벨) 하이브리드 구조는 설계엔 포함돼 있으나 아직 미구현. 지금까지의 실패 사례가 전부 “키워드는 겹치는데 그래프 탐색이 못 찾은” 유형이라, 진짜 동의어(글자가 하나도 안 겹치는) 실패 사례가 실제로 나오면 그때 도입 예정.
  • 계약정보 외 나머지 3개 도메인(계약해지/보험금보장/보험료납입, 전체 92개 문서 중 71개)은 아직 착수 전

8.3 의사결정이 필요한 사항

현재 시점에 도메인 전문가 없이 벡터DB+그래프DB 하이브리드 RAG까지 우선 완성해볼지 고민이다.


© 2022 JeongHwan Yun.