ElasticsearchEmbeddingsCache 통합

ElasticsearchEmbeddingsCache 통합

임베딩을 효율적으로 저장하고 검색할 수 있는 백엔드가 필요할 때가 있어요. RAG 파이프라인에서 문서를 임베딩할 때 매번 계산하는 대신 한 번 계산한 벡터를 캐시해 두고 싶죠. 이럴 때 쓰는 게 Elasticsearch를 백엔드로 하는 ElasticsearchEmbeddingsCache예요.

출처: 공식문서 - ElasticsearchEmbeddingsCache integration

ElasticsearchEmbeddingsCacheByteStore 구현 중 하나로, 여러분의 Elasticsearch 인스턴스를 활용해 임베딩을 효율적으로 저장하고 조회해요. 자세한 기능과 설정은 API 레퍼런스에서 확인할 수 있어요.

준비하기

셋업

ElasticsearchEmbeddingsCache 바이트 저장소를 만들려면 Elasticsearch 클러스터가 필요해요. 로컬에 설치하거나 Elastic 계정을 만들어 쓸 수 있어요.

설치

통합은 langchain-elasticsearch 패키지에 들어 있어요.

pip install -qU langchain-elasticsearch

만들기

바이트 저장소를 만들 때 Elasticsearch URL과 인덱스 이름, 인증 정보 등을 지정해요.

from langchain_elasticsearch import ElasticsearchEmbeddingsCache

# 로컬에서 실행 중인 Elasticsearch 예시 설정이에요.
kv_store = ElasticsearchEmbeddingsCache(
    es_url="https://localhost:9200",
    index_name="llm-chat-cache",
    metadata={"project": "my_chatgpt_project"},
    namespace="my_chatgpt_project",
    es_user="elastic",
    es_password="<GENERATED PASSWORD>",
    es_params={
        "ca_certs": "~/http_ca.crt",
    },
)

namespace는 서로 다른 데이터 간 키 충돌을 막아 주는 구분자 역할을 해요.

사용하기

mset 메서드로 키에 값을 저장해요.

kv_store.mset(
    [
        ["key1", b"value1"],
        ["key2", b"value2"],
    ]
)

kv_store.mget(
    [
        "key1",
        "key2",
    ]
)
[b'value1', b'value2']

삭제는 mdelete 메서드를 쓰면 돼요.

kv_store.mdelete(
    [
        "key1",
        "key2",
    ]
)

kv_store.mget(
    [
        "key1",
        "key2",
    ]
)
[None, None]

임베딩 캐시로 쓰기

다른 ByteStore와 마찬가지로, ElasticsearchEmbeddingsCache 인스턴스는 RAG를 위한 문서 수집 과정에서 영속 캐시(persistent caching)로 쓸 수 있어요.

다만 기본적으로 캐시된 벡터는 검색이 안 돼요. 검색 가능하게 하려면 Elasticsearch 문서를 구성하는 방법을 직접 커스터마이즈해서 색인된 벡터 필드를 추가해야 해요. 클래스를 상속해 매핑과 문서 빌드 메서드를 오버라이드하면 돼요.

from typing import Any, Dict, List


class SearchableElasticsearchStore(ElasticsearchEmbeddingsCache):
    @property
    def mapping(self) -> Dict[str, Any]:
        mapping = super().mapping
        mapping["mappings"]["properties"]["vector"] = {
            "type": "dense_vector",
            "dims": 1536,
            "index": True,
            "similarity": "dot_product",
        }
        return mapping

    def build_document(self, llm_input: str, vector: List[float]) -> Dict[str, Any]:
        body = super().build_document(llm_input, vector)
        body["vector"] = vector
        return body

매핑과 문서 빌드를 오버라이드할 때는 기존 매핑을 그대로 두고 추가적인 수정만 하는 게 좋아요.

API 레퍼런스

ElasticsearchEmbeddingsCache의 모든 기능과 설정은 API 레퍼런스에서 확인할 수 있어요.

더 알아보기 (Learn more)