Construyendo un ChatGPT en .NET MAUI Parte 2
En esta segunda parte de mi publicación, el enfoque se centra en la interfaz de usuario de la aplicación y su interacción con el ViewModel.
INFO: Es importante para mí que tengas plena confianza en la autenticidad de mis publicaciones. Por ello, quiero informarte de que esta publicación contó con la ayuda de GPT-3.5. Sin embargo, siempre utilizo mis criterios para asegurarme de que la publicación sea clara y fácil de entender. En caso de que en el futuro vuelva a utilizar esta herramienta o cualquier otra, te lo haré saber de antemano para asegurar la transparencia en todo momento.
ADVERTENCIA: Esta publicación enfatiza la importancia de utilizar la aplicación de manera ética y responsable, la cual ha sido desarrollada en la plataforma .NET MAUI y se basa en la tecnología de OpenAI. Si bien no me considero una autoridad moral, reconozco que he tenido errores en el pasado y que seguiré aprendiendo y evolucionando como ser humano en el futuro. Esta misma filosofía se aplica al ámbito tecnológico, donde tanto los usuarios como los desarrolladores deben ser conscientes de las posibles implicaciones éticas y sociales de sus acciones. Es crucial considerar el impacto de la tecnología en la sociedad y trabajar juntos para garantizar su uso adecuado y responsable. Para ello, es necesario adoptar estándares éticos y responsables, como la transparencia, la equidad y la responsabilidad. La transparencia implica una divulgación adecuada y clara de los procesos y los resultados del uso de la tecnología. La equidad, por su parte, requiere que las aplicaciones sean accesibles y justas para todas las personas, independientemente de su origen, género, raza o creencias. Y la responsabilidad implica asumir las consecuencias de nuestras acciones y decisiones, así como la responsabilidad social de garantizar que la tecnología no cause daño a la sociedad. En resumen, el uso ético y responsable de la tecnología es esencial para avanzar hacia una sociedad más justa y equitativa. Es necesario que tanto los usuarios como los desarrolladores adopten estándares éticos y responsables, y trabajemos juntos para garantizar que la tecnología se utilice para el bien común.
Quiero destacar que toda la información presentada en esta publicación se debe a la valiosa charla impartida por Luis Beltran, PhD, quien nos enseñó cómo construir un ChatGPT en .NET MAUI con las APIs de OpenAI. Agradezco su contribución y espero que esta publicación pueda ayudar a otros desarrolladores a implementar esta tecnología en sus propias aplicaciones de .NET.
Partes de ConversationView
La vista de ConversationView se compone de tres secciones distintas: la sección superior, la sección central y la sección inferior. La sección superior incluye la imagen de marca y el título de la aplicación, junto con botones para generar texto e imágenes. La sección central presenta la conversación entre el usuario y el chatbot, presentada en un CollectionView. Y, por último, la sección inferior incluye un campo para introducir texto y botones para enviar o capturar audio por voz.
Animación de Lottie cuando la lista de mensajes está vacía
Cuando la lista de mensajes de la aplicación está vacía, se activa automáticamente una animación Lottie que tiene como objetivo mejorar la experiencia del usuario y añadir un toque de personalidad a la interfaz de la aplicación. Esta animación se reproduce de manera continua y llama la atención del usuario, indicándole que puede enviar una consulta al chatbot en cualquier momento. Una vez que el usuario envía un mensaje o recibe una respuesta del chatbot, la animación se detiene de forma automática, permitiendo que el usuario se centre en la conversación con el chatbot. De esta manera, la animación es una herramienta eficaz para atraer la atención del usuario y guiarlo hacia el uso del chatbot.
Lottie animation when message list is empty
Interacción de la UI con el ViewModel
La forma en que el chatbot proporciona información no depende únicamente de las consultas que los usuarios ingresen en el campo de entrada de texto, sino también de los botones de la parte superior que cambian la respuesta del chatbot, ya sea a través de texto o imágenes. Detrás de escena, el ViewModel se encarga de administrar la lógica de la aplicación y comunicarse con el servicio de OpenAI. A continuación, se presenta una imagen que resume cómo fluye la información entre la interfaz de usuario y el ViewModel.
Command flow and methods in write and image mode
Para el método AskQuestion
Se establece la instancia
CurrentCommand
en su estado inicial, que esAskQuestion
. Además, se ajusta laOpacityModeMessage
a 1 y la deOpacityModeImage
a 0.5, y se muestra un toast (mensaje breve y temporal) que indica que está en modo de escritura.Se crea una nueva instancia de
AsyncRelayCommand
que llama al métodoAskQuestionAsync
.Cuando se llama al método
AskQuestionAsync
, se establece el indicadorIsTextActive
entrue
y el indicadorIsImageActive
enfalse
.El método
QueryManagerAsync
es llamado con la función_openAIService.AskQuestion
como argumento.En
QueryManagerAsync
, se agrega el mensaje de usuario a la lista de mensajes, se establece el indicadorisUserMessage
entrue
y se llama a la función_openAIService.AskQuestion
con la consulta del usuario como argumento.Se agrega la respuesta del bot a la lista de mensajes, se establece el indicador
isUserMessage
enfalse
y se desplaza la vista hacia el final de la lista de mensajes.
Para el método CreateImage
Cuando el usuario cambia al modo imagen a través del botón correspondiente, se llama al método
CreateImage
. Dentro de este método, se establece laOpacityModeMessage
en 0.5 y laOpacityModeImage
en 1, y se muestra un toast (mensaje breve y temporal) indicando que se ha activado el modo de imagen.Después, se asigna a la propiedad
CurrentCommand
un nuevo comando asincrónico (AsyncRelayCommand
) que, al activarse, ejecutará el métodoCreateImageAsync
.Cuando se llama al método
CreateImageAsync
, se establece el indicadorIsTextActive
enfalse
y el indicadorIsImageActive
entrue
.El método
QueryManagerAsync
es llamado con la función_openAIService.CreateImage
como argumento.En
QueryManagerAsync
, se agrega el mensaje de usuario a la lista de mensajes, se establece el indicadorisUserMessage
entrue
y se llama a la función_openAIService.CreateImage
con la consulta del usuario como argumento.Se agrega la respuesta del bot a la lista de mensajes, se establece el indicador
isUserMessage
enfalse
y se desplaza la vista hacia el final de la lista de mensajes.
Data templates en ConversationView
La distinción entre los mensajes enviados por el usuario y los mensajes enviados por el chatbot se realiza mediante el uso de dos plantillas diferentes en la UI. La plantilla de mensaje de usuario (UserMessageItemTemplate
) es utilizada para mostrar los mensajes enviados por el usuario, mientras que la plantilla de mensaje de chatbot (BotMessageItemTemplate
) es utilizada para mostrar los mensajes enviados por el chatbot. Esto permite una mejor organización visual de la conversación y facilita la comprensión por parte del usuario de los mensajes que recibe.
Selección de temas
Cuando se hace clic en el branding de la aplicación, se activa el método SelectTheme
. Este método, que es un método asíncrono, permite cambiar el tema de la aplicación y realiza una animación en la vista de conversación para que la transición sea más fluida.
Primero, el método obtiene el tema actual de la aplicación y establece el nuevo tema como el opuesto al actual (oscuro o claro). Luego, establece el nuevo tema como el tema de la aplicación.
A continuación, se ejecuta una animación en la vista de conversación utilizando el método ScaleTo
. Durante 250 milisegundos, la vista se reduce a un 95% de su tamaño original, luego se amplía a un 105% de su tamaño original durante otros 250 milisegundos y, finalmente, se restablece al tamaño original durante otros 250 milisegundos. La animación utiliza la función de aceleración CubicOut
para reducir la velocidad de la animación al final.
1
2
3
4
5
6
7
8
9
10
[RelayCommand]
private async Task SelectTheme()
{
AppTheme currentTheme = Application.Current.RequestedTheme;
AppTheme newTheme = currentTheme == AppTheme.Dark ? AppTheme.Light : AppTheme.Dark;
Application.Current.UserAppTheme = newTheme;
await ConversationView.ScaleTo(0.95, 250, Easing.CubicOut);
await ConversationView.ScaleTo(1.05, 250, Easing.CubicIn);
await ConversationView.ScaleTo(1, 250, Easing.CubicOut);
}
Repositorio
El proyecto es de código abierto y puedes verlo haciendo clic en la siguiente imagen. ¡No dudes en echar un vistazo!
Recursos
- Trabajando con GridLayout en Xamarin Forms - Escrito por Leomaris Reyes.
- Plantillas de datos - Documentación oficial de .NET MAUI.
- Borde - Documentación oficial de .NET MAUI.
- MVVM is easier than ever before with Source Generators, .NET 7, & the MVVM Toolkit - .NET Conf 2022.
Publicación en inglés
Conclusiones
En resumen, para construir la UI de chatbot en .NET MAUI se han mostrado las tres secciones distintas que componen la vista de ConversationView, así como la plantilla de mensaje de usuario (UserMessageItemTemplate) y la plantilla de mensaje de chatbot (BotMessageItemTemplate). Además, se ha presentado una animación Lottie que se muestra cuando la lista de mensajes está vacía, lo que contribuye a mejorar la experiencia del usuario.
Siéntete libre de darme tu opinión y con la ayuda de mi repositorio, saca tus propias conclusiones. Si tiene alguna pregunta o sugerencia constructiva, me gustaría mucho leerla. Gracias por tu tiempo.