initial commit: slides ready + upgraded
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: cover
|
||||
class: text-center
|
||||
---
|
||||
|
||||
# Módulo 4: Mensajes y Prompts
|
||||
|
||||
Sistema de mensajes, templates y gestión de contexto
|
||||
|
||||
<div class="pt-12">
|
||||
<span class="text-xl opacity-80">
|
||||
Comunicándote efectivamente con los LLMs
|
||||
</span>
|
||||
</div>
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Tipos de Mensajes
|
||||
|
||||
<div class="mt-4 text-sm">
|
||||
|
||||
Los **Chat Models** trabajan con mensajes tipados, no con texto plano. Cada tipo tiene una **carga semántica** que el modelo interpreta de forma diferente
|
||||
|
||||
<div class="mt-4 space-y-4">
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-blue-500 pl-3 bg-blue-50 dark:bg-blue-900/20 py-2 px-3">
|
||||
<span class="font-bold text-base">💼 SystemMessage</span> <span class="text-xs opacity-70">(role: "system")</span>
|
||||
<p class="text-sm mt-2 mb-0">Instrucciones iniciales que <b>condicionan todo el comportamiento</b> del modelo. Define persona, reglas, restricciones y formato de respuesta. Tiene la <b>mayor prioridad</b> en la atención del modelo.</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-green-500 pl-3 bg-green-50 dark:bg-green-900/20 py-2 px-3">
|
||||
<span class="font-bold text-base">👤 HumanMessage</span> <span class="text-xs opacity-70">(role: "user")</span>
|
||||
<p class="text-sm mt-2 mb-0">Input del usuario. Es lo que el modelo debe <b>responder directamente</b>. Puede contener texto, imágenes, audio y archivos (multimodal).</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Tipos de Mensajes (cont.)
|
||||
|
||||
<div class="mt-4 text-sm">
|
||||
|
||||
<div class="mt-4 space-y-4">
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-purple-500 pl-3 bg-purple-50 dark:bg-purple-900/20 py-2 px-3">
|
||||
<span class="font-bold text-base">🤖 AIMessage</span> <span class="text-xs opacity-70">(role: "assistant")</span>
|
||||
<p class="text-sm mt-2 mb-0">Respuesta previa del modelo. Se usa para <b>historial de conversación</b> y para <b>few-shot learning</b>. Puede incluir <code>tool_calls</code>, <code>usage_metadata</code> y <code>response_metadata</code>.</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-orange-500 pl-3 bg-orange-50 dark:bg-orange-900/20 py-2 px-3">
|
||||
<span class="font-bold text-base">🔧 ToolMessage</span> <span class="text-xs opacity-70">(role: "tool")</span>
|
||||
<p class="text-sm mt-2 mb-0">Resultado de una herramienta ejecutada. Requiere <code>tool_call_id</code> que enlaza con el <code>AIMessage</code> que solicitó la herramienta. Cierra el <b>ciclo de tool-calling</b>.</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="mt-4 text-xs bg-gray-100 dark:bg-gray-800 rounded p-3">
|
||||
💡 También puedes usar la <b>notación abreviada</b> con tuplas: <code>["system", "..."]</code>, <code>["human", "..."]</code>, <code>["ai", "..."]</code> dentro de <code>ChatPromptTemplate</code>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Implicaciones: System vs Human
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
|
||||
El tipo de mensaje **no es solo una etiqueta**, cambia cómo el modelo procesa la información
|
||||
|
||||
<div class="mt-4 grid grid-cols-2 gap-4">
|
||||
|
||||
<v-click>
|
||||
<div class="border rounded-lg p-4 bg-blue-50 dark:bg-blue-900/20">
|
||||
<h3 class="text-base font-bold mb-2">💼 System vs Human</h3>
|
||||
<p class="text-xs mb-2">Poner instrucciones en <code>SystemMessage</code> vs en <code>HumanMessage</code> <b>no es equivalente</b>:</p>
|
||||
<ul class="text-xs list-disc pl-4 space-y-1">
|
||||
<li>System tiene <b>mayor prioridad</b> — el modelo lo trata como "ley"</li>
|
||||
<li>Human se trata como "petición" — puede ser ignorado si contradice al system</li>
|
||||
<li>En Anthropic, system va en un <b>parámetro separado</b> de la API</li>
|
||||
</ul>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border rounded-lg p-4 bg-purple-50 dark:bg-purple-900/20">
|
||||
<h3 class="text-base font-bold mb-2">🤖 AIMessage manual</h3>
|
||||
<p class="text-xs mb-2">Puedes <b>inyectar AIMessages falsos</b> en el historial:</p>
|
||||
<ul class="text-xs list-disc pl-4 space-y-1">
|
||||
<li>El modelo "cree" que él mismo dijo eso</li>
|
||||
<li>Útil para <b>few-shot</b>: enseñar el patrón de respuesta deseado</li>
|
||||
<li>Útil para <b>prefilling</b>: forzar el inicio de la respuesta</li>
|
||||
</ul>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Implicaciones: Tool Calling y Orden
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
|
||||
<div class="mt-4 grid grid-cols-2 gap-4">
|
||||
|
||||
<v-click>
|
||||
<div class="border rounded-lg p-4 bg-orange-50 dark:bg-orange-900/20">
|
||||
<h3 class="text-base font-bold mb-2">🔧 Ciclo de Tool Calling</h3>
|
||||
<p class="text-xs mb-2">El flujo completo requiere <b>3 mensajes</b>:</p>
|
||||
<ol class="text-xs list-decimal pl-4 space-y-1">
|
||||
<li><code>AIMessage</code> con <code>tool_calls</code> → modelo pide ejecutar</li>
|
||||
<li><code>ToolMessage</code> con resultado → tu app ejecuta y devuelve</li>
|
||||
<li><code>AIMessage</code> final → modelo interpreta el resultado</li>
|
||||
</ol>
|
||||
<p class="text-xs mt-2 opacity-70">Lo veremos en detalle en el módulo de <b>Agentes</b></p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border rounded-lg p-4 bg-green-50 dark:bg-green-900/20">
|
||||
<h3 class="text-base font-bold mb-2">📋 El orden importa</h3>
|
||||
<p class="text-xs mb-2">La <b>secuencia</b> de mensajes define el contexto:</p>
|
||||
<ul class="text-xs list-disc pl-4 space-y-1">
|
||||
<li>Los mensajes recientes tienen <b>más peso</b> que los antiguos</li>
|
||||
<li>El modelo espera alternancia <code>Human → AI → Human</code></li>
|
||||
<li>Romper la alternancia puede causar comportamiento inesperado</li>
|
||||
</ul>
|
||||
<p class="text-xs mt-2 opacity-70">Por eso la <b>gestión del historial</b> es clave</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Ejemplo: Usando Mensajes
|
||||
|
||||
<div class="text-sm mt-6">
|
||||
|
||||
```typescript
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import {
|
||||
SystemMessage,
|
||||
HumanMessage
|
||||
} from "@langchain/core/messages";
|
||||
|
||||
const model = new ChatOpenAI({ model: "gpt-4.1-mini" });
|
||||
|
||||
const messages = [
|
||||
new SystemMessage("Eres un experto en JavaScript y TypeScript"),
|
||||
new HumanMessage("¿Qué es async/await?")
|
||||
];
|
||||
|
||||
const response = await model.invoke(messages);
|
||||
|
||||
console.log(response.content);
|
||||
// Respuesta contextualizada como experto en JS/TS
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Prompt Templates
|
||||
|
||||
<div class="mt-4 text-sm">
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mb-4">
|
||||
|
||||
**ChatPromptTemplate** permite reutilizar prompts con variables dinámicas y la notación abreviada de roles
|
||||
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
```typescript
|
||||
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
||||
|
||||
const template = ChatPromptTemplate.fromMessages([
|
||||
["system", "Eres un experto en {topic}"], // ← shorthand de SystemMessage
|
||||
["human", "{question}"] // ← shorthand de HumanMessage
|
||||
]);
|
||||
|
||||
const prompt = await template.invoke({
|
||||
topic: "JavaScript",
|
||||
question: "¿Qué es async/await?"
|
||||
});
|
||||
|
||||
const response = await model.invoke(prompt);
|
||||
```
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mt-3 text-xs bg-gray-100 dark:bg-gray-800 rounded p-2">
|
||||
💡 Los templates son útiles para <b>reutilización</b>, <b>testing</b> y separar prompts de la lógica. Pero para casos simples, puedes usar mensajes directamente.
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Ventajas de Templates
|
||||
|
||||
<div class="mt-6 text-sm space-y-3">
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-green-500 pl-4 bg-green-50 dark:bg-green-900/20 py-2 px-3">
|
||||
<h3 class="text-base font-bold mb-1">✅ Reutilización</h3>
|
||||
<p class="text-xs">El mismo template con diferentes variables</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-blue-500 pl-4 bg-blue-50 dark:bg-blue-900/20 py-2 px-3">
|
||||
<h3 class="text-base font-bold mb-1">✅ Mantenibilidad</h3>
|
||||
<p class="text-xs">Cambiar el prompt en un solo lugar</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-purple-500 pl-4 bg-purple-50 dark:bg-purple-900/20 py-2 px-3">
|
||||
<h3 class="text-base font-bold mb-1">✅ Testing</h3>
|
||||
<p class="text-xs">Probar con múltiples combinaciones de variables</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-orange-500 pl-4 bg-orange-50 dark:bg-orange-900/20 py-2 px-3">
|
||||
<h3 class="text-base font-bold mb-1">✅ Separación de Responsabilidades</h3>
|
||||
<p class="text-xs">Prompts independientes de la lógica de negocio</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Few-Shot Prompting
|
||||
|
||||
<div class="mt-8 text-sm">
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mb-6">
|
||||
|
||||
**Few-shot**: Dar ejemplos al LLM para que aprenda el patrón deseado
|
||||
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
```typescript
|
||||
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
||||
|
||||
const template = ChatPromptTemplate.fromMessages([
|
||||
["system", "Clasifica el sentimiento de tweets"],
|
||||
["human", "Me encanta este producto!"],
|
||||
["ai", "positivo"],
|
||||
["human", "No funciona bien :("],
|
||||
["ai", "negativo"],
|
||||
["human", "{tweet}"] // El tweet a clasificar
|
||||
]);
|
||||
|
||||
const response = await model.invoke(
|
||||
await template.invoke({ tweet: "Buena experiencia" })
|
||||
);
|
||||
// → "positivo"
|
||||
```
|
||||
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Historial de Conversación
|
||||
|
||||
<div class="mt-8 text-sm">
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mb-6">
|
||||
|
||||
Para mantener **contexto** entre mensajes, acumula el historial
|
||||
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
```typescript
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { HumanMessage, AIMessage } from "@langchain/core/messages";
|
||||
|
||||
const model = new ChatOpenAI({ model: "gpt-4.1-mini" });
|
||||
|
||||
const history = [
|
||||
new HumanMessage("Hola, me llamo Juan"),
|
||||
new AIMessage("Hola Juan, ¿en qué puedo ayudarte?"),
|
||||
new HumanMessage("¿Cuál es mi nombre?")
|
||||
];
|
||||
|
||||
const response = await model.invoke(history);
|
||||
console.log(response.content);
|
||||
// → "Tu nombre es Juan"
|
||||
```
|
||||
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Gestión de Historial
|
||||
|
||||
<div class="mt-10 text-sm">
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mb-8">
|
||||
|
||||
**Problema**: El historial crece indefinidamente → Tokens infinitos → Costos altos
|
||||
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
<div class="space-y-5">
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-orange-500 pl-4 bg-orange-50 dark:bg-orange-900/20 p-3">
|
||||
<h3 class="text-base font-bold mb-2">📏 Limitar por cantidad</h3>
|
||||
<p class="text-xs">Mantener solo los últimos N mensajes</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-blue-500 pl-4 bg-blue-50 dark:bg-blue-900/20 p-3">
|
||||
<h3 class="text-base font-bold mb-2">📊 Limitar por tokens</h3>
|
||||
<p class="text-xs">Mantener solo los últimos N tokens</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
<div class="border-l-4 border-purple-500 pl-4 bg-purple-50 dark:bg-purple-900/20 p-3">
|
||||
<h3 class="text-base font-bold mb-2">📝 Resumir</h3>
|
||||
<p class="text-xs">Comprimir conversaciones antiguas en un resumen</p>
|
||||
</div>
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Ejemplo: Limitando Historial
|
||||
|
||||
<div class="text-sm mt-6">
|
||||
|
||||
```typescript
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { HumanMessage, AIMessage } from "@langchain/core/messages";
|
||||
|
||||
const model = new ChatOpenAI({ model: "gpt-4.1-mini" });
|
||||
|
||||
// Simular un historial largo
|
||||
const fullHistory = [
|
||||
new HumanMessage("Mensaje 1"),
|
||||
new AIMessage("Respuesta 1"),
|
||||
new HumanMessage("Mensaje 2"),
|
||||
new AIMessage("Respuesta 2"),
|
||||
new HumanMessage("Mensaje 3"),
|
||||
new AIMessage("Respuesta 3"),
|
||||
];
|
||||
|
||||
// Mantener solo los últimos 4 mensajes (2 turnos)
|
||||
const recentHistory = fullHistory.slice(-4);
|
||||
|
||||
const response = await model.invoke([
|
||||
...recentHistory,
|
||||
new HumanMessage("Nueva pregunta")
|
||||
]);
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Placeholder Variables
|
||||
|
||||
<div class="mt-8 text-sm">
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mb-6">
|
||||
|
||||
**MessagesPlaceholder**: Insertar arrays de mensajes dinámicamente en templates
|
||||
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
```typescript
|
||||
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
|
||||
|
||||
const template = ChatPromptTemplate.fromMessages([
|
||||
["system", "Eres un asistente útil"],
|
||||
new MessagesPlaceholder("history"), // Array de mensajes
|
||||
["human", "{input}"]
|
||||
]);
|
||||
|
||||
const response = await model.invoke(
|
||||
await template.invoke({
|
||||
history: [
|
||||
new HumanMessage("Hola"),
|
||||
new AIMessage("¡Hola! ¿En qué puedo ayudarte?")
|
||||
],
|
||||
input: "¿Qué tiempo hace?"
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mt-2 text-xs text-gray-500">
|
||||
💡 <code>["system", "..."]</code> y <code>["human", "..."]</code> son la forma abreviada de <code>SystemMessage</code> y <code>HumanMessage</code> en <code>ChatPromptTemplate</code>
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
# Partial Templates
|
||||
|
||||
<div class="mt-8 text-sm">
|
||||
|
||||
<v-click>
|
||||
|
||||
<div class="mb-6">
|
||||
|
||||
**Partial**: Pre-rellenar algunas variables, completar otras después
|
||||
|
||||
</div>
|
||||
|
||||
</v-click>
|
||||
|
||||
<v-click>
|
||||
|
||||
```typescript
|
||||
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
||||
|
||||
const template = ChatPromptTemplate.fromMessages([
|
||||
["system", "Eres un experto en {topic} que habla {language}"],
|
||||
["human", "{question}"]
|
||||
]);
|
||||
|
||||
// Pre-configurar topic y language
|
||||
const spanishJSTemplate = await template.partial({
|
||||
topic: "JavaScript",
|
||||
language: "español"
|
||||
});
|
||||
|
||||
// Ahora solo necesitas la pregunta
|
||||
const response = await model.invoke(
|
||||
await spanishJSTemplate.invoke({ question: "¿Qué es async/await?" })
|
||||
);
|
||||
```
|
||||
|
||||
</v-click>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user