Comparteix a través de


Agente de inteligencia artificial

Los agentes de inteligencia artificial están diseñados para realizar tareas específicas, responder preguntas y automatizar procesos para los usuarios. Estos agentes varían ampliamente en complejidad. Van desde bots de chat simples, hasta copilotos, hasta asistentes avanzados de inteligencia artificial en forma de sistemas digitales o robóticos que pueden ejecutar flujos de trabajo complejos de forma autónoma.

En este artículo se proporcionan información general conceptual y ejemplos de implementación detallados para los agentes de inteligencia artificial.

¿Qué son los agentes de inteligencia artificial?

A diferencia de los modelos de lenguaje grandes (LLM) autónomos o de los sistemas de software o hardware basados en reglas, el agente de inteligencia artificial tiene estas características comunes:

  • Planificación: El agente de inteligencia artificial puede planear y secuenciar acciones para lograr objetivos específicos. La integración de LLM ha revolucionado sus capacidades de planificación.
  • Herramienta de uso: El agente de inteligencia artificial avanzado puede usar varias herramientas, como la ejecución de código, la búsqueda y las funcionalidades de cálculo, para realizar tareas de forma eficaz. Los agentes de inteligencia artificial suelen usar herramientas a través de llamadas a funciones.
  • Percepción: los agentes de inteligencia artificial pueden percibir y procesar información de su entorno, para que sean más interactivas y conscientes del contexto. Esta información incluye datos visuales, auditivos y otros datos sensoriales.
  • Memoria: Los agentes de inteligencia artificial tienen la capacidad de recordar interacciones anteriores (uso y percepción de herramientas) y comportamientos (uso y planificación de herramientas). Almacenan estas experiencias e incluso realizan autorreflexiones para fundamentar futuras acciones. Este componente de memoria permite la continuidad y la mejora del rendimiento del agente a lo largo del tiempo.

Nota:

El uso del término memoria en el contexto de los agentes de IA es diferente del concepto de memoria del equipo (por ejemplo, volátil, no volátil y memoria persistente).

Copilotos

Los copilotos son un tipo de agente de inteligencia artificial. Funcionan junto con usuarios en lugar de trabajar de forma independiente. A diferencia de los agentes totalmente automatizados, los copilotos proporcionan sugerencias y recomendaciones para ayudar a los usuarios a completar tareas.

Por ejemplo, cuando un usuario escribe un correo electrónico, un copiloto podría sugerir frases, oraciones o párrafos. El usuario también puede pedir al copiloto que busque información relevante en otros correos electrónicos o archivos para apoyar la sugerencia (consulte la generación aumentada por recuperación). El usuario puede aceptar, rechazar o editar los pasajes sugeridos.

Agentes autónomos

Los agentes autónomos pueden funcionar de forma más independiente. Al configurar agentes autónomos para ayudar con la composición del correo electrónico, puede permitirles realizar las tareas siguientes:

  • Consultar los correos electrónicos, chats, archivos y demás información interna y pública existentes que estén relacionados con el asunto en cuestión.
  • Realizar análisis cualitativos o cuantitativos sobre la información recopilada y extraer conclusiones relevantes para el correo electrónico.
  • Escribir el correo electrónico completo en función de las conclusiones e incorporar pruebas complementarias.
  • Adjuntar archivos relevantes al correo electrónico.
  • Revise el correo electrónico para asegurarse de que toda la información incorporada sea objetivamente precisa y de que las aserciones sean válidas.
  • Seleccione los destinatarios adecuados en Para, CC y CCO, y busque sus direcciones de correo electrónico.
  • Programar una hora adecuada para enviar el correo electrónico.
  • Realizar seguimientos si se esperan respuestas pero no se reciben.

Puede configurar los agentes para realizar cada una de las tareas anteriores con o sin aprobación humana.

Sistemas multiagente

Una estrategia popular para lograr agentes autónomos eficaces es el uso de sistemas multiagente. En los sistemas multiagente, varios agentes autónomos, ya sean digitales o robóticos, interactúan o trabajan juntos para alcanzar objetivos individuales o colectivos. Los agentes del sistema pueden operar de forma independiente y poseer su propio conocimiento o información. Cada agente también puede tener la capacidad de percibir su entorno, tomar decisiones y ejecutar acciones en función de sus objetivos.

Los sistemas multiagente tienen estas características clave:

  • Autónomos: cada agente funciona de forma independiente. Toma sus propias decisiones sin intervención directa humana ni control por parte de otros agentes.
  • Interactivos: los agentes se comunican y colaboran entre sí para compartir información, negociar y coordinar sus acciones. Esta interacción puede producirse a través de varios protocolos y canales de comunicación.
  • Orientados a objetivos: los agentes de un sistema multiagente están diseñados para lograr objetivos específicos, que se pueden alinear con objetivos individuales o con un objetivo compartido entre los agentes.
  • Distribuidos: los sistemas multiagente funcionan de forma distribuida, sin un único punto de control. Esta distribución mejora la solidez, la escalabilidad y la eficiencia de los recursos del sistema.

Un sistema multiagente proporciona las siguientes ventajas sobre un copiloto o una sola instancia de inferencia de LLM:

  • Razonamiento dinámico: en comparación con el razonamiento en cadena o en árbol, los sistemas multiagente permiten una navegación dinámica a través de varias vías de razonamiento.
  • Capacidades sofisticadas: los sistemas multiagente pueden gestionar problemas complejos o a gran escala mediante la realización de procesos exhaustivos de toma de decisiones y la distribución de tareas entre varios agentes.
  • Memoria mejorada: los sistemas multiagente con memoria pueden superar las ventanas de contexto de las VM para permitir una mejor comprensión y retención de la información.

Implementación de agentes de IA

Razonamiento y planificación

El razonamiento y la planificación complejos son el sello distintivo de los agentes autónomos avanzados. Los marcos populares para agentes autónomos incorporan una o varias de las metodologías siguientes (con vínculos a páginas de archivo arXiv) para el razonamiento y la planificación:

  • Autoconsulta

    Mejora la cadena de pensamiento haciendo que el modelo se plantee explícitamente (y responda) preguntas de seguimiento antes de responder a la pregunta inicial.

  • Razón y acción (ReAct)

    Use LLM para generar seguimientos de razonamiento y acciones específicas de tareas de manera intercalada. Los seguimientos de razonamiento ayudan al modelo a inducir, realizar un seguimiento y actualizar los planes de acción, junto con el control de excepciones. Las acciones permiten que el modelo se conecte con orígenes externos, como bases de conocimiento o entornos, para recopilar información adicional.

  • Planear y resolver

    Diseñar un plan para dividir toda la tarea en subtareas más pequeñas y, a continuación, llevar a cabo las subtareas según el plan. Este enfoque mitiga los errores de cálculo, los errores de paso en falso y los errores de malentendido semántico que a menudo están presentes en las indicaciones de cadena de pensamiento (CoT) de disparo cero.

  • Reflexión/autocrítica

    Use agentes de reflexión que reflejen verbalmente las señales de comentarios de tareas. Estos agentes mantienen su propio texto reflectante en un búfer de memoria episódica para inducir una mejor toma de decisiones en los ensayos posteriores.

Marcos de trabajo

Varios marcos y herramientas pueden facilitar el desarrollo y la implementación de los agentes de inteligencia artificial.

Para el uso y la percepción de herramientas que no requieren una planificación y memoria sofisticadas, algunos marcos orquestadores de LLM populares son LangChain, LlamaIndex, Prompt Flow y Semantic Kernel.

Para flujos de trabajo avanzados y autónomos de planificación y ejecución, AutoGen propulsó la oleada multiagente que comenzó a finales de 2022. La API Assistants de OpenAI permite a sus usuarios crear agentes de forma nativa en el ecosistema de GPT. LangChain Agents y LlamaIndex Agents también surgieron a la vez.

Sugerencia

El ejemplo de implementación más adelante en este artículo muestra cómo crear un sistema simple de varios agentes mediante uno de los marcos populares y un sistema de memoria de agente unificado.

Sistema de memoria del agente de inteligencia artificial

La práctica habitual para experimentar con aplicaciones mejoradas con inteligencia artificial entre 2022 y 2024 ha sido usar sistemas de administración de bases de datos independientes para diversos flujos de trabajo o tipos de datos. Por ejemplo, puede usar una base de datos en memoria para el almacenamiento en caché, una base de datos relacional para los datos operativos (incluidos los registros de seguimiento o actividad y el historial de conversaciones de LLM) y una base de datos vectorial pura para la administración de inserciones.

Sin embargo, esta práctica de usar una red compleja de bases de datos independientes puede afectar al rendimiento del agente de inteligencia. La integración de todas estas bases de datos dispares en un sistema de memoria cohesivo, interoperable y resistente para los agentes de inteligencia artificial es su propio desafío.

Además, muchos de los servicios de base de datos usados con frecuencia no son óptimos para la velocidad y escalabilidad que necesitan los sistemas de agentes de inteligencia artificial. Las debilidades individuales de estas bases de datos se agravan en los sistemas multiagente.

Bases de datos en memoria

Las bases de datos en memoria son excelentes por su velocidad, pero pueden tener problemas con la persistencia de datos a gran escala que necesita el agente de inteligencia artificial.

Bases de datos relacionales

Las bases de datos relacionales no son ideales para las diversas modalidades y esquemas fluidos de los datos que administran los agentes. Las bases de datos relacionales requieren esfuerzos manuales e incluso tiempo de inactividad para administrar el aprovisionamiento, la creación de particiones y el particionamiento.

Bases de datos vectoriales puras

Las bases de datos vectoriales puras tienden a ser menos eficaces para las operaciones transaccionales, las actualizaciones en tiempo real y las cargas de trabajo distribuidas. Las bases de datos vectoriales puras populares actualmente suelen ofrecer:

  • No hay ninguna garantía de lecturas y escrituras.
  • Rendimiento de ingesta limitado.
  • Baja disponibilidad (por debajo del 99,9 %, o interrupción anual de casi 9 horas o más).
  • Un nivel de coherencia (eventual).
  • Índice de vectores en memoria que consume muchos recursos.
  • Opciones limitadas para multiinquilino.
  • Seguridad limitada.

Características de un sistema sólido de memoria del agente de IA

Al igual que los sistemas eficientes de administración de bases de datos son fundamentales para el rendimiento de las aplicaciones informáticas, también lo es proporcionar a los agentes impulsados por LLM información relevante y útil para guiar su inferencia. Los sistemas de memoria sólidos permiten organizar y almacenar varios tipos de información que los agentes pueden recuperar en el momento de la inferencia.

En la actualidad, las aplicaciones impulsadas por LLM suelen usar la generación aumentada por recuperación que usa la búsqueda semántica básica o el vector de búsqueda para recuperar pasajes o documentos. El vector de búsqueda puede ser útil para buscar información general. Sin embargo, el vector de búsqueda podría no capturar el contexto, la estructura o las relaciones específicos que son relevantes para una tarea o dominio concretos.

Por ejemplo, si la tarea es escribir código, es posible que el vector de búsqueda no pueda recuperar el árbol de sintaxis, el diseño del sistema de archivos, los resúmenes de código o las firmas de API que son importantes para generar código coherente y correcto. De forma similar, si la tarea es trabajar con datos tabulares, es posible que el vector de búsqueda no pueda recuperar el esquema, las claves externas, los procedimientos almacenados o los informes que son útiles para consultar o analizar los datos.

Tejer una red de bases de datos independientes en memoria, relacionales y vectoriales (como se describe anteriormente) no es una solución óptima para los distintos tipos de datos. Este enfoque podría funcionar para sistemas de agentes prototípicos. Sin embargo, agrega cuellos de botella de complejidad y rendimiento que pueden dificultar el rendimiento de los agentes autónomos avanzados.

Un sistema de memoria sólido debe tener las siguientes características.

Multimodal

Los sistemas de memoria de los agentes de inteligencia artificial deben proporcionar colecciones que almacenen metadatos, relaciones, entidades, resúmenes u otros tipos de información que puedan ser útiles para varias tareas y dominios. Estas colecciones se pueden basar en la estructura y el formato de los datos, como documentos, tablas o código. O bien, se pueden basar en el contenido y el significado de los datos, como conceptos, asociaciones o pasos de procedimiento.

Los sistemas de memoria no solo son críticos para los agentes de inteligencia artificial. También son importantes para los seres humanos que desarrollan, mantienen y usan estos agentes.

Por ejemplo, los seres humanos pueden necesitar supervisar los flujos de trabajo de planificación y ejecución de los agentes casi en tiempo real. Mientras supervisan, los humanos pueden intervenir para orientar o editar en línea los diálogos o monólogos de los agentes. Los seres humanos también pueden necesitar auditar el razonamiento y las acciones de los agentes para comprobar la validez de la salida final.

Es probable que las interacciones de agentes humanos estén en lenguajes naturales o de programación, mientras que los agentes "piensen", "aprendan" y "recuerden" a través de inserciones. Esta diferencia plantea otro requisito en la coherencia de los sistemas de memoria entre modalidades de datos.

Operativos

Los sistemas de memoria deben proporcionar bancos de memoria que almacenan información relevante para la interacción con el usuario y el entorno. Esta información puede incluir el historial de chat, las preferencias del usuario, los datos sensoriales, las decisiones tomadas, los hechos aprendidos u otros datos operativos que se actualizan con alta frecuencia y a grandes volúmenes.

Estos bancos de memoria pueden ayudar a los agentes a recordar información a corto y largo plazo, evitar repetirse o contradecirse y mantener la coherencia de las tareas. Estos requisitos deben cumplirse incluso si los agentes realizan una multitud de tareas no relacionadas sucesivamente. En casos avanzados, los agentes también pueden probar combinaciones de numerosos planes de bifurcación que divergen o convergen en diferentes puntos.

Se puede compartir, pero también separar

A nivel de macro, los sistemas de memoria deben permitir que varios agentes de inteligencia artificial colaboren en un problema o procesen diferentes aspectos del problema proporcionando memoria compartida accesible a todos los agentes. La memoria compartida puede facilitar el intercambio de información y la coordinación de acciones entre los agentes.

Al mismo tiempo, el sistema de memoria debe permitir que los agentes conserven su propio rol y características, como sus colecciones únicas de mensajes y recuerdos.

Creación de un sistema de memoria sólido para agentes de inteligencia artificial

Las características anteriores exigen que los sistemas de memoria de los agentes de inteligencia artificial sean altamente escalables y rápidos. Es posible que la combinación de bases de datos dispares en memoria, relacionales y vectoriales (como se ha descrito anteriormente) funcione para aplicaciones habilitadas para IA en fase temprana. Sin embargo, este enfoque agrega cuellos de botella de complejidad y rendimiento que pueden dificultar el rendimiento de los agentes autónomos avanzados.

En lugar de todas las bases de datos independientes, Azure Cosmos DB puede servir como una solución unificada para los sistemas de memoria del agente de inteligencia artificial. Su solidez permitió al servicio ChatGPT de OpenAI escalar dinámicamente con gran fiabilidad y bajo mantenimiento. Con tecnología de un motor de secuencia de registros Atom, es el primer servicio de base de datos NoSQL, relacional y vectorial distribuido globalmente del mundo que ofrece un modo sin servidor. Los agentes de inteligencia artificial basados en Azure Cosmos DB ofrecen velocidad, escala y simplicidad.

Velocidad

Azure Cosmos DB proporciona latencia de milisegundos de un solo dígito. Esta funcionalidad hace que sea adecuado para los procesos que requieren un acceso y administración de datos rápidos. Estos procesos incluyen el almacenamiento en caché (almacenamiento en caché tradicional ysemántico), las transacciones y las cargas de trabajo operativas.

La baja latencia es fundamental para los agentes de inteligencia artificial que necesitan realizar razonamientos complejos, tomar decisiones en tiempo real y proporcionar respuestas inmediatas. Además, el uso del servicio del algoritmo DiskANN proporciona una búsqueda de vectores precisa y rápida con un consumo mínimo de memoria.

Escala

Azure Cosmos DB está diseñado para la distribución global y la escalabilidad horizontal. Ofrece compatibilidad con E/S de varias regiones y multiinquilino.

El servicio ayuda a garantizar que los sistemas de memoria puedan expandirse sin problemas y mantenerse al día de los agentes y los datos asociados rápidamente. La garantía de disponibilidad en su acuerdo de nivel de servicio (SLA) se traduce en menos de 5 minutos de tiempo de inactividad al año. Los servicios de base de datos vectoriales puros, por el contrario, incluyen 9 horas o más de tiempo de inactividad. Esta disponibilidad proporciona una base sólida para cargas de trabajo críticas. Al mismo tiempo, los distintos modelos de servicio de Azure Cosmos DB, como la capacidad reservada o sin servidor, pueden ayudar a reducir los costos financieros.

Simplicidad

Azure Cosmos DB puede simplificar la administración de datos y la arquitectura al integrar múltiples funcionalidades de bases de datos en una plataforma única y cohesionada.

Sus funcionalidades de base de datos vectoriales integradas pueden almacenar, indexar e insertar consultas junto con los datos correspondientes en lenguajes naturales o de programación. Esta funcionalidad permite una mayor coherencia, escala y rendimiento de los datos.

Su flexibilidad admite las diversas modalidades y esquemas fluidos de los metadatos, relaciones, entidades, resúmenes, historial de chat, preferencias del usuario, datos sensoriales, decisiones, hechos aprendidos u otros datos operativos que intervienen en los flujos de trabajo de los agentes. La base de datos indexa automáticamente todos los datos sin necesidad de administrar esquemas o índices, lo que ayuda a los agentes de inteligencia artificial a realizar consultas complejas con rapidez y eficacia.

Azure Cosmos DB está totalmente administrado, lo que elimina la sobrecarga de las tareas de administración de bases de datos, como el escalado, la aplicación de revisiones y las copias de seguridad. Sin esta sobrecarga, los desarrolladores pueden centrarse en la creación y optimización de agentes de inteligencia artificial sin preocuparse por la infraestructura de datos subyacente.

Características avanzadas

Azure Cosmos DB incorpora características avanzadas, como la fuente de cambios, que permite el seguimiento y la respuesta a los cambios en los datos en tiempo real. Esta funcionalidad es útil para los agentes de inteligencia artificial que necesitan reaccionar rápidamente a la nueva información.

Además, la compatibilidad integrada con escrituras de arquitectura multimaestro permite alta disponibilidad y resistencia, ayuda a garantizar el funcionamiento continuo de los agentes de inteligencia artificial incluso después de errores regionales.

Los cinco niveles de coherencia disponibles (de fuerte a eventual) también pueden satisfacer varias cargas de trabajo distribuidas en función de los requisitos del escenario.

Sugerencia

Puede elegir entre dos API de Azure Cosmos DB para compilar el sistema de memoria del agente de IA:

Para obtener información sobre las garantías de disponibilidad para estas API, consulte los Acuerdos de nivel de servicio.

Ejemplo de implementación

En esta sección se explora la implementación de un agente autónomo para procesar consultas de viajeros y reservas en una aplicación de viajes de una línea de cruceros.

Los bots de chat son un concepto de larga duración, pero los agentes de inteligencia artificial están avanzando más allá de la conversación humana básica para llevar a cabo tareas basadas en lenguaje natural. Estas tareas tradicionalmente requerían lógica codificada. El agente de viajes de IA de este ejemplo de implementación usa el marco del agente LangChain para planear el agente, el uso de herramientas y la percepción.

El sistema de memoria unificada del agente de viajes de IA usa la base de datos vectorial y las capacidades de almacenamiento de documentos de Azure Cosmos DB para atender las consultas de los viajeros y facilitar las reservas de viajes. El uso de Azure Cosmos DB para este propósito ayuda a garantizar la velocidad, la escala y la simplicidad, como se ha descrito anteriormente.

El agente de ejemplo funciona dentro de un back-end de Python FastAPI. Admite interacciones de usuario a través de una interfaz de usuario de JavaScript de React.

Requisitos previos

  • Suscripción a Azure. Si no tiene una, puede probar Azure Cosmos DB de forma gratuita durante 30 días sin crear una cuenta de Azure. La evaluación gratuita no requiere una tarjeta de crédito y ningún compromiso sigue el período de prueba.
  • Una cuenta para la API de OpenAI o Azure OpenAI Service.
  • Un clúster en el núcleo virtual de Azure Cosmos DB for MongoDB. Puede crear uno siguiendo este inicio rápido.
  • Un entorno de desarrollo integrado, como Visual Studio Code.
  • Python 3.11.4 instalado en el entorno de desarrollo.

Descarga del proyecto

Todos los conjuntos de datos de código y ejemplo están disponibles en este repositorio de GitHub. El repositorio incluye estas carpetas:

  • cargador: esta carpeta contiene código de Python para cargar documentos de ejemplo e incrustaciones de vectores en Azure Cosmos DB.
  • api: esta carpeta contiene el proyecto FastAPI de Python para hospedar el agente de viajes de IA.
  • web: esta carpeta contiene código para la interfaz web de React.

Carga de documentos de viaje en Azure Cosmos DB

El repositorio de GitHub contiene un proyecto de Python en el directorio del cargador. Está pensado para cargar los documentos de viaje de ejemplo en Azure Cosmos DB.

Configuración del entorno

Configure el entorno virtual de Python en el directorio cargador mediante la ejecución del siguiente comando:

    python -m venv venv

Active el entorno e instale las dependencias en el directorio cargador:

    venv\Scripts\activate
    python -m pip install -r requirements.txt

Cree un archivo, denominado .env en el directorio cargador, para almacenar las siguientes variables de entorno:

    OPENAI_API_KEY="<your OpenAI key>"
    MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"

Carga de documentos y vectores

El archivo de Python main.py sirve como punto de entrada central para cargar datos en Azure Cosmos DB. Este código procesa los datos de viaje de ejemplo del repositorio de GitHub, incluida la información sobre los buques y destinos. El código también genera paquetes de itinerarios de viaje para cada barco y destino, para que los viajeros puedan reservarlos mediante el agente de IA. La herramienta CosmosDBLoader es responsable de crear colecciones, inserciones vectoriales e índices en la instancia de Azure Cosmos DB.

Este es el contenido de 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')])

Cargue los documentos, cargue los vectores y cree índices ejecutando el siguiente comando desde el directorio cargador:

    python main.py

Esta es la salida de main.py:

--build itinerary--
--load itinerary--
--load destinations--
--load vectors ships--

Compilación del agente de viajes de IA mediante Python FastAPI

El agente de viajes de IA se hospeda en una API de back-end a través de Python FastAPI, lo que facilita la integración con la interfaz de usuario front-end. El proyecto de API procesa las peticiones de los agentes basando las solicitudes de LLM en la capa de datos, concretamente en los vectores y documentos de Azure Cosmos DB.

El agente usa varias herramientas, especialmente las funciones de Python proporcionadas en el nivel de servicio de API. Este artículo se centra en el código necesario para los agentes de inteligencia artificial dentro del código de API.

El proyecto de API del repositorio de GitHub está estructurado de la siguiente manera:

  • Los componentes de modelado de datos usan modelos Pydantic.
  • Los componentes de la capa web son responsables de enrutar las peticiones y gestionar la comunicación.
  • Los componentes de la capa de servicio son responsables de la lógica de negocio primaria y de la interacción con la capa de datos; el Agente LangChain y las herramientas de agente.
  • Los componentes de la capa de datos son responsables de interactuar con el almacenamiento de documentos y el vector de búsqueda de Azure Cosmos DB for MongoDB.

Configuración del entorno para la API

Usamos la versión 3.11.4 de Python para el desarrollo y las pruebas de la API.

Configure el entorno virtual de Python en el directorio api:

    python -m venv venv

Active el entorno e instale las dependencias mediante el archivo de requisitos en el directorio de api:

    venv\Scripts\activate
    python -m pip install -r requirements.txt

Cree un archivo, denominado .env en el directorio api, para almacenar las variables de entorno:

    OPENAI_API_KEY="<your Open AI key>"
    MONGO_CONNECTION_STRING="mongodb+srv:<your connection string from Azure Cosmos DB>"

Ahora que ha configurado el entorno y establecido variables, ejecute el siguiente comando desde el directorio de API para iniciar el servidor:

    python app.py

El servidor de FastAPI comienza en el bucle invertido localhost 127.0.0.1 puerto 8000 de forma predeterminada. Puede acceder a los documentos de Swagger mediante la siguiente dirección localhost: http://127.0.0.1:8000/docs.

Uso de una sesión para la memoria del agente de inteligencia artificial

Es imperativo que el agente de viajes sea capaz de hacer referencia a la información proporcionada previamente dentro de la conversación en curso. Esta capacidad se conoce normalmente como memoria en el contexto de los LLM.

Para lograr este objetivo, use el historial de mensajes de chat almacenado en la instancia de Azure Cosmos DB. El historial de cada sesión de chat se almacena a través de un identificador de sesión para asegurarse de que solo se puede acceder a los mensajes de la sesión de conversación actual. Esta necesidad es la razón de la existencia de un método Get Session en la API. Es un método de marcador de posición para administrar sesiones web para ilustrar el uso del historial de mensajes de chat.

Haga clic en Probar para /session/.

Captura de pantalla del uso del método Get Session en Python FastAPI, con el botón para probarlo.

{
  "session_id": "0505a645526f4d68a3603ef01efaab19"
}

Para el agente de inteligencia artificial, solo es necesario simular una sesión. El método de código auxiliar simplemente devuelve un identificador de sesión generado para el historial de mensajes de seguimiento. En una implementación práctica, esta sesión se almacenaría en Azure Cosmos DB y potencialmente en localStorage de React.

Este es el contenido de web/session.py:

    @router.get("/")
    def get_session():
        return {'session_id':str(uuid.uuid4().hex)}

Inicio de una conversación con el agente de viajes de inteligencia artificial

Use el identificador de sesión que obtuvo del paso anterior para iniciar un diálogo nuevo con el agente de IA, así puede validar su funcionalidad. Lleve cabo la prueba enviando la siguiente frase: "Quiero tomarme unas vacaciones relajantes".

Haga clic en Probar para /agent/agent_chat.

Captura de pantalla del uso del método Chat del agente en Python FastAPI, con el botón para probarlo.

Use este parámetro de ejemplo:

{
  "input": "I want to take a relaxing vacation.",
  "session_id": "0505a645526f4d68a3603ef01efaab19"
}

La ejecución inicial da como resultado una recomendación para el crucero Tranquil Breeze y el crucero Fantasy Seas Adventure porque el agente prevé que son los cruceros más relajantes disponibles a través del vector de búsqueda. Estos documentos tienen la puntuación más alta para similarity_search_with_score llamado en la capa de datos de la API, data.mongodb.travel.similarity_search().

Las puntuaciones de búsqueda de similitud aparecen como salida de la API con fines de depuración. Esta es la salida después de una llamada a data.mongodb.travel.similarity_search():

0.8394561085977978
0.8086545112328692
2

Sugerencia

Si no se devuelven documentos para el vector de búsqueda, modifique el límite de similarity_search_with_score o el valor del filtro de puntuación según sea necesario ([doc for doc, score in docs if score >=.78]) en data.mongodb.travel.similarity_search().

Al llamar a agent_chat por primera vez se crea una nueva colección denominadahistory en Azure Cosmos DB para almacenar la conversación por sesión. Esta llamada permite al agente acceder al historial de mensajes de chat almacenado según sea necesario. Las ejecuciones posteriores de agent_chat con los mismos parámetros generan resultados variables porque se extraen de la memoria.

Tutorial del agente de IA

Cuando está integrando el agente de inteligencia artificial en la API, los componentes de búsqueda web son responsables de iniciar todas las solicitudes. Los componentes de búsqueda web van seguidos del servicio de búsqueda y, por último, los componentes de datos.

En este caso específico, se usa una búsqueda de datos de MongoDB que se conecta a Azure Cosmos DB. Las capas facilitan el intercambio de componentes del Modelo, con el código del agente de inteligencia artificial y de la herramienta del agente de inteligencia artificial residiendo en la capa de servicio. Este enfoque permite la indistinta capacidad de intercambio de orígenes de datos. También amplía las funcionalidades del agente de inteligencia artificial con funcionalidades o herramientas adicionales más complejas.

Diagrama de las capas de FastAPI del agente de viajes de IA.

Capa de servicio

La capa de servicio es la base de la lógica empresarial principal. En este escenario concreto, la capa de servicio desempeña un papel fundamental como repositorio para el código del agente LangChain. Facilita la integración sin problemas de las solicitudes de usuario con datos, memoria de conversación y funciones de agente de Azure Cosmos DB para el agente de IA.

La capa de servicio emplea un módulo de patrón singleton para controlar las inicializaciones relacionadas con el agente en el archivo init.py. Este es el contenido del service/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()

El archivo init.py inicia la carga de variables de entorno desde un archivo .env mediante el método load_dotenv(override=False). A continuación, se crea una instancia de una variable global denominada agent_with_chat_history para el agente. Este agente está diseñado para su uso por TravelAgent.py.

El método LLM_init() se invoca durante la inicialización del módulo para configurar el agente de inteligencia artificial para la conversación a través del nivel web de API. El objeto OpenAI chat se instancia a través del modelo GPT-3.5 e incorpora parámetros específicos, como el nombre del modelo y la temperatura. El objeto chat, la lista de herramientas y la plantilla de solicitud se combinan para generar AgentExecutor, que funciona como agente de viajes de IA.

El agente con historial, agent_with_chat_history, se establece a través de RunnableWithMessageHistory con el historial de chat (MongoDBChatMessageHistory). Esta acción le permite mantener un historial de conversaciones completo a través de Azure Cosmos DB.

Prompt

El aviso de LLM comenzó inicialmente con la simple instrucción "Eres un asistente de viajes servicial y amable para una compañía de cruceros". Sin embargo, las pruebas mostraron que podría obtener resultados más coherentes incluyendo la instrucción "Responder preguntas de viaje a la mejor de su capacidad, proporcionando solo información relevante. Para reservar un crucero, captar el nombre de la persona es esencial." Los resultados aparecen en formato HTML para mejorar el atractivo visual de la interfaz web.

Herramientas del agente

Las herramientas son interfaces que un agente puede usar para interactuar con el mundo, a menudo a través de llamadas a funciones.

Al crear un agente, debe proporcionarlo con un conjunto de herramientas que puede usar. El decorador @tool ofrece el enfoque más sencillo para definir una herramienta personalizada.

De forma predeterminada, el decorador usa el nombre de la función como nombre de la herramienta, aunque puede reemplazarlo proporcionando una cadena como primer argumento. El decorador usa la docstring de la función como descripción de la herramienta, por lo que requiere el aprovisionamiento de una docstring.

Este es el contenido del service/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"

El archivo TravelAgentTools.py define tres herramientas:

  • vacation_lookup realiza una búsqueda de vectores en Azure Cosmos DB. Utiliza similarity_search para recuperar material relevante relacionado con viajes.
  • itinerary_lookup recupera los detalles y programaciones del paquete de crucero para un barco de crucero especificado.
  • book_cruise reserva un paquete de crucero para un pasajero.

Las instrucciones específicas ("Para reservar un crucero necesito saber su nombre") pueden ser necesarias para garantizar la captura del nombre y el número de habitación del pasajero para reservar el paquete de crucero, aunque haya incluido estas instrucciones en el aviso de LLM.

Agente de inteligencia artificial

El concepto fundamental que subyace a los agentes es usar un modelo de lenguaje para seleccionar una secuencia de acciones que se van a ejecutar.

Este es el contenido del service/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))

El archivo TravelAgent.py es sencillo porque agent_with_chat_history y sus dependencias (herramientas, solicitud y LLM) se inicializan y se configuran en el archivo init.py. Este archivo llama al agente mediante la entrada recibida del usuario, junto con el identificador de sesión para la memoria de conversación. Después, se devuelve PromptResponse (modelo/aviso) con el tiempo de salida y respuesta del agente.

Integración del agente de IA con la interfaz de usuario de React

Con la carga correcta de los datos y la accesibilidad del agente de inteligencia artificial a través de la API, ahora puede completar la solución estableciendo una interfaz de usuario web (mediante React) para su sitio web de viajes. El uso de las funcionalidades de React ayuda a ilustrar la integración sin problemas del agente de IA en un sitio de viaje. Esta integración mejora la experiencia del usuario con un asistente de viajes conversacional para consultas y reservas.

Configuración del entorno para React

Instale Node.js y las dependencias antes de probar la interfaz de React.

Ejecute el siguiente comando desde el directorio web para realizar una instalación limpia de las dependencias del proyecto. La instalación puede tardar un tiempo.

    npm ci

A continuación, cree un archivo denominado .env dentro del directorio web para facilitar el almacenamiento de variables de entorno. Incluya los detalles siguientes en el archivo .env recién creado:

REACT_APP_API_HOST=http://127.0.0.1:8000

Ahora, ejecute el siguiente comando desde el directorio web para iniciar la interfaz de usuario web de React:

    npm start

Al ejecutar el comando anterior, se abre la aplicación web React.

Recorrido por la interfaz web de React

El proyecto web del repositorio de GitHub es una aplicación sencilla para facilitar la interacción del usuario con el agente de inteligencia artificial. Los componentes principales necesarios para conversar con el agente son TravelAgent.js y ChatLayout.js. El archivo Main.js actúa como la página de aterrizaje del módulo central o del usuario.

Captura de pantalla de la interfaz web de JavaScript de React.

Principal

El componente principal actúa como administrador central de la aplicación. Actúa como punto de entrada designado para el enrutamiento. Dentro de la función representar, genera código JSX para delimitar el diseño de página principal. Este diseño abarca elementos de marcador de posición para la aplicación, como logotipos y vínculos, una sección que aloja el componente del agente de viajes y un pie de página que contiene una declinación de responsabilidades de ejemplo sobre la naturaleza de la aplicación.

Este es el contenido de 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 viajes

El componente Agente de viajes tiene un propósito sencillo: capturar entradas de usuario y mostrar respuestas. Desempeña un papel clave en la administración de la integración con el agente de inteligencia artificial de back-end, principalmente mediante la captura de sesiones y el reenvío de solicitudes de usuario al servicio FastAPI. Las respuestas resultantes se almacenan en una matriz para su visualización, que facilita el componente Diseño de chat.

Estos son los contenidos de 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>
  )
}

Seleccione Planear su viaje sin esfuerzo para abrir el asistente de viajes.

Diseño de chat

El componente de diseño de chat supervisa la disposición del chat. Procesa sistemáticamente los mensajes del chat e implementa el formato especificado en el objeto JSON message.

Estos son los contenidos de TripPlanning/ChatLayout.py:

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>
  )
}

Las indicaciones del usuario están en el lado derecho y son de color azul. Las respuestas del agente de viajes de IA están en el lado izquierdo y de color verde. Como se muestra en la imagen siguiente, las respuestas con formato HTML se contabilizan en la conversación.

Captura de pantalla de un chat.

Cuando el agente de inteligencia artificial esté listo para entrar en producción, puede usar el almacenamiento en caché semántico para mejorar el rendimiento de las consultas en un 80 % y para reducir los costos de inferencia de LLM y llamada API. Para implementar el almacenamiento en caché semántico, consulte esta entrada en el blog del codificador estocástico.

Diagrama del almacenamiento en caché semántico.