📝 Chats con Plantillas Dinámicas
.
ℹ️ Summary
Esta guía proporciona un caso de uso sobre “Chat Dynamic Prompts”, donde partiendo de un prompt dinámico, proveer la información necesaria para dar un contexto a un chat.
.
🗂️ Background
Muchas veces las cadenas toman o devuelven múltiples claves de entrada/salida. En estos casos, ¿cómo podemos saber qué claves queremos guardar en el historial de mensajes de chat? En general, esto se puede controlar mediante los parámetros input_key
y output_key
de los tipos de memoria. Estos por defecto son undefined
.
.
Al operar con un formato entre entrada/salida en los contextos de un prompt, se requiere especificar el nombre del que se va a utilizar como input
o entrada del prompt como identificador de la memorización.
.
Enlaces auxiliares:
.
🎯 Problem
Implementar un “Chat Dynamic Prompts” utilizando TypeScript para generar un chat con un contexto dinámico a partir de una entrada de la cadena conversacional.
.
🚧 Solution
LanChain provee de ChatPromptTemplate
para poder darle formato a partir de una plantilla. Una vez establecida las plantillas según el origen (user, AI, etc.), se genera un contexto para que el chat.
import {
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
ChatPromptTemplate,
} from 'langchain/prompts'
const prompt = ChatPromptTemplate.fromMessages([
SystemMessagePromptTemplate.fromTemplate(
'You are a product expert who must provide detailed information about products from the brand {brand}.',
),
HumanMessagePromptTemplate.fromTemplate('{input}'),
])
En el prompt dinámico, generamos las variables de las cuales se embeberán en la creación del contexto.
.
Debido a que se proveerá de una memorización para proveer del contexto a partir del prompt, BufferMemory
requiere que se le indique el inputKey
para encadenar el contexto.
const memory = new BufferMemory({ inputKey: 'input' })
Finalmente, generamos una cadena conversacional e ingresamos las variables de entrada y dinámicas.
const chain = new ConversationChain({
llm,
memory,
prompt,
})
const response = await chain.call({
input: 'What features does the newest phone have?',
brand: 'Apple',
})
🍻 Discussion
Un sistema de memoria necesita soportar dos acciones básicas: lectura y escritura. Recordemos que cada cadena define un núcleo lógico de ejecución que espera ciertas entradas. Algunas de estas entradas vienen directamente del usuario, pero otras pueden venir de la memoria. Una cadena interactuará con su sistema de memoria dos veces en una ejecución dada.
.
- DESPUÉS de recibir las entradas iniciales del usuario pero ANTES de ejecutar la lógica del núcleo, una cadena LEERÁ de su sistema de memoria y aumentará las entradas del usuario.
- DESPUÉS de ejecutar la lógica central pero ANTES de devolver la respuesta, una cadena ESCRIBIRÁ las entradas y salidas de la ejecución actual en la memoria, para que puedan ser consultadas en futuras ejecuciones.
.
import { ConversationChain } from 'langchain/chains'
import { ChatOpenAI } from 'langchain/chat_models/openai'
import { BufferMemory } from 'langchain/memory'
import {
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
ChatPromptTemplate,
} from 'langchain/prompts'
const API_TOKEN = // 👈 Enter the API Token from OpenAI
const llm = new ChatOpenAI({
maxTokens: -1,
modelName: 'gpt-4',
temperature: 0,
openAIApiKey: API_TOKEN,
})
const prompt = ChatPromptTemplate.fromMessages([
SystemMessagePromptTemplate.fromTemplate(
'You are a product expert who must provide detailed information about products from the brand {brand}.',
),
HumanMessagePromptTemplate.fromTemplate('{input}'),
])
const memory = new BufferMemory({ inputKey: 'input' })
const chain = new ConversationChain({
llm,
memory,
prompt,
})
const response = await chain.call({
input: 'What features does the newest phone have?',
brand: 'Apple',
})
console.log(response)
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?