이 애플리케이션에서는 flask create-index 명령으로 모든 예제 문서의 수집이 트리거됩니다. 이 명령의 구현은 api 디렉토리의 app.py 파일에 있으며,데이터 디렉토리에서 index_data.py 모듈을 가져온 다음 함수를 호출하여 main() data.json 파일에 저장된 모든 문서를 완전히 가져오는 작업을 수행하기만 하면 됩니다.
문서 구조
각 문서의 구조는 다음과 같습니다:
name문서 제목url외부 사이트에서 호스팅되는 문서의 URL입니다.summary문서 내용에 대한 간략한 요약 정보content문서 본문created_on생성 날짜updated_at업데이트 날짜(문서가 업데이트되지 않은 경우 누락될 수 있음)category문서 카테고리(github,sharepoint또는teamsrolePermissions역할 권한 목록
이 예제 애플리케이션에서는 content 필드를 인덱싱할 텍스트로 사용하고 name, summary, url, category 및 updated_at 을 관련 메타데이터로 추가합니다.
다음 Python 코드 스니펫은 문서를 가져오는 방법을 보여줍니다:
여기서는 Python 표준 라이브러리의 json 모듈을 사용하여 데이터 파일을 읽은 다음, 포함된 각 문서에 대해 Langchain의 Document 객체를 생성합니다. 문서에는 벡터로 변환하여 검색할 콘텐츠를 정의하는 page_content 속성과 메타데이터로 저장되는 여러 가지 추가 필드가 있습니다. metadata_keys 은 소스 콘텐츠의 어떤 필드를 문서 메타데이터로 저장할지 결정합니다.
수집 요구 사항에 따라 방법을 세분화하거나 변경할 수 있습니다. Langchain 프로젝트는 소스 콘텐츠의 형식에 따라 사용할 수 있는 다양한 문서 로더를 제공합니다.
Elastic 학습형 스파스 인코더(ELSER) 모델
이 애플리케이션에서 사용되는 Elasticsearch 인덱스는 삽입되는 모든 문서에 대해 스파스 벡터 임베딩을 자동으로 생성하도록 구성되어 있습니다. index_data.py의 install_elser() 함수는 사용 중인 Elasticsearch 인스턴스에 ELSER 모델이 설치 및 배포되었는지 확인합니다.
텍스트 분할
이러한 문서의 content 필드가 길기 때문에 한 번의 임베딩으로는 완전히 표현할 수 없습니다. 많은 양의 텍스트로 작업할 때 표준 솔루션은 텍스트를 짧은 구절로 분할한 다음 개별 구절에 대한 임베딩을 가져와 모두 저장하고 색인을 생성하는 것입니다.
이 애플리케이션에서는 Langchain 라이브러리의 RecursiveCharacterTextSplitter 클래스가 사용되며, OpenAI의 틱토큰 인코더와 결합되어 LLM이 사용하는 것과 동일한 단위인 토큰으로 구절의 길이를 계산합니다.
애플리케이션에서 텍스트 분할이 어떻게 작동하는지 보여주는 다음 예시를 살펴보세요:
텍스트 분할기의 chunk_size 인수를 설정하면 결과 구절의 길이를 제어할 수 있습니다. chunk_overlap 은 구절 간에 어느 정도 겹치는 부분을 허용하므로 더 나은 임베딩을 얻는 데 도움이 되는 경우가 많습니다.
실제 애플리케이션에서 스플리터는 다음 인수를 사용하여 초기화됩니다:
이러한 값을 변경하고 변경 사항이 챗봇의 품질에 어떤 영향을 미치는지 확인할 수 있습니다. 분할기의 구성을 변경할 때마다 flask create-index 명령을 실행하여 인덱스를 다시 생성해야 합니다.
ELSER 모델과 함께 사용하는 텍스트 분할에 대해 알아두어야 할 고려 사항이 더 있습니다. 프로덕션 사용 사례의 경우 이 튜토리얼에서와 같이 다른 토큰화 방법을 선택해야 할 수도 있습니다.
문서 저장소
문서는 Elasticsearch 인덱스에 저장됩니다. 인덱스의 이름은 .env에 정의된 ES_INDEX 환경 변수에 의해 제어됩니다. 파일입니다. 기본적으로 이 인덱스의 이름은 workplace-app-docs 입니다.
이 애플리케이션은 Langchain의 Elasticsearch 통합의 일부인 ElasticsearchStore 클래스를 사용하며 Python용 공식 Elasticsearch 클라이언트 라이브러리를 사용합니다.
Elasticsearch 인덱스를 처리하는 전체 로직은 아래와 같습니다:
ElasticsearchStore.from_documents() 메서드는 workplace_docs 에 저장된 모든 Document 인스턴스를 가져와 index_name 인수에 지정된 인덱스에 기록합니다. 모든 작업은 es_connection 인수에 지정된 클라이언트를 통해 수행됩니다.
strategy 인수는 이 인덱스가 사용되는 방식을 정의합니다. 이 애플리케이션의 경우 SparseVectorRetrievalStrategy 클래스는 각 문서에 대해 스파스 벡터 임베딩을 유지해야 함을 나타냅니다. 그러면 요청된 모델을 통해 임베딩을 생성하는 파이프라인이 인덱스에 추가됩니다(이 경우 ELSER 버전 2).
Elasticsearch와 Langchain의 통합은 사용 사례에 따라 사용할 수 있는 다른 전략을 제공합니다. 특히 고밀도 벡터 임베딩을 사용하는 경우 ApproxRetrievalStrategy를 사용할 수 있습니다.