온톨로지 구현

온톨로지 구현

계약정보 도메인 문서를 계층적으로 파싱한 문서와 온톨로지 설계를 기반으로 만든 CLAUDE.md를 기반으로 구현시작.

문서 스코프

  • 11 증권정보변경: 청약서/증권/약관 재발행 (2건)
  • 11-1-1 ~ 11-2-2 계약변경: 감액·특약삭제, 사망보험금유동화, 납입주기/기간, 건강플러스·실손할인, UL보험료변경, 지수연동기간, 감액완납, 연장정기, 실손중지재개, 장애인전용보험전환, 적립서비스해지, 일시납종신전환, 직무직종, 보험종목, 갱신, 비흡연자 — 총 16건의 세부 변경유형 (16건)
  • 5-1, 5-2: 실효안내, 자동부활, 일반부활 (3건)
문서들이 사실상 “계약변경 하위 유형 하나”에 대응하는 SOP이고, 내부 구조는 거의 동일하게 반복된다
순서도 → 신청인/필수확인·안내사항/주의사항 → Talk Point → 업무프로세스(신청방법·채널별 구비서류 표) → 고객에게 알릴 사항(처리기준, 법적근거, 계약상태별 가능여부) → Q&A.

감액 문서에서 파편화 위험(휴대폰인증/신분증인증/본인인증)이 확인됨 — “추징/반제금 발생 시 본인인증 필수”가 감액, 부활, 반제금취소 등 여러 문서에서 각각 다른 표현으로 반복 등장한다. 또한 “타인을위한해지프로세스”, “AML/FATCA-CRS 대상”, “비교안내제도” 같은 조건부 규정이 계약변경 여러 유형에 공통으로 걸쳐 있어서, 이게 멀티홉 그래프 쿼리가 필요한 지점으로 보인다 (예: “이 감액 신청이 타인을위한해지프로세스 대상인가?” 같은 질문을 LLM 재추론 없이 그래프로 답하려는 것).

아직 정하지 않은 것

  1. Neo4j/LPG vs Neptune/RDF
  2. 최상위 클래스(CQ를 뽑아서 역산)
  3. 청크 - 엔티티 연결방식

Competency Questions 초안

질문에 답하기 위해 최소한 필요한 클래스가 무엇인지 역산한다. 문서에 등장하는 명사를 다 클래스 후보로 올리지 않는다 (bottom-up으로 인한 데이터 파편화 방지).

업무매뉴얼_계약정보.xlsx에 있는 135개 실제 업무 Q&A(자동부활/일반부활, 증권재발행, 감액, 납입주기·기간변경, 각종 할인, 직무직종, 감액완납/연장정기 등)을 참고해 작성함.

Competency Questions (14개)

  1. 특정 계약이 특정 계약변경(감액/납입주기변경/보종전환 등)을 신청 가능한 상태인가?
  2. 이 계약변경을 신청하려면 누가(계약자 본인/대리인/법정대리인) 어떤 서류를, 어떤 채널로 제출해야 하는가?
  3. 이 계약변경 건에 타인을위한해지프로세스가 적용되는가? (계약자와 수익자가 상이한 경우)
  4. 이 계약변경에서 본인인증이 필요한 조건은 무엇이고, 요구되는 인증방식(휴대폰/신분증)은?
  5. 실효된 계약이 특정 시점 기준 자동부활/일반부활 대상인가, 그 조건과 기한은?
  6. 특정 계약상태(정상/실효/납입면제 등)에서 이 계약변경이 허용되는가, 불허되는가?
  7. 이 계약변경이 AML/FATCA-CRS 대상에 해당하는가, 해당 시 추가 구비서류는?
  8. 미성년자/법인/외국인 계약자인 경우 이 업무에서 추가로 필요한 절차·서류는?
  9. 이 계약변경 처리로 반제금/추징금이 발생하는가, 발생 시 지급기준(지급일/반환계좌 제약)은?
  10. 이 계약변경이 비교안내 대상인가? (신계약 후 6개월 이내 등 조건)
  11. 특정 통지(미납안내/해지예고/실효안내)가 어떤 수신자·전달매체를 거쳤을 때 법적으로 유효한 수령/안내완료로 인정되는가?
  12. 특정 업무 처리가 완료된 후 취소가 가능한가, 가능하다면 기한과 조건은?
  13. 특정 업무 처리가 다른 특약/보장/부가서비스(멤버십, 건강관리자금, 연금전환 등)에 어떤 파급 효과를 미치는가?
  14. 청약 시점과 현재 시점의 상태(국적, 건강상태, 직업 등)가 다를 경우 어느 시점 기준으로 자격/가능여부를 판단하는가?

