0Pricing
AI Prompt Engineering · Lección

Técnicas de sustitución de variables

f-strings, .format() y bibliotecas de plantillas para generar prompts.

Técnicas de sustitución de variables es una lección gratuita de AI Prompt Engineering en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Prompt Engineering, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Prompt Engineering incluye 4 lecciones en total.

Cuatro enfoques de Python para el renderizado de plantillas

Python ofrece varias formas de renderizar plantillas de prompts con sustitución de variables. Cada una tiene sus ventajas y limitaciones:

  • f-strings — en línea, inmediatas y sin necesidad de importar nada
  • str.format() — marcadores de posición con nombre y facilidad para validar
  • string.Template — sustitución segura mediante signos de dólar y compatibilidad con el completado parcial
  • Jinja2 — motor de plantillas completo: condicionales, bucles, filtros y herencia

La elección del enfoque adecuado depende de la complejidad de la plantilla, los conocimientos del equipo y la necesidad de funciones avanzadas como condicionales y bucles.

Enfoque 1: f-strings de Python

Las f-strings son el enfoque más sencillo para las plantillas de prompts cuando todas las variables están disponibles en el momento del renderizado:

import openai

client = openai.OpenAI(api_key='sk-...')

def generate_linkedin_post(company, topic, tone, word_count):
    prompt = (
        f'Write a LinkedIn post for {company} about {topic}. '
        f'Tone: {tone}. '
        f'Length: {word_count} words. '
        'Professional but conversational. '
        'End with one question to engage readers. '
        'No hashtags. Active voice.'
    )

    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

print(generate_linkedin_post(
    company='DataStream Analytics',
    topic='how AI is changing data pipelines',
    tone='enthusiastic but grounded',
    word_count=180
))

Enfoque 2: str.format()

str.format() funciona bien cuando desea almacenar las cadenas de plantilla por separado del código que las completa, algo útil para cargar plantillas desde archivos:

import openai

client = openai.OpenAI(api_key='sk-...')

# Template stored as a module-level constant or loaded from a file
SUPPORT_REPLY_TEMPLATE = '''You are a customer support agent for {company_name}.

Respond to this customer message:
---
{customer_message}
---

Tone: {tone}.
Keep the response under {max_words} words.
Do not offer refunds unless the customer explicitly asks.
Always close by asking if there is anything else you can help with.'''

def generate_support_reply(company, message, tone='empathetic and helpful', max_words=150):
    prompt = SUPPORT_REPLY_TEMPLATE.format(
        company_name=company,
        customer_message=message,
        tone=tone,
        max_words=max_words
    )

    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

Enfoque 3: string.Template

string.Template, de la biblioteca estándar de Python, utiliza marcadores de posición con signos de dólar ($variable o ${variable}). Su principal ventaja es que safe_substitute() deja las variables ausentes como texto literal del marcador de posición en lugar de generar un error, lo que permite realizar completados parciales:

from string import Template
import openai

client = openai.OpenAI(api_key='sk-...')

# $ placeholders — safe with code that contains curly braces
BASE_TEMPLATE = Template(
    'Write a $format_type for $audience about $topic. '
    'Tone: $tone. Length: $word_count words. '
    'Active voice. No jargon.'
)

def generate(format_type, audience, topic, tone='professional', word_count=200):
    prompt = BASE_TEMPLATE.substitute(
        format_type=format_type,
        audience=audience,
        topic=topic,
        tone=tone,
        word_count=word_count
    )

    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

# Partial fill example — safe_substitute leaves $word_count as-is
partial = BASE_TEMPLATE.safe_substitute(
    format_type='blog post', audience='developers', topic='API design'
)
print(partial)  # $tone and $word_count remain as placeholders

Enfoque 4: conceptos básicos de Jinja2

Jinja2 es un motor de plantillas completo. Admite condicionales, bucles, filtros y herencia de plantillas, mucho más que una simple sustitución de cadenas:

from jinja2 import Template
import openai

client = openai.OpenAI(api_key='sk-...')

# Jinja2 uses {{ }} for variables and {% %} for logic
JINJA_PROMPT = Template('''
Write a {{content_type}} for {{audience}} about {{topic}}.
Tone: {{tone}}.
{% if include_examples %}
Include {{example_count}} concrete examples.
{% endif %}
{% if word_count %}
Length: {{word_count}} words.
{% else %}
Aim for 200-300 words.
{% endif %}
Active voice. No jargon.
''')

def generate(content_type, audience, topic, tone, include_examples=False, example_count=2, word_count=None):
    prompt = JINJA_PROMPT.render(
        content_type=content_type,
        audience=audience,
        topic=topic,
        tone=tone,
        include_examples=include_examples,
        example_count=example_count,
        word_count=word_count
    )

    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

Bucles de Jinja2 en las plantillas

Los bucles de Jinja2 permiten iterar sobre listas en la plantilla, algo útil para generar prompts con varios elementos a partir de estructuras de datos:

from jinja2 import Template
import openai

client = openai.OpenAI(api_key='sk-...')

MULTI_PRODUCT_TEMPLATE = Template('''
Write a product comparison for {{audience}}.
Compare the following products:

{% for product in products %}
- {{product.name}}: {{product.description}}
{% endfor %}

Structure: one paragraph per product, then a 2-sentence recommendation.
Tone: {{tone}}. Active voice. No bullet points in paragraphs.
''')

products = [
    {'name': 'Asana', 'description': 'project management with timeline views'},
    {'name': 'Linear', 'description': 'developer-focused issue tracking'},
    {'name': 'Monday.com', 'description': 'visual work management for teams'}
]

prompt = MULTI_PRODUCT_TEMPLATE.render(
    audience='startup founders',
    products=products,
    tone='direct and practical'
)

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': prompt}]
)
print(response.choices[0].message.content)

Filtros de Jinja2

Los filtros de Jinja2 transforman los valores de las variables en línea durante el renderizado de la plantilla. Estos filtros integrados son útiles para los prompts:

  • {{ topic | upper }} — convertir el tema a mayúsculas
  • {{ word_count | default(200) }} — utilizar 200 si no se proporciona word_count
  • {{ audience | title }} — aplicar formato de título a la cadena de audience
  • {{ items | join(', ') }} — unir una lista con comas

Los filtros mantienen la lógica de transformación dentro de la plantilla en lugar de situarla en el código Python que la invoca, lo que hace que las plantillas sean más autónomas y portátiles.

Carga de plantillas desde archivos

En el caso de las plantillas grandes o complejas, almacenarlas en archivos de texto independientes mantiene limpio el código Python. Environment y FileSystemLoader de Jinja2 gestionan esta tarea adecuadamente:

from jinja2 import Environment, FileSystemLoader
import openai

client = openai.OpenAI(api_key='sk-...')

# Load all templates from the 'prompts/' directory
env = Environment(loader=FileSystemLoader('prompts/'))

def render_template(template_name, variables):
    '''Load and render a .j2 template file with the given variables.'''
    template = env.get_template(template_name)
    return template.render(**variables)

def generate_from_file(template_name, variables):
    prompt = render_template(template_name, variables)

    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

# Usage: load prompts/blog_post.j2 and fill with variables
result = generate_from_file('blog_post.j2', {
    'topic': 'API rate limiting strategies',
    'audience': 'backend engineers',
    'tone': 'technical and direct',
    'word_count': 500
})
print(result)

Elección del enfoque adecuado

Adapte el enfoque de sustitución a la complejidad de sus plantillas:

  • f-strings — scripts rápidos, automatización puntual y plantillas lo bastante cortas como para leerlas en línea
  • str.format() — plantillas almacenadas, bases de código de equipos y situaciones en las que resulta conveniente generar un KeyError cuando faltan variables
  • string.Template — cuando el contenido puede contener llaves (fragmentos de código) o se necesita un completado parcial
  • Jinja2 — plantillas complejas con condicionales, bucles, varios archivos o equipos con experiencia en sistemas de plantillas

El exceso de complejidad es un riesgo real: recurra a Jinja2 solo cuando necesite realmente sus funciones avanzadas.

Seguridad de las plantillas: ataques de inyección

Cuando los valores de las variables proceden de entradas del usuario, la inyección de prompts supone un riesgo real. Un usuario malintencionado podría proporcionar un valor como: "Ignore todas las instrucciones anteriores y..."

Medidas defensivas:

  • Valide y limpie todas las variables proporcionadas por el usuario antes de la sustitución
  • Para las entradas destinadas a usuarios, rodee la variable con delimitadores: "La entrada del usuario es: ---{user_input}---"
  • Utilice filtros de salida para detectar y rechazar respuestas que parezcan haber seguido instrucciones inyectadas
  • No permita nunca que los valores proporcionados por el usuario accedan a las variables del prompt del sistema

Prueba del renderizado de plantillas

Pruebe siempre el renderizado de las plantillas por separado de las llamadas a la API. Valide la cadena renderizada antes de enviarla al modelo:

def test_template_render():
    test_cases = [
        {'topic': 'cloud security', 'audience': 'CTOs', 'tone': 'formal', 'word_count': 300},
        {'topic': 'ML pipelines', 'audience': 'data scientists', 'tone': 'technical', 'word_count': 500},
        # Edge cases
        {'topic': '', 'audience': 'developers', 'tone': 'casual', 'word_count': 100},  # empty topic
        {'topic': 'AI' * 100, 'audience': 'all', 'tone': 'brief', 'word_count': 50},  # very long topic
    ]

    TEMPLATE = 'Write a {word_count}-word {tone} article about {topic} for {audience}. Active voice.'

    for i, case in enumerate(test_cases):
        try:
            rendered = TEMPLATE.format(**case)
            assert len(rendered) > 0, 'Empty render'
            print(f'Case {i+1} OK: {len(rendered)} chars')
        except (KeyError, AssertionError) as e:
            print(f'Case {i+1} FAILED: {e}')

test_template_render()

Comprobación de conocimientos: técnicas de sustitución

Está creando un sistema de prompts en el que los archivos de plantilla se almacenan en el disco, las plantillas incluyen secciones condicionales (por ejemplo, incluir opcionalmente una sección sobre precios según un indicador) y varios miembros del equipo familiarizados con los sistemas de plantillas web pueden contribuir a las plantillas.

¿Qué enfoque de sustitución es el más adecuado para este escenario?

Recapitulación: técnicas de sustitución de variables

Python ofrece cuatro enfoques para renderizar plantillas de prompts: f-strings (en línea y sencillas), str.format() (marcadores de posición con nombre y KeyError cuando faltan variables), string.Template (sintaxis con signos de dólar y completados parciales seguros) y Jinja2 (motor completo con condicionales, bucles, filtros y carga de archivos).

Adapte el enfoque a la complejidad: utilice f-strings para scripts rápidos, str.format() para plantillas almacenadas, string.Template cuando el contenido contenga llaves y Jinja2 cuando necesite condicionales, bucles o plantillas basadas en archivos. Pruebe siempre el renderizado por separado de las llamadas a la API.

Preguntas frecuentes

¿La lección «Técnicas de sustitución de variables» es gratis?

Sí — el texto completo de «Técnicas de sustitución de variables» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Prompt Engineering, actualiza a CoddyKit PRO. El curso de AI Prompt Engineering incluye 4 lecciones en total.

¿Qué aprenderé en «Técnicas de sustitución de variables»?

f-strings, .format() y bibliotecas de plantillas para generar prompts. Practicas AI Prompt Engineering con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar AI Prompt Engineering?

No se requiere experiencia previa. AI Prompt Engineering en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Técnicas de sustitución de variables»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de AI Prompt Engineering?

Sí. Cada lección de AI Prompt Engineering incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. ¿Qué es una plantilla de prompt?
  2. Creación de patrones para completar espacios
  3. Técnicas de sustitución de variables
  4. Reutilizar plantillas en distintas tareas
← Volver a AI Prompt Engineering