IA generativa (GenAI)

Do conceito ao código: LLM + RAG com Couchbase

As tecnologias GenAI são definitivamente um item de tendência em 2023 e 2024 e, como eu trabalho para a  Tikalque publica seu próprio relatório anual radar e tendências tecnológicas relatório, o LLM e a genAI não escaparam da minha atenção. Como desenvolvedor, frequentemente consulto chatbots de IA generativa para me ajudar a resolver todos os tipos de erros de TypeScript e problemas misteriosos de linting, uso ferramentas de assistência genAI em meu IDE e para melhorar meus PRs. Essa tecnologia pode mudar sua vida.

Como pessoal técnico e, definitivamente, nós, desenvolvedores de software, essa nova tendência abre a oportunidade de integrar esses recursos a todos os projetos em que trabalhamos, e vejo meus amigos e colegas explorando essas opções, o que me levou à decisão: eu também deveria fazer isso!

E eu tinha exatamente o projeto:

Sou um dançarino amador que dança em uma trupe de dança amadora. Muitas vezes me pergunto como os artistas amadores podem explorar o vasto mundo dos eventos culturais locais e mundiais para poder entrar em contato e talvez receber o convite desejado para se apresentar. Não temos os recursos, as conexões e o conhecimento de tudo o que está disponível. É claro que existem mecanismos de pesquisa e sites especializados, mas é preciso saber o que e como pesquisar, por isso decidi usar o genAI para obter recomendações.

Etapa 1 - Isso pode ser feito?

A verificação da viabilidade de um mecanismo de recomendação usando um dos LLMs incluiu a abertura de contas em vários serviços de bate-papo da genAI e a realização da mesma pergunta:

Somos uma amador Dança folclórica israelense grupo, incluindo dançarinos em cadeiras de rodas. Estamos procurando por cultural e folclore eventos e festivais em Europa para entrar em contato sobre a possibilidade de recebermos um convite para nos apresentarmos, desde que cobrir nossas despesas. Você poderia recomendar alguns?

Os resultados no primeiro semestre de 2024 variaram entre os diferentes serviços de bate-papo:

    • Me direcionou para sites dedicados que eu poderia consultar para obter resultados
    • Me deu resultados reais

Dos que retornaram resultados, classifiquei a qualidade dos resultados de acordo com a relevância e a precisão, e cheguei a OpenAI GPT-3 como opção.

Etapa 2 - É suficiente?

Lembrando que até mesmo um dos assistentes de bate-papo na Etapa 1 sugeriu que eu verificasse outros sites, e se eu pudesse incorporar alguns desses dados nos resultados?

Considerando que também sou dependente de quem treinou o modelo e quando ele foi treinado, eu queria que minhas recomendações fossem baseadas em mais fontes de dados e sabia que isso poderia ser feito com o RAG. Antes de tudo, o que é o RAG?

Geração Aumentada de Recuperação (RAG)

RAG é o processo de enriquecimento e otimização dos resultados que você recebe do LLM adicionando dados "externos". Se eu puder adicionar resultados baseados na mesma pesquisa em fontes de dados externas (de sites dedicados), poderei expandir a variedade dos resultados que meu aplicativo fornecerá.

Para fazer isso, você precisará de:

    • Fontes de dados externas - Para meu experimento, criei uma conta de avaliação para API de eventos do predictHQ
    • Armazenar meus dados externos é um mecanismo que permite a pesquisa por similaridade e não uma correspondência exata

Tornar os dados acessíveis para o RAG

Depois de analisar os dados, sua aparência e os recursos que eles contêm, é hora de selecionar os recursos de dados que você gostaria de usar e torná-los utilizáveis para o RAG.

Para permitir uma pesquisa de similaridade, precisaríamos transformar nossos dados em um formato que seja pesquisável e comparável. Como não estamos procurando correspondências exatas, mas correspondências semelhantes, há duas técnicas muito comuns para isso:

Técnica RAG Detalhes
Pesquisa vetorial (também conhecida como RAG comum) As informações e a pergunta são transformadas em vetores de números (pontos flutuantes).

Os cálculos matemáticos são usados para determinar a similaridade entre a pergunta e os dados

GraphRAG As informações e a pergunta são transformadas em gráfico vértices e bordas.

As relações do gráfico são comparadas quanto à similaridade

O processo de criação da representação dos dados é chamado de incorporaçãoNeste artigo, vamos nos concentrar na pesquisa vetorial.

Métrica de similaridade

Há três opções comuns (em resumo):

    • Produto de pontos: Cálculo da similaridade com base no produto dos valores em cada vetor
    • Cosseno: Com base no ângulo entre os vetores
    • L2_norm: Distância euclidiana entre os vetores, com base no ângulo entre os vetores e o comprimento de cada vetor

Leia mais sobre o opções de similaridade de vetores.

Etapa 3 - Como faço isso?

Antes de nos aprofundarmos em como vamos fazer isso e em alguns códigos e capturas de tela reais, vamos ver como essa arquitetura seria construída e como o Couchbase entra em cena:

 



O que isso significa na prática é:

    • Ingestão app para:
      1. Obter dados da API externa
      2. Criar embeddings vetoriais
      3. Carregar dados em uma coleção do Couchbase
    • Criar um índice de pesquisa vetorial no Couchbase
    • Solicitação imediata para:
      1. Solicitar resultados aos dados do Couchbase
      2. Adicione os resultados da pesquisa de vetores ao prompt do LLM como contexto
      3. Devolver os resultados coesos aos usuários

Aplicação por ingestão

Esse processo foi provavelmente o mais longo, pois passei um tempo criando incorporações em diferentes campos e em diferentes formatos. Para simplificar, acabei optando por usar apenas as informações geográficas que coletei:

Para criar a incorporação, optei por usar as incorporações textuais como ponto de partida, ou seja, "comparar" a representação de texto com a representação de texto. A incorporação em si inclui cerca de 1.500 números (esse é o menor deles).

O código em si não é extremamente complexo, mas pode ser demorado. Criar uma incorporação para 5.000 eventos levou aproximadamente uma hora em meu MacBook pro M1 de 16 GB.

O código completo usando o pandas2 pode ser encontrado em este repositório.

Coleção e índice de pesquisa do Couchbase

Para poder pesquisar dados semelhantes entre a pergunta e os resultados que preparamos com base em uma API externa, vamos

    1. Criar uma coleção do Couchbase
    2. Faça upload dos dados preparados para uma coleção do Couchbase incluindo os embeddings
    3. Crie um índice de pesquisa nos campos de incorporação escolhendo o algoritmo de similaridade de vetores para comparar vetores

Nova coleção do Couchbase

Para meu aplicativo, optei por usar o serviço hospedado do Couchbase - Capella, cuja configuração é muito fácil. Eu me registrei, escolhi o serviço de nuvem e criei um novo projeto.

Clicando em meu projeto e navegando até a guia Ferramentas de dados, posso agora criar uma nova coleção para os dados que preparei:

Para carregar os dados que preparei, há várias opções: como o tamanho do arquivo era bastante grande, optei por usar o cbimport utilitário para fazer isso.

Observe que escolhi a opção ID dos documentos JSON para ser o documento chave na coleção.

Lembre-se que, antes de fazer isso, você precisa:

    • Criar usuário/senha de acesso ao banco de dados com privilégio de gravação, no mínimo
    • Abra o cluster para chamadas de seu host
    • Faça o download de um certificado para o cluster

O esquema de documento inferido mostra que o incorporação foi criado com o tipo de matriz de números:

Para permitir a pesquisa de similaridade de vetores, vamos criar o índice de pesquisa navegando até a guia Search (Pesquisa).

Obviamente, devemos selecionar o campo de incorporação para o índice de pesquisa, mas observe que há mais parâmetros a serem definidos:

Já discutimos qual é a métrica de similaridade, basta observar que o Couchbase suporta l2_norm (ou seja, distância euclidiana) e produto escalar.produto de pontos"o que pode ser mais vantajoso para meu sistema de recomendação.

A próxima etapa é escolher campos adicionais dos documentos que seriam retornados sempre que um vetor fosse dimerizado de forma semelhante à pergunta:

Se você não adicionar pelo menos um campo, seu aplicativo falhará porque não haverá nenhum dado retornado.

Aqui está, a seleção dos campos de índice:

Chegamos a um ponto crucial em nosso projeto, agora podemos começar a executar a pesquisa de similaridade nos dados que preparamos, mas talvez você não consiga fazer uma pesquisa de similaridade que funcione na primeira tentativa. Descreverei algumas dicas para obter resultados da sua pesquisa de similaridade ou para verificar por que não está obtendo resultados:

    • Certifique-se de que sua técnica de incorporação, ao criar os dados e preparar uma pesquisa, seja idêntica
    • Comece com um formato simples e previsível para as informações que você deseja comparar. Por exemplo, , ,
    • Certifique-se de que não haja informações extras que sejam acidentalmente anexadas aos dados para os quais você está criando embeddings (por exemplo, eu tinha quebras de linha)
    • Certifique-se de que a pesquisa de correspondência exata funcione:
      • Pesquisa dos dados exatos para os quais você criou embeddings
      • Compare o vetor de incorporação para garantir que sejam criadas incorporações idênticas na parte de geração e pesquisa (a depuração será útil aqui). Se houver alguma diferença, volte às etapas 1-3

Depois de ter uma busca por similaridade que funcione, adicione gradualmente mais campos, altere formatos, incorporações e tudo o mais que achar que está faltando.

Lembre-se de que qualquer alteração nos embeddings significa:

    1. Recriando os embeddings
    2. Carregamento dos dados de alterações em uma coleção truncada
    3. Alterar o índice de pesquisa, se necessário
    4. É necessário alterar o código

Essas etapas podem ser demoradas, especialmente a criação de incorporações, portanto, talvez você queira começar por elas:

    • Uma pequena parte de seus documentos
    • Uma técnica de incorporação pequena/rápida

Aplicação para LLM e RAG

O que nosso aplicativo precisa fazer é:

    1. Peça ao Couchbase para encontrar resultados semelhantes à pergunta do usuário
    2. Adicione os resultados ao contexto da pergunta do LLM
    3. Faça uma pergunta ao LLM

Para simplificar, criei esse código em Python como um notebook Jupyter, que você pode encontrar neste repositório. Usei as seguintes bibliotecas para fazer isso:

    1. Couchbase: Conectar e autenticar no meu cluster Capella
    2. LangChain: uma estrutura para o desenvolvimento de aplicativos alimentados por grandes modelos de linguagem (LLMs), para:
      1. Embeddings
      2. Usando o Couchbase como um armazenamento de vetores
      3. "Conversando" com a OpenAI
    3. LangGraph: Uma estrutura para criar aplicativos LLM com vários atores e com estado, para criar um fluxo do aplicativo LLM

Se você tem lido sobre, e até mesmo tentado criar seu próprio aplicativo LLM, provavelmente está familiarizado com o LangChain, que é um conjunto de bibliotecas que permite escrever, criar, implantar e monitorar um aplicativo. Ele tem muitos agentes e extensões que permitem integrar diferentes partes ao seu código, como uma API de terceiros, um banco de dados, uma pesquisa na Web e muito mais.

Ultimamente, também tomei conhecimento do LangGraph, da casa do LangChain, que permite que você, como desenvolvedor, crie topologias mais complexas do aplicativo LLM com condições, loops (o gráfico não precisa ser um DAG!), interação com o usuário e, talvez, o recurso mais procurado: Manter o estado.

Antes de examinarmos o código, vamos dar uma olhada no arquivo de ambiente (.env) para ver quais credenciais e outros dados confidenciais são necessários:

O estado de cada nó do gráfico é:

É importante observar que, a menos que você defina um redutor, o estado será substituído entre cada nó do gráfico. O membro messages da classe state tem um redutor que anexará as novas mensagens à lista.

Para conectar-se ao Couchbase e usá-lo como um armazenamento de vetores para o aplicativo LLM, autenticamos o cluster e passamos a conexão do cluster para o objeto LangChain do armazenamento de vetores:

Há dois detalhes importantes que devem ser levados em conta:

    • A incorporação no aplicativo deve ser idêntico ao usado na parte de ingestão
    • O nome padrão do campo de incorporação é "embedding"; se o nome do respectivo campo for diferente em seu índice de pesquisa, você precisará defini-lo durante a instanciação do CouchbaseVectorStore (embedding_key)

Neste momento, você está pronto para escrever seu aplicativo LangGraph e usar o Couchbase como armazenamento de vetores. Vamos montar tudo: cada gráfico precisa de nós, ponto inicial e bordas direcionadas.

Nosso gráfico buscará dados do armazenamento de vetores e continuará a adicionar essas informações ao contexto do prompt do LLM.

No código acima, isso se traduz em dois nós:

    1. vector_search (ponto de entrada)
    2. chatbot (ponto de chegada)

Como uma imagem vale mais que mil palavras, usei o código a seguir para visualizar o gráfico para você:

O resultado foi o seguinte desenho:

Para obter mais opções de visualização no langGraph, consulte este Notebook Jupyter da LangGraph.

Perguntar ao vector store significa pesquisar dados com localização semelhante. Você pode notar que o formato da consulta é o mesmo do texto incorporado; os resultados são adicionados ao estado para serem usados no próximo nó.

O nó do chatbot obtém as informações das mensagens e as incorpora à pergunta do prompt para o LLM.

Observe que o estado é mantido no banco de dados sqlite na memória. Para usar o gráfico, fique à vontade para usar o exemplo a seguir:

E aí está, você criou um aplicativo LLM para recomendar eventos culturais para grupos amadores solicitarem convites.

Resumo

Começar a usar os aplicativos do LLM é empolgante e, na minha humilde opinião, é um aumento divertido, empolgante e factível devido à sua natureza rápida; no entanto, tornar nosso aplicativo melhor e mais robusto esconde mais desafios.

Neste artigo, concentrei-me no desafio de aproveitar o conhecimento do nosso modo com dados externos por meio da técnica ou RAG e em como você pode aproveitar o Couchbase para fazer isso.

É importante lembrar que a criação de embeddings que o aplicativo LLM encontrará na pesquisa de vetores pode não funcionar em sua primeira tentativa. Verifique a formatação, tente começar com embeddings simples e use a depuração o máximo possível.

Também demonstrei os recursos do LangGraph da LangChain, que permite criar decisões e fluxos complexos no aplicativo LLM.

Aproveite sua jornada com as inscrições para o LLM.



Compartilhe este artigo
Receba atualizações do blog do Couchbase em sua caixa de entrada
Esse campo é obrigatório.

Autor

Postado por Sigal Shaharabani - Líder técnico, Tikal

Sou líder técnico e líder de grupo na Tikal, com uma grande paixão por back-end e sistemas de dados. Em meu tempo livre, gosto de nadar e dançar folclore israelense.

Deixe um comentário

Pronto para começar a usar o Couchbase Capella?

Iniciar a construção

Confira nosso portal do desenvolvedor para explorar o NoSQL, procurar recursos e começar a usar os tutoriais.

Use o Capella gratuitamente

Comece a trabalhar com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Deseja saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.