최상위 클래스 후보

클래스 후보 근거 CQ 비고
계약 1, 5, 6 계약번호, 보험료 등은 속성으로 관리. 계약상태는 별도 논의
당사자 2, 3, 8, 9 역할(계약자, 피보험자, 수익자, 대리인, 예금주, 친권자, 상속인) 및 미성년·법인·외국인 여부 관리
업무유형 (계약변경, 부활, 재발행 등) 전체 21개 문서 각각이 이 클래스의 인스턴스. 대부분의 관계가 이 노드를 중심으로 연결됨
신청채널 2, 8 전화, 우편, 내방, AIA+, 팩스, 이메일, LMS
구비서류 2, 7, 9 신분증, 인감증명서, 가족관계증명서 등
규정조건 3, 4, 6, 7, 9, 12, 14 타인을 위한 해지 프로세스, AML 대상 여부, 본인인증 기준, 비교안내 대상, 취소 기준, 시점 판단 기준 등 조건부 규칙 묶음
통지(안내장) 11 미납안내, 해지예고, 실효안내 등. 수신자, 전달매체, 유효성 판정 필요
특약·보장·부가서비스 13 멤버십, 건강관리자금, 연금전환 등. 업무유형의 파급효과 대상

8개 후보 수정안

클래스 처리
계약, 당사자, 신청채널, 구비서류, 규정조건 변경 없음
업무유형 유지. 구분 속성만 추가(업무분류 노드 X, 문서섹션 노드 X)
통지 통지유형 + 전달매체로 세분화 채택(통지이력·당사자역할 노드는 보류)
특약·보장·부가서비스 계약구성요소로 명칭 변경. 계약과 분리된 최상위 클래스는 아니며, 계약의 하위 구성요소로 위치

고려애햐 할 사항 3가지

  1. 계약상태를 노드로 승격할지, 계약의 속성으로 둘지 원칙2 기준으로는 “계약 내부 값”이라 속성이 맞아 보이지만, 실제로는 업무유형마다 “이 상태에서 가능/불가”라는 규칙이 반복해서 이 값을 참조합니다(CQ1, CQ6). 즉 계약상태값 자체가 여러 업무유형 규칙에서 재사용되는 관계의 대상이 될 수 있습니다. 이 경우 노드로 승격하는 게 맞다고 생각하는데, 어떻게 보시나요?
  2. 반제금/추징금을 노드로 승격할지, 관계 속성으로 둘지 금액뿐 아니라 지급기준·지급일·취소가능여부 같은 자체 규칙이 붙습니다(CQ10, CQ12). “계약-[:감액신청]->당사자” 관계의 속성으로 붙일지, 아니면 별도 “재무처리” 노드로 승격해 규정조건과 연결할지 — 이건 관계 정의(3단계) 직전에 정해야 할 것 같습니다.
  3. “규정조건”을 하나의 큰 클래스로 둘지, 하위 유형으로 쪼갤지 타인을위한해지프로세스/AML/본인인증기준/비교안내/취소기준/시점판단기준이 성격이 꽤 다릅니다(법적근거 vs 내부정책 vs 판정로직). 하나로 묶으면 관계는 단순해지지만 domain/range 제약이 뭉뚱그려질 위험이 있고, 쪼개면 클래스 수가 늘어납니다.
