검증: 실행 가능한 질의로서의 역량 질문
📍 현재 위치: 제6부 · 검증 — 모델이 만들어지는 것이 아니라 평가받는 단계입니다. 지배적 방법론은 SAMOD의 테스트 우선 루프(SAMOD와 NeOn은 확립된 두 온톨로지 공학 방법이며, SAMOD의 루프는 질문을 쓰고, 슬라이스를 모델링하고, 테스트하는 것입니다)로, 온톨로지 전체를 닫아 줍니다. 그리고 온톨로지는 그 요구사항에 답함으로써 검증된다는 NeOn의 원칙입니다. 이 장은 실행 가능한 ORSD(Ontology Requirements Specification Document — 역량 질문의 카탈로그)가 약속이기를 멈추고 실행이 되는 지점입니다.
다섯 개 부에 걸쳐 우리는 하나의 mAb 캠페인을 관통하는 간선(지식 그래프의 명명된 링크)을 놓아 왔습니다. 마스터·연구 은행에서 파생된 워킹 세포 은행(CHO = Chinese hamster ovary, 표준적인 항체 생산 세포주), 시드 트레인, 생물반응기 배치, 포획 풀, 두 개의 직교 바이러스 제거 풀, 폴리싱 풀, 원료의약품, 그리고 거기서 충전된 완제의약품 로트들 — 바이오의약품 제조에 처음부터 끝까지 펼쳐진 물리적 캠페인입니다. 각 장은 그 간선들이 실제 제조 질문에 답할 수 있으리라 믿었습니다 — 이 바이알을 그 세포 은행까지 추적하라, 실패한 로트의 운명 범위를 정하라, 바이러스 장벽들의 합을 증명하라. 검증은 우리가 믿기를 멈추고 실행하기 시작하는 순간입니다. 명세 장은 cq-catalog.json에 23개의 역량 질문을 고정하고 그것을 실행 가능한 요구사항 개요서라고 불렀습니다. 러닝 예제는 그 23개 전부가 하나의 초록색 표로 통과함을 보였습니다. 이 장은 그 표를 열어 그 아래에 깔린 질의들 — 각 제조 질문을, 로드되고 추론된 그래프 위에서 테스트된 사실로 바꾸는 실제 SPARQL — 을 읽습니다.
배치 기록은 여러분이 바이알을 그것이 나온 정확한 세포 은행까지 거슬러 추적할 수 있다고 약속합니다. 품질 검토자는 그 약속을 다시 읽지 않습니다 — 추적을 실행합니다. 역량 질문(competency question)은 배치 기록이 하는 약속("이 바이알이 무엇으로 만들어졌는지 전부 말해 줄 수 있는가?")이고, SPARQL 질의(SPARQL은 지식 그래프를 위한 표준 질의 언어로, SQL이 테이블에 대해 그러한 것과 같습니다)는 추적을 실행하는 것이며, 카탈로그의 기대 결과(expected result)는 기록이 반드시 산출해야 하는 답 — 여기서는 세포 은행에서 끝나는 조상 열한 개 — 입니다. 이 장은 검토자가 캠페인이 약속하는 모든 추적을 실행하고 각각 옆에 PASS 또는 FAIL을 쓰는 안내 과정이며 — 그리고 한 추적은 비어서 돌아오는 것이 당연한데, 무엇에 포장되어 있는가를 무엇으로 만들어졌는가와 분리해 두는 것 자체가 하나의 요구사항이기 때문입니다. (새로운 어휘 — SPARQL, 속성 경로, LRV, OWL-RL 폐포 — 는 이 페이지 맨 아래 핵심 용어에 모아 두었습니다.)
질문에서 출발하라
이 장은 질문-으로서의-질의가 머무는 곳이라, ORSD 카탈로그에서 가장 큰 몫을 짊어집니다 — 그리고 모든 질문은 조사관이, 출하 검토자가, 또는 리콜 팀이 바로 이 항체에 대해 묻는 실제 사안입니다. 계보(lineage) 질문 — 이 로트는 어떤 깊이까지든 무엇에서 파생되는가?(CQ-01)와 기원이 되는 생물반응기 배치와 그 모노머 값은 무엇인가?(CQ-03) — 은 일탈 조사가 시작하는 추적입니다. 영향(impact) 질문 — 캠페인 전체에서 워킹 세포 은행으로부터 내려오는 것은 무엇인가?(CQ-02)와 실패한 로트의 운명을 어떤 형제 로트들이 공유하는가?(CQ-04) — 은 리콜 팀이 가장 먼저 던지는 질문입니다. 궤적(trajectory) 질문(CQ-05)은 정제 사슬을 따라 핵심 품질 속성을 추적합니다. QbD(Quality-by-Design — 품질을 나중에 시험해서 가려내는 대신 공정에 설계해 넣는 것) 질문(CQ-06, CQ-07)은 개발 단계에서 설정된 공급 속도 파라미터에서 출하된 로트의 모노머 순도까지를 가로지릅니다. 바이러스(viral) 질문(CQ-12)은 두 개의 직교 제거 장벽을 합산합니다. 포장(packaging) 쌍(CQ-13, CQ-14)은 바이알이 무엇에 포장되어 있는가를 무엇으로 만들어졌는가와 분리해 둡니다. 출처(provenance)(CQ-15, CQ-16), 특성 규명(characterization)(CQ-18), 그리고 단위/구조(units/structural) 질문(CQ-19, CQ-20, CQ-21)이 그 집합을 채웁니다. 이 장은 그 질문 중 아홉 개를 온전히 걸어갑니다. 나머지 여덟 개의 질의 기반 CQ — 기원 배치 추적(CQ-03), 파라미터-대-CQA 매핑(CQ-06), 서명된 출하 ASK(CQ-09), 출처 및 특성 규명 검사(CQ-15, CQ-16, CQ-18), 맨숫자 금지 감사(CQ-19), 장비-대-배치 구조 분리(CQ-21) — 는 같은 형태를 따르며 러닝 예제의 전체 표에서 각자의 초록색 행으로 나타납니다. 각각은 산문이 아니라 그 질의가 카탈로그가 반드시 반환해야 한다고 말한 바로 그것을 정확히 반환하는지로 평가됩니다.
역량 질문은 어떻게 실행 가능한 질의가 되는가. 명세 장은 CQ가 어떻게 작성되는지를 보였습니다 — 원자적이며, 그 답의 형태가 미리 고정됩니다. 이 장은 그다음 단계를 합니다. 그 작성된 질문을 validate.py가 실행하고 판정하는 무언가로 바꾸는 것입니다. 그 절차는 스물세 개 전부에 대해 동일하며, 대표 사례인 CQ-01(로트는 어떤 깊이까지든 어떤 물질에서 파생되는가?)로 드러내 놓고 해 볼 만합니다 — 계보 추적은 제조 기록이 존재하는 이유인 바로 그 질문이라, 그 도출은 이 장의 이후 모든 CQ가 그것의 변형인 단 하나의 사례이기 때문에 골랐습니다:
- 답의 형태에서 결정적 산출물을 고른다. ORSD는 CQ-01의 답을 고정된 크기의 조상 물질 집합으로 고정했습니다 — 열거 가능한 결과이므로, 산출물은 SHACL 게이트(SHACL은 요구된 구조가 존재하는지를 검사하는 언어로, "빠진 것이 있는가?"에 답함)나 추론기 검사(추론기는 언명된 사실에서 논리적으로 따라 나오는 새로운 사실을 도출하며, "이것이 추론되었는가?"에 답함)가 아니라 SPARQL
SELECT(결과 행을 반환하는 질의)입니다. 답의 형태가 도구를 고릅니다. - 놓인 간선들에 대해 질의를 작성한다. 모델은 이미
derivedFrom을 전이적 속성(A가 B에서 파생되고 B가 C에서 파생되면, 자동으로 A는 C에서 파생됨)으로 지니므로, 그 추적은 단 하나의 속성 경로 —bp:DS-001 (bp:derivedFrom)+ ?ancestor, 즉 "원료의약품DS-001에서 출발해,derivedFrom을 하나 이상(+) 따라가며, 도달한 각 물질을 변수?ancestor에 모은다"로 읽음 — 이고(bp:는 프로젝트 자체 네임스페이스를 가리키는 짧은 접두어일 뿐입니다) 아무것도 미리 계산할 필요가 없습니다. 질의는 모델링 장들이 놓은 바로 그 간선들을, 실제 물질 변환마다 하나씩 읽습니다. - 질의가 실행되는 그래프를 명명한다. CQ-01의 카탈로그 항목은
"graph": "raw"를 기록합니다. 속성 경로가 도달 가능성을 자체적으로 계산하므로 질의는 미추론 트리플 위에서 실행되고(트리플은 지식 그래프의 원자 단위 — DS-001 → derivedFrom → POLpool-001 같은 주어-술어-목적어 진술이며, "원시(raw)" 그래프는 추론기가 어떤 것도 추가하기 전, 로드된 그대로의 트리플일 뿐입니다), 추론을 검사하는 CQ들(CQ-22)만 OWL-RL 폐포(추론기가 논리적으로 따라 나오는 모든 사실을 추가한 뒤의 더 큰 트리플 집합)를 요청합니다. 그래프를 고르는 것은 질문을 바인딩하는 일의 일부입니다. check.type을 답의 형태에 바인딩한다. 고정된 크기의 집합은{"type": "row_count", "value": 11}를 뜻하고, 명명된 집합이라면equals/contains, 불리언이라면ask, 합산된 열이라면sum, 요구된 행이라면row_match가 됩니다.check.type은 반증 가능한 답의 형태를 기계화한 것 그 자체이며 —validate.py는 그것에 직접 디스패치합니다.cq-catalog.json에 등록한다. 그 항목 —id,question,query파일,graph,check— 은validate.py가 읽는 단 하나의 기록입니다. 한 번 등록되면 CQ는 매 빌드의 수용 표에서 통과/실패 줄로 실행되고, 올바른 열한 개를 더는 반환하지 않게 된 모델은 눈에 보이게 실패합니다. 카탈로그에 없는 질문은 모델이 답하기로 약속하지 않은 질문입니다.
아래의 모든 절은 이 레시피의 한 번의 통과입니다. 산문은 질문과 그 동기를 명명하고, .rq 블록은 2단계이며, 그 옆에 인용된 카탈로그 check는 4단계입니다 — 그래서 각 PASS 줄은 레시피를 처음부터 끝까지 실행한 것입니다.
검증: 계보 추적이 CQ-01에 답한다
대표 질의는 계보 추적(lineage walk)입니다 — 로트가 파생되는 모든 것을, 몇 홉 떨어져 있든 재구성합니다. 이것은 제조 기록이 존재하는 이유인 바로 그 질문입니다. 세포 은행은 캠페인의 모든 배치가 거기서 내려오는 단 하나의 뿌리이고, 잘못 식별되거나 오염된 은행은 모든 하류 물질로 완전한 확신과 함께 전파되므로, 어떤 로트에서든 거기까지 거슬러 걸어갈 수 있다는 것은 편의가 아니라 규제·안전상의 필수입니다. derivedFrom이 전이적이기 때문에, 그 추적은 단 하나의 SPARQL 속성 경로(property path)입니다. (bp:derivedFrom)+는 하나 이상의 홉을 따라가므로, 계보가 세 단계든 스무 단계든 같은 한 줄이 작동합니다 [1]. queries/CQ-01.rq는 원료의약품에서 거슬러 걸으며 각 조상의 유형을 바인딩합니다(그 끝의 FILTER(STRSTARTS(...)) 줄은 단지 프로젝트 자체의 bp: 유형만 남기고, 임포트된 상위 온톨로지 클래스는 떨어뜨립니다):
# queries/CQ-01.rq — Lineage walk: everything DS-001 derives from, to any depth, in one property path.
# (bp:derivedFrom)+ = one-or-more hops; works whether the lineage is 3 steps or 20.
PREFIX bp: <https://example.org/bioproc#>
SELECT ?ancestor ?type WHERE {
bp:DS-001 (bp:derivedFrom)+ ?ancestor .
?ancestor a ?type .
FILTER(STRSTARTS(STR(?type), STR(bp:)))
} ORDER BY ?ancestor
카탈로그의 검사는 { "type": "row_count", "value": 11 }이고, 로드된 그래프 위에서 이 질의는 정확히 열한 개의 조상을 반환합니다 — 거친 CSV 사슬이 뭉개 버리는 모든 단위 작업 중간물입니다. 어느 그래프인지에 주목하십시오. validate.py는 질의 기반 CQ들을 원시(raw), 미추론 트리플 위에서 실행하는데, 속성 경로 (bp:derivedFrom)+가 이미 그 추적을 수행하기 때문입니다 — 계보 질문에 답하는 데에는 추론기가 필요 없고, 긴 간선을 그 자체의 트리플로 구체화(경로가 단계별로 계산해 내는 DS-001 derivedFrom RCB-CHO-001 같은 지름길 간선을 새로 저장되는 트리플로 써내는 것)하는 데에만 필요하며, 그것은 CQ-22가 인증하는 별개의 것입니다. 같은 질의를 OWL-RL 폐포 이후에 실행하면 사실 열한 개보다 많이 반환하는데 — 그렇게 추가된 지름길 트리플이 원시 그래프는 저장하지 않는 추가 ?ancestor 일치를 들여오기 때문입니다. 열한 개는 제조 기록이 산출해야 하는 답이며, 그것을 산출하는 것은 원시 속성 경로입니다. validate.py는 이 통과를 자신의 수용 표에서 한 줄로 보고합니다:
CQ-01 lineage PASS 11 row(s)
그 열한 개의 조상은 SELECT가 거슬러 걸어가는 열한 개의 바인딩된 ?ancestor 행입니다(BATCH-2026-001, CLAR-001, MCB-CHO-001, PApool-001, POLpool-001, RCB-CHO-001, SEED-001, SEEDFLASK-001, VFpool-001, VIpool-001, WCB-CHO-001). 그 깊이는 물리적 공정 전체를 역순으로 되짚습니다. DS-001은 폴리싱 풀(POLpool-001), 두 개의 직교 바이러스 제거 풀(VFpool-001, VIpool-001), 단백질 A 포획 풀과 청징 회수액(PApool-001, CLAR-001), 생물반응기 배치, 시드 트레인(SEED-001, SEEDFLASK-001), 그리고 세 개의 세포 은행 계층 — 워킹·마스터·연구 은행(WCB-CHO-001, MCB-CHO-001, RCB-CHO-001) — 을 거슬러 추적합니다. 그 세 계층은 임의의 위계가 아닙니다. 연구 은행이 마스터 은행의 시드가 되고, 마스터 은행이 워킹 은행의 시드가 되며, 오직 워킹 은행만 생산으로 확장되어, 항체의 유전적으로 특성 규명된 기원이 상업 제품을 만드는 여러 해에 걸쳐 보존됩니다. DS-001에서 RCB-CHO-001까지의 원거리 도달 가능성은 손으로 단언되는 일이 결코 없습니다. 속성 경로가 그것을 요청 시 계산하고, 전이적 폐포가 그것을 명시적 트리플로 구체화합니다. CQ-01의 PASS는 그 전반부를 인증합니다 — 놓인 간선들을 따라간 추적이 올바른 열한 개를 반환한다는 것입니다. CQ-22의 PASS는 그 후반부를 인증합니다 — 추론기가 DS-001 derivedFrom RCB-CHO-001을 하나의 사실로 단언하리라는 것입니다. 어느 쪽이든 요점은 그대로입니다. 간선을 충실히 — 실제 물질 변환마다 하나씩 — 놓으면, 계보는 마감을 앞둔 조사가 필요로 할 때 스프레드시트 고고학으로 재구성되는 것이 아니라 계산됩니다.
검증: 영향 분석이 CQ-02와 CQ-04에 답한다
영향 분석은 리콜 조사가 실제로 던지는, 역방향의 바깥쪽 질의입니다. CQ-02는 (bp:derivedFrom)+를 안쪽으로 뿌리까지 걸어가, WCB-CHO-001로부터 내려오는 캠페인 전체 — 그 한 은행으로 추적되는 모든 배치, 풀, 원료의약품, 제품 로트 — 를 반환하는데, 이는 세포 은행 수준의 우려(오식별 플래그, 무균성 의문)가 단 한 걸음에 위험에 빠뜨리는 집합입니다. CQ-04는 더 어려운 것입니다. DP-004가 출하에 실패할 때, 질문은 그 밖에 무엇이 영향을 받는가?입니다 — 그리고 그래프는 DP-004의 계보를 따라 공유 조상까지 올라간 다음, 거기로 추적되는 다른 모든 완제의약품까지 다시 내려가며 답합니다:
# queries/CQ-04.rq — Impact analysis: when DP-004 fails, what shares its fate?
PREFIX bp: <https://example.org/bioproc#>
SELECT DISTINCT ?affected WHERE {
bp:DP-004 (bp:derivedFrom)+ ?shared . # an ancestor of the failed lot
?affected (bp:derivedFrom)+ ?shared . # anything else derived from it
?affected a bp:DrugProduct .
FILTER(?affected != bp:DP-004)
} ORDER BY ?affected
CQ-04를 추동하는 실패는 구체적입니다. DP-004는 폴리싱이 고분자량(HMW) 응집체 — 출하 게이트가 상한으로 막는 면역원성 위험인 뭉친 항체 — 를 충분히 제거하지 못한 형제 계보라, 그 모노머 순도는 규격 안에 머무는데도 hmwPct가 2.0 % 출하 상한에 대해 2.41 %에 떨어집니다 — "그 밖에 무엇이 영향을 받는가?"를 가설이 아니라 긴급한 질문으로 만드는, 현실적인 규격 이탈 양상입니다. 카탈로그는 { "type": "equals", "var": "affected", "values": ["DP-001", "DP-002"] }를 요구하고, validate.py는 정확히 그 두 형제를 반환합니다 — 같은 원료의약품에서 충전되어 DP-004의 WCB-CHO-001 세포 은행을 공유하는, 출하된 로트들입니다. equals 검사는 수용 표에 일치된 집합을 출력합니다:
CQ-04 impact PASS affected = [DP-001, DP-002]
캠페인의 모든 배치가 그 한 세포 은행으로 추적되기 때문에, 오염 우려는 단 한 번의 순회로 캠페인 전체에 걸쳐 답할 수 있습니다 — 질의로 범위가 정해진 리콜과, 캠페인 전체를 눈먼 채 격리하는 것 사이의 차이입니다. 모델이 지니는 전방 분기(bp:DS-001 bp:fillsInto bp:DP-001 , bp:DP-002)는 영향 집합을 운에 의해서가 아니라 구성에 의해 완전하게 만드는 것입니다. 그것은 하류 장들이 놓은 후방 풀링 분기를 거울처럼 비추는, 전방향의 동일한 공유-운명 분기여서, 여러 충전 로트로 부채처럼 펼쳐지는 단 하나의 원료의약품이 완전히 순회 가능합니다. CQ-04의 equals 검사 — 단순한 contains가 아니라 — 는 모델이 모든 형제를 반환하되 가짜를 하나도 반환하지 않도록 붙드는 것이며, 이는 리콜 범위가 방어 가능하려면 충족해야 하는 바로 그 기준입니다. 같은 추적은 은행이 아니라 소모품을 공유하는 형제들도 범위에 넣을 것입니다(모델은 수지 로트 수명도 지닙니다). 여기서는 실패한 경로가 공유된 세포 은행을 통과하므로, 은행이 그 추적이 도달하는 조상입니다. 그 equals 기준 — 모든 참된 형제를, 가짜는 하나도 없이 — 은 리콜 기준 그 자체입니다. 거짓 음성을 흘려보내는 contains 검사는 영향받은 로트를 시장에 남겨 둘 것이고, 거짓 양성은 멀쩡한 로트를 격리할 것입니다.
검증: 수명주기를 가로지르는 추적이 CQ-07에 답한다
세 번째 부류는 개발, 제조, 출하 사이의 이음매를 가로지릅니다 — 오직 이 책의 모델링만이 물을 수 있게 만드는 질문입니다. 그것은 질의 가능해진 Quality-by-Design 약속입니다. 개발 단계에서 실험계획법 연구(어떤 입력이 출력을 움직이는지 보기 위해 입력을 변화시키는 구조화된 실험 묶음)가 공급 속도가 모노머 순도를 움직인다는 것을 발견하고, 그 발견은 연구 보고서의 산문 속에 묻히는 대신 공정 파라미터에서 품질 속성으로 가는, 저작된 affectsQuality 간선 — 모델러가 의도적으로 추가하는 링크 — 으로 기록됩니다. CQ-07은 그 핵심 공정 파라미터(CPP — 공정 입력, 여기서는 공급 속도로, 제품 품질을 좌우하기 때문에 통제됨)에서 출발해, 개발기의 affectsQuality 링크를 따라 품질 속성(CQA — 측정 가능한 제품 특성, 여기서는 출하 한도 안에 머물러야 하는 모노머 순도)에 이르고, 그 파라미터를 생산 생물반응기의 설정값으로 실현(realize)한 실행을 찾고, 그 실행이 출력한 배치로 이동한 다음, derivedFrom을 전방으로 걸어가 모노머 결과를 지닌 출하된 원료의약품 로트에 도달합니다:
# queries/CQ-07.rq — From a CPP, through affectsQuality, to the run that REALIZED it,
# to the batch it output, forward down derivedFrom to the released DS lot.
PREFIX bp: <https://example.org/bioproc#>
SELECT ?parameter ?attribute ?lot WHERE {
?parameter bp:affectsQuality ?attribute .
?setting bp:parameterType ?parameter .
?phase bp:realizesParameter ?setting .
?run bp:hasPhase ?phase ;
bp:hasOutput ?batch .
?lot bp:derivedFrom+ ?batch ;
bp:monomerPct ?m ;
a bp:DrugSubstance .
}
카탈로그의 검사는 { "type": "row_match", "match": { "parameter": "FeedRate", "lot": "DS-001" } }입니다 — 그리고 질의는 공급 속도 CPP를 그것이 궁극적으로 빚어낸 출하 로트에 안착시키며, 분절된 공장이 세 가지 방언으로 따로 두는 세 시스템 — 개발 연구, 플랜트 히스토리안과 QC 출하 기록(시계열 센서 아카이브와 품질관리 실험실의 결과 데이터베이스, 제2권에서 정의됨) — 을 결합합니다. 질의의 다섯 줄은 그 시스템들을 한 홉씩 사슬로 엮습니다 — ?parameter affectsQuality ?attribute는 개발 발견이고, ?setting parameterType ?parameter와 ?phase realizesParameter ?setting은 생물반응기에서 실제로 실행된 설정값으로 이동하며, ?run hasPhase ?phase ; hasOutput ?batch는 실행과 그것이 생산한 배치를 명명하고, ?lot derivedFrom+ ?batch는 모노머 결과를 지닌 출하된 원료의약품 로트로 전방으로 걸어갑니다. row_match 검사는 요구된 행이 존재함을 확인합니다(바인딩된 행은 ?attribute = MonomerPct-CQA, 즉 공급 속도가 영향을 주는 모노머 속성을 지닙니다):
CQ-07 qbd PASS row {parameter: FeedRate, lot: DS-001} present
그것이 책 전체가 향해 쌓아 온 단 하나의 질의입니다 [2]: 개발기의 affectsQuality 단언, 이 실행에서의 실현된 공급 속도 설정, 그리고 DS-001에 대한 QC 판정이 하나의 문장으로 결합됩니다. 공유 모델이 없으면 이 셋은 세 개의 서류함에 살고 "우리가 개발에서 조정한 파라미터가 정말로 출하 시 약속한 순도에 안착했는가?"라는 질문은 수작업 상호 참조입니다. 그것이 있으면, QbD 지식은 연결되고 질의 가능한 구조입니다.
CQ-07에 답하는 바로 그 affectsQuality 간선과 derivedFrom 계보는 또한 머신러닝 모델이 정직하게 견주어야 하는 그라운드 트루스입니다. 공급 속도로부터 모노머 순도를 예측하는 설계 공간 모델은 인과 주장을 단언하는 것이고, 그래프는 그 주장의 단언되고 사람이 큐레이션한 판본을 지니며, 추론되고 SHACL에 적합한 그래프와 모순되는 학습된 모델은 동반 권이 명명하는 검증 역설입니다 — 유창한 모델 대 검사된 기록의 대결이며, 기록이 이깁니다. 더 직접적으로, 계보 추적이 곧 교차 검증 폴드입니다. 바이오공정 ML의 대죄는 행 단위 무작위 학습/시험 분할인데, 형제 배치는 독립적인 사례가 아니기 때문입니다 — 이 캠페인의 모든 로트는 같은 WCB-CHO-001에서 내려오므로, 한 세포 은행에서 나온 두 로트는 사실상 쌍둥이이며, 그것들을 학습/시험 선 양쪽에 가르면 모델이 답을 보게 되어 환상의 점수를 보고합니다. 그 해법은 배치 그룹 분할(grouped split) — 한 배치의 모든 기록을 학습에 통째로 또는 시험에 통째로 보내는 것 — 이고, (bp:derivedFrom)+로 공유 세포 은행까지 거슬러 걸어가는 추적이 바로 그 그룹 키, 즉 Book 5의 데이터 장이 기본으로 삼고 모델·검증 장이 GroupKFold와 중첩 교차 검증으로 바꾸는 배치 단위 제외(leave-one-batch-out)(또는 세포 은행 단위 제외) 그룹화입니다. 리콜 범위를 정하는 그래프(CQ-04)와 정직한 검증 폴드를 정의하는 그래프는 같은 그래프이며 — 이것은 또한 "이 로트는 무엇에서 파생되었는가?"에 답하는 GraphRAG 검색이 CQ-01의 속성 경로를 그대로 재사용하는 이유입니다. 검색 계층의 진실의 원천은 모델이 존재하기를 바라는 한 문단이 아니라 카탈로그의 이미 초록색인 질의입니다.
세 가지 역량 질문, 하나의 그래프: 속성 경로가 계보를 세포 은행까지 거슬러 걸어가고(CQ-01), 영향 질의가 공유된 세포 은행을 통해 형제들에 걸쳐 실패 범위를 정하며(CQ-04), 수명주기를 가로지르는 링크가 공정 파라미터(FeedRate)를 그것이 영향을 주는 핵심 품질 속성(MonomerPct-CQA)에 잇고, 그 출하된 값은 DS-001에서 98.611 %입니다(CQ-07) — 각각
validate.py가 실행하고 카탈로그와 대조해 검사합니다.
저자가 AI의 도움을 받아 직접 제작한 그림입니다.
검증: 품질 궤적이 CQ-05에 답한다
CQ-05는 묻습니다 — 모노머 순도는 어디서 정화되었는가? — 그리고 정직한 답은 단일한 지점이 아니라 궤적입니다. 고분자량(HMW) 응집체 분율이 중요한 까닭은 응집체가 면역원성 위험이기 때문입니다. 출하 게이트는 그것을 상한으로 막고, 하류 사슬 전체가 그것을 끌어내리려 작동합니다. 그러나 어떤 단일 단계도 최종 수치를 "소유"하지 않습니다. 포획이 순도를 올리고, 바이러스 안전성이 그것을 보호하며, 폴리싱이 그것을 정련합니다 — 순도는 정제 시퀀스 전체의 누적 속성으로, 거의 창발적이며, 결코 한 작업의 행위가 아닙니다 [3]. 폴리싱은 항체를 밀접하게 관련된 산물 변이체 — 같은 항체 분자의 약간 변형된 형태, 여기서는 응집체 bp:AGG-1과 산성 전하 변이체 bp:CHV-1(약간 다른 전하를 띠어 의도된 산물로부터 분리 가능한 버전), 둘 다 바이러스 여과된 풀로부터 derivedFrom되고 폴리싱 폐기물 스트림으로 routedTo된 실제 존재로 모델링됨 — 로부터 분리함으로써 그 자리를 얻으며, 그래서 그래프는 수치가 개선되었다는 사실만이 아니라 무엇이 제거되었고 어디로 갔는지를 기록합니다. 질의는 HMW 값을 지닌 모든 공정 중 결과를 수집합니다:
# queries/CQ-05.rq — Quality-attribute trajectory: the in-process HMW aggregate value at
# each step along the purification chain, so an analyst can see WHERE a quality changed.
PREFIX bp: <https://example.org/bioproc#>
SELECT ?material ?hmw WHERE {
?result a bp:InProcessResult ;
bp:isAbout ?material ;
bp:hmwPct ?hmw .
} ORDER BY DESC(?hmw)
카탈로그는 결과가 PApool-001과 POLpool-001을 포함하도록 요구하고, 질의는 두 점짜리 사슬을 반환합니다 — HMW가 포획 후 4.1 %에서 폴리싱 후 1.4 %로 떨어지는, 한 품질 속성의 로드 가능하고 순서가 매겨진 역사입니다. 정밀한 독자라면 ORDER BY DESC(?hmw)가 계보 위치가 아니라 값으로 정렬한다는 점을 알아챌 것입니다 — 여기서 내림차순이 정제 시퀀스와 일치하는 것은 오직 순도가 단조롭게 개선되기 때문이며, 권위 있는 공정 순서는 derivedFrom 사슬이고, 그것이 바로 CQ-01의 계보 추적이 읽는 것입니다. CQ-05는 값을 보고하고, 사슬에서의 그 위치는 CQ-01에서 읽힙니다. 이것은 derivedFrom을 단순한 계보가 아니라 품질의 보관 사슬(chain of custody)로 읽는 것입니다. 각 간선은 물질과 그 속성의 진화하는 상태를 함께 지니므로, 그래프는 "이것은 어디서 왔는가?"뿐 아니라 "그 순도는 단계별로 어떻게 여기에 이르렀는가?"에도 답합니다 — 이는 계보를, 분석가가 설계 공간에 견주어 재생할 수 있는 공정 이해 기록으로 바꿉니다. CQ-05의 PASS는 그 역사가 서로 다른 시스템에 철해진 단계별 시험 보고서에 흩어져 있는 것이 아니라 질의 가능함을 인증합니다. CQ-05가 의도적으로 주장하지 않는 것은 인과입니다. 궤적은 값이 어디서 바뀌었는지를 보여 주지만, 단계들이 독립적이지 않기 때문에 — 폴리싱이 달성할 수 있는 것은 포획이 남긴 것에 달려 있으므로 — 그래프는 그것들 사이에 공로를 배분할 수 없습니다. 그 배분은 계보가 아니라 설계 공간 모델이 답하는 인과 추론 질문입니다. 이 장의 규율은 궤적을 기록하되 단일한 "순도 결정 단계"를 단언하기를 거부하는 것입니다.
검토자는 이 궤적에서 권위 수준도 읽어 냅니다. 4.1 %와 1.4 % 지점은 공정 중 결과(in-process result)(bp:InProcessResult, bp:isAbout를 통해 풀에 실림)로, 로트 처분이 아니라 공정 통제를 위해 측정됩니다. 로트를 출하하는 수치는 그와 다른, 더 높은 권위의 결과입니다. 원료의약품 로트 자체에 대한 SEC(크기 배제 크로마토그래피, 응집체 분율을 측정하는 분석법) HMW(bp:DS-001 bp:hmwPct "1.287")로, 출하 시료에서 <= 2.0 % 기준에 견주어 시험됩니다. 공정 중 모니터링 값을 출하 판정과 뒤섞는 것은 실제 데이터 무결성 실패 양상입니다. 폴리싱 풀에서 나온 1.4 %는 공정 지식이고, DS-001의 1.287 %는 처분 사실이며, 21 CFR 211(의약품 제조 출하를 규율하는 미국 FDA 규정) 출하가 의지하는 것은 오직 후자입니다. 그 구분은 ALCOA+의 구분 — 규제기관이 말하는, 귀속 가능(Attributable)·판독 가능(Legible)·동시 기록(Contemporaneous)·원본(Original)·정확(Accurate)하고, 더해(그 "+") 완전·일관·항구한 데이터의 약칭 — 입니다. 처분 값은 귀속 가능해야(누구의 서명이 그것을 출하하는가) 하고 원본이어야(전사된 모니터링 수치가 아니라 SEC 결과) 하며, bp:InProcessResult를 bp:DS-001 위의 출하 CQA와 구별해 두는 타입 부여 그래프는 그 귀속을 절차가 아니라 구조적으로 강제하는 것입니다. CQ-05는 공정 이해 질문에 답하고, 다음 장이 여는 출하 게이트는 처분 질문에 답하며, 모델은 결코 하나가 다른 하나로 행세하게 두지 않습니다.
검증: 직교 바이러스 제거가 CQ-12에 답한다
바이러스 안전성은 모델의 정직함이 시험받는 곳인데, 중요한 양이 산물 속성이 전혀 아니라 위험 감소의 척도 — 애초에 결코 거기 없었기를 바라는 오염원에 대한 보증 — 이기 때문입니다. 배치에서 "바이러스 제로"를 측정할 수는 없습니다. 대신 공정은 직교(orthogonal) 장벽들 — 서로 다른 메커니즘으로 바이러스를 제거하는 장벽들 — 로 구성되어, 하나를 살아남은 바이러스가 다른 하나도 살아남기는 어렵습니다. 러닝 예제는 두 개의 표준 장벽을 지닙니다. 외피 보유 바이러스를 불활성화하는 저 pH 유지(VI-001)와, 바이러스 입자를 크기로 제거하는 바이러스 차단 나노여과 단계(VF-001)입니다. 메커니즘이 독립적이기 때문에 그 로그 감소 값(LRV — 각각 단계가 바이러스를 얼마나 제거하는지의 밑 10 로그값으로, LRV 4.5는 단계가 바이러스 수준을 대략 10^4.5배, 약 30,000배 낮춘다는 뜻)도 독립적이며, 총 제거는 그것들의 합입니다 — 로그를 더하는 것으로, 4.5 + 4.2 = 8.7은 합쳐서 약 10^8.7배(대략 5억 배)의 감소입니다 — 단계들이 직교이기 때문에 비로소 방어 가능한 합입니다 [4]. 모델은 안전성 논거가 의존하는 날카로운 구분을 유지합니다. 각 단계의 LRV(4.5, 4.2)는 검증된 역량(validated capability)으로, 전용 제거 연구에서 한 번 입증되어 bp:hasClearanceCapability를 통해 단계에 매달리는 반면, 그 연구가 의존한 배치별 조건 — 이 실행에서 실제로 달성된 pH 3.6과 60분 유지 — 은 제거된 물질에 내재하는 측정된 품질입니다. CQ-12는 각 단계의 검증된 역량을 걸어가 그 LRV와 메커니즘을 읽습니다:
# queries/CQ-12.rq — Viral safety: each clearance step's VALIDATED log reduction value
# (a capability, not a per-batch measurement) and its mechanism.
PREFIX bp: <https://example.org/bioproc#>
SELECT ?step ?lrv ?mechanism WHERE {
?step bp:hasClearanceCapability ?cap .
?cap bp:lrvValue ?lrv ;
bp:clearanceMechanism ?mechanism .
} ORDER BY ?step
카탈로그의 검사는 { "type": "sum", "var": "lrv", "round": 1, "value": 8.7 }입니다. 질의는 [('VF-001', 4.2), ('VI-001', 4.5)]를 반환합니다 — 나노여과 단계의 size-based removal (nanofiltration)가 4.2이고 저 pH 유지의 enveloped-virus inactivation by low pH가 4.5이며 — 그 합인 8.7은 bp:VClear-Study가 한 번 확립한 직교 총합인 파생된 bp:TotalClearance-mAb-A 개체와 정확히 일치합니다. LRV가 bp:hasClearanceCapability를 통해 단계에 매달리는 것은 바로 그것이 배치별 측정과 결코 혼동되지 않도록 하기 위함입니다. 만약 그래프가 LRV를 이 배치의 산물에서 관측된 것처럼 기록한다면, 어떤 기기도 보지 못한 것을 단언하는 셈입니다 — 모델이 저지를 수 있는 안전성상 가장 치명적인 단 하나의 왜곡입니다.
온톨로지가 스스로에 대해 기록해 두는 정직한 단서가 하나 있습니다. BFO(기본 형식 온톨로지, 이 모델이 그 위에 쌓아 올리는 토대가 되는 상위 온톨로지)는 물질 존재(material entity)(필터나 액체 풀처럼 지속하는 것)와 발생물(occurrent)(공정 단계처럼 일어나는 것) 사이에 날카로운 선을 긋습니다. BFO에서 성향(disposition — 알맞은 조건 아래에서 특정 방식으로 거동하는 잠재적 경향이며, 역량은 성향의 일종)은 발생물이 아니라 물질 존재에 내재(belong)합니다 — 그런데 bp:VI-001과 bp:VF-001은 공정입니다(bp:ViralClearanceStep ⊑ bp:UnitOperation ⊑ bp:Process, 여기서 ⊑는 "의 하위 클래스이다"로 읽음). 따라서 LRV를 bp:hasClearanceCapability를 통해 단계에 매다는 것은 교육적 명료성을 위한 의도적이고 명시된 단순화이며, bp:hasClearanceCapability 정의가 파일 안에서 그렇게 밝혀 둡니다. BFO에 맞는 닻은 바로 그 옆에 보입니다. 나노필터 bp:NF-01은 bp:VF-001에서 실현되는 제거 bp:Function(bp:hasFunction bp:NF-clearance-fn)을 담지합니다. 배치별 조건은 이미 엄밀한 방식으로 모델링되어 있습니다 — bp:VIcond-pH와 bp:VIcond-time은 제거된 물질인 bp:VIpool-001에 bp:inheresIn하는 품질입니다. 이 CQ가 가르치는 교훈은 그 단서에도 살아남습니다. LRV는 관측이 아니라 검증된 역량입니다.
그 합을 검토자에게 방어 가능하게 만드는 것은 모델이 부호화하는 바입니다. ICH Q5A(R2)(FDA, EMA 등이 채택한 국제 바이러스 안전성 가이드라인) 아래에서 총 제거를 개별 로그 감소 값의 합으로 주장할 수 있는 것은, 단계들이 메커니즘상 직교이고 각 LRV가 관련 및 모델 바이러스 — 우려 바이러스에 대한 최악 조건의 대역(예컨대 외피 보유 모델로 X-MuLV, 작은 비외피 모델로 MMV) — 를 써서 축소 규모로 스파이크된 검증 연구(단계의 실험실 규모 복제본에 알려진 바이러스를 의도적으로 투여해 제거를 측정할 수 있게 한 것)에서 확립된 경우에 한합니다. 그래프는 그 출처를 지닙니다. 각 bp:LogReductionValue는 bp:establishedBy bp:VClear-Study이므로, LRV는 그 뒤에 연구를 둔 주장입니다 — 조사관이 4.5는 어디서 나왔는가?라고 물을 때 bp:hasClearanceCapability가 취하는 형태입니다. 두 장벽은 진정으로 다른 메커니즘으로 제거해야 합니다 — 저 pH는 지질 외피를 변성시키고, 나노여과는 크기로 배제합니다 — 그래서 비외피이고 여과에 저항하는 인자는 직교성 가정을 무너뜨리며, 방어 가능한 안전성 논거가 숨기는 대신 인정해야 하는 경계 사례입니다. 조건 범위(pH 3.6, 60분 유지)는 다음 장에서 강제 가능한 게이트가 됩니다.
CQ-12는 안전성 논거가 두 개의 무관한 서류함 속 수작업 집계가 아니라 — 각 LRV가 그 메커니즘에 연결되고 직교 합이 도출 가능한 — 연결되고 검사 가능한 구조임을 검증합니다.
두 직교 장벽, 합산되고 검사됨: CQ-12는
bp:hasClearanceCapability를 걸어가 각 단계의 검증된 LRV(4.5와 4.2)에 도달하고, 카탈로그는 그 합이 총 제거 8.7임을 확인합니다 — 스프레드시트 합계가 아니라 파생되고 질의 가능한 안전성 사실입니다.
저자가 AI의 도움을 받아 직접 제작한 그림입니다.
검증: 포함은 계보가 아니다 (CQ-13과 CQ-14)
원료의약품이 바이알에 충전되고 그 바이알이 유통을 위해 포장되면, 두 개의 전이적 위계가 같은 물리적 대상 위에서 만납니다 — 그리고 모델은 그것들을 날카롭게 유지해야 합니다. 포함(containment)(바이알이 지금 무엇에 포장되어 있는가 — 팔레트가 케이스를 담고, 케이스가 카톤을 담고, 카톤이 바이알을 담으며, 바이알은 재포장될 수 있음)은 계보(genealogy)(그것이 무엇으로 만들어졌는가 — 세포 은행, 배치, 원료의약품, 영구적이고 시간상 거꾸로 향함)가 아닙니다. 둘을 뒤섞으면 포장 변경이 계보 변경처럼 보이게 되는데, 이는 바로 리콜 추적을 깨뜨리는 종류의 오류입니다. CQ-13은 전이적 bp:contains 집계 위계를 걸어갑니다:
# queries/CQ-13.rq — Packaging containment (NOT lineage): walk the aggregation hierarchy
# pallet -> case -> carton -> serialized vial with the transitive bp:contains property.
PREFIX bp: <https://example.org/bioproc#>
SELECT ?package ?content WHERE {
?package bp:contains+ ?content .
?content a bp:SerializedUnit .
} ORDER BY ?package
그것은 카탈로그와 일치하는 패키지 [CARTON-001, CASE-001, PALLET-001]을 반환합니다. CQ-14는 비어서 돌아오는 것이 당연한 단 하나의 질의입니다 — 그것은 ASK(SELECT처럼 행이 아니라 단일한 참/거짓을 반환하는 SPARQL 형식)를 써서 직렬화된 바이알 VIAL-DP-001-000042의 포함 경로와 계보 경로 양쪽에 있는 노드가 있는지를 묻고, 모델은 그 답이 False일 때만 올바릅니다:
# queries/CQ-14.rq — containment is NOT genealogy. The model is correct when this ASK is FALSE.
PREFIX bp: <https://example.org/bioproc#>
ASK {
?container bp:contains+ bp:VIAL-DP-001-000042 .
bp:VIAL-DP-001-000042 bp:derivedFrom+ ?container .
}
카탈로그의 검사는 { "type": "ask", "value": false }이고, validate.py는 ASK = False를 보고합니다. 이것은 산문만으로는 놓치는 검증의 미묘한 부분입니다. 여기서 올바른 모델은 일치를 전혀 산출하지 않는데, 바이알이 무엇에 포장되어 있든 그것은 또한 그것이 만들어진 무언가가 아니기 때문입니다. 카톤은 바이알의 현재 포장의 일부이지 그 제조 역사가 아니며, 세포 은행은 그 역사의 일부이지 그 포장이 아닙니다. 빈 결과가 요구사항이며, CQ-14의 PASS는 두 전이적 위계의 disjointness가 유지된다는 증거입니다 — 그래서 재포장이 결코 재제조처럼 보이지 않고, derivedFrom을 따라 내려가는 리콜 추적이 결코 배송 컨테이너로 빠져나가지 않습니다. 그 비어 있음은 운이 아니라 구조적으로 보장됩니다. bp:contains와 bp:derivedFrom은 독립적인 속성으로 — 서로의 하위 속성(하나가 다른 하나를 함의하지 않음, "는-어머니이다"가 "는-부모이다"를 함의하는 식과 다름)도 역(하나를 거꾸로 따라가는 것이 다른 하나를 앞으로 따라가는 것과 같지 않음)도 아니고 — 캠페인의 어떤 개체도 바이알이 들어앉은 패키지이면서 동시에 바이알이 만들어진 물질인 경우가 없으므로, 두 전이적 위계는 disjoint하게(노드를 공유하지 않게) 유지되어 결코 겹칠 수 없습니다.
검증: 안정적인 숙주 동일성이 CQ-20에 답한다
CQ-20은 상호운용 가능한 동일성으로 그 집합을 마무리합니다 — 이 세포주는, 안정적인 식별자로 보아, 어떤 숙주 생물에서 그 산물을 발현하는가? 그 답이 중요한 까닭은 맨 문자열로서의 "CHO"는 실험실과 수십 년에 걸쳐 모호한 반면, 항체의 발현 숙주는 협력 기관이 추측 없이 읽을 수 있어야 하는 규제 대상 사실이기 때문입니다. 질의는 세포 은행의 숙주를 로컬 레이블이 아니라 그 클래스의 rdfs:subClassOf 정렬을 통해 공개 분류학 클래스로 해소합니다. 그 정렬은 의도적인 포섭(subsumption)입니다 — bp:HostOrganism rdfs:subClassOf obo:NCBITaxon_10029, 즉 로컬 숙주 클래스가 공개 택손 클래스의 일종("is-a")이라고 말하는, 연결 선택지 중 가장 약하고 가장 안전한 것 — 결코 owl:equivalentClass(두 클래스가 정확히 같은 집합)나 owl:sameAs(동일한 개체에 대한 두 이름)가 아닙니다. (접두어는 각 용어가 어디에 사는지를 명명합니다. rdfs:와 owl:은 표준 RDF-스키마와 OWL 어휘, obo:는 공개 OBO 라이브러리, bp:는 프로젝트 자체 네임스페이스입니다.) 프로그램은 자신의 로컬 숙주 클래스가 NCBI 택손이다라고 주장하지 않고, 모든 숙주가 그 아래에 든다고만 주장하는데, 이는 정렬이 두 어휘를 과도하게 병합하지 않도록 막는 보수적 선택입니다. 질의는 숙주 개체에서 그 클래스로, 다시 그 택손 IRI로 올라갑니다:
# queries/CQ-20.rq — the working cell bank's host organism is named by a STABLE public identifier.
PREFIX bp: <https://example.org/bioproc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
SELECT ?host ?taxon WHERE {
bp:WCB-CHO-001 bp:hasHostOrganism ?host .
?host a ?cls .
?cls rdfs:subClassOf ?taxon .
FILTER(STRSTARTS(STR(?taxon), STR(obo:)))
}
카탈로그는 행 { "host": "CHO-host", "taxon": "NCBITaxon_10029" }를 요구하고, 질의는 obo:NCBITaxon_10029에 도달합니다 — Cricetulus griseus, 그 CHO 세포가 상업 항체 생산을 지배하는 중국 햄스터 — 그래서 "무슨 종인가?"는 로컬 문자열이 아니라 협력 기관이 역참조할 수 있는 안정적인 IRI로 해소됩니다. 이곳은 또한 교차 온톨로지 이음매가 드러나는 곳입니다. 세포 은행의 생물학적 측면은 NCBI Taxonomy IRI로 손을 뻗고, 그 제조 기술 서술은 IOF 바이오제약 모듈로 손을 뻗으며, 그 다리는 조용히 임포트되는 것이 아니라 정렬에서 저작되고 유지됩니다.
평가: 카탈로그 전체, 초록색
이 아홉 개는 스물세 개 중 일부입니다. validate.py는 카탈로그 전체를 읽고, 로드되어 OWL-RL로 추론된 그래프에 대해 모든 항목을 실행하며, 역량 질문마다 PASS/FAIL 줄을 출력하고, 하나라도 실패하면 0이 아닌 값으로 종료합니다. 러닝 예제 장은 전체 표를 보여 줍니다. 이 장의 질의들이 산출하는 행들은 다음과 같이 읽힙니다:
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-04 impact PASS affected = [DP-001, DP-002]
CQ-05 trajectory PASS material superset of {PApool-001, POLpool-001} (2 total)
CQ-07 qbd PASS row {parameter: FeedRate, lot: DS-001} present
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-20 units PASS row {host: CHO-host, taxon: NCBITaxon_10029} present
그 표는 독자가 일 분 만에 실행할 수 있는 전적으로 오픈소스인 스택이 산출하며, 그것이 바로 실행 가능한 ORSD의 요점입니다. validate.py는 세 개의 Turtle 파일을 RDFLib(파이썬 RDF 라이브러리)로 파싱하고, OWL-RL 폐포를 owlrl로 구체화하며, 닫힌 세계 게이트를 pyShacl로 실행하고, 각 cq-catalog.json 항목을 그 check.type에 디스패치합니다 — 셋 모두 관대하게 라이선스되어(RDFLib과 pyShacl은 BSD 계열, owlrl은 W3C) 단 한 줄의 pip로 설치되고, 서버가 필요 없습니다. 전체 하니스는 로컬 그래프에 대해 오프라인으로 실행되며(python -m venv .venv && .venv/bin/pip install rdflib pyshacl owlrl, 이어서 .venv/bin/python examples/platform/ontology/validate.py), 이것이 수용 모음을 벤더 데모가 아니라 CI 단계로 만드는 것입니다. 오픈소스 책이 RDFLib과 SHACL로 노트북 위에서 구축하는 바로 그 검사들을, 여기서는 요구사항 카탈로그에 배선한 것입니다. 플랜트 규모에서는 동일한 .rq 파일들이 영속 트리플스토어 — Fuseki나 GraphDB 엔드포인트 — 에 대해 변경 없이 실행될 것인데, SPARQL 속성 경로가 엔진 이식 가능하기 때문입니다. 이 모음의 가치는 답을 고정한다는 데 있어, 저장소를 바꾸어도 리콜 범위가 조용히 달라질 수 없습니다. 카탈로그 자체는 설계상 벤더 중립을 유지합니다. CQ 항목은 .rq 파일과 graph와 check를 명명하므로, 요구사항은 트리플이 RDFLib의 인메모리 그래프에 살든 엔터프라이즈 저장소에 살든 동일합니다.
RESULT 열이 계약이고, DETAIL 열이 증거입니다. SPARQL 질의는 스물세 개 중 열일곱 개에 답합니다. 남은 여섯 개 중 네 개는 SELECT가 제기할 수 없는 닫힌 세계 출하·특성 규명 질문입니다 — 출하된 로트가 요구되는 모든 CQA에 대해 규격 안의 값을 정확히 하나씩 지니는가?(CQ-08), 완제 로트가 완제 고유 기준 — 무균성, 외관, 타당한 충전 용량 — 을 충족하는가?(CQ-10), 규격 이탈 로트가 정확히 실패한 경로에서만, 그리고 다른 어디서도 아니게 플래그되는가?(CQ-11), 워킹 세포 은행이 동일성, 무균성, 바이러스 안전성, 유전적 안정성에 대해 완전히 특성 규명되었는가?(CQ-17) — 이고, 이것들은 다음 장이 여는 SHACL 게이트가 답하는데, "빠진 것이 있는가?"는 존재하는 트리플이 아니라 존재해야 하는 트리플에 관한 질문이기 때문입니다. (나머지 두 개의 비-SELECT 항목인 CQ-22와 CQ-23은 형식화에서 구조적으로 실행되는 추론기 가드와 disjointness 가드입니다.) 그 네 개의 출하·특성 규명 질문은 폴리싱이 추동하는 출하 규격과 세포 은행 특성 규명 요구사항이 단지 추적 가능한 것을 넘어 강제 가능해지는 곳입니다.
이 분할은 열린 세계 논리와 닫힌 세계 논리의 경계입니다. SPARQL 속성 경로는 존재하는 간선을 걸어가므로, 질의 기반 CQ들은 "무엇에 도달 가능한가?"를 묻습니다 — 트리플이 추가될수록 자라기만 하는 답이며, 그래서 그것들은 원시, 미추론 그래프(gq = load()) 위에서 실행됩니다. (bp:derivedFrom)+ 경로는 전이적 도달 가능성을 기술 논리 추론기 없이 자체적으로 계산하므로, 계보 추적은 OWL 2 EL, QL, RL(세 개의 표준 OWL 프로파일 — 온톨로지 언어의 제한된 방언으로, 각각 다른 종류의 추론에 맞춰짐. 그 이름을 기억할 필요는 없고, 그 선택이 이 추적에 영향을 주지 않는다는 것만 기억하면 됩니다) 중 무엇을 고르든 독립적입니다. validate.py가 구체화하는 OWL-RL 폐포는 추론 자체를 검사하는 단 하나의 CQ — CQ-22 — 에만 필요합니다. 닫힌 세계 질문은 그 반대의, 열린 세계에서 불법인 질문 — "빠진 것이 있는가?" — 을 묻는데, 어떤 SELECT도 답할 수 없습니다. 열린 세계 가정(open-world assumption) 아래에서는 — 이런 종류의 논리에서의 기본값으로, 언명되지 않은 것을 거짓이 아니라 단지 미지로 다룹니다 — 없는 트리플은 거짓이 아니라 미지이기 때문입니다. (그 반대인 닫힌 세계(closed-world) 논리는 존재하지 않는 것을 거짓으로 다루며, 이것이 바로 SHACL 게이트가 요구된 값을 "빠졌다"고 선언할 수 있게 하는 것입니다.) 그것들은 다음 장에서 SHACL 셰이프가 됩니다. 요컨대 검증은 읽기 연습이 아닙니다. 그것은 실행이며, 모델은 모든 줄이 PASS라고 말할 때 정확히 검증됩니다.
미해결 과제: 통과하는 질의는 모델이 답한다는 것을 증명할 뿐, 데이터가 참임을 증명하지는 않는다
역량 질문 모음은 모델이 그 요구사항에 답할 수 있음을 인증합니다 — 그러나 그것은 파생된 뷰(derived view) 위에서 실행되며, 질의는 마지막 로드만큼만 참입니다. 그래프의 트리플은 실제 진실의 원천인 관계형 배치 기록, 플랜트 히스토리안과 LIMS(시계열 센서 아카이브와 실험실 정보 관리 시스템, 즉 QC 실험실의 결과 데이터베이스)에서 복사되므로, 로드가 변경 통제 아래에서 검증되고 완전하며 재실행되지 않는 한, 그래프는 그것이 비추는 시스템으로부터 조용히 표류(drift)할 수 있습니다. 그 원천들은 임의의 테이블이 아닙니다. CQ-07이 걸어가는 실현된 실행은 ISA-95 / B2MML 배치 생산 기록(실행된 배치를 위한 표준 XML 교환 — 그 <Equipment> 참조는 배치에 두 번째 유형을 붙이는 것이 아니라 occursIn 간선이 됨)과 히스토리안 아래의 OPC UA 태그, 즉 CQ-07이 결합하는 타입 부여 설정값으로 내려앉는 단위 보유 읽기를 통해 그래프에 도달하며, 이는 Book 2의 데이터모델 장이 명세하는 바입니다. 그 데이터모델을 존중하는 로더는 그래프의 계보를 MES의 배치 계보를 손실 있게 다시 키잉한 것이 아니라 그것과 동형으로 유지합니다. 그리고 로드는 규제기관이 검사할 수 있는 기록을 산출하는 시스템이므로 21 CFR Part 11 / EU Annex 11 의무 — 검증되고, 감사 추적되며, 귀속 가능한 변환 — 를 상속합니다. 그래서 derivedFrom 분기를 떨어뜨리는 재로드는 단순한 데이터 버그가 아니라 통제되고, 기록되고, 재검증되어야 하는 변경이며, 이는 CSV에서 CSA로 옮겨 가는 전산 시스템 검증이 모든 GxP 변환에 적용하는 바로 그 규율입니다. 그 위험은 이 장의 가치가 사는 바로 그곳에서 가장 날카롭습니다. 권위 있어 보이는 계보 추적이 조용히 불완전할 수 있습니다 — 로더가 건너뛴 derivedFrom 간선, 마지막 로드 이후의 원천 편집 — 그리고 그래프를 채우는 도크가 배치를 그것이 실행된 생물반응기로 착각하거나 형제 로트로 가는 분기를 빠뜨리면, 계보가 무너지고 리콜 추적이 조용히 바이알 하나를 놓칩니다. CQ-01이 조상 열한 개를 반환한다는 것은 속성 경로가 작동하고 로드된 간선이 연결됨을 증명합니다. 그러나 그것들을 산출한 로드가 부분적이었다면, 그 열한 개가 올바른 열한 개인지는 증명할 수 없습니다. 더 깊은 한계는 연합(federation, 하나의 지붕 아래 단일 그래프가 아니라 서로 다른 조직이 소유하고 호스팅하는 여러 그래프를 가로질러 질의하는 것)입니다. 수명주기를 가로지르는 추적과 계보 추적은 한 조직이 통제하는 공장 내부에서는 철벽이지만, 실타래가 유통업자와 공급망에 도달하는 순간 그것은 다른 당사자들의 그래프에, 그들의 식별자로 의존하며, 누구도 전체를 강제할 수 없습니다. 질의는 결코 어려운 부분이 아니었습니다. 그것이 실행되는 그래프를 참되게 유지하는 것이 어렵습니다 — 빠진 SELECT가 아니라 엔지니어링과 거버넌스 작업입니다.
왜 중요한가
검증은 모델링이 주장이기를 멈추고 측정 가능한 속성이 되는 곳이며 — 규제 대상 항체에게 그 이해관계는 구체적입니다. 실행 가능한 카탈로그가 없으면 "이 모델이 바이알을 그 세포 은행까지 추적하거나, 실패한 로트의 리콜 범위를 정할 수 있는가?"에는 테스트가 없습니다. 그것이 있으면, 그 질문들은 validate.py를 실행하고 표를 읽는 것으로 환원됩니다. 이 책의 모든 모델링 결정 — 상위 척추, 유형 값, 실제 변환마다의 충실한 derivedFrom 간선, 직교 제거 셰이프, disjointness 가드 — 은 이 질의들을 신뢰할 수 있게 만들기 위해 존재하며, 각 장은 자신이 봉사하는 역량 질문을 가리킴으로써 그 클래스를 얻습니다. 모든 질문에 답하는 모델이라도 아무도 적어 두지 않은 스물네 번째 질문에는 여전히 쓸모없을 수 있습니다. 그러나 자신의 질문 중 하나에 실패하는 모델 — 바이러스 장벽을 합산하지 못하거나, 잘못된 리콜 범위를 반환하는 모델 — 은 지금, 눈에 보이게, 빌드에서 깨져 있습니다.
실무에서는
역량 질문 규율은 산업이 채택하는 방법론의 척추이며, 실제 플랫폼에서 이 동일한 추적들은 일상적 작업입니다. derivedFrom 계보 경로는 Palantir Foundry 객체 링크나 Neo4j Cypher 순회(Foundry와 Neo4j는 널리 쓰이는 그래프 데이터 플랫폼이고, Cypher는 Neo4j의 질의 언어로 SPARQL의 속성 그래프 대응물)이고, 영향 분석은 로트가 실패하는 순간 리콜 팀이 던지는 질의입니다. 직교 제거 합산과 세포 은행 계보 추적은 모든 상업 mAb 공정이 이미 유지하는 바이러스 안전성 도시에와 은행 특성 규명 기록에 직접 대응합니다 — 모델링의 진전은 그것들을 연결하여 안전성 논거와 계보가 손으로 조정되는 별개의 서류함이 아니라 연결되고 질의 가능한 구조가 되게 하는 것입니다. 수명주기를 가로지르는 추적은 또한 실제 제품이 피할 수 없는 사건 — 기술 이전(tech transfer), 즉 공정을 개발 사이트에서 상업 플랜트나 제2의 제조사로 자격 인증을 거쳐 옮기는 것 — 에서도 살아남습니다. 같은 레시피가 새 생물반응기에서 다시 실현될 때, realizesParameter 간선은 설치·운전·성능이 재적격성 평가된 장비(이전된 라인이 출하 가능한 로트를 만들기 전에 통과해야 하는 IQ/OQ/PQ) 위에서 입증된 설정값에 다시 묶이므로, CQ-07은 여전히 개발기의 affectsQuality 발견을 수용 사이트의 출하된 로트에 안착시킵니다 — 그래프가 새롭고 단절된 기록을 시작하는 것이 아니라 그 이전을 가로질러 계보를 나릅니다. 그리고 CQ-01이 걸어가는 derivedFrom 계보는 정확히 MES(제조 실행 시스템) 배치 기록이 단언하고 예외에 의한 검토(review-by-exception)가 신뢰하는 구조입니다. 실행 가능한 카탈로그는 그 계보를, 마감을 앞두고 검토자가 손으로 다시 점검하는 종이 주장이 아니라 테스트된 불변식으로 만듭니다. 여전히 드문 것 — 그리고 이 책이 주장하는 것 — 은 역량 질문을 실행 가능하게 만들어, 요구사항과 회귀 테스트 모음이 결코 어긋나지 않게 하는 것입니다 [1]. 시맨틱 링크를 수명주기를 가로지르는 결합 조직으로 보는 디지털 스레드 개념은 스마트 제조와 디지털 트윈 문헌에서 확립되어 있습니다 [2]. 데모와 프로덕션 스레드를 가르는 것은 바로 이 장의 미해결 과제 — 검증되고 표류가 통제된 로드 — 이며, 이는 아무도 쓰지 않은 질의가 아니라 거버넌스 작업입니다.
핵심 용어
- ORSD(Ontology Requirements Specification Document) — 온톨로지가 반드시 해야 하는 일의 사전 카탈로그. 여기서는 그것이 실행 가능함 —
cq-catalog.json안의 23개 역량 질문으로, 각각 질의로 실행되어 기대 결과와 대조해 검사됨. - 역량 질문(Competency question, CQ) — 완성된 온톨로지가 반드시 답해야 하는 질의로, 모델링 이전에 고정됨. 여기서는
validate.py가 실행하고cq-catalog.json과 대조해 검사하는 실제 제조 질문(추적, 리콜 범위, QbD 링크). - SPARQL 속성 경로(SPARQL property path) — 임의 깊이의 계보나 포함 추적을 한 줄로 표현하는
(bp:derivedFrom)+"하나 이상의 홉" 구성. - 계보 추적(Lineage walk, CQ-01) —
DS-001의 모든 열한 개 조상을 풀, 배치, 시드 트레인, 세 세포 은행 계층을 거슬러 재구성하는 속성 경로 질의.(bp:derivedFrom)+경로가 원시 그래프 위에서 원거리 도달 가능성을 계산함(그것을 트리플로 구체화하는 OWL-RL 폐포는 CQ-22가 인증하는 별개의 것). - 영향 분석(Impact analysis, CQ-04) — 공유 세포 은행까지 올라갔다가
fillsInto전방 분기를 통해 두 형제DP-001과DP-002까지 다시 내려가며 실패한 로트의 운명 범위를 정하는, 역방향의 바깥쪽 질의. - 수명주기를 가로지르는 질의(Cross-lifecycle query, CQ-07) — 개발, 제조, 출하 이음매를 가로지르는 QbD 질문(공급 속도 파라미터 → 실현된 실행 → 출하된 로트)으로, 오직 공유 모델만이 물을 수 있게 함.
- 품질 궤적(Quality trajectory, CQ-05) — 사슬을 따라 내려가는 공정 중 HMW 값(
4.1 %→1.4 %)으로, 품질의 보관 사슬로 읽힌derivedFrom. 순도가 어디서 바뀌었는지를 보여 주지, 어떤 단계가 그것을 야기했는지를 보여 주지 않음. - 직교 제거(Orthogonal clearance, CQ-12) — 메커니즘상 독립적인 두 LRV의 합(저 pH 불활성화 4.5 + 크기 기반 나노여과 4.2 = 8.7)으로, 장벽이 직교이기 때문에 유효함. 배치별 측정이 아니라 단계의 검증된 역량.
- 포함은 계보가 아니다(Containment-is-not-genealogy, CQ-14) — False일 때만 올바른
ASK. 어떤 노드도 바이알의contains경로와derivedFrom경로 양쪽에 있지 않음. - 파생된 뷰 / 표류(Derived view / drift) — 그래프의 트리플은 원천 시스템에서 복사되므로, 통과하는 질의는 모델이 답한다는 것을 증명할 뿐, 거버넌스되지 않고 오래된 로드가 여전히 참임을 증명하지는 않음.
- 배치 그룹 분할 / 배치 단위 제외(Grouped / leave-one-batch-out split) — 한 배치의 모든 기록을 학습에 통째로 또는 시험에 통째로 두는 교차 검증 규율.
(bp:derivedFrom)+로 공유 세포 은행까지 거슬러 걸어가는 추적이 곧 그룹 키이므로, 계보 그래프와 정직한 검증 폴드가 하나의 구조임(Book 5의 데이터와 모델·검증 참조). - ALCOA+ — 데이터 무결성 표준(귀속 가능, 판독 가능, 동시 기록, 원본, 정확, 더해 완전·일관·항구).
bp:InProcessResult를 출하 CQA와 구별해 두는 것이 귀속을 구조적으로 강제하고, Part 11 / Annex 11 감사 추적이 그래프를 채우는 로드를 거버넌스함. - 기술 이전 / IQ-OQ-PQ(Tech transfer / IQ-OQ-PQ) — 공정을 새 라인으로 자격 인증을 거쳐 옮기는 것. 실현된 파라미터 간선이 재적격성 평가된 장비에 다시 묶이므로, CQ-07은 개발 발견을 수용 사이트의 출하된 로트에 안착시키지 단절된 기록을 시작하지 않음.
이어지는 곳
SPARQL 질의가 답할 수 있는 역량 질문은 답해졌고 초록색입니다. 그러나 스물세 개 중 네 개는 질의가 제기할 수 없는 닫힌 세계 질문입니다 — 세포 은행이 완전히 특성 규명되었는가? 이 로트가 요구되는 모든 속성에서 규격 안에 있는가? 다음 장 출하 게이트와 SHACL: 완전성과 규격의 검증은 그것들로 향합니다. 그것은 출하 결정을 게이트하는 SHACL 셰이프 — 위에서 소개한 요구된 구조 검사 — 를 구축하고, 규격 이탈 형제 DP-004가 정확히 한 경로(2.0 % 상한에 대한 2.41 %의 hmwPct)에서만 실패하고 다른 어디서도 실패하지 않는 이유를 보이며, 질의가 닿을 수 없는 닫힌 세계 절반으로 검증 단계를 완성합니다.