PromptTemplate
A PromptTemplate is a string with named placeholders. You fill them in at runtime.
from langchain_core.prompts import PromptTemplate
template = PromptTemplate.from_template(
"You are a helpful assistant. Answer this question: {question}"
)
prompt = template.invoke({"question": "What is LangChain?"})
Use PromptTemplate when working with plain LLMs (text-in). For chat models, use ChatPromptTemplate.
ChatPromptTemplate
Chat models expect a list of messages. ChatPromptTemplate lets you template that list with variables.
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "You are an expert in {topic}. Be concise."),
("human", "{question}"),
])
chain = prompt | llm | StrOutputParser()
chain.invoke({"topic": "Python", "question": "What is a decorator?"})
The system message sets the context; the human message is the user's input. Both accept variables.
Few-shot prompts
Show the model examples of the input/output pattern you expect. This significantly improves output quality for structured tasks.
from langchain_core.prompts import FewShotChatMessagePromptTemplate
examples = [
{"input": "happy", "output": "sad"},
{"input": "tall", "output": "short"},
]
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"), ("ai", "{output}")
])
few_shot_prompt = FewShotChatMessagePromptTemplate(
examples=examples,
example_prompt=example_prompt,
)
final_prompt = ChatPromptTemplate.from_messages([
("system", "Give the antonym of the word."),
few_shot_prompt,
("human", "{input}"),
])
Structured outputs (JSON mode)
Instead of parsing free text, you can tell the model to return a specific JSON schema every time.
LangChain's .with_structured_output() handles this cleanly using Pydantic.
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
class MovieReview(BaseModel):
title: str
rating: int # 1–10
summary: str
llm = ChatOpenAI(model="gpt-4o-mini")
structured_llm = llm.with_structured_output(MovieReview)
result = structured_llm.invoke("Review the movie Inception")
print(result.title) # "Inception"
print(result.rating) # 9
print(result.summary) # "A mind-bending thriller..."
The model is forced to output valid JSON matching your Pydantic schema. No output parsing needed — you get a typed Python object back.
Guardrails & validation
Structured outputs give you implicit validation — if the model's output does not match the schema, LangChain raises an error. For explicit guardrails, add validators to your Pydantic model:
from pydantic import BaseModel, field_validator
class MovieReview(BaseModel):
title: str
rating: int
summary: str
@field_validator("rating")
@classmethod
def rating_in_range(cls, v):
if not 1 <= v <= 10:
raise ValueError("Rating must be between 1 and 10")
return v
If the model returns a rating of 11, the validator rejects it before it reaches your code. Combine with LangChain's .with_retry() to automatically ask the model to try again.
Prompt debugging tips
1. Print the rendered prompt before sending
print(prompt.invoke({"topic": "Python", "question": "..."}))
Always verify the prompt looks exactly as intended before debugging the model's output.
2. Enable verbose mode
from langchain.globals import set_verbose
set_verbose(True)
Prints every prompt and response to the console as they happen. Turn off in production.
3. Use LangSmith for tracing
Set LANGCHAIN_TRACING_V2=true and LANGCHAIN_API_KEY to get a full trace of every chain run in the LangSmith UI — inputs, outputs, latency, token counts.
4. Test prompts in isolation
Before adding a prompt to a chain, invoke it standalone with llm.invoke(prompt.invoke({...})). Isolate whether the issue is the prompt or the chain.
Quick summary
- Use
ChatPromptTemplatefor all modern chat models - Few-shot examples dramatically improve output quality for structured tasks
.with_structured_output(PydanticModel)returns typed Python objects, no parsing needed- Add
field_validatorto enforce output constraints and combine with.with_retry() - Debug with
set_verbose(True)locally and LangSmith in production
LangChain Prompt Templates FAQ
What is a PromptTemplate in LangChain?
A PromptTemplate is a string with named placeholders that you fill in at runtime, such as 'Answer this question: {question}'. You build it with PromptTemplate.from_template() and call .invoke() with a dict of values. Use it with plain text-in LLMs; for chat models, use ChatPromptTemplate instead.
What is the difference between PromptTemplate and ChatPromptTemplate?
PromptTemplate produces a single string for text-in LLMs. ChatPromptTemplate produces a list of role-tagged messages (system, human, ai) for modern chat models like GPT-4o and Claude. Since nearly all current models are chat models, ChatPromptTemplate is what you should use for new projects.
How do I get structured JSON output from a LangChain prompt?
Call .with_structured_output(YourPydanticModel) on the chat model. LangChain forces the model to return JSON matching your Pydantic schema and gives you back a typed Python object — no manual parsing. Add field validators to your model to reject invalid values automatically.
What is a few-shot prompt in LangChain?
A few-shot prompt includes a handful of example input/output pairs so the model learns the pattern you expect. In LangChain you build these with FewShotChatMessagePromptTemplate, which injects the examples into the prompt. Few-shot examples noticeably improve output quality on structured tasks.
How do I debug LangChain prompts?
Print the rendered prompt with prompt.invoke({...}) before sending it, enable set_verbose(True) to log every prompt and response locally, use LangSmith tracing in production by setting LANGCHAIN_TRACING_V2=true, and test prompts in isolation before adding them to a chain.