3가지 판단 확정

노드 승격 판단: 계약상태 / 반제금·추징금 / 규정조건

최상위 클래스 후보 8개(계약, 당사자, 업무유형, 신청채널, 구비서류, 규정조건, 통지, 특약·보장·부가서비스)를 CQ에서 역산한 뒤에도, 후보 각각을 “속성으로 둘지 노드로 승격할지”는 별개의 판단이 필요했다. 기준은 프로젝트 원칙 2였다: 그 값 자체로 검색/필터링해야 하거나 여러 노드가 그 값을 공유하며 연결될 필요가 있으면 노드로 승격, 특정 노드에 도달했을 때만 참조하면 되는 부가정보면 속성. 이 기준 하나로 세 가지 애매한 지점을 판단했다.

  1. 계약상태 — 속성처럼 보이지만 노드로 승격

계약상태(정상/실효/납입면제 등)는 언뜻 계약 레코드 안에 박혀있는 값이라 “노드 내부 값 = 속성”이라는 기본값에 들어맞는 것처럼 보인다. 하지만 실제 업무 규칙을 보면 계약상태 자체가 여러 업무유형에서 반복적으로 참조되는 대상이다 — “실효 상태에서는 감액 가능”, “납입면제 상태에서는 특정 변경 불가” 같은 규칙이 업무유형마다 계약상태값을 걸고 넘어진다.

판단 기준은 “이 계약 하나에서 이 값을 한 번 쓰고 마는가, 아니면 이 값 자체가 여러 관계(업무유형별 허용/불허 규칙)의 대상이 되어 재사용되는가”였다. 후자에 해당하므로 노드로 승격했다. 계약 인스턴스 입장에서는 “이 계약은 현재 실효 상태다”라는 사실 하나뿐이지만, 계약상태라는 개념 자체는 여러 업무유형 규칙이 공유하는 조회 대상이기 때문이다.

  1. 반제금/추징금 — 개별 노드가 아니라 “재무처리”로 통합

반제금과 추징금은 금액 외에도 지급기준, 지급일, 취소가능여부 같은 자체 규칙이 붙어서 속성으로 두기엔 정보가 너무 많다 — 여기까지는 노드 승격이 자명했다. 문제는 그다음이었다: 반제금 노드와 추징금 노드를 따로 만들 것인가, 하나의 상위 개념으로 묶을 것인가.

실제 문서를 보면 금전 이벤트 유형이 반제금/추징금 둘로 끝나지 않는다 — 대출최저상환금, 부활보험료입금, 자동이체반환, 카드승인취소 등으로 계속 늘어나는 패턴이다. 유형별로 노드를 따로 만들면 “이 계약변경으로 어떤 금전 이벤트가 발생했는가?” 같은 질문 하나를 답하기 위해 관계 이름을 전부 나열해서 훑어야 한다 — 그래프 쿼리로 멀티홉을 대체한다는 원래 목적과 어긋난다.

그래서 재무처리라는 하나의 노드 타입으로 통합하고, 그 안에 구분 속성(반제금/추징금/대출최저상환금…)으로 유형을 나누기로 했다.

// 예시 표기일 뿐, 저장기술 확정을 의미하지 않음 (업무유형)-[:발생시킨다]->(재무처리 {구분: “반제금”, 금액, 지급기준…}) (업무유형)-[:발생시킨다]->(재무처리 {구분: “추징금”, 금액, 납부방법…})

관계 이름이 하나로 고정되므로 새 금전 이벤트 유형이 늘어나도 관계 구조를 바꿀 필요 없이 구분 값만 추가하면 된다. 대신 유형마다 필요한 속성이 서로 겹치지 않을 수 있다는 점(반제금엔 지급계좌가, 추징금엔 납부방법이 핵심)은 일단 감수했다 — 실제로 속성 충돌이 심해지면 그때 재검토하기로 남겨뒀다.

  1. 규정조건 — 지금은 하나로, 필요해지면 쪼갠다

