Important
Une couche de mise en cache pour les LLM qui exploite Elasticsearch, entièrement compatible avec la mise en cache de Langchain, à la fois pour les modèles de chat et d'intégration.
pip install llm-elasticsearch-cacheLe cache Langchain peut être utilisé de manière similaire aux autres intégrations de cache.
from langchain . globals import set_llm_cache
from llmescache . langchain import ElasticsearchCache
from elasticsearch import Elasticsearch
es_client = Elasticsearch ( hosts = "http://localhost:9200" )
set_llm_cache (
ElasticsearchCache (
es_client = es_client ,
es_index = "llm-chat-cache" ,
metadata = { "project" : "my_chatgpt_project" }
)
) Le paramètre es_index peut également prendre des alias. Cela permet d'utiliser l'ILM: gérer le cycle de vie de l'index que nous suggérons de considérer pour gérer la rétention et contrôler la croissance du cache.
Regardez la classe docstring pour tous les paramètres.
Les données mises en cache ne seront pas consultables par défaut. Le développeur peut personnaliser la construction du document Elasticsearch afin d'ajouter des champs de texte indexés, où mettre, par exemple, le texte généré par le LLM.
Cela peut être fait en sous-classement des méthodes de remplacement des extrémités. La nouvelle classe de cache peut également être appliquée à un indice de cache préexistant:
from llmescache . langchain import ElasticsearchCache
from elasticsearch import Elasticsearch
from langchain_core . caches import RETURN_VAL_TYPE
from typing import Any , Dict , List
from langchain . globals import set_llm_cache
import json
class SearchableElasticsearchCache ( ElasticsearchCache ):
@ property
def mapping ( self ) -> Dict [ str , Any ]:
mapping = super (). mapping
mapping [ "mappings" ][ "properties" ][ "parsed_llm_output" ] = { "type" : "text" , "analyzer" : "english" }
return mapping
def build_document ( self , prompt : str , llm_string : str , return_val : RETURN_VAL_TYPE ) -> Dict [ str , Any ]:
body = super (). build_document ( prompt , llm_string , return_val )
body [ "parsed_llm_output" ] = self . _parse_output ( body [ "llm_output" ])
return body
@ staticmethod
def _parse_output ( data : List [ str ]) -> List [ str ]:
return [ json . loads ( output )[ "kwargs" ][ "message" ][ "kwargs" ][ "content" ] for output in data ]
es_client = Elasticsearch ( hosts = "http://localhost:9200" )
set_llm_cache ( SearchableElasticsearchCache ( es_client = es_client , es_index = "llm-chat-cache" ))Les incorporations de mise en cache sont obtenues en utilisant les cache-backedembedddings, d'une manière légèrement différente de la documentation officielle.
from llmescache . langchain import ElasticsearchStore
from elasticsearch import Elasticsearch
from langchain . embeddings import CacheBackedEmbeddings
from langchain_openai import OpenAIEmbeddings
es_client = Elasticsearch ( hosts = "http://localhost:9200" )
underlying_embeddings = OpenAIEmbeddings ( model = "text-embedding-3-small" )
store = ElasticsearchStore (
es_client = es_client ,
es_index = "llm-embeddings-cache" ,
namespace = underlying_embeddings . model ,
metadata = { "project" : "my_llm_project" }
)
cached_embeddings = CacheBackedEmbeddings (
underlying_embeddings ,
store
) De façon similaire au cache de chat, on peut sous-classer ElasticsearchStore pour indexer les vecteurs de recherche.
from llmescache . langchain import ElasticsearchStore
from typing import Any , Dict , List
class SearchableElasticsearchStore ( ElasticsearchStore ):
@ 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 Sachez que CacheBackedEmbeddings ne prend actuellement pas en charge les requêtes de mise en cache, cela signifie que les requêtes texte, pour les recherches vectorielles, ne seront pas mises en cache. Cependant, en remplaçant la méthode embed_query , il faut être en mesure de l'implémenter facilement.