Un flujo de trabajo completo para la optimización automática de indicaciones utilizando Gemini Flash, selección de pocas tomas y búsqueda de instrucciones evolutivas

En este tutorial, pasamos de la elaboración tradicional de mensajes a un enfoque más sistemático y programable al tratar los mensajes como parámetros ajustables en lugar de texto estático. En lugar de adivinar qué instrucción o ejemplo funciona mejor, creamos un ciclo de optimización alrededor de Gemini 2.0 Flash que experimenta, evalúa y selecciona automáticamente la configuración de aviso más sólida. En esta implementación, observamos cómo nuestro modelo mejora paso a paso, lo que demuestra cómo la ingeniería rápida se vuelve mucho más poderosa cuando la orquestamos con una búsqueda basada en datos en lugar de con la intuición. Consulte los códigos completos aquí.

importar google.generativeai como genai importar json importar aleatorio al escribir importar Lista, Dict, Tuple, Opcional de clases de datos importar clase de datos importar numpy como np de colecciones importar Contador def setup_gemini(api_key: str = Ninguno): si api_key es Ninguno: api_key = input(“Ingrese su clave API de Gemini: “).strip() genai.configure(api_key=api_key) model = genai.GenerativeModel(‘gemini-2.0-flash-exp’) print(” ✓ Gemini 2.0 Flash configurado”) modelo de retorno clase @dataclass Ejemplo: texto: str sentimiento: str def to_dict(self): return {“text”: self.text, “sentiment”: self.sentiment} @dataclass clase Predicción: sentimiento: str razonamiento: str = “” confianza: float = 1.0

Importamos todas las bibliotecas necesarias y definimos el asistente setup_gemini para configurar Gemini 2.0 Flash. También creamos las clases de datos de Ejemplo y Predicción para representar las entradas del conjunto de datos y las salidas del modelo de una manera limpia y estructurada. Consulte los códigos completos aquí.

def create_dataset() -> Tupla[List[Example]Lista[Example]]: datos_tren = [
Example(“This movie was absolutely fantastic! Best film of the year.”, “positive”),
Example(“Terrible experience, waste of time and money.”, “negative”),
Example(“The product works as expected, nothing special.”, “neutral”),
Example(“I’m blown away by the quality and attention to detail!”, “positive”),
Example(“Disappointing and overpriced. Would not recommend.”, “negative”),
Example(“It’s okay, does the job but could be better.”, “neutral”),
Example(“Incredible customer service and amazing results!”, “positive”),
Example(“Complete garbage, broke after one use.”, “negative”),
Example(“Average product, met my basic expectations.”, “neutral”),
Example(“Revolutionary! This changed everything for me.”, “positive”),
Example(“Frustrating bugs and poor design choices.”, “negative”),
Example(“Decent quality for the price point.”, “neutral”),
Example(“Exceeded all my expectations, truly remarkable!”, “positive”),
Example(“Worst purchase I’ve ever made, avoid at all costs.”, “negative”),
Example(“It’s fine, nothing to complain about really.”, “neutral”),
Example(“Absolutely stellar performance, 5 stars!”, “positive”),
Example(“Broken and unusable, total disaster.”, “negative”),
Example(“Meets requirements, standard quality.”, “neutral”),
]
val_datos = [
Example(“Absolutely love it, couldn’t be happier!”, “positive”),
Example(“Broken on arrival, very upset.”, “negative”),
Example(“Works fine, no major issues.”, “neutral”),
Example(“Outstanding performance and great value!”, “positive”),
Example(“Regret buying this, total letdown.”, “negative”),
Example(“Adequate for basic use.”, “neutral”),
]
devolver train_data, val_data clase PromptTemplate: def __init__(self, instrucción: str = “”, ejemplos: Lista[Example] = Ninguno): self.instruction = instrucción self.examples = ejemplos o []
def formato(self, texto: str) -> str: Prompt_parts = []
if self.instruction:prompt_parts.append(self.instruction) if self.examples:prompt_parts.append(“\nEjemplos:”) for ex in self.examples:prompt_parts.append(f”\nTexto: {ex.text}”)prompt_parts.append(f”Sentimiento: {ex.sentiment}”)prompt_parts.append(f”\nTexto: {texto}”) Prompt_parts.append(“Sentimiento:”) return “\n”.join(prompt_parts) def clone(self): devuelve PromptTemplate(self.instruction, self.examples.copy())

Generamos un conjunto de datos de sentimientos pequeño pero diverso para entrenamiento y validación utilizando la función create_dataset. Luego definimos PromptTemplate, que nos permite ensamblar instrucciones, algunos ejemplos breves y una consulta actual en una única cadena de aviso. Tratamos la plantilla como un objeto programable para que podamos intercambiar instrucciones y ejemplos durante la optimización. Consulte los códigos completos aquí.

clase SentimentModel: def __init__(self, model, Prompt_template: PromptTemplate): self.model = model self.prompt_template = Prompt_template def predict(self, text: str) -> Predicción: Prompt = self.prompt_template.format(text) prueba: respuesta = self.model.generate_content(prompt) resultado = respuesta.text.strip().lower() para sentimiento en [‘positive’, ‘negative’, ‘neutral’]: si el sentimiento está en el resultado: devuelve Predicción(sentimiento=sentimiento, razonamiento=resultado) devuelve Predicción(sentimiento=”neutral”, razonamiento=resultado) excepto Excepción como e: devuelve Predicción(sentimiento=”neutral”, razonamiento=cadena(e)) def evaluar(self, conjunto de datos: Lista[Example]) -> float: correcto = 0 por ejemplo en el conjunto de datos: pred = self.predict(ejemplo.texto) if pred.sentiment == ejemplo.sentiment: correcto += 1 return (correcto / len(conjunto de datos)) * 100

Envolvemos Gemini en la clase SentimentModel para poder llamarlo como un clasificador normal. Formateamos las indicaciones a través de la plantilla, llamamos a generate_content y postprocesamos el texto para extraer uno de los tres sentimientos. También agregamos un método de evaluación para poder medir la precisión de cualquier conjunto de datos con una sola llamada. Consulte los códigos completos aquí.

clase PromptOptimizer: def __init__(self, modelo): self.model = modelo self.instruction_candidates = [
“Analyze the sentiment of the following text. Classify as positive, negative, or neutral.”,
“Classify the sentiment: positive, negative, or neutral.”,
“Determine if this text expresses positive, negative, or neutral sentiment.”,
“What is the emotional tone? Answer: positive, negative, or neutral.”,
“Sentiment classification (positive/negative/neutral):”,
“Evaluate sentiment and respond with exactly one word: positive, negative, or neutral.”,
]

def select_best_examples(self, train_data: Lista[Example]val_data: lista[Example]n_ejemplos: int = 3) -> Lista[Example]: mejores_ejemplos = Ninguno mejor_puntuación = 0 para _ en el rango(10): ejemplos_por_sentimento = { ‘positivo’: [e for e in train_data if e.sentiment == ‘positive’]’negativo’: [e for e in train_data if e.sentiment == ‘negative’]’neutral’: [e for e in train_data if e.sentiment == ‘neutral’]
} seleccionado = []
por el sentimiento en [‘positive’, ‘negative’, ‘neutral’]: si ejemplos_por_sentimiento[sentiment]: seleccionado.append(elección.aleatoria(examples_by_sentiment[sentiment])) restante = [e for e in train_data if e not in selected]
mientras len(seleccionado) < n_ejemplos y restante: seleccionado.append(random.choice(restante)) restante.remove(seleccionado[-1]) plantilla = PromptTemplate (instrucción = self.instruction_candidates[0]ejemplos = seleccionado) test_model = SentimentModel (self.model, plantilla) puntuación = test_model.evaluate (val_data)[:3]) si puntaje > mejor puntaje: mejor puntaje = puntaje mejores_ejemplos = seleccionado devolver mejores_ejemplos def optimizar_instrucción(self, ejemplos: Lista[Example]val_data: lista[Example]) -> str: best_instruction = self.instruction_candidates[0]
best_score = 0 para instrucción en self.instruction_candidates: plantilla = PromptTemplate(instrucción=instrucción, ejemplos=ejemplos) test_model = SentimentModel(self.model, plantilla) puntaje = test_model.evaluate(val_data) if puntaje > mejor_puntuación: mejor_puntuación = puntaje mejor_instrucción = retorno de instrucción mejor_instrucción

Introducimos la clase PromptOptimizer y definimos un grupo de instrucciones candidatas para probar. Implementamos select_best_examples para buscar un conjunto pequeño y diverso de ejemplos de pocas tomas y optimizamos_instruction para calificar cada variante de instrucción en los datos de validación. De manera efectiva, estamos convirtiendo el diseño rápido en un problema de búsqueda liviano en lugar de ejemplos e instrucciones. Consulte los códigos completos aquí.

def compilar(self, train_data: Lista[Example]val_data: lista[Example]n_examples: int = 3) -> PromptTemplate: best_examples = self.select_best_examples(train_data, val_data, n_examples) best_instruction = self.optimize_instruction(best_examples, val_data) optimizado_template = PromptTemplate(instruction=best_instruction, ejemplos=best_examples) return plantilla_optimizada def main(): print(“=”*70) print(“Tutorial de optimización de mensajes”) print(“¡Deje de escribir mensajes, comience a programarlos!”) print(“=”*70) model = setup_gemini() train_data, val_data = create_dataset() print(f” ✓ {len(train_data)} ejemplos de entrenamiento, {len(val_data)} ejemplos de validación”) baseline_template = PromptTemplate( instrucción=”Clasificar sentimiento como positivo, negativo o neutral.”, ejemplos=[]
) base_model = SentimentModel(modelo, base_template) base_score = base_model.evaluate(val_data) manual_examples = train_data[:3]
manual_template = PromptTemplate( instrucción=”Clasificar sentimiento como positivo, negativo o neutral.”, ejemplos=manual_examples ) manual_model = SentimentModel(modelo, manual_template) manual_score = manual_model.evaluate(val_data) optimizador = PromptOptimizer(modelo) optimizado_template = optimizador.compile(train_data, val_data, n_examples=4)

Agregamos el método de compilación para combinar los mejores ejemplos y las mejores instrucciones en un PromptTemplate final optimizado. Dentro de main, configuramos Gemini, construimos el conjunto de datos y evaluamos tanto una línea de base de cero disparos como un sencillo mensaje manual de pocos disparos. Luego llamamos al optimizador para generar nuestro mensaje optimizado y compilado para el análisis de sentimientos. Consulte los códigos completos aquí.

modelo_optimizado = SentimentModel(modelo, plantilla_optimizada) puntuación_optimizada = modelo_optimizado.evaluate(val_data) print(f”Línea base (disparo cero): {baseline_score:.1f}%”) print(f”Pocas tomas manuales: {manual_score:.1f}%”) print(f”Optimizado (compilado): {optimized_score:.1f}%”) print(f”\nInstrucción: {optimized_template.instruction}”) print(f”\nEjemplos seleccionados ({len(optimized_template.examples)}):”) for i, ex in enumerate(optimized_template.examples, 1): print(f”\n{i}. Texto: {ex.text}”) print(f” Sentimiento: {ex.sentiment}”) test_cases = [
“This is absolutely amazing, I love it!”,
“Completely broken and unusable.”,
“It works as advertised, no complaints.”
]

para test_text en test_cases: print(f”\nEntrada: {test_text}”) pred = optimizado_model.predict(test_text) print(f”Predicted: {pred.sentiment}”) print(“¡Tutorial completo!”) if __name__ == “__main__”: main()

Evaluamos el modelo optimizado y comparamos su precisión con la configuración inicial y manual de pocos disparos. Imprimimos la instrucción elegida y los ejemplos seleccionados para poder inspeccionar lo que descubre el optimizador y luego ejecutamos algunas oraciones de prueba en vivo para ver las predicciones en acción. Terminamos resumiendo las mejoras y reforzando la idea de que las indicaciones se pueden ajustar mediante programación en lugar de escribirlas a mano.

En conclusión, implementamos cómo la optimización programática de avisos proporciona un flujo de trabajo repetible y basado en evidencia para diseñar avisos de alto rendimiento. Comenzamos con una base frágil, luego probamos instrucciones de forma iterativa, seleccionamos diversos ejemplos y compilamos una plantilla optimizada que supera los intentos manuales. Este proceso muestra que ya no dependemos de indicaciones de prueba y error; en cambio, organizamos un ciclo de optimización controlado. Además, podemos ampliar este proceso a nuevas tareas, conjuntos de datos más completos y métodos de puntuación más avanzados, lo que nos permite diseñar indicaciones con precisión, confianza y escalabilidad.

Consulte los códigos completos aquí. No dude en consultar nuestra página de GitHub para tutoriales, códigos y cuadernos. Además, no dude en seguirnos en Twitter y no olvide unirse a nuestro SubReddit de más de 100.000 ML y suscribirse a nuestro boletín. ¡Esperar! estas en telegrama? Ahora también puedes unirte a nosotros en Telegram.

Asif Razzaq es el director ejecutivo de Marktechpost Media Inc.. Como empresario e ingeniero visionario, Asif está comprometido a aprovechar el potencial de la inteligencia artificial para el bien social. Su esfuerzo más reciente es el lanzamiento de una plataforma de medios de inteligencia artificial, Marktechpost, que se destaca por su cobertura en profundidad del aprendizaje automático y las noticias sobre aprendizaje profundo que es técnicamente sólida y fácilmente comprensible para una amplia audiencia. La plataforma cuenta con más de 2 millones de visitas mensuales, lo que ilustra su popularidad entre el público.