Agentes de IA no Azure Cosmos DB
Os agentes de IA são projetados para executar tarefas específicas, responder perguntas e automatizar processos para os usuários. Estes agentes variam muito em complexidade. Eles variam de simples chatbots a copilotos, passando por assistentes avançados de IA na forma de sistemas digitais ou robóticos que podem executar fluxos de trabalho complexos de forma autônoma.
Este artigo fornece visões gerais conceituais e exemplos de implementação detalhados para agentes de IA.
O que são agentes de IA?
Ao contrário de modelos de linguagem grandes (LLMs) autônomos ou sistemas de software/hardware baseados em regras, os agentes de IA têm estas características comuns:
- Planejamento: os agentes de IA podem planejar e sequenciar ações para atingir objetivos específicos. A integração de LLMs revolucionou suas capacidades de planejamento.
- Uso de ferramentas: agentes avançados de IA podem usar várias ferramentas, como execução de código, pesquisa e recursos de computação, para executar tarefas de forma eficaz. Os agentes de IA geralmente usam ferramentas por meio de chamadas de função.
- Perceção: os agentes de IA podem perceber e processar informações de seu ambiente, para torná-los mais interativos e conscientes do contexto. Essas informações incluem dados visuais, auditivos e outros dados sensoriais.
- Memória: os agentes de IA têm a capacidade de lembrar interações passadas (uso e perceção da ferramenta) e comportamentos (uso e planejamento da ferramenta). Eles armazenam essas experiências e até realizam autorreflexão para informar ações futuras. Esse componente de memória permite a continuidade e a melhoria no desempenho do agente ao longo do tempo.
Nota
O uso do termo memória no contexto de agentes de IA é diferente do conceito de memória de computador (como memória volátil, não volátil e persistente).
Copilots
Copilots são um tipo de agente de IA. Trabalham em conjunto com os utilizadores, em vez de operarem de forma independente. Ao contrário dos agentes totalmente automatizados, os copilots fornecem sugestões e recomendações para ajudar os usuários a concluir tarefas.
Por exemplo, quando um usuário está escrevendo um e-mail, um copiloto pode sugerir frases, frases ou parágrafos. O usuário também pode pedir ao copiloto para encontrar informações relevantes em outros e-mails ou arquivos para apoiar a sugestão (consulte geração aumentada de recuperação). O usuário pode aceitar, rejeitar ou editar as passagens sugeridas.
Agentes autónomos
Os agentes autónomos podem operar de forma mais independente. Ao configurar agentes autônomos para ajudar na composição de e-mails, você pode permitir que eles executem as seguintes tarefas:
- Consulte e-mails, chats, arquivos e outras informações internas e públicas existentes relacionadas ao assunto.
- Realize análises qualitativas ou quantitativas sobre as informações coletadas e tire conclusões relevantes para o e-mail.
- Escreva o e-mail completo com base nas conclusões e incorpore evidências de apoio.
- Anexe ficheiros relevantes ao e-mail.
- Analise o e-mail para garantir que todas as informações incorporadas são factualmente precisas e que as afirmações são válidas.
- Selecione os destinatários apropriados para Para, Cc e Cco e procure seus endereços de e-mail.
- Agende um horário apropriado para enviar o e-mail.
- Realize acompanhamentos se as respostas forem esperadas, mas não recebidas.
Você pode configurar os agentes para executar cada uma das tarefas anteriores com ou sem aprovação humana.
Sistemas multiagentes
Uma estratégia popular para alcançar agentes autônomos de alto desempenho é o uso de sistemas multiagentes. Em sistemas multiagentes, múltiplos agentes autônomos, seja na forma digital ou robótica, interagem ou trabalham juntos para alcançar objetivos individuais ou coletivos. Os agentes no sistema podem operar de forma independente e possuir seus próprios conhecimentos ou informações. Cada agente também pode ter a capacidade de perceber seu ambiente, tomar decisões e executar ações com base em seus objetivos.
Os sistemas multiagentes têm estas características principais:
- Autónomo: Cada agente funciona de forma independente. Toma as suas próprias decisões sem intervenção humana direta ou controlo por parte de outros agentes.
- Interativo: os agentes se comunicam e colaboram entre si para compartilhar informações, negociar e coordenar suas ações. Esta interação pode ocorrer através de vários protocolos e canais de comunicação.
- Orientado a metas: Os agentes em um sistema multiagente são projetados para atingir metas específicas, que podem ser alinhadas com objetivos individuais ou um objetivo compartilhado entre os agentes.
- Distribuído: Os sistemas multiagentes operam de forma distribuída, sem um único ponto de controle. Essa distribuição aumenta a robustez, a escalabilidade e a eficiência de recursos do sistema.
Um sistema multiagente oferece as seguintes vantagens em relação a um copiloto ou a uma única instância de inferência LLM:
- Raciocínio dinâmico: Em comparação com a corrente de pensamento ou a árvore de pensamento, os sistemas multiagentes permitem a navegação dinâmica através de vários caminhos de raciocínio.
- Habilidades sofisticadas: Os sistemas multiagentes podem lidar com problemas complexos ou de grande escala, conduzindo processos de tomada de decisão minuciosos e distribuindo tarefas entre vários agentes.
- Memória aprimorada: sistemas multiagentes com memória podem superar as janelas de contexto dos LLMs para permitir uma melhor compreensão e retenção de informações.
Implementação de agentes de IA
Raciocínio e planeamento
O raciocínio complexo e o planeamento são a marca distintiva dos agentes autónomos avançados. Estruturas populares para agentes autônomos incorporam uma ou mais das seguintes metodologias (com links para páginas de arquivo arXiv) para raciocínio e planejamento:
-
Melhore a cadeia de pensamento fazendo com que o modelo se pergunte explicitamente (e responda) a perguntas de acompanhamento antes de responder à pergunta inicial.
-
Use LLMs para gerar traços de raciocínio e ações específicas de tarefas de forma intercalada. Os rastreamentos de raciocínio ajudam o modelo a induzir, controlar e atualizar planos de ação, juntamente com o tratamento de exceções. As ações permitem que o modelo se conecte com fontes externas, como bases de conhecimento ou ambientes, para coletar informações adicionais.
-
Elabore um plano para dividir toda a tarefa em subtarefas menores e, em seguida, execute as subtarefas de acordo com o plano. Essa abordagem atenua os erros de cálculo, erros de etapa ausente e erros de mal-entendido semântico que geralmente estão presentes no prompt de cadeia de pensamento de tiro zero.
-
Use agentes de reflexão que reflitam verbalmente sobre os sinais de feedback da tarefa. Esses agentes mantêm seu próprio texto reflexivo em um buffer de memória episódica para induzir uma melhor tomada de decisão em ensaios subsequentes.
Frameworks
Várias estruturas e ferramentas podem facilitar o desenvolvimento e a implantação de agentes de IA.
Para uso e perceção de ferramentas que não exigem planejamento e memória sofisticados, algumas estruturas populares do orquestrador LLM são LangChain, LlamaIndex, Prompt Flow e Semantic Kernel.
Para fluxos de trabalho avançados e autônomos de planejamento e execução, a AutoGen impulsionou a onda multiagente que começou no final de 2022. A API de Assistentes da OpenAI permite que seus usuários criem agentes nativamente dentro do ecossistema GPT. LangChain Agents e LlamaIndex Agents também surgiram na mesma época.
Gorjeta
O exemplo de implementação mais adiante neste artigo mostra como criar um sistema multiagente simples usando uma das estruturas populares e um sistema de memória de agente unificado.
Sistema de memória do agente AI
A prática predominante para experimentar aplicativos aprimorados por IA de 2022 a 2024 tem sido o uso de sistemas de gerenciamento de banco de dados autônomos para vários fluxos de trabalho ou tipos de dados. Por exemplo, você pode usar um banco de dados na memória para armazenamento em cache, um banco de dados relacional para dados operacionais (incluindo logs de rastreamento/atividade e histórico de conversas LLM) e um banco de dados vetorial puro para gerenciamento de incorporação.
No entanto, essa prática de usar uma complexa rede de bancos de dados autônomos pode prejudicar o desempenho de um agente de IA. Integrar todos esses bancos de dados díspares em um sistema de memória coeso, interoperável e resiliente para agentes de IA é seu próprio desafio.
Além disso, muitos dos serviços de banco de dados usados com frequência não são ideais para a velocidade e a escalabilidade que os sistemas de agentes de IA precisam. As fraquezas individuais destas bases de dados são exacerbadas em sistemas multiagentes.
Bancos de dados na memória
Os bancos de dados na memória são excelentes para velocidade, mas podem ter dificuldades com a persistência de dados em larga escala de que os agentes de IA precisam.
Bases de dados relacionais
Os bancos de dados relacionais não são ideais para as variadas modalidades e esquemas fluidos de dados que os agentes manipulam. Os bancos de dados relacionais exigem esforços manuais e até mesmo tempo de inatividade para gerenciar provisionamento, particionamento e fragmentação.
Bancos de dados vetoriais puros
Bancos de dados vetoriais puros tendem a ser menos eficazes para operações transacionais, atualizações em tempo real e cargas de trabalho distribuídas. Os populares bancos de dados vetoriais puros hoje em dia normalmente oferecem:
- Nenhuma garantia em leituras e gravações.
- Rendimento de ingestão limitado.
- Baixa disponibilidade (abaixo de 99,9%, ou uma interrupção anualizada de 9 horas ou mais).
- Um nível de consistência (eventual).
- Um índice vetorial na memória que consome muitos recursos.
- Opções limitadas para multilocação.
- Segurança limitada.
Características de um sistema robusto de memória de agente de IA
Assim como sistemas eficientes de gerenciamento de banco de dados são essenciais para o desempenho de aplicativos de software, é fundamental fornecer aos agentes baseados em LLM informações relevantes e úteis para orientar sua inferência. Sistemas de memória robustos permitem organizar e armazenar vários tipos de informações que os agentes podem recuperar no momento da inferência.
Atualmente, os aplicativos baseados em LLM geralmente usam geração aumentada de recuperação que usa pesquisa semântica básica ou pesquisa vetorial para recuperar passagens ou documentos. A pesquisa vetorial pode ser útil para encontrar informações gerais. Mas a pesquisa vetorial pode não capturar o contexto, a estrutura ou as relações específicas que são relevantes para uma determinada tarefa ou domínio.
Por exemplo, se a tarefa for escrever código, a pesquisa vetorial pode não ser capaz de recuperar a árvore de sintaxe, o layout do sistema de arquivos, resumos de código ou assinaturas de API que são importantes para gerar código coerente e correto. Da mesma forma, se a tarefa for trabalhar com dados tabulares, a pesquisa vetorial pode não ser capaz de recuperar o esquema, as chaves estrangeiras, os procedimentos armazenados ou os relatórios que são úteis para consultar ou analisar os dados.
Tecer uma rede de bancos de dados autônomos na memória, relacionais e vetoriais (conforme descrito anteriormente) não é uma solução ideal para os variados tipos de dados. Essa abordagem pode funcionar para sistemas de agentes prototípicos. No entanto, acrescenta complexidade e gargalos de desempenho que podem prejudicar o desempenho de agentes autônomos avançados.
Um sistema de memória robusto deve ter as seguintes características.
Multimodal
Os sistemas de memória do agente de IA devem fornecer coleções que armazenam metadados, relacionamentos, entidades, resumos ou outros tipos de informações que podem ser úteis para várias tarefas e domínios. Essas coleções podem ser baseadas na estrutura e no formato dos dados, como documentos, tabelas ou código. Ou podem ser baseados no conteúdo e significado dos dados, como conceitos, associações ou etapas processuais.
Os sistemas de memória não são apenas críticos para os agentes de IA. Eles também são importantes para os seres humanos que desenvolvem, mantêm e usam esses agentes.
Por exemplo, os seres humanos podem precisar supervisionar os fluxos de trabalho de planejamento e execução dos agentes quase em tempo real. Durante a supervisão, os seres humanos podem interjeitar com orientação ou fazer edições em linha de diálogos ou monólogos dos agentes. Os seres humanos também podem precisar auditar o raciocínio e as ações dos agentes para verificar a validade do resultado final.
As interações humano/agente são prováveis em linguagens naturais ou de programação, enquanto os agentes "pensam", "aprendem" e "lembram" através de incorporações. Essa diferença representa outro requisito na consistência dos sistemas de memória entre as modalidades de dados.
Operacional
Os sistemas de memória devem fornecer bancos de memória que armazenem informações relevantes para a interação com o usuário e o ambiente. Essas informações podem incluir histórico de bate-papo, preferências do usuário, dados sensoriais, decisões tomadas, fatos aprendidos ou outros dados operacionais atualizados com alta frequência e em grandes volumes.
Esses bancos de memória podem ajudar os agentes a lembrar informações de curto e longo prazo, evitar repetir-se ou contradizer-se e manter a coerência das tarefas. Estes requisitos devem ser válidos mesmo que os agentes executem sucessivamente uma multiplicidade de tarefas não relacionadas. Em casos avançados, os agentes também podem testar vários planos de filiais que divergem ou convergem em pontos diferentes.
Partilhável, mas também separável
No nível macro, os sistemas de memória devem permitir que vários agentes de IA colaborem em um problema ou processem diferentes aspetos do problema, fornecendo memória compartilhada acessível a todos os agentes. A memória compartilhada pode facilitar a troca de informações e a coordenação de ações entre os agentes.
Ao mesmo tempo, o sistema de memória deve permitir que os agentes preservem sua própria persona e características, como suas coleções únicas de prompts e memórias.
Construindo um sistema robusto de memória de agente de IA
As características anteriores exigem que os sistemas de memória do agente de IA sejam altamente escaláveis e rápidos. Entrelaçar cuidadosamente bancos de dados diferentes, relacionais e vetoriais na memória (conforme descrito anteriormente) pode funcionar para aplicativos habilitados para IA em estágio inicial. No entanto, essa abordagem adiciona complexidade e gargalos de desempenho que podem prejudicar o desempenho de agentes autônomos avançados.
No lugar de todos os bancos de dados autônomos, o Azure Cosmos DB pode servir como uma solução unificada para sistemas de memória de agente de IA. Sua robustez permitiu com sucesso que o serviço ChatGPT da OpenAI escalasse dinamicamente com alta confiabilidade e baixa manutenção. Alimentado por um mecanismo de seqüência de registros de átomos, é o primeiro serviço de banco de dados NoSQL, relacional e vetorial distribuído globalmente do mundo que oferece um modo sem servidor. Os agentes de IA criados com base no Azure Cosmos DB oferecem velocidade, escala e simplicidade.
Velocidade
O Azure Cosmos DB fornece latência de milissegundos de um dígito. Esse recurso o torna adequado para processos que exigem acesso e gerenciamento rápidos de dados. Esses processos incluem cache (cache tradicional e semântico, transações e cargas de trabalho operacionais.
A baixa latência é crucial para os agentes de IA que precisam executar raciocínios complexos, tomar decisões em tempo real e fornecer respostas imediatas. Além disso, o uso do algoritmo DiskANN pelo serviço fornece pesquisa vetorial precisa e rápida com consumo mínimo de memória.
Escala
O Azure Cosmos DB foi projetado para distribuição global e escalabilidade horizontal. Ele oferece suporte para E/S de várias regiões e multilocação.
O serviço ajuda a garantir que os sistemas de memória possam se expandir perfeitamente e acompanhar os agentes em rápido crescimento e os dados associados. A garantia de disponibilidade em seu contrato de nível de serviço (SLA) se traduz em menos de 5 minutos de tempo de inatividade por ano. Os serviços de banco de dados vetorial puro, por outro lado, vêm com 9 horas ou mais de tempo de inatividade. Essa disponibilidade fornece uma base sólida para cargas de trabalho de missão crítica. Ao mesmo tempo, os vários modelos de serviço no Azure Cosmos DB, como Capacidade Reservada ou Sem Servidor, podem ajudar a reduzir os custos financeiros.
Simplicidade
O Azure Cosmos DB pode simplificar o gerenciamento e a arquitetura de dados integrando várias funcionalidades de banco de dados em uma única plataforma coesa.
Seus recursos integrados de banco de dados vetorial podem armazenar, indexar e consultar incorporações ao lado dos dados correspondentes em linguagens naturais ou de programação. Esse recurso permite maior consistência, escala e desempenho de dados.
Sua flexibilidade suporta as variadas modalidades e esquemas fluidos dos metadados, relacionamentos, entidades, resumos, histórico de bate-papo, preferências do usuário, dados sensoriais, decisões, fatos aprendidos ou outros dados operacionais envolvidos nos fluxos de trabalho dos agentes. O banco de dados indexa automaticamente todos os dados sem exigir gerenciamento de esquema ou índice, o que ajuda os agentes de IA a executar consultas complexas de forma rápida e eficiente.
O Azure Cosmos DB é totalmente gerenciado, o que elimina a sobrecarga de tarefas de administração de banco de dados, como dimensionamento, aplicação de patches e backups. Sem essa sobrecarga, os desenvolvedores podem se concentrar na criação e otimização de agentes de IA sem se preocupar com a infraestrutura de dados subjacente.
Funcionalidades avançadas
O Azure Cosmos DB incorpora recursos avançados, como o feed de alterações, que permite controlar e responder a alterações nos dados em tempo real. Esse recurso é útil para agentes de IA que precisam reagir a novas informações prontamente.
Além disso, o suporte integrado para gravações multimestre permite alta disponibilidade e resiliência para ajudar a garantir a operação contínua dos agentes de IA, mesmo após falhas regionais.
Os cinco níveis de consistência disponíveis (do forte ao eventual) também podem atender a várias cargas de trabalho distribuídas, dependendo dos requisitos do cenário.
Gorjeta
Você pode escolher entre duas APIs do Azure Cosmos DB para criar seu sistema de memória do agente de IA:
- Azure Cosmos DB para NoSQL, que oferece 99,999% de garantia de disponibilidade e fornece três algoritmos de pesquisa vetorial: IVF, HNSW e DiskANN
- Azure Cosmos DB para MongoDB baseado em vCore, que oferece 99,995% de garantia de disponibilidade e fornece dois algoritmos de pesquisa vetorial: FIV e HNSW (o DiskANN está chegando)
Para obter informações sobre as garantias de disponibilidade para essas APIs, consulte os SLAs de serviço.
Exemplo de implementação
Esta seção explora a implementação de um agente autônomo para processar consultas e reservas de viajantes em um aplicativo de viagem para uma linha de cruzeiro.
Os chatbots são um conceito de longa data, mas os agentes de IA estão avançando além da conversa humana básica para realizar tarefas baseadas em linguagem natural. Essas tarefas tradicionalmente exigiam lógica codificada. O agente de viagens de IA neste exemplo de implementação usa a estrutura do LangChain Agent para planejamento de agentes, uso de ferramentas e perceção.
O sistema de memória unificada do agente de viagens AI usa o banco de dados vetorial e os recursos de armazenamento de documentos do Azure Cosmos DB para atender às consultas dos viajantes e facilitar as reservas de viagens. Usar o Azure Cosmos DB para essa finalidade ajuda a garantir velocidade, escala e simplicidade, conforme descrito anteriormente.
O agente de exemplo opera dentro de um back-end Python FastAPI. Ele suporta interações do usuário através de uma interface de usuário React JavaScript.
Pré-requisitos
- Uma subscrição do Azure. Se não tiver uma, pode experimentar o Azure Cosmos DB gratuitamente durante 30 dias sem criar uma conta do Azure. A avaliação gratuita não requer cartão de crédito e nenhum compromisso segue o período de avaliação.
- Uma conta para a API OpenAI ou o Serviço OpenAI do Azure.
- Um cluster vCore no Azure Cosmos DB para MongoDB. Você pode criar um seguindo este início rápido.
- Um ambiente de desenvolvimento integrado, como o Visual Studio Code.
- Python 3.11.4 instalado no ambiente de desenvolvimento.
Faça o download do projeto
Todos os conjuntos de dados de código e exemplo estão disponíveis neste repositório GitHub. O repositório inclui estas pastas:
- loader: Esta pasta contém código Python para carregar documentos de exemplo e incorporações vetoriais no Azure Cosmos DB.
- api: Esta pasta contém o projeto Python FastAPI para hospedar o agente de viagens AI.
- web: Esta pasta contém código para a interface web React.
Carregar documentos de viagem no Azure Cosmos DB
O repositório GitHub contém um projeto Python no diretório loader . Destina-se a carregar os documentos de viagem de exemplo no Azure Cosmos DB.
Configurar o ambiente
Configure seu ambiente virtual Python no diretório loader executando o seguinte comando:
python -m venv venv
Ative seu ambiente e instale dependências no diretório do carregador :
venv\Scripts\activate
python -m pip install -r requirements.txt
Crie um arquivo chamado .env no diretório do carregador , para armazenar as seguintes variáveis de ambiente:
OPENAI_API_KEY="<your OpenAI key>"
MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"
Carregar documentos e vetores
O arquivo Python main.py serve como o ponto de entrada central para carregar dados no Azure Cosmos DB. Esse código processa os dados de viagem de exemplo do repositório GitHub, incluindo informações sobre navios e destinos. O código também gera pacotes de itinerário de viagem para cada navio e destino, para que os viajantes possam reservá-los usando o agente de IA. A ferramenta CosmosDBLoader é responsável pela criação de coleções, incorporações vetoriais e índices na instância do Azure Cosmos DB.
Eis o conteúdo da main.py:
from cosmosdbloader import CosmosDBLoader
from itinerarybuilder import ItineraryBuilder
import json
cosmosdb_loader = CosmosDBLoader(DB_Name='travel')
#read in ship data
with open('documents/ships.json') as file:
ship_json = json.load(file)
#read in destination data
with open('documents/destinations.json') as file:
destinations_json = json.load(file)
builder = ItineraryBuilder(ship_json['ships'],destinations_json['destinations'])
# Create five itinerary packages
itinerary = builder.build(5)
# Save itinerary packages to Cosmos DB
cosmosdb_loader.load_data(itinerary,'itinerary')
# Save destinations to Cosmos DB
cosmosdb_loader.load_data(destinations_json['destinations'],'destinations')
# Save ships to Cosmos DB, create vector store
collection = cosmosdb_loader.load_vectors(ship_json['ships'],'ships')
# Add text search index to ship name
collection.create_index([('name', 'text')])
Carregue os documentos, carregue os vetores e crie índices executando o seguinte comando a partir do diretório do carregador :
python main.py
Aqui está a saída de main.py:
--build itinerary--
--load itinerary--
--load destinations--
--load vectors ships--
Crie o agente de viagens de IA usando Python FastAPI
O agente de viagens AI é hospedado em uma API de back-end através do Python FastAPI, o que facilita a integração com a interface do usuário front-end. O projeto de API processa solicitações de agente aterrando os prompts LLM na camada de dados, especificamente os vetores e documentos no Azure Cosmos DB.
O agente faz uso de várias ferramentas, particularmente as funções Python fornecidas na camada de serviço da API. Este artigo se concentra no código necessário para agentes de IA dentro do código da API.
O projeto de API no repositório GitHub é estruturado da seguinte forma:
- Os componentes de modelagem de dados usam modelos Pydantic.
- Os componentes da camada da Web são responsáveis pelo roteamento de solicitações e pelo gerenciamento da comunicação.
- Os componentes da camada de serviço são responsáveis pela lógica de negócios primária e pela interação com a camada de dados, o Agente LangChain e as ferramentas do agente.
- Os componentes da camada de dados são responsáveis pela interação com o Azure Cosmos DB para armazenamento de documentos e pesquisa vetorial do MongoDB.
Configurar o ambiente para a API
Utilizamos Python versão 3.11.4 para o desenvolvimento e teste da API.
Configure seu ambiente virtual Python no diretório api :
python -m venv venv
Ative seu ambiente e instale dependências usando o arquivo de requisitos no diretório api :
venv\Scripts\activate
python -m pip install -r requirements.txt
Crie um arquivo chamado .env no diretório api , para armazenar suas variáveis de ambiente:
OPENAI_API_KEY="<your Open AI key>"
MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"
Agora que você configurou o ambiente e as variáveis, execute o seguinte comando no diretório api para iniciar o servidor:
python app.py
O servidor FastAPI é iniciado no loopback localhost 127.0.0.1 porta 8000 por padrão. Você pode acessar os documentos Swagger usando o seguinte endereço localhost: http://127.0.0.1:8000/docs
.
Usar uma sessão para a memória do agente de IA
É imperativo que o agente de viagens seja capaz de referenciar informações fornecidas anteriormente dentro da conversa em curso. Esta capacidade é comumente conhecida como memória no contexto de LLMs.
Para atingir esse objetivo, use o histórico de mensagens de chat armazenado na instância do Azure Cosmos DB. O histórico de cada sessão de chat é armazenado através de um ID de sessão para garantir que apenas as mensagens da sessão de conversação atual estão acessíveis. Essa necessidade é a razão por trás da existência de um Get Session
método na API. É um método de espaço reservado para gerenciar sessões da Web para ilustrar o uso do histórico de mensagens de chat.
Selecione Experimentar para /session/
.
{
"session_id": "0505a645526f4d68a3603ef01efaab19"
}
Para o agente de IA, você só precisa simular uma sessão. O método stubbed-out apenas retorna um ID de sessão gerado para rastrear o histórico de mensagens. Em uma implementação prática, essa sessão seria armazenada no Azure Cosmos DB e, potencialmente, no React localStorage
.
Aqui estão os conteúdos da web/session.py:
@router.get("/")
def get_session():
return {'session_id':str(uuid.uuid4().hex)}
Inicie uma conversa com o agente de viagens AI
Use o ID de sessão obtido na etapa anterior para iniciar um novo diálogo com o agente de IA, para que você possa validar sua funcionalidade. Realize o teste enviando a seguinte frase: "Quero tirar umas férias relaxantes".
Selecione Experimentar para /agent/agent_chat
.
Use este parâmetro de exemplo:
{
"input": "I want to take a relaxing vacation.",
"session_id": "0505a645526f4d68a3603ef01efaab19"
}
A execução inicial resulta numa recomendação para o Tranquil Breeze Cruise e o Fantasy Seas Adventure Cruise, porque o agente antecipa que são os cruzeiros mais relaxantes disponíveis através da pesquisa vetorial. Esses documentos têm a pontuação mais alta para similarity_search_with_score
chamados na camada de dados da API, data.mongodb.travel.similarity_search()
.
As pontuações de pesquisa de semelhança aparecem como saída da API para fins de depuração. Aqui está a saída após uma chamada para data.mongodb.travel.similarity_search()
:
0.8394561085977978
0.8086545112328692
2
Gorjeta
Se os documentos não estiverem sendo retornados para pesquisa vetorial, modifique o similarity_search_with_score
limite ou o valor do filtro de pontuação conforme necessário ([doc for doc, score in docs if score >=.78]
) em data.mongodb.travel.similarity_search()
.
Chamar agent_chat
pela primeira vez cria uma nova coleção nomeada history
no Azure Cosmos DB para armazenar a conversa por sessão. Essa chamada permite que o agente acesse o histórico de mensagens de bate-papo armazenado conforme necessário. Execuções subsequentes de agent_chat
com os mesmos parâmetros produzem resultados variáveis, porque se extrai da memória.
Percorra o agente de IA
Quando você está integrando o agente de IA na API, os componentes de pesquisa na Web são responsáveis por iniciar todas as solicitações. Os componentes de pesquisa na Web são seguidos pelo serviço de pesquisa e, finalmente, os componentes de dados.
Nesse caso específico, você usa uma pesquisa de dados do MongoDB que se conecta ao Azure Cosmos DB. As camadas facilitam a troca de componentes do modelo, com o agente de IA e o código da ferramenta do agente de IA residindo na camada de serviço. Essa abordagem permite a intercambiabilidade perfeita de fontes de dados. Também amplia as capacidades do agente de IA com funcionalidades ou ferramentas adicionais e mais complexas.
Camada de serviço
A camada de serviço forma a pedra angular da lógica de negócios principal. Neste cenário específico, a camada de serviço desempenha um papel crucial como o repositório para o código do LangChain Agent. Ele facilita a integração perfeita de prompts do usuário com dados do Azure Cosmos DB, memória de conversação e funções de agente para o agente de IA.
A camada de serviço emprega um módulo de padrão singleton para lidar com inicializações relacionadas ao agente no arquivo init.py . Aqui estão os conteúdos do serviço/init.py:
from dotenv import load_dotenv
from os import environ
from langchain.globals import set_llm_cache
from langchain_openai import ChatOpenAI
from langchain_mongodb.chat_message_histories import MongoDBChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.agents import AgentExecutor, create_openai_tools_agent
from service import TravelAgentTools as agent_tools
load_dotenv(override=False)
chat : ChatOpenAI | None=None
agent_with_chat_history : RunnableWithMessageHistory | None=None
def LLM_init():
global chat,agent_with_chat_history
chat = ChatOpenAI(model_name="gpt-3.5-turbo-16k",temperature=0)
tools = [agent_tools.vacation_lookup, agent_tools.itinerary_lookup, agent_tools.book_cruise ]
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a helpful and friendly travel assistant for a cruise company. Answer travel questions to the best of your ability providing only relevant information. In order to book a cruise you will need to capture the person's name.",
),
MessagesPlaceholder(variable_name="chat_history"),
("user", "Answer should be embedded in html tags. {input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)
#Answer should be embedded in HTML tags. Only answer questions related to cruise travel, If you can not answer respond with \"I am here to assist with your travel questions.\".
agent = create_openai_tools_agent(chat, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
lambda session_id: MongoDBChatMessageHistory( database_name="travel",
collection_name="history",
connection_string=environ.get("MONGO_CONNECTION_STRING"),
session_id=session_id),
input_messages_key="input",
history_messages_key="chat_history",
)
LLM_init()
O arquivo init.py inicia o carregamento de variáveis de ambiente de um arquivo .env usando o load_dotenv(override=False)
método. Em seguida, uma variável global nomeada agent_with_chat_history
é instanciada para o agente. Este agente destina-se a ser utilizado por TravelAgent.py.
O LLM_init()
método é invocado durante a inicialização do módulo para configurar o agente de IA para conversação por meio da camada da Web da API. O objeto OpenAI chat
é instanciado através do modelo GPT-3.5 e incorpora parâmetros específicos, como nome do modelo e temperatura. O chat
objeto, a lista de ferramentas e o modelo de prompt são combinados para gerar AgentExecutor
o , que opera como o agente de viagens de IA.
O agente com histórico, agent_with_chat_history
, é estabelecido através do histórico de RunnableWithMessageHistory
bate-papo (MongoDBChatMessageHistory
). Esta ação permite-lhe manter um histórico de conversações completo através do Azure Cosmos DB.
Pedido
O prompt LLM começou com a simples declaração "Você é um assistente de viagem útil e amigável para uma empresa de cruzeiros." No entanto, os testes mostraram que você poderia obter resultados mais consistentes incluindo a instrução "Responda às perguntas de viagem da melhor maneira possível, fornecendo apenas informações relevantes. Para reservar um cruzeiro, capturar o nome da pessoa é essencial." Os resultados aparecem em formato HTML para melhorar o apelo visual da interface web.
Ferramentas do agente
As ferramentas são interfaces que um agente pode usar para interagir com o mundo, muitas vezes através de chamadas de função.
Ao criar um agente, você deve fornecê-lo com um conjunto de ferramentas que ele possa usar. O @tool
decorador oferece a abordagem mais direta para definir uma ferramenta personalizada.
Por padrão, o decorador usa o nome da função como o nome da ferramenta, embora você possa substituí-lo fornecendo uma cadeia de caracteres como o primeiro argumento. O decorador usa o docstring da função como descrição da ferramenta, por isso requer o provisionamento de um docstring.
Aqui estão os conteúdos do serviço/TravelAgentTools.py:
from langchain_core.tools import tool
from langchain.docstore.document import Document
from data.mongodb import travel
from model.travel import Ship
@tool
def vacation_lookup(input:str) -> list[Document]:
"""find information on vacations and trips"""
ships: list[Ship] = travel.similarity_search(input)
content = ""
for ship in ships:
content += f" Cruise ship {ship.name} description: {ship.description} with amenities {'/n-'.join(ship.amenities)} "
return content
@tool
def itinerary_lookup(ship_name:str) -> str:
"""find ship itinerary, cruise packages and destinations by ship name"""
it = travel.itnerary_search(ship_name)
results = ""
for i in it:
results += f" Cruise Package {i.Name} room prices: {'/n-'.join(i.Rooms)} schedule: {'/n-'.join(i.Schedule)}"
return results
@tool
def book_cruise(package_name:str, passenger_name:str, room: str )-> str:
"""book cruise using package name and passenger name and room """
print(f"Package: {package_name} passenger: {passenger_name} room: {room}")
# LLM defaults empty name to John Doe
if passenger_name == "John Doe":
return "In order to book a cruise I need to know your name."
else:
if room == '':
return "which room would you like to book"
return "Cruise has been booked, ref number is 343242"
O arquivo TravelAgentTools.py define três ferramentas:
vacation_lookup
conduz uma pesquisa vetorial no Azure Cosmos DB. Servesimilarity_search
para recuperar material relevante relacionado com viagens.itinerary_lookup
Recupera detalhes e horários do pacote de cruzeiro para um navio de cruzeiro especificado.book_cruise
reserva um pacote de cruzeiro para um passageiro.
Instruções específicas ("Para reservar um cruzeiro, preciso saber seu nome") podem ser necessárias para garantir a captura do nome do passageiro e do número do quarto para reservar o pacote de cruzeiro, mesmo que você tenha incluído essas instruções no prompt do LLM.
Agente de IA
O conceito fundamental subjacente aos agentes é usar um modelo de linguagem para selecionar uma sequência de ações a serem executadas.
Aqui estão os conteúdos do serviço/TravelAgent.py:
from .init import agent_with_chat_history
from model.prompt import PromptResponse
import time
from dotenv import load_dotenv
load_dotenv(override=False)
def agent_chat(input:str, session_id:str)->str:
start_time = time.time()
results=agent_with_chat_history.invoke(
{"input": input},
config={"configurable": {"session_id": session_id}},
)
return PromptResponse(text=results["output"],ResponseSeconds=(time.time() - start_time))
O arquivo TravelAgent.py é simples, porque agent_with_chat_history
e suas dependências (ferramentas, prompt e LLM) são inicializadas e configuradas no arquivo init.py . Esse arquivo chama o agente usando a entrada recebida do usuário, juntamente com o ID da sessão para a memória de conversação. Depois, PromptResponse
(modelo/prompt) é retornado com a saída do agente e o tempo de resposta.
Integração do agente de IA com a interface de usuário do React
Com o carregamento bem-sucedido dos dados e a acessibilidade do agente de IA através da API, agora você pode completar a solução estabelecendo uma interface de usuário da Web (usando o React) para seu site de viagens. O uso dos recursos do React ajuda a ilustrar a integração perfeita do agente de IA em um site de viagens. Essa integração melhora a experiência do usuário com um assistente de viagem conversacional para consultas e reservas.
Configurar o ambiente para o React
Instale o Node.js e as dependências antes de testar a interface React.
Execute o seguinte comando a partir do diretório da Web para executar uma instalação limpa das dependências do projeto. A instalação pode levar algum tempo.
npm ci
Em seguida, crie um arquivo chamado .env dentro do diretório da Web para facilitar o armazenamento de variáveis de ambiente. Inclua os seguintes detalhes no arquivo .env recém-criado:
REACT_APP_API_HOST=http://127.0.0.1:8000
Agora, execute o seguinte comando a partir do diretório da Web para iniciar a interface do usuário da Web React:
npm start
A execução do comando anterior abre o aplicativo Web React.
Percorra a interface web do React
O projeto web do repositório GitHub é um aplicativo simples para facilitar a interação do usuário com o agente de IA. Os principais componentes necessários para conversar com o agente são TravelAgent.js e ChatLayout.js. O arquivo Main.js serve como módulo central ou página de destino do usuário.
Principal
O componente principal serve como o gerente central do aplicativo. Funciona como o ponto de entrada designado para o encaminhamento. Dentro da função de renderização, ele produz código JSX para delinear o layout da página principal. Esse layout engloba elementos de espaço reservado para o aplicativo, como logotipos e links, uma seção que abriga o componente agente de viagens e um rodapé que contém um exemplo de isenção de responsabilidade sobre a natureza do aplicativo.
Eis o conteúdo da main.js:
import React, { Component } from 'react'
import { Stack, Link, Paper } from '@mui/material'
import TravelAgent from './TripPlanning/TravelAgent'
import './Main.css'
class Main extends Component {
constructor() {
super()
}
render() {
return (
<div className="Main">
<div className="Main-Header">
<Stack direction="row" spacing={5}>
<img src="/mainlogo.png" alt="Logo" height={'120px'} />
<Link
href="#"
sx={{ color: 'white', fontWeight: 'bold', fontSize: 18 }}
underline="hover"
>
Ships
</Link>
<Link
href="#"
sx={{ color: 'white', fontWeight: 'bold', fontSize: 18 }}
underline="hover"
>
Destinations
</Link>
</Stack>
</div>
<div className="Main-Body">
<div className="Main-Content">
<Paper elevation={3} sx={{p:1}} >
<Stack
direction="row"
justifyContent="space-evenly"
alignItems="center"
spacing={2}
>
<Link href="#">
<img
src={require('./images/destinations.png')} width={'400px'} />
</Link>
<TravelAgent ></TravelAgent>
<Link href="#">
<img
src={require('./images/ships.png')} width={'400px'} />
</Link>
</Stack>
</Paper>
</div>
</div>
<div className="Main-Footer">
<b>Disclaimer: Sample Application</b>
<br />
Please note that this sample application is provided for demonstration
purposes only and should not be used in production environments
without proper validation and testing.
</div>
</div>
)
}
}
export default Main
Agente de viagens
O componente de agente de viagens tem um propósito simples: capturar as entradas do usuário e exibir as respostas. Ele desempenha um papel fundamental no gerenciamento da integração com o agente de IA back-end, principalmente capturando sessões e encaminhando prompts do usuário para o serviço FastAPI. As respostas resultantes são armazenadas em uma matriz para exibição, facilitada pelo componente de layout de bate-papo.
Aqui estão os conteúdos do TripPlanning/TravelAgent.js:
import React, { useState, useEffect } from 'react'
import { Button, Box, Link, Stack, TextField } from '@mui/material'
import SendIcon from '@mui/icons-material/Send'
import { Dialog, DialogContent } from '@mui/material'
import ChatLayout from './ChatLayout'
import './TravelAgent.css'
export default function TravelAgent() {
const [open, setOpen] = React.useState(false)
const [session, setSession] = useState('')
const [chatPrompt, setChatPrompt] = useState(
'I want to take a relaxing vacation.',
)
const [message, setMessage] = useState([
{
message: 'Hello, how can I assist you today?',
direction: 'left',
bg: '#E7FAEC',
},
])
const handlePrompt = (prompt) => {
setChatPrompt('')
setMessage((message) => [
...message,
{ message: prompt, direction: 'right', bg: '#E7F4FA' },
])
console.log(session)
fetch(process.env.REACT_APP_API_HOST + '/agent/agent_chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ input: prompt, session_id: session }),
})
.then((response) => response.json())
.then((res) => {
setMessage((message) => [
...message,
{ message: res.text, direction: 'left', bg: '#E7FAEC' },
])
})
}
const handleSession = () => {
fetch(process.env.REACT_APP_API_HOST + '/session/')
.then((response) => response.json())
.then((res) => {
setSession(res.session_id)
})
}
const handleClickOpen = () => {
setOpen(true)
}
const handleClose = (value) => {
setOpen(false)
}
useEffect(() => {
if (session === '') handleSession()
}, [])
return (
<Box>
<Dialog onClose={handleClose} open={open} maxWidth="md" fullWidth="true">
<DialogContent>
<Stack>
<Box sx={{ height: '500px' }}>
<div className="AgentArea">
<ChatLayout messages={message} />
</div>
</Box>
<Stack direction="row" spacing={0}>
<TextField
sx={{ width: '80%' }}
variant="outlined"
label="Message"
helperText="Chat with AI Travel Agent"
defaultValue="I want to take a relaxing vacation."
value={chatPrompt}
onChange={(event) => setChatPrompt(event.target.value)}
></TextField>
<Button
variant="contained"
endIcon={<SendIcon />}
sx={{ mb: 3, ml: 3, mt: 1 }}
onClick={(event) => handlePrompt(chatPrompt)}
>
Submit
</Button>
</Stack>
</Stack>
</DialogContent>
</Dialog>
<Link href="#" onClick={() => handleClickOpen()}>
<img src={require('.././images/planvoyage.png')} width={'400px'} />
</Link>
</Box>
)
}
Selecione Planejar sua viagem sem esforço para abrir o assistente de viagem.
Layout do bate-papo
O componente de layout do bate-papo supervisiona a organização do bate-papo. Ele processa sistematicamente as mensagens de bate-papo e implementa a formatação especificada no message
objeto JSON.
Aqui estão os conteúdos do TripPlanning/ChatLayout.js:
import React from 'react'
import { Box, Stack } from '@mui/material'
import parse from 'html-react-parser'
import './ChatLayout.css'
export default function ChatLayout(messages) {
return (
<Stack direction="column" spacing="1">
{messages.messages.map((obj, i = 0) => (
<div className="bubbleContainer" key={i}>
<Box
key={i++}
className="bubble"
sx={{ float: obj.direction, fontSize: '10pt', background: obj.bg }}
>
<div>{parse(obj.message)}</div>
</Box>
</div>
))}
</Stack>
)
}
Os prompts do usuário estão no lado direito e coloridos em azul. As respostas do agente de viagens AI estão no lado esquerdo e coloridas em verde. Como mostra a imagem a seguir, as respostas formatadas em HTML são contabilizadas na conversa.
Quando seu agente de IA estiver pronto para entrar em produção, você poderá usar o cache semântico para melhorar o desempenho da consulta em 80% e reduzir os custos de inferência LLM e chamada de API. Para implementar o cache semântico, consulte este post no blog do Coder Estocástico.