Lo que aprendí al llevar la Ingeniería de Prompt al límite

What I learned from pushing Prompt Engineering to its limits.

Representación satírica de la ingeniería de indicaciones. Irónicamente, la imagen generada por DALL-E2 fue generada por el autor utilizando la ingeniería de indicaciones con la indicación “un científico loco entregando un pergamino a un robot artificialmente inteligente, generado en un estilo retro”, más una variación, más outpainting.

Pasé los últimos dos meses construyendo una aplicación impulsada por un modelo de lenguaje grande (LLM). Fue una experiencia emocionante, intelectualmente estimulante y a veces frustrante. Mi concepción completa de la ingeniería de indicaciones – y de lo que es posible con LLMs – cambió a lo largo del proyecto.

Me encantaría compartir con ustedes algunas de las lecciones más importantes con el objetivo de arrojar luz sobre algunos de los aspectos a menudo no hablados de la ingeniería de indicaciones. Espero que después de leer sobre mis pruebas y tribulaciones, puedan tomar decisiones informadas sobre la ingeniería de indicaciones. Si ya han experimentado con la ingeniería de indicaciones, ¡espero que esto les ayude a avanzar en su propio camino!

Para contextualizar, aquí está la versión corta del proyecto del que aprenderemos:

  • Mi equipo y yo construimos VoxelGPT, una aplicación que combina LLMs con el lenguaje de consulta de visión por computadora FiftyOne para permitir la búsqueda a través de conjuntos de datos de imágenes y videos mediante lenguaje natural. VoxelGPT también responde preguntas sobre FiftyOne en sí.
  • VoxelGPT es de código abierto (¡también lo es FiftyOne!). Todo el código está disponible en GitHub.
  • Puedes probar VoxelGPT de forma gratuita en gpt.fiftyone.ai.
  • Si te interesa cómo construimos VoxelGPT, puedes leer más al respecto en TDS aquí.

Ahora, he dividido las lecciones de ingeniería de indicaciones en cuatro categorías:

  1. Lecciones generales
  2. Técnicas de indicación
  3. Ejemplos
  4. Herramientas

Lecciones generales

¿Ciencia? ¿Ingeniería? ¿Magia Negra?

La ingeniería de indicaciones es tanto experimentación como ingeniería. Hay un número infinito de formas de escribir una indicación, desde la redacción específica de su pregunta, hasta el contenido y formato del contexto que se alimenta. Puede ser abrumador. Encontré que lo más fácil era empezar de forma simple y construir una intuición – y luego probar hipótesis.

En visión por computadora, cada conjunto de datos tiene su propio esquema, tipos de etiquetas y nombres de clases. El objetivo de VoxelGPT era poder trabajar con cualquier conjunto de datos de visión por computadora, pero comenzamos con un solo conjunto de datos: MS COCO. Mantener todos los grados adicionales de libertad fijos nos permitió clavar la capacidad del LLM para escribir consultas sintácticamente correctas en primer lugar.

Una vez que haya determinado una fórmula que tenga éxito en un contexto limitado, luego descubra cómo generalizar y construir sobre esto.

¿Qué modelos usar?

La gente dice que una de las características más importantes de los modelos de lenguaje grande es que son relativamente intercambiables. En teoría, debería poder intercambiar un LLM por otro sin cambiar sustancialmente el tejido conectivo.

Aunque es cierto que cambiar el LLM que utiliza a menudo es tan simple como cambiar una llamada de API, definitivamente hay algunas dificultades que surgen en la práctica.

  • Algunos modelos tienen longitudes de contexto mucho más cortas que otros. Cambiar a un modelo con un contexto más corto puede requerir una refactorización importante.
  • El código abierto es genial, pero los LLM de código abierto no son tan efectivos (todavía) como los modelos GPT. Además, si está implementando una aplicación con un LLM de código abierto, deberá asegurarse de que el contenedor que ejecuta el modelo tenga suficiente memoria y almacenamiento. Esto puede terminar siendo más problemático (y más caro) que simplemente usar puntos finales de API.
  • Si comienza a usar GPT-4 y luego cambia a GPT-3.5 debido al costo, es posible que se sorprenda por la disminución del rendimiento. Para tareas de generación de código e inferencia complicadas, GPT-4 es MUCHO mejor.

¿Dónde usar LLMs?

Los grandes modelos de lenguaje son poderosos. Pero solo porque sean capaces de ciertas tareas no significa que necesite -o incluso deba- usarlos para esas tareas. La mejor manera de pensar en LLMs es como habilitadores. Los LLMs no son la SOLUCIÓN COMPLETA: solo son parte de ella. No espere que los grandes modelos de lenguaje hagan todo.

Como ejemplo, puede ser el caso de que el LLM que está utilizando pueda (en circunstancias ideales) generar llamadas API con formato adecuado. Pero si sabe cómo debería ser la estructura de la llamada API y realmente está interesado en completar secciones de la llamada API (nombres de variables, condiciones, etc.), entonces simplemente use el LLM para hacer esas tareas y use las salidas del LLM (postprocesadas correctamente) para generar llamadas API estructuradas usted mismo. Esto será más económico, eficiente y confiable.

Un sistema completo con LLMs definitivamente tendrá una gran cantidad de tejido conectivo y lógica clásica, además de una multitud de componentes de ingeniería de software tradicional y de ingeniería de ML. Encuentre lo que mejor funcione para su aplicación.

Los LLMs están sesgados

Los modelos de lenguaje son tanto motores de inferencia como almacenes de conocimiento. A menudo, el aspecto del almacén de conocimiento de un LLM puede ser de gran interés para los usuarios, ¡muchas personas usan LLMs como reemplazos de motores de búsqueda! A estas alturas, cualquiera que haya usado un LLM sabe que son propensos a inventar “hechos” falsos, un fenómeno conocido como alucinación.

A veces, sin embargo, los LLMs sufren del problema opuesto: están demasiado firmemente fijados en los hechos de sus datos de entrenamiento.

En nuestro caso, intentábamos provocar a GPT-3.5 para determinar las correspondientes ViewStages (tuberías de operaciones lógicas) requeridas para convertir la consulta de lenguaje natural del usuario en una consulta Python válida FiftyOne. El problema era que GPT-3.5 conocía los ViewStages ‘Match’ y ‘FilterLabels’, que han existido en FiftyOne durante algún tiempo, pero sus datos de entrenamiento no incluían una funcionalidad agregada recientemente donde se puede usar un ViewStage ‘SortBySimilarity’ para encontrar imágenes que se parecen a una indicación de texto.

Intentamos pasar una definición de ‘SortBySimilarity’, detalles sobre su uso y ejemplos. Incluso intentamos instruir a GPT-3.5 que NO DEBE usar los ViewStages ‘Match’ o ‘FilterLabels’, o de lo contrario será penalizado. No importa lo que intentamos, el LLM todavía se orientó hacia lo que sabía, ya sea que fuera la elección correcta o no. ¡Estábamos luchando contra los instintos del LLM!

Terminamos teniendo que lidiar con este problema en el postprocesamiento.

El doloroso postprocesamiento es inevitable

No importa cuán buenos sean sus ejemplos, ni cuán estrictas sean sus instrucciones: los grandes modelos de lenguaje inevitablemente alucinarán, le darán respuestas con formato incorrecto y harán berrinches cuando no comprendan la información de entrada. La propiedad más previsible de los LLMs es la imprevisibilidad de sus resultados.

Pasé una cantidad inconmensurable de tiempo escribiendo rutinas para buscar patrones y corregir la sintaxis alucinada. ¡El archivo de postprocesamiento terminó conteniedo casi 1600 líneas de código Python!

Algunas de estas subrutinas fueron tan simples como agregar paréntesis o cambiar “y” y “o” a “&” y “|” en expresiones lógicas. Algunas subrutinas fueron mucho más complicadas, como validar los nombres de las entidades en las respuestas de LLM, convertir un ViewStage en otro si se cumplían ciertas condiciones, asegurarse de que los números y tipos de argumentos para los métodos fueran válidos.

Si está utilizando la ingeniería de instrucciones en un contexto de generación de código algo confinado, recomendaría el siguiente enfoque:

  1. Escriba su propio analizador de errores personalizado utilizando árboles de sintaxis abstracta (módulo ast de Python).
  2. Si los resultados no son sintácticamente válidos, alimente el mensaje de error generado en su LLM e inténtelo nuevamente.

Este enfoque no aborda el caso más insidioso donde la sintaxis es válida pero los resultados no son correctos. Si alguien tiene una buena sugerencia para esto (más allá de AutoGPT y enfoques estilo “muestra tu trabajo”), ¡por favor háganmelo saber!

Técnicas de instrucción

Cuanto más, mejor

Para construir VoxelGPT, utilicé lo que parecía ser cada técnica de instrucción bajo el sol:

  • “Eres un experto”
  • “Tu tarea es”
  • “DEBES”
  • “Serás penalizado”
  • “Aquí están las reglas”

Ninguna combinación de estas frases garantiza un tipo específico de comportamiento. Una sugerencia inteligente simplemente no es suficiente.

Dicho esto, cuanto más de estas técnicas se empleen en una sugerencia, ¡más se empuja al LLM en la dirección correcta!

Ejemplos > Documentación

Es conocimiento común (¡y sentido común!) que tanto los ejemplos como otra información contextual como la documentación pueden ayudar a obtener mejores respuestas de un gran modelo de lenguaje. Encontré que esto era cierto para VoxelGPT.

Una vez que se agregan todos los ejemplos y documentación pertinentes directamente, ¿qué deberías hacer si tienes espacio extra en la ventana de contexto? En mi experiencia, encontré que los ejemplos tangencialmente relacionados eran más importantes que la documentación tangencialmente relacionada.

Modularidad >> Monolito

Cuanto más puedas desglosar un problema general en subproblemas más pequeños, mejor. En lugar de alimentar el esquema del conjunto de datos y una lista de ejemplos de extremo a extremo, es mucho más efectivo identificar los pasos de selección e inferencia individuales (sugerencias de selección-inferencia) y alimentar solo la información relevante en cada paso.

Esto es preferible por tres razones:

  1. Los LLM son mejores haciendo una tarea a la vez que varias tareas a la vez.
  2. Cuanto más pequeños sean los pasos, más fácil será sanear las entradas y salidas.
  3. Es un ejercicio importante para ti como ingeniero comprender la lógica de tu aplicación. El punto de los LLM no es convertir el mundo en una caja negra. Es permitir nuevos flujos de trabajo.

Ejemplos

¿Cuántos necesito?

Una gran parte de la ingeniería de sugerencias es descubrir cuántos ejemplos necesitas para una tarea específica. Esto es altamente específico del problema.

Para algunas tareas (generación efectiva de consultas y respuesta a preguntas basadas en la documentación de FiftyOne), pudimos salirnos sin ejemplos. Para otros (selección de etiquetas, si el historial de chat es relevante y reconocimiento de entidades nombradas para clases de etiquetas), solo necesitamos algunos ejemplos para hacer el trabajo. Nuestra tarea principal de inferencia, sin embargo, tiene casi 400 ejemplos (y aún es el factor limitante en el rendimiento general), por lo que solo pasamos los ejemplos más relevantes en el momento de la inferencia.

Cuando estés generando ejemplos, trata de seguir dos pautas:

  1. Sé lo más exhaustivo posible. Si tienes un espacio finito de posibilidades, intenta dar al LLM al menos un ejemplo para cada caso. Para VoxelGPT, intentamos tener al menos un ejemplo para cada forma sintácticamente correcta de usar cada uno de los ViewStage, y típicamente unos pocos ejemplos para cada uno, para que el LLM pueda hacer coincidencias de patrones.
  2. Sé lo más consistente posible. Si estás dividiendo la tarea en múltiples sub-tareas, asegúrate de que los ejemplos sean consistentes de una tarea a la siguiente. ¡Puedes reutilizar ejemplos!

Ejemplos sintéticos

Generar ejemplos es un proceso laborioso y los ejemplos hechos a mano solo te llevarán hasta cierto punto. No es posible pensar en todos los posibles escenarios de antemano. Cuando implementes tu aplicación, puedes registrar las consultas de los usuarios y usarlas para mejorar tu conjunto de ejemplos.

Antes de la implementación, sin embargo, tu mejor opción podría ser generar ejemplos sintéticos.

Aquí hay dos enfoques para generar ejemplos sintéticos que podrían resultarte útiles:

  1. Usa un LLM para generar ejemplos. ¡Puedes pedirle al LLM que varíe su lenguaje o incluso imite el estilo de los usuarios potenciales! Esto no funcionó para nosotros, pero estoy convencido de que podría funcionar para muchas aplicaciones.
  2. Genera ejemplos programáticamente, potencialmente con aleatoriedad, basándote en elementos en la consulta de entrada en sí. Para VoxelGPT, esto significa generar ejemplos basados en los campos en el conjunto de datos del usuario. Estamos en proceso de incorporar esto en nuestro pipeline, y los resultados que hemos visto hasta ahora han sido prometedores.

Herramientas

LangChain

LangChain es popular por una razón: la biblioteca facilita la conexión de las entradas y salidas de LLM de manera compleja, abstrayendo los detalles sangrientos. Los módulos Models y Prompts son especialmente excelentes.

Dicho esto, LangChain definitivamente es un trabajo en progreso: sus módulos de Recuerdos, Índices y Cadenas tienen limitaciones significativas. Aquí hay solo algunos de los problemas que encontré al intentar usar LangChain:

  1. Cargadores de documentos y divisores de texto: en LangChain, los Cargadores de Documentos deben transformar datos de diferentes formatos de archivo en texto, y los Divisores de Texto deben dividir el texto en fragmentos semánticamente significativos. VoxelGPT responde preguntas sobre la documentación de FiftyOne recuperando los fragmentos más relevantes de los documentos y enviándolos a una sugerencia. Para generar respuestas significativas a preguntas sobre la documentación de FiftyOne, tuve que construir efectivamente cargadores y divisores personalizados, porque LangChain no proporcionó la flexibilidad adecuada.
  2. Vectorstores: LangChain ofrece integraciones con Vectorstore y Recuperadores basados en Vectorstore para ayudar a encontrar información relevante para incorporar en las sugerencias de LLM. Esto es genial en teoría, pero las implementaciones carecen de flexibilidad. Tuve que escribir una implementación personalizada con ChromaDB para pasar vectores de embedding de antemano y no tener que recomputarlos cada vez que ejecutaba la aplicación. También tuve que escribir un recuperador personalizado para implementar el prefiltrado personalizado que necesitaba.
  3. Respuestas a preguntas con fuentes: al desarrollar respuestas a preguntas sobre la documentación de FiftyOne, llegué a una solución razonable utilizando la Cadena `RetrievalQA` de LangChain. Cuando quise agregar fuentes, pensé que sería tan sencillo como cambiar esa cadena por la Cadena `RetrievalQAWithSourcesChain` de LangChain. Sin embargo, las malas técnicas de sugerencia provocaron que esta cadena exhibiera un comportamiento desafortunado, como alucinaciones sobre Michael Jackson. Una vez más, tuve que tomar medidas por mi cuenta.

¿Qué significa todo esto? ¡Quizás sea más fácil construir los componentes por ti mismo!

Bases de datos vectoriales

La búsqueda vectorial puede estar en 🔥🔥🔥, pero eso no significa que la necesites para tu proyecto. Inicialmente implementé nuestra rutina de recuperación de ejemplos similares utilizando ChromaDB, pero como solo teníamos cientos de ejemplos, terminé cambiando a una búsqueda exacta del vecino más cercano. Sí tuve que lidiar con todo el filtrado de metadatos por mi cuenta, pero el resultado fue una rutina más rápida con menos dependencias.

TikToken

Agregar TikToken a la ecuación fue increíblemente fácil. En total, TikToken agregó <10 líneas de código al proyecto, pero nos permitió ser mucho más precisos al contar tokens e intentar ajustar la mayor cantidad de información posible en la longitud del contexto. Esta es la única herramienta verdaderamente sin complicaciones cuando se trata de herramientas.

Conclusión

Hay un montón de LLM para elegir, muchas herramientas nuevas y brillantes, y un montón de técnicas de “ingeniería de sugerencias”. Todo esto puede ser emocionante y abrumador al mismo tiempo. La clave para construir una aplicación con ingeniería de sugerencias es:

  1. Descomponer el problema; construir la solución
  2. Tratar a los LLM como habilitadores, no como soluciones de extremo a extremo
  3. Usar herramientas solo cuando te faciliten la vida
  4. ¡Acepta la experimentación!

¡Ve a construir algo genial!

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Una forma bayesiana de elegir un restaurante

Recientemente estuve buscando un nuevo buen restaurante. Google Maps me destacó 2 opciones el restaurante A con 10 re...

Inteligencia Artificial

Nvidia libera un chip de IA revolucionario para acelerar aplicaciones de IA generativa

En una era en la que la tecnología empuja constantemente los límites, Nvidia ha dejado una vez más su huella. La comp...

Inteligencia Artificial

La manía de la IA ¿Se dirige hacia una burbuja a punto de estallar?

El mundo de la inteligencia artificial (IA) experimentó un gran aumento de interés por parte de los inversores de cap...

Inteligencia Artificial

Este artículo de IA presenta LLaVA-Plus un asistente multimodal de propósito general que amplía las capacidades de los modelos multimodales grandes

Crear asistentes de propósito general que puedan llevar a cabo eficientemente diversas actividades del mundo real sig...

Ciencias de la Computación

Matthew Kearney Trayendo la inteligencia artificial y la filosofía al diálogo.

La doble especialización en informática y filosofía tiene como objetivo avanzar en el campo de la ética de la intelig...

Inteligencia Artificial

Automatiza la creación de subtítulos y la búsqueda de imágenes a escala empresarial utilizando la inteligencia artificial generativa y Amazon Kendra

Amazon Kendra es un servicio de búsqueda inteligente impulsado por aprendizaje automático (ML). Amazon Kendra redefin...