타인을위한해지프로세스, AML대상, 본인인증기준, 비교안내대상, 취소기준, 시점판단기준은 성격이 상당히 다르다 — 어떤 건 법적 근거(상법 조항)가 핵심이고, 어떤 건 내부 정책이 핵심이고, 어떤 건 판정 로직(청약시점 vs 현재시점 중 뭘 기준으로 볼지)에 가깝다. 지금 이걸 다 쪼개서 클래스로 만들 수도 있지만, 그러면 domain/range를 유형마다 다르게 정의해야 하고 클래스 수가 급격히 늘어난다.

그래서 지금은 규정조건이라는 하나의 클래스로 묶어서 시작하고, 이후 샘플 문서 검증 단계에서 속성/관계가 유형별로 크게 갈리는 게 확인되면 그때 하위 클래스로 쪼개기로 했다. 근거는 스키마 변경 원칙이다: 기존 클래스의 이름 변경이나 구조 개편은 비용이 크지만, 새로운 클래스/관계 추가는 유연하게 허용된다. 지금 하나로 묶었다가 나중에 하위 클래스를 추가하는 방향은 “새로 추가”에 해당하지 “기존 걸 뜯어고치는” 게 아니므로, 지금 성급하게 잘게 쪼개는 것보다 안전한 선택이다.

관계와 domain/range 정의

2단계에서 확정한 최상위 클래스 11개(계약, 당사자, 계약상태, 업무유형, 신청채널, 구비서류, 규정조건, 재무처리, 통지유형, 전달매체, 계약구성요소)를 바탕으로, 이제 클래스 사이를 잇는 관계와 각 관계의 domain(출발 클래스)/range(도착 클래스)를 정의했다.

codex 교차검증

클래스를 확정하기 전, codex에게 CQ 14개와 8개 후보 클래스를 그대로 주고 독립적인 2차 검토를 요청했다. 결과는 세 가지였다.

  • 업무유형: codex는 21개 문서를 단일 클래스로 두되 상위 “업무분류” 노드를 추가하자고 제안했다. 하지만 이 근거로 든 질의(“계약변경류 업무만 비교안내 조건을 조회하라” 등)는 확정된 14개 CQ 어디에도 없었다. 실제 감액 문서 원문도 규정을 “대상업무: 해약(해지) 및 감액(특약삭제)”처럼 인스턴스 단위로 명시하지, 카테고리 단위로 걸지 않는다. CQ에 없는 가상의 미래 질의로 클래스를 늘리는 건 방법론 위반이라 판단해 반려했다. 대신 구분 속성만 추가하고, 실제로 카테고리 단위 규정이 나오면 그때 노드로 승격하기로 했다.
  • 통지: codex의 노드 승격 제안(통지유형/통지이력/전달매체/당사자역할)에는 절반만 동의했다. 통지유형과 전달매체는 CQ11(“통지가 어떤 매체로, 누구에게 전달됐을 때 유효한가”)을 그래프로 풀려면 반드시 필요했다. 하지만 통지이력(실제 발송 기록)은 운영 데이터 스키마에 가깝고, 이 온톨로지는 규정/정책 텍스트에서 뽑는 것이라 지금 범위 밖으로 남겼다. 당사자역할도 별도 노드로 만들 근거가 약해 — 이미 CLAUDE.md 원칙3 예시에서 당사자.역할을 속성으로 정의해뒀기 때문에 — 신설하지 않았다.
  • 특약·보장·부가서비스: codex가 제안한 “계약구성요소”로의 재정의는 그대로 받아들였다. 특약 상품(예: 실손의료비특약) 자체는 여러 계약에 걸쳐 재사용되는 반면, 계약에 실제로 붙은 특약은 상태·가입금액이 계약마다 다르다 — 당사자를 노드로 승격했던 논리와 같은 패턴이라 설득력이 있었다. 다만 “상품 정의 vs 계약별 인스턴스”를 두 노드로 쪼갤지는 지금 정하지 않고 관계 설계 단계로 넘겼다.

