LangChain으로 LLM RAG 챗봇 구축 IV

2024. 4. 17. 21:24python/intermediate

2단계: 비즈니스 요구 사항 및 데이터 이해

 

AI 프로젝트 작업을 시작하기 전에 해결하려는 문제를 이해하고 문제 해결 방법에 대한 계획을 세워야 합니다. 여기에는 문제를 명확하게 정의하고, 요구 사항을 수집하고, 사용할 수 있는 데이터와 기술을 이해하고, 이해관계자의 명확한 기대치를 설정하는 것이 포함됩니다. 이 프로젝트에서는 문제를 정의하고 챗봇에 대한 비즈니스 요구 사항을 수집하는 것부터 시작합니다.

 

문제 및 요구 사항 이해

 

당신이 미국의 대규모 병원 시스템에서 일하는 AI 엔지니어라고 상상해 보세요. 이해관계자는 자신이 수집하는 끊임없이 변화하는 데이터에 대한 더 많은 가시성을 원합니다. 그들은 SQL과 같은 쿼리 언어를 이해하거나 분석가에게 보고서를 요청하거나 누군가 대시보드를 구축할 때까지 기다리지 않고도 환자, 방문, 의사, 병원 및 보험 납부자에 대한 임시 질문에 대한 답변을 원합니다.

이를 달성하기 위해 이해관계자는 회사 데이터에 대한 질문에 답할 수 있는 ChatGPT와 유사한 내부 챗봇 도구를 원합니다. 요구 사항을 수집하기 위해 충족한 후에는 챗봇이 답변해야 하는 질문 종류 목록이 제공됩니다.

  • 현재 XYZ 병원의 대기 시간은 얼마나 되나요?
  • 현재 대기 시간이 가장 짧은 병원은 어디입니까?
  • 환자가 청구 및 보험 문제에 대해 불만을 제기하는 병원은 어디입니까?
  • 병원이 깨끗하지 않다고 불평하는 환자가 있나요?
  • 의사와 간호사가 의사소통하는 방식에 대해 환자들이 뭐라고 말했습니까?
  • XYZ 병원의 간호 직원에 대해 환자들이 말하는 것은 무엇입니까?
  • 2023년에 Cigna 납부자 에게 청구된 총 청구 금액은 얼마입니까 ?
  • John Doe 박사는 몇 명의 환자를 치료했습니까?
  • 열려 있는 방문 수는 몇 번이며 평균 방문 기간은 며칠입니까?
  • 평균 방문 기간(일)이 가장 낮은 의사는 누구입니까?
  • 789번 환자의 숙박 비용은 얼마입니까?
  • 2023년에 Cigna 환자를 가장 많이 진료한 병원은 어디입니까?
  • 병원별 응급진료 청구금액은 평균 얼마입니까?
  • 2022년부터 2023년까지 inedicaid 방문이 가장 많이 증가한 주는 어디입니까?

2023년에 Cigna 납부자에게 청구된 총 청구 금액은 얼마입니까? 와 같은 질문에 답할 수 있습니다. SQL과 같은 쿼리 언어를 사용하여 집계 통계를 사용합니다. 결정적으로 이러한 질문에는 하나의 객관적인 답이 있습니다. 사전 정의된 쿼리를 실행하여 이에 답할 수 있지만 이해관계자가 새롭거나 약간 미묘한 질문이 있을 때마다 새 쿼리를 작성해야 합니다. 이를 방지하려면 챗봇이 정확한 쿼리를 동적으로 생성해야 합니다.

병원이 깨끗하지 않다고 불평하는 환자가 있습니까? 또는 의사와 간호사가 의사소통하는 방식에 대해 환자들이 뭐라고 말했습니까? 더 주관적이며 수용 가능한 답변이 많을 수 있습니다. 이러한 종류의 질문에 답하려면 챗봇이 환자 리뷰와 같은 문서를 읽어야 합니다.

궁극적으로 이해관계자는 주관적 질문과 객관적 질문 모두에 원활하게 답변할 수 있는 단일 채팅 인터페이스를 원합니다. 이는 질문이 제시될 때 챗봇이 어떤 유형의 질문을 받고 어떤 데이터 소스에서 가져올지 알아야 함을 의미합니다.

예를 들어, 789번 환자의 체류 비용은 얼마입니까? , 귀하의 챗봇은 답을 찾기 위해 데이터베이스를 쿼리해야 한다는 것을 알아야 합니다. 의사와 간호사가 의사소통하는 방식에 대해 환자들이 뭐라고 말했습니까?, 귀하의 챗봇은 환자 리뷰를 읽고 요약해야 한다는 것을 알아야 합니다.

다음으로, 병원 시스템이 기록하는 데이터를 살펴보겠습니다. 이는 아마도 챗봇을 구축하는 데 가장 중요한 전제 조건일 것입니다.

 

사용 가능한 데이터 탐색

 

챗봇을 구축하기 전에 사용자 쿼리에 응답하는 데 사용할 데이터를 철저히 이해해야 합니다. 이를 통해 가능한 것이 무엇인지, 그리고 챗봇이 쉽게 액세스할 수 있도록 데이터를 구성하는 방법을 결정하는 데 도움이 됩니다. 이 강의에서 사용할 모든 데이터는 종합적으로 생성되었으며, 그 중 대부분은 Kaggle의 인기 있는 의료 데이터세트 에서 파생되었습니다.

실제로 다음 데이터 세트는 SQL 데이터베이스에 테이블로 저장될 가능성이 높지만 챗봇 구축에 집중하기 위해 CSV 파일을 사용하게 됩니다. 이 섹션에서는 각 CSV 파일에 대한 자세한 설명을 제공합니다.

튜토리얼을 계속 진행하기 전에 이 프로젝트의 일부인 모든 CSV 파일을 data/ 폴더에 배치해야 합니다. 자료에서 다운로드하여 data/ 폴더에 넣었는지 확인하세요.

 

병원.csv

 

hospitals.csv 파일에는 회사에서 관리하는 각 병원의 정보가 기록됩니다. 이 파일에는 30개의 병원과 3개의 필드가 있습니다.

  • hospital_id: 병원을 고유하게 식별하는 정수입니다.
  • hospital_name: 병원 이름.
  • hospital_state: 병원이 위치한 주입니다.

기존 SQL 데이터베이스와 스타 스키마에 익숙하다면 hospitals.csv을 차원 테이블로 생각할 수 있습니다. 차원 테이블은 상대적으로 짧으며 팩트 테이블의 데이터에 대한 컨텍스트를 제공하는 설명 정보나 속성을 포함합니다. 팩트 테이블은 차원 테이블에 저장된 엔터티에 대한 이벤트를 기록하며 테이블이 더 긴 경향이 있습니다.

이 경우 hospitals.csv는 병원과 관련된 정보를 기록하지만 이를 사실 테이블에 결합하여 어떤 환자, 의사 및 지불인이 병원과 관련되어 있는지에 대한 질문에 답할 수 있습니다. visits.csv를 탐색해 보면 이는 더욱 명확해집니다.

궁금하다면 Polars와 같은 데이터프레임 라이브러리 사용하는 Polarshospitals.csv의 처음 몇 행을 검사해 보세요. Polars가 가상 환경에 설치되어 있는지 확인 하고 다음 코드를 실행하세요.

 
[ ]:
!pip install polars
 
 
 
[ ]:
import polars as pl
 
HOSPITAL_DATA_PATH = "data/hospitals.csv"
data_hospitals = pl.read_csv(HOSPITAL_DATA_PATH)
 
data_hospitals.shape
 
 
 
[ ]:
data_hospitals.head()
 
 
 

이 코드 블록에서는 Polars를 가져오고, hospitals.csv의 경로를 정의하고, Polars DataFrame으로 데이터를 읽고, 데이터의 모양을 표시하고, 처음 5개 행을 표시합니다. 예를 들어 Walton, LLC 병원의 ID는 2이고 플로리다주 플로리다에 위치해 있음을 보여줍니다.

 

의사.csv

 

physicians.csv 파일에는 병원 시스템에서 일하는 의사에 대한 데이터가 포함되어 있습니다. 이 데이터세트에는 다음과 같은 필드가 있습니다.

  • physician_id: 각 의사를 고유하게 식별하는 정수입니다.
  • physician_name: 의사의 이름입니다.
  • physician_dob: 의사의 생년월일.
  • physician_grad_year: 의사가 의과대학을 졸업한 연도입니다.
  • medical_school: 의사가 의과대학을 다녔던 곳입니다.
  • salary: 의사의 월급을 표시합니다.

이 데이터는 다시 차원 테이블로 간주될 수 있으며 Polars를 사용하여 처음 몇 행을 검사할 수 있습니다.

 
[ ]:
PHYSICIAN_DATA_PATH = "data/physicians.csv"
data_physician = pl.read_csv(PHYSICIAN_DATA_PATH)
 
data_physician.shape
 
 
 
[ ]:
data_physician.head()
 
 
 

코드 블록에서 볼 수 있듯이 physicians.csv에는 의사가 500명 있습니다. physicians.csv의 처음 몇 행을 보면 데이터가 어떤 모양인지 알 수 있습니다. 예를 들어, Heather Smith의 의사 ID는 3이고, 1965년 6월 15일에 태어나 1995년 6월 15일에 의과대학을 졸업하고 NYU Grossman Medical School에 다녔으며 급여는 약 $295,239입니다.

 

payers.csv

 

다음 파일인 payers.csv은 병원에서 환자 방문에 대해 청구하는 보험 회사에 대한 정보를 기록합니다. hospitals.csv와 유사하며 몇 가지 필드가 포함된 작은 파일입니다.

  • payer_id: 각 지불자를 고유하게 식별하는 정수입니다.
  • payer_name: 지급인의 회사명입니다.

데이터에 포함된 유일한 5개 지불자는 Medicaid, UnitedHealthcare, Aetna, Cigna 및 Blue Cross 입니다. 이해관계자는 지불인 활동에 매우 관심이 있으므로 payers.csv가 환자, 병원 및 의사와 연결되면 도움이 될 것입니다.

 

reviews.csv

 

reviews.csv 파일에는 병원에서의 경험에 대한 환자 리뷰가 포함되어 있습니다. 여기에는 다음과 같은 필드가 있습니다.

  • review_id: 리뷰를 고유하게 식별하는 정수입니다.
  • visit_id: 리뷰에 관한 환자의 방문을 식별하는 정수입니다.
  • review: 환자분이 남겨주신 자유 형식의 텍스트 리뷰입니다.
  • physician_name: 환자를 치료한 의사의 이름입니다.
  • hospital_name: 환자가 머물렀던 병원입니다.
  • patient_name: 환자의 이름입니다.

이 데이터 세트는 자유 텍스트 검토 필드가 포함된 첫 번째 데이터 세트이며, 챗봇은 이를 사용하여 검토 세부 사항 및 환자 경험에 대한 질문에 답변해야 합니다.

다음은 다음 reviews.csv과 같습니다.

 
[ ]:
REVIEWS_DATA_PATH = "data/reviews.csv"
data_reviews = pl.read_csv(REVIEWS_DATA_PATH)
 
data_reviews.shape
 
 
 
[ ]:
data_reviews.head()
 
 
 

이 데이터 세트에는 1005개의 리뷰가 있으며 각 리뷰가 방문과 어떻게 관련되어 있는지 확인할 수 있습니다. 예를 들어, ID 9인 리뷰는 방문 ID 8138에 해당하고 처음 몇 단어는 "병원의 팻…"에 대한 약속입니다. 리뷰를 환자에게 연결하는 방법, 더 일반적으로는 지금까지 설명한 모든 데이터 세트를 서로 연결하는 방법이 궁금할 수 있습니다. 이곳이 visits.csv가 등장하는 곳입니다 .

 

visits.csv

 

마지막 파일인 visits.csv은 회사에서 제공한 모든 병원 방문에 대한 세부 정보를 기록합니다. 별표 스키마 비유를 계속하면, visits.csv가 병원, 의사, 환자 및 지불인을 연결하는 팩트 테이블로 생각할 수 있습니다. 필드항은 다음과 같습니다.

  • visit_id: 병원 방문의 고유 식별자입니다.
  • patient_id: 방문과 관련된 환자의 ID입니다.
  • date_of_admission: 환자가 병원에 ​​입원한 날짜입니다.
  • room_number: 환자의 병실번호입니다.
  • admission_type: '선택', '긴급', '긴급' 중 하나입니다.
  • chief_complaint: 환자가 병원에 ​​온 주된 이유를 설명하는 문자열입니다.
  • primary_diagnosis: 의사가 내린 기본 진단을 설명하는 문자열입니다.
  • treatment_description: 의사가 제공한 치료에 대한 텍스트 요약입니다.
  • test_results: '결정적이지 않음', '정상', '비정상' 중 하나입니다.
  • discharge_date: 환자가 퇴원한 날짜입니다.
  • physician_id: 환자를 진료한 의사의 ID입니다.
  • hospital_id: 환자가 입원한 병원의 ID입니다.
  • payer_id: 환자가 사용하는 보험금지급인의 ID입니다.
  • billing_amount: 방문에 대해 지불인에게 청구되는 금액입니다.
  • visit_status: 'OPEN' 또는 'DISCHARGED' 중 하나입니다.

이 데이터 세트는 각 병원 법인 간의 관계에 대한 질문에 답하는 데 필요한 모든 것을 제공합니다. 예를 들어, 의사 ID를 알고 있는 경우 해당 의사가 어떤 환자, 지불인 및 병원과 연관되어 있는지 파악하는 데 visits.csv를 사용할 수 있습니다. Polars와 비슷해 보이는 visits.csv의 모습을 살펴보세요 .

 
[ ]:
VISITS_DATA_PATH = "data/visits.csv"
data_visits = pl.read_csv(VISITS_DATA_PATH)
 
data_visits.shape
 
 
 
[ ]:
data_visits.head()
 
 
 

위에서 설명한 15개 필드와 함께 9998 회의 방문이 기록된 것을 볼 수 있습니다. 방문 시 chief_complaint, treatment_description 및 primary_diagnosis가 누락되었을 수 있습니다. 이해관계자는 많은 방문에서 중요한 데이터가 누락되었다는 사실을 인식하지 못할 수 있으므로 이 점을 명심해야 합니다. 이는 그 자체로 귀중한 통찰력이 될 수 있습니다! 마지막으로, 방문이 아직 진행 중이면 이 discharged_date는 누락됩니다.

이제 이해관계자가 원하는 챗봇을 구축하는 데 사용할 데이터를 이해했습니다. 요약하자면, 기존 SQL 데이터베이스의 모습을 시뮬레이션하기 위해 파일이 분할되었습니다. 모든 병원, 환자, 의사, 리뷰, 지불인은 visits.csv를 통해 연결됩니다.

 

대기 시간

 

XYZ 병원의 현재 대기 시간은 얼마입니까? 와 같은 질문에 답할 수 있는 데이터가 없다는 것을 눈치채셨을 것입니다. 또는 현재 대기 시간이 가장 짧은 병원은 어디입니까? 불행하게도 병원 시스템은 과거의 대기 시간을 기록하지 않았습니다. 챗봇은 현재 대기 시간 정보를 얻기 위해 API를 호출해야 합니다. 나중에 이것이 어떻게 작동하는지 알게 될 것입니다.

비즈니스 요구 사항, 사용 가능한 데이터 및 LangChain 기능을 이해하면 챗봇을 위한 디자인을 만들 수 있습니다.

 

챗봇 디자인

 

이제 비즈니스 요구 사항, 데이터 및 LangChain 전제 조건을 알았으므로 챗봇을 설계할 준비가 되었습니다. 좋은 디자인은 귀하와 다른 사람들이 챗봇을 구축하는 데 필요한 구성 요소에 대한 개념적 이해를 제공합니다. 디자인은 데이터가 챗봇을 통해 어떻게 흐르는지 명확하게 보여야 하며 개발 중에 유용한 참조 역할을 해야 합니다.

챗봇은 여러 도구를 사용하여 병원 시스템에 대한 다양한 질문에 답변합니다. 다음은 이를 수행하는 방법을 보여주는 순서도입니다.

 

병원 시스템 챗봇의 아키텍처 및 데이터 흐름

 

이 순서도는 사용자의 입력 쿼리부터 최종 응답까지 데이터가 챗봇을 통해 이동하는 방식을 보여줍니다. 각 구성 요소를 요약하면 다음과 같습니다.

  • LangChain 에이전트 : LangChain 에이전트는 챗봇의 두뇌입니다. 사용자 쿼리가 주어지면 에이전트는 호출할 도구와 도구에 입력으로 제공할 항목을 결정합니다. 그런 다음 에이전트는 도구의 출력을 관찰하고 사용자에게 무엇을 반환할지 결정합니다. 이것이 에이전트의 응답입니다.
  • Neo4j AuraDB : Neo4j AuraDB 그래프 데이터베이스에 구조화된 병원 시스템 데이터와 환자 리뷰를 모두 저장합니다. 다음 섹션에서 이에 대한 모든 내cnfcjddk용을 배우게 됩니다.
  • LangChain Neo4j Cypher Chain : 이 체인은 사용자 쿼리를 Neo4j의 쿼리 언어인 Cypher로 변환하고 Neo4j에서 Cypher 쿼리를 실행하려고 시도합니다. 그런 다음 체인은 Cypher 쿼리 결과를 사용하여 사용자 쿼리에 응답합니다. 체인의 응답은 LangChain 에이전트로 피드백되어 사용자에게 전송됩니다.
  • LangChain Neo4j 리뷰 벡터 체인 : 이는 환자 리뷰 임베딩이 Neo4j에 저장된다는 점을 제외하면 1단계 에서 구축한 체인과 매우 유사합니다. 체인은 사용자 쿼리와 의미상 유사한 리뷰를 기반으로 관련 리뷰를 검색하고, 리뷰는 사용자 쿼리에 답변하는 데 사용됩니다.
  • 대기 시간 기능 : 1단계의 로직과 유사하게 LangChain 에이전트는 사용자 쿼리에서 병원 이름을 추출하려고 시도합니다. 병원 이름은 대기 시간을 가져오는 Python 함수에 입력으로 전달되고 대기 시간은 에이전트에 반환됩니다.

예를 살펴보기 위해 사용자가 2023년에 긴급 방문이 몇 번 있었나요?라고 묻는다고 가정해 보겠습니다. LangChain 에이전트는 이 질문을 받고 어떤 도구에 질문을 전달할 것인지 결정합니다. 이 경우 에이전트는 LangChain Neo4j Cypher Chain에 질문을 전달해야 합니다. 체인은 질문을 Cypher 쿼리로 변환하고 Neo4j에서 Cypher 쿼리를 실행한 다음 쿼리 결과를 사용하여 질문에 답하려고 시도합니다.

LangChain Neo4j Cypher Chain이 질문에 답변하면 에이전트에게 답변을 반환하고 에이전트는 답변을 사용자에게 전달합니다.

이 디자인을 염두에 두고 챗봇 구축을 시작할 수 있습니다. 첫 번째 작업은 챗봇이 액세스할 수 있도록 Neo4j AuraDB 인스턴스를 설정하는 것입니다.

 

< 출처 : https://realpython.com/build-llm-rag-chatbot-with-langchain/>