0Pricing
AI Prompt Engineering · 강의

변수 치환 기법

프롬프트 렌더링에 사용하는 f-문자열, .format() 및 템플릿 라이브러리를 살펴봅니다.

변수 치환 기법은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.

파이썬의 템플릿 렌더링 네 가지 방식

파이썬에서는 변수 치환을 포함한 프롬프트 템플릿을 렌더링하는 여러 방법을 제공합니다. 각 방식에는 장점과 절충점이 있습니다:

  • f 문자열 — 인라인으로 즉시 사용할 수 있고 가져오기가 필요하지 않음
  • str.format() — 이름이 지정된 자리 표시자를 사용하며 유효성 검사에 유리함
  • string.Template — 안전한 달러 기호 치환을 지원하고 일부만 채울 수 있음
  • Jinja2 — 조건문, 반복문, 필터, 상속을 지원하는 완전한 템플릿 엔진

적절한 방식을 선택할 때는 템플릿의 복잡도, 팀의 역량, 조건문과 반복문 같은 고급 기능이 필요한지를 고려해야 합니다.

접근법 1: 파이썬 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

파이썬 표준 라이브러리의 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 }} — 대상 문자열을 제목 표기 형식으로 변환
  • {{ items | join(', ') }} — 쉼표로 목록 결합

필터를 사용하면 변환 로직을 호출하는 파이썬 코드가 아니라 템플릿 내부에 둘 수 있으므로 템플릿을 더 독립적이고 이식성 있게 만들 수 있습니다.

파일에서 템플릿 불러오기

크거나 복잡한 템플릿을 별도의 텍스트 파일에 저장하면 파이썬 코드를 깔끔하게 유지할 수 있습니다. 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()

지식 확인: 치환 기법

디스크에 템플릿 파일을 저장하고, 템플릿에 조건부 섹션을 포함하며(예: 플래그에 따라 가격 정보를 다루는 섹션을 선택적으로 포함), 여러 팀원이 템플릿을 작성하고 그 팀원들이 웹 템플릿 작성에 익숙한 프롬프트 시스템을 구축하고 있습니다.

이 시나리오에 가장 적합한 치환 방식은 무엇입니까?

복습: 변수 치환 기법

파이썬은 프롬프트 템플릿 렌더링을 위한 네 가지 방식을 제공합니다. f 문자열(인라인 방식, 간단함), str.format()(이름이 지정된 자리 표시자, 누락된 변수에 대한 KeyError), string.Template(달러 기호 구문, 안전한 부분 치환), Jinja2(조건문, 반복문, 필터, 파일 불러오기를 지원하는 완전한 엔진)입니다.

복잡도에 맞춰 방식을 선택하세요. 빠른 스크립트에는 f 문자열을, 저장된 템플릿에는 str.format()을, 콘텐츠에 중괄호가 포함될 때는 string.Template을, 조건문이나 반복문 또는 파일 기반 템플릿이 필요할 때는 Jinja2를 사용하세요. 렌더링은 항상 API 호출과 별도로 테스트하세요.

자주 묻는 질문

“변수 치환 기법” 강의는 무료인가요?

네 — “변수 치환 기법” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.

“변수 치환 기법”에서 뭘 배우나요?

프롬프트 렌더링에 사용하는 f-문자열, .format() 및 템플릿 라이브러리를 살펴봅니다. 브라우저에서 직접 실행하는 실습 코드로 AI Prompt Engineering을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Prompt Engineering을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Prompt Engineering은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“변수 치환 기법” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 프롬프트 템플릿이란 무엇인가
  2. 빈칸 채우기 패턴 만들기
  3. 변수 치환 기법
  4. 여러 작업에서 템플릿 재사용하기
← AI Prompt Engineering(으)로 돌아가기