관계 domain/range 표

관계 domain range 근거 CQ
계약자이다/피보험자이다/수익자이다/대리인이다/예금주이다 계약 당사자 2,3,8,9
현재상태이다 계약 계약상태 1,6
포함한다 계약 계약구성요소 13
요구조건 업무유형 규정조건 3,4,6,7,9,10,12,14
허용상태 규정조건 계약상태 1,6
접수채널 업무유형 신청채널 2,8
요구서류 업무유형 구비서류 2,7,8
추가서류 규정조건 구비서류 8,9
발생시킨다 업무유형 재무처리 9,10,12
지급조건 재무처리 규정조건 9
파급효과 업무유형 계약구성요소 13
필요통지 업무유형 통지유형 5,11
유효매체 통지유형 전달매체 11
유효성조건 통지유형 규정조건 11

역할 관계(계약자이다 등)는 당사자 노드 자체에 역할을 고정하지 않는다. 같은 사람이 계약마다 역할이 다를 수 있기 때문에(“계약A에서는 계약자, 계약B에서는 수익자”), 역할은 노드 속성이 아니라 어떤 화살표로 연결됐는지로 표현한다.

미성년자/법인/외국인 같은 당사자 조건도 별도 노드 없이 규정조건.적용역할 속성으로 처리하기로 했다 — 당사자역할 노드를 반려한 결정과 일관성을 맞췄다.

domain/range의 실제 역할은 질문(쿼리)을 막는 게 아니라, 이후 LLM이 문서에서 트리플을 추출할 때 “구비서류가 계약자다” 같은 잘못된 연결이 생기는 걸 막는 데 있다. 새로운 질문이 들어왔을 때 기존 클래스·관계 조합으로 답이 되면 문제없이 답이 나오고, 커버 안 되는 정보를 물으면 에러가 아니라 빈 결과가 나올 뿐이다 — 이 경우 원칙6에 따라 관계/클래스를 유연하게 추가하면 된다.

아직 확정하지 못한 판단 4가지(역할 관계명 방식, 구비서류 이원화, 파급효과 노드화 여부, 규정조건.적용역할 속성 충분성)는 4단계 샘플 검증 이후 다시 다루기로 하고 세션을 마무리했다.

도메인/range 초안을 CQ 14개에 대입해서 다시 훑어봤는데, 구조적으로는 빠지는 부분 없이 잘 커버되고 있습니다. 몇 가지 까다로운 CQ로 검증해보면:

  • CQ1 (계약이 특정 업무 신청 가능 상태인가): 계약-[현재상태이다]->계약상태 와 업무유형-[요구조건]->규정조건-[허용상태]->계약상태 를 매치시키면 됨 — 계약과 업무유형 사이에 직접 관계가 없어도 성립. (업무유형은 계약별 인스턴스가 아니라 유형 자체라서 맞는 설계)
  • CQ3 (타인을위한해지프로세스): 계약-[계약자이다]->당사자A, 계약-[수익자이다]->당사자B 를 뽑아서 A≠B 비교하는 그래프 패턴 — 별도 관계 안 만들어도 기존 domain/range로 충분
  • CQ8, CQ9 (미성년자/법인 추가서류, 반제금 지급조건): 규정조건.적용역할 속성과 재무처리-[지급조건]->규정조건 으로 커버

즉 관계 구조 자체는 구멍 없이 잘 짜여 있습니다. “초안”이라고 표시해둔 이유는 관계가 틀려서가 아니라, 노트에 적힌 미확정 판단 지점 4가지 때문이었죠.

그런데 이 4가지를 지금 여기서 탁상공론으로 정하는 것보다, CLAUDE.md 4단계 원칙(“매핑이 안 되는 개체가 나올 때만 뼈대를 보강”)을 그대로 적용하는 게 나을 것 같습니다. 4가지 다 “실제 문서/Q&A에서 패턴이 어떻게 나타나는지 봐야 답이 나오는” 성격이거든요:

  1. 역할별 관계명 vs 단일관계+역할속성 → 역할 종류가 4단계 샘플에서 5개(계약자/피보험자/수익자/대리인/예금주) 이상으로 늘어나는지 봐야 판단 가능
  2. 구비서류 이원화 → 실제 감액/납입주기변경 문서의 구비서류표가 이 패턴과 맞는지 봐야 함
  3. 파급효과 속성 vs 노드 승격 → 효과유형이 다른 클래스와 또 연결돼야 하는 사례가 나오는지 봐야 함
  4. 규정조건.적용역할 → 역할별 규정조건이 재사용되는 패턴이 나오는지 봐야 함

제안: 지금 이 4가지를 미리 확정 짓지 말고, 지금 초안(11개 클래스 + 관계표)을 그대로 작업가설로 들고 4단계(업무매뉴얼_계약정보.xlsx + parse/ 샘플 매핑)로 넘어가서, 매핑하다가 안 맞는 지점이 나오면 그때 4가지 중 해당하는 걸 조정하는 게 CLAUDE.md 절차에 더 맞다고 봅니다.

❯ 조금 더 쉽게 설명해줘봐 초등학생 눈높이로

좋아요, 장난감 정리에 비유해서 설명해볼게요.

클래스 = 상자 종류 방을 정리할 때 “인형 상자”, “블록 상자”, “책 상자”처럼 상자 종류를 나누죠? 우리가 만든 “계약”, “당사자”, “계약상태” 같은 것도 그런 상자 종류예요. AIA 서류에 나오는 온갖 단어를 다 상자로 만들면 상자가 너무 많아지니까, “이 질문에 답하려면 꼭 필요한 상자가 뭘까?”만 골라서 11개만 만든 거고요.

관계 = 상자끼리 이어주는 화살표 근데 상자만 있으면 안 되고, 상자끼리 연결이 있어야 쓸모가 있어요. 예를 들어 “이 계약 상자는 이 사람 상자랑 연결돼있어(이 사람이 계약자야)” 처럼요.

domain/range = 화살표 규칙 이게 오늘 물어보신 부분인데요 — 화살표를 아무 상자에서나 아무 상자로나 막 그으면 나중에 헷갈려요. 그래서 “이 화살표는 꼭 A상자에서 시작해서 B상자로만 가야 해”라는 규칙을 미리 정해두는 거예요.

예를 들어:

  • “계약자이다” 화살표는 → 꼭 [계약] 상자에서 출발해서 [당사자] 상자로만 가야 함
  • 만약 이 규칙이 없으면, 나중에 AI가 서류 읽다가 실수로 “[구비서류] 상자에서 [계약상태] 상자로” 화살표를 그어버릴 수도 있어요. 말이 안 되는 연결이죠. 규칙이 있으면 이런 실수를 미리 막을 수 있어요.

지금까지 확인한 것 우리가 미리 뽑아둔 14개 질문(예: “이 계약, 감액 가능한 상태야?”)에 답하려면 이 화살표들로 다 답이 나오는지 하나하나 확인해봤는데 — 문제없이 잘 됐어요.

남은 애매한 4가지 다만 몇 개는 “화살표를 이렇게 그어도 되고 저렇게 그어도 되는데, 뭐가 더 나을지” 애매한 게 4개 남았어요. 근데 이건 지금 머리로 상상만 해서는 답이 안 나오고, 실제 서류(엑셀 Q&A 135개, 진짜 문서들)를 보면서 “어, 이 패턴은 이렇게 그리는 게 맞네” 하고 확인하는 게 더 정확해요.

그래서 제안 지금 상자랑 화살표 규칙(11개 상자 + 관계표)은 일단 다 만들었으니, 애매한 4개는 억지로 지금 정하지 말고 진짜 서류 보면서 자연스럽게 정하는 다음 단계로 넘어가자는 거였어요.


© 2022 JeongHwan Yun.