AI로 챗봇 테스트하다 운영 데이터베이스를 통째로 날렸다 — 원인과 복구의 기록

📚 「AI 헬스케어 파이널 프로젝트」 연재 12편입니다. (11편: AI 에이전트팀에게 챗봇 API를 맡겼더니)

표지

📝 한줄 요약

지난 편까지 만든 의료 챗봇을 진짜 환경(docker)에서 처음부터 끝까지 돌려본 날입니다. 통합에서만 드러나는 문제들을 줄줄이 잡고, “영양 수치를 음식으로 비유하는” 기능까지 추가했는데 — 마지막에 테스트가 운영 데이터베이스를 통째로 삭제하는 사고가 터졌습니다. 다행히 원인을 끝까지 추적해 복구했고, 그 과정이 가장 큰 교훈이 됐습니다.

바쁘시면 이것만 읽어도 돼요:

  • “내 컴퓨터에선 됐는데” 진짜 환경에선 줄줄이 터짐 — 통합 테스트의 진짜 가치
  • AI가 “닭가슴살=단백질 23g”을 지어내지 않도록, 영양 자료 표에 근거해서만 음식 비유
  • 테스트가 운영 DB를 날린 사고 — 원인은 “테스트 설정이 운영 DB를 가리킴”. 로컬에서 통합 테스트를 운영 DB에 돌리면 안 됨
  • 출처가 ‘청크’로 잘못 나온 버그 — 데이터는 멀쩡, 프롬프트의 섹션 제목이 원인. 엉뚱한 데 안 고치고 진짜 원인만 수정
  • AI에게 “왜 사라졌는지 끝까지 추적해줘”라고 하면, 추리하듯 근본 원인을 찾아줌

🎯 이런 분들께 도움돼요

  • AI로 만든 걸 “내 컴퓨터”가 아니라 진짜 환경에서 검증하려는 분
  • AI가 사실을 지어내는(환각) 게 걱정돼서 도입을 망설이는 분
  • 문제가 터졌을 때 AI와 함께 원인을 추적하는 법이 궁금한 분

😫 문제 상황 (Before)

지난 편에서 챗봇 API까지 연결했지만, 그건 어디까지나 부분 부분 테스트였습니다. 실제 사용자처럼 모든 걸 진짜로 띄워놓고 처음부터 끝까지 써본 적은 없었죠. “단위 테스트는 통과했는데, 진짜로 작동할까?”가 풀어야 할 숙제였습니다.

🛠️ 사용한 도구

  • 도구: Claude Code
  • 모델: Claude Opus
  • 특이사항: 진짜 환경(docker)을 띄워 실제 사용자처럼 검증. 새 기능은 브레인스토밍 → 설계 → AI 분업으로 구현

🔧 작업 과정

진짜 환경에 띄웠더니 줄줄이 터졌다 — 통합의 진짜 가치

Phase 5 E2E 검증 시작하자

모든 부품(데이터베이스·검색엔진·AI 작업자·웹서버 등 6개)을 한 번에 띄우자, 부분 테스트에선 안 보이던 문제 3개가 줄줄이 나왔습니다. AI 작업자가 옛날 빈 껍데기로 떠 있거나, 데이터베이스 접속 설정이 빠져 있거나, 예전 폴더가 충돌하거나. 단위 테스트는 다 통과했는데도요.

💡 “부품이 다 멀쩡해도 합치면 안 될 수 있다.” 통합 검증은 부분 테스트로는 절대 못 잡는 문제를 잡습니다. 그래서 진짜 환경에서 돌려보는 게 중요했습니다.

검증 끝에 실제 질문 → 정확한 답변 + 출처 + 면책, 위험 질문(자해·응급) 차단까지 모두 통과했습니다.


프론트엔드 화면 연결 — 백엔드는 한 줄도 안 고쳤다

프런트엔드에 rag챗봇 ui를 만들었는데 그것도 연결해줘

