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
PascalCase.
Discussion
Loading…