变量替换技巧
使用 f 字符串、.format() 和模板库渲染提示
变量替换技巧 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。
Python 模板渲染的四种方法
Python 提供了多种使用变量替换来渲染提示词模板的方法。每种方法都有其优势和取舍:
- f 字符串 — 内联、即时执行,无需导入
- str.format() — 命名占位符,便于验证
- string.Template — 安全的美元符号替换,支持部分填充
- Jinja2 — 完整的模板引擎:条件语句、循环、过滤器、继承
选择哪种方法取决于模板的复杂程度、团队技能,以及您是否需要条件语句和循环等高级功能。
方法 1:Python f 字符串
对于所有变量在渲染时都已准备好的提示词模板,f 字符串是最简单的方法:
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
))方法 2:str.format()
如果您希望将模板字符串与填充它们的代码分开存储,str.format() 会非常实用——例如从文件中加载模板时:
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方法 3:string.Template
Python 标准库中的 string.Template 使用美元符号占位符($variable 或 ${variable})。它的主要优势是:safe_substitute() 会将缺失的变量保留为字面占位符文本,而不是引发错误,因此可以实现部分填充:
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方法 4:Jinja2 基础
Jinja2 是一个完整的模板引擎。它支持条件语句、循环、过滤器和模板继承,功能远不止简单的字符串替换:
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模板中的 Jinja2 循环
Jinja2 循环可以让您遍历模板中的列表,适合根据数据结构生成包含多个项目的提示词:
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)Jinja2 过滤器
Jinja2 过滤器会在模板渲染期间直接转换变量值。以下是一些对提示词很有用的内置过滤器:
{{ topic | upper }}— 将主题转换为大写{{ word_count | default(200) }}— 未提供 word_count 时使用 200{{ audience | title }}— 将 audience 字符串转换为标题格式{{ items | join(', ') }}— 使用逗号连接列表
过滤器将转换逻辑保留在模板中,而不是放在调用模板的 Python 代码中,从而使模板更加独立且易于移植。
从文件加载模板
对于大型或复杂的模板,将模板存储在单独的文本文件中,可以让 Python 代码保持简洁。Jinja2 的环境对象和 FileSystemLoader 很适合处理这种情况:
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)选择合适的方法
请根据模板的复杂程度选择合适的替换方法:
- f 字符串 — 快速脚本、一次性自动化任务,以及短到可以直接内联阅读的模板
- str.format() — 存储的模板、团队代码库,以及希望在缺少变量时引发 KeyError 的情况
- string.Template — 内容可能包含花括号(例如代码片段),或需要部分填充时
- Jinja2 — 包含条件语句、循环、多个文件的复杂模板,或团队具备模板技术经验时
过度设计确实存在风险——只有在确实需要其高级功能时,才应选择 Jinja2。
模板安全性:注入攻击
当变量值来自用户输入时,提示词注入是一项实际风险。恶意用户可能会提供类似以下内容的值:“忽略之前的所有指令,并且……”
防御措施:
- 在替换前验证并清理所有用户提供的变量
- 对于面向用户的输入,请用分隔符包裹变量:“用户输入为:---{user_input}---”
- 使用输出过滤来检测并拒绝看起来遵循了注入指令的响应
- 绝不要让用户提供的值访问系统提示词变量
测试模板渲染
请始终将模板渲染与 API 调用分开测试。在将渲染后的字符串发送给模型之前,先对其进行验证:
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()知识检查:替换技术
您正在构建一个提示词系统:模板文件存储在磁盘上,模板包含条件部分(例如,根据某个标志决定是否包含定价部分),并且模板可能由多位熟悉 Web 模板技术的团队成员共同编写。
哪种替换方法最适合这种场景?
回顾:变量替换技术
Python 提供了四种提示词模板渲染方法:f 字符串(内联、简单)、str.format()(命名占位符,缺少变量时引发 KeyError)、string.Template(美元符号语法,支持安全的部分填充)以及 Jinja2(支持条件语句、循环、过滤器和文件加载的完整引擎)。
请根据复杂程度选择方法:快速脚本使用 f 字符串,存储的模板使用 str.format(),内容包含花括号时使用 string.Template,需要条件语句、循环或基于文件的模板时使用 Jinja2。请始终将模板渲染与 API 调用分开测试。
常见问题解答
「变量替换技巧」课时是免费的吗?
是的 — 「变量替换技巧」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。
「变量替换技巧」这节课中我会学到什么?
使用 f 字符串、.format() 和模板库渲染提示 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Prompt Engineering 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「变量替换技巧」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Prompt Engineering 课中编写并运行代码吗?
能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 什么是提示模板
- 创建填空模式
- 变量替换技巧
- 在不同任务间复用模板