Techniki podstawiania zmiennych
f-stringi, .format() i biblioteki szablonów do renderowania promptów.
Techniki podstawiania zmiennych to bezpłatna lekcja AI Prompt Engineering na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Prompt Engineering, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.
Cztery podejścia w Pythonie do renderowania szablonów
Python oferuje kilka sposobów renderowania szablonów promptów z podstawianiem zmiennych. Każdy z nich ma zalety i kompromisy:
- f-strings — umieszczane bezpośrednio w tekście, natychmiastowe, niewymagające importów
- str.format() — nazwane placeholdery, łatwe walidowanie
- string.Template — bezpieczne podstawianie z użyciem znaków dolara, obsługa częściowego uzupełniania
- Jinja2 — pełny silnik szablonów: warunki, pętle, filtry i dziedziczenie
Wybór właściwego podejścia zależy od złożoności szablonu, umiejętności zespołu oraz tego, czy potrzebne są zaawansowane funkcje, takie jak warunki i pętle.
Podejście 1: f-stringi w Pythonie
F-stringi są najprostszym podejściem do szablonów promptów, gdy wszystkie zmienne są dostępne w momencie renderowania:
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
))Podejście 2: str.format()
str.format() sprawdza się dobrze, gdy chcesz przechowywać ciągi szablonów oddzielnie od kodu, który je uzupełnia — jest to przydatne podczas wczytywania szablonów z plików:
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.contentPodejście 3: string.Template
string.Template ze standardowej biblioteki Pythona używa placeholderów ze znakiem dolara ($variable lub ${variable}). Jego kluczową zaletą jest to, że safe_substitute() pozostawia brakujące zmienne jako dosłowny tekst placeholdera zamiast zgłaszać błąd, co umożliwia częściowe uzupełnianie:
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 placeholdersPodejście 4: podstawy Jinja2
Jinja2 to pełny silnik szablonów. Obsługuje warunki, pętle, filtry i dziedziczenie szablonów — znacznie wykracza więc poza proste podstawianie ciągów znaków:
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.contentPętle Jinja2 w szablonach
Pętle Jinja2 umożliwiają iterowanie po listach w szablonie — jest to przydatne podczas generowania promptów zawierających wiele elementów na podstawie struktur danych:
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)Filtry Jinja2
Filtry Jinja2 przekształcają wartości zmiennych bezpośrednio podczas renderowania szablonu. Przydatne w promptach filtry wbudowane:
{{ topic | upper }}— zapisuje temat wielkimi literami{{ word_count | default(200) }}— używa wartości 200, jeśli nie podano word_count{{ audience | title }}— zapisuje ciąg audience w formacie tytułowym{{ items | join(', ') }}— łączy listę przecinkami
Filtry przenoszą logikę przekształceń do szablonu zamiast do kodu Pythona, który go wywołuje, dzięki czemu szablony są bardziej samodzielne i przenośne.
Wczytywanie szablonów z plików
W przypadku dużych lub złożonych szablonów przechowywanie ich w oddzielnych plikach tekstowych pozwala zachować przejrzystość kodu Pythona. Środowisko Jinja2 Environment i FileSystemLoader dobrze obsługują taki sposób pracy:
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)Wybór właściwego podejścia
Podejście do podstawiania należy dopasować do złożoności szablonów:
- f-strings — szybkie skrypty, jednorazowa automatyzacja, szablony wystarczająco krótkie, by czytać je bezpośrednio w kodzie
- str.format() — przechowywane szablony, projekty zespołowe, sytuacje, w których pożądany jest błąd KeyError przy braku zmiennych
- string.Template — gdy treść może zawierać nawiasy klamrowe (fragmenty kodu) lub potrzebne jest częściowe uzupełnianie
- Jinja2 — złożone szablony zawierające warunki, pętle, wiele plików lub używane przez zespół mający doświadczenie w tworzeniu szablonów
Nadmierne komplikowanie rozwiązania stanowi realne ryzyko — po Jinja2 należy sięgać tylko wtedy, gdy rzeczywiście potrzebne są jego zaawansowane funkcje.
Bezpieczeństwo szablonów: ataki typu injection
Gdy wartości zmiennych pochodzą od użytkownika, prompt injection stanowi realne zagrożenie. Złośliwy użytkownik może podać wartość taką jak: "Zignoruj wszystkie wcześniejsze instrukcje i..."
Środki ochrony:
- Waliduj i sanityzuj wszystkie zmienne podane przez użytkownika przed podstawieniem
- W przypadku danych wejściowych widocznych dla użytkownika ujmuj zmienną w delimitery: "Dane wejściowe użytkownika to: ---{user_input}---"
- Stosuj filtrowanie wyników, aby wykrywać i odrzucać odpowiedzi wyglądające na wygenerowane zgodnie z wstrzykniętymi instrukcjami
- Nigdy nie udostępniaj wartościom podanym przez użytkownika dostępu do zmiennych promptu systemowego
Testowanie renderowania szablonów
Zawsze należy testować renderowanie szablonów niezależnie od wywołań API. Przed wysłaniem wyrenderowanego ciągu znaków do modelu należy go zwalidować:
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()Sprawdzenie wiedzy: techniki podstawiania
Tworzysz system promptów, w którym pliki szablonów są przechowywane na dysku, szablony zawierają sekcje warunkowe (np. opcjonalną sekcję o cenach, dołączaną zależnie od flagi), a nad szablonami może pracować wielu członków zespołu znających technologie tworzenia szablonów internetowych.
Jakie podejście do podstawiania najlepiej pasuje do tego scenariusza?
Podsumowanie: techniki podstawiania zmiennych
Python oferuje cztery podejścia do renderowania szablonów promptów: f-stringi (bezpośrednie, proste), str.format() (nazwane placeholdery, KeyError przy braku zmiennych), string.Template (składnia ze znakiem dolara, bezpieczne częściowe uzupełnianie) oraz Jinja2 (pełny silnik z warunkami, pętlami, filtrami i wczytywaniem plików).
Podejście należy dopasować do złożoności: f-stringów używaj w szybkich skryptach, str.format() w przypadku przechowywanych szablonów, string.Template, gdy treść zawiera nawiasy klamrowe, a Jinja2, gdy potrzebujesz warunków, pętli lub szablonów opartych na plikach. Zawsze należy testować renderowanie niezależnie od wywołań API.
Często zadawane pytania
Czy lekcja „Techniki podstawiania zmiennych” jest bezpłatna?
Tak — pełny tekst „Techniki podstawiania zmiennych” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Prompt Engineering, przejdź na CoddyKit PRO. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.
Co nauczysz się w „Techniki podstawiania zmiennych”?
f-stringi, .format() i biblioteki szablonów do renderowania promptów. Ćwiczysz AI Prompt Engineering z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć AI Prompt Engineering?
Nie wymagamy żadnego doświadczenia. AI Prompt Engineering w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Techniki podstawiania zmiennych”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji AI Prompt Engineering?
Tak. Każda lekcja AI Prompt Engineering zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Czym jest szablon promptu?
- Tworzenie wzorców z miejscami do uzupełnienia
- Techniki podstawiania zmiennych
- Ponowne używanie szablonów w różnych zadaniach