๊ธฐ๋Šฅ ์ƒ์„ธ ๋ณด๊ณ 

๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ + ํด๋Ÿฌ์Šคํ„ฐ๋ง (A~E tier) โ€” ๊ธฐ๋Šฅ ๋ถ„์„

๋ถ„์„ ๋ฃจํŠธ: AgenticAI4SCIENCE_pyrosetta_track/repos/ai4sci-kaeri ๋Œ€์ƒ ํŒŒ์ผ: - pyrosetta_flow/cluster_report.py (A~E tier ๋ถ„๋ฅ˜, ๊ฒฐ์ •๋ก ์ ) - AG_src/agents/diversity_manager.py (๊ตฌ์กฐ/์„œ์—ด ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ ์—์ด์ „ํŠธ) - AG_src/tools/mcp/foldmason_server.py (FoldMason CLI MCP ๋ž˜ํผ) - AG_src/pipeline/step07_analysis.py (FoldMason ์‹คํ˜ธ์ถœ ๊ฒฝ๋กœ) - ํ˜ธ์ถœ๋ถ€: pyrosetta_flow/runner.py, AG_src/pipeline/orchestrator.py, run_pipeline_live.py, backend/routers/cluster.py ๋ชจ๋“  ์ˆ˜์น˜ยท๋™์ž‘์€ ์†Œ์Šค ์ง๋… ์ธ์šฉ. ๋ฏธํ™•์ธ ํ•ญ๋ชฉ์€ "๋ฏธ๊ฒ€์ฆ" ๋ช…์‹œ.

์ค‘์š”: ๋ณธ ๋ถ„์„์€ ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์‹œ์Šคํ…œ์„ ๋‹ค๋ฃฌ๋‹ค. 1. A~E tier ๋ถ„๋ฅ˜ (cluster_report.py) โ€” ์•ฝ๋ฆฌ/๊ตฌ์กฐ ์ˆ˜์น˜ ์ž„๊ณ„๊ฐ’ ๊ธฐ๋ฐ˜ ๊ฒฐ์ •๋ก ์  5๋ถ„๋ฅ˜. 2. ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ ํด๋Ÿฌ์Šคํ„ฐ๋ง (diversity_manager.py) โ€” ์œ ์‚ฌ ํ›„๋ณด ๊ทธ๋ฃนํ•‘ยท์ค‘๋ณต ์ œ๊ฑฐ. ์ด๋ฆ„์€ ๋‘˜ ๋‹ค "cluster"์ด์ง€๋งŒ ๋ชฉ์ ยท์•Œ๊ณ ๋ฆฌ์ฆ˜ยทtier ์˜๋ฏธ๊ฐ€ ์ „ํ˜€ ๋‹ค๋ฅด๋‹ค (โ‘ข ์ฐธ์กฐ).


โ‘  ๋™์ž‘ ์›๋ฆฌ

1.1 A~E tier ๋ถ„๋ฅ˜ (cluster_report.py)

ํ›„๋ณด 1๊ฑด์„ ์•ฝ๋ฆฌ/๊ตฌ์กฐ ์ˆ˜์น˜ ์ž„๊ณ„๊ฐ’์œผ๋กœ ์šฐ์„ ์ˆœ์œ„ A > B > C > D > E ๋‹จ์ผ ๋ฐฐ์ •ํ•œ๋‹ค (cluster_report.py:24-25, classify_cluster() :252-336). ์™ธ๋ถ€ ์˜์กด ์—†๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜.

