AlphaFold 3 JSON 입력 형식 이해하기
FASTA 한 줄에서 분자 시스템 명세서로
AlphaFold 2나 ColabFold를 처음 배울 때는 대개 FASTA 파일 하나로 시작했습니다. 단백질 서열을 붙여 넣고, 실행 버튼을 누르고, 결과 구조를 열어 보는 흐름이었습니다. 하지만 AlphaFold 3로 들어오면 상황이 달라집니다. 이제 예측 대상은 단백질 하나가 아니라 단백질, DNA, RNA, 작은 분자 ligand, 금속 이온, 변형 잔기까지 함께 놓인 '분자 시스템'입니다. 그러니 입력도 단순한 서열 메모가 아니라, 누가 무대에 오르고, 몇 명이 오르고, 어떤 이름표를 달고, 서로 어떤 화학적 관계를 갖는지 적은 명세서가 되어야 합니다.
그 명세서가 바로 JSON입니다. JSON은 사람이 읽을 수 있는 데이터 형식입니다. 중괄호 {} 안에 이름과 값을 짝지어 적고, 대괄호 [] 안에 여러 항목을 배열로 넣습니다. AlphaFold 3 코드베이스의 입력 JSON은 AlphaFold Server에서 내려받는 JSON과 다르며, 단백질·RNA·DNA·ligand, 변형 잔기, 사용자 MSA, 템플릿, CCD 또는 SMILES ligand, 사용자 정의 CCD, 공유결합, 여러 random seed를 표현할 수 있습니다.1
이 장의 목표는 분명합니다. 로컬 AlphaFold 3를 실행하기 위해 직접 JSON 파일을 만들고, 실행 전에 스스로 검증할 수 있게 되는 것입니다. 코드를 많이 쓰지 않아도 괜찮습니다. 핵심은 JSON을 '컴퓨터가 읽는 주문서'가 아니라 '내가 예측하려는 생물학적 장면의 설계도'로 이해하는 것입니다.

가장 작은 AlphaFold 3 JSON
가장 단순한 입력부터 보겠습니다. 단백질 사슬 하나를 예측하는 JSON은 다음처럼 생겼습니다.
{
"name": "single_protein_test",
"modelSeeds": [1],
"sequences": [
{
"protein": {
"id": "A",
"sequence": "PVLSCGEWQL"
}
}
],
"dialect": "alphafold3",
"version": 4
}이 파일은 짧지만 AlphaFold 3 입력의 뼈대를 모두 갖고 있습니다. name은 작업 이름입니다. 출력 폴더와 파일 이름에 사용되므로, 공백이나 특수문자를 잔뜩 넣기보다 kinase_atp_seed1처럼 나중에 봐도 뜻이 분명한 이름을 쓰는 편이 좋습니다.
modelSeeds는 random seed 목록입니다. seed는 모델이 구조를 생성할 때 사용하는 난수 시작점입니다. 같은 입력이라도 seed가 다르면 약간 다른 구조가 나올 수 있습니다. modelSeeds: [1]이면 한 번 예측하고, [1, 2, 3]이면 같은 시스템을 seed 세 개로 예측합니다. 복합체, ligand 결합, 유연한 영역처럼 여러 해답이 가능해 보이는 문제에서는 seed를 여러 개 주고 반복성을 확인하는 것이 좋습니다. 다만 처음에는 한 개로 시작하십시오. JSON과 실행 환경이 정상인지 확인한 뒤 seed 수를 늘리는 편이 시간과 GPU 비용을 아낍니다.
sequences는 가장 중요한 본문입니다. 이름은 sequences이지만, 실제로는 단백질 서열뿐 아니라 RNA, DNA, ligand까지 모두 들어갑니다. 다시 말해 이 배열은 '예측에 참여하는 entity 목록'입니다. 여기서 entity는 하나의 분자 단위라고 생각하면 됩니다. 단백질 사슬 하나, RNA 사슬 하나, DNA 사슬 하나, ATP 한 분자, 마그네슘 이온 하나가 각각 entity가 될 수 있습니다.
dialect는 입력 형식의 방언을 지정합니다. 로컬 AlphaFold 3 코드베이스 형식으로 직접 작성한다면 alphafold3로 적습니다. version은 입력 형식의 버전입니다. 공식 문서의 현재 형식은 version 4까지 설명하며, version 4에서는 각 entity에 설명용 description 필드를 넣을 수 있습니다.1 다만 기관 HPC에 설치된 AlphaFold 3가 오래된 버전이면 지원하는 JSON version이 낮을 수 있습니다. 단순 입력이 계속 거절된다면 설치 문서와 예제 JSON의 version 값을 먼저 확인하십시오.
중요한 실무 규칙이 하나 있습니다. 위 예시는 JSON입니다. 실제 JSON 파일에는 주석을 넣을 수 없습니다. 마지막 항목 뒤의 쉼표도 허용되지 않습니다. 문서에서 설명용으로 보는 # optional 같은 주석을 그대로 복사하면 실행 전에 파서가 먼저 넘어집니다.
최상위 필드 읽기: name, modelSeeds, sequences, dialect, version
AlphaFold 3 JSON의 최상위 구조는 대체로 다음과 같습니다.
{
"name": "job_name",
"modelSeeds": [1, 2],
"sequences": [
{"protein": {}},
{"rna": {}},
{"dna": {}},
{"ligand": {}}
],
"bondedAtomPairs": [],
"dialect": "alphafold3",
"version": 4
}여기에서 꼭 필요한 축은 name, modelSeeds, sequences, dialect, version입니다. bondedAtomPairs는 공유결합을 직접 지정할 때만 필요합니다. 사용자 정의 ligand를 CCD mmCIF 형식으로 넣을 때는 userCCD 또는 userCCDPath가 추가될 수 있지만, 처음부터 만질 필드는 아닙니다.
name은 단순한 이름 이상의 역할을 합니다. 여러 입력을 돌리다 보면 출력 폴더가 쌓입니다. test1, new, final_final 같은 이름은 며칠 뒤 재앙이 됩니다. 좋은 이름은 실험 노트의 제목처럼 작동합니다. 예를 들어 egfr_kinase_atp_mg_seed1, protein_dna_complex_no_ligand, homodimer_phosphoS42처럼 대상과 조건을 드러내면 결과 파일을 열기 전에도 맥락이 살아납니다.
modelSeeds는 반드시 비어 있지 않은 정수 배열이어야 합니다. AlphaFold Server 형식에서는 빈 seed 배열을 허용하고 서버가 seed를 고를 수 있지만, 로컬 alphafold3 형식에서는 적어도 하나의 seed를 직접 넣어야 합니다.1 재현 가능한 보고서를 쓰려면 seed를 기록해야 하므로, 연구용 실행에서는 무작위에 맡기기보다 명시적으로 적는 습관이 좋습니다.
sequences는 entity를 나열하는 배열입니다. 배열 안의 각 항목은 { "protein": {...} }, { "rna": {...} }, { "dna": {...} }, { "ligand": {...} } 중 하나의 형태를 갖습니다. 한 항목 안에 protein과 ligand를 동시에 넣는 방식이 아닙니다. 각 entity는 자기 칸을 하나씩 차지합니다.
dialect와 version은 입력을 읽는 프로그램에 '이 문서가 어떤 문법으로 쓰였는지'를 알려 줍니다. 특히 Server JSON과 로컬 AlphaFold 3 JSON은 비슷해 보이지만 다릅니다. 이 차이를 무시하면 파일은 JSON 문법상 맞아도 AlphaFold 3 입장에서는 엉뚱한 편지가 됩니다.
protein entity: 단백질 사슬을 정의하는 법
단백질 entity의 최소 필드는 id와 sequence입니다.
{
"protein": {
"id": "A",
"sequence": "MVTRFLGPRYRELVKNWVPTAYT"
}
}id는 이 entity의 이름표입니다. 보통 A, B, C처럼 대문자를 씁니다. 이 ID는 단지 JSON 안에서만 쓰이는 별명이 아닙니다. 출력 mmCIF 파일의 chain ID와 연결됩니다.1 따라서 나중에 구조를 PyMOL, ChimeraX, Mol* 같은 도구에서 열었을 때 'chain A가 무엇이었지?'라고 헤매지 않으려면 처음부터 의미 있게 정해야 합니다.
sequence에는 표준 아미노산 1문자 코드를 이어서 씁니다. FASTA 헤더는 넣지 않습니다. 줄바꿈도 넣지 않는 편이 안전합니다. UniProt에서 복사한 서열을 넣는다면 공백, 숫자, 줄 번호, * 같은 문자가 섞이지 않았는지 확인해야 합니다. AlphaFold 3는 당신의 의도를 추측하는 비서가 아니라, 입력을 엄격하게 읽는 실험 장비에 가깝습니다.
단백질에는 선택적으로 modifications, description, unpairedMsa, pairedMsa, templates 같은 필드가 들어갈 수 있습니다. 이 장에서는 JSON 골격을 이해하는 것이 우선이므로 MSA와 템플릿은 다음 장 이후의 고급 옵션으로 미뤄 두겠습니다. 다만 description은 실무에서 유용합니다.
{
"protein": {
"id": "A",
"sequence": "MVTRFLGPRYRELVKNWVPTAYT",
"description": "human protein fragment, residues 35-58"
}
}description은 모델 입력의 생물학적 의미를 사람에게 남기는 메모입니다. 예측에는 직접 쓰이지 않는 설명 필드로 이해하면 됩니다. version 4를 지원하는 환경에서 사용할 수 있습니다. 오래된 설치에서 오류가 난다면 우선 description을 빼고 다시 시도하십시오.
RNA와 DNA entity: 염기서열도 같은 원리로 쓴다
AlphaFold 3는 단백질만 접는 도구가 아닙니다. 단백질-DNA 복합체, 단백질-RNA 복합체, 단일 RNA 사슬, 이중가닥 DNA 같은 생체분자 복합체를 한 입력에서 다룰 수 있습니다. AlphaFold 3가 단백질, 핵산, 작은 분자, 이온, 변형 잔기까지 포함하는 복합체를 모델링할 수 있다는 점이 AlphaFold 2와 크게 달라진 지점입니다.2
RNA entity는 다음처럼 씁니다.
{
"rna": {
"id": "R",
"sequence": "AGCU"
}
}RNA 서열에는 A, C, G, U를 씁니다. DNA entity는 비슷하지만 U 대신 T를 씁니다.
{
"dna": {
"id": "D",
"sequence": "GACCTCT"
}
}이중가닥 DNA를 넣고 싶다면 두 가닥을 별도 DNA entity로 넣습니다. 이때 두 가닥의 방향을 조심해야 합니다. 구조 생물학에서 서열은 보통 5′에서 3′ 방향으로 씁니다. 상보 가닥을 넣을 때도 그 가닥 자체의 5′→3′ 서열을 적어야 합니다. 단순히 원래 서열을 뒤집지 않고 상보 변환만 하거나, 상보 변환 없이 뒤집기만 하면 잘못된 DNA가 됩니다.
{
"name": "protein_dna_example",
"modelSeeds": [1],
"sequences": [
{
"protein": {
"id": "A",
"sequence": "PVLSCGEWQL"
}
},
{
"dna": {
"id": "D",
"sequence": "GACCTCT"
}
},
{
"dna": {
"id": "E",
"sequence": "AGAGGTC"
}
}
],
"dialect": "alphafold3",
"version": 4
}여기서 chain D와 E는 출력 mmCIF에서도 구분됩니다. 나중에 PAE나 interface를 볼 때 chain ID가 해석의 좌표가 됩니다. 'DNA 1', 'DNA 2'라는 막연한 기억보다 D, E라는 고정된 이름표가 훨씬 강합니다.
ligand entity: CCD 코드와 SMILES 중 하나를 고른다
AlphaFold 3에서 ligand는 단백질이나 핵산과 함께 놓이는 작은 분자입니다. ATP, NAD, heme, 당, 저해제, 금속 이온이 모두 이 범주에서 다뤄질 수 있습니다. 로컬 AlphaFold 3 입력에서 ligand를 지정하는 대표적인 방법은 CCD 코드와 SMILES입니다.1
CCD는 Chemical Component Dictionary의 약자입니다. PDB에서 화학 성분을 정의할 때 쓰는 사전이라고 생각하면 됩니다. ATP처럼 널리 쓰이는 분자는 보통 CCD 코드가 있습니다.
{
"ligand": {
"id": "L",
"ccdCodes": ["ATP"]
}
}금속 이온도 로컬 AlphaFold 3 JSON에서는 ligand로 넣습니다. 예를 들어 마그네슘 이온은 다음처럼 씁니다.
{
"ligand": {
"id": "M",
"ccdCodes": ["MG"]
}
}이 점은 AlphaFold Server JSON과 헷갈리기 쉽습니다. Server에서는 ion과 ligand를 별도 entity처럼 다루지만, 로컬 AlphaFold 3 형식에서는 ion도 ligand입니다.1 따라서 ion이라는 새 entity를 만들지 말고 ligand 안에 ccdCodes로 넣어야 합니다.
CCD에 없는 작은 분자는 SMILES로 지정할 수 있습니다. SMILES는 원자와 결합을 한 줄 문자열로 표현하는 화학식 언어입니다.
{
"ligand": {
"id": "X",
"smiles": "CC(=O)O"
}
}중요한 제한이 있습니다. 하나의 ligand entity에서 ccdCodes와 smiles를 동시에 쓰면 안 됩니다. 둘 중 하나만 선택해야 합니다. 또한 SMILES로 넣은 ligand는 공유결합 지정에 적합하지 않습니다. 공유결합을 정의하려면 특정 원자의 이름을 정확히 불러야 하는데, SMILES만으로는 AlphaFold 3가 그 원자 이름을 안정적으로 참조하기 어렵기 때문입니다. 이런 경우에는 사용자 정의 CCD, 즉 userCCD나 userCCDPath를 검토해야 합니다.1
SMILES 문자열에는 또 하나의 함정이 있습니다. JSON 안에서 역슬래시 ``는 특별한 의미를 갖기 때문에, SMILES에 역슬래시가 들어가면 \처럼 두 번 적어 escape해야 합니다. ligand 입력 오류가 JSON 파싱 단계에서 바로 난다면, 화학이 아니라 문자열 escape 문제일 수 있습니다.
동종 다량체는 id 리스트로 표현한다
복합체 예측에서 자주 나오는 질문이 있습니다. 같은 단백질이 두 개 모여 homodimer를 만들 때 sequence 항목을 두 번 써야 할까요? AlphaFold 3 JSON에서는 더 간단한 방법이 있습니다. 같은 entity의 id를 문자열 하나가 아니라 리스트로 쓰면 됩니다.
{
"name": "homodimer_example",
"modelSeeds": [1],
"sequences": [
{
"protein": {
"id": ["A", "B"],
"sequence": "GMRESYANENQFGFKTINSDIHKIVIVGGY"
}
}
],
"dialect": "alphafold3",
"version": 4
}이 입력은 같은 단백질 사슬 두 사본을 뜻합니다. 출력 mmCIF에는 chain A와 chain B가 생깁니다. 두 사슬은 같은 sequence와 같은 설정을 공유합니다. homotrimer라면 id: ["A", "B", "C"]처럼 쓰면 됩니다.
반대로 서로 다른 단백질 두 개가 결합하는 heterodimer라면 별도 protein entity 두 개를 써야 합니다.
{
"name": "heterodimer_example",
"modelSeeds": [1],
"sequences": [
{
"protein": {
"id": "A",
"sequence": "PVLSCGEWQL"
}
},
{
"protein": {
"id": "B",
"sequence": "MKTAYIAKQRQISFVKSHFSRQ"
}
}
],
"dialect": "alphafold3",
"version": 4
}이 차이는 작아 보이지만 해석에서는 큽니다. id 리스트는 '같은 분자의 여러 사본'이라는 뜻입니다. 별도 entity는 '다른 분자'라는 뜻입니다. 같은 sequence라도 하나는 야생형, 하나는 변이형이라면 같은 entity의 id 리스트로 묶으면 안 됩니다. 각각 별도 protein entity로 쓰고 sequence를 다르게 적어야 합니다.
Ligand도 같은 방식으로 여러 사본을 표현할 수 있습니다.
{
"ligand": {
"id": ["L", "M"],
"ccdCodes": ["ATP"]
}
}이것은 ATP 두 분자를 넣는다는 뜻입니다. 출력에서 L과 M을 구분할 수 있으므로, 하나가 active site에 가고 다른 하나가 표면에 붙는지 같은 해석이 가능해집니다.
ID는 나중의 해석을 위한 좌표다
JSON을 처음 쓸 때는 id를 아무렇게나 붙이고 싶어집니다. 하지만 ID는 나중에 결과를 읽는 눈금자입니다. pLDDT는 잔기별로 보고, PAE는 chain 사이의 상대 배치를 보고, interface는 어느 chain과 어느 ligand 사이인지 봅니다. 이때 JSON의 id가 출력 mmCIF chain ID와 이어지므로, ID를 잘 정하면 해석이 쉬워지고 잘못 정하면 자기 결과를 스스로 암호문으로 만듭니다.
실무에서는 단백질을 A, B, C로, DNA를 D, E로, RNA를 R, S로, ligand를 L, M, N으로 두는 식의 자기 규칙을 만들면 좋습니다. 꼭 이렇게 해야 하는 것은 아니지만, 한 프로젝트 안에서는 일관성이 중요합니다. 여러 글자로 된 ID도 쓸 수 있으나, 시각화 도구나 후처리 스크립트에서 불편할 수 있으므로 처음에는 단순한 대문자 한 글자를 추천합니다.
ID는 전체 JSON 안에서 고유해야 합니다. protein A와 ligand A를 동시에 만들면 안 됩니다. homodimer에서 id: ["A", "B"]를 썼다면 다른 entity는 A나 B를 다시 쓰면 안 됩니다. ID 충돌은 실험실에서 두 시료 튜브에 같은 라벨을 붙이는 것과 같습니다. 결과가 나와도 무엇이 무엇인지 알 수 없습니다.
변형 잔기: sequence를 바꾸는 것이 아니라 modification으로 표시한다
생물학적 분자는 교과서의 표준 서열 그대로만 존재하지 않습니다. 단백질은 인산화, 메틸화, 당화 같은 번역 후 변형을 받을 수 있고, RNA와 DNA에도 변형 염기가 있을 수 있습니다. AlphaFold 3 JSON은 이런 변형을 별도 필드로 지정할 수 있습니다.
단백질 변형은 modifications 배열에 넣습니다.
{
"protein": {
"id": "A",
"sequence": "MSTPVLSCGEWQL",
"modifications": [
{
"ptmType": "SEP",
"ptmPosition": 2
}
]
}
}여기서 SEP는 phosphoserine을 뜻하는 CCD 코드로 흔히 쓰입니다. ptmPosition은 입력 sequence에서의 1-based 위치입니다. 프로그래밍에서 자주 쓰는 0부터 세는 방식이 아닙니다. 위 예시에서는 두 번째 잔기 S가 변형 대상입니다.
이 위치가 매우 중요합니다. UniProt 번호, 논문에 나온 성숙 단백질 번호, PDB residue number와 JSON sequence의 위치가 서로 다를 수 있습니다. signal peptide를 제거한 sequence를 넣었다면, 변형 위치도 제거된 sequence 기준으로 다시 세야 합니다. 'Ser42가 인산화된다'라는 문장을 그대로 ptmPosition: 42로 옮기기 전에, 내가 넣은 sequence의 42번째가 정말 그 serine인지 확인해야 합니다.
RNA와 DNA 변형도 비슷합니다.
{
"rna": {
"id": "R",
"sequence": "AGCU",
"modifications": [
{
"modificationType": "5MC",
"basePosition": 2
}
]
}
}{
"dna": {
"id": "D",
"sequence": "GACCTCT",
"modifications": [
{
"modificationType": "6MA",
"basePosition": 2
}
]
}
}modificationType도 CCD 코드입니다. 즉 변형 이름을 영어로 길게 쓰는 것이 아니라, AlphaFold 3가 이해할 수 있는 화학 성분 코드를 넣어야 합니다. 변형을 넣을 때는 코드가 실제로 지원되는지, 위치가 맞는지, 표준 base나 residue와 화학적으로 말이 되는지 함께 확인해야 합니다.
공유결합을 직접 지정하는 bondedAtomPairs
대부분의 비공유결합 상호작용은 별도 결합 지정을 하지 않습니다. ATP가 단백질 pocket에 들어갈지, Mg²⁺가 어디에 놓일지, DNA가 단백질 표면과 어떻게 접촉할지는 모델이 예측합니다. 하지만 어떤 경우에는 두 원자가 실제로 공유결합으로 연결되어 있다는 정보를 입력에 넣어야 합니다. 예를 들어 ligand가 cysteine에 공유결합으로 붙는 저해제이거나, 여러 CCD 조각을 이어 glycan이나 특수 ligand를 만들 때가 그렇습니다.
AlphaFold 3 JSON에서는 bondedAtomPairs를 최상위 필드에 둡니다. 한 결합은 두 원자의 쌍으로 표현합니다. 각 원자는 대체로 [entity ID, residue index, atom name] 형태로 가리킵니다.
{
"name": "covalent_ligand_example",
"modelSeeds": [1],
"sequences": [
{
"protein": {
"id": "A",
"sequence": "MCCCCCCCCCC"
}
},
{
"ligand": {
"id": "L",
"ccdCodes": ["LIG"]
}
}
],
"bondedAtomPairs": [
[
["A", 2, "SG"],
["L", 1, "C1"]
]
],
"dialect": "alphafold3",
"version": 4
}위 예시는 형식을 보여 주기 위한 것입니다. 실제로 LIG라는 CCD 코드와 C1 원자명이 존재해야 하며, 단백질 chain A의 2번 잔기가 cysteine이어야 SG 원자가 의미를 갖습니다. 단일 CCD ligand라면 ligand 쪽 residue index는 보통 1로 생각할 수 있습니다. 여러 CCD 블록을 하나의 ligand entity로 묶었다면 몇 번째 블록의 어떤 원자인지 더 꼼꼼히 확인해야 합니다.
공유결합 입력에서 가장 흔한 오류는 세 가지입니다. 첫째, residue 번호를 PDB 번호로 착각합니다. JSON의 위치는 입력 sequence 기준입니다. 둘째, 원자명을 대충 씁니다. SG, NZ, C1 같은 이름은 CCD 또는 잔기 정의에 실제로 존재해야 합니다. 셋째, SMILES ligand에 공유결합을 걸려고 합니다. 공식 문서는 SMILES가 원자 이름을 유일하게 지정할 수 없기 때문에 다른 entity와의 공유결합 지정에는 적합하지 않으며, 이런 경우 사용자 제공 CCD를 사용해야 한다고 설명합니다.1
공유결합은 강력하지만 위험한 기능입니다. 잘 쓰면 생물학적으로 필수적인 연결을 모델에 알려 줄 수 있습니다. 잘못 쓰면 모델에게 존재하지 않는 화학 결박을 강요합니다. 확실한 화학 근거가 있을 때만 쓰고, 입력 후에는 출력 구조에서 결합 길이와 주변 기하가 말이 되는지 반드시 확인하십시오.
사용자 정의 CCD는 전문가 모드다
ccdCodes로 표현할 수 없는 ligand가 있고, SMILES만으로는 부족한 경우가 있습니다. 대표적으로 공유결합을 지정해야 하는 custom ligand, RDKit이 conformer를 잘 만들지 못하는 ligand, 또는 원자 이름과 기준 좌표를 직접 통제해야 하는 분자입니다. 이때 userCCD 또는 userCCDPath를 사용할 수 있습니다.
userCCD는 CCD mmCIF 내용을 JSON 안에 문자열로 직접 넣는 방식이고, userCCDPath는 별도 파일 경로를 가리키는 방식입니다. 둘은 동시에 쓰면 안 됩니다. 실제 프로젝트에서는 JSON이 너무 길어지는 것을 피하기 위해 userCCDPath를 쓰는 편이 관리하기 쉽습니다.
처음 AlphaFold 3를 배우는 단계라면 사용자 정의 CCD부터 시작하지 마십시오. 먼저 표준 단백질, 핵산, 일반 CCD ligand로 입력과 출력 흐름을 익히는 것이 좋습니다. 사용자 정의 CCD는 화학 정보, atom name, bond table, 좌표, 파일 형식이 모두 맞아야 하는 전문가 모드입니다. 이 모드는 어렵다는 뜻이 아니라, 실수했을 때 오류가 생물학 문제가 아니라 파일 형식 문제인지 구분하기 어렵다는 뜻입니다.
Server JSON과 로컬 AlphaFold 3 JSON의 차이
AlphaFold Server에서 작업을 만들고 JSON을 내려받은 뒤, 그 파일을 로컬 AlphaFold 3에 그대로 넣고 싶을 수 있습니다. 때로는 변환이 됩니다. 하지만 두 형식은 본질적으로 다릅니다. 공식 문서에 따르면 run_alphafold.py에는 AlphaFold Server JSON을 로컬 alphafold3 형식으로 변환하는 기능이 있으며, converter는 Server 형식을 alphafoldserver, 로컬 코드베이스 형식을 alphafold3로 구분합니다.1
가장 눈에 띄는 차이는 최상위 구조입니다. AlphaFold Server JSON은 최상위가 리스트일 수 있고, 한 파일에 여러 입력을 담을 수 있습니다. 반면 로컬 alphafold3 JSON은 한 파일에 정확히 하나의 입력을 담는 객체 구조입니다. converter는 최상위가 리스트인지 아닌지로 형식을 구분하므로, Server 스타일 JSON을 리스트 없이 어설프게 저장하면 오류가 날 수 있습니다.1
또 다른 차이는 entity ID입니다. 로컬 alphafold3 형식에서는 각 entity에 고유한 id를 직접 지정해야 합니다. Server JSON은 사용자가 entity별 ID를 세밀하게 지정하는 방식이 아니므로, 변환 과정에서 ID가 자동 부여됩니다. 이 자동 ID는 결과 해석에는 충분할 수 있지만, 논문 그림이나 재현 보고서를 만들 때는 내가 의도한 chain 이름과 다를 수 있습니다.
seed도 다릅니다. Server JSON에서는 modelSeeds: []처럼 비워 두고 서버가 seed를 고르게 할 수 있지만, 로컬 alphafold3 형식에서는 seed를 적어도 하나 넣어야 합니다. 변환기는 빈 seed를 만나면 임의 seed를 골라 넣을 수 있습니다.1 재현성이 중요하다면 변환된 JSON에서 seed를 확인하고 기록해야 합니다.
ion 처리도 다릅니다. Server에서는 ion이 ligand와 별도 범주처럼 보일 수 있지만, 로컬 AlphaFold 3 JSON에서는 ion을 ligand로 넣습니다. 예를 들어 Mg²⁺는 ligand entity에 ccdCodes: ["MG"]로 씁니다.
마지막으로 glycan과 복잡한 공유결합에서는 자동 변환을 과신하지 않는 편이 좋습니다. 공식 문서는 Server 형식의 glycan을 로컬 형식으로 변환하는 것이 지원되지 않아 오류가 날 수 있다고 설명합니다.1 또한 로컬 형식은 custom ligand, branched glycan, entity 간 공유결합을 더 유연하게 표현할 수 있으므로, 복잡한 화학 시스템에서는 Server JSON을 출발점으로 삼더라도 최종 입력은 로컬 형식으로 직접 정리하는 것이 안전합니다.
실전 예시: 단백질, ATP, 마그네슘을 함께 넣기
이제 조금 더 실제 같은 입력을 보겠습니다. 단백질 하나, ATP 하나, Mg²⁺ 하나를 같은 시스템에 넣는 예입니다.
{
"name": "protein_atp_mg_example",
"modelSeeds": [1, 2, 3],
"sequences": [
{
"protein": {
"id": "A",
"sequence": "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQ",
"description": "example protein chain"
}
},
{
"ligand": {
"id": "L",
"ccdCodes": ["ATP"],
"description": "ATP ligand"
}
},
{
"ligand": {
"id": "M",
"ccdCodes": ["MG"],
"description": "magnesium ion"
}
}
],
"dialect": "alphafold3",
"version": 4
}이 입력은 'ATP가 반드시 active site에 정확히 들어간다'는 보증서가 아닙니다. AlphaFold 3는 가능한 결합 pose를 예측합니다. 결과를 받은 뒤에는 ligand 주변 pLDDT, ligand와 단백질의 접촉, steric clash, 금속 배위 거리, 여러 seed 사이의 pose 반복성을 확인해야 합니다. 이전 장에서 AlphaFold Server 결과를 읽을 때 보았듯, ligand가 있다고 해서 ligand 해석이 자동으로 확정되는 것은 아닙니다. JSON은 무대를 꾸미는 일이고, 신뢰도 해석은 공연이 끝난 뒤의 비평입니다.
실행 전에 하는 JSON 검증 루틴
좋은 JSON은 실행이 됩니다. 더 좋은 JSON은 실행 전에 스스로 설명할 수 있습니다. AlphaFold 3를 돌리기 전에 다음 순서로 확인해 보십시오.
먼저 JSON 문법부터 검사합니다. Linux나 macOS에서는 다음 명령으로 기본 문법 오류를 잡을 수 있습니다.
python -m json.tool input.json > /dev/null아무 메시지 없이 끝나면 JSON 문법은 통과한 것입니다. 여기서 실패하면 AlphaFold 3 문제가 아닙니다. 쉼표, 따옴표, 중괄호, 대괄호, SMILES escape를 먼저 고쳐야 합니다.
그다음 생물학적 내용을 확인합니다. 이 단계에서는 파일을 눈으로 읽어야 합니다. modelSeeds가 비어 있지 않은지, 모든 entity ID가 고유한지, sequence에 허용되지 않는 문자가 없는지, RNA에 T를 쓰거나 DNA에 U를 쓰지 않았는지 확인합니다. 변형 잔기를 넣었다면 위치가 입력 sequence 기준 1-based인지 다시 셉니다. ligand를 넣었다면 CCD 코드가 맞는지, SMILES와 CCD를 한 entity에 동시에 넣지 않았는지 확인합니다. 공유결합을 넣었다면 atom name과 residue index가 실제 정의와 맞는지 확인합니다.
마지막으로 실행 규모를 확인합니다. 처음부터 seed 20개, ligand 여러 개, DNA 두 가닥, custom CCD, 공유결합을 모두 넣고 돌리면 문제가 생겼을 때 원인을 찾기 어렵습니다. 좋은 전략은 작게 시작해 한 단계씩 키우는 것입니다. 단백질만 먼저 돌리고, 그다음 핵산을 추가하고, 그다음 ligand를 추가하고, 마지막에 변형이나 공유결합을 넣습니다. 예측 모델도 실험 장비와 같습니다. 한 번에 모든 변수를 바꾸면 무엇이 문제였는지 알 수 없습니다.
자주 나는 오류를 미리 피하기
JSON 입력에서 발생하는 오류는 대부분 모델이 어려워서가 아니라 명세서가 애매해서 생깁니다. 특히 다음 실수는 매우 흔합니다.
Server JSON을 로컬
alphafold3JSON이라고 생각하고 그대로 수정하다가 최상위 리스트와 객체 구조를 섞는 실수homodimer를 표현하려고 같은 sequence를 별도 entity로 두 번 쓰면서 MSA와 chain 해석을 불필요하게 복잡하게 만드는 실수
변형 위치를 UniProt 번호로 넣고, 실제 입력 sequence에서는 다른 잔기를 가리키는 실수
ion entity를 따로 만들거나, Mg²⁺를
MG2+처럼 임의 이름으로 쓰는 실수SMILES ligand에
bondedAtomPairs를 걸려고 하거나, CCD 원자명을 확인하지 않고 공유결합을 지정하는 실수
이런 오류를 줄이는 가장 좋은 방법은 JSON 파일 맨 위의 name과 각 entity의 description에 자신의 의도를 적어 두는 것입니다. 설명을 적다 보면 스스로 모순을 발견하는 경우가 많습니다. 'chain B, same as A but mutant'라고 쓰려는 순간, id: ["A", "B"]로 묶으면 안 된다는 사실이 보입니다. 'phosphorylated Ser42 in mature protein'이라고 쓰려는 순간, mature protein 기준 42번과 입력 sequence 기준 42번이 같은지 확인해야 한다는 생각이 듭니다.
JSON은 예측의 일부다
AlphaFold 3를 제대로 쓰는 일은 실행 명령을 외우는 일이 아닙니다. 내가 예측하려는 분자 시스템을 정확히 선언하는 일입니다. FASTA가 '이 단백질을 접어 주세요'라는 짧은 부탁이었다면, AlphaFold 3 JSON은 '이 단백질 A와 DNA D/E, ATP L, Mg M을 같은 공간에 놓고, 이 변형과 이 사본 수를 고려해 주세요'라는 상세한 실험 설계서입니다.
이 설계서가 정확할수록 결과 해석도 쉬워집니다. chain ID가 분명하면 mmCIF를 열었을 때 길을 잃지 않습니다. seed가 기록되어 있으면 재현할 수 있습니다. ligand가 CCD인지 SMILES인지 명확하면 오류를 추적할 수 있습니다. 변형 위치가 입력 sequence 기준으로 확인되어 있으면 잘못된 생물학적 결론을 피할 수 있습니다.
다음 단계에서는 이 JSON을 실제 로컬, HPC, 클라우드 환경에서 어떻게 실행할지 다루게 됩니다. 그때부터는 GPU, 데이터베이스, 모델 파라미터, 작업 스케줄러가 등장합니다. 하지만 어떤 환경에서 돌리든 출발점은 같습니다. AlphaFold 3에게 무엇을 예측하게 할 것인지, JSON으로 명확히 말할 수 있어야 합니다.
참고
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.