본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 03. 19:28

저는 헬스케어 테크 분야에서 일합니다. 제가 임상 문서를 위한 RAG 도구를 만든 이유입니다.

요약

헬스케어 분야의 임상 문서 탐색 효율을 높이기 위해 RAG 기술을 적용한 사례를 소개합니다. 환자 정보의 정확성이 필수적인 의료 환경에서 환각 현상을 방지하기 위한 구체적인 설계 전략을 다룹니다.

핵심 포인트

  • 임상 환경에서는 유창함보다 데이터의 정확성이 최우선임
  • Temperature 0 설정을 통해 모델의 결정론적 응답 유도
  • 시스템 프롬프트를 활용해 컨텍스트 내에서만 답변하도록 제한
  • 문서 추출부터 벡터 DB 저장까지의 RAG 파이프라인 구축

저는 RAG (Retrieval-Augmented Generation, 검색 증강 생성) 애플리케이션을 만들려고 시작한 것이 아닙니다. 제가 계속해서 목격해 온 짜증 나는 문제를 해결하려고 시작했습니다.

저는 벨파스트(Belfast)의 헬스케어 기술 분야에서 시니어 소프트웨어 개발자 (Senior Software Developer)로 일하고 있습니다. 이 직무의 큰 부분은 무엇이 실제로 그들의 속도를 늦추는지 이해하고, 소프트웨어가 어디에서 도움을 줄 수 있는지 파악하는 것입니다. 기술적으로 인상적인 것이 아니라, 진정으로 유용한 것이 무엇인지를 찾는 일입니다.

제가 계속해서 주목한 한 가지는, 문서를 탐색하는 데 많은 시간이 소비된다는 점이었습니다. 문서를 주의 깊고 사려 깊게 읽는 것이 아니라, 그저 탐색하는 데 말이죠. 환자 이름을 찾기 위한 Ctrl+F, 약물 복용량을 찾기 위한 스크롤, 퇴원 요약서(Discharge Summary) 7페이지의 네 번째 단락에 파묻힌 후속 조치 지침을 찾아 헤매는 일 같은 것들 말입니다.

사소하게 들릴 수도 있습니다. 하지만 이를 모든 임상 문서와 모든 근무일에 곱해보면, 그 수치는 빠르게 불어납니다.

해결책으로서 RAG를 생각하기 시작했을 때, 제가 가장 먼저 한 일은 속도를 늦추고 임상 환경에서 "정확성 (Accuracy)"이 무엇을 의미하는지 생각하는 것이었습니다. 왜냐하면 임상 환경에서의 정확성은 대부분의 소프트웨어 문맥에서 의미하는 것과 다르기 때문입니다.

헬스케어 분야 대부분의 AI 데모가 가진 문제점

헬스케어 분야의 대부분의 AI 데모는 다음과 같이 진행됩니다: 문서를 업로드하고, 질문을 던지면, 유창하고 자신감 있는 답변을 얻습니다. 매우 인상적으로 보입니다. 문제는 유창하고 자신감이 있다는 것이 정확하다는 것을 의미하지는 않는다는 점입니다. 언어 모델 (Language Models)은 일관성 있는 텍스트를 생성하도록 최적화되어 있습니다. 모델에게 그대로 맡겨두면, 모델은 공백을 채우고, 추론을 하며, 때로는 마치 실제 답변처럼 읽히는 방식으로 무언가를 지어내기도 합니다.

대부분의 문맥에서 이는 허용 가능한 절충안(Tradeoff)입니다. 하지만 임상 문맥에서는 그렇지 않습니다. 환자의 퇴원 약물, 후속 진료 예약, 기록된 알레르기 정보 등은 이러한 종류의 문서에 보통 무엇이 나타나는지에 기반한 모델의 최선의 추측이 아니라, 실제 문서에서 가져와야 합니다.

그래서 코드 한 줄을 쓰기 전에 저는 두 가지 결정을 내렸습니다:

  1. Temperature 0. 창의성 배제. 결정론적 (Deterministic) 응답만 허용. 모델은 문서에서 답을 찾아내거나, 모른다고 말해야 합니다.
  2. 명시적인 시스템 프롬프트 (System prompt). 모델에게 직접적으로 지시합니다: 제공된 컨텍스트 (Context) 내에서만 답변할 것. 만약 답이 거기에 없다면, 명확하게 그렇게 말할 것. 추측하지 말 것.
    이것들은 복잡한 결정이 아닙니다. 하지만 이 유스케이스 (Use case)에는 올바른 결정이며, 저는 이 결정을 아무도 내리지 않은 수많은 헬스케어 AI 데모들을 보아왔습니다.

RAG가 실제로 작동하는 방식 (과장 없이)

RAG는 검색 증강 생성 (Retrieval-Augmented Generation)의 약자입니다. 아이디어는 간단합니다:
언어 모델 (Language model)에게 질문을 던지고 모델이 학습을 통해 답을 알고 있기를 바라는 대신, 먼저 실제 문서에서 관련 섹션을 검색(Retrieve)한 다음, 검색된 내용만을 바탕으로 답변하도록 모델에게 요청하는 것입니다.

파이프라인은 다음과 같습니다:
문서 (PDF)

텍스트 추출 (Extract text)

청크 (Chunks)로 분할

각 청크를 벡터 (Vector)로 임베딩 (Embed)

벡터 데이터베이스 (Vector database)에 저장

↓ (쿼리 시점)

질문

질문을 벡터로 임베딩

가장 유사한 청크 찾기 (시맨틱 검색, Semantic search)

해당 청크들 + 질문을 LLM에 전달

문서에 근거한 (Grounded) 답변 획득

핵심 단어는 근거가 있다는 것 (Grounded)입니다. LLM은 학습을 통해 당신의 문서에 무엇이 있는지 알지 못합니다. 오직 당신이 검색하여 전달한 내용만을 알 뿐입니다. 만약 답변이 검색된 청크 안에 없다면, 지시를 잘 받은 모델은 당신에게 그 사실을 알려줄 것입니다.

구축하기: 중요한 결정 사항들

청킹 전략 (Chunking strategy)
문서를 청크 (chunk)로 어떻게 나누느냐는 대부분의 튜토리얼이 인정하는 것보다 훨씬 더 중요합니다. 너무 작게 나누면 문맥 (context)을 잃게 됩니다. 예를 들어, 약물 이름과 분리된 약물 복용량 정보는 쓸모가 없습니다. 반대로 너무 크게 나누면 검색 (retrieval)이 부정확해집니다.

저는 500자 크기의 청크와 50자의 중첩 (overlap)을 선택했습니다. 중첩은 매우 중요합니다. 이는 두 청크 사이의 경계가 항상 양쪽의 문맥을 모두 포함하고 있음을 의미하며, 분할 지점에서 의미를 잃지 않도록 해줍니다.

splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", ". ", " ", ""]
)

구분자 (separator)의 계층 구조도 중요합니다. 먼저 문단 경계에서 나누려고 시도하고, 그다음 문장 경계, 그다음 공백 순으로 시도합니다. 문장 중간에서 나누는 것은 최후의 수단입니다.

임베딩 모델 (Embedding model)
저는 OpenAI의 text-embedding-3-small을 사용했습니다. 빠르고 저렴하며 문서 검색에 충분히 훌륭합니다. 복잡한 의학 용어를 다루는 프로덕션 (production) 단계의 임상 시스템이라면 도메인 특화 임베딩 (domain-specific embeddings)을 평가해야 하겠지만, 범용 도구로서는 이것으로 충분합니다.

시스템 프롬프트 (The system prompt)
이 부분이 임상 RAG의 성패를 결정짓는 지점입니다:

system_prompt = (
"당신은 임상 문서에 관한 질문에 답하는 유능한 어시스턴트입니다. "
"제공된 문맥 (context) 내에서만 답변하십시오. 만약 답변이 문맥에 없다면, "
"그 사실을 명확히 밝히십시오. 추측하거나 정보를 지어내지 마십시오. "
"임상 환경에서는 완전성 (completeness)보다 정확성 (accuracy)이 더 중요합니다."
)

마지막 문장인 "완전성보다 정확성이 더 중요하다"는 문장이 매우 큰 역할을 합니다. 이 문장은 모델이 그럴듯해 보이는 답변을 만들어내는 대신 "모르겠습니다"라고 말할 수 있는 권한을 부여합니다. 제 테스트 결과, 이 문장을 포함하는 것이 엣지 케이스 (edge cases)에서의 환각 (hallucinations) 발생률을 낮추는 데 실질적인 차이를 만들어냈습니다.

이 프로젝트를 구축하며 배운 점
지저분한 문서 문제 (messy document problem)는 실제로 존재합니다. 대부분의 RAG 튜토리얼은 깔끔하고 잘 구조화된 PDF를 사용합니다. 하지만 임상 문서 (clinical documents)는 깔끔하거나 잘 구조화되어 있지 않습니다. 형식이 일관되지 않은 스캔된 퇴원 요약지 (discharge summaries), 병원마다 약어가 다른 소견서 (referral letters), 깔끔하게 청킹 (chunking)되지 않는 표가 포함된 가이드라인 등 이 모든 것들이 검색 품질 (retrieval quality)을 저하시킵니다. 이를 더 잘 처리하기 위한 전처리 파이프라인 (pre-processing pipelines)에 대해 고민하기 시작했으며, 프로젝트에 추가할 수도 있습니다.

신뢰도 (confidence)가 중요합니다. 저는 검색된 관련 청크 (relevant chunks)의 개수를 기반으로 간단한 신뢰도 지표를 추가했습니다. 이는 거친 휴리스틱 (heuristic)입니다. 즉, 더 많은 청크가 검색되었다는 것은 질문에 답변할 수 있는 가능성이 높다는 것을 의미하지만, 사용자에게 응답을 얼마나 신뢰해야 하는지에 대한 신호를 제공합니다. 임상적 맥락 (clinical context)에서는 답변 자체만큼이나 원본 문서와 대조하여 검증해야 할 시점을 아는 것이 중요합니다.

UI는 매우 단순해야 합니다. 임상 의료진은 개발자가 아닙니다. 인터페이스를 작동하는 데 기술적 지식이 필요하다면 사용되지 않을 것입니다. Streamlit 앱은 세 가지 상호작용을 가집니다: 파일 업로드, 질문 입력, 답변 읽기. 그게 전부입니다.

코드
이 프로젝트는 GitHub에서 오픈 소스로 공개되어 있습니다: github.com/Monika-Sonnadmath/clinical-rag
자신의 파이프라인 (pipelines)에 임베딩하고자 하는 개발자를 위한 Python API와, 단순히 직접 사용하기를 원하는 모든 사람을 위한 Streamlit 웹 앱이 있습니다.

pip install -r requirements.txt
export OPENAI_API_KEY=sk-...
streamlit run app.py

PDF를 업로드하고, 질문을 하고, 답변을 받으세요. 그것이 전부입니다.

향후 계획 (What's Next)
추가하고 싶은 몇 가지 기능이 있습니다:
• Ollama를 통한 로컬 LLM (Large Language Model) 지원 — API 키 없이 작동하며 문서를 완전히 온프레미스 (on-premises) 환경에 유지할 수 있도록 합니다. 임상 사례 (clinical use cases)의 경우, 데이터가 외부로 유출되는 것은 매우 민감한 문제입니다.
• 다중 문서 질의 (Multi-document querying) — 문서 폴더 전체를 대상으로 한 번에 질문하기
• 더 나은 전처리 (pre-processing) — 품질이 가변적인 스캔 문서를 처리하는 기능. 이는 OCR (Optical Character Recognition) 분야에서는 이미 해결된 문제이지만, 검색 파이프라인 (retrieval pipeline)과의 연결이 필요합니다.
만약 귀하가 헬스케어 테크 분야에서 일하고 계시며, 이 도구를 어떻게 하면 더 유용하게 만들 수 있을지에 대한 의견이 있다면 진심으로 듣고 싶습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0