tier ์ •์˜ (cluster_report.py:9-22 docstring + ์‹ค์ œ criteria ํ•จ์ˆ˜):

  • A โ€” High Affinity Core (_criteria_a :159-188): ddG โ‰ค -8.0 AND clash_score โ‰ค 5.0 AND pLDDT โ‰ฅ 75 AND FWKT ์ ‘์ด‰ ์œ ์ง€.
  • pLDDT๋Š” ์˜ต์…˜ ์ฒ˜๋ฆฌ: None/0/NaN(ESMFold ๋ฏธ๊ฐ€๋™ PyRosetta-only ๋ชจ๋“œ)์ด๋ฉด ํ•ด๋‹น ๊ธฐ์ค€์„ True๋กœ ์Šคํ‚ต(:177-179) โ€” ๋‚˜๋จธ์ง€ 3๊ธฐ์ค€์œผ๋กœ A ์ž๊ฒฉ ๋ถ€์—ฌ.
  • FWKT ํŒ์ •: structural_rules.rules.fwkt_pharmacophore.pass ๋ถˆ๋ฆฌ์–ธ(_fwkt_contact_maintained :70-87).
  • B โ€” Selectivity-Optimised (_criteria_b :191-206): selectivity_margin โ‰ฅ 3.0 AND ddG < -5.0("SSTR2 binding present"๋กœ operationalize, :201).
  • C โ€” Stability-Enhanced (_criteria_c :209-226): instability_index < 30 AND BLOSUM62 total โ‰ฅ 0 AND protease_sites โ‰ค 9 (SST-14 native baseline _SST14_PROTEASE_BASELINE=9, :56, :220).
  • D โ€” Radiochemistry-Optimal (_criteria_d :229-246): GRAVY โˆˆ [-1.0, +0.5] AND |net_charge_ph74| โ‰ค 1.0 AND chelator site ๊ฐ€์šฉ.
  • chelator ํŒ์ •(_chelator_site_from_candidate :125-153): sequence ์šฐ์„  โ€” N-๋ง๋‹จ non-Pro(ฮฑ-NHโ‚‚) ๋˜๋Š” Lys ์กด์žฌ(ฮต-NHโ‚‚)์ด๋ฉด True. sequence ์—†์„ ๋•Œ๋งŒ metal_coordination.n_strong โ‰ฅ 1 fallback.
  • ์ด๋Š” P2-1 ์ˆ˜์ •(:133-141): ๊ธฐ์กด n_strong ๋กœ์ง์ด SS-bond Cys thiol์„ chelation ๋ถ€์œ„๋กœ ๊ณผ๋Œ€ํ‰๊ฐ€ํ•˜๋˜ ๋ฒ„๊ทธ๋ฅผ ์•ฝ๋ฆฌํ•™ ๊ธฐ์ค€(Krenning 1992; de Jong 2002; Maecke 2005)์œผ๋กœ ๊ต์ฒด.
  • E โ€” Exploratory (:325-336): A~D ๋ฏธ์ถฉ์กฑ ์ „๋ถ€.

๋ฐฐ์น˜ ๋ถ„๋ฅ˜ batch_classify() (:339-381): ํ›„๋ณด๋ณ„ ๋ถ„๋ฅ˜ + tier๋ณ„ ๋ถ„ํฌ ์นด์šดํŠธ/ํผ์„ผํŠธ + tierโ†’์‹๋ณ„์ž ๊ทธ๋ฃน๋งต ๋ฐ˜ํ™˜. ์‹๋ณ„์ž๋Š” nameโ†’sequenceโ†’candidate_{idx} ์ˆœ(:360).

๊ฐ criteria ํ•จ์ˆ˜๋Š” ๊ฐœ๋ณ„ ๋ถˆ๋ฆฌ์–ธ dict๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  all(...) ์œผ๋กœ ํ†ต๊ณผ ํŒ์ • โ€” ์ฆ‰ ์–ด๋А ํ•ญ๋ชฉ์ด ์™œ ๋–จ์–ด์กŒ๋Š”์ง€ ์ถ”์  ๊ฐ€๋Šฅ(criteria_met ํ•„๋“œ, :277,:290 ๋“ฑ).

1.2 ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ (diversity_manager.py โ€” DiversityManagerAgent)

QC ๊ฒŒ์ดํŠธ ํ†ต๊ณผ ํ›„๋ณด๊ฐ€ ์ถฉ๋ถ„ํžˆ ๋‹ค์–‘ํ•œ ๊ตฌ์กฐ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๋Š”์ง€ ๋ณด์žฅํ•˜๊ณ  ์œ ์‚ฌ ํ›„๋ณด ์ค‘๋ณต์„ ์ œ๊ฑฐํ•œ๋‹ค(:1-11, :72-96). ํ†ตํ•ฉ ์œ„์น˜: QC apply_gates() ์ดํ›„ โ†’ ์ตœ์ข… ranking ์ด์ „(:10,:85).

