본문으로 건너뛰기

러닝 예제와 증명 하니스

📍 현재 위치: 제1부 · 명세 — 두 번째 행마. 요구사항은 작성되었습니다. 이제 책 전체가 모델링하는 단 하나의 캠페인과, 그것을 담는 파일들, 그리고 그 모델이 자신의 역량 질문 23개에 답함을 증명하는 하니스를 만나 봅니다.

앞 장은 온톨로지가 무엇을 답해야 하는지를 적어 두었습니다. 이 장은 무엇에 대해 답하는지를 소개합니다 — 단 하나의 단일클론항체 제조 캠페인, 시리즈의 나머지가 따라가는 바로 그 배치 — 그리고 ORSD를 정직하게 유지하는 실행 가능한 증명 하니스를. 이 책의 모든 Turtle, SPARQL, SHACL 조각은 여기서 소개하는 파일들의 진짜 발췌이며, 카탈로그의 모든 역량 질문은 그 파일들이 통과하는 테스트입니다.

쉽게 말하면

이 책은 십수 개의 장난감 예제 대신 하나의 약을 처음부터 끝까지 따라갑니다. 모든 전문의가 주석을 다는 한 환자의 차트처럼 말입니다. 얼린 세포 한 바이알이 배치가 되고, 정제된 원료의약품이 되고, 충전된 바이알이 됩니다 — 그리고 각 단계마다 차트에 몇 가지 사실이 더해집니다. "증명 하니스"는 그저 차트 전체를 다시 읽어서 명세서의 23개 질문에 여전히 답이 있는지 확인하는 프로그램입니다. 사실 하나를 바꾸면, 프로그램은 어떤 질문을 망가뜨렸는지 알려 줍니다.

역량 질문이 실행 가능한 테스트로 바뀌는 4단계 파이프라인 도해: 자연어 역량 질문 상자(CQ-04, 영향)에서 시작해, queries/CQ-04.rq라고 표시된 SPARQL 질의 상자로 화살표가 이어지고, cq-catalog.json을 읽어 모든 역량 질문을 실행하는 validate.py 상자로, 다시 결과가 기대 답과 대조되는 초록색 CQ-04 PASS 상자로 화살표가 이어집니다. PASS 상자에서 질문으로 돌아가는 초록색 회귀 루프가 있어, 요구사항은 변경이 있을 때마다 다시 실행되는 테스트이며 빌드를 통과하려면 23개 모두 초록색을 유지해야 함을 표시합니다. 하단 주석은 cq-catalog.json이 23개 역량 질문 전부를 각각 SPARQL 질의, SHACL 게이트, 또는 추론기 검사에 묶는다고 적습니다. 테스트로서의 요구사항: 각 역량 질문은 cq-catalog.json 안에서 그것에 답하는 산출물에 묶이며, validate.py는 23개 전부를 통과/실패 인수 테스트로 실행합니다. 저자가 AI의 도움을 받아 직접 제작한 그림입니다.

하나의 캠페인, 처음부터 끝까지

러닝 예제는 하나의 CHO 세포 단일클론항체로, 발견 표적에서 환자의 콜드체인 바이알까지 운반됩니다. 그 계보는 그래프 전체가 매달리는 척추입니다:

워킹 세포 은행 WCB-CHO-001이 시드 트레인 SEED-001을 심고, 이는 생산 생물반응기 배치 BATCH-2026-001에 접종되며, 그 수확물은 청징(CLAR-001)되고 Protein A로 포획(PApool-001)되며, 바이러스가 제거(VIpool-001, VFpool-001)되고, 폴리싱(POLpool-001)되며, 원료의약품 로트 DS-001으로 농축되어, 완제의약품 로트 DP-001DP-002로 충전됩니다.