팀원이 만든 챗봇 화면을 백엔드에 연결했는데, 이미 프록시(통로) 설정이 돼 있어서 백엔드 코드를 한 줄도 안 고치고 연결됐습니다. 브라우저에서 직접 챗봇과 대화하는 것까지 확인했죠.


영양 수치를 음식으로 — AI가 ‘지어내지’ 않게

사람들이 g수 쉽게 비교해서 먹기쉽도록 이해하기 쉽게,
g수 및 음식으로 비유해줘. 이게 가능한가?

“단백질 48g”이라고 하면 일반인은 감이 안 오니, “닭가슴살 약 210g”처럼 음식으로 비유하자는 아이디어였습니다. 그런데 여기 함정이 있었습니다. AI가 “닭가슴살은 단백질 23g”이라고 지어내면(환각) 의료 정보로선 위험하니까요.

이때 핵심 해법이 나왔습니다 — AI가 비유를 머릿속에서 만들지 말고, 영양 자료 표를 보고 계산만 하게 하는 거였죠. AI는 답변에 표식만 달고, 별도 단계가 표를 보고 음식으로 환산합니다. 이러면 비유가 “지어낸 것”이 아니라 “자료에 근거한 사실”이 됩니다.

실제로 돌려보니 처음엔 “체중 1kg당 0.8g → 닭가슴살 5g” 같은 무의미한 비유가 나왔는데(너무 적은 양), “일반 성인 기준 하루 총량으로 환산”하도록 고치니 “닭가슴살 약 210g 또는 달걀 약 8개”처럼 현실적인 비유가 됐습니다.

💡 AI의 환각이 걱정되면, “지어내게” 하지 말고 “자료를 보고 계산만” 하게 설계하세요. 같은 AI라도 역할을 어떻게 주느냐에 따라 신뢰도가 완전히 달라집니다.


”안되네” — 사라진 데이터베이스를 추적하다

내가 한번 사용해보려고 하는데 안되네

직접 써보려는데 챗봇이 응답하지 않았습니다. AI에게 원인을 추적시켰더니 — 운영 데이터베이스가 통째로 사라져 있었습니다. 회원 정보, 데이터가 다 날아간 거죠.

“누가 지웠지?”를 끝까지 파고들었습니다. AI가 추리하듯 단서를 모은 결과, 범인은 다름 아닌 제가 조금 전에 돌린 테스트였습니다. 합치기 전에 “자동검사 흉내”를 내려고 테스트를 로컬에서 돌렸는데, 그 테스트 설정이 하필 운영 데이터베이스를 가리키고 있었고, 테스트가 끝나면서 그 DB를 **삭제(drop)**해버린 거였습니다.

복구는 의외로 빨랐습니다. DB를 다시 만들고 → 서버를 재시작하니 표(테이블)가 자동으로 복원되고 → 계정만 다시 만들면 끝. 하지만 교훈은 컸습니다.

💡 로컬에서 “통합 테스트”를 진짜 데이터에 돌리면 안 됩니다. 테스트는 격리된 환경에서 돌게 돼 있는데, 설정이 운영 DB를 가리키면 데이터를 지워버릴 수 있습니다. 이 교훈은 “다시는 반복하지 않게” 따로 기록해뒀습니다.


출처가 ‘청크’로 나왔다 — 엉뚱한 데 안 고치기

출처가 청크로 표시되는건 뭐야?

답변 끝에 [출처: 청크 p.93]처럼 문서명 자리에 “청크”라는 엉뚱한 단어가 나왔습니다. 처음엔 “데이터가 잘못 저장됐나?” 의심했지만, AI와 추적해보니 출처 데이터도, 연결도 전부 정상이었습니다.

진짜 원인은 의외였습니다 — AI에게 주는 지시문에 [출처 청크]라는 섹션 제목이 있었는데, AI가 그 제목을 출처명으로 착각한 거였죠. 그래서 데이터를 건드리지 않고 그 제목 한 줄만 바꿨더니 실제 문서명이 정확히 나왔습니다.

💡 문제가 보이는 곳과 원인이 있는 곳은 다를 수 있습니다. “출처가 이상하다”고 데이터를 뜯어고치는 대신, 진짜 원인(프롬프트의 한 단어)만 찾아 고치는 게 훨씬 안전합니다.


✅ 결과 (After)

Before vs After

항목BeforeAfter
검증 수준부분 테스트만진짜 환경 풀스택(화면→AI→답변) 작동
영양 수치 안내”단백질 48g” (감 안 옴)닭가슴살 약 210g·달걀 8개” (자료 근거 비유)
출처 표기[출처: 청크] (오류)실제 문서명 정확 인용
사고 대응운영 DB 소실 → 원인 규명 + 복구 + 재발방지 기록

결과물

  • 진짜 환경에서 작동하는 의료 RAG 챗봇 (화면 포함)
  • 영양 수치 음식 비유 기능
  • “테스트가 운영 DB를 지운” 사고의 원인·복구·예방 기록

💬 이 과정에서 배운 AI 활용 팁

효과적이었던 것

  1. 진짜 환경에서 검증: 부분 테스트가 다 통과해도 통합에선 문제가 나옴. 실제로 띄워봐야 함
  2. 환각은 설계로 막기: AI가 사실을 “지어내게” 하지 말고 “자료를 보고 계산만” 하게
  3. 원인을 끝까지 추적: “왜 이렇게 됐는지 근본 원인을 찾아줘”라고 하면 AI가 추리하듯 진짜 범인을 찾음

이렇게 하면 안 돼요

  1. 로컬에서 통합 테스트를 운영 데이터에 돌리기: 테스트가 데이터를 지울 수 있음. 격리된 환경에서만
  2. 증상이 보이는 곳을 무작정 고치기: 출처가 이상하다고 데이터를 뜯지 말 것. 진짜 원인을 먼저 찾기

🌍 다른 업무에 적용한다면?

“부분은 다 되는데 합치면 안 되는” 상황은 어디에나 있습니다(여러 부서 데이터 통합, 여러 도구 연동 등). 전체를 한 번에 돌려보는 검증문제 발생 시 AI와 원인 추적은 코드가 아니어도 똑같이 유용합니다. 특히 “진짜 데이터로 실험할 땐 백업·격리부터”는 모든 데이터 작업의 기본이고요.

🚀 앞으로의 계획

이제 챗봇이 진짜 환경에서 작동하니, 다음은 팀원이 보내준 예측 모델을 우리 시스템에 이식하는 일입니다. 콩팥 기능 위험도를 예측하는 모델을 팀원이 따로 학습시켜 노트북(Colab) 파일로 보내줬는데, 이걸 우리 docker 환경에 그대로 옮겨 붙여야 하거든요. 그런데 옮기자마자 파이썬 버전이 안 맞아 전쟁이 벌어집니다. 다음 편에서 그 이야기를 풀어볼게요.

📋 재사용 가능한 프롬프트

프롬프트 1: 진짜 환경 통합 검증

부분 테스트는 통과했는데, 모든 걸 진짜 환경에 한 번에 띄워서 실제 사용자처럼 처음부터 끝까지 작동하는지 검증해줘. 통합에서만 드러나는 문제가 있으면 찾아서 고쳐줘.

프롬프트 2: AI 환각 막는 설계

[수치/사실]을 AI가 머릿속에서 지어내지 말고, [자료/표]에 근거해서만 계산·변환하도록 설계해줘. 자료에 없으면 비워두고, 절대 지어내지 않게.

프롬프트 3: 근본 원인 추적

[증상]이 발생했어. 증상이 보이는 곳을 무작정 고치지 말고, 왜 이렇게 됐는지 단서를 모아서 근본 원인을 끝까지 추적해줘. 원인을 확정한 다음에만 고치자.


📌 「AI 헬스케어 파이널 프로젝트」 연재 12편입니다. 다음 막에서 또 이어집니다.

← 블로그 전체 목록