SMC(삼성서울병원) 의료진과 챗봇 개발을 진행하며, 이번에 일부 내용을 논문으로 공개하게 되었어요. 이 글에서는 논문에서 다루지 못했던 고민을 함께 나누고자 해요. 현재 공개된 eirene-v1을 기준으로 작성했어요.

삼성서울병원과 문제를 공유해요

연구실 인턴으로 SMC와 함께 의료 챗봇 개발에 참여하게 되었어요. 의료진과의 미팅을 통해 임종을 앞둔 말기암 환자분들을 돕는 시스템이 필요하다는 의견이 나왔어요. 임종을 앞둔 환자분들은 연명의료를 받을지 결정해야 하는데, 갑작스러운 말기암 진단으로 심리적으로 혼란스러울 뿐만 아니라 의료 지식을 이해하고 결정하는 데 어려움을 겪고 있다고 해요. 의료진분들 또한 많은 업무로 인해 모든 환자분들께 충분한 시간을 할애하기 어렵고, 의료 지식을 환자분들이 이해할 수 있는 언어로 설명하는 게 힘들다고 하셨어요. 그래서 말기암 환자분들을 돕기 위한 챗봇의 형태로 시작하기로 의견이 모였어요. 연구실에서는 실제 개발 인원 4명이 참여했고, 크게 의료·심리 지식을 바탕으로 상담 프로토콜을 설계하는 팀과 실제 동작하는 서비스를 개발하는 팀으로 나뉘었어요. 저는 개발을 리드하며 이론을 코드로 구현하는 일을 맡았어요.

구현 예시

개발의 우선순위가 뭘까

이번 개발의 목표는 (1) 빠른 프로토타입 완성과 (2) 멀티에이전트 활용이었어요. 첫 결과물 마감까지 약 한 달 정도의 시간이 있었어요. 한 달 만에 완벽한 서비스를 만들기에는 무리가 있죠. 저는 좋은 엔지니어는 최고의 선택이 아니라 최선의 선택을 해야 한다고 생각해요. 제한된 시간과 인력으로 최선의 결과를 만들기 위해 초기 결정이 중요하다고 판단했어요. ‘빠른 프로토타입 완성’을 위해 어떤 고민을 했는지 다음 챕터에서 자세히 이야기해 볼게요. 두 번째 목표는 멀티에이전트를 활용하는 것이었어요. 처음에 polaris에서 아이디어를 얻었어요. 의료 챗봇은 단순히 듣기 좋은 답변만 하는 게 아니에요. 환자의 상태를 체크하고, 오류 없는 의료 지식을 제공하며, 환자의 자기결정권을 존중하면서 챗봇의 발화가 위험하지 않은지를 검증해야 해요. 이처럼 많은 일을 하나의 시스템이 관리해야 하는데, 단일 LLM이 다루기에는 context가 너무 복잡하고 많아요. 그래서 각 업무를 에이전트에게 분배하여 메인 에이전트가 중요한 context만 관리하도록 하자는 것이 주요 아이디어였어요.

어떤 기술을 사용해야 할까

먼저, 어떤 LLM 모델을 사용할지 결정해야 해요. 의료진과 미팅할 때 환자의 페르소나를 2-3개 제시해 주셨어요. 페르소나는 모두 50대 이상의 한국인 환자였어요. 이를 보고 바로 ClovaX를 떠올렸어요. 한국 문화를 얼마나 잘 반영하는지 개인적으로 테스트한 적이 있어요. GPT, Claude, ClovaX에게 사투리를 하도록 시켰고, 당시 ClovaX가 가장 자연스럽게 사투리를 구사했어요. Tech-report에도 ClovaX가 GPT-4보다 한국 문화 이해 능력이 높다고 보고하고 있죠. 더불어 모든 대화가 한국어로 이루어지기 때문에 ClovaX를 사용하는 것이 토큰 효율도 더 좋을 것으로 판단했어요 (참고). 따라서 당시 ClovaX에서 제공하는 고성능 모델 HCX-005와 고효율 모델 HCX-DASH-002를 함께 사용하기로 했어요.

architecture

다음으로 기술 스택을 결정해야 했어요. 멀티에이전트를 구현하기 위해 Python + Langchain을 사용해야겠다고 생각했어요. 팀원들이 모두 Python에 익숙했고, 높은 자유도를 가지면서 커뮤니티가 큰 패키지는 LangChain만한 게 없었죠. 그렇다면 백엔드 프레임워크는 Python 기반의 FastAPI나 Django 중 하나를 선택해야 해요. 목표가 프로토타입이었기에 POST 요청이 오면 챗봇 답변만 보내주면 됐어요. 그렇기 때문에 admin 패널, 유저 권한 관리 등 기능이 당장 필요하지 않았어요. 게다가 당시 팀원 대부분이 백엔드를 처음 다뤄봤기에 코드 복잡도를 늘리고 싶지 않았어요. FastAPI로 API를 처리하고, API 로직과 에이전트 로직을 잘 분리해두면 팀원들이 코드를 파악하기 더 쉬울 거라 생각했어요. 그래서 최종적으로는 FastAPI를 사용하기로 결정했어요.

사용자 인터렉션을 위해 프론트도 개발해야 했는데, Gradio나 Sveltekit 중 고민했어요. 빠르게 Gradio로 만들 것인지, 조금 더 섬세하게 Sveltekit를 사용할 것인지 고민했죠. 저는 프로토타입이 완성되면 사용자 테스트를 할 거라고 생각하고 있었어요. 그렇다면 챗봇 답변만큼이나 UI는 사용자 만족도를 높이는 데 중요한 요소라고 생각했죠. 예를 들어, 챗봇의 답변이 오래 걸리면 ‘생각 중…‘이라는 문구가 깜박거리면서 작동 중임을 보여주는 등 사소한 경험 말이에요. 그래서 시간이 조금 더 걸리더라도 Sveltekit을 선택했어요. 참고로 JS 프레임워크 중 Svelte를 선택한 건 프론트 개발 인력이 저 혼자였고 제가 가장 익숙한 프레임워크가 Svelte였기 때문이에요.

마지막으로 DB를 선택해야 했어요. 사용자 정보 저장을 위해 RDB가 필요했고, 고민 없이 SQLite를 선택했어요. 이유는 단순해요. 오버엔지니어링을 피하기 위해서죠. 저희는 내부 테스트용 프로토타입을 만들기 때문에 사용자 데이터를 다량으로 저장할 일이 없었어요. 또 RDB 스키마만 잘 정의해두면 다른 DB로 확장하는 건 나중에 해도 늦지 않다고 판단했어요.

memory issue

문제는 Vector DB였어요. 우선 Langchain과 통합 가능한 DB였으면 좋겠고, 로컬에서 실행 가능하며, 참고할 만한 자료가 많았으면 했어요. 이 기준을 만족하는 DB는 Chroma와 FAISS가 있어요. 두 DB 모두 사전 지식이 많지 않았기 때문에 더 빠르다고 알려진 FAISS를 선택했어요 (참고). 지금 와서 생각하면 Chroma가 더 적합한 선택이었을지도 모르겠어요. Chroma는 완성된 관리 시스템에 가깝다면, FAISS는 검색 알고리즘에 더 가까워요. DB로써 작동하기 위해서는 여러 추가 작업이 필요하죠. 이걸 몰라서 이후에 기능을 확장하면서 메모리 문제를 겪기도 했어요. 여러 프로세스가 메모리 자원에 동시 접근하면서 생기는 문제였죠. 대규모 연산이 필요하지 않다면 Chroma를 사용하는 게 더 안전하다는 것을 새로 배웠어요.

의료 챗봇은 뭐가 다를까

앞서 기술에 대해 고민했다면 ‘좋은 의료 챗봇은 뭘까’에 대한 고민도 있었어요. 첫 번째로 의료 챗봇도 사용성이 중요해요. 챗봇의 답변이 한 번에 출력되는 것보다는 Streaming 방식으로 Time to First Token을 낮춰야 하죠. 또 router나 memory(챗봇 기억)처럼 I/O가 자주 발생하는 구간은 비동기로 처리해 CPU가 효율적으로 일하도록 설계했어요.

두 번째로 안정성이 매우 중요해요. ChatGPT 같은 사용 서비스에는 ‘실수를 할 수 있습니다’라는 문구가 있어요. 하지만 의료 챗봇의 실수는 상용 챗봇의 실수보다 훨씬 치명적일 수 있어요. WHO 가이드에서도 안전 장치 설정과 인간 전문가의 감독이 필요하다고 설명하고 있어요. 저희 팀도 RAG를 이용해 환각을 줄이고, 챗봇의 발화나 사용자의 발화를 검토하는 안전 장치를 적용했어요.

세 번째 특징은 ‘자기 노출’이에요. 의료 상담은 환자가 솔직하게 증상이나 감정을 이야기해 줘야 다음 단계로 나아갈 수 있어요. 네이버의 연구는 챗봇의 장기 기억이 자기 노출에 중요한 역할을 한다고 해요. 자세한 내용은 블로그에 올려뒀으니 참고해주세요. 저희 팀은 ClovaX를 사용하고 있었고, 장기 기억 프레임워크로 mem0를 사용하기로 했어요. 그런데 당시 ClovaX가 JSON 출력을 지원하지 않아 mem0 내부 로직과 충돌이 있었어요. 이 문제를 해결하기 위해 mem0의 소스코드 자체를 수정했어요. ClovaX는 문자열 출력 안에 JSON을 포함하도록 했고, mem0는 문자열에서 JSON 정보를 파싱해 원래 구현된 로직을 실행하는 방향으로 수정했어요. 이 기능 덕분에 사용자가 이전에 언급했던 의료 정보나 심리 상태를 반영해 챗봇 답변을 생성할 수 있었어요.

앞으로 어떤 문제를 해결할까

여기까지가 초기 프로토타입 v1에 대한 이야기예요. v2, v3에 대해서는 간단히 이야기해보려 해요. 보다시피 v1의 에이전트 구조는 매우 복잡해요.

에이전트 구성

저희 팀도 이 문제를 인지하고 있었어요. 위 구조는 멀티에이전트보다는 LLM 앙상블에 가까워요. 이 문제를 해결하기 위해 ablation study를 진행했어요. 이후 불필요한 에이전트를 줄여가며 시스템 v3를 완성했어요. v3도 논문으로 공개하기 위해 작업 중이에요. 할 이야기가 많기에 논문이 게재되면 더 자세히 이야기해 볼게요.


* Iphone mockup: Apple iPhone 14 Devices by Jasper Vermeulen is licensed under CC BY 4.0.