제6장
제2–5장의 측정값이 어떤 순서와 관문을 거쳐 하나의 흐름으로 이어지는지, validateDrugCandidate()와 assessBiosimilarity()가 실제로 무엇을 판정하는지, 그리고 같은 논리가 공정 변경과 바이오시밀러 비교에 어떻게 적용되는지를 살펴본다.
통신 표준에서 "프로토콜"은 각 단계가 앞 단계의 응답에 따라 진행되도록 합의된 메시지 순서를 뜻한다. WIA-BIO-016에는 회선을 오가는 메시지가 없지만, 그런 성격의 순서는 분명히 있다. 명세서 §3부터 §9까지는 바이오의약품이 근거를 쌓아 가는 순서대로 배열되어 있다. 분자의 특성을 분석하고, 결합을 측정하고, 노출과 효과를 모델링하고, 면역원성과 안정성을 평가한 뒤, 무언가(자사의 이전 공정 또는 대조약)와 비교하고, 마지막으로 전체 기록을 허가 신청 자료로 묶는다. 제3장은 데이터 형식(TypeScript 타입)을, 제4장과 제5장은 계산 API를 설명했다. 이 장은 그 순서 자체를 프로토콜로 다룬다. 각 단계가 어떤 기록을 만들고, 어느 뒤 단계가 그것을 쓰며, 어디에서 중단·반복·진행을 결정하는지가 핵심이다.
참조 구현은 이 순서를 강제하지 않는다. SDK 함수는 모두 따로 호출할 수 있으며, 안정성을 한 번도 측정하지 않은 제품에 바이오시밀러 평가를 돌리는 것을 막는 장치도 없다. 따라서 이 순서는 코드가 부과하는 규칙이 아니라 구현자가 스스로 채택하는 규율이다. 이를 글로 적어 두는 가치는 모든 관문을 명시적이고 검토 가능한 형태로 만든다는 데 있다.
단계 기록 / 타입 SDK 진입점
------------------------ ------------------------------------ -----------------------------
1 특성분석 ProteinCharacterization, PTM, Glycan (데이터 기록만)
QualityAttributes
|
2 결합 BindingAffinity, KineticParameters calculateBindingAffinity()
| calculateKinetics()
3 PK/PD PKParameters, PDParameters calculatePharmacokinetics()
| calculatePharmacodynamics()
4 면역원성 ImmunogenicityParams, ADAData assessImmunogenicity()
|
5 안정성 StabilityConditions, StabilityResult predictShelfLife()
|
[관문 A] DrugCandidate ------------------------------> validateDrugCandidate()
| 오류 -> 중단 또는 발굴 단계로 복귀
| 경고 -> 완화 계획을 세우고 진행
v
6 제조 CellCultureParams, PurificationProcess (데이터 기록만)
|
7 비교 QualityAttributes x 2 assessBiosimilarity()
[관문 B] similar / further-testing-required / not-similar
|
8 허가 자료 RegulatorySubmission (데이터 기록만)
이 그림에서 강조할 점이 두 가지 있다. 첫째, 여덟 단계 가운데 세 단계에는 계산이 전혀 없고 표준은 타입이 정해진 기록만 제공한다. 이는 약점이 아니다. 특성분석, 제조, 허가 업무에서 어려운 부분은 완전하고 일관된 기록을 유지하는 일이며, 공통 스키마가 바로 그 일을 돕는다. 둘째, SDK가 판정처럼 보이는 결과를 돌려주는 지점은 후보 관문(관문 A)과 비교 관문(관문 B) 두 곳뿐이다. 아래에서 둘을 자세히 살펴보며, 둘 다 반환값이 암시하는 것보다 더 많은 해석이 필요하다.
아래 표는 단계 간 인계 내용을 요약한다. 실무에서 가장 쉽게 놓치는 것은 추적성이다. 뒤 단계는 자신이 어떤 앞 단계 기록에 근거했는지를 기록해야 한다. 그래야 예컨대 역가 측정에 쓴 표준품이 바뀌었을 때 그에 의존한 모든 결과를 찾아낼 수 있다.
| 보내는 단계 | 받는 단계 | 넘기는 내용 | 다음 단계에 필요한 이유 |
|---|---|---|---|
| 특성분석 | 결합, 비교 | 확인된 서열, 분자량, 당쇄 프로파일, 시험 로트의 QualityAttributes | 결합 결과는 정의된 분자에 대해서만 의미가 있고, 비교 단계는 같은 속성을 다시 쓴다 |
| 결합 | PK/PD, 관문 A | Kd(M), kon, koff | Kd는 수용체 점유율 계산에 들어가고 DrugCandidate.targetAffinity가 된다 |
| PK/PD | 허가 자료, 임상 설계 | CL, Vd, t½, EC50, 제안 투여 간격 | 최초 인체 투여 용량 선정을 뒷받침하고, 바이오시밀러라면 PK 동등성 시험 설계의 근거가 된다 |
| 면역원성 | 관문 A | IRS와 위험 등급 | DrugCandidate.immunogenicityRisk로 매핑된다 |
| 안정성 | 관문 A, 허가 자료 | 분해 속도, 잔존 역가 또는 단량체, 예측 유효기간 | 0–1 범위의 stability 점수로 요약되고, CTD 3.2.P.8에는 전체 자료로 기술된다 |
| 제조 | 비교 | 공정 기술, 단계별 수율, 로트 출하 자료 | 공정을 바꿀 때마다 동등성 평가가 필요하다 |
| 비교 | 허가 자료 | BiosimilarAssessment와 그 근거가 된 로트 자료 | 분석적 유사성은 351(k) 신청이나 동등성 평가 보고서의 토대다 |
파이프라인은 왼쪽에서 오른쪽으로 한 번 흐른다. 개발 프로토콜은 되돌아간다. 관문 A에서 Kd가 약하면 프로그램은 친화도 성숙 단계로 돌아가 새 분자를 만들고 특성분석을 다시 시작한다. 비교 결과가 further-testing-required이면 다음 단계로 가는 대신 같은 로트에 대해 분석을 더 한다. 소프트웨어 관점에서 이는 기록을 덮어쓰지 말고 버전을 매겨 서로 연결해야 한다는 뜻이다. SDK 함수는 아무것도 기억하지 않는 순수 계산이므로 이력은 함수를 호출하는 시스템이 보관해야 한다. 제7장은 데이터 무결성을 다루면서 이 문제로 돌아온다.
간단한 방법은 관문 호출마다 입력, 출력, 그리고 결과를 낸 코드 버전을 담은 근거 기록으로 감싸는 것이다. 다음 구조는 제안일 뿐 WIA-BIO-016 v1.0의 일부가 아니다.
{
"gate": "A-candidate",
"calledFunction": "validateDrugCandidate",
"sdkVersion": "1.0.0",
"inputRef": "candidate/XB-017/iteration-3",
"input": { "targetAffinity": 2.5e-8, "stability": 0.88, "immunogenicityRisk": "moderate" },
"outputDigest": "sha256:<반환 JSON의 다이제스트>",
"decision": "proceed-with-mitigation",
"decidedBy": "<검토자 ID>",
"rationale": "경고 2건 수용, 친화도 성숙을 병행 진행"
}
기록된 decision은 함수 출력을 참고한 사람의 결정이지 출력을 옮겨 적은 것이 아니라는 점에 유의해야 한다. 이 구분이 왜 중요한지는 이 장의 나머지 부분이 보여 준다.
validateDrugCandidate()를 이용한 후보 관문
관문 A는 앞 다섯 단계를 의도적으로 압축한 DrugCandidate 기록을 받아 DrugValidationResult를 돌려준다. 입력 필드는 아홉 개다. drugType, target, targetAffinity(몰 단위 Kd), molecularWeight, stability(0과 1 사이 점수), immunogenicityRisk('low' | 'moderate' | 'high'), expressionSystem, manufacturingComplexity, developmentStage.
구현(index.ts)을 읽으면 규칙 전체를 알 수 있다. 결과에 영향을 주는 것은 이것뿐이다.
| 조건 | 결과에 미치는 영향 |
|---|---|
targetAffinity > 1×10−8 M(10 nM, MIN_THERAPEUTIC_KD) | 경고와 위험 항목 추가 |
targetAffinity > 1×10−7 M(100 nM) | 오류: "Affinity too weak for therapeutic application" |
stability < 0.9 | 경고와 제형 개선 권고 추가 |
stability < 0.7 | 오류와 위험 항목 추가 |
immunogenicityRisk = 'high' | 경고, 위험 항목, 인간화·탈면역화 권고 |
drugType = 'monoclonal-antibody'이고 분자량이 145,000–155,000 Da 밖 | 경고 |
manufacturingComplexity = 'high' | 경고와 위험 항목 추가 |
단일클론항체를 'e-coli' 또는 'yeast'에서 발현 | 경고, CHO 또는 HEK293 사용 권고 |
실현 가능성은 개수를 세어 정한다. 오류가 하나라도 있으면 'low', 그렇지 않고 경고가 셋 이상이거나 위험 항목이 셋 이상이면 'medium', 나머지는 모두 'high'다. isValid는 단순히 "오류 없음"을 뜻한다.
대부분의 규칙에 깔린 생물학적 근거는 타당하며 제1, 4, 5장에서 다루었다. 그러나 임계값 자체는 WIA가 고른 값이다. 혈중에 매우 많은 가용성 표적을 겨냥하는 후보라면 10 nM보다 훨씬 강한 결합이 필요할 수 있고, 일부 수용체 작용제는 일부러 결합을 약하게 설계하기도 한다. 이 관문은 과학적 경계가 아니라 "논의가 필요한 항목 표시"로 읽어야 한다.
이름에 함정이 하나 있다. MIN_THERAPEUTIC_KD는 사실상 최댓값이다. Kd가 작을수록 결합이 강하므로 이 상수는 경고 없이 허용되는 가장 약한 결합을 표시한다. 코드를 확장할 때는 MAX_KD_WARN 같은 이름을 쓰는 편이 안전하다.
이름을 밝히지 않은 표적에 대한 가상의 전임상 IgG1 후보를 생각해 보자. CHO에서 발현하며, 측정 Kd는 25 nM, 안정성 점수는 0.88이다. 수치는 예시다.
import { validateDrugCandidate } from './index';
const result = validateDrugCandidate({
drugType: 'monoclonal-antibody',
target: 'target-X',
targetAffinity: 2.5e-8, // M
molecularWeight: 148000, // Da
stability: 0.88, // 0-1 점수, 정의는 별도 문서화
immunogenicityRisk: 'moderate',
expressionSystem: 'cho',
manufacturingComplexity: 'medium',
developmentStage: 'preclinical',
});
참조 구현을 실행하면 다음을 돌려준다(권고는 줄임).
{
"isValid": true,
"errors": [],
"warnings": [
"Target affinity (2.5e-8 M) is weaker than typical therapeutic threshold (1e-8 M)",
"Stability is below optimal threshold (90%)"
],
"feasibility": "high",
"estimatedTimeline": 8,
"estimatedCost": 1500,
"risks": [ "Suboptimal target affinity may reduce efficacy" ],
"recommendations": [ "Optimize formulation for improved stability",
"Strong candidate for advancement", "..." ],
"successProbability": 0.72
}
이 결과에는 눈여겨볼 내부 모순이 있다. 경고 두 건과 효능 관련 위험 항목이 있는데도 실현 가능성은 'high'이고 권고에는 "Strong candidate for advancement"가 붙는다. 실현 가능성 규칙이 세 번째 경고부터 반응하기 때문이다. 경고를 읽은 검토자는 요약 필드만 읽은 검토자보다 신중한 결론에 이를 것이다. 따라서 SDK 위에 만든 시스템은 경고와 위험 항목을 실현 가능성 표시보다 먼저, 더 눈에 띄게 보여 주어야 한다.
결과의 세 필드는 예측처럼 보이지만 고정된 조회값이다. estimatedTimeline은 developmentStage를 키로 하는 표(발굴 10년, 전임상 8년, 승인 0년 등)에서 가져오고, 제조 복잡도가 높으면 1년, 면역원성 위험이 높으면 0.5년을 더한다. estimatedCost는 약물 종류별 상수(항체 1,500, 백신 800, 그 밖 1,000, 단위는 모두 백만 달러)에 복잡도와 실현 가능성에 따른 배수를 곱한 값이다. successProbability는 0.9에서 시작해 경고당 0.05, 오류당 0.2, 위험 항목당 0.08을 빼고, 면역원성 위험이 높으면 0.15를 더 뺀 뒤 0.1과 0.95 사이로 자른다.
이 값들은 어느 것도 후보에 관한 자료에서 나오지 않았고 업계 경험으로 보정되지도 않았다. 포트폴리오 검토, 투자 자료, 허가 신청서에 추정치로 등장해서는 안 된다. 화면에 꼭 표시해야 한다면 "SDK 자리표시용 휴리스틱"이라고 분명히 밝혀야 한다. 더 나은 방법은 이 값들을 빼고 조직이 자체 모델을 쓰게 하는 것이다.
BIO007(INVALID_PARAMETERS)을 던지지 않는다. targetAffinity: NaN, stability: NaN으로 실행하면 NaN과의 비교가 모두 거짓이 되므로 isValid: true, 실현 가능성 'high', 성공 확률 0.9가 나온다. 안정성을 백분율로 입력해도(0.92 대신 92) 조용히 통과한다. 호출하는 쪽이 유한성, 부호, 범위를 먼저 확인해야 한다.assessImmunogenicity()는 'very-high'를 돌려줄 수 있지만 DrugCandidate에는 그 값이 없고, 그대로 넘기면 어떤 규칙도 작동하지 않는다. 명시적으로 'high'에 매핑하고 매핑했다는 사실을 기록해야 한다.'monoclonal-antibody'에만 적용된다. ADC, Fab, Fc 융합단백질은 크기 검사를 받지 않으며, 제8장에서 다루는 ADC 고유 속성(DAR, 링커, 페이로드)에는 필드가 없다.ClinicalPhase와 다르다. developmentStage에는 'discovery'와 'approved'가 있고 'phase4'가 없는 반면, ClinicalPhase에는 'phase4'가 있고 'discovery'가 없다. 둘을 함께 저장하는 시스템은 매핑 규칙을 문서화해야 한다.wia-bio-016 validate는 이 규칙 일부를 셸로 다시 구현하고 숫자 비교에 bc를 쓰는데, bc는 1e-9 같은 지수 표기를 해석하지 못한다. 스크립트 자체의 상수(10e-9, 100e-9)도 그렇게 적혀 있어서 친화도 검사는 입력과 상관없이 구문 오류를 내고 "Within therapeutic range"로 넘어간다. 참조 스크립트로 시험해 보면 --affinity 2e-7(200 nM)도 허용 범위로 보고된다. 재현과 수정 방법은 제7장에서 보인다. 그때까지 친화도 판정을 CLI에 맡겨서는 안 된다."공정이 곧 제품이다"(제1장)라는 말이 여기서 구체적인 모습을 띤다. 후보가 관문 A를 통과하면 다음으로 쌓이는 기록은 그 제품을 어떻게 만드는지에 관한 것이다. WIA-BIO-016 v1.0은 이를 위해 상류 세포 배양과 하류 정제에 하나씩, 두 개의 요약 타입을 제공한다. 둘 다 뒤에 계산이 없으며, 가치는 공정 데이터를 사이트와 프로그램이 달라도 같은 형태로 담는 데 있다.
CellCultureParams| 필드 | 문서상 의미 | 설명 |
|---|---|---|
cellLine | 세포주 | 자유 텍스트다. "CHO"만 적지 말고 세포은행 식별자를 참조해야 한다 |
expressionSystem | 숙주 | DrugCandidate와 같은 열거형을 쓴다 |
productivity | "Volumetric productivity (mg/L)" | mg/L 값은 역가(titer)다. 부피 생산성은 보통 속도(부피·일당 질량)로 표시한다. 어느 쪽인지 기록해야 한다 |
cultureDuration | 일 | 예를 들어 CHO 유가식 배양은 흔히 2주 안팎이고, 관류 배양은 훨씬 길다 |
viability | % | 대개 수확 기준이며, 값 하나로는 시간 경과가 드러나지 않는다 |
cellDensity | cells/mL | 최고 생세포 밀도를 가장 흔히 쓴다. 전체 세포인지 생세포인지 밝혀야 한다 |
생존율은 수율 이상의 의미가 있다. 세포가 죽으면서 숙주세포 단백질, DNA, 단백질 분해효소가 수확액으로 나오고, 이는 하류 정제의 부담을 키우며 절단이나 변형을 통해 품질까지 바꿀 수 있다. 정의된 타입은 한 시점의 스냅숏만 담는다. 일별 생세포 밀도, 대사체, 포도당과 젖산 같은 추이 자료가 필요한 팀은 제8장에서 제안하는 방식으로 타입을 확장해야 한다.
PurificationProcess전형적인 단일클론항체 정제 공정은 잘 알려진 몇 가지 단위 공정으로 이루어지며, 각각은 무엇을 제거하느냐에 따라 선택된다.
PurificationProcess는 단계의 순서 목록을 담는다. 각 단계에는 name, type('affinity' | 'ion-exchange' | 'hydrophobic' | 'size-exclusion' | 'ultrafiltration'), yield, purity(둘 다 0–1)가 있고, 공정 전체 필드로 overallYield, finalPurity, processDuration(시간)이 있다. 두 가지를 주의해야 한다. 첫째, 타입 열거형에는 바이러스 불활화 단계나 바이러스 여과를 나타내는 값이 없다. 바이러스 안전성 평가가 가장 크게 의존하는 두 단계다. 나노필터를 'size-exclusion'으로 적으면 오해를 부른다. 크기배제 크로마토그래피와 바이러스 여과는 다른 공정이기 때문이다. 둘째, overallYield는 계산값이 아니라 저장값이다. 여러 단계를 거친 전체 수율은 단계 수율의 곱이다.
overallYield = yield_1 × yield_2 × ... × yield_n
예시로 단계 수율이 0.90(Protein A), 0.88(양이온교환), 0.95(음이온교환 통과), 0.95(UF/DF)인 네 단계 공정이라면 전체 수율은 0.90 × 0.88 × 0.95 × 0.95 ≈ 0.715다. 그런데 SDK에는 같은 단계에 대해 0.85라고 적은 기록을 막는 장치가 없다. 일관성 검사는 몇 줄이면 된다.
import type { PurificationProcess } from './types';
// 예시 보조 함수 - WIA-BIO-016 v1.0의 일부가 아니다.
export function checkPurification(p: PurificationProcess, tol = 0.005): string[] {
const issues: string[] = [];
for (const s of p.steps) {
if (!(s.yield > 0 && s.yield <= 1)) issues.push(`${s.name}: yield must be in (0, 1]`);
if (!(s.purity >= 0 && s.purity <= 1)) issues.push(`${s.name}: purity must be in [0, 1]`);
}
const product = p.steps.reduce((acc, s) => acc * s.yield, 1);
if (Math.abs(product - p.overallYield) > tol) {
issues.push(`overallYield ${p.overallYield} differs from product of step yields ${product.toFixed(3)}`);
}
const last = p.steps[p.steps.length - 1];
if (last && Math.abs(last.purity - p.finalPurity) > tol) {
issues.push('finalPurity differs from the purity after the last step');
}
return issues;
}
관련된 단위 함정도 있다. 정제 공정의 순도는 분율(0–1)로 저장되지만 QualityAttributes.purity는 백분율이다. 출하 로트의 순도를 비교 단계로 옮길 때는 100을 곱해야 한다. 두 관례를 섞어도 오류는 나지 않는다. 터무니없는 유사도 값이 나올 뿐이다.
포유류 세포주는 외래성 인자를 지닐 수 있고, CHO 세포는 내인성 레트로바이러스 유사 입자를 만든다고 알려져 있다. 그래서 ICH Q5A(현행 개정판 R2)는 바이오의약품의 바이러스 안전성을 서로 보완하는 세 요소 위에 세우도록 요구한다. 세포은행과 원자재 시험, 미정제 벌크 시험, 그리고 정제 공정이 바이러스를 제거하거나 불활화한다는 입증이다. 마지막 요소는 모델 바이러스를 첨가한 축소 공정 모델에서 측정하며 로그 감소값으로 표시한다.
LRV = log10( 부하액 중 총 바이러스량 / 산출액 중 총 바이러스량 )
전체 제거 능력은 LRV를 더해 산정하되, 저pH 불활화, 크기에 의한 제거, 전하에 의한 제거처럼 작용 기전이 서로 다른 단계만 더한다. 기전이 같은 두 단계를 더하면 공정의 실제 능력을 부풀리게 된다. 모델 바이러스와 요구되는 전체 감소량은 가이드라인에 제시되어 있으며 규제기관과 협의해 정한다.
v1.0에는 바이러스 제거용 타입이 없으므로 필요한 구현자는 작은 확장을 덧붙일 수 있다. 아래 형태는 제안이며 값은 자리표시다.
{
"viralClearance": [
{ "step": "low-pH hold", "mechanism": "inactivation", "modelVirus": "<외피 모델 바이러스>", "lrv": null },
{ "step": "anion exchange FT", "mechanism": "removal-charge", "modelVirus": "<비외피 모델 바이러스>", "lrv": null },
{ "step": "virus filtration", "mechanism": "removal-size", "modelVirus": "<비외피 모델 바이러스>", "lrv": null }
],
"claimRule": "sum LRVs of steps with distinct mechanisms only"
}
모든 제조 공정은 수명 동안 바뀐다. 임상 단계 사이의 규모 확대, 새 제조소, 새 배양 배지, 정제 단계 수정은 모두 같은 질문을 던진다. 변경 후에 만든 제품이 기존 임상 자료를 만든 그 제품과 같은가? ICH Q5E는 이 질문에 동등성(comparability) 개념으로 답한다. 변경 전후 물질이 똑같을 필요는 없다. 매우 유사해야 하고, 기존 지식으로 차이가 안전성이나 유효성에 나쁜 영향을 주지 않음을 보일 수 있어야 한다. 분석 자료만으로 부족하면 비임상 또는 임상 가교 시험을 더한다.
바이오시밀러는 출발점만 다를 뿐 거의 같은 질문을 던진다. 미국 공중보건서비스법(Public Health Service Act) 351(k)조는 바이오시밀러를 임상적으로 비활성인 구성 성분의 사소한 차이에도 불구하고 대조약과 매우 유사하며, 안전성·순도·역가에서 임상적으로 의미 있는 차이가 없는 제품으로 정의한다. 분석 논리는 동등성 평가와 같다. 임상 성능에 영향을 줄 수 있는 품질 속성을 측정하고, 제품들이 타당한 한계 안에서 일치함을 보인다. 다른 것은 기준이 되는 제품과, 개발자가 그 제품에 대해 아는 정도다.
| 측면 | 동등성 평가(ICH Q5E) | 바이오시밀러 |
|---|---|---|
| 기준 제품 | 개발자 자신의 변경 전 제품 | 다른 회사의 허가 제품 |
| 기준 제품 공정에 대한 지식 | 완전하다. 공정 이력과 모든 로트 자료를 개발자가 가진다 | 없다. 시판 로트를 구입해 분석할 수 있을 뿐이다 |
| 기준 제품 변동성의 출처 | 과거 출하·특성분석 자료 | 오랜 기간에 걸쳐 구입한 여러 로트, 흔히 유효기간이 서로 다르다 |
| 분석 결과가 일치할 때의 전형적 결과 | 변경을 적용하며, 새 임상 자료 없이 가능한 경우도 있다 | 임상 프로그램 범위가 줄지만 보통 완전히 없어지지는 않는다(6.6절) |
| 규제 경로 | 허가 후 변경 신청, 또는 개발 중 변경 보고 | 별도의 품목허가 신청(예: 미국 351(k)) |
WIA-BIO-016에 주는 시사점은 단순하고 유용하다. assessBiosimilarity(reference, biosimilar)는 자신이 두 상황 중 어디에 있는지 모른다. 변경 전 QualityAttributes를 기준으로, 변경 후 자료를 비교 대상으로 넘기면 1차 동등성 점검 도구가 된다. 다음 절에서 설명하는 한계는 두 용도에 똑같이 적용된다.
바이오시밀러 개발자에게는 실무상 복잡한 점이 하나 더 있다. 대조약이 여러 지역에서 허가되어 있을 수 있다는 것이다. 한 시장에서 구입한 제품이 다른 지역에서 허가된 대조약을 자동으로 대신할 수는 없으며, 개발자는 보통 지역별 제품 사이의 분석적 가교 자료를 함께 낸다. 따라서 대조약 로트 자료를 저장하는 기록은 로트마다 구입 시장을 밝혀야 한다. 이 필드는 QualityAttributes에 없으며 이를 감싸는 로트 기록에 두어야 한다.
명세서 §8.1.2는 품질 속성을 중요도에 따라 세 등급으로 나눈다. 1등급은 1차 구조, 고차 구조, 생물학적 활성, 2등급은 전하 변이체, 당질화, 응집체, 3등급은 제품 관련 불순물이다. SDK 함수는 같은 등급 번호를 쓰지만 QualityAttributes에 마침 있는 속성들에 등급을 매기므로 두 목록이 일치하지 않는다.
| 속성 | 명세서 §8.1.2 등급 | assessBiosimilarity()의 등급 | 코드의 허용 오차(상대값) |
|---|---|---|---|
| 1차 구조 | 1 | 비교 안 함(필드 없음) | — |
| 고차 구조 | 1 | 비교 안 함(필드 없음) | — |
| 생물학적 활성(역가) | 1 | 1 | 20 % |
| 순도(SEC) | — | 1 | 5 % |
| 단량체(SEC) | — | 2 | 5 % |
| 응집체 | 2 | 2 | 50 % |
| 주 전하 피크 | 2(전하 변이체) | 2 | 10 % |
| 산성/염기성 변이체 | 2(전하 변이체) | 3 | 각 20 % |
| 당질화 | 2 | 비교 안 함(필드 없음) | — |
| 절편, 엔도톡신, HCP, 잔류 DNA | 3(불순물) | 비교 안 함(필드는 있으나 무시) | — |
여기서 세 가지를 알 수 있다. 명세서가 바이오시밀러에 가장 중요하다고 보는 1차 구조와 고차 구조는 계산에 전혀 들어가지 않으므로 펩타이드 맵핑, 온전한 질량 분석, 분광학적 비교(제2장)로 따로 입증해야 한다. Fc 작동 기능을 크게 바꿀 수 있는 당질화도 빠져 있다. 그리고 타입 문서에 따르면 purity와 monomer는 둘 다 SEC 측정값이어서, 크로마토그래피 결과 하나가 서로 다른 두 등급에 걸쳐 점수에 두 번 들어간다.
함수는 속성마다 유사도(%)와 허용 여부를 계산한다.
similarity = max(0, 100 - |biosimilar - reference| / reference × 100)
acceptable = |biosimilar - reference| / reference <= tolerance
이어서 등급별로 유사도를 평균하고, 등급 평균을 50 %(1등급), 35 %(2등급), 15 %(3등급)의 고정 가중치로 합한다. 1등급과 2등급 속성이 모두 허용되고 가중 유사도가 95 이상이면 'similar', 1등급이 통과하고 가중 유사도가 90 이상이면 'further-testing-required', 그 밖에는 'not-similar'다. 3등급의 허용 여부는 계산되지만 결론에는 쓰이지 않는다. 명세서의 공식(§8.1.1, "Similarity = 1 − |Δ|/Ref, 목표 >95 %")은 같은 계산을 분율로 적은 것이다. 가중치, 허용 오차, 95/90 기준은 WIA 휴리스틱이며 FDA나 EMA가 공표한 기준이 아니다.
다음 대조약과 후보 값은 설명을 위해 만든 것이다. IgG1으로서 그럴듯한 크기이지만 실제 제품을 나타내지 않는다.
import { assessBiosimilarity } from './index';
const reference = { purity: 99.0, monomer: 98.6, aggregates: 1.0, fragments: 0.4,
mainPeak: 65.0, acidicVariants: 22.0, basicVariants: 13.0,
potency: 100, endotoxin: 0.05 };
const candidate = { purity: 98.7, monomer: 98.4, aggregates: 1.3, fragments: 0.3,
mainPeak: 62.0, acidicVariants: 25.0, basicVariants: 13.0,
potency: 96, endotoxin: 0.04 };
const a = assessBiosimilarity(reference, candidate);
// a.overallSimilarity -> 93.84
// a.conclusion -> 'further-testing-required'
| 속성 | 등급 | 대조약 | 후보 | 유사도 | 허용 |
|---|---|---|---|---|---|
| 역가(%) | 1 | 100 | 96 | 96.0 | 예 |
| 순도(%) | 1 | 99.0 | 98.7 | 99.7 | 예 |
| 단량체(%) | 2 | 98.6 | 98.4 | 99.8 | 예 |
| 응집체(%) | 2 | 1.0 | 1.3 | 70.0 | 예 |
| 주 피크(%) | 2 | 65.0 | 62.0 | 95.4 | 예 |
| 산성 변이체(%) | 3 | 22.0 | 25.0 | 86.4 | 예 |
| 염기성 변이체(%) | 3 | 13.0 | 13.0 | 100.0 | 예 |
| 등급 평균(1등급 97.85, 2등급 88.39, 3등급 93.18)의 가중합 | 93.84 | — | |||
모든 속성이 각자의 허용 오차를 통과했는데도 결론은 'further-testing-required'다. 원인은 한 줄에 있다. 응집체의 절대 차이 0.3 %p는 상대 차이로 30 %이고, 이것이 70점을 받아 2등급 평균을 88.39로 끌어내리고, 그 결과 가중 점수가 'similar'에 필요한 95 아래로 떨어진다(응집체만 같았다면 같은 로트의 점수는 97.34다). 이 차이를 표시하는 것 자체는 합리적이다. 그러나 이 예는 가중 점수가 값이 작은 속성에 좌우된다는 것을 보여 준다. 작은 값에서는 적당한 절대 차이도 큰 상대 차이가 된다.
'not-similar'가 된다. 실제 바이오시밀러 프로그램에서도 낮은 불순물 수준은 설명해야 할 차이이지만, 높은 불순물과 같은 의미의 비유사성 근거는 아니다. 함수는 둘을 똑같이 취급한다.'not-similar'다. 둘 다 0이면 유사도가 NaN이 되어 전체 점수까지 번지고, 똑같은 두 입력이 'not-similar'로 판정된다. 정량한계 미만 값은 함수에 넣기 전에 명시적인 관례를 정해야 한다.QualityAttributes 기록 두 개를 비교한다. 실제 분석적 유사성 평가는 분포를 비교한다. 즉 대조약 여러 로트와 후보 여러 로트를 비교한다. 단일 로트 비교로는 실제 차이와 통상적인 로트 간·시험법 변동을 구별할 수 없다.'similar'를 받는다. 역가 차이가 허용되는지는 고정된 20 % 폭이 아니라 대조약과 생물학적 시험법의 변동성에 비추어 판단해야 한다.BIO009(BIOSIMILARITY_FAILURE)도 BIO007도 던지지 않으며, 실패는 conclusion으로만 표현된다. 예외로 흐름을 제어하는 호출자는 예외를 보지 못한다.규제 실무는 하나의 숫자로 된 유사도 점수에서 멀어져 왔다. FDA가 2017년에 낸 분석적 유사성 통계 접근법 가이던스 초안은 가장 중요한 속성에 대해 대조약 로트 변동성에서 유도한 한계로 정식 동등성 검정을 하는 등급 체계를 제안했다. 이 초안은 2018년에 철회되었고, 이후 FDA의 비교 분석 평가 가이던스 초안(2019)은 품질 범위 접근법에 무게를 둔다. 속성의 범위를 대조약 로트로부터, 대개 평균에 표준편차의 몇 배를 더하고 빼는 방식으로 정하고, 신청 제품 로트의 충분한 비율이 그 안에 들 것을 기대하며, 배수와 비율의 선택은 신청자가 정당화한다. EMA의 바이오시밀러 품질 가이드라인과 품질 속성 비교를 위한 통계 방법론 성찰 문서(reflection paper)도 마찬가지로 로트 기반 비교와 허용 범위의 과학적 정당화를 요구한다.
이 접근법들에는 공통 원칙이 둘 있다. 비교는 여러 로트에 근거하고, 허용 한계는 미리 고정하지 않고 대조약 자체의 변동성에서 유도한다. 대조약 로트에서 품질 범위를 계산하는 작은 래퍼를 쓰면 assessBiosimilarity()를 그런 실무에 더 가깝게 만들 수 있다. 아래 예의 배수 k는 신청자가 정당화해야 할 매개변수이며, 특정 값을 뜻하지 않는다.
import type { QualityAttributes } from './types';
type NumericKey = Exclude<keyof QualityAttributes, 'hcp' | 'residualDNA'>;
// 예시 확장 - WIA-BIO-016 v1.0의 일부가 아니다.
export function qualityRange(refLots: QualityAttributes[], key: NumericKey, k: number) {
const xs = refLots.map((lot) => lot[key]);
const mean = xs.reduce((a, b) => a + b, 0) / xs.length;
const sd = Math.sqrt(xs.reduce((a, b) => a + (b - mean) ** 2, 0) / (xs.length - 1));
return { mean, sd, low: mean - k * sd, high: mean + k * sd };
}
export function fractionWithin(
candidateLots: QualityAttributes[], key: NumericKey,
range: { low: number; high: number },
): number {
const inside = candidateLots.filter((lot) => lot[key] >= range.low && lot[key] <= range.high);
return inside.length / candidateLots.length;
}
이런 래퍼의 출력은 점수 하나가 아니라 속성별 범위와 비율의 집합이며, 이는 의도한 것이다. 근거를 검토자가 기대하는 형태로 유지하고, 어떤 속성을 정성적으로만 비교할지(예: 펩타이드 맵 겹쳐 보기)를 포함한 판단을 책임 있는 과학자에게 남긴다.
분석적 유사성은 토대이지 결론이 아니다. 표준의 BiosimilarAssessment 타입은 이를 내다보고 pkSimilarity와 clinicalSimilarity라는 선택적 불리언 두 개를 두었지만, SDK는 이 값을 채우지 않는다. 보통 뒤따르는 임상시험 결과를 위한 자리다.
비교 PK 시험은 바이오시밀러 임상 프로그램에서 가장 표준화된 부분이다. 노출은 AUC와 Cmax로 요약하며, 둘 다 대략 로그정규분포를 따르므로 로그 변환값으로 분석한다. 관심 있는 양은 시험약 대 대조약의 기하평균비(GMR)이며, 각 1차 매개변수에서 GMR의 90 % 신뢰구간이 80–125 % 안에 완전히 들어가면 동등하다고 결론짓는다. 비대칭으로 보이는 이 한계는 로그 척도에서 ±ln(1.25)일 뿐이다. ln(0.8) = −ln(1.25)이기 때문이다. 명세서 §8.2는 이 기준을 정확히 적고 있다.
예를 들어 두 군의 로그 AUC 평균 차이가 GMR 1.03에 해당하고, 로그 차이의 표준오차가 0.045, 자유도가 약 100(양측 90 % 구간에서 t ≈ 1.66)이라고 하자.
ln GMR = ln(1.03) = 0.0296
반폭 = 1.66 × 0.045 = 0.0747
90 % CI = exp(0.0296 ± 0.0747) = 0.956 ~ 1.110
기준 = 0.80 ~ 1.25 -> 이 매개변수는 충족
산술보다 설계 선택이 더 중요하다. 명세서 §8.3.1은 "교차 설계 선호", "군당 n ≥ 50"이라고 적는다. 대부분의 저분자와 반감기가 짧은 단백질에는 각 피험자가 자신의 대조가 되는 교차 설계가 실제로 효율적이다. 그러나 반감기가 몇 주인 단일클론항체에 교차 설계를 쓰면 휴약기가 매우 길어지고, 첫 투여기에 항약물항체가 생기면 결과가 교란된다. 그래서 항체에는 평행군 설계가 통상적이며, 표본 크기는 고정된 숫자가 아니라 예상 변동성과 가정한 실제 GMR에 근거한 검정력 계산에서 나온다. PK 시험은 안전하다면 건강한 자원자 대상 단회 투여로 하는 경우가 많고, 건강한 사람에게 윤리적으로 투여할 수 없는 제품은 환자에서 연구하며 때로 더 큰 임상시험 안에서 수행한다.
면역원성은 PK와 함께 비교한다. 제품 간 항약물항체 형성의 차이는 노출과 안전성을 바꿀 수 있기 때문이다. 제5장의 분석 전략이 그대로 적용되며, ADA 시험법이 두 제품 모두에 대한 항체를 검출해야 한다는 점이 중요하게 더해진다.
지금까지 대부분의 바이오시밀러 프로그램은 비교 유효성 시험도 포함했다. 그 목적은 대조약이 이미 입증한 약효를 다시 확인하는 것이 아니라, 분석과 PK 비교 뒤에 남은 불확실성을 해소하는 것이다. 그래서 제품 간 차이에 민감하도록 고른 대상 집단과 평가변수로 수행하며, 양측 한계를 둔 동등성 시험으로 분석한다. 한계는 대조약 효과에 관한 자료를 바탕으로 평가변수와 적응증마다 정당화하며, 제품 전반에 적용되는 일반적 백분율은 없다. 명세서 §8.3.2는 "비열등성 한계: Δ = 15 %(전형적)"라고 적고 있으나, 구현자는 이 수치를 채택하지 말아야 한다. 또한 단측 비열등성 설계로는 양 방향 모두에서 임상적으로 의미 있는 차이가 없음을 입증할 수 없다는 점도 유의해야 한다. 이런 시험을 언제 줄이거나 면제할 수 있는지에 관한 규제 흐름은 제8장에서 다룬다.
한 적응증에서 바이오시밀러성이 확립되면, 작용 기전, PK, 면역원성이 해당 적응증들에 걸쳐 적용 가능하다는 과학적 정당화를 근거로 대조약의 다른 적응증에 대한 허가를 외삽으로 구할 수 있다. 미국에서는 바이오시밀러가 351(k)(4)조에 따라 추가로 상호교환 가능(interchangeable) 지정을 받을 수 있으며, 이 경우 주법에 따라 처방자의 개입 없이 약국에서 대체할 수 있다. 법정 기준은 제품이 어느 환자에게서든 대조약과 같은 임상 결과를 낼 것으로 기대될 수 있어야 하고, 두 번 이상 투여하는 제품이라면 제품을 번갈아 쓰는 위험이 대조약을 계속 쓰는 것보다 크지 않아야 한다는 것이다. 유럽연합에는 별도의 상호교환성 지정이 없다. EMA와 의약품청장협의체(HMA)는 EU에서 허가된 바이오시밀러가 상호교환 가능하다는 입장을 밝혔으며, 자동 대체 여부는 각 회원국이 결정한다.
SDK가 pkSimilarity와 clinicalSimilarity를 비워 두므로, 바이오시밀러 근거를 저장하는 시스템은 이 값을 시험 결과에서 채워야 하며 분석 점수에서 추론해서는 안 되고, 각 불리언을 출처와 연결해야 한다. 최소 형태는 다음과 같다.
{
"overallSimilarity": 93.84,
"conclusion": "further-testing-required",
"analyticalSimilarity": false,
"pkSimilarity": true,
"pkEvidence": { "study": "<시험 ID>", "parameter": "AUC0-inf",
"gmr": 1.03, "ci90": [0.956, 1.110], "design": "parallel, single dose" },
"clinicalSimilarity": null
}
pkEvidence 필드와, 아직 답하지 않은 질문을 나타내는 null 값은 확장이다. v1.0은 true, false, 또는 필드 생략만 허용한다. "아직 시험하지 않음"과 "시험했으나 실패"는 다음 단계가 전혀 다르므로 이 확장을 둘 가치가 있다.
이 장의 내용은 관문 목록으로 압축할 수 있다. 각 관문에는 필요한 근거와 결정 주체가 있다. 오른쪽 열의 함수들은 결정에 들어갈 입력을 제공할 뿐 결정을 내리지 않는다.
| 관문 | 필요한 근거 | SDK 지원 | SDK가 하지 못하는 것 |
|---|---|---|---|
| A: 후보 선정 | Kd, 정의된 안정성 지표, 면역원성 평가, 숙주, 분자 유형 | validateDrugCandidate()가 약한 결합, 낮은 안정성, 높은 면역원성, 숙주 부적합을 표시 | 입력 검증, 안정성 정의, 기간·비용·성공 확률 추정 |
| 공정 확정 | 배양 매개변수, 단계별 수율을 포함한 정제 공정, 바이러스 제거 자료 | 타입만 제공 | 수율 일관성 검사, 바이러스 불활화·여과 단계 표현 |
| 공정 변경 | 변경 전후 로트 자료, 영향받는 속성의 위험 평가 | 1차 비교 도구로서의 assessBiosimilarity() | 다로트 통계, 필드가 없는 속성(구조, 당쇄) |
| B: 분석적 유사성 | 대조약과 후보의 여러 로트, 직교 분석법 | assessBiosimilarity() 단일 로트 점수 | 품질 범위, 차이의 방향, 정량한계 미만 값 |
| 임상적 동등성 | PK 동등성(GMR 90 % CI가 80–125 % 이내), 비교 면역원성, 필요 시 유효성 | BiosimilarAssessment의 선택적 불리언 | 임상 자료의 모든 통계 분석 |
이렇게 읽으면 WIA-BIO-016은 공통 어휘이자 투명한 1차 점검 도구 모음으로서 가장 쓸모가 있다. 관문은 한 줄씩 감사할 수 있을 만큼 단순하다. 구현자의 책임은 그 투명성을 지키는 것이다. 입력을 저장하고, 결과에 버전을 매기고, SDK가 검증하지 않는 것을 검증하며, 휴리스틱 출력을 결론처럼 제시하지 않아야 한다. 제7장은 이 프로토콜이 만든 기록을 공통기술문서(CTD)에 대응시키고, 이어서 표준 구현 자체를 어떻게 시험하고 인증하는지로 넘어간다.