구현: 인스턴스 그래프 구축하기
📍 현재 위치: 제5부 · 구현 — 제3~4부의 클래스, 공리, 정렬이 로드 가능한 파일 안에서 개별자(individual)가 되는 단계입니다. 방법론은 여전히 SAMOD의 테스트 우선 루프이지만, 테스트 데이터는 실제 mAb 캠페인입니다: 조작된 CHO 세포가 든 얼린 바이알 하나를 확장하고, 수확하고, 포획하고, 폴리싱하고, 바이알에 충전합니다. 우리는 그 캠페인을 인스턴스화한 뒤, 제조사가 실제로 던지는 계보와 출하 질문 — 어떤 은행이 이 로트를 만들었는가, 계대 한도 내인가, 실패한 로트와 운명을 공유하는 것은 무엇인가 — 을 우리가 구축한 그래프에 대고 묻습니다.
어떤 배치도 채워 넣지 않는 어휘는 온톨로지가 아니라 가설입니다. 구현이란 하나의 항체 캠페인의 개별자(individual) — 워킹 세포 은행 bp:WCB-CHO-001, 정제된 수확물 bp:CLAR-001, 출하된 원료의약품 bp:DS-001 — 을 단언하는 행위이며, 그렇게 해야 품질 부서가 의지하는 질문들이 약속이기를 멈추고 답이 있는 질의가 됩니다. 이 장은 전체 작업 예제를 담은 단일 파일 instances.ttl을 처음부터 끝까지 따라갑니다: 선도 항체를 발현하는 조작된 세포주를 만드는 형질주입에서 시작해, 마스터·워킹 세포 은행 단계를 내려가, 계대가 누적되는 시드 트레인을 거쳐, 한 탱크의 배양액이 두 물질이 되는 수확 경계를 가로질러, 여러 배치에 걸쳐 재사용되는 수지에서 다수 사이클이 하나의 풀로 합쳐지는 포획을 지나, 열한 조상이 수렴하고 출하가 결정되는 원료의약품에 이릅니다. 아래의 모든 블록은 그 파일의 한 글자도 다르지 않은 발췌입니다. 지어낸 것은 없습니다. 핵심 수치 — 검증된 한도 40에 대한 계대 8, 단량체 98.611, DS-001의 열한 조상, 게이트를 걸리게 하는 규격 외 HMW 응집체 — 는 추론기(reasoner)가 점검하는 바로 그 수치입니다.
클래스 다이어그램은 일련의 양식(form)입니다: "세포 은행", "배치", "원료의약품"이라고 적힌 빈 상자들. 그러나 세포 은행은 빈 상자가 아닙니다 — 그것은 살아 있고 얼린 세포가 든 바이알이며, 모든 빵 덩어리가 빵집의 사워도우 스타터로 거슬러 올라가듯, 이후의 모든 배치가 거기서 내려옵니다. 구현이란 그 양식을 하나의 특정 항체에 대해 채워 넣는 일입니다: 스타터 바이알에 WCB-CHO-001, 그것이 자라난 생산 운전에 BATCH-2026-001, 출하된 로트에 DS-001을 적고, 이 로트는 저 은행에서 나왔다고 말하는 화살표를 그리는 것입니다. 양식이 채워지고 나면, 빈 상자를 감상하는 대신 마침내 실제 제조 질문 — "이 로트가 실패하면, 같은 은행에서 나온 다른 것은 무엇인가?" — 을 던질 수 있습니다. 이 장은 하나의 mAb 캠페인에 대해 모든 양식을 채워 넣고, 그것을 담은 파일을 보여 줍니다.
제조사가 던지는 질문에서 출발하라
인스턴스 그래프는 어떤 의약품이 출하되는지를 결정하는 계보와 영향 질문에 답하기 위해 존재합니다. 세 개의 역량 질문(competency question)이 아래의 거의 모든 것을 이끌며, 각각은 구조 질문이 아니라 실제 성향(disposition) 질문입니다. CQ-01 — 임의의 하류 물질이 주어졌을 때, 그것은 어떤 물질에서 깊이에 상관없이 유래하는가? — 은 출하된 로트가 의심스러울 때 조사관이 던지는 질문입니다: 모든 정제 단계를 거쳐 세포 은행까지 거슬러 추적하며, 우리가 간선 하나하나로 까는 derivedFrom 사슬이 답합니다. CQ-02 — 워킹 세포 은행이 주어졌을 때, 캠페인 전체에서 어떤 물질이 거기서 내려오는가? — 은 리콜이 범위를 정하는 질문입니다: 은행이 의심스러우면 거기서 분주된 모든 것도 그렇기에, bp:WCB-CHO-001로부터의 역방향 순회가 답합니다. CQ-03 — 원료의약품 로트의 기원 생물반응기 배치는 무엇이며, 그 출하 단량체 값은 얼마인가? — 은 출하된 로트를 그것을 만든 운전으로 다시 묶으며, bp:DS-001에서 bp:BATCH-2026-001로 걸어가 98.611을 읽음으로써 답합니다. 그리고 CQ-04 — 로트가 실패하면, 어떤 다른 것들이 그 운명을 공유하는가? — 는 확신에 찬 리콜을 추측이 아니라 질의로 바꾸는 질문입니다. 보조 게이트들(CQ-17 세포 은행 특성 규명, CQ-18 계대 한도)도 여기서 구축한 개별자에 묶입니다. 우리가 단언하는 모든 인스턴스는 이 중 하나에 봉사함으로써 제자리를 얻습니다. 철저해 보이려고 모델링한 것은 없습니다.
만듦을 구현하라: 조작된 세포주를 만드는 형질주입
생물의약품의 계보는 사물이 아니라 사건(event)에서 시작합니다 — 그리고 사건을 사물과 구별해 두는 것이야말로, 나중에 그래프가 이것은 무엇인가?만이 아니라 이것은 어떻게 만들어졌는가?에 답하게 합니다. 세포주 슬라이스는 CellLine ⊑ ∃createdBy.Transfection을 선언하여 제조 사실 하나를 인코딩했습니다: 조작된 CHO 세포주는 그냥 존재하는 것이 아니라, 항체 유전자를 숙주에 도입함으로써 생산되었습니다. 구현은 그 존재 제약(existential restriction)을 실제 occurrent로 충족해야 합니다. 형질주입은 발현 벡터를 소비하고 조작된 세포주를 산출하며, 그 세포주는 발견 선도 bp:mAb-A를 발현합니다:
# instances.ttl — the line was MADE (an occurrent), satisfying CellLine ⊑ ∃createdBy.Transfection.
bp:CHO-host a bp:HostOrganism ; rdfs:label "Chinese hamster (Cricetulus griseus)" .
bp:CONSTRUCT-mAb-A a bp:GeneticConstruct ; rdfs:label "mAb-A expression vector" .
bp:CELLLINE-001 a bp:CellLine ; rdfs:label "engineered CHO line for mAb-A" ;
bp:hasHostOrganism bp:CHO-host ;
bp:createdBy bp:TF-001 ;
bp:expresses bp:mAb-A .
bp:TF-001 a bp:Transfection ; rdfs:label "transfection of mAb-A construct into CHO" ;
bp:hasInput bp:CONSTRUCT-mAb-A ; bp:hasOutput bp:CELLLINE-001 .
bp:CLONE-7 a bp:Clone ; rdfs:label "selected single-cell clone #7" .
숙주는 bp:CHO-host로, bp:HostOrganism으로 유형이 정해지고 문자열 "CHO"가 아니라 Cricetulus griseus의 NCBI Taxonomy IRI로 정렬됩니다 [1]. 이것은 인스턴스 수준에서 구체화된 재사용 규율이며, 제조상의 이유로도 중요합니다: CHO는 상업적 항체 생산의 주력 숙주이고, 그 유전체는 서열이 밝혀져 공개되어 있으며, 분류군 IRI를 읽는 하류 도구는 우리 숙주를 다른 누구의 CHO 세포주와도 나란히 줄 세울 수 있습니다. 생물학은 빌려 온 공개 식별자이며, 오직 프로그램 고유의 클론과 세포주만이 로컬로 새로 발행됩니다. 하나의 형질주입을 가리키는 bp:createdBy 간선은 함수적(functional)이므로, 추론기는 두 번 입력된 형질주입 기록을 같은 사건으로 취급합니다 — 평평한 세포 은행 기록 스프레드시트라면 조용히 두 번 받아들였을 중복 출처를 내장된 방식으로 중복 제거하는 것입니다.
계보를 구현하라: RCB → MCB → WCB-CHO-001, 닻이 되는 뿌리
그다음은 은행 작업(banking) — derivedFrom 사슬이며, 그 뿌리는 그래프에서 가장 중요한 노드입니다. 이후의 모든 배치가 그것으로 거슬러 올라가고, 그 동일성에 생긴 오류가 모든 후손으로 전파되기 때문입니다. 제조 프로그램이 하나가 아니라 세 단계를 짓는 이유는 규제와 안전의 이유입니다: 단일 연구 은행(RCB)이 마스터 은행(MCB)으로 특성 규명되어 철저히 시험되고 단 한 번 동결되며, 각 캠페인은 마스터에서 워킹 은행(WCB)을 인출하여 귀중한 마스터가 결코 소진되지 않게 합니다. 워킹 은행은 자신의 계대 수와, 세포 은행 게이트가 요구하는 네 가지 특성 규명 결과를 짊어집니다 [2]:
# instances.ttl — the cell-bank tiers: RCB -> MCB -> WCB (the root of the genealogy).
bp:RCB-CHO-001 a bp:ResearchCellBank ; rdfs:label "RCB-CHO-001" ;
bp:expresses bp:mAb-A ; bp:passageNumber 2 .
bp:MCB-CHO-001 a bp:MasterCellBank ; rdfs:label "MCB-CHO-001" ;
bp:derivedFrom bp:RCB-CHO-001 ;
bp:hasClone bp:CLONE-7 ;
bp:passageNumber 5 .
bp:WCB-CHO-001 a bp:WorkingCellBank ; rdfs:label "WCB-CHO-001" ;
bp:derivedFrom bp:MCB-CHO-001 ;
bp:hasHostOrganism bp:CHO-host ;
bp:expresses bp:mAb-A ;
bp:passageNumber 8 ;
bp:hasCharacterization bp:CR-identity , bp:CR-sterility , bp:CR-viral , bp:CR-genetic .
bp:PassageLimit-mAb-A a bp:ValidatedPassageLimit ; rdfs:label "validated passage limit, mAb-A line" ;
bp:validatedPassageLimit 40 .
이것이 CQ-18에 대한 구현 답입니다: 은행은 계대 8에 서 있고, 검증된 한도는 40이며, 한도 내(within limit)는 그래프가 평가하는 조인(8 <= 40)입니다. 계대 수는 관료적 장부 기재가 아닙니다 — 그것은 생산성 표류와 산물 품질 변화가 실제 위험이 되기 전에 살아 있는 배양을 얼마나 오래 키울 수 있는지를 한정하므로, 그 비교는 진짜 GMP 게이트입니다. 네 개의 bp:CharacterizationResult 개별자는 각각, 오인식되거나 오염된 은행이라면 실패할 무언가를 시험합니다: CR-identity(정말로 mAb-A 세포주인가?), CR-sterility(마이코플라스마 없음), CR-viral(외래 인자 없음), CR-genetic(구성체가 안정적임). 각각은 bp:verdict "PASS"와 함께 bp:isAbout bp:WCB-CHO-001이며, CQ-17과 이 장에서 앞서 작성한 한정 카디널리티 제약을 충족합니다. 여기서 확립된 계대 수는 시드 트레인이 증가시키는 시계(clock)입니다.
구현된 뿌리: 형질주입이 조작된 세포주를 만들고, 클론은 연구·마스터·워킹 단계를 거치며
derivedFrom 계통으로 은행에 보관되며, WCB-CHO-001은 이후 모든 하류 개별자가 전이적으로 거슬러 올라가는 닻이 됩니다.
저자가 AI의 도움을 받아 직접 제작한 그림입니다.
시드 트레인을 구현하라: 세포가 확장되며 계대가 누적된다
WCB 바이알 하나에는 고작 수백만 개의 세포가 들어 있지만, 생산에는 수십억 개가 필요합니다. 시드 트레인(seed train)은 바이알을 해동해 점점 더 큰 용기 — 진탕 플라스크, 그다음 시드 생물반응기 — 를 거쳐 세포를 키움으로써 그 간극을 메우며, 각 스케일업은 하나의 세포 물질을 소비하고 더 큰 물질을 산출하는 실제 확장 occurrent로 모델링되고, 계대 시계는 각 단계마다 전진합니다(진탕 플라스크에서 12, 시드 생물반응기에서 16):
# instances.ttl — the seed train: real expansion stages, accumulating passage.
bp:SEEDFLASK-001 a bp:ShakeFlaskCulture ; rdfs:label "shake-flask seed culture" ;
bp:derivedFrom bp:WCB-CHO-001 ;
bp:participatesIn bp:EXP-001 ;
bp:passageNumber 12 .
bp:SEED-001 a bp:SeedBioreactorCulture ; rdfs:label "SEED-001 (seed bioreactor culture)" ;
bp:derivedFrom bp:SEEDFLASK-001 ;
bp:participatesIn bp:EXP-002 ;
bp:hasHostOrganism bp:CHO-host ;
bp:passageNumber 16 .
이어서 bp:BATCH-2026-001이 derivedFrom bp:SEED-001이므로, 생산 배치는 전이적으로 WCB-CHO-001로 거슬러 올라갑니다 — 사이에 확장 단계가 몇 개 놓이든 상관없이 CQ-01이 걸어가는 등뼈입니다. 계대는 8 → 12 → 16으로 오르며 모두 검증된 40 미만이므로, 이 배치는 한도 내 세포에서 접종되었는가?라는 GMP 질문이 이제는 실험 노트로부터의 재구성이 아니라 질의가 됩니다. 그러나 깔끔한 두 노드 사슬은 진짜 모델링 판단을 감추고 있습니다: 시드 트레인은 사실 이산적인 사건의 시퀀스가 아니라 연속적인 성장(continuous growth)이며, 세포는 매일 분열하고 때때로 용기 사이에서 나뉩니다. 노드 경계를 어디에 둘 것인가 — 용기 이송마다, 하루마다, 플라스크 분할마다 — 는 생물학이 대신 정해 주지 않는 선택입니다. 너무 거칠게 모델링하면 오염을 특정 이송까지 추적할 수 없고, 너무 세밀하게 하면 그래프가 아무도 질의하지 않는 노드에 잠깁니다. 우리는 확장 단계마다 노드를 하나씩 발행하는데, 그것이 세포가 샘플링되고 계대가 세어지는 입도이기 때문입니다. 그러나 그 노드들은 살아 있는 연속체의 의도적인 단순화이지, 생물학이 건네주는 사실이 아닙니다. 배치는 bp:monomerPct "98.611"을 공정 중(in-process) 값으로 짊어지며, 디지털 스레드는 나중에 CQ-03에 답할 때 이것을 읽습니다 — 다만, 곧 보겠지만 그 결과가 충실하게 깃들 곳은 배치가 아니라 출하된 로트입니다.
물질 개별화를 구현하라: 수확은 하나가 들어가 둘이 나온다
수확과 정제(clarification)는 하류의 본보기이며, 모든 derivedFrom 간선 밑에 숨은 질문을 강제합니다: 하나의 물질은 언제 자기 자신이기를 멈추고 그래프가 이름 붙여야 할 새로운 것이 되는가? 정제된 수확물 속의 산물 분자는 배양액 속에 있던 바로 그 분자입니다 — 아무것도 생겨나지 않았고, 다만 세포와 잔해로부터 분리되었을 뿐입니다. 그렇다면 정제된 수확물은 자기 IRI를 받을 자격이 있는 새 물질 존재인가, 아니면 이름만 다시 붙인 같은 물질인가? 화학이 정하지 않습니다. 모델이 정합니다. 이 책이 취하는 관습은 각 단위 조작(unit operation) 경계마다 새 물질 노드를 발행하는 것인데, 그것이 물질이 샘플링·시험·풀링·출하되는 입도이기 때문입니다 — 그리고 정제는 두 개의 그러한 물질을 산출합니다: 우리가 보관하는 정제된 수확물과, 우리가 폐기하는 소진된 바이오매스입니다 [3]:
# instances.ttl — harvest clarification: one material in, two out (the downstream template).
bp:CLAR-001 a bp:ClarifiedHarvest ; rdfs:label "clarified harvest of BATCH-2026-001" ;
bp:derivedFrom bp:BATCH-2026-001 ;
bp:participatesIn bp:HARV-001 ;
bp:turbidityNtu "3.2"^^xsd:float .
bp:BIOMASS-001 a bp:SpentBiomass ; rdfs:label "spent biomass (cells + debris)" ;
bp:derivedFrom bp:BATCH-2026-001 .
bp:HARV-001 a bp:Clarification ; rdfs:label "harvest clarification" ;
bp:hasInput bp:BATCH-2026-001 ;
bp:hasOutput bp:CLAR-001 , bp:BIOMASS-001 .
정제된 수확물은 탁도 결과(3.2 NTU, 그것의 첫 공정 중 품질)와 앞으로의 인계를 받는 것이기에 자기 노드를 얻습니다. 소진된 바이오매스도 하나를 얻는데, 그렇게 해야 오염 추적과 물질수지가 가리킬 폐기 스트림을 갖게 됩니다. 교과서를 조직하는 그 유명한 상류-대-하류 경계는, 그래프에는 하나의 연속 사슬 속 또 하나의 derivedFrom 간선일 뿐입니다. 이 간선이 강제하지 않는 한 가지는 물질수지(mass balance)입니다: derivedFrom은 계보를 기록하지 보존을 기록하지 않습니다 — "이것이 저것에서 나왔다"고 말할 뿐, "이만큼이 저만큼에서 나왔다"고 말하지 않습니다. 그래프는 보관된 수확물과 폐기물을 합쳐도 투입된 것과 맞아떨어지지 않는, 완벽히 순회 가능한 계보를 기꺼이 내놓을 것입니다. 그것을 잡아내려면 양(quantity)을 명시적으로 모델링하고 검증해야 하기 때문입니다. 정직한 기준은, 그래프가 계보를 색인하는 동안 물질수지는 공정 기록에 산다는 것입니다. 맨 3.2는 정직하지만, 단위가 부여되기 전까지는 빈약하며, 그것이 다음 장의 주제입니다.
풀링 분기를 구현하라: PApool-001, 여러 사이클에서 나온 하나의 풀
포획 크로마토그래피는 단순한 부모-자식 간선이 처음으로 무너지는 곳입니다. Protein A 포획은 항체를 특이적으로 결합하고 나머지를 모두 씻어 내어 한 번의 조작으로 불순물 대부분을 제거합니다 — 그러나 컬럼은 로드당 일정량만 담을 수 있으므로, 이 단계는 여러 사이클(many cycles)로 운전되어 각각이 일부를 용출하고, 모두가 하나의 풀로 합쳐집니다. 처음으로 하나의 물질이 여러 부모로부터 동시에 derivedFrom되며, 계보는 뒤로 갈라집니다(forks backward) [4]. 구현은 그 분기를 뭉개기를 거부합니다: 세 개의 사이클 용출액은 실제 개별자이고, PApool-001은 derivedFrom의 유형화된 하위 속성인 bp:includedFraction을 통해 자신이 무엇을 풀링했는지 정확히 기록합니다:
# instances.ttl — the capture pool, with its cycle-level provenance preserved.
bp:ELU-001a a bp:CycleEluate ; rdfs:label "capture cycle 1 eluate" ; bp:derivedFrom bp:CLAR-001 .
bp:ELU-001b a bp:CycleEluate ; rdfs:label "capture cycle 2 eluate" ; bp:derivedFrom bp:CLAR-001 .
bp:ELU-001c a bp:CycleEluate ; rdfs:label "capture cycle 3 eluate (excluded by pooling)" ; bp:derivedFrom bp:CLAR-001 .
bp:PApool-001 a bp:CapturePool ; rdfs:label "PApool-001 (Protein A capture pool)" ;
bp:derivedFrom bp:CLAR-001 ;
bp:fromBatch bp:BATCH-2026-001 ;
bp:includedFraction bp:ELU-001a , bp:ELU-001b ;
bp:participatesIn bp:CAP-001 ;
bp:hasInProcessResult bp:IPR-PApool-hcp .
핵심 간선 PApool-001 derivedFrom CLAR-001은 직접 단언되어 거친 사슬이 CQ-01에 도달 가능하게 유지되는 한편, 그 아래의 사이클 세부는 조사가 실제로 던지는 "어느 로드가 기여했는가?"라는 법의학적 질문에 답합니다. 사이클 3(bp:ELU-001c)은 실시간 풀링 결정에 의해 제외(excluded)되었으나 bp:POOL-DEC-001을 통해 라우팅된 개별자로 보존되어, 풀의 구성이 단지 기록되는 것이 아니라 설명됩니다. 포획은 또한 앞선 단계들이 부담시키지 않은 소모품 하나를 도입합니다 — 여러 배치에 걸쳐 재사용(reused)되는 수지입니다:
# instances.ttl — the resin as a persisting consumable with a usage history — carryover is answerable.
bp:CAP-001 a bp:CaptureChromatography ; rdfs:label "Protein A capture step" ;
bp:hasInput bp:CLAR-001 ; bp:hasOutput bp:PApool-001 ;
bp:performedOn bp:RESIN-PrA-07 .
bp:RESIN-PrA-07 a bp:ResinLot ; rdfs:label "Protein A resin lot PrA-07" ;
bp:hasDisposition bp:PrA-bind ;
bp:cycleCount 38 ; bp:cycleLifetimeLimit 200 .
bp:PrA-bind a bp:BindingDisposition ; rdfs:label "Protein A antibody-binding disposition" ;
bp:isRealizedIn bp:CAP-001 .
Protein A 수지는 비싸고, 폐기 전에 여러 배치에 걸쳐 많은 사이클 동안 쓰이므로, 추적되는 물질 존재입니다 — bp:RESIN-PrA-07이 bp:cycleLifetimeLimit(200)에 대한 자신의 bp:cycleCount(38)를 짊어지고, 항체를 결합하는 성향(disposition)을 지닙니다. 로트가 여러 배치에 걸쳐 지속되기 때문에, 산물 사슬만으로는 놓치는 계보를 만들어 냅니다: 수지에서 일어난 분해나 캐리오버는 산물 계보를 전혀 공유하지 않는 배치들을 연결할 수 있으며, 바로 그것이 "어떤 배치들이 이 수지를 공유했는가?"를 고고학 프로젝트가 아니라 질의로 만듭니다. 이 노드에 관해 명명할 가치가 있는 두 가지 정직함이 있습니다. 첫째, 정렬 정직함(alignment honesty): bp:ChromatographyColumn과 bp:ChromatographyResin은 검증된 IOF 용어(iof:ChromatographyColumn, iof:ChromatographyMedium)로 정렬되지만, bp:CaptureColumn과 bp:ResinLot은 align.ttl에서 ILLUSTRATIVE 로컬 자리표시자로 표시되어 있는데, Protein A 포획 컬럼이나 단일 수지 로트에 대해 정착된 일대일 외부 리프(leaf)가 아직 존재하지 않기 때문입니다 — 규율은 진정으로 정착되는 것을 닻으로 잡고 나머지는 표시하는 것이지, 빌림을 위조하는 것이 아닙니다. 둘째, 검증된 것 대 측정된 것(validated versus measured): 사이클 간 캐리오버를 통제하는 세척은 세척 공정에 관한 검증된 주장이지 배치별 측정이 아니며 — 사이클 200의 수지는 세포주가 가진 것과 같은 살아 있는 존재의 동일성 무름을 지닙니다. 그것은 분해되고, 세척되고, 퇴역하기 때문입니다. 그래프는 캐리오버를 답할 수 있게 만드는 사이클 수를 운반하지만, 완전한 배치 간 사용 이력은 모든 공장이 협상하는 비용-대-충실도 절충입니다.
구현된 포획 풀: 풀링 결정에 의해 사이클 3이 제외된 채 풀링된 사이클 용출액(역방향 분기)에서 파생되는 물질로, 여러 배치에 걸쳐 재사용되는 추적된 수지 로트 위에서 생산됩니다 — 풀링 출처가 단일 간선으로 뭉개지지 않고 개별자로 보존됩니다.
저자가 AI의 도움을 받아 직접 제작한 그림입니다.
수렴을 구현하라: DS-001과 그 열한 조상
원료의약품은 모든 상류 계보 개별자가 단일 물질로 수렴하는 곳이자, 구속력 있는 출하 규격이 부착되는 곳입니다 [5]. UF/DF는 폴리싱된 산물을 농축하고 제형 완충액으로 교환하여 DS-001을 산출합니다. 전이적 derivedFrom을 통해, bp:DS-001은 폴리싱 중간체, 두 개의 바이러스 풀, 포획 풀, 정제된 수확물, 생물반응기 배치, 시드 트레인을 거쳐 WCB-CHO-001로, 그리고 세포 은행 단계를 따라 RCB-CHO-001까지 거슬러 올라갑니다 — 계보 순회가 반환하는 열한 조상(eleven ancestors)입니다. 이것은 출하 결정이 내려지는 로트이므로, 전체 CQA 패널이 자신이 실제로 기술하는 로트 위, 바로 여기에 자리합니다:
# instances.ttl — the convergence node carrying the full release panel.
bp:DS-001 a bp:DrugSubstance ; rdfs:label "DS-001" ;
bp:derivedFrom bp:POLpool-001 ;
bp:participatesIn bp:UFDF-001 ;
bp:hasSpecification bp:Spec-DS-mAb-A ;
bp:releaseStatus "PASS" ;
bp:monomerPct "98.611"^^xsd:float ;
bp:hmwPct "1.287"^^xsd:float ;
bp:cexMainPct "70.686"^^xsd:float ;
bp:hcpPpm "12.0"^^xsd:float ;
# ... residual DNA, endotoxin (more panel scalars) elided ...
bp:proteinConcMgPerMl "50.2"^^xsd:float ;
# ... QUDT value nodes (monomerValue, cexValue) elided ...
bp:approvedBy bp:SIG-DS-001 ;
bp:hasCertificate bp:CofA-DS-001 .
이 패널의 각 스칼라는 존재할 제조상의 이유가 있는 실제 항체 품질 속성입니다. monomerPct(98.611)는 온전하고 올바르게 접힌 단량체의 비율이고, hmwPct(1.287)는 폴리싱 단계가 제거하는 고분자량 응집체(aggregate)로, 응집체가 환자에게 면역 반응을 유발할 수 있어 통제됩니다. cexMainPct(70.686)는 주요 전하 변이체 피크로, 번역 후 균질성의 대리 지표이고, hcpPpm(12.0)은 잔류 숙주세포단백질입니다. monomerPct를 거친 로더가 한때 두었던 생물반응기 배치가 아니라 여기에 두는 것은 원료의약품 장이 공개적으로 한 의도적인 귀속 정정입니다: 생물반응기 배양액은 최종 단량체 순도에 대해 결코 분석된 적이 없으므로, 단량체 순도는 DS-001의 시료에서 측정된 로트의 출하 속성입니다. 그 교훈은 일반적이며 간직할 가치가 있습니다: 결과가 어디에 부착되는가는 결과를 낳는 모델링 결정이며, 그래프는 완벽히 순회 가능하면서도 자신이 인증해야 할 사실을 미묘하게 잘못 위치시킬 수 있습니다. 이 한 노드로부터 계보는 앞으로 갈라집니다: DP-001과 DP-002는 둘 다 derivedFrom DS-001(충전 분기, 포획의 역방향 풀링 분기의 거울상)이고, 규격 외 형제 계보 WCB-CHO-001 → SEED-004 → BATCH-2026-004 → PApool-004 → DS-004 → DP-004도 같은 뿌리를 공유합니다 — 바로 그래서 리콜 영향 질의가 하나의 은행에서 두 운명 모두에 도달할 수 있습니다.
운반 가능한 공정 지식으로서의 레시피
구현된 모든 개별자가 물질인 것은 아닙니다. 캠페인 전체를 공장 현장으로 옮긴 패키지 — 마스터 레시피(master recipe) — 는 전달 가능한 형태의 지식이며, 일반 의존 연속자(generically dependent continuant)로 모델링됩니다: 소비되지 않고 한 사이트에서 다른 사이트로 복사될 수 있는 계획입니다. 그 구조는 배치 제어 표준인 ISA-88(IEC 61512)에서 오며, ISA-88은 레시피를 절차·조작·페이즈의 위계로 모델링하고 레시피를 그것을 실행하는 장비와 분리합니다:
# instances.ttl — the recipe as ISA-88 information, realized by a run, transferred between sites.
bp:Recipe-mAb-A a bp:MasterBatchRecord ; rdfs:label "master recipe, mAb-A" ;
bp:hasRecipeElement bp:RP-production .
bp:RP-production a bp:RecipePhase ; rdfs:label "production-phase recipe element" ;
bp:prescribesParameter bp:FeedRate , bp:Temperature ;
bp:requiresEquipment bp:REQ-2000L .
bp:REQ-2000L a bp:EquipmentRequirement ; rdfs:label "2000 L single-use production bioreactor requirement" .
bp:BR-204 a bp:ProductionBioreactor ; rdfs:label "BR-204 (receiving-site vessel)" ;
bp:locatedAt bp:SITE-B ; bp:qualifiesFor bp:REQ-2000L .
bp:TT-001 a bp:TechTransfer ; rdfs:label "tech transfer of mAb-A to site B" ;
bp:transferredFrom bp:SITE-A ; bp:transferredTo bp:SITE-B ; bp:isAbout bp:Recipe-mAb-A .
레시피를 운반 가능하게(portable) 만드는 수는, 각 단계가 필요로 하는(needs) 것을 어느 사이트가 가진(has) 것과 별도로 모델링하는 것입니다. RP-production은 "용기 BR-101"을 요구하지 않습니다. 그것은 bp:REQ-2000L — 주어진 클래스와 규모의 생산 생물반응기 — 을 요구하며, 이는 실제 용기가 역할(role)을 함으로써 충족하는 장비 요구사항(equipment requirement)입니다. 세포 배양 운전 bp:CCP-001 bp:realizes bp:Recipe-mAb-A는 기원 사이트에서 일어나고, 사이트 B의 bp:BR-204는 bp:qualifiesFor bp:REQ-2000L을 선언하므로, 같은 레시피가 다시 쓰지 않고도 다른 용기에서 운전되며 그래프는 후보 용기가 자격을 갖추는지를 기계적으로 점검할 수 있습니다. 이 정보 산물 대 occurrent 분리야말로 하나의 레시피가 여러 운전으로 실현되고 사이트 간에 전달되게 합니다. 기원 MES가 실제로 교환하는 B2MML XML은 동반 리포의 로더에 의해 요소 하나하나가 바로 이 트리플로 걸어 들어갑니다 — 같은 레시피가 한쪽에서는 와이어 포맷으로, 다른 쪽에서는 IOF 정렬 RDF로 직렬화됩니다. 모델이 보장할 수 없는 것은 공정(process)입니다: 2,000 L의 배양은 2 L의 배양과 다르게 혼합되고, 산소가 공급되고, 전단되며, 새 사이트의 물과 원료 로트는 미묘하게 다르게 거동하므로, 모델링된 모든 파라미터를 동일하게 유지해도 CQA는 이동할 수 있습니다. 그래프는 이전을 표시하고 그것을 탐색하는 엔지니어링 및 확인 운전을 연결합니다. 그것은 이동을 예측할 수 없습니다. 운반 가능한 모델이 운반 가능한 공정은 아닙니다.
평가: 로드된 그래프는 자신의 질문에 답하는가?
모델은 그것을 로드하고, 그 위에서 추론하고, 역량 질문을 돌려 봄으로써 검증됩니다 [6]. validate.py는 bioproc.ttl + align.ttl + instances.ttl을 — 작성된 대로 2120개 트리플 — 파싱하고, OWL-RL 폐쇄(closure)를 적용하면 그래프는 추론된 간선을 포함해 7137개 트리플로 닫힙니다(closes). bp:derivedFrom이 전이적이기 때문에, 장거리 계보는 손으로 단언되지 않고 함의(entail)됩니다: bp:DS-001로부터의 역방향 순회는 열한 조상(eleven ancestors)을 반환하고(CQ-01에 답하고, 기원 배치의 98.611을 읽어 CQ-03에 답함), 역방향 순회는 CQ-02에 답합니다:
# queries/CQ-02.rq — Cell-bank impact: every material that descends from the working cell bank.
PREFIX bp: <https://example.org/bioproc#>
SELECT ?descendant WHERE {
?descendant (bp:derivedFrom)+ bp:WCB-CHO-001 .
} ORDER BY ?descendant
추론된 그래프에서 돌리면 그것은 캠페인 전체(entire campaign)를 반환합니다 — 황금 계보 DP-001/DP-002와 규격 외 형제 DP-004 둘 다, 이 하나의 은행으로 추적되는 모든 노드를, 정확히 오염 우려가 필요로 하는 세포 은행 수준의 도달 범위로. 영향 질의 CQ-04가 그것을 날카롭게 합니다: DP-004가 실패하면, 그 계보를 따라 공유된 WCB-CHO-001까지 올라갔다가 다시 내려오는 순회는 ['DP-001', 'DP-002']를 반환합니다 — 리콜이 범위를 정해야 할 운명 공유 집합이, 공장 전체를 격리하는 대신 질의로 계산됩니다:
# queries/CQ-04.rq — Impact analysis: when DP-004 fails, which drug products share its lineage?
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
그다음 폐쇄세계(closed-world) SHACL 게이트는 WCB-CHO-001이 자신의 네 가지 특성 규명과 계대 수를 짊어졌음을 확인하고(CQ-17), 출하 게이트는 DS-004/DP-004에서 오직 hmwPct만 표시합니다(한도 2.0 %에 대한 2.41) — 단량체가 98.687로 규격 내이므로 여기서 실제 실패 모드인 응집체입니다 — 그리하여 다른 모든 로트의 다른 모든 패널 값이 통과하는 가운데 단 하나의 진짜 위반을 고립시킵니다.
미해결 부분: 로드 가능한 그래프는 스냅숏이지 살아 있는 기록이 아니다
인스턴스 그래프는 정직하고, 순회 가능하고, 추론되었으며 — 그리고 얼어 있습니다. 그것은 한 순간의 한 캠페인을 포착합니다: 계대 8, 단량체 98.611, 열한 조상. 그러나 이 장이 드러낸 더 깊은 두 진실이 그 얼어붙음 아래에 자리합니다. 첫째는 그래프가 이름 붙이는 것들이 살아 있고 연속적(alive and continuous)이라는 것입니다. 세포 은행은 세대를 거치며 돌연변이하고 표류하는 세포의 집단이므로, "워킹 은행"은 마스터와 유전적으로 동일하지 않으며, 어떤 owl:sameAs도 계대 60의 배양이 계대 5의 것과 같은 존재인지를 답하지 못합니다 — 여기서 동일성은 IRI가 암시하는 또렷한 동일함이 아니라 특성 규명으로 한정된 유용한 허구입니다. 더 나쁘고 역사적으로 실재하는 것은 오인식(misidentification)입니다: 세포주는 수십 년 동안 생명과학 전반에서 혼동되고 교차오염되어 왔으며, 제조 뿌리 노드에서 이는 가능한 한 최악의 오류입니다. 완전한 확신을 가지고 단언되고, 모든 derivedFrom 간선을 통해 전파되며, 그 어떤 하류 데이터 무결성도 그것을 잡아내지 못하기 때문입니다 — 모든 하류 사실이 잘못 식별된 뿌리에서 올바르게 유래됩니다. 둘째 진실은 그래프가 헌신하는 개별화 관습이 형이상학적 사실이 아니라는 것입니다: 단위 조작 경계에서 bp:CLAR-001을 발행하는 것, PApool-001을 이산적 사이클에서 나온 하나의 풀로 다루는 것, 출하를 이산적 bp:DS-001 로트에 닻 내리는 것은 모두 배치(batch) 세계를 가정합니다. 공정이 연속이 되어 감에 따라, 그 이산적 개별자들은 자연스러운 경계를 잃고, "출하 로트"는 자연적 객체가 아니라 연속체 위에 부과된 시간 한정 관습 — 온톨로지가 기록할 수는 있어도 도출할 수는 없는 것 — 이 됩니다. 그러므로 로드 가능한 그래프는 모델이 실제 데이터에 대해 자신의 질문에 답할 수 있음을 증명합니다. 그것은 데이터가 뿌리에서 주장하는 그것임을 증명하지도, 배치 없는 공정에서 이산적 노드가 살아남음을 증명하지도 않으며, 둘 다 구현이 아니라 거버넌스와 유지보수의 문제입니다.
왜 중요한가
개별자는 온톨로지가 다이어그램이기를 멈추고 제조 기록이 되기 시작하는 곳입니다. 추론기 아래에서 7137개로 닫히는 instances.ttl의 2120개 트리플은, 모델이 로트를 그 세포 은행으로 추적할 수 있다고 주장하는 것과 DS-001의 열한 조상을 반환하고 DP-004가 실패할 때 리콜을 DP-001과 DP-002로 범위 짓는 것을 보여 주는 것의 차이입니다 — 스프레드시트 고고학 2주가 아니라 두 번의 질의로. 출하 게이트와 디지털 스레드가 의존하는 모든 역량 질문은 여기서 단언된 간선을 순회함으로써 답해집니다. 인스턴스 그래프를 충실히 구축하라 — occurrent로서의 형질주입, 뿌리로서의 세포 은행 단계, 하나의 전이적 등뼈 위의 계보, 추적된 수지 위에 보존된 풀링 분기, 자신이 기술하는 로트에 부착된 출하 속성 — 그러면 의약품을 게이트하는 질문들이 질의로 풀립니다. 그것을 건너뛰거나 순도 결과를 잘못된 노드에 걸면, 그래프의 출하 결정적 부분은 어떤 추론기도 결코 돌린 적 없는, 시험되지 않은 가설입니다.
실제 현장에서는
모든 상업적 포유류 세포 프로그램은 이미 RCB/MCB/WCB 계보, 시드 트레인 계대 이력, 단계별 풀링 물질과 추적된 수지 로트, 그리고 인증서를 가진 출하된 원료의약품 로트를 유지합니다 — 세포 은행 위계와 그 특성 규명은 선택적인 모범 관행이 아니라 규제 기대입니다 [1][3][4]. 고르지 못한 것은, 그 기록이 MES, LIMS, ELN, 크로마토그래피 로그북에 흩어져 살기에 "우리는 추적성을 갖췄다"가 서류 정리에 관한 주장이라는 점입니다. 여기서 모델링한 구현 — 세포 은행, 풀, 수지, 원료의약품이 유형화된 derivedFrom 간선으로 이어진 노드인 단일 로드 가능 파일 — 이야말로 그 주장을 질의가 검증할 수 있는 속성으로 바꾸고, 리콜을 캠페인 전역 격리에서 두 형제 로트의 범위 지어진 집합으로 바꾸는 바로 그 산물입니다.
핵심 용어
- 인스턴스 그래프(Instance graph) — 어휘의 클래스를 채우는, 하나의 mAb 캠페인의 단언된 개별자들(
bp:WCB-CHO-001,bp:CLAR-001,bp:DS-001…). 로드 가능한 실행 예제instances.ttl. - 물질 개별화(Material individuation) — 단위 조작마다 하나의 새 물질 노드를 발행하는 관습. 정제 같은 경계에 고정되고, 풀링·분할·연속 흐름에 의해 부담을 받으며, 생물학이 건네주는 사실이 아닙니다.
- 물질수지(강제되지 않음)(Mass balance, not enforced) —
derivedFrom은 계보를 기록하지 보존을 기록하지 않습니다. 양이 모델링되지 않는 한, 순회 가능한 계보가 양적으로 불가능할 수 있습니다. - 역방향 풀링 분기 / 캐리오버 계보(Backward pooling fork / carryover lineage) —
PApool-001이bp:includedFraction을 통해 여러 사이클 용출액으로부터derivedFrom되며, 여러 배치에 걸쳐 재사용되는 수지(RESIN-PrA-07) 위에서 어떤 산물 계보도 잇지 않는 로트들을 연결합니다. - 수렴 노드(Convergence node) —
bp:DS-001, 전체 상류 계보가 열한 전이적 조상과 구속력 있는 출하 규격을 가진 하나의 물질로 만나는 곳.monomerPct출하 결과의 정정된 거처. - 전이적 함의(Transitive entailment) — OWL-RL 폐쇄가 추론하는 장거리
derivedFrom간선(2120 → 7137 트리플)이므로, 임의의 깊이까지의 계보가 손으로 단언될 필요가 없습니다. - 운반 가능한 정보 산물(Portable information artifact) — 마스터 레시피. ISA-88 구조의 일반 의존 연속자로, 운전에 의해 실현되고, 용기가 아니라 장비 요구사항에 결합함으로써 사이트 간에 전달됩니다.
다음 이야기
이제 어휘는 채워진 캠페인 그래프가 되었지만, 그 스칼라 중 몇몇 — 수확물의 맨 3.2 NTU, 운전의 맨 설정점 — 은 단위도 출처도 지니지 않아 정직하지만 빈약합니다. 다음 장, 와이어에서 그래프로는 그 수치들이 실제로 어떻게 도착하는지를 보여 줍니다: OPC UA 송신기에서 나와, 히스토리안을 거쳐, 단위가 부여된 qudt:QuantityValue와 Allotrope가 뒷받침하는 결과로 — 깨끗한 인스턴스 그래프와 그것을 먹이는 지저분한 공장 신호 사이의 간극을 메웁니다.