Published · 10 min read

Construindo um Agente Versátil AI

Um Guia para Iniciantes sobre Desenvolvimento de Modelos de Linguagem Grande Personalizáveis para Resolver Casos de Uso Simples

Autor: Rachel Martinez | Função: Desenvolvedor | Tag: AI Agentes


Introdução

Bem-vindo ao nosso blog técnico, onde tornamos conceitos complexos acessíveis a todos, independentemente de seu background. Hoje, estamos mergulhando em um projeto emocionante: desenvolver um Agente de Modelo de Linguagem Grande (LLM) que possa se adaptar a várias tarefas.

Estamos criando uma infraestrutura robusta de Recuperação, Aumento e Geração (RAG) para nos ajudar a selecionar o LLM mais adequado para cada tarefa. Empresas como H2O e HuggingFace já lançaram sistemas semelhantes, e recebemos interesse de startups ansiosas para integrar nossa tecnologia AI em seus aplicativos.

Nosso caso de uso específico exige a capacidade de acionar o LLM usando uma única entrada (um disparo) ou encadeando várias entradas. Isso necessita a criação de módulos personalizáveis e amigáveis ao usuário LLM para vários cenários.

Fique atento enquanto embarcamos nesta jornada, desmembrando cada etapa de forma simples e atraente.

Caso de Uso Atual

Em nosso caso de uso atual, melhoramos o conteúdo do currículo de um usuário por meio de um processo de duas etapas:

  1. Entrada: O usuário insere as seções de “Resumo Profissional” e “Experiência” do seu currículo no sistema e consulta o LLM para gerar uma versão mais polida do texto.
  2. Revisão: O usuário revisa o conteúdo gerado pelo LLM e fornece prompts adicionais ou orientação para refinar e personalizar a saída, garantindo que ela esteja alinhada com suas habilidades e experiências únicas.

Ao seguir essa abordagem, os usuários podem aproveitar o poder do LLM para criar um currículo convincente que se destaque para os empregadores potenciais.

Alvo

Nosso objetivo é construir um módulo LLM totalmente personalizável que suporte nosso caso de uso e, pelo menos parcialmente, automatize o processo de criação de currículos.

Implementação

Etapa 1: Escolhendo o LLM

Ao selecionar o LLM certo para as suas necessidades, existem duas principais categorias a considerar: LLMs de código aberto e LLMs proprietários. Discutiremos opções populares de ambos os grupos, focando nos benefícios de escolher LLMs de código aberto.

LLMs de Código Aberto

Exemplos: Mistral AI, Phi 3, LLaMa 3.

Vantagens:

  • Suporte da Comunidade: Comunidades grandes e ativas de desenvolvedores e usuários fornecem orientação, compartilham recursos e colaboram em melhorias.
  • Customização: O acesso ao código-fonte permite modificações e adaptações para atender a casos de uso específicos.
  • Transparência: Entender o funcionamento interno do modelo é crucial para aplicações com diretrizes éticas ou de privacidade rigorosas.

LLMs Proprietários

Exemplos: GPT-4.

Vantagens: Desempenho impressionante e recursos únicos.

Limitações:

  • Falta de Customização: Limitado ao uso do modelo como está.
  • Custo: Taxas baseadas no uso podem se acumular ao longo do tempo.
  • Natureza Opaca: Difícil entender a mecânica subjacente, o que pode ser uma preocupação para aqueles que priorizam a transparência e a explicabilidade.

Em resumo, embora os LLMs de código aberto e proprietários tenham vantagens e desvantagens, os LLMs de código aberto, como o Mistral AI, Phi 3 e LLaMa 3, oferecem acessibilidade, personalização e transparência que podem ser altamente benéficas para uma ampla gama de usuários.

Etapa 2: Analisando Custos e Recursos

Os LLMs de código aberto geralmente são econômicos, pois podem ser hospedados em seus próprios servidores ou com provedores como Azure ou AWS com um modelo de pagamento por uso. Aqui está um resumo dos custos e recursos de hospedagem de vários LLMs:

LLMDetalhesComprimento de ContextoCusto
Mixtral 8x7BMoE LLM por Mistral ATreinado: 8192 tokensR$0.7/1M tokens (barato)
Mixtral 8x22BSucessor do MixtralTreinado: 32768 tokens$2/1M tokens (disponível)
LLaMa 3 70BModelo não-MoE da MetTreinado: 2048 tokens$0.02/1K tokens (Azure)
Phi 3 128KMultimodal-SLM da MeTreinado e Total: 3$0.002/1K tokens (Azure)
GPT-4 TurboProprietário LLM da O16K padrão, superiorNão disponível em AWS

Etapa 3: Testes utilizando APIs Públicas Compatíveis com OpenRouter

