Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Saiba por que o MongoDB foi selecionado como um líder no 2024 Gartner_Magic Quadrupnt()
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-right

Resposta de LLMs em cache com MongoDB Atlas e Vector Atlas Search

Kanin Kearpimy8 min read • Published Sep 02, 2024 • Updated Sep 02, 2024
IAAtlasPython
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Os modelos de linguagem de grandes dimensões (LLMs) são a solução reconhecida para a maioria dos domínios empresariais no 2024. Embora haja uma estimativa de que 750 milhões de aplicativos serão integrados com LLMs em 2025, o treinamento de LLMs consome recursos monetários significativos. Portanto, o custo das plataformas LLM , como a REST API GPT da OpenAI, reflete o custo acima em seus preços. O problema é como podemos reduzir o custo operacional dos aplicativos de AI em produção; a resposta obvia é chamar menos a API , e então surge outro problema: a manutenção da qualidade da resposta aos usuários.
O cache é uma solução fundamental na engenharia de software há muitos anos. O aplicação cria um cache extraindo uma chave da solicitação e armazenando o resultado correspondente. Da próxima vez que a mesma chave for chamada, o servidor poderá responder imediatamente às queries dos usuários na rede sem computação extra.
No entanto, o caractere da query LLM não é uma chave fixa, mas um formato flexível como o significado da pergunta do ser humano. Consequentemente, o cache tradicional que armazena chaves fixas é ineficiente o suficiente para lidar com queries LLM.

Cache semântica

Ao contrário do cache tradicional,as características do cache semântica de dados e a representação semântica são simplesmente descritas como representações baseadas em significado. Chamamos esse processo de incorporação. Nos sistemas LLM, o modelo converte texto em vetores numéricos que representam seu significado semântica.
Armazenaremos as incorporações no sistema de cache. Quando uma nova solicitação chega, o sistema extrai sua representação semântica criando uma incorporação. Em seguida, ele procura similaridades entre essa nova incorporação e as incorporações armazenadas no sistema de cache. Se uma correspondência de alta similaridade for encontrada, a resposta em cache correspondente será retornada. Esse processo permite a recuperação semântica de respostas calculadas anteriormente, reduzindo potencialmente a necessidade de chamadas repetidas de API para o serviço LLM.
Sistema e lógica de alto nível.
Todo o código está em Github.

Pré-requisitos

– Python (3.12.3 ou mais recente) – FastAPI (0.11 ou mais recente) – PyMongo (4.7.2 ou mais recente) – uvicorn (0.29,0 ou mais recente).

1) Configurar dependência no Python

Precisamos instalar as dependências conforme mencionado acima. Você pode utilizar o pip para o gerenciador de pacote . As dependências necessárias estão em requires.txt. Após clonar o projeto e inserir o diretório do projeto, você pode executar o comando abaixo para instalá-los.
1pip install fastapi pymongo openai uvicorn
Caso esteja criando um projeto isolado, você pode habilitar o Python virtualenv para esse ambiente específico.)

2) Criar servidor FastAPI

Para simular o servidor de cache , a solicitação deve vir de uma solicitação HTTP. Assim, configuramos um servidor web em Python pela FastAPI.1.2.1) Crie app.py no diretório raiz.1.2.2) Importe FastAPI e inicie / e /ask rotas.
app.py
1from fastapi import FastAPI
2server = FastAPI()
3# root route
4@server.get("/")
5async def home():
6 return { "message": "This is home server" }
7
8# search route
9@server.get("/ask")
10async def search(query: str):
11 return { "message": "The query is: {}".format(query) }
Em seguida, execute o aplicação para testar nossa rota. (--recarregar para atualização rápida se o código do aplicação for editado.)
1uvicorn app:server --reload
Seu servidor deve estar executando em http://127.0.0.1:8000. Agora podemos testar nossa rota de pesquisa usando o comando abaixo.
1curl -X GET "http://127.0.0.1:8000/ask?query=hello+this+is+search+query"
O servidor deve responder da seguinte forma:
1{ "message": "The query is: hello this is search query" }

3) Conectar OpenAI

Anteriormente, configuramos um servidor FastAPI básico e perguntamos a rota. Em seguida, a funcionalidade LLM será integrada.
1.3.1) Crie llm.py no mesmo diretório que app.py. 1.3.2) Configure o OpenAI como um serviço LLM. llm.py
1from openai import OpenAI
2
3open_api_key = "..." # OpenAI API Key
4openai_client = OpenAI(api_key=open_api_key)
5language_model = "gpt-3.5-turbo"
6
7# getTextResponse receive text and ask LLM for answer
8def getTextResponse(text):
9 chat_completion = openai_client.chat.completions.create(
10 messages=[{"role": "user", "content": text}], model=language_model
11 )
12 return chat_completion.choices[0].message.content
Precisamos modificar app.py com algumas linhas de código. app.py
1# ... other import dependencies
2from llm import getTextResponse
3# ... other routes
4# search route
5@server.get("/ask")
6async def search(query):
7 llm_response = getTextResponse(query)
8 return {"message": "Your AI response is: {}".format(llm_response)}
Em seguida, podemos invocar a rota query com uma nova query.
1curl -X GET "http://127.0.0.1:8000/ask?query=what+is+llm?"
2Response
3{
4 "message": "Your AI response is: LLM stands for Master of Laws, which is an advanced law degree typically pursued by individuals who have already received a law degree (such as a JD) and want to further specialize or advance their knowledge in a specific area of law. LLM programs are typically one year in length and often focus on areas such as international law, human rights, or commercial law."
5}

4) Incorporando resposta LLM

Agora podemos receber uma resposta do OpenAI LLM. No entanto, o sistema está sempre dependendo do serviço OpenAI. Nosso objetivo é reduzir a carga do serviço de AI para o sistema de cache. Para armazenar em cache a resposta LLM, devemos transformar nosso texto (ou qualquer tipo de dados) em dados vetoriais. Um vetor pode ser considerado uma matriz N-dimensional (dependendo do modelo de incorporação) na qual cada número representa o significado dos dados originais. Exemplo:
1text = "Large Language Model"
2# embedding_function(text: str) -> vector<number>([...N])
3vector = embedding_function(text)
4
5# vector = [12, 23, 0.11, 22, 85, 43, ..., 90]
Podemos incorporar nossos dados usando um modelo de idioma. No nosso caso, utilizamos o modelo de incorporação de texto do OpenAI. Portanto, modificamos llm.py com algumas linhas.
llm.py
1# ... other code
2text_embedding_model = "text-embedding-3-small"
3# getEmbedding receives text and response embedding (vector) of its original data
4def getEmbedding(text):
5 embedding = openai_client.embeddings.create(input=text, model=text_embedding_model)
6 return embedding.data[0].embedding
Então, modificaremos app.py para usar a nova funcionalidade do llm.py. app.py
1# ... other import dependencies
2from llm import getTextResponse, getEmbedding
3
4# ... other routes
5
6# search route
7@server.get("/ask")
8async def search(query):
9 llm_response = getTextResponse(query)
10 query_vector = getEmbedding(query)
11 print("embedding : ", query_vector)
12 return {"message": "Your AI response is: {}".format(llm_response)}
Se executarmos o comandocurl para invocar ask novamente, no shell do servidor , ele deverá imprimir dados semelhantes, como abaixo.
1embedding : [-0.02254991, 0.031336114, 0.019013261, 0.00017081834, -0.0202526, -0.0020466715, 0.0111036645, -0.0111036645, 0.036172554, 0.04038429, -0.027043771, 0.0046273666, -0.039820038, -0.011456322, 0.0048339227, 0.021824444, 0.0048666694, -0.017501874, 0.03915503, 0.03895351, 0.041311275, ..., 0.046349235]

5) Armazenar informações vetoriais no MongoDB Atlas

Já temos dados vetoriais para sua semântica. Vamos ver como os armazenaremos para nosso sistema de cache. O MongoDB Atlas Vector Search é um recurso chave que nos permite ativar a pesquisa semântica alimentada por IA em dados vetoriais. Para fazer isso, devemos primeiro armazenar documentos no MongoDB de banco de dados do MongoDB.First, registre-se para uma conta do MongoDB Atlas. Usuários existentes podem entrar no MongoDB Atlas.Siga as instruções. Selecione a UI do Atlas como o procedimento para implantar seu primeiro cluster.
4.1) Conecte o MongoDB ao Python. 4.1.1) Crie db.py no mesmo diretório de app.py. 4.1.2) Implemente o salvamento de documento no MongoDB.
db.py
1import pymongo
2
3MONGO_URI = "" # MongoDB connection string
4mongo_client = pymongo.MongoClient(MONGO_URI)
5
6db = mongo_client.get_database("logging") # database name in mongodb
7collection = db.get_collection("test") # collection name
8
9# document {
10# query: string,
11# response: string,
12# embeddings: vector<number<1408>>
13# }
14
15def save_cache(document):
16 collection.insert_one(document)
4.1.3) Salvar resposta da AI no banco de banco de dados. Modifique app.py para salvar a resposta da AI e suas informações vetoriais no banco de banco de dados. app.py
1# ... other import dependencies
2from db import save_cache
3
4# ... other code
5
6# search route
7@server.get("/ask")
8async def search(query):
9 llm_response = getTextResponse(query)
10 query_vector = getEmbedding(query)
11
12 document = {
13 "response": llm_response,
14 "embeddings": query_vector,
15 "query": query
16 }
17 save_cache(document)
18
19 return {"message": "Your AI response is: {}".format(llm_response)}
4.2) Crie uma pesquisa vetorial de índice no MongoDB O Vector Search do AtlasMongoDB permite que experiências alimentadas por IA realizem pesquisas semânticas de dados não estruturados por suas incorporações com modelos de aprendizado de máquina. Precisamos ativar o índice de pesquisa vetorial no banco de banco de dados. Você pode Go o banco de dados de dados em Atlas -> Atlas Search -> CREATE SEARCH INDEX.
Abaixo está a versão do editor JSON do índice Atlas .
1{
2 "type": "vectorSearch", # vector search identity
3 "fields": [
4 {
5 # type of data in the asking the system again with a new question (but similar meaning): Howfield (vector information)
6 "type": "vector",
7 # field of document that store vector information
8 "path": "embeddings",
9 # dimension of vector, receiving from language model specification.
10 # for `text-embedding-3-small` of OpenAI, it's 1408 dimensions of vector.
11 "numDimensions": 1408,
12 # vector search find similarity of searching document with other. So, closest documents would get high score.
13 "similarity": "cosine"
14 }
15 ]
16}

6) Obter cache do sistema no MongoDB Atlas

Logicamente, quando recebermos uma nova solicitação do cliente, incorporaremos a query de pesquisa e realizaremos uma pesquisa vetorial para localizar os documentos que contêm incorporações semanticamente semelhantes à incorporação da query. A pesquisa vetorial é um dos estágios dos pipelines de agregação . O pipeline é construído como mostrado abaixo.
1# Step 1: Perform vector search
2{
3 # $vectorSearch operation
4 "$vectorSearch": {
5 # Vector Search index in Atlas
6 "index": "vector_index",
7 # vector information in document
8 "path": "embeddings",
9 # embedding information of client's query
10 "queryVector": numerical_embedding,
11 # number of nearest neighbors to find the closest group. This value is used for 'searchScore' ranking
12 "numCandidates": 20,
13 # number of document to return ranked by semantic meaning / searchScore
14 "limit": 5,
15 },
16},
17# add 'score' field to show vector search score.
18{
19 "$addFields": {
20 "score": {
21 # vectorSearchScore is attached in $meta for pipeline after vectorSearch operation
22 "$meta": "vectorSearchScore"
23 }
24 }
25},
26# return document that score greater than specific ratio
27# in this case, only top one that has ration > 70% is going to return.
28{
29 "$match": {
30 "score": { "$gte": 0.70 }
31 }
32},
33# remove `embeddings` field. Because it reduce load to retrieve data.
34{
35 "$unset": ["embeddings"]
36}
37]
Modifique db.py e app.py para implementar o agregação pipeline do PyMongo para pesquisa vetorial. db.py
1# ... other code
2def perform_search_cache(query):
3 pipeline = [
4 {
5 "$vectorSearch": {
6 "index": "vector_index",
7 "path": "embeddings",
8 "queryVector": query,
9 "numCandidates": 20,
10 "limit": 1,
11 },
12 },
13 {"$addFields": {"score": {"$meta": "vectorSearchScore"}}},
14 {"$match": {"score": {"$gte": 0.70}}},
15 {"$unset": ["embeddings"]},
16 ]
17 result = collection.aggregate(pipeline)
18 return result
app.py
1# ... other import dependencies
2from db import save_cache, perform_search_cache
3
4# ... other code
5# search route
6@server.get("/ask")
7async def search(query):
8 query_vector = getEmbedding(query)
9 cache_response = list(perform_search_cache(query_vector))
10 response = ""
11 if len(cache_response) < 1:
12 # in case no cache hit
13 # perform search and save the cache
14 llm_response = getTextResponse(query)
15 document = {"response": llm_response, "embeddings": query_vector, "query": query}
16 save_cache(document)
17 response = llm_response
18 else:
19 # if cache hit, return it
20 response = cache_response[0]["response"]
21 print("cache hit")
22 print(cache_response)
23 return {"message": "Your AI response is: {}".format(response)}
Podemos tentar enviar a solicitação para o nosso sistema. Vamos perguntar ao sistema, “How are things with you? "
1curl -X GET "http://127.0.0.1:8000/ask?query=how+are+things+with+you?"
resposta Pela primeira vez, o sistema recupera dados do serviço de AI .
1{
2 "message": "Your AI response is: I'm just a computer program, so I don't have feelings or emotions. But I'm here to help you with anything you need! How can I assist you today?"
3}
Vamos tentar fazer uma nova pergunta ao sistema (mas com um significado semelhante): Como você está hoje?
1curl -X GET "http://127.0.0.1:8000/ask?query=how+are+you+today?"
Agora, o sistema retornará dados de cache do MongoDB Atlas.
1{
2 "message": "Your AI response is: I'm just a computer program, so I don't have feelings or emotions. But I'm here to help you with anything you need! How can I assist you today?"
3}
Se você Go for shell/ , verá um log como abaixo.
1cache hit
2[
3 {
4 '_id': ObjectId('6671440cb2bf0b0eb12b75b3'),
5 'response': "I'm just a computer program, so I don't have feelings or emotions. But I'm here to help you with anything you need! How can I assist you today?",
6 'query': 'how are thing with you?',
7 'score': 0.8066450357437134
8 }
9]
parece que a query "How are you today? " é 80% semelhante a "How are things with you? " É o que espervamos.

Resumo

Este artigo descreve a implementação de um sistema de cache semântica para respostas LLM utilizando MongoDB Atlas e Vector Search. A solução abordada neste artigo tem como objetivo reduzir os custos e a latência associados a chamadas frequentes da API do LLM, armazenando respostas em cache com base na semântica da query em vez de correspondências exatas.
A solução integra FastAPI, OpenAI e MongoDB Atlas para criar um fluxo de trabalho em que as queries de entrada são incorporadas em vetores e comparadas com entradas em cache. Queries correspondentes recuperam respostas armazenadas, enquanto novas queries são processadas pelo LLM e depois armazenadas em cache.
Os principais benefícios incluem carga de serviço LLM reduzida, custos mais baixos, tempos de resposta mais rápidos para queries semelhantes e escalabilidade. O sistema demonstra como a combinação de recursos de pesquisa vetorial com LLMs pode otimizar aplicativos de processamento de linguagem natural, oferecendo um equilíbrio entre eficiência e qualidade de resposta.
Saiba como implementar o cache semântica com a biblioteca de estrutura LLM amplamente aceita, a LangChain.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Dados do MongoDB ELT usando o Airbyte


Nov 16, 2022 | 2 min read
Artigo

Melhores práticas e um tutorial para usar o Google Cloud Functions com o MongoDB Atlas


Jun 13, 2023 | 13 min read
Tutorial

Como implementar o MongoDB Atlas com o AWS CDK no TypeScript


Jan 23, 2024 | 5 min read
exemplo de código

Aplicação de exemplo Hostels Kenya


Jul 07, 2022 | 4 min read
Sumário