¿Alguna vez te has confundido con las plantillas Prompt en LangChain? ¿Qué hacen las llaves? ¿Cómo se pasan las variables para obtener la cadena final? ¿Cómo funcionan las cadenas multilínea? ¿Y las cadenas f?
Si estas preguntas te suenan, ¡has llegado al lugar adecuado! A mí también me resultaba confuso, así que he enumerado aquí cómo funcionan muchas de estas variaciones.
Mucho de esto es sólo saber cómo funcionan las cadenas literales en Python, por ejemplo, cómo funcionan las cadenas multi-línea, o las cadenas-f, así que si no estás muy familiarizado con ellas, puede ser muy confuso cuando las veas aparecer en PromptTemplates
.
Recuerda que si te interesa aprender más acerca de está maravilla puedes hacerlo AQUI
Bueno, al menos ese fue mi caso.
Vamos a sumergirnos.
Contenido
Configuración
Cómo crear una plantilla de aviso
Comillas simples y dobles
Plantilla Prompt con cadenas puras
Plantilla Prompt con variables
Creación de plantillas de instrucciones mediante el constructor
Plantillas Prompt con cadenas multilínea y variables
Prompt Templates con f-strings y Variables
Prompt Templates con f-strings multilínea y variables
Uso de una PromptTemplate en llamadas LLM
Conclusión
Configurar
Algunas cosas para configurar antes de empezar a bucear en Prompt Templates. Para seguir adelante puedes crear un directorio de proyecto para esto, configurar un entorno virtual, e instalar los paquetes necesarios
mkdir prompt-templates
cd prompt-templates
python3 -m venv .venv
touch prompt-templates.py
pip install python-dotenv langchain langchain-openai
También puedes clonar el siguiente código desde GitHub utilizando
git clone https://github.com/smaameri/prompt-templates
O si lo prefieres, también puedes verlo dentro de un Google Colab
En esencia, un PromptTemplate
es sólo una plantilla de cadena a la que podemos pasar variables para generar nuestra cadena final. Y luego podemos pasar estos PromptTemplate's
a los LLM's para crear prompts con un formato consistente para el LLM.
Cómo crear una plantilla de aviso
Normalmente creamos el PromptTemplate`
usando el método from_template
, y llamamos al método format para generar la cadena final
prompt_template = PromptTemplate.from_template('my string ..')
print(prompt_template.format()) # -> 'my string ..'
Más detalles a continuación. Pero primero...
Comillas simples y dobles
No hay diferencia entre comillas simples y dobles en python así que no dejes que eso te confunda. Se pueden utilizar indistintamente.
Un caso en el que podría tener sentido es si su cadena también incluye una comilla simple o doble en su interior, en cuyo caso es posible que desee utilizar el tipo opuesto para encapsular la cadena literal, por lo que la comilla dentro de la cadena no rompe la encapsulación. Por supuesto, también puede escapar ( \ )
las comillas que aparecen dentro de la cadena.
En cualquier caso, las comillas simples y dobles son básicamente lo mismo, así que no dejes que esa parte te confunda si empiezas a verlas en ejemplos de código y documentación. Es sólo una elección estilística
Plantilla Prompt con cadenas puras
En realidad, ni siquiera es necesario tener variables en un PromptTemplate
para que funcione, aunque no estoy seguro de que tenga sentido usar PromptTemplates
para tal caso. Es mejor pasar una cadena simple al LLM. Así es como se ve
prompt_template = PromptTemplate.from_template(
'Tell me a funny joke about elephants.'
)
print(prompt_template.format())
# -> 'Tell me a funny joke about elephants.'
Plantilla con variables
Este es el caso de uso mucho más común para las plantillas prompt. Tenemos una cadena de plantilla, que queremos poder reemplazar dinámicamente sólo ciertas partes de esa cadena
Las partes variables de la plantilla están rodeadas por llaves { }
, y para rellenar estas partes pasamos una lista de pares clave-valor
(kwargs en python) con el nombre de la variable y el texto con el que deben rellenarse al método format()
de la plantilla de aviso.
prompt_template = PromptTemplate.from_template(
'Tell me a {adjective} joke about {content}'
)
print(prompt_template.format(adjective='funny', content='chickens'))
# -> 'Tell me a funny joke about chickens.'
Creación de plantillas Prompt mediante el constructor
También podemos crear una PromptTemplate
a través del constructor, en lugar de a través del método from_template
prompt_template = PromptTemplate(
template='Tell me a {adjective} joke about {content}',
input_variables=['adjective', 'cotent']
)
print(prompt_template.format(adjective='funny', content='chickens'))
# -> 'Tell me a funny joke about chickens.'
Plantillas con cadenas multilínea y variables
En realidad es lo mismo que una cadena normal. Sólo tiene que incluir comillas triples al principio y al final y listo. Las comillas simples o dobles funcionan igual
template = '''You are a joke generating chatbot.
Provide funny jokes based on the themes requested.
Question: Tell me a {adjective} joke about {content}
Answer: '''
prompt_template = PromptTemplate.from_template(template)
print(prompt_template.format(adjective='funny', content='chickens'))
Prompt Templates con f-strings
y Variables
Estos aparecen todo el tiempo, y son probablemente la base de mi confusión con las cadenas de plantilla, que probablemente apunta a una falta de conocimiento de python, v.s nada realmente hacer con LangChain.
prompt_template = PromptTemplate.from_template(
f'Tell me a {{adjective}} joke about {{content}}'
)
print(prompt_template.format(adjective="funny", content="chickens"))
El truco es que las variables deben ir entre comillas dobles. El IDE también resalta estas partes, haciéndolas más fáciles de identificar.
La razón es que las cadenas f analizan cualquier cosa dentro de llaves como expresiones python. Si desea incluir llaves dentro de una cadena-f, según los documentos de python:
Si necesita incluir un carácter de llaves en el texto literal, se puede escapar por duplicado: {{ y }}.
Un buen artículo con más detalles sobre f-strings
está aquí también.
Así que la única razón para usar f-strings
en PromptTemplates
sería si hay alguna variable externa o expresión python que te gustaría incluir en el PromptTemplate.
Este podría ser un caso de uso legítimo basado en lo que estés construyendo en ese momento.
Sin embargo, si no tiene un uso para ello, es mejor que utilice una cadena literal normal.
Sólo para demostrar lo que podría parecer, aquí hay un ejemplo en el que podemos querer incluir la fecha en nuestra plantilla de aviso
from datetime import date
today = date.today()
prompt_template = PromptTemplate.from_template(
f'Todays Date: {today}: Tell me a {{adjective}} joke about {{content}}',
template_format='f-string'
)
print(prompt_template.format(adjective="funny", content="chickens"))
# -> 'Todays Date: 2024-04-01:Tell me a funny joke about chickens.'
Plantillas con cadenas f multilínea y variables
Esto es igual que lo anterior, excepto que, de nuevo, utilizamos comillas triples para el inicio y el final de las cadenas multilínea, incluso si son cadenas f
template = f'''You are a joke generating chatbot.
Provide funny jokes based on the themes requested.
Question: Tell me a {{adjective}} joke about {{content}}'
Answer: '''
prompt_template = PromptTemplate.from_template(template)
print(prompt_template.format(adjective='funny', content='chickens'))
Uso de un PromptTemplate en llamadas LLM
Ninguna guía está completa sin hacer algunas llamadas a un LLM, ¿verdad?
Uno de los casos de uso de PromptTemplates
en LangChain es que puedes pasar el PromptTemplate como parámetro a una LLMChain
, y en futuras llamadas a la cadena, sólo necesitas pasar las variables que quieres sustituir.
prompt_template = PromptTemplate.from_template(
'Tell me a {adjective} joke about {content}'
)
openai = ChatOpenAI(
model_name='gpt-3.5-turbo-16k',
openai_api_key='sk-'
)
chain = LLMChain(llm=openai, prompt=prompt_template)
response = chain.invoke(
input={'adjective': 'scary', 'content': 'French'}
)
print(response['text'])
# -> Why did the French ghost refuse to go into haunted houses?
# -> Because he had déjà boo!
Conclusión
Espero que te haya sido útil.
¿Me he perdido algún caso de uso de PromptTemplate que utilices mucho, o que te gustaría que añadiera a la lista anterior? Házmelo saber, y estaremos encantados de actualizar la lista anterior basándome en algunos de tus casos de uso.
¡Feliz hacking!