로봇 치과 수술에 기억을 부여하기: Qwen Cloud 기반의 HELPIT 구축
요약
Qwen Cloud를 기반으로 치과 로봇 수술의 안전성을 높이는 기억 계층 시스템 HELPIT를 소개합니다. 환자의 과거 이력과 유사 사례 데이터를 활용해 수술 전 브리핑을 제공하고, 결정론적 로직을 통해 안전 게이트를 관리합니다.
핵심 포인트
- 환자의 일화적·의미론적 기억을 인출하여 수술 전 브리핑 제공
- LLM의 불확실성을 방지하기 위해 안전 게이트는 결정론적 Python 코드로 구현
- 수술 결과가 자동으로 시스템에 기록되어 다음 시술의 학습 데이터로 활용
- 금기 사항 발견 시 즉각적인 일시 중단 및 에스컬레이션 기능 수행
이 모든 것의 시작이 된 문제
로봇을 이용한 치과 임플란트 수술은 더 이상 공상 과학이 아닙니다. 임플란트 식립 로봇은 이미 임상에서 사용되고 있으며, 서브 밀리미터(sub-millimeter) 단위의 정밀도로 임플란트를 드릴링하고 식립합니다. 하지만 부족했던 것은 정밀도가 아니었습니다. 바로 '기억'이었습니다.
이러한 시스템들은 모두 매번 동일한 방식으로 절차를 시작합니다. 즉, 냉정하게(cold) 시작한다는 것입니다. 로봇은 이 환자가 3년 전 턱 반대편에 임플란트 실패 경험이 있다는 사실을 알지 못합니다. 6개월 전의 골밀도 스캔 결과가 오늘과 달랐다는 사실도 모릅니다. 또한, 정확히 동일한 골밀도 등급과 동일한 임플란트 브랜드를 사용했던 지난 환자가 토크(torque)가 45 Ncm를 초과했을 때 거부율이 30% 더 높았다는 사실도 알지 못합니다. 그러한 지식은 치과의사의 머릿속에 있거나, 아무도 실시간으로 대조 확인하지 않는 종이 차트에 있거나, 혹은 아예 존재하지 않습니다.
그래서 저는 HELPIT를 구축했습니다. HELPIT는 치과의사, 환자 기록, 그리고 로봇 사이에 위치하는 '기억 계층 (memory layer)'으로, 환자 본인의 이력, 수천 명의 유사한 환자들에게 효과적이었던 사례, 그리고 무언가 일어나기 전에 일시 정지(pause) 또는 _중단(stop)_을 명령할 수 있는 엄격한 게이트(hard gate)를 포함한 전체적인 그림 없이는 절차가 시작되지 않도록 차단합니다.
HELPIT가 실제로 하는 일
어떠한 로봇 절차가 시작되기 전, HELPIT는 기억 및 안전 파이프라인 (memory-and-safety pipeline)을 실행하고 치과의사에게 인용된 근거 기반의 브리핑을 전달합니다. 이는 결코 로봇이 스스로 감독 없이 내리는 결정이 아닙니다:
- 기억 인출 (Retrieve memory) — 이 환자에 대한 일화적 기억 (episodic history; 이전 시술, 합병증, 치유 궤적)과 의미론적 기억 (semantic memory; 이 골밀도 클래스에 대한 인구 집단 수준의 결과 패턴)을 병렬로 불러옵니다.
- 게이트 평가 (Evaluate the gate) — 결정론적인 진행 (PROCEED) / 일시 중단 (PAUSE) / 에스컬레이션 (ESCALATE) 결정을 내립니다. 단 하나의 명확한 금기 사항(재료 알레르기, 항응고제 플래그, 스캔 모순 사항)은 다른 요소들이 양호한 종합 점수보다 항상 우선합니다. 이 부분은 모델 호출이 아닌 순수 Python 코드로 작성되었습니다. 그 이유는 아래에서 더 자세히 다룹니다.
- 승인 및 모니터링 (Approve & monitor) — 치과의사가 인용된 브리핑을 검토하고 승인합니다. 모든 단계는 계획에 따라 실시간으로 추적되며, 편차가 발생하면 자동으로 일시 중단됩니다 (또한 감사 추적(audit trail)을 잃지 않고 나중에 잘못 입력된 값을 수정할 수 있는 방법도 제공됩니다).
- 결과 통합 (Consolidate outcomes) — 시술 후 결과가 자동으로 기억에 다시 기록되어, 유사한 해부학적 구조를 가진 다음 환자가 방금 학습된 내용을 통해 혜택을 얻을 수 있습니다.
게이트 자체를 LLM 호출로 처리하지 않는 이유
이것은 제가 가장 강력하게 옹호할 설계 결정입니다. Qwen이 그냥... 결정하게 만드는 것은 쉬운 일이었을 것입니다. 환자의 이력을 읽고, 인구 데이터를 읽고, PROCEED/PAUSE/ESCALATE를 출력하게 하는 것이죠. 하지만 모델이 조용히 틀릴 수 있거나, 재시도(re-roll) 시 답변이 바뀌어 버릴 수 있는 안전 중심의 분기(safety-critical branch)는 제가 출시할 수 있는 성질의 것이 아니었습니다.
대신, gate_evaluator.py는 결정론적(deterministic)입니다:
if has_allergy_or_systemic_flag or has_anatomy_contradiction or risk_score >= settings.gate_risk_escalate_threshold:
gate_result = GateResult.ESCALATE
elif (
...
Qwen의 역할은 그 결정 '주변'의 모든 것입니다. 결정을 설명하는 서사를 작성하고, 근거가 되는 특정 기록을 인용하며, 해부학적 변화(anatomy-drift) 요약을 생성하는 것입니다. 결정 자체는 재현 가능하고 테스트 가능합니다. 저는 모델이 무엇을 출력하든 상관없이, 명확한 금기 사항이 다른 양호한 점수에 의해 가려질 수 없음을 증명하는 것을 목적으로 하는 전체 pytest 파일을 보유하고 있습니다.
Qwen Cloud가 모델별로 실제로 사용되는 방식
저는 기본적으로 하나의 모델이 모든 것을 수행하는 방식을 원하지 않았습니다. 해커톤 식의 "뭐든지 그냥 qwen-plus를 호출해" 식의 방식은 속도도 더 느릴 뿐만 아니라, 각 호출에 실제로 무엇이 필요한지에 대해 덜 정직한 방식이 되었을 것입니다. 따라서 라우팅(routing)은 의도적으로 설계되었습니다:
| 모델 | 용도 | 선정 이유 |
|---|---|---|
qwen3.7-max | 수술 준비 요약 (surgery-ready brief) | 파이프라인에서 단일 호출 중 가장 높은 이해관계가 걸린 생성 호출 — 사용 가능한 가장 깊은 추론 (reasoning) 모델을 사용할 가치가 있음 |
| ... |
해부학적 서사(anatomy narrative)와 수술 요약(surgery brief)은 서로의 출력에 의존하지 않으므로 asyncio.gather를 통해 **동시(concurrently)**에 실행됩니다. 이것만으로도 엔드-투-엔드 게이트 평가(end-to-end gate evaluation) 시간을 두 번의 모델 호출을 순차적으로 쌓는 대신 약 9초 정도로 유지할 수 있습니다.
특히 Qwen3.x에 대해 가장 많은 것을 가르쳐준 버그
(해커톤의 필수 모델 요구 사항을 충족하기 위해) 요약 생성기를 qwen3.7-max로 전환했을 때, 게이트 평가 시간이 조용히 약 9초에서 약 50초로 늘어났습니다. 프롬프트는 동일하고 출력 품질도 동일했지만, 5배 더 느려졌습니다.
원인은 다음과 같습니다: qwen3.x 제품군은 실제 답변을 내놓기 전에 확장된 사고 사슬(chain-of-thought) "생각하기(thinking)\
HELPIT은 7개의 FastMCP 도구 서버(환자 기억(patient memory), 영상(imaging), 절차 추적(procedure tracking), 시맨틱 지식 베이스(semantic knowledge base), 위험 점수 산정(risk scoring), 치과의사 선호도(dentist preferences), 결과 추적(outcome tracking))를 보유하고 있습니다. 이 시스템의 정직한 첫 번째 버전은 이들을 단순히 인프로세스(in-process) 방식의 일반 Python 함수로만 호출했습니다. 즉, @mcp.tool()은 코드를 정리하는 역할 외에는 아무것도 하지 않았습니다. 기능적으로는 맞았지만, 진정한 의미의 "MCP를 사용"하는 것은 아니었습니다.
따라서 이제 두 개의 서버는 실제 독립적인 엔트리포인트(entrypoint)도 갖추고 있습니다:
if __name__ == "__main__":
mcp.run(transport="stdio")
그리고 저는 이를 증명하는 클라이언트 스크립트를 작성했습니다. 이는 실제 프로토콜을 통해, 실행 중인 앱이 사용하는 것과 동일한 라이브 SQLite 데이터베이스를 대상으로 진정한 MCP initialize() 핸드셰이크(handshake), list_tools(), call_tool()을 수행합니다:
async def call_server(module, tool_name, arguments):
params = StdioServerParameters(command=sys.executable, args=["-m", module], cwd=str(REPO_ROOT))
async with stdio_client(params) as (read, write):
...
patient_memory_server를 대상으로 실행하면 웹 앱이 보여주는 것과 동일한 5명의 초기 데이터 환자가 반환됩니다. 즉, 독립적인 MCP 클라이언트와 FastAPI 앱이 완전히 다른 두 가지 전송 방식(transports)을 통해 동일한 기억을 읽어들이고 있는 것입니다.
실제 해부학 구조, 그리고 아무도 요청하지 않은 단순화(decimation) 알고리즘
저는 3D 치아/임플란트 미리보기가 절차적으로 생성된 상자와 구 형태가 아닌, 실제 해부학적 구조이기를 원했습니다. 실제 스캔 모델은 "이것이 치아처럼 보이는가"라는 문제를 즉각적으로 해결해 주었습니다. 하지만 제가 가져온 전체 상악궁(maxillary arch) 모델(퍼블릭 도메인, NIH 3D)은 실제 스캔 데이터에서 바로 가져온 것으로, **34MB 크기에 951,316개의 정점(vertices)**을 가지고 있었습니다. CAD 뷰어에는 적합했지만, 이미 다른 4개의 3D 캔버스를 자동 회전시키고 있는 브라우저 탭에는 적합하지 않았습니다.
three.js의 표준 엣지 콜랩스(edge-collapse) 단순화 도구는 이 메쉬(mesh)를 처리하는 데 20분 이상 소요되었습니다. 그래서 저는 대신 그리드 기반의 정점 클러스터링 단순화기(grid-based vertex-clustering decimator)를 작성했습니다. 메쉬의 경계 상자(bounding-box) 대각선 길이를 기준으로 한 분수 크기의 3D 그리드 셀에 모든 정점을 스냅(snap)시키고, 동일한 셀에 들어오는 모든 정점을 하나로 평균화한 뒤, 기존→신규 매핑을 통해 삼각형 인덱스를 재매핑하고, 퇴화(degenerated)된 요소는 삭제하는 방식입니다:
cell_size = diagonal * 0.0026
cell = tuple(int((v[axis] - bbox_min[axis]) / cell_size) for axis in range(3))
accumulate all vertices sharing a cell, average, remap triangle indices
951,316개 → 128,720개의 정점 (13.5%), 1.9M → 264K 개의 삼각형, 34MB → 13.2MB로 줄였으며, 실행 시간은 수십 분이 아닌 몇 초가 걸립니다. 이 알고리즘이 미묘한 것은 아닙니다. 가장 간단한 공간 해시(spatial hash)일 뿐이지만, 이번 작업에 필요한 기능 면에서 '실제로 합리적인 시간 안에 완료되는 가장 단순한 것'이 '교과서적으로 정확한 간소화기'보다 더 효과적이었습니다.
현재 상태 (Where it stands right now)
- 레이블링된 5명의 환자 평가 환경(eval harness)에서 100% 게이트 정확도, 0% 오탐지(false-PROCEED)율을 달성했습니다. (가장 위험한 실패 모드 — PAUSE 또는 ESCALATE해야 할 환자에게서 발생하는 false PROCEED는 0이 아니면 평가 실행 자체를 중단시킵니다.)
- CI에서 모든 배포에 게이트를 거치는 26개의 pytest 테스트를 갖추고 있으며, 여기에는 실제로 까다로운 SQLAlchemy 버그(JSON 컬럼의 캐시된 리스트를 제자리에서 수정하고 동일한 객체 참조로 재할당하는 것은 ORM의 더티 트래킹(dirty-tracking)에 대해 조용한 No-op입니다. API 응답은 올바르게 보였지만, 데이터베이스 쓰기 작업 자체가 발생하지 않았습니다)에 대한 영구적인 회귀 테스트가 포함되어 있습니다.
- Alibaba Cloud ECS에서 실시간으로 운영 중이며,
main브랜치에 푸시할 때마다 자동으로 재배포됩니다.
다음 계획 (What's next)
- 합성 환자 데이터 대신 실제 EHR(Electronic Health Record) 통합
- 비(非) 치과 영역에서 동일한 에피소드 + 의미론적(semantic) + 게이트 패턴의 두 번째 참조 구현을 통해,
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기