iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Prompt Templates

Prompts are how you talk to the LLM. PromptTemplate / ChatPromptTemplate let you parametrise messages with variables, build chains, and re-use templates across the app.

Templates, messages, few-shot, partial

EXAMPLE
from langchain_core.prompts import (
    PromptTemplate, ChatPromptTemplate,
    MessagesPlaceholder, FewShotPromptTemplate, FewShotChatMessagePromptTemplate,
)
from langchain_core.example_selectors import LengthBasedExampleSelector, SemanticSimilarityExampleSelector
from langchain_anthropic import ChatAnthropic
from langchain_core.output_parsers import StrOutputParser

# 1) Simple string prompt
template = PromptTemplate.from_template(
    'Translate the following from English to {language}: {text}'
)

print(template.format(language='French', text='Hello'))
# Translate the following from English to French: Hello

# 2) Use it in a chain
llm = ChatAnthropic(model='claude-opus-4-7', temperature=0)
chain = template | llm | StrOutputParser()
chain.invoke({'language': 'French', 'text': 'Hello'})

# 3) ChatPromptTemplate — for chat models (with system / user / assistant roles)
chat_template = ChatPromptTemplate.from_messages([
    ('system', 'You are a helpful assistant translating from English to {language}.'),
    ('user',   '{text}'),
])

messages = chat_template.format_messages(language='French', text='Hello')
for m in messages:
    print(m.type, m.content)

# 4) With placeholder for chat history
from langchain_core.messages import HumanMessage, AIMessage

chat_template = ChatPromptTemplate.from_messages([
    ('system', 'You are a friendly assistant.'),
    MessagesPlaceholder('history'),
    ('user', '{input}'),
])

history = [
    HumanMessage(content='Hi, my name is Ada'),
    AIMessage(content='Hello Ada! How can I help?'),
]

chain = chat_template | llm | StrOutputParser()
chain.invoke({'history': history, 'input': 'What is my name?'})

# 5) Partial templates — pre-fill some variables
base = PromptTemplate.from_template(
    'You are an expert in {topic}. Answer this question: {question}'
)

python_expert = base.partial(topic='Python')
result = python_expert.format(question='How do I read a CSV file?')

# 6) Few-shot prompting — examples + a query
examples = [
    {'input': 'happy',    'output': 'sad'},
    {'input': 'tall',     'output': 'short'},
    {'input': 'fast',     'output': 'slow'},
]

example_template = PromptTemplate.from_template('Input: {input}\nOutput: {output}')

few_shot = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_template,
    prefix='Give the antonym of the input word.',
    suffix='Input: {word}\nOutput:',
    input_variables=['word'],
)

print(few_shot.format(word='hot'))

# 7) Few-shot for chat
example_chat = ChatPromptTemplate.from_messages([
    ('user',      '{input}'),
    ('assistant', '{output}'),
])

few_shot_chat = FewShotChatMessagePromptTemplate(
    example_prompt=example_chat,
    examples=examples,
)

chat = ChatPromptTemplate.from_messages([
    ('system', 'You are a word antonym assistant.'),
    few_shot_chat,
    ('user', '{input}'),
])

# 8) Dynamic example selection — too many examples to include all
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(),
    Chroma,
    k=3,                                   # top-3 most similar examples
)

dynamic = FewShotPromptTemplate(
    example_selector=selector,
    example_prompt=example_template,
    prefix='Give the antonym of the input word.',
    suffix='Input: {word}\nOutput:',
    input_variables=['word'],
)

print(dynamic.format(word='warm'))
# Picks the 3 most-similar examples from the corpus

# 9) Length-based selector
length_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_template,
    max_length=200,                        # truncate examples to fit context
)

# 10) Multimodal prompts (vision / image input)
from langchain_core.messages import HumanMessage

message = HumanMessage(content=[
    {'type': 'text', 'text': 'What is in this image?'},
    {'type': 'image_url', 'image_url': {'url': image_url}},
])

result = llm.invoke([message])

# 11) Structured output prompts — pair with parsers
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

class Person(BaseModel):
    name: str = Field(description='Full name')
    age:  int = Field(description='Age in years')
    email: str = Field(description='Email address')

parser = PydanticOutputParser(pydantic_object=Person)
prompt = PromptTemplate(
    template='Extract person info from: {text}\n{format_instructions}',
    input_variables=['text'],
    partial_variables={'format_instructions': parser.get_format_instructions()},
)

chain = prompt | llm | parser
result: Person = chain.invoke({'text': 'Ada is 32, ada@example.com'})

# 12) From file
template = PromptTemplate.from_file('./prompts/translate.txt')
# translate.txt:
# Translate the following from English to {language}: {text}

# 13) JSON loading
import json
with open('prompt.json') as f:
    config = json.load(f)
template = PromptTemplate(**config)

# 14) Composing prompts with PipelinePromptTemplate (deprecated path — favour LCEL)
# Modern approach: nest templates via .partial() and chain composition

# 15) Best practices
#   • Write the system prompt once; parametrise only what changes
#   • Few-shot examples > zero-shot for non-obvious tasks; 2-5 examples typically optimal
#   • Use the lowest temperature compatible with creativity needs (0 for extraction, 0.7 for ideation)
#   • Include format instructions when you want structured output
#   • Test with edge cases — empty inputs, very long inputs, hostile inputs
#   • Version your prompts (git, LangSmith) so you can A/B test changes
#   • Cache deterministic prompts (temperature=0) to save tokens

# 16) Common bugs
#   • Forgetting to escape curly braces in templates: '{{not a variable}}'
#   • Mixing chat + completion model with the wrong template type
#   • System prompt that contradicts user behaviour → model ignores one
#   • Few-shot with examples that are too similar → model overfits to them
#   • Long context window stuffed with examples → cost + latency explode

# 17) Modern alternatives
#   • Prompt-flow tools: LangSmith, Helicone, Promptlayer
#   • Versioned prompts in a registry + traced runs
#   • Eval frameworks: pytest-style for prompt regressions

Why it matters

Prompts are code — version them, test them, parametrise them. Few-shot with a dynamic example selector (semantic similarity over a corpus) outperforms hand-picked examples once you have more than a dozen.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
    ('system', 'You are a helpful tutor for {subject}.'),
    ('human', '{question}'),
])
messages = prompt.format_messages(subject='SQL', question='What is a JOIN?')
Try it Yourself »

Exercise

Reusable prompt template class.

from langchain_core.prompts import

Test yourself

Q1. A reusable templated prompt uses…
Q2. A prompt is filled in with…
Q3. Use system messages to…

Discussion

Loading…