Evolución de un sistema RAG en Azure
En nuestra entrada anterior «RAG en AWS con Terraform«, exploramos la arquitectura de un sistema RAG básico. En este artículo, mostramos técnicas adicionales para mejorar el rendimiento de la aplicación. Además aportamos una introducción a la transcripción y diarización de audio. Por otro lado, avanzamos hacia una arquitectura más desacoplada. Separando la interfaz Streamlit del sistema RAG mediante una aplicación FastAPI para el backend. El código para la infraestructura y la aplicación se puede encontrar en el repositorio de GitHub. Continúa leyendo si quieres aprender más sobre RAG en Azure.
Infraestructura RAG en Azure
Para un cambio significativo respecto a nuestra arquitectura anterior, implementaremos nuestra solución en Azure. Usaremos Azure Web App para alojar la interfaz Streamlit. Nuestra API backend se desarrollará utilizando FastAPI y Langchain, y se desplegará en Azure Container App.
En cuanto a la base de datos vectorial, tiene sentido utilizar Azure AI Search; un servicio completamente gestionado para nuestra tienda de vectores. Como tanto el frontend como el backend estarán en contenedores, se utilizará Azure Container Registry para almacenar las imágenes Docker.
Pipeline de Ingesta
Para mejorar la versión anterior de nuestro sistema RAG, hemos agregado dos características principales:
– Soporte para transcripción y diarización de audio.
– Reemplazo de la división por caracteres por «Semantic Chunking».
Transcripción y Diarización de Audio
Para el proceso de transcripción, hemos optado por el modelo Whisper de OpenAI. Es importante especificar en la llamada API que se devuelvan las marcas de tiempo para segmentos y palabras. Nos interesan los segmentos devueltos por el modelo:
```json
segments=[
{
'id': 0,
'seek': 0,
'start': 0.2800000011920929,
'end': 5.440000057220459,
'text': 'And you know what they call a quarter pounder with cheese in Paris?',
'tokens': [50364, 400, 291, 458, 437, 436, 818, 257, 6555, 12013, 260, 365, 5399, 294, 8380, 30, 50614],
'temperature': 0.0,
'avg_logprob': -0.28278398513793945,
'compression_ratio': 2.1312217712402344,
'no_speech_prob': 0.006958003155887127
},
{ ... },
{ ... }
]
```
Aunque solo necesitamos los segmentos, es importante especificar también la granularidad de las palabras debido a un comportamiento extraño del modelo. Si solo se devuelven los segmentos, la primera marca de tiempo siempre empezará en 0, incluso si no es precisa.
Ahora utilizaremos el modelo pyannote/speaker-diarization-3.1 para obtener nuestras anotaciones de audio, que lucen algo así:
```
[00:00:00.469 --> 00:00:04.570] A SPEAKER_01
[00:00:05.110 --> 00:00:05.498] B SPEAKER_01
[00:00:05.498 --> 00:00:05.565] C SPEAKER_00
[00:00:05.565 --> 00:00:05.599] D SPEAKER_01
[00:00:05.599 --> 00:00:05.616] E SPEAKER_00
[00:00:05.616 --> 00:00:05.667] F SPEAKER_01
[00:00:05.667 --> 00:00:05.700] G SPEAKER_00
[00:00:05.700 --> 00:00:05.717] H SPEAKER_01
```
Solo queda un poco de lógica para fusionar las anotaciones y la transcripción por segmentos. Como recordatorio, todo el código está en el repositorio.
```
SPEAKER_01: And you know what they call a quarter pounder with cheese in Paris?
SPEAKER_00: They don't call it a quarter pounder with cheese?
SPEAKER_01: No, man, they got the metric system. They wouldn't know what the *** a quarter pounder is.
SPEAKER_00: What do they call it?
SPEAKER_01: They call it a Royale with cheese.
SPEAKER_00: Royale with cheese.
SPEAKER_00: That's strange.
SPEAKER_00: What do they call a Big Mac?
SPEAKER_01: Big Mac's a Big Mac, but they call it Le Big Mac.
SPEAKER_00: Le Big Mac.
SPEAKER_00: What do they call a Whopper?
SPEAKER_01: I don't know. I didn't go into Burger King.
```
Semantic Chunking
La forma más común de dividir documentos es por caracteres: párrafos, saltos de línea o espacios hasta que losfragmentos se ajusten al tamaño especificado. Un método más avanzado que introducimos en esta arquitectura es el «Semantic Chunking». Con el respaldo de un modelo de embeddings, calculamos los vectores para cada oración y creamos grupos de oraciones semánticamente similares. Estos grupos se insertan juntos en la tienda de vectores.
Pipeline de Chat
También hay algunas mejoras nuevas en el pipeline de chatbot. Dos técnicas adicionales conforman nuestro proceso de preguntas y respuestas:
– Expansión de Consultas
– Reordenación
Expansión de Consultas
La idea es simple: en lugar de usar solo la consulta original para recuperar documentos relevantes de la base de datos vectorial, creamos múltiples consultas sintéticas con el mismo significado. En este sentido, utilizaremos GPT-3.5 como nuestro modelo preferido para la expansión. Con los embeddings de la colección de consultas, aumentamos la probabilidad de recuperar documentos relevantes para nuestro prompt. ¡No pongas todos tus huevos en una sola canasta!
Reordenación
Si el propósito de la expansión de consultas es recuperar documentos relevantes, usaremos la técnica de reordenación. Esto nos permitirá realizar un filtro final para proporcionar al LLM un subconjunto preciso de nuestra recuperación inicial. Esta técnica utiliza el endpoint de reordenación de Cohere. La combinación de expansión de consultas y reordenación nos da la capacidad de lanzar una red amplia en la recuperación inicial. Así, luego filtrar con precisión la selección.
Próximos Pasos
Ya ha finalizado nuestro post sobre como montar tu primer RAG en Azure. En nuestro próximo artículo, finalmente introduciremos el marco de evaluación RAGAS y una plataforma como Langsmith. Lo último nos ayudará a lo largo del ciclo de vida de las aplicaciones LLM. Además, queremos explorar la creación de pipelines más complejos que involucren enrutamiento dinámico y agentes especializados. En el incluiremos la recuperación condicional de información de diferentes fuentes como bases de datos SQL.