QueryNormalizer
일상 언어("머리 지끈지끈")를 표준 의학용어("두통")로 자동 변환합니다. BM25 키워드 검색의 재현율 저하를 막아 비전문가도 자연어로 접근할 수 있습니다. 피부질환 의료상담 챗봇 논문을 내과에 응용해 증상 표현→표준 의학용어 매핑(SYMPTOM_PATTERNS)을 설계했습니다. [설계]
내과 데이터를 학습시킨 도메인 특화 AI를 RAG로 구축한 내과 자문 챗봇입니다. 응급 상황을 대비해 Red Flag를 설계했고, 검색과 생성으로 사용자에게 자문을 제공합니다.
총 valid 1,248건을 유형별로 평가했습니다 — 객관식 995 · 단답형 148 · 서술형 105. 아래 점수는 각 유형 표본에서 나온 값입니다. (EM = 정답과 정확히 일치한 비율 · BERTScore·ROUGE-L = 서술 답변의 의미·표현 일치도)
"인터넷 건강정보 이용률 84.4%인 사회에서, 범용 LLM의 감별진단 실패율은 90–100%."
한국보건사회연구원에 따르면 인터넷 건강정보 이용률은 84.4%이며, 이투데이 2021 기준 디지털 헬스케어 수요는 86.8% 늘었습니다. 하지만 병원 챗봇은 예약 안내 중심이고 LLM은 할루시네이션을 제공하며 포털 검색은 사이버콘드리아를 만들어냅니다. "내과 도메인을 학습시키고 안전하게 자문할 수 있도록" LoRA 파인튜닝+하이브리드 RAG+Guardrails로 만들었습니다.
※ 출처 — 인터넷 건강정보 이용률 84.4%: 한국보건사회연구원 · 디지털 헬스케어 수요 86.8%: 이투데이(2021) · 감별진단 실패율 90–100%: 2026 JAMA Network Open(LLM 21종 · 임상 vignette 29개) · LLM 할루시네이션 사례: 보도.
UI/UX부터 LLM Guardrails(위험 출력을 막는 안전장치)까지, 의료 도메인 특성을 설계에 녹인 세 가지 기능입니다.
일상 언어("머리 지끈지끈")를 표준 의학용어("두통")로 자동 변환합니다. BM25 키워드 검색의 재현율 저하를 막아 비전문가도 자연어로 접근할 수 있습니다. 피부질환 의료상담 챗봇 논문을 내과에 응용해 증상 표현→표준 의학용어 매핑(SYMPTOM_PATTERNS)을 설계했습니다. [설계]
BYPASS 13개 정규식(심근경색·뇌졸중 등) 감지 즉시 LLM·RAG를 완전히 건너뛰고 119·응급실 가이드를 반환합니다. RED_FLAG 37개 키워드는 배너 경고를 띄운 뒤 정상 처리합니다. PostFilter가 단정형 어미를 권유형으로 바꿉니다.
채팅 종료 후 의심 질병·참조 데이터·증상 목록·병원 안내(카카오맵)를 의사 전달용 리포트로 만듭니다. PostFilter가 면책 조항을 자동으로 붙입니다.
컴퓨팅 제약·검색 품질·의료 안전, 세 병목을 각각 코드로 해결한 기록입니다.
Qwen2.5-7B-Instruct(76.1억 파라미터)는 당시 컴퓨팅으로 Full Fine-Tuning이 불가능했습니다.
QLoRA — LoRA(모델을 가볍게 미세조정하는 기법 · r=16)에 4-bit 양자화(nf4)를 더해(train_config.yaml) 단일 GPU에서 도메인을 적응시켰습니다. 학습 데이터는 OpenAI API로 CoT(Chain-of-Thought, 단계별 추론 과정을 명시하는 기법) 전처리했습니다. instruction = "주어진 임상 문제 및 환자 상태를 분석하여, 최적의 진단/처치 또는 의학적 근거를 논리적인 추론 과정과 함께 서술하시오." Raw {question, answer} → PreCleaned {instruction, input, output: [상황 및 핵심 파악]→[의학적 추론 및 근거]→[최종 결론]} 3단 구조로 재구성했습니다. 평가: 객관식 EM(정답과 정확히 일치한 비율) 0.71 (Mode C) [실측-발표자료]
초기 FAISS 기반 밀집 검색은 의학 전문용어의 형태 변형에 취약했습니다. 메타데이터 관리와 확장성도 부족했습니다.
ChromaDB로 전환 후 BM25Okapi+Kiwi 형태소와 α=0.5 가중치로 Hybrid Retrieval(키워드 검색과 의미 검색을 합친 방식)을 구성했습니다. QueryNormalizer로 일상어→표준 의학용어를 매핑해 27,000 chunk [설계]에서 재현율과 접근성을 함께 확보했습니다.
응급 상황에서 LLM 응답이 그대로 나가거나 단정적 진단 표현이 출력되면 법적·의료적 위험이 생깁니다.
Guardrails 3층 구조를 코드로 구현했습니다. ① BYPASS 13 정규식 → Emergency Exit(119 안내, LLM 완전 우회) ② RED_FLAG 37 키워드 → 경고 배너 표시 후 정상 처리 ③ PostFilter → 단정형 어미를 권유형으로 변환하고 면책 조항을 자동 삽입합니다. [설계]
사용자 쿼리가 Guardrails·검색·생성 파이프라인을 거쳐 검증된 응답으로 나오는 구조입니다.
| Stage | 질문 유형 | max_len | batch | learning rate | epoch |
|---|---|---|---|---|---|
| Stage 1 | 단답형 | 560 | 4 | 0.002 |
2 |
| Stage 2 | 서술형 | 730 | 2 | 0.001 |
2 |
| Stage 3 | 객관식 | 840 | 2 | 0.0005 |
2 |
면책 동의 없이는 시작할 수 없습니다(Step -1). 연령·성별 버튼 입력(Step 0). 증상 자연어 채팅 + RedFlag 배너(Step 1). 의사용 문진 요약 리포트(Step 2). 알려줄고양 고양이 페르소나가 온보딩 친근 톤("~다냥")↔결과 전문 톤으로 전환합니다.
요청이 들어오면 Guardrails(BYPASS→Emergency Exit / RED_FLAG→배너)가 먼저 판단합니다. 통과하면 RetrievalService(Dense+BM25 Hybrid·QueryNormalizer)→GenerationService(OpenAI/Qwen+LoRA) 순으로 처리하고 PostFilter가 어미를 교정합니다.
3,447 내과 문서(약 1,229만 자)를 size500/overlap50으로 청킹해 ChromaDB에 저장했습니다. ko-sroberta-multitask(768차원) 밀집 검색 + Kiwi 형태소 BM25 키워드 검색을 α=0.5로 합쳐 의학 전문용어 재현율을 보강합니다.
동일 평가셋(valid 1,248)에서 변수(RAG·LoRA)를 하나씩 추가해 각 설계 선택의 독립 기여도를 분리했습니다.
| Mode | 구성 | 객관식 EM valid 995 |
서술형 BERT valid 105 |
서술형 Rouge-L valid 105 |
단답형 EM 전 모드 |
|---|---|---|---|---|---|
| Mode A | LLM 단독 | 0.69 | 0.70 | 0.12 | 0.05 — 지표 한계 |
| Mode B | LLM + RAG | 0.67 | 0.69 | 0.11 | 0.06 — 지표 한계 |
| Mode C | LoRA + RAG | 0.71 (+0.02) | 0.73 (+0.03) | 0.14 (+0.02) | 0.06 — 지표 한계 |
RedFlag 2단 안전장치(긴급/경고)와 싱글·멀티턴을 실제 시연한 4개 시나리오.
BYPASS 정규식 감지 → LLM·RAG 건너뛰고 119·응급실 즉시 안내(Emergency Exit).
RED_FLAG 키워드 → 경고 배너 표시 후 정상 자문 진행.
단일 질의 자문 — Hybrid RAG 검색 + 권유형 어미.
다중턴 문진 → 의사용 문진 요약 리포트.
부트캠프 팀 프로젝트 1(멀티홉)에서 같은 하이브리드 검색 설계 사고를 다른 도메인에 구현했습니다. ChromaDB 밀집 검색 단독으로는 홉 깊이가 깊어질수록 의미론적 오류가 급증합니다. 이를 데이터로 확인하고 BM25+ProgramFC 하이브리드로 전환한 근거를 만들었습니다.
두 프로젝트 모두 "하이브리드 검색으로 검색 품질을 보강하고, 단계별 Guardrails(RedFlag / Unknown Guard)로 오류 전파를 차단한다"는 같은 검증 설계 사고를 공유합니다.
팀장 · 검색 모듈(BM25+하이브리드 리트리버) 담당.
멀티홉에서 확인한 벡터 검색 단독의 한계를, 의료챗봇 BM25+ChromaDB 하이브리드 설계에 직접 반영했습니다. 같은 방법론을 다른 도메인에 이식한 사례입니다. RAG(검색해서 그 내용으로 답하는 구조)를 단계별로 분해해 평가하는 관점이 두 프로젝트를 관통합니다.
현재 한계와 다음 단계를 기록합니다.
한↔영 의학용어 표기 차이(예: "두통" vs "headache")로 EM(정답과 정확히 일치한 비율) 자체가 낮게 측정됩니다. 동일 개념을 한영으로 혼재 표기하면 엄격 일치 채점이 정답을 오답으로 처리합니다. 이를 보완하기 위해 채점용 한영 Dictionary를 생성해 분석했습니다. 발표자료도 과대포장 없이 그대로 노출했습니다.
→ 의학용어 사전 확장 + Fuzzy Match(edit distance 기반) 또는 BERT Score(문장 의미 유사도 점수) 대체 평가로 개선할 수 있습니다. 엄격 EM이 과소평가하는 구조를 인지하고 eval 개선 시 반영할 예정입니다.현재 파이프라인은 하이브리드 검색(BM25+Dense) 결과를 LLM에 바로 넘깁니다. Reranker(검색 결과를 다시 정밀하게 정렬하는 모듈)가 없어 상위 k개 청크 중 노이즈가 섞일 수 있습니다.
→ 다음 파이프라인 개선 시 cross-encoder Reranker 삽입 예정. 현재 단계에선 미구현.현재 eval은 EM·BERT Score(문장 의미 유사도 점수)·Rouge-L로 생성 품질만 측정했습니다. "검색된 컨텍스트가 생성에 얼마나 충실히 반영됐는가(faithfulness, 생성된 답이 근거 문서에 충실한 정도)"와 "관련 컨텍스트를 얼마나 찾았는가(context recall)"는 측정하지 못했습니다.
→ 향후 파이프라인 개선 시 RAGAS 측정 적용 예정. 이 갭을 인식하는 것 자체가 eval 설계 역량의 일부입니다.현재 27,000 chunk 데이터는 내과 Q-A 쌍입니다. 외과·정신과 등 타 진료과로 확장하려면 도메인별 데이터와 Guardrails를 다시 구성해야 합니다.
→ 진료과별 데이터 파이프라인 모듈화 방향발표자료로 질문 유형별 점진 학습 순서를 확정했습니다. Stage 1(단답형 · max_len 560 · lr 0.002) → Stage 2(서술형 · 730 · 0.001) → Stage 3(객관식 · 840 · 0.0005). max_len을 단계마다 늘리고 lr을 줄이는 점진 커리큘럼으로, 짧고 명확한 유형 먼저 학습 후 복잡 유형으로 전환했습니다. 전 단계 QLoRA(LoRA r=16 · 4-bit nf4) 동일 적용.
→ 발표자료로 확정. 아키텍처 섹션 커리큘럼 표 참조.현재 성능으로 리팩토링이 가능합니다. 재측정 후 위 수치를 갱신할 예정입니다.
→ 리팩토링 완료 후 수치 일괄 갱신무엇을 학습시키고 검색시켰는지 출처와 함께 밝힙니다. [실측-AI-Hub] 원본 데이터를 재배포하지 않으며, 본 포트폴리오는 설계·방법·결과만 공개합니다(clean-room).
AI-Hub 데이터셋 번호 71875
과학기술정보통신부·한국지능정보사회진흥원(NIA) 구축, 가톨릭대학교 산학협력단 주관. 서울성모·삼성서울·서울대·세브란스·보라매병원 참여. 내과 도메인 질의응답 쌍 수록.
AI-Hub 데이터셋 번호 71874
동일 구축 주관(과학기술정보통신부·NIA·가톨릭대학교 산학협력단). 의학 교과서·학회 가이드라인·온라인 의료 정보를 원천으로 하는 의학 말뭉치 수록. RAG 청킹 원천.
내과 도메인 질의응답 12,781쌍을 train / valid(10,299 / 1,248)로 분할·CoT(Chain-of-Thought, 단계별 추론 과정을 명시하는 기법) 전처리 후 LoRA(가볍게 미세조정하는 기법) 학습에 사용했습니다.
원천 의학 말뭉치(의학 교과서·학회 가이드라인·온라인 의료 정보)를 청킹 → RAG(검색해서 그 내용으로 답하는 구조) 약 27,000 chunk 구성. 학술 논문·기타(동의서 등)는 미사용.
AI-Hub 보건의료 데이터로 안심존(보안구역) 개방 방식으로 제공됩니다(연구·개발 목적, IRB·내국인 신청 기반).
원본 데이터는 재배포하지 않습니다. 본 포트폴리오는 해당 데이터를 활용한 설계·방법·결과만 공개합니다. 공개 데이터를 활용한 프로젝트입니다.
LoRA·하이브리드 RAG·Guardrails를 결합해 "안전하게 자문하는" 공백을 채웠습니다. 3원 통제 실험으로 각 설계 선택의 기여도를 분리해 측정했습니다.