각 화살표는 하나의 bp:derivedFrom 간선이 됩니다. 그 관계가 전이적이기 때문에, 모든 중간 노드가 그 사이에 놓여 있어도 DS-001은 단 한 번의 순회로 WCB-CHO-001까지 거슬러 올라갑니다 — 바로 이것이 CQ-01과 CQ-02를 답 가능하게 만드는 것입니다. 이 캠페인은 또한 의도적으로 규격 이탈 형제(out-of-spec sibling)를 함께 가지고 있습니다: 별도의 원료의약품 로트 DS-004에서 파생되었지만 세포 은행 WCB-CHO-001을 공유하는 완제의약품 로트 DP-004. 이 OOS 로트가 바로 조사자가 실제로 던지는 질문 — 이 로트의 계보를 또 무엇이 공유하는가? (CQ-04) — 에 모델이 답하게 해 주는 것이며, 출하 게이트가 정확히 한 경로에서 실패함을 (CQ-11) 보여 줄 수 있게 해 주는 것입니다.

이 책 전체에서 우리는 예시용 네임스페이스 bp:https://example.org/bioproc#에 대해 사용하는데, 이는 오픈소스 자매 책이 쓰는 것과 동일하므로, 여기의 클래스는 거기의 클래스와 같습니다.

데이터셋: 하나로 로드되는 여섯 파일

캠페인은 examples/platform/ontology/에, 하나의 RDF 그래프로 파싱되는 작은 파일 묶음으로 살아 있습니다:

파일담는 내용
bioproc.ttl로컬 bp: 어휘 — BFO 척추(Material / Equipment / Quality / RealizableEntity / InformationArtifact / Process) 전반에 걸친 클래스와 관계, 그리고 그것을 떠받치는 OWL 공리
align.ttl공개 온톨로지로의 정렬 — BFO, IOF Core 및 biopharma, OBO 생물학, Allotrope, QUDT, PROV, SOSA(제2부의 주제)
instances.ttl개체로서의 러닝 예제 — 위 계보의 모든 노드, 더하여 설계 공간, 분석, 출하 패널, 일련화, 유통, 출처
shapes.ttlSHACL 게이트 — 출하 규격, 완제 게이트, 세포 은행 게이트, 그리고 비교차성 가드
cq-catalog.json실행 가능한 ORSD — 23개 역량 질문, 각각 그것에 답하는 산출물에 묶임
queries/CQ-*.rq질의 기반 역량 질문 하나당 SPARQL 파일 하나

Turtle, SPARQL, JSON은 언어 중립적이므로, 한국어판은 바로 그 동일한 파일들을 인용합니다 — 모델의 번역본은 없고, 오직 그 주변 산문만 번역됩니다.

하니스: validate.py

validate.py는 앞 장의 비유에 나온 검사관입니다. 그것은 다음 세 가지를 순서대로 합니다:

  1. 세 Turtle 파일을 하나의 그래프로 파싱한다.
  2. 그것을 OWL-RL 폐포 [1]추론하여 함의된 사실들을 도출한다 — 가장 중요하게는 장거리 전이적 derivedFrom 간선과, 장비가 BFO 물질 존재라는 추론(구조적 역량 질문 CQ-22).
  3. cq-catalog.json역량 질문을 실행한다 — 질의 기반 질문은 각각 SPARQL 평가 [2]로, 게이트 질문은 각각 SHACL 검증 [3]으로, 구조적 질문은 각각 추론기 검사로 — 그리고 질문마다 통과/실패 한 줄을 출력한다.

23개가 모두 통과할 때에만 종료 코드 0으로 끝납니다. 다음은 그 실제 출력 — 이 책 전체가 유지하도록 설계된 초록색 기준선입니다:

[1] parsed 2120 triples (bioproc + align + instances)
[2] reasoned: 2120 -> 7137 triples after OWL-RL closure
[3] competency questions (ORSD v1.0.0 acceptance tests):

CQ GROUP RESULT DETAIL
CQ-01 lineage PASS 11 row(s)
CQ-02 impact PASS descendant superset of {DP-001, DP-002, DP-004, DS-001} (26 total)
CQ-03 lineage PASS row {batch: BATCH-2026-001, monomer: 98.611} present
CQ-04 impact PASS affected = [DP-001, DP-002]
CQ-05 trajectory PASS material superset of {PApool-001, POLpool-001} (2 total)
CQ-06 qbd PASS parameter superset of {FeedRate, Temperature} (2 total)
CQ-07 qbd PASS row {parameter: FeedRate, lot: DS-001} present
CQ-08 release PASS DS-001 release panel complete and in spec
CQ-09 release PASS ASK = True
CQ-10 release PASS DP-001/DP-002 pass release + finish gates
CQ-11 release PASS OOS [DP-004, DS-004] on path [hmwPct]
CQ-12 viral PASS sum(lrv) = 8.7 over 2 step(s)
CQ-13 packaging PASS package = [CARTON-001, CASE-001, PALLET-001]
CQ-14 packaging PASS ASK = False
CQ-15 provenance PASS claim = [claim-batch-001, claim-vessel-001]
CQ-16 provenance PASS ASK = True
CQ-17 characterization PASS WCB-CHO-001 conforms to the cell-bank gate
CQ-18 characterization PASS ASK = True
CQ-19 units PASS 0 row(s)
CQ-20 units PASS row {host: CHO-host, taxon: NCBITaxon_10029} present
CQ-21 structural PASS row {run: CCP-001, vessel: BR-101, vesselType: ProductionBioreactor} present
CQ-22 structural PASS transitive lineage + equipment-is-material inferred
CQ-23 structural PASS Batch-as-process and Batch-as-bioreactor both caught

23/23 competency questions PASS

ALL CHECKS PASSED

몇 줄만 읽어 보면 설계가 구체적으로 다가옵니다. CQ-01은 DS-001에서 11개의 조상을 순회합니다. CQ-04는 실패한 로트와 세포 은행을 공유하는 정확히 두 형제를 반환합니다. CQ-11은 출하 게이트가 오직 두 개의 -004 로트에 대해 오직 hmwPct에서만 실패함을 보여 줍니다 — 다른 모든 패널 값은 규격 이내입니다 — 이것이 현실적인 규격 이탈 사건의 모습입니다. CQ-14는 올바르게 FalseASK입니다: 바이알이 안에 담기는 그 어떤 것도 그것이 만들어진 재료는 아니므로, 담음(containment)과 계보는 분리된 채로 유지됩니다. DETAIL 열은 증거이고, RESULT 열은 계약입니다.

빌드 규칙으로서의 진실

"모든 조각은 진짜 발췌다"라는 비기능 요구사항은 문체상의 약속이 아니라 — 강제됩니다. 조각들이 bioproc.ttl, instances.ttl, shapes.ttl의 발췌이고, validate.py가 바로 그 동일한 파일들을 실행하기 때문에, 데이터셋에서 표류한 조각은 역량 질문을 망가뜨리거나(그리고 빌드를 실패시키거나) 살아 있는 출력과의 대조 리뷰에서 잡힙니다. 이 책의 숫자들 — 단량체 98.611 %, 총 LRV 8.7, 조상 11개, 2120 트리플이 7137로 폐포되는 것 — 은 예시용 어림수가 아니라 하니스가 출력하는 그대로입니다. 뒤의 어떤 장이 Turtle 블록을 보여 줄 때, 여러분은 모델을 읽고 있는 것이지 그것의 스케치를 읽는 것이 아닙니다.

미해결 부분: 초록색은 필요조건이지 충분조건이 아니다

통과하는 하니스는 모델이 자신의 질문들에 대해 일관되고 완전함을 증명합니다. 그것이 모델이 임을 증명하지는 않습니다. validate.pyWCB-CHO-001이 완전히 특성 규명되었고 계대 한도 이내임을 (CQ-17, CQ-18) 확인하지만, 냉동고의 바이알이 실제로 WCB-CHO-001이고 잘못 표시된 이웃이 아님을 확인할 수는 없습니다. 그것은 모든 수량이 단위를 지님을 (CQ-19) 확인하지만, 분석자가 올바른 숫자를 입력했는지는 확인할 수 없습니다. 하니스는 요구사항모델 사이의 루프를 닫습니다; 모델현실 사이의 루프는 습식 실험실 특성 규명, 데이터 무결성, 그리고 인간의 판단으로 닫힙니다 — 판결이 되돌아가는 그 한계들입니다. 초록색 표가 장마다 거듭 등장하는 동안 이 구분을 시야에 두십시오: 그것은 모델이 약속한 일을 한다는 것을 보증하는데, 이는 모델이 옳다는 주장보다 더 작고 더 정직한 주장입니다.

왜 중요한가

러닝 예제에 실행 가능한 하니스를 더한 것이, 이 책의 나머지를 그럴듯한 데 그치지 않고 신뢰할 만하게 만드는 것입니다. 앞으로의 모든 모델링 결정은 같은 방식으로 검사될 수 있습니다: 모델을 바꾸고, 하니스를 실행하고, 23줄을 읽으면 됩니다. 어떤 클래스가 제 자리를 얻는다면 역량 질문이 그것에 의존하며 초록색을 유지하고; 그렇지 않다면 그것을 제거해도 아무것도 망가지지 않습니다 — 이것이 어떤 클래스가 속하는지를 가리는 가장 깔끔한 검사입니다. 약은 이 책에 구체성을 주고, 하니스는 엄밀함을 줍니다.

실제 현장에서는

완전히 작업된 단 하나의 예제를 실행 가능한 검증기로 뒷받침하는 것이, 진지한 온톨로지가 실제로 출하되고 회귀 테스트되는 방식입니다 — SAMOD가 형식화한 패턴이자, 큰 어휘 프로젝트들이 모델이 성장하면서 썩지 않도록 유지하는 데 쓰는 패턴입니다 [2][3]. 실제 플랫폼에서 동일한 derivedFrom 순회는 Palantir Foundry의 객체 링크이거나 Neo4j Cypher 순회이며, 동일한 SHACL 게이트는 트리플스토어의 검증 단계에서 실행됩니다; 여기의 데이터셋은 한나절이면 읽을 만큼 작으면서도 생산 그래프가 답해야 할 모든 질문을 행사할 만큼 완전한데, 이것이야말로 교육용 산출물이 갖추어야 할 바로 그것입니다.

핵심 용어

  • 러닝 예제(Running example) — 처음부터 끝까지 모델링된 하나의 CHO mAb 캠페인(WCB-CHO-001 → … → DP-001, OOS 형제 DP-004 포함). 그래서 모든 장이 동일한 구체적 그래프 위에 쌓입니다.
  • 증명 하니스(validate.py) — 데이터셋을 파싱하고, 추론하고, 그것에 대해 23개 역량 질문을 실행하여 통과/실패 표를 출력하고 그것으로 게이트를 거는 프로그램.
  • OWL-RL 폐포(closure) — 질의가 실행되기 전에 함의된 사실들(전이적 계보, 장비 유형화)을 도출하는 규칙 기반 추론 단계.
  • 진짜 발췌(True excerpt) — 단순화된 예시가 아니라 로드 가능한 데이터셋의 일부를 글자 그대로 옮긴 코드 조각. 이 책의 상시 규칙입니다.
  • 초록색 기준선(Green baseline) — 뒤의 모든 장이 보존해야 하는 하니스의 전체 통과 상태(23/23).

다음 이야기

요구사항은 작성되었고 예제는 초록색으로 로드됩니다. 이제 생애주기 본편이 시작됩니다 — 그리고 그 첫 규칙은 빌릴 수 있는 것은 만들지 말라입니다. 다음 장, 상위 척추: 연속체, 발생체, 그리고 왜 모두가 BFO 위에 쌓는가는 모델의 가장 꼭대기에서 제2부(재사용)를 엽니다: 이후의 모든 클래스가 매달리는, 작고 도메인 중립적인 범주 집합과, 온톨로지가 내리는 첫 번째이자 가장 중대한 재사용 결정입니다.