๊ธฐ๋ฅ ์์ธ ๋ณด๊ณ
๋ณ์ด ์์ฑ ์์ง + Scaffold ๊ฐ๋ โ ๊ธฐ๋ฅ ๋ถ์ ๋ณด๊ณ ์
๊ฒ์ฆ ์์น: ๋ณธ ๋ณด๊ณ ์์ ๋ชจ๋ ๋์ยท์ ๋ ์ฃผ์ฅ์
file_path:line์ธ์ฉ์ผ๋ก ๊ฒ์ฆํ๋ค. ์ฝ๋์์ ํ์ธ๋์ง ์์ ๋ด์ฉ์ "๋ฏธ๊ฒ์ฆ"์ผ๋ก ๋ช ์ํ๋ค. ์์น๋ ์ฝ๋์ ๋ช ์๋ ๊ฐ๋ง ์ธ์ฉํ๋ค.๋ถ์ ๋ฃจํธ:
AgenticAI4SCIENCE_pyrosetta_track/repos/ai4sci-kaeri๋์ ํ์ผ:pyrosetta_flow/runner.py,pyrosetta_flow/schema.py,pyrosetta_flow/adapter.py(๋ณ์ด ์์ฑ๊ธฐ),AG_src/llm/prompts.py
โ ๋์ ์๋ฆฌ
(1) ๋ณ์ด ์์น ์ ํ โ _mutable_design_positions
๋ณ์ด ๊ฐ๋ฅ ์์น๋ config.design_positions ์์ ์ฝ๋ฆฌ๋จ(FWKT, 7-10) ๊ณผ Cys ์์น(์ดํฉํ) ๋ฅผ ์ ์ธํ์ฌ ์ฐ์ถํ๋ค.
design_positions๊ธฐ๋ณธ๊ฐ:[1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12]โpyrosetta_flow/schema.py:14-18(์ฃผ์: ์ค์ ๋ณ์ด ๊ฐ๋ฅ =[1,2,4,5,6,11,12]โ Cys3/14ยทFWKT ์ ์ธ,schema.py:15-16)- ์ฝ๋ฆฌ๋จ ์์น ์์:
PHARMACOPHORE_POSITIONS_1IDX = (7, 8, 9, 10)โrunner.py:102 - Cys ์์น ์ถ์ถ:
_disulfide_cys_positions๊ฐ ์ฐธ์กฐ ์์ด์์C์ธ ์์น(1-indexed)๋ฅผ ๋ชจ๋ ๋ฐํ โrunner.py:114-116 - ์ต์ข
ํํฐ:
mutable_positions = [pos for pos in config.design_positions if pos not in PHARMACOPHORE_POSITIONS_1IDX and pos not in cys]โrunner.py:135-138 - ์์ ํด๋ฐฑ: ํํฐ ๊ฒฐ๊ณผ๊ฐ ๋น๋ฉด
config.design_positions์ ์ฒด๋ฅผ ๊ทธ๋๋ก ๋ฐํ (mutable_positions or list(config.design_positions)) โrunner.py:139โ ๋ฏธ๊ฒ์ฆ ์ฐ๋ ค: ์ด ํด๋ฐฑ์ด ๋ฐ๋ํ๋ฉด FWKT/Cys ๊ฐ ๋ณ์ด ํ๋ณด์ ๋ค์ ํฌํจ๋ ์ ์์ผ๋, ํ์ ํ๋_preserves_scaffold๊ฒ์ดํธ๊ฐ ํ๋จ์์ ๊ทธ๋ฐ ์ ์์ ๊ฑฐ๋ถํ๋ฏ๋ก ์ค์ ํต๊ณผ๋ ์ฐจ๋จ๋จ(์๋ (3) ์ฐธ์กฐ).
์ด ํจ์์ ์ฐ์ถ๋ฌผ์ ๋ณ์ด ๋ฃจํ ์ง์
์ง์ ํ ๋ฒ ํธ์ถ๋์ด mutation_positions ๋ก ์ฌ์ฉ๋๋ค โ runner.py:596.
(2) ์ฝ๋ฆฌ๋จ(FWKT 7-10) ยท Cys3/Cys14 ๋ณด์กด ๋ฉ์ปค๋์ฆ
์ธ ๋จ๊ณ๋ก ์๋ํ๋ค.
- ์์น ์ ํ ๋จ๊ณ ์ ์ธ (์ฌ์ ์ฐจ๋จ): ์ (1)์์ FWKTยทCys ๋ฅผ ๋ณ์ด ํ๋ณด์์ ์ ๊ฑฐ โ
runner.py:132-139. - ์์ฑ๊ธฐ ์์ฒด ์ ์ฝ: ์ค์ ๋ณ์ด ์๋ฏธ๋
ธ์ฐ ํ์์ Cys ๋ฅผ ๋ฐฐ์ .
-
AA_NO_CYS = list("ADEFGHIKLMNPQRSTVWY")(19์ข , Cys ์์) โadapter.py:10-generate_random_mutant๊ฐ ์ด ํ์์๋ง ์นํ โadapter.py:53-54-generate_guided_mutant๋ ์ถ์ฒ ํ์์C๋ฅผ ๋ช ์ ๋ฐฐ์ (aa != "C") โadapter.py:91, ํด๋ฐฑ ํ๋AA_NO_CYSโadapter.py:96โ ์ฆ ๋ณ์ด๋ก ์ธํด ์๋ก์ด Cys ๊ฐ ๋์ ๋์ง ์๋๋ค. (๋จ, ๊ธฐ์กด Cys ๊ฐ ๋ค๋ฅธ AA ๋ก ๋ฐ๋๋ ๊ฒ์ ์์ฑ๊ธฐ๋ง์ผ๋ก๋ ๋ชป ๋ง์ โ ๊ทธ๋์ (3) ๊ฒ์ดํธ๊ฐ ํ์.) - ์ฌํ ๊ฒ์ดํธ (๊ฑฐ๋ถ): ์์ฑ๋ ํ๋ณด๊ฐ ์ฝ๋ฆฌ๋จยท์ดํฉํ๋ฅผ ๋ณด์กดํ๋์ง ๊ฒ์ฆ โ ์๋ (3).
์ฝ๋ฆฌ๋จ ๋ณด์กด ํ์ :
- _pharmacophore_slice(seq) = seq[6:10] (7-10 ์์น ์ฌ๋ผ์ด์ค) โ runner.py:106-107
- _preserves_pharmacophore ๋ ํ๋ณด์ ์ฐธ์กฐ์ 7-10 ์ฌ๋ผ์ด์ค๊ฐ ์์ ๋์ผํ ๋๋ง True โ runner.py:110-111
์ดํฉํ ๋ณด์กด ํ์ :
- _preserves_disulfide: ์ฐธ์กฐ ์์ด์ ๋ชจ๋ Cys ์์น๊ฐ ํ๋ณด์์๋ C ์ฌ์ผ True โ runner.py:119-123
- ๊ฒฐํฉ ๊ฒ์ดํธ _preserves_scaffold = ์ฝ๋ฆฌ๋จ ๋ณด์กด AND ์ดํฉํ ๋ณด์กด โ runner.py:126-129
(3) ๊ฑฐ๋ถ ๋ก์ง (๋ณ์ด ์์ฑ ๋ฃจํ)
ํ๋ณด 1๊ฐ ์์ฑ์ ๋ํด ์ฝ๋ฆฌ๋จ ์ฌ์๋ ์ธ์ธต + dedup ๋ด์ธต์ ์ด์ค ๋ฃจํ ๊ตฌ์กฐ โ runner.py:597-687.
- ์ฝ๋ฆฌ๋จ ์ฌ์๋ ํ๋:
PHARMACOPHORE_RETRY_LIMIT = 3โ ์ธ์ธต์range(PHARMACOPHORE_RETRY_LIMIT + 1)= 4ํ โrunner.py:103,runner.py:601 - dedup ๋ด์ธต:
range(config.max_dedup_trials)(๊ธฐ๋ณธmax_dedup_trials = 50) โrunner.py:603,schema.py:40 - ๋ณ์ด ์ escalation: ๋ด์ธต trial ์ด ์งํ๋ ์๋ก ๊ฐ์ ๋ณ์ด ์๋ฅผ 1โ2โ
max_random_mutationsโmax_random_mutations+1๋ก ์ํฅ (max_random_mutations๊ธฐ๋ณธ 3) โrunner.py:605-611,schema.py:41 - ๊ฑฐ๋ถ ๋ถ๊ธฐ:
- ์๋ณธ๊ณผ ๋์ผํ๊ฑฐ๋ ์ด๋ฏธ ๋ณธ ์์ด โ
continue(์ฌ์๋) โrunner.py:640-641 - scaffold ๋ฏธ๋ณด์กด โ
break(ํด๋น dedup ๋ด์ธต ์ฆ์ ํ์ถ) โrunner.py:642-643 - ํต๊ณผ ์
mutantํ์ +seen_sequences๋ฑ๋ก โrunner.py:644-646 - ํด๋ฐฑ ๊ฒฝ๋ก: ๋ด์ธต์์ mutant ๋ฏธํ์ ์, ๋ง์ง๋ง ์ ์์ด scaffold ์๋ฐ์ด๋ฉด ์ธ์ธต
continue; ์๋๋ฉด ๋ณ์ด ์๋ฅผmax(2, len//2)๋ก ๊ฐ์ ํ ์ถ๊ฐ random ํ๋ณด๋ฅผ ๋ง๋ค์ด scaffoldยทdedupยทnon-native ํต๊ณผ ์ ์ฑํ โrunner.py:649-672 - ์ต์ข
์คํจ ์ฒ๋ฆฌ: 4ํ ์ธ์ธต์ ๋ชจ๋ ์์งํด๋ mutant ๊ฐ ์์ผ๋ฉด
fail_reason = "FWKT pharmacophore gate failed after 3 retries"๋ก ํ์ํ๊ณ ๋ง์ง๋ง ์ ์์ mutant ๋ก ๋ โrunner.py:674-679. ์ด ํ๋ณด๋ ๋ํน ๋จ๊ณ์์ddg=999.0๋ฑ์ผ๋ก ์ฆ์ ์คํจ ์ฒ๋ฆฌ โrunner.py:721-732.
seen_sequences ์ด๊ธฐ๊ฐ์ {config.original_sequence} ๋ก, ๋ค์ดํฐ๋ธ ์์ด์ด ํ๋ณด๋ก ์ ๋ ์ ์ถ๋์ง ์๋๋ก ํ๋ค โ runner.py:458.
(4) LLM ํ๋กฌํํธ ์ธก ๋ณด์กด ๋ช
์ธ โ AG_src/llm/prompts.py
LLM ์ง์ ๋ณ์ด ์์ฑ ๊ฒฝ๋ก(build_variant_generation_prompt)๋ ๋์ผ ์ ์ฝ์ ์์ฐ์ด/few-shot ์ผ๋ก ๊ฐ์ ํ๋ค.
- ์์คํ
ํ๋กฌํํธ
VARIANT_DESIGN_SYSTEM_PROMPT: "Preserve C3 and C14 (disulfide) โ positions 3 and 14 FIXED", "Preserve FWKT pharmacophore โ positions 7,8,9,10 FIXED" โprompts.py:445-458 - ๊ฑฐ๋ถ ์กฐ๊ฑด ๋ช
์: "Any mutation modifies positions 3, 7, 8, 9, 10, or 14" โ output rejected โ
prompts.py:456 build_variant_generation_prompt๋ณธ๋ฌธ๋ ๋์ผ RULE 1ยท2 ๋ฐ๋ณต + few-shot 2๊ฐ โprompts.py:493-505- few-shot ์์(
_SST14_FEW_SHOT_EXAMPLES):AGCKNFFWKTFTSCโPGCKHFFWKTFISC(pos 1/5/12 ๋ณ์ด),AECKNLFWKTYTSC(pos 2/6/11 ๋ณ์ด) โprompts.py:417-442. ๋ ์์ ๋ชจ๋ 3ยท7ยท8ยท9ยท10ยท14 ๋ฅผ ๋ณด์กดํ๋ค(์ก์ ๊ฒ์ฆ). - Planner ์์คํ
ํ๋กฌํํธ๋ "PRESERVE FWKT pharmacophore (pos 7-10) and Cys3/Cys14 disulfide โ never mutate these" โ
prompts.py:69-71
๋ถ์ผ์น (๋ฏธ๊ฒ์ฆ/์ฃผ์):
build_variant_generation_prompt์ docstringยท์์๋ ๊ฐ๋ณ ์์น๋ฅผ[1,2,4,5,6,11,12,13](pos 13 ํฌํจ)์ผ๋ก ๊ธฐ์ โprompts.py:18,255,416,479. ๋ฐ๋ฉด ์ค์ ์์งdesign_positions๊ธฐ๋ณธ๊ฐ์ 13์ ํฌํจํ์ง ์์([...,11,12],schema.py:17). ๋ํformat_planner_prompt์ fallback ํ์ ๋ฌธ์์ด์[1,2,4,5,6,7,8,9,10,11,12,14](14 ํฌํจ) โprompts.py:255. ์ด LLM-๊ฒฝ๋ก ํ๋กฌํํธ์ ์ค์ ์คํ ๊ฒฝ๋ก(generate_random_mutant/generate_guided_mutant,runner.py:614,627)์ ์์น ์งํฉ์ด ์๋ก ๋ค๋ฅด๋ค. ์คํ ๊ฒฝ๋ก์ scaffold ๊ฒ์ดํธ๊ฐ ์ต์ข ์์ ๋ง์ด๋ฏ๋ก ๊ฒฐ๊ณผ ์ ํฉ์ฑ์ ์ ์ง๋๋, ํ๋กฌํํธ์ ์์น ๋ช ์ธ๋ ์ฝ๋ ๊ธฐ๋ณธ๊ฐ๊ณผ ๋๊ธฐํ๋์ด ์์ง ์์(๋ฏธํด์ ๋ฌธ์ ๋ถ์ฑ).
โก ์ํฅ / ํจ๊ณผ โ ์ดํฉํ ํ๊ดด ๋ฐฉ์ง๊ฐ ์์ผ๋ฉด?
_preserves_disulfide docstring ์ด ๋ถ์ฌ ์ ๋ฒ๊ทธ๋ฅผ ์ง์ ๋ช
์ํ๋ค:
"์ด์ ์ ๊ฐ๋ ๋ถ์ฌ๋ก C14โH ๋ณ์ด๊ฐ ํต๊ณผํด SS bond ๊ฐ ๊นจ์ก๋ค." โ
runner.py:120-121
๊ฐ๋ ๋ถ์ฌ ์ ๊ฒฐํจ (C14H ์ฌ๋ก)
- SST-14 ๋ Cys3-Cys14 ์ดํฉํ๊ฒฐํฉ์ผ๋ก ๊ณ ๋ฆฌํ(cyclic) ๊ตฌ์กฐ๋ฅผ ํ์ฑํ๋ค(ํ๋ก์ ํธ ์ปจํ
์คํธ CLAUDE.md,
prompts.py:456). - ๊ฐ๋๊ฐ ์์ผ๋ฉด ๋ณ์ด ์์ฑ๊ธฐ๊ฐ pos 14 ์
C๋ฅผ ๋ค๋ฅธ ์๋ฏธ๋ ธ์ฐ(์: His)์ผ๋ก ์นํํ ์ ์๊ณ , ๊ทธ ํ๋ณด๊ฐ ๊ฑฐ๋ถ ์์ด ๋ํนยท์ฑ์ ๊น์ง ์ง์ ํ๋ค. - ๊ฒฐ๊ณผ: ์ดํฉํ๊ฒฐํฉ์ด ๋๊ธด ์ ํ ํฉํ์ด๋๊ฐ "SST-14 analog" ์ผ๋ก ํ๊ฐ๋จ โ ๊ตฌ์กฐยท๊ฒฐํฉ ์์ ์๋์ง(ddG) ๊ฒฐ๊ณผ๊ฐ ์ค์ cyclic scaffold ์ ๋ฌด๊ดํ ๊ฐ์ด ๋จ โ ํ๋ณด ๋ญํนยท์ ํ์ฑ ํ์ ์ค์ผ.
- ์ด๋ ๋จ์ ์ ์ ์ค๋ฅ๊ฐ ์๋๋ผ scaffold ์ ์ฒด์ฑ ๋ถ๊ดด(์ค๊ณ ๋์์ด ์๋ ๋ถ์๋ฅผ ํ๊ฐ)์ ํด๋น.
ํ์ฌ ๊ฐ๋์ ํจ๊ณผ
generate_random_mutant/generate_guided_mutant๊ฐ Cys ๋์ ์ ๋ง๊ณ (AA_NO_CYS,adapter.py:10,53,91,96),_mutable_design_positions๊ฐ Cys ์์น๋ฅผ ๋ณ์ด ํ๋ณด์์ ์ ๊ฑฐํ๋ฉฐ(runner.py:135-138),_preserves_scaffold๊ฐ ์์กดํ๋ ์๋ฐ ํ๋ณด๋ฅผ ๋ํน ์ง์ ๊ฑฐ๋ถ(runner.py:642-643)ํ๋ค.- ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ํน์ ๋ค์ด๊ฐ๋ ๋ชจ๋ ํ๋ณด๋ FWKT ์ฝ๋ฆฌ๋จ + Cys3/Cys14 ์ดํฉํ ๊ฐ ๋ณด์กด๋ ํฉ๋ฒ scaffold ์์ด ๋ณด์ฅ๋จ(ํต๊ณผ ํ๋ณด ํ์ ).
- ํตํฉ ์ค๋ชจํฌ ํ
์คํธ๊ฐ ์ด ๋ถ๋ณ์์ ๊ฐ์ ๊ฒ์ฆ:
assert result["disulfide_intact"] is True, "Cys3-Cys14 ์ดํฉํ๊ฒฐํฉ ์ ์ค"โpyrosetta_flow/tests/test_integration_smoke.py:160.
โข ๊ด๋ จ Action Item
retro-Q2 (_workspace/release/retro-2026-Q2.md:158-169)์ 8๊ฐ Action Item ์ ๋ชจ๋ CI ๋ฑ๋กยทharness ๋ฉํยท๋ฌธํ LITERATURE_VALUES ๋ฑ ์ธํ๋ผ/๋ฉํ ์์
์ด๋ฉฐ, scaffold ๊ฐ๋ ๊ธฐ๋ฅ ์์ฒด๋ฅผ ์ง์ ๋ค๋ฃจ๋ ํญ๋ชฉ์ ์์.
๊ฐ์ฅ ๊ทผ์ ํ ๊ฐ์ ์ฐ๊ฒฐ:
- Q-2026-Q3-1 "CI์ pytest + routing test ๋ฑ๋ก" (retro-2026-Q2.md:162): ๋ณธ ๊ฐ๋(_preserves_disulfide/_preserves_scaffold/_mutable_design_positions)์ ๋ํ ์ง์ ๋จ์ ํ
์คํธ๊ฐ ์ ์ฅ์์ ๋ถ์ฌํจ์ ํ์ธ(๊ฒ์ ๊ฒฐ๊ณผ pyrosetta_flow/tests, AG_src/tests, tests ์ ์ด ํจ์๋ช
์ง์ ํธ์ถ ํ
์คํธ ์์ โ ๊ฐ์ ์ค๋ชจํฌ๋ง ์กด์ฌ, test_integration_smoke.py:160). ๋ฐ๋ผ์ ์ด ๊ฐ๋์ ํ๊ท ๋ณดํธ๋ Q3-1 ์ ์ฌ์ ๊ถ์ ๋ค์ด๊ฐ๋, ๋ช
์์ ์ผ๋ก ์ง์ ๋์ง ์์.
์ฐ๋ ๊ด๊ณ: ๋ณธ ๊ฐ๋๋ 2026-06-10 ์ ๋์
(runner.py:120,133, schema.py:15 ์ฃผ์ ๋ ์ง)๋์ด, retro-Q2(2026-Q2 ๋ถ๊ธฐ, CLAUDE.md Stage ์ด๋ ฅ์ 2026-05-11 ์์ฑ)๋ณด๋ค ์ดํ ์์
์ด๋ค. ๋ฐ๋ผ์ retro-Q2 Action Item ๊ณผ๋ ์ง์ ๋ฌด๊ดํ๋ค.
๊ฒฐ๋ก : ์ง์ ์ฐ๊ฒฐ๋๋ Action Item ์์. ์ฌ์ โ (a) ๊ฐ๋ ๋์ (2026-06-10)์ด retro-Q2(2026-05-11) ์ดํ, (b) retro-Q2 ์ 8๊ฑด์ ๋ฉํ/CI/๋ฌธํ ์์ ์ผ๋ก scaffold ๋ณด์กด ๋ก์ง๊ณผ ๋๋ฉ์ธ์ด ๋ค๋ฆ. ๊ธฐ๋ฅ ๋๊ธฐ๋ Action Item ์ด ์๋๋ผ ๋ฉ๋ชจ๋ฆฌ์ ์ ํ์ฑ GOAL(
sstr2-selectivity-goal, 2026-06-10)์ ์์ โ ๋ฌดํ ๋ฐ๊ตด ์์ง์์ ๋ค์ ๋ณ์ด๋ฅผ ์๋ ์์ฑํ ๋ scaffold ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํจ.
โฃ ์์ฑ๋ % + ๊ทผ๊ฑฐ
์์ฑ๋: ์ฝ 85%
๊ทผ๊ฑฐ:
- (+) ํต์ฌ ๋ณด์กด ๋ก์ง 3์ค ๋ฐฉ์ด(์์น ์ ์ธ + ์์ฑ๊ธฐ Cys ๋ฐฐ์ + ์ฌํ ๊ฒ์ดํธ) ๋ชจ๋ ๊ตฌํยท์ฐ๊ฒฐ๋จ โ runner.py:135-138,642-643, adapter.py:10,91.
- (+) ๊ฑฐ๋ถ ์ ์ฌ์๋ยทescalationยทํด๋ฐฑยท์คํจํ์๊น์ง ์๋น โ runner.py:601-679.
- (+) LLM ๊ฒฝ๋ก ํ๋กฌํํธ์๋ ๋์ผ ์ ์ฝ ๋ช
์ธ + few-shot โ prompts.py:445-458,493-505.
- (+) ๋ํน ๋จ๊ณ๊ฐ fail_reason ํ๋ณด๋ฅผ ์ฆ์ 999 ์ฒ๋ฆฌํ์ฌ ์ค์ผ ์ฐจ๋จ โ runner.py:721-732.
- (โ) ์ง์ ๋จ์ ํ
์คํธ ๋ถ์ฌ: _preserves_disulfide/_preserves_scaffold/_mutable_design_positions ๋ฅผ ์ง์ ํธ์ถํ๋ ํ๊ท ํ
์คํธ ๋ฏธ๋ฐ๊ฒฌ(๊ฐ์ ์ค๋ชจํฌ 1๊ฑด๋ง, test_integration_smoke.py:160). C14H ํ๊ท๋ฅผ ๋ช
์ ๋ฐฉ์ดํ๋ ํ
์คํธ๊ฐ ์์ โ ์ฝ -10%.
- (โ) ํ๋กฌํํธโ์ฝ๋ ์์น ๋ช
์ธ ๋ถ์ผ์น: LLM ๊ฒฝ๋ก ๊ฐ๋ณ ์์น([1,2,4,5,6,11,12,13]/14 ํฌํจ)์ ์คํ ๊ฒฝ๋ก design_positions([...,11,12])๊ฐ ๋ค๋ฆ โ prompts.py:255,479 vs schema.py:17 โ ์ฝ -5%.
- (โ) _mutable_design_positions ํด๋ฐฑ(runner.py:139)์ด FWKT/Cys ๋ฅผ ์ฌํฌํจ์ํฌ ์ ์๋ ๊ฒฝ๋ก ์กด์ฌ(๊ฒ์ดํธ๊ฐ ํ๋จ์์ ์ฐจ๋จํ๋ ๋ฐฉ์ด์ ์ค๊ณ ๊ด์ ์์ ๋ฏธ์ธ ๊ฒฐํจ) โ ๋ฏธ๊ฒ์ฆ ์ํฅ, ๊ฐ์ ์.
โค ํ์ ๊ฐ์น (์ / ์ค / ํ)
ํ๊ฐ: ์(้ซ)
๊ทผ๊ฑฐ:
- ํฉํ์ด๋/๋จ๋ฐฑ์ง ์ค๊ณ์์ scaffold ์ ์ฝ(disulfide-constrained, pharmacophore-fixed mutagenesis) ์ ํ์ค์ ์ด๊ณ ํ์ ์ ์ผ๋ก ์ค์ํ ์ค๊ณ ์๋ฆฌ๋ค. ๋ฌด์์/์ ๋ ๋ณ์ด๊ฐ ์ฝ๋ฌผํ์ฑ๋จ(FWKT)๊ณผ ๊ตฌ์กฐ ๊ฒฐ์ ์์(์ดํฉํ๊ฒฐํฉ)๋ฅผ ๋ณด์กดํ๋๋ก ๊ฐ์ ํ๋ ๊ฒ์, ์ค๊ณ ๊ณต๊ฐ์ "์๋ฌผํ์ ์ผ๋ก ์ ํจํ analog" ๋ก ํ์ ํ๋ ํต์ฌ ๋ฉ์ปค๋์ฆ์ด๋ค.
- SST-14 ์ FWKT ๋ SSTR ๊ฒฐํฉ ์ฝ๋ฆฌ๋จ์ผ๋ก ์๋ ค์ ธ ์๊ณ (prompts.py:449,497 ๋ช
์ธ), Cys3-Cys14 ์ดํฉํ๋ ํ์ฑ ํํ(ฮฒ-turn) ์ ์ง์ ํ์ โ ์ด๋ฅผ ์ฝ๋ ๋ ๋ฒจ์์ ๋ถ๋ณ์์ผ๋ก ๋ฐ์ ํ ๊ฒ์ "์ ํจ analog ๋ง ํ๊ฐ" ๋ผ๋ ๋ฐฉ๋ฒ๋ก ์ ์ ๋น์ฑ์ ๋ถ์ฌํ๋ค.
- ๋ณธ ๊ฐ๋๊ฐ ๋ง๋ ๊ฒฐํจ(scaffold ์ ์ฒด์ฑ ๋ถ๊ดด, โก์ C14H ์ฌ๋ก)์ in-silico ์คํฌ๋ฆฌ๋ ๊ฒฐ๊ณผ์ ํ๋น์ฑ(validity) ์ ์ง๊ฒฐ๋๋ฏ๋ก, ๋จ์ ์์ง๋์ด๋ง์ด ์๋ ๊ณผํ์ ๋ฐฉ๋ฒ๋ก ๊ฐ๋์ ์ฑ๊ฒฉ์ ๊ฐ์ง๋ค.
- ๊ฐ์ ์์: ๋ณด์กด ํ์ ์ด "์์น ๋์ผ์ฑ"์ด๋ผ๋ ๋จ์ ๋น๊ต(runner.py:111,123)๋ก, ๋ณด์กด์ ์นํ(conservative substitution)ยท์ดํฉํ ์์(topology) ๊ฒ์ฆ ๊ฐ์ ์ ๊ตํ ๊ตฌ์กฐ ํํ ๊ฒ์ฆ์ ์๋. ์ด๋ ์ ์ ๋จ์ํ์ด๋ "๊ณ ๊ธ ํ์ ๊ธฐ์ฌ"๋ผ๊ธฐ๋ณด๋ค "ํ์ ๊ฑด์ ์ฑ ๊ฐ๋" ์์ค. ๊ทธ๋ผ์๋ ์คํฌ๋ฆฌ๋ ๊ฒฐ๊ณผ ์ ๋ขฐ์ฑ์ ๋ฏธ์น๋ ์ํฅ์ด ์ปค ์ข
ํฉ ์.
โฅ ์ฌ์ฉ๋ฒ (config / ํจ์)
๊ด๋ จ config (FlowConfig, schema.py)
original_sequence(๊ธฐ๋ณธ"AGCKNFFWKTFTSC",schema.py:13) โ Cys ์์นยท์ฝ๋ฆฌ๋จ ์ฌ๋ผ์ด์ค์ ๊ธฐ์ค ์์ด.design_positions(๊ธฐ๋ณธ[1,2,4,5,6,7,8,9,10,11,12],schema.py:14-18) โ ๋ณ์ด ํ๋ณด ํ์ ์์ฒ. ์ฌ๊ธฐ์ FWKTยทCys ๊ฐ ์๋ ์ ์ธ๋จ.max_dedup_trials(๊ธฐ๋ณธ 50,schema.py:40) โ scaffold/dedup ์ฌ์๋ ๋ด์ธต ํ์.max_random_mutations(๊ธฐ๋ณธ 3,schema.py:41) โ ๋์ ๋ณ์ด ์ ์ํ(escalation ์ +1).n_candidates(๊ธฐ๋ณธ 8,schema.py:19) โ iteration ๋น ์์ฑ ํ๋ณด ์.
ํธ์ถ ํ๋ฆ (์๋, runner.py)
run_pyrosetta_agentic_mutdock_flow(config)์ง์ โrunner.py:294.- ๋ณ์ด ๋จ๊ณ์์
mutation_positions = _mutable_design_positions(config)โrunner.py:596. - ํ๋ณด๋ณ ๋ฃจํ์์
generate_guided_mutant(๊ฐ์ด๋ ์์ ๋) ๋๋generate_random_mutantํธ์ถ โrunner.py:613-638. - ์ ์๋ง๋ค
_preserves_scaffold(proposal, config.original_sequence)๊ฒ์ดํธ โrunner.py:642. (์ง์ ํธ์ถํ ๋ณด์กฐ:_preserves_pharmacophore,_preserves_disulfide,_disulfide_cys_positionsโrunner.py:110,119,114)
LLM ์ง์ ๋ณ์ด ์์ฑ (์ ํ์ ๊ฒฝ๋ก)
build_variant_generation_prompt(reference_sequence, mutable_positions, n_mutations, variant_id)โprompts.py:461-532.- ์ต์
์์คํ
ํ๋กฌํํธ:
VARIANT_DESIGN_SYSTEM_PROMPTโprompts.py:445. - ์ฌ์ฉ ์:
provider.generate_json(prompt, system_prompt=VARIANT_DESIGN_SYSTEM_PROMPT)โprompts.py:14-21,485(docstring ์์). ๋จ, โฃ์์ ์ง์ ํ ์์น ๋ช ์ธ ๋ถ์ผ์น ์ ์.
โฆ (Action ๋ฌด๊ด ์) ์ ํ์ํ๊ฐ
๋ณธ ๊ธฐ๋ฅ์ retro-Q2 Action Item ๊ณผ ์ง์ ๋ฌด๊ด(โข)ํ๋ฏ๋ก ํ์์ฑ์ ๋ช ์ํ๋ค.
- ์ ํจ analog ๋ณด์ฅ: ๋ฌดํ ๋ฐ๊ตด ์์ง(๋ฉ๋ชจ๋ฆฌ
sstr2-selectivity-goal,continuous.py)์ ๋งค iteration ๋ค์ ๋ณ์ด๋ฅผ ์๋ ์์ฑํ๋ค. ๊ฐ๋๊ฐ ์์ผ๋ฉด ์๋ ์์ฑ ๊ณผ์ ์์ FWKT/์ดํฉํ๋ฅผ ๊นจ๋ ํ๋ณด๊ฐ ์์ฌ, ๊ฒฐํฉํ์ฑ์ ์์ ๋ถ์๊ฐ "SST-14 analog ํ๋ณด" ๋ก ๋ํนยท๋ญํน์ ์ง์ ํ๋ค. - C14H ํ๊ท์ ์๊ตฌ ์ฐจ๋จ: ์ค์ ๋ก ๊ฐ๋ ๋ถ์ฌ ์ C14โH ๋ณ์ด๊ฐ ํต๊ณผํด SS bond ๊ฐ ๊นจ์ง ์ ๋ก๊ฐ ์๋ค(
runner.py:120-121). ๋ณธ ๊ฐ๋๋ ๊ทธ ํ๊ท๋ฅผ ์ฝ๋ ๋ถ๋ณ์์ผ๋ก ๋ด์ธํ๋ค. - ์ ํ์ฑ ์บ ํ์ธ ์ ๋ขฐ์ฑ: ์บ ํ์ธ ๋ชฉํ๋ SSTR2 ์ ํ์ฑ(ฮmargin>0,
prompts.py:86-95)์ด๋ค. scaffold ๊ฐ ๊นจ์ง ํ๋ณด์ ddG/์ ํ์ฑ ์์น๋ ๋ฌด์๋ฏธํ๋ฏ๋ก, ๊ฐ๋๋ ์ ํ์ฑ ํ์ ์ ์ ๋ ฅ ๊ฑด์ ์ฑ์ ์งํค๋ ์ ์ ์กฐ๊ฑด์ด๋ค.
๊ฒ์ฆ ์ธ์ฉ ๋ชฉ๋ก (file:line)
pyrosetta_flow/runner.py
- :102 โ PHARMACOPHORE_POSITIONS_1IDX = (7, 8, 9, 10)
- :103 โ PHARMACOPHORE_RETRY_LIMIT = 3
- :106-107 โ _pharmacophore_slice (7-10 ์ฌ๋ผ์ด์ค)
- :110-111 โ _preserves_pharmacophore (์ฌ๋ผ์ด์ค ๋์ผ์ฑ)
- :114-116 โ _disulfide_cys_positions (์ฐธ์กฐ Cys ์์น 1-indexed)
- :119-123 โ _preserves_disulfide + docstring "C14โH ๋ณ์ด๊ฐ ํต๊ณผํด SS bond ๊ฐ ๊นจ์ก๋ค"
- :126-129 โ _preserves_scaffold = ์ฝ๋ฆฌ๋จ AND ์ดํฉํ
- :132-139 โ _mutable_design_positions (FWKTยทCys ์ ์ธ + ํด๋ฐฑ)
- :458 โ seen_sequences = {config.original_sequence} (๋ค์ดํฐ๋ธ ์ ์ธ)
- :596 โ mutation_positions = _mutable_design_positions(config)
- :597-687 โ ํ๋ณด ์์ฑ ์ด์ค ๋ฃจํ
- :601 โ ์ฝ๋ฆฌ๋จ ์ฌ์๋ ์ธ์ธต range(PHARMACOPHORE_RETRY_LIMIT + 1)
- :603 โ dedup ๋ด์ธต range(max_trials)
- :605-611 โ ๋ณ์ด ์ escalation
- :613-638 โ guided/random ๋ณ์ด ํธ์ถ
- :640-643 โ ๊ฑฐ๋ถ ๋ถ๊ธฐ(์๋ณธ/์ค๋ณต continue, scaffold ์๋ฐ break)
- :644-646 โ mutant ํ์ + seen ๋ฑ๋ก
- :649-672 โ ํด๋ฐฑ ๊ฒฝ๋ก
- :674-679 โ ์ต์ข
์คํจ fail_reason = "FWKT pharmacophore gate failed after 3 retries"
- :721-732 โ fail_reason ํ๋ณด ddg=999 ์ฒ๋ฆฌ
pyrosetta_flow/schema.py
- :13 โ original_sequence = "AGCKNFFWKTFTSC"
- :14-18 โ design_positions ๊ธฐ๋ณธ๊ฐ + Cys14 ์ ๊ฑฐ ์ฃผ์
- :19 โ n_candidates = 8
- :40 โ max_dedup_trials = 50
- :41 โ max_random_mutations = 3
pyrosetta_flow/adapter.py
- :10 โ AA_NO_CYS = list("ADEFGHIKLMNPQRSTVWY")
- :36-55 โ generate_random_mutant (AA_NO_CYS ์นํ)
- :58-99 โ generate_guided_mutant
- :91 โ ์ถ์ฒ ํ์์ aa != "C" ๋ฐฐ์
- :96 โ ํด๋ฐฑ ํ AA_NO_CYS
AG_src/llm/prompts.py
- :18,255,416,479 โ LLM ๊ฒฝ๋ก ๊ฐ๋ณ ์์น ๋ช
์ธ([1,2,4,5,6,11,12,13] ๋ฑ) โ ์ฝ๋ ๊ธฐ๋ณธ๊ฐ๊ณผ ๋ถ์ผ์น
- :69-71 โ Planner: "PRESERVE FWKT (7-10) and Cys3/Cys14 โ never mutate these"
- :86-95 โ Critic: ์ ํ์ฑ ฮmargin ๋ชฉํ
- :417-442 โ _SST14_FEW_SHOT_EXAMPLES (3/7/8/9/10/14 ๋ณด์กด ์์)
- :445-458 โ VARIANT_DESIGN_SYSTEM_PROMPT (RULE 1ยท2, ๊ฑฐ๋ถ ์กฐ๊ฑด)
- :461-532 โ build_variant_generation_prompt
- :493-505 โ ํ๋กฌํํธ ๋ณธ๋ฌธ RULE ๋ฐ๋ณต
ํ
์คํธ / Action Item
- pyrosetta_flow/tests/test_integration_smoke.py:160 โ disulfide_intact is True ๊ฐ์ ๊ฒ์ฆ
- _workspace/release/retro-2026-Q2.md:158-169 โ Phase E Action Item 8๊ฑด(์ง์ ๋ฌด๊ด)
- _workspace/release/retro-2026-Q2.md:162 โ Q-2026-Q3-1 "CI์ pytest ๋ฑ๋ก"(๊ฐ์ ์ฐ๊ฒฐ)
๋ฏธ๊ฒ์ฆ ํญ๋ชฉ
- _preserves_disulfide/_preserves_scaffold/_mutable_design_positions ์ง์ ๋จ์ ํ
์คํธ ๋ถ์ฌ (์ ์ฅ์ ๊ฒ์ ๊ฒฐ๊ณผ ๋ฏธ๋ฐ๊ฒฌ โ ์ง์ ํธ์ถ ํ
์คํธ ์์, ๊ฐ์ ์ค๋ชจํฌ๋ง ์กด์ฌ)
- _mutable_design_positions ํด๋ฐฑ(runner.py:139) ๋ฐ๋ ์ FWKT/Cys ์ฌํฌํจ ๊ฐ๋ฅ์ฑ์ ์ค์ ์ํฅ (๊ฒ์ดํธ ํ๋จ ์ฐจ๋จ์ผ๋ก ๊ฒฐ๊ณผ ์ํฅ์ ์ฐจ๋จ ์ถ์ )