4๊ฐœ ๊ณต๊ฐœ ๋ฉ”์„œ๋“œ:

  • cluster_candidates() (:122-157): ํ›„๋ณด๋ฅผ ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ๊ทธ๋ฃนํ•‘.
  • method="foldmason" AND tool_fn ์ฃผ์ž…๋จ โ†’ _cluster_by_foldmason() (lDDT ํ–‰๋ ฌ greedy).
  • method="hybrid" AND tool_fn โ†’ _cluster_hybrid().
  • ๊ทธ ์™ธ(๋˜๋Š” tool_fn ์—†์Œ) โ†’ _cluster_by_sequence() ์„œ์—ด greedy fallback, ์ด๋•Œ ๊ฒฝ๊ณ  ๋กœ๊ทธ "FoldMason tool ๋ฏธ๋“ฑ๋ก - ์„œ์—ด ๊ธฐ๋ฐ˜ ๊ทผ์‚ฌโ€ฆ"(:151-152).
  • select_diverse_set(clusters, n) (:159-208): โ‘ ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ ๋Œ€ํ‘œ 1๊ฐœ์”ฉ ์„ ํƒ โ†’ โ‘ก๋ถ€์กฑํ•˜๋ฉด ํฐ ํด๋Ÿฌ์Šคํ„ฐ 2๋ฒˆ์งธ ๋ฉค๋ฒ„ ์ถ”๊ฐ€ โ†’ โ‘ขfinal_score ๋‚ด๋ฆผ์ฐจ์ˆœ ๋ฐ˜ํ™˜.
  • compute_diversity_score() (:210-250): ๋ชจ๋“  ํ›„๋ณด์— lDDT ์ฑ„์›Œ์กŒ์œผ๋ฉด diversity = 1 - mean_lDDT(:229-234), ์•„๋‹ˆ๋ฉด ํ‰๊ท  ์„œ์—ด๋™์ผ์„ฑ ๊ธฐ๋ฐ˜ diversity = 1 - mean_identity(:236-250). 1์— ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ๋‹ค์–‘.
  • flag_redundant() (:252-291): final_score ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ๋ณด์กด, ์„œ์—ด๋™์ผ์„ฑ โ‰ฅ threshold(๊ธฐ๋ณธ 0.8, :100)์ธ ๋‚ฎ์€ ์ ์ˆ˜ ์ชฝ์„ ์ค‘๋ณต ํ‘œ์‹œ.

greedy ํด๋Ÿฌ์Šคํ„ฐ๋ง ๊ณตํ†ต ํŒจํ„ด(_cluster_by_sequence :382-419, _cluster_by_foldmason :421-490): final_score ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ โ†’ ๊ณ ๋“์  seed๊ฐ€ ๋Œ€ํ‘œ โ†’ ๋ฏธ๋ฐฐ์ • ํ›„๋ณด ์ค‘ ์œ ์‚ฌ๋„ โ‰ฅ threshold๋ฉด ๊ฐ™์€ ํด๋Ÿฌ์Šคํ„ฐ์— ํก์ˆ˜. ๊ฒฐ๊ณผ๋Š” ํฌ๊ธฐ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ(:155).

์„œ์—ด๋™์ผ์„ฑ์€ ์ •๋ ฌ ์—†๋Š” ์œ„์น˜๋ณ„ ๋‹จ์ˆœ ๋น„๊ต(_sequence_identity :507-521): ์งง์€ ์ชฝ ๊ธฐ์ค€ ๋งค์นญ / ๊ธด ์ชฝ ๊ธธ์ด โ€” ๊ธธ์ด์ฐจ ํŒจ๋„ํ‹ฐ ํฌํ•จ. (์ •๋ ฌ ๋ฏธ์ˆ˜ํ–‰์€ ํ•œ๊ณ„, โ‘ค ์ฐธ์กฐ.)

1.3 FoldMason ๊ตฌ์กฐ ํด๋Ÿฌ์Šคํ„ฐ๋ง โ€” ์‹ค์ œ ํ˜ธ์ถœ ์—ฌ๋ถ€

ํ•ต์‹ฌ ํ™•์ธ ๊ฒฐ๊ณผ: FoldMason ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ž˜ํผ๋Š” 2๊ณณ์— ์กด์žฌํ•˜๋‚˜, DiversityManager ๊ฒฝ๋กœ์—์„œ๋Š” ์‹คํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.

  • foldmason_server.py (MCP ๋ž˜ํผ): easy_msa/compute_lddt/refine_msa/cluster_structures 4ํˆด์„ subprocess.run([foldmason, โ€ฆ])๋กœ ์‹ค์ œ CLI ํ˜ธ์ถœํ•˜๋„๋ก ์ •์˜(:47-69, :265-401). ๋‹จ docstring์ด _compute_lddt/_refine_msa/_cluster_structures๋ฅผ "IMPLEMENTATION SKELETON"์œผ๋กœ ๋ช…์‹œ(:314,:342,:365) โ€” ์‹คํŒŒ์‹ฑ์€ ๋ฏธ๊ฒ€์ฆ. ํŒŒ์ผ ์ƒ๋‹จ๋„ "This is an interface definition"(:11).
  • step07_analysis.py:run_foldmason_alignment() (:186-254): conda run -n <env> foldmason easy-msa โ€ฆ --alignment-type 3Di+AA๋ฅผ ์‹ค์ œ subprocess ํ˜ธ์ถœ(:212-223). ์‹คํŒจ ์‹œ placeholder lDDT(0.0/1.0)๋กœ fallback(:236-237,:247-254). ์ด ๊ฒฐ๊ณผ๋Š” orchestrator์—์„œ Candidate.lddt๋กœ ํ˜๋Ÿฌ๋“ค์–ด๊ฐ(orchestrator.py:1096).
  • ๊ทธ๋Ÿฌ๋‚˜ DiversityManagerAgent์˜ tool_fn(=run_foldmason ์ฝœ๋Ÿฌ๋ธ”)์€ ์–ด๋–ค ํ˜ธ์ถœ๋ถ€์—์„œ๋„ ์ฃผ์ž…๋˜์ง€ ์•Š๋Š”๋‹ค. ์ „ ํ˜ธ์ถœ ์ง€์ :
  • run_pipeline_live.py:1020 DiversityManagerAgent(llm_provider=llm) โ€” tool_fn ์—†์Œ.
  • AG_src/pipeline/orchestrator.py:851 ๋™์ผ โ€” tool_fn ์—†์Œ.
  • runs/run_live_demo.py:747 ๋™์ผ โ€” tool_fn ์—†์Œ. โ†’ ๋”ฐ๋ผ์„œ method="foldmason"์„ ์ง€์ •ํ•ด๋„(run_pipeline_live.py:1021) ํ•ญ์ƒ _cluster_by_sequence() ์„œ์—ด fallback์œผ๋กœ ๋ถ„๊ธฐ(diversity_manager.py:145-153).
  • ์ถ”๊ฐ€๋กœ ํ™˜๊ฒฝ์— foldmason ๋ฐ”์ด๋„ˆ๋ฆฌ ์ž์ฒด๊ฐ€ PATH์— ์—†์Œ(๋ณธ ๋ถ„์„ ์‹œ์  which foldmason โ†’ NOT FOUND). foldmason_server.py:44๋Š” ๋ฏธ๋ฐœ๊ฒฌ ์‹œ ๋ฌธ์ž์—ด "foldmason"๋กœ ํด๋ฐฑ.

์ฆ‰ ํ˜„์žฌ ์šด์˜ ๋‹ค์–‘์„ฑ ํด๋Ÿฌ์Šคํ„ฐ๋ง์€ 100% ์„œ์—ด ๊ธฐ๋ฐ˜์ด๋ฉฐ, ๊ตฌ์กฐ(3Di/lDDT) ํด๋Ÿฌ์Šคํ„ฐ๋ง์€ ์ฝ”๋“œ์ƒ ๊ฐ€๋Šฅํ•˜๋‚˜ ๋น„ํ™œ์„ฑ ์ƒํƒœ๋‹ค(๋ฏธ๊ฒ€์ฆ: foldmason ์„ค์น˜๋œ ๋ณ„๋„ ํ™˜๊ฒฝ ์กด์žฌ ์—ฌ๋ถ€).

1.4 ํŒŒ์ดํ”„๋ผ์ธ ํ†ตํ•ฉ ํ๋ฆ„

  • PyRosetta runner(A~E tier): runner.py:1163-1188 โ€” pharma enrich ํ›„ _batch_classify(cluster_input) ํ˜ธ์ถœ, ๊ฒฐ๊ณผ๋ฅผ candidate manifest entry["cluster"]์— ๋ถ€์ฐฉ. _HAS_CLUSTER and _HAS_PHARMA ๋™์‹œ ๊ฐ€์šฉ ์‹œ์—๋งŒ(:1163), ์‹คํŒจ๋Š” best-effort ํก์ˆ˜(:1187-1188).
  • AG ์—์ด์ „ํŠธ ํŒŒ์ดํ”„๋ผ์ธ(๋‹ค์–‘์„ฑ): orchestrator.py:626-644 โ€” Step05b ์„ ํƒ์„ฑ ์ดํ›„ _invoke_agent("diversity_manager", {docking_results}) โ†’ _adapt_agent_context๊ฐ€ docking_resultsโ†’candidates๋กœ ๋ณ€ํ™˜(:96-105), n_select=config diversity_top_n(๊ธฐ๋ณธ 20). ๊ฒฐ๊ณผ diverse_candidatesโ†’selected_seq_ids ์—ญ๋งคํ•‘(:1045-1054)์œผ๋กœ ํ›„๋ณด ์ถ•์†Œ.
  • ๋ฐฑ์—”๋“œ API: backend/routers/cluster.py:7-27 POST /cluster/classify โ€” batch_classify ์ง์ ‘ ๋…ธ์ถœ, ๋ชจ๋“ˆ ๋ถ€์žฌ ์‹œ 503.

โ‘ก ์˜ํ–ฅ

  • Local optimum ํšŒํ”ผ: ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ๊ฐ€ ์œ ์‚ฌ ์„œ์—ด์„ ํ•œ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋ฌถ๊ณ  ๋Œ€ํ‘œ๋งŒ ๋‚จ๊ฒจ (select_diverse_set), ์‹คํ—˜ ์Šฌ๋กฏ์ด ๊ฑฐ์˜ ๋™์ผํ•œ ํ›„๋ณด๋กœ ์ฑ„์›Œ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค. greedy seed๊ฐ€ final_score ์ตœ์ƒ์œ„๋ผ "์ข‹์œผ๋ฉด์„œ๋„ ์„œ๋กœ ๋‹ค๋ฅธ" ์ง‘ํ•ฉ์„ ์ง€ํ–ฅ.
  • ๋‹จ ๊ตฌ์กฐ ๋‹ค์–‘์„ฑ์ด ์•„๋‹Œ ์„œ์—ด ๋‹ค์–‘์„ฑ๋งŒ ์‹คํšจ(โ‘ขยท1.3) โ†’ ๋™์ผ ์„œ์—ด์˜ ์„œ๋กœ ๋‹ค๋ฅธ backbone/conformer๋Š” ๋‹ค์–‘ํ•˜๋‹ค๊ณ  ์ธ์‹ํ•˜์ง€ ๋ชปํ•จ. local optimum ํšŒํ”ผ๋ ฅ์€ ์ œํ•œ์ .
  • ํ›„๋ณด ๋ถ„๋ฅ˜(triage): A~E tier๊ฐ€ ํ›„๋ณด๋ฅผ ์•ฝ๋ฆฌ/๋ชฉ์ ๋ณ„๋กœ ๋ฌถ์–ด ๋‹ค์šด์ŠคํŠธ๋ฆผ ์šฐ์„ ์ˆœ์œ„์™€ ๋Œ€์‹œ๋ณด๋“œ ํ‘œ์‹œ(runner.py:1190-1209 ์ดํ›„ enrichment)์— ์‚ฌ์šฉ. A=์นœํ™”๋„, B=์„ ํƒ์„ฑ, C=์•ˆ์ •์„ฑ, D=๋ฐฉ์‚ฌํ™”ํ•™, E=ํƒ์ƒ‰์œผ๋กœ ์˜์‚ฌ๊ฒฐ์ •์ž๊ฐ€ ํ›„๋ณด ์„ฑ๊ฒฉ์„ ์ฆ‰์‹œ ํŒŒ์•….
  • ์ค‘๋ณต ์ œ๊ฑฐ ํšจ์œจ: flag_redundant๊ฐ€ ๋™์ผ/์œ ์‚ฌ ํ›„๋ณด ์ค‘ ์ €์ ์ˆ˜ ์ธก์„ ์ œ๊ฑฐํ•ด ๋„ํ‚น/์ •๋ฐ€ํ™” ๋น„์šฉ ์ ˆ๊ฐ(diversity_manager.py:252-291).

โ‘ข ๊ด€๋ จ Action Item

๋ช…์‹œ์ ์œผ๋กœ ๋“ฑ๋ก๋œ Action Item(_workspace ๋‚ด AI-/R๋ฒˆํ˜ธ ๋“ฑ)๊ณผ ๋ณธ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฌธ์„œ๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์Œ(_workspace/CONTINUOUS_DISCOVERY.md์— divers/cluster/ foldmason ๊ด€๋ จ Action Item grep โ†’ ๊ฒฐ๊ณผ ์—†์Œ). ๋”ฐ๋ผ์„œ ์ง์ ‘ ๋ฌด๊ด€์œผ๋กœ ํŒ์ •ํ•˜๋˜, ์•„๋ž˜ ์ฝ”๋“œ ์ž์ฒด์—์„œ ๋“œ๋Ÿฌ๋‚œ ๊ฐญ(์ž ์žฌ Action Item ํ›„๋ณด)์„ ๊ธฐ๋กํ•œ๋‹ค:

  1. (์ž ์žฌ) FoldMason tool_fn ๋ฏธ์ฃผ์ž… โ€” method="foldmason" ์ง€์ •์—๋„ ํ•ญ์ƒ ์„œ์—ด fallback (1.3). ๊ตฌ์กฐ ํด๋Ÿฌ์Šคํ„ฐ๋ง์„ ์‹ค์ œ๋กœ ์“ฐ๋ ค๋ฉด ํ˜ธ์ถœ๋ถ€์—์„œ tool_fn=run_foldmason_alignment ๋“ฑ์„ ์ฃผ์ž…ํ•ด์•ผ ํ•จ. ํ˜„์žฌ ๋ฏธ์—ฐ๊ฒฐ.
  2. (์ž ์žฌ) ๋‘ "cluster" ๊ฐœ๋… ํ˜ผ๋™ ์œ„ํ—˜ โ€” cluster_report(A~E tier)์™€ diversity_manager(๊ตฌ์กฐ ๊ทธ๋ฃน)๋Š” ๋ณ„๊ฐœ์ธ๋ฐ ์ด๋ฆ„ยท๋Œ€์‹œ๋ณด๋“œ ๋ผ๋ฒจ์ด ๋ชจ๋‘ "Cluster" (backend/routers/pipelines.py:59 step07="Cluster", agents.py:44 diversity= "foldmason ํด๋Ÿฌ์Šคํ„ฐ๋ง"). ๋ฌธ์„œ/๋„ค์ด๋ฐ ๋ถ„๋ฆฌ ๊ถŒ์žฅ.
  3. (์ž ์žฌ) foldmason_server skeleton โ€” _compute_lddt/_cluster_structures ํŒŒ์‹ฑ์ด skeleton ํ‘œ๊ธฐ(1.3). ์‹ค TSV ํฌ๋งท ๊ฒ€์ฆ ํ•„์š”.

โ‘ฃ ์™„์„ฑ๋„ % + ๊ทผ๊ฑฐ

๊ตฌ์„ฑ์š”์†Œ ์™„์„ฑ๋„ ๊ทผ๊ฑฐ
A~E tier ๋ถ„๋ฅ˜ (cluster_report.py) ~95% 5 criteria ์ „๋ถ€ ๊ตฌํ˜„, P2-1 chelator ๋ฒ„๊ทธ ์ˆ˜์ • ๋ฐ˜์˜, ๊ฒฐ์ •๋ก ์ , runnerยทAPIยทํ…Œ์ŠคํŠธ(65๊ฐœ test, test_cluster_report.py) ์—ฐ๊ฒฐ. ์ž”์—ฌ: pLDDT ์Šคํ‚ตยทddG operationalize ๋“ฑ ๊ธฐ์ค€์ด spec ๊ทผ์‚ฌ.
๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ โ€” ์„œ์—ด ๊ฒฝ๋กœ ~85% cluster/select/score/redundant 4๋ฉ”์„œ๋“œ + execute ์™„๋น„, orchestratorยทlive ์—ฐ๊ฒฐ. ์ž”์—ฌ: ์„œ์—ด๋™์ผ์„ฑ์ด ์ •๋ ฌ ์—†๋Š” ์œ„์น˜ ๋น„๊ต(:511)๋ผ indel์— ์ทจ์•ฝ.
๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ โ€” FoldMason ๊ตฌ์กฐ ๊ฒฝ๋กœ ~40% _cluster_by_foldmason ๋กœ์ง ์กด์žฌํ•˜๋‚˜ tool_fn ๋ฏธ์ฃผ์ž…์œผ๋กœ ๋น„ํ™œ์„ฑ, ๋ฐ”์ด๋„ˆ๋ฆฌ PATH ๋ถ€์žฌ(1.3). ์ฝ”๋“œ๋Š” ์žˆ์œผ๋‚˜ ์šด์˜ ๋ฏธ๊ฐ€๋™.
FoldMason MCP ๋ž˜ํผ ~60% easy_msa ์‹คํ˜ธ์ถœ ๊ตฌํ˜„, ๊ทธ๋Ÿฌ๋‚˜ lddt/cluster ํ•ธ๋“ค๋Ÿฌ "skeleton" ํ‘œ๊ธฐ(foldmason_server.py:314๋“ฑ), ์ถœ๋ ฅ ํŒŒ์‹ฑ ๋ฏธ๊ฒ€์ฆ.
step07 FoldMason ์ •๋ ฌ ~80% ์‹ค subprocess + ์‹คํŒจ fallback ๊ตฌํ˜„(step07_analysis.py:212-254), lddt JSON ํŒŒ์‹ฑ์€ sidecar ์กด์žฌ ๊ฐ€์ •.

์ข…ํ•ฉ: A~E tier๋Š” ์šด์˜๊ธ‰, ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ๋Š” ์„œ์—ด ๋ชจ๋“œ ํ•œ์ • ์šด์˜๊ธ‰, ๊ตฌ์กฐ ํด๋Ÿฌ์Šคํ„ฐ๋ง์€ ๋ฏธ๊ฐ€๋™.


โ‘ค ํ•™์ˆ  ๊ฐ€์น˜

  • A~E tier: ๋ฐฉ์‚ฌ์„ฑ์˜์•ฝํ’ˆ ํ›„๋ณด๋ฅผ ์•ฝ๋ฆฌ ๋ชฉ์ (์นœํ™”๋„/์„ ํƒ์„ฑ/์•ˆ์ •์„ฑ/๋ฐฉ์‚ฌํ™”ํ•™/ํƒ์ƒ‰)์œผ๋กœ ๋ถ„๋ฅ˜ํ•˜๋Š” ๊ฒฐ์ •๋ก ์  triage๋Š” ๋‹ค๋ชฉ์  ์ตœ์ ํ™” ํ›„๋ณด ํ•ด์„์— ์œ ์šฉ. chelator ํŒ์ •์˜ ์•ฝ๋ฆฌํ•™์  ๊ต์ •(SS-bond Cys ์ œ์™ธ, N-term/Lys ๊ธฐ๋ฐ˜, :142 ๋ฌธํ—Œ ์ธ์šฉ)์€ ๋ฐฉ๋ฒ•๋ก ์ ์œผ๋กœ ์ •์ง.
  • ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ: ๊ตฌ์กฐ ๊ธฐ๋ฐ˜ MSA(FoldMason 3Di) ํด๋Ÿฌ์Šคํ„ฐ๋ง ์•„์ด๋””์–ด๋Š” ์ €์„œ์—ด๋™์ผ์„ฑ ํŽฉํƒ€์ด๋“œ ๋ณ€์ด์ฒด์— ์ ํ•ฉํ•œ ์„ ํƒ. ๋‹จ ํ˜„์žฌ ์‹ค์ธก์€ ์„œ์—ด๋™์ผ์„ฑ ๊ธฐ๋ฐ˜์ด๋ผ ํ•™์ˆ  ์ฃผ์žฅ ์‹œ "๊ตฌ์กฐ ๋‹ค์–‘์„ฑ" ํ‘œํ˜„์€ ๊ณผ์žฅ โ€” ์„œ์—ด ๋‹ค์–‘์„ฑ์œผ๋กœ ํ•œ์ •ํ•ด์•ผ ํ•จ.
  • ํ•œ๊ณ„(์ •์ง์„ฑ): ์„œ์—ด๋™์ผ์„ฑ์ด ์ •๋ ฌ ์—†๋Š” ์œ„์น˜๋ณ„ ๋น„๊ต(_sequence_identity :507-521) โ†’ ๊ธธ์ด ๋ณ€์ดยท์‚ฝ์ž…/๊ฒฐ์‹ค์ด ์žˆ๋Š” ํ›„๋ณด๊ตฐ์—์„œ ์œ ์‚ฌ๋„ ๊ณผ์†Œํ‰๊ฐ€ ๊ฐ€๋Šฅ. compute_diversity_score์˜ lDDT ๋ถ„๊ธฐ๋„ lDDT๊ฐ€ ์ „ ํ›„๋ณด์— ์ฑ„์›Œ์ง„ ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™(:228-229).

โ‘ฅ ์‚ฌ์šฉ๋ฒ•

A~E tier ๋ถ„๋ฅ˜ (๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ):

from pyrosetta_flow.cluster_report import classify_cluster, batch_classify
res = classify_cluster({"sequence": "AGCKNFFWKTFTSC", "ddG": -9.0,
                        "clash_score": 3, "structural_rules": {...}, ...})
# res["cluster"] in {"A".."E"}, res["criteria_met"], res["note"]
batch = batch_classify([cand1, cand2, ...])  # batch["statistics"]["distribution"]

API:

curl -X POST .../cluster/classify -d '{"candidates": [ {...}, {...} ]}'

๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ:

from AG_src.agents.diversity_manager import DiversityManagerAgent
mgr = DiversityManagerAgent(similarity_threshold=0.8, clustering_method="foldmason",
                            tool_fn=run_foldmason)   # tool_fn ๋ฏธ์ฃผ์ž… ์‹œ ์„œ์—ด fallback
out = mgr.execute({"candidates": cand_list, "n_select": 20, "method": "foldmason"})
# out["diverse_candidates"], out["clusters"], out["diversity_report"], out["redundant_ids"]

ํŒŒ์ดํ”„๋ผ์ธ์—์„œ๋Š” ๋ณ„๋„ ํ˜ธ์ถœ ๋ถˆํ•„์š” โ€” runner(A~E)ยทorchestrator(๋‹ค์–‘์„ฑ)์— ์ž๋™ ํ†ตํ•ฉ.


โ‘ฆ ํ•„์š” ์ด์œ 

  • ๋‹ค์–‘์„ฑ ๊ด€๋ฆฌ: ๋ฌดํ•œ ๋ฐœ๊ตด ์—”์ง„์€ ์œ ์‚ฌ ๋ณ€์ด๋ฅผ ๋Œ€๋Ÿ‰ ์ƒ์„ฑํ•˜๋ฏ€๋กœ, ์ค‘๋ณต ํ›„๋ณด๊ฐ€ ์‹คํ—˜ยท๋„ํ‚น ์Šฌ๋กฏ์„ ์ž ์‹ํ•˜๋ฉด ํƒ์ƒ‰ ํšจ์œจ์ด ๊ธ‰๊ฐํ•œ๋‹ค. ๋Œ€ํ‘œ ์„ ํƒยท์ค‘๋ณต ์ œ๊ฑฐ๊ฐ€ local optimum ๊ณ ์ฐฉ์„ ๋Šฆ์ถ”๊ณ  ์ œํ•œ๋œ wetlab ์Šฌ๋กฏ์„ ์„œ๋กœ ๋‹ค๋ฅธ ํ›„๋ณด๋กœ ์ฑ„์šด๋‹ค.
  • A~E tier: ๋‹จ์ผ ์Šค์นผ๋ผ ์ ์ˆ˜๋งŒ์œผ๋กœ๋Š” "์™œ ์ด ํ›„๋ณด๊ฐ€ ์ข‹์€๊ฐ€"๋ฅผ ์„ค๋ช… ๋ชป ํ•œ๋‹ค. ๋ชฉ์ ๋ณ„ tier๊ฐ€ ์˜์‚ฌ๊ฒฐ์ •์ž์—๊ฒŒ ํ›„๋ณด ์„ฑ๊ฒฉ(๊ณ ์นœํ™” vs ์„ ํƒ์  vs ์•ˆ์ • vs ๋ฐฉ์‚ฌํ™”ํ•™)์„ ์ฆ‰์‹œ ์ œ๊ณตํ•ด ๋‹ค๋ชฉ์  trade-off ์˜์‚ฌ๊ฒฐ์ •์„ ์ง€์›ํ•œ๋‹ค.

๊ฒ€์ฆ ์ธ์šฉ ๋ชฉ๋ก

  • A~E tier ์ •์˜/์šฐ์„ ์ˆœ์œ„: cluster_report.py:9-25, :47-53
  • criteria A~D: cluster_report.py:159-188, :191-206, :209-226, :229-246
  • pLDDT ์˜ต์…˜ ์Šคํ‚ต: cluster_report.py:177-179
  • chelator P2-1 ์ˆ˜์ •: cluster_report.py:125-153
  • batch ํ†ต๊ณ„: cluster_report.py:339-381
  • DiversityManager ๋ถ„๊ธฐ(foldmason/hybrid/sequence): diversity_manager.py:145-153
  • tool_fn ๋ฏธ์ฃผ์ž… ์‹œ ๊ฒฝ๊ณ : diversity_manager.py:151-152
  • _cluster_by_foldmason / _cluster_by_sequence: diversity_manager.py:421-490, :382-419
  • select_diverse_set / compute_diversity_score / flag_redundant: diversity_manager.py:159-208, :210-250, :252-291
  • ์„œ์—ด๋™์ผ์„ฑ(์ •๋ ฌ ์—†์Œ): diversity_manager.py:507-521
  • DiversityManager ์ƒ์„ฑ(์ „๋ถ€ tool_fn ์—†์Œ): run_pipeline_live.py:1020, orchestrator.py:851, runs/run_live_demo.py:747
  • live์—์„œ method="foldmason" ์ง€์ •: run_pipeline_live.py:1021
  • FoldMason MCP ์‹ค subprocess + skeleton ํ‘œ๊ธฐ: foldmason_server.py:47-69, :265-401, :11, :314, :342, :365, :44
  • step07 FoldMason ์‹คํ˜ธ์ถœ/fallback: step07_analysis.py:186-254, :212-223, :236-254
  • lddt โ†’ Candidate: orchestrator.py:1096
  • runner A~E ํ†ตํ•ฉ: runner.py:1162-1188
  • orchestrator ๋‹ค์–‘์„ฑ ํ†ตํ•ฉ: orchestrator.py:626-644, :96-105, :1045-1054
  • ๋ฐฑ์—”๋“œ cluster API: backend/routers/cluster.py:7-27
  • ํ™˜๊ฒฝ ํ™•์ธ: which foldmason โ†’ NOT FOUND (๋ณธ ๋ถ„์„ ์‹œ์ )
  • ๋ฏธ๊ฒ€์ฆ: foldmason TSV/JSON ์‹คํŒŒ์‹ฑ ๊ฒฐ๊ณผ, ๋ณ„๋„ conda env์˜ foldmason ์„ค์น˜ ์—ฌ๋ถ€, step07 ์‹คํ–‰ ์‹œ๊ฐ„ยท์‹ค์ œ lDDT ๊ฐ’