Selecionar e testar o melhor LLM exige uma forma simplificada de acessar e avaliar diferentes modelos. OpenRouter, um padrão de código aberto API, permite a troca transparente entre vários modelos e serviços AI. Escolhemos Fireworks AI como nosso provedor porque:

  • Diversidade de Modelos: Oferece uma ampla variedade de modelos AI, incluindo LLMs de código aberto populares como Mistral AI, Phi 3 e LLaMa 3.
  • Facilidade de Integração: Adere ao padrão OpenRouter, simplificando a integração à infraestrutura existente.
  • Escalabilidade: Projetado para lidar com grandes volumes de solicitações e escalar de forma transparente.

Aqui está uma função de amostra para invocar respostas de modelo e os resultados de latência usando o mesmo hardware:

import json

def get_sanitized_json_response(user_input, guardrail):
    final = chain.invoke({"text": f"Sanitize {user_input}. Guardrail: {guardrail}"})
    final = chain.invoke({"text": final.content})
    return json.loads(final.content.replace("<json>", "").replace("</json>", "").replace("\n",""))
ModeloLatênciaObservações
Mixtral 8x7B2,1sModelo mais leve, desempenho
Mixtral 8x22B5,3sModelo sucessor, simulação
LLaMa 3 70B2,6sResposta decente, mas
Phi 3 128K1.5 minModelo multimodal com

Um guardrail e uma entrada muito simples foram utilizados para testar o acima:

guardrail = """Format details as bullets and use the XYZ method to format the relevant detail.
            For example:
            - I did X boosting Y percent resulting in Z.
"""

Obtivemos a seguinte resposta json sanitizada após sua invocação:

get_sanitized_json_response("""I served as Junior as a Software Engineer at TechCorp in Sydney in January 2011 and worked there until December 2018. During my tenure,
                            I led the team that developed advanced AI-driven financial analytics tools for processing hundreds of millions of records in a
                            distributed environment and created the initial version of the company's proprietary data pipeline. In my role, I was responsible for
                            designing solutions and implementing multiple APIs. In my last year managing a team focused on blockchain solutions.""", guardrail)

{'experience': [{'title': 'Software Engineer',
                'company': 'TechCorp',
                'location': 'Sydney',
                'start_date': '2011-01',
                'end_date': '2018-12',
                'highlights': ['- Engineered scalable database systems of a major project that improved client data processing speed by 40%.',
                              '- Spearheaded a team focused on AI-driven solutions.',
                              '- Developed AI-driven financial analytics tools processing 100M+ records in distributed environments.',
                              '- Created company\'s proprietary data pipeline.',
                              '- Managed team on blockchain solutions in final year.']}]}

Em conclusão, como a qualidade da resposta foi razoavelmente comparável entre todos esses modelos, dependia da latência e do custo. O experimento foi executado 3 vezes, alcançando resultados muito semelhantes. Portanto, escolhemos o Mixtral 8x7B da Mistral AI devido ao seu equilíbrio favorável de latência e custo.

Etapa 4: Construindo uma Camada de Orquestração

Gerenciar e coordenar vários modelos de linguagem de grande escala ou um modelo único em várias aplicações é crucial para o desempenho ótimo e a adaptabilidade. Em vez de construir do zero usando vanilla PyTorch, empregar uma estrutura de orquestração é mais prático e eficiente. Aqui estão três opções:

Langchain

Vantagens: Vasta gama de integrações, suporta Python e JavaScript, amplo suporte da comunidade.

Desvantagens: Introduz uma dependência adicional, curva de aprendizado potencial.

LlamaIndex

Vantagens: Apoiado pela Meta, oferece interoperabilidade com Langchain.

Desvantagens: Sintaxe menos amigável para desenvolvedores.

Feno

Vantagens: Sintaxe amigável ao usuário, apoiada por corporações de tecnologia proeminentes.

Desvantagens: Integrações limitadas, pois ainda está em desenvolvimento.

Usar um framework de orquestração simplifica o desenvolvimento, melhora a escalabilidade e fornece acesso a uma comunidade de apoio, tornando-o uma escolha mais favorável para nosso projeto.

Design e Fluxo de Dados

A imagem a seguir mostra o diagrama de design:

O fluxo de dados dentro de nosso sistema impulsionado por AI é um aspecto essencial para garantir uma experiência do usuário sem interrupções e eficiente. Embora o diagrama de design forneça uma representação visual do processo, uma explicação detalhada pode ajudar a esclarecer as etapas envolvidas:

  1. Entrada do Usuário: A jornada começa quando o usuário insere seus detalhes, como as seções “sobre” e “experiência” de seu currículo, no sistema.
  2. Geração de Prompt: A entrada do usuário é processada e transformada em um ou mais prompts, que serão usados para consultar o Grande Modelo de Linguagem (LLM) para obter uma versão mais polida e impressionante do texto.
  3. LLM Integração via Langchain: As prompts geradas são passadas para Langchain, nossa estrutura de orquestração escolhida, que facilita a interação com o cliente LLM. Langchain utiliza um esquema Pydantic na forma de uma classe para analisar e validar os dados usando kor, garantindo que eles atendam ao formato exigido.
  4. Geração de JSONResponse: Uma vez que os dados são validados, eles são convertidos em uma JSONResponse final, um formato de dados estruturado e fácil de trabalhar que simplifica o processamento e manipulação posteriores.
  5. Extração e Indexação de Conteúdo: A parte de conteúdo da JSONResponse é extraída usando kor e indexada por meio de embeddings, que são representações matemáticas do texto. Esses embeddings são armazenados em um banco de dados de vetores, como Qdrant, para recuperação e comparação eficientes durante consultas subsequentes.
  6. Cache para Módulo de Contexto: A JSONResponse inteira é armazenada em cache para que o módulo de contexto funcione corretamente. Isso garante que o sistema possa manter o contexto da entrada do usuário e da saída do LLM durante consultas de follow-up.
  7. Consultas de Follow-up: Quando o usuário fornece entrada adicional ou solicita refino adicional do texto gerado, a JSONResponse armazenada em cache é modificada de acordo com o novo contexto e encadeada ao prompt atualizado. Esse prompt modificado então passa por todo o processo novamente, desde a integração LLM até a extração e indexação de conteúdo, para fornecer ao usuário uma resposta personalizada e precisa.

Ao entender o fluxo de dados dentro do nosso sistema, podemos apreciar a importância de cada etapa e o papel da estrutura de orquestração no processo de simplificação, resultando finalmente em uma solução eficiente e amigável ao usuário, impulsionada por AI.

Construção e Encadeamento de Prompts usando LCEL

Este é um exemplo de uma amostra PromptTemplate:

from langchain.core.output_parsers import PydanticOutputParser
prompt = PromptTemplate(
    template="Please extract the following information from the given text and format it as a JSON object according to the schema:\n\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": output_parser.get_format_instructions()},
)

chain = prompt | chat_model | output_parser

Um modelo típico consiste em dois principais argumentos (existem mais, mas isso está fora do escopo deste blog) que são input_variables e template. O primeiro argumento aceita uma lista de strings que seriam injetadas no modelo de prompt em tempo de execução. Essa variável atua tipicamente como as do Jinja2Template ou f-strings. O chat_model aqui seria o LLM que estamos usando e está sendo encadeado ao prompt. O operador | (pipe) semelhante ao operador BASH | representa uma cadeia. Isso é um atalho conveniente fornecido pela especificação da Linguagem de Expressão LCEL (LangChain). Isso permitiria encadear a resposta de um prompt à entrada de outro. Ele também suporta chamadas de função, em outras palavras, é possível encadear expressões lambda ou algumas funções para sanitizar a saída. Isso reduz a complexidade do código simplesmente escrevendo cadeias em vez de funções grandes.

Etapa 5: Usando VectorDBs

Bancos de dados vetoriais (VectorDBs) armazenam, gerenciam e pesquisam eficientemente vetores de alta dimensionalidade, como embeddings de texto gerados por LLMs. Aqui está uma comparação das opções populares:

Qdrant

Vantagens: Alto desempenho, integração fácil, comunidade ativa.

Desvantagens: Nenhuma significativa.

Milvus

Vantagens: Múltiplas métricas de distância, ferramenta de visualização de dados.

Desvantagens: Curva de aprendizado mais acentuada.

Chroma

Vantagens: Fácil de usar Python API, design modular.

Desvantagens: Relativamente novo, suporte de comunidade menos extenso.

PGVector

Vantagens: Aproveita as capacidades do PostgreSQL, consultas baseadas em SQL.

Desvantagens: Menos performático para busca de vetores de alta dimensionalidade.

FAISS

Vantagens: Busca de alto desempenho, suporte a GPU.

Desvantagens: Requer integração com outros bancos de dados.

A escalabilidade, a facilidade de integração e o desenvolvimento ativo do Qdrant o tornam uma escolha adequada para nossa solução impulsionada por AI.

Utilizando VectorDBs como uma Solução Robusta de IR

Criar uma solução de Recuperação de Informações (IR) usando VectorDBs envolve:

  1. Pré-processamento de Texto: Limpar e pré-processar dados de texto brutos.
  2. Geração de Incorporação de Texto: Converter texto pré-processado em vetores de alta dimensionalidade usando um LLM.
  3. Armazenamento de Incorporações em VectorDB: Indexar incorporações para busca eficiente.
  4. Processamento de Consultas: Pré-processar e converter consultas de usuário em embeddings.
  5. Pesquisa de Semelhança: Realizar pesquisa de semelhança em VectorDB para encontrar embeddings relevantes.
  6. Classificação e Exibição de Resultados: Classificar embeddings recuperados e convertê-los de volta em texto para exibição.

Seguindo esse processo e utilizando VectorDBs, podemos construir um sistema de IR eficiente e eficaz.

Pronto para contratar com precisão?

Comece grátis, convide toda a sua equipe e veja seu primeiro candidato pontuado em 15 minutos.

pt