온톨로지 구현
온톨로지 구현
계약정보 도메인 문서를 계층적으로 파싱한 문서와 온톨로지 설계를 기반으로 만든 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 재추론 없이 그래프로 답하려는 것).
아직 정하지 않은 것
- Neo4j/LPG vs Neptune/RDF
- 최상위 클래스(CQ를 뽑아서 역산)
- 청크 - 엔티티 연결방식
Competency Questions 초안
질문에 답하기 위해 최소한 필요한 클래스가 무엇인지 역산한다. 문서에 등장하는 명사를 다 클래스 후보로 올리지 않는다 (bottom-up으로 인한 데이터 파편화 방지).
업무매뉴얼_계약정보.xlsx에 있는 135개 실제 업무 Q&A(자동부활/일반부활, 증권재발행, 감액, 납입주기·기간변경, 각종 할인, 직무직종, 감액완납/연장정기 등)을 참고해 작성함.
Competency Questions (14개)
- 특정 계약이 특정 계약변경(감액/납입주기변경/보종전환 등)을 신청 가능한 상태인가?
- 이 계약변경을 신청하려면 누가(계약자 본인/대리인/법정대리인) 어떤 서류를, 어떤 채널로 제출해야 하는가?
- 이 계약변경 건에 타인을위한해지프로세스가 적용되는가? (계약자와 수익자가 상이한 경우)
- 이 계약변경에서 본인인증이 필요한 조건은 무엇이고, 요구되는 인증방식(휴대폰/신분증)은?
- 실효된 계약이 특정 시점 기준 자동부활/일반부활 대상인가, 그 조건과 기한은?
- 특정 계약상태(정상/실효/납입면제 등)에서 이 계약변경이 허용되는가, 불허되는가?
- 이 계약변경이 AML/FATCA-CRS 대상에 해당하는가, 해당 시 추가 구비서류는?
- 미성년자/법인/외국인 계약자인 경우 이 업무에서 추가로 필요한 절차·서류는?
- 이 계약변경 처리로 반제금/추징금이 발생하는가, 발생 시 지급기준(지급일/반환계좌 제약)은?
- 이 계약변경이 비교안내 대상인가? (신계약 후 6개월 이내 등 조건)
- 특정 통지(미납안내/해지예고/실효안내)가 어떤 수신자·전달매체를 거쳤을 때 법적으로 유효한 수령/안내완료로 인정되는가?
- 특정 업무 처리가 완료된 후 취소가 가능한가, 가능하다면 기한과 조건은?
- 특정 업무 처리가 다른 특약/보장/부가서비스(멤버십, 건강관리자금, 연금전환 등)에 어떤 파급 효과를 미치는가?
- 청약 시점과 현재 시점의 상태(국적, 건강상태, 직업 등)가 다를 경우 어느 시점 기준으로 자격/가능여부를 판단하는가?
최상위 클래스 후보
| 클래스 후보 | 근거 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가지
- 계약상태를 노드로 승격할지, 계약의 속성으로 둘지 원칙2 기준으로는 “계약 내부 값”이라 속성이 맞아 보이지만, 실제로는 업무유형마다 “이 상태에서 가능/불가”라는 규칙이 반복해서 이 값을 참조합니다(CQ1, CQ6). 즉 계약상태값 자체가 여러 업무유형 규칙에서 재사용되는 관계의 대상이 될 수 있습니다. 이 경우 노드로 승격하는 게 맞다고 생각하는데, 어떻게 보시나요?
- 반제금/추징금을 노드로 승격할지, 관계 속성으로 둘지 금액뿐 아니라 지급기준·지급일·취소가능여부 같은 자체 규칙이 붙습니다(CQ10, CQ12). “계약-[:감액신청]->당사자” 관계의 속성으로 붙일지, 아니면 별도 “재무처리” 노드로 승격해 규정조건과 연결할지 — 이건 관계 정의(3단계) 직전에 정해야 할 것 같습니다.
- “규정조건”을 하나의 큰 클래스로 둘지, 하위 유형으로 쪼갤지 타인을위한해지프로세스/AML/본인인증기준/비교안내/취소기준/시점판단기준이 성격이 꽤 다릅니다(법적근거 vs 내부정책 vs 판정로직). 하나로 묶으면 관계는 단순해지지만 domain/range 제약이 뭉뚱그려질 위험이 있고, 쪼개면 클래스 수가 늘어납니다.
3가지 판단 확정
노드 승격 판단: 계약상태 / 반제금·추징금 / 규정조건
최상위 클래스 후보 8개(계약, 당사자, 업무유형, 신청채널, 구비서류, 규정조건, 통지, 특약·보장·부가서비스)를 CQ에서 역산한 뒤에도, 후보 각각을 “속성으로 둘지 노드로 승격할지”는 별개의 판단이 필요했다. 기준은 프로젝트 원칙 2였다: 그 값 자체로 검색/필터링해야 하거나 여러 노드가 그 값을 공유하며 연결될 필요가 있으면 노드로 승격, 특정 노드에 도달했을 때만 참조하면 되는 부가정보면 속성. 이 기준 하나로 세 가지 애매한 지점을 판단했다.
- 계약상태 — 속성처럼 보이지만 노드로 승격
계약상태(정상/실효/납입면제 등)는 언뜻 계약 레코드 안에 박혀있는 값이라 “노드 내부 값 = 속성”이라는 기본값에 들어맞는 것처럼 보인다. 하지만 실제 업무 규칙을 보면 계약상태 자체가 여러 업무유형에서 반복적으로 참조되는 대상이다 — “실효 상태에서는 감액 가능”, “납입면제 상태에서는 특정 변경 불가” 같은 규칙이 업무유형마다 계약상태값을 걸고 넘어진다.
판단 기준은 “이 계약 하나에서 이 값을 한 번 쓰고 마는가, 아니면 이 값 자체가 여러 관계(업무유형별 허용/불허 규칙)의 대상이 되어 재사용되는가”였다. 후자에 해당하므로 노드로 승격했다. 계약 인스턴스 입장에서는 “이 계약은 현재 실효 상태다”라는 사실 하나뿐이지만, 계약상태라는 개념 자체는 여러 업무유형 규칙이 공유하는 조회 대상이기 때문이다.
- 반제금/추징금 — 개별 노드가 아니라 “재무처리”로 통합
반제금과 추징금은 금액 외에도 지급기준, 지급일, 취소가능여부 같은 자체 규칙이 붙어서 속성으로 두기엔 정보가 너무 많다 — 여기까지는 노드 승격이 자명했다. 문제는 그다음이었다: 반제금 노드와 추징금 노드를 따로 만들 것인가, 하나의 상위 개념으로 묶을 것인가.
실제 문서를 보면 금전 이벤트 유형이 반제금/추징금 둘로 끝나지 않는다 — 대출최저상환금, 부활보험료입금, 자동이체반환, 카드승인취소 등으로 계속 늘어나는 패턴이다. 유형별로 노드를 따로 만들면 “이 계약변경으로 어떤 금전 이벤트가 발생했는가?” 같은 질문 하나를 답하기 위해 관계 이름을 전부 나열해서 훑어야 한다 — 그래프 쿼리로 멀티홉을 대체한다는 원래 목적과 어긋난다.
그래서 재무처리라는 하나의 노드 타입으로 통합하고, 그 안에 구분 속성(반제금/추징금/대출최저상환금…)으로 유형을 나누기로 했다.
// 예시 표기일 뿐, 저장기술 확정을 의미하지 않음 (업무유형)-[:발생시킨다]->(재무처리 {구분: “반제금”, 금액, 지급기준…}) (업무유형)-[:발생시킨다]->(재무처리 {구분: “추징금”, 금액, 납부방법…})
관계 이름이 하나로 고정되므로 새 금전 이벤트 유형이 늘어나도 관계 구조를 바꿀 필요 없이 구분 값만 추가하면 된다. 대신 유형마다 필요한 속성이 서로 겹치지 않을 수 있다는 점(반제금엔 지급계좌가, 추징금엔 납부방법이 핵심)은 일단 감수했다 — 실제로 속성 충돌이 심해지면 그때 재검토하기로 남겨뒀다.
- 규정조건 — 지금은 하나로, 필요해지면 쪼갠다
타인을위한해지프로세스, 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에서 패턴이 어떻게 나타나는지 봐야 답이 나오는” 성격이거든요:
- 역할별 관계명 vs 단일관계+역할속성 → 역할 종류가 4단계 샘플에서 5개(계약자/피보험자/수익자/대리인/예금주) 이상으로 늘어나는지 봐야 판단 가능
- 구비서류 이원화 → 실제 감액/납입주기변경 문서의 구비서류표가 이 패턴과 맞는지 봐야 함
- 파급효과 속성 vs 노드 승격 → 효과유형이 다른 클래스와 또 연결돼야 하는 사례가 나오는지 봐야 함
- 규정조건.적용역할 → 역할별 규정조건이 재사용되는 패턴이 나오는지 봐야 함
제안: 지금 이 4가지를 미리 확정 짓지 말고, 지금 초안(11개 클래스 + 관계표)을 그대로 작업가설로 들고 4단계(업무매뉴얼_계약정보.xlsx + parse/ 샘플 매핑)로 넘어가서, 매핑하다가 안 맞는 지점이 나오면 그때 4가지 중 해당하는 걸 조정하는 게 CLAUDE.md 절차에 더 맞다고 봅니다.
❯ 조금 더 쉽게 설명해줘봐 초등학생 눈높이로
좋아요, 장난감 정리에 비유해서 설명해볼게요.
클래스 = 상자 종류 방을 정리할 때 “인형 상자”, “블록 상자”, “책 상자”처럼 상자 종류를 나누죠? 우리가 만든 “계약”, “당사자”, “계약상태” 같은 것도 그런 상자 종류예요. AIA 서류에 나오는 온갖 단어를 다 상자로 만들면 상자가 너무 많아지니까, “이 질문에 답하려면 꼭 필요한 상자가 뭘까?”만 골라서 11개만 만든 거고요.
관계 = 상자끼리 이어주는 화살표 근데 상자만 있으면 안 되고, 상자끼리 연결이 있어야 쓸모가 있어요. 예를 들어 “이 계약 상자는 이 사람 상자랑 연결돼있어(이 사람이 계약자야)” 처럼요.
domain/range = 화살표 규칙 이게 오늘 물어보신 부분인데요 — 화살표를 아무 상자에서나 아무 상자로나 막 그으면 나중에 헷갈려요. 그래서 “이 화살표는 꼭 A상자에서 시작해서 B상자로만 가야 해”라는 규칙을 미리 정해두는 거예요.
예를 들어:
- “계약자이다” 화살표는 → 꼭 [계약] 상자에서 출발해서 [당사자] 상자로만 가야 함
- 만약 이 규칙이 없으면, 나중에 AI가 서류 읽다가 실수로 “[구비서류] 상자에서 [계약상태] 상자로” 화살표를 그어버릴 수도 있어요. 말이 안 되는 연결이죠. 규칙이 있으면 이런 실수를 미리 막을 수 있어요.
지금까지 확인한 것 우리가 미리 뽑아둔 14개 질문(예: “이 계약, 감액 가능한 상태야?”)에 답하려면 이 화살표들로 다 답이 나오는지 하나하나 확인해봤는데 — 문제없이 잘 됐어요.
남은 애매한 4가지 다만 몇 개는 “화살표를 이렇게 그어도 되고 저렇게 그어도 되는데, 뭐가 더 나을지” 애매한 게 4개 남았어요. 근데 이건 지금 머리로 상상만 해서는 답이 안 나오고, 실제 서류(엑셀 Q&A 135개, 진짜 문서들)를 보면서 “어, 이 패턴은 이렇게 그리는 게 맞네” 하고 확인하는 게 더 정확해요.
그래서 제안 지금 상자랑 화살표 규칙(11개 상자 + 관계표)은 일단 다 만들었으니, 애매한 4개는 억지로 지금 정하지 말고 진짜 서류 보면서 자연스럽게 정하는 다음 단계로 넘어가자는 거였어요.