Learn/LangChain Mastery/Part 3 · 2. LCEL & Prompt Architecture
Lesson 14 of 68
SyllabusLangChain Mastery · Part 3

PromptTemplate vs ChatPromptTemplate

Why hardcoded strings kill your app. Treating prompts as software components.

Course outline & contents
LangChain Mastery
Your First Chatbot: Talking to an LLMLCEL: Why LangChain Is a Composition EngineThe Runnable Protocol (invoke, batch, stream)Pipe Operator & Data FlowRunnableLambda & Custom LogicRunnableParallel & BranchingPromptTemplate vs ChatPromptTemplateSystem, Human, AI MessagesPrompt Architecture & ReusabilityStructured Output with JSON ModePydanticOutputParserOutputFixingParserStreaming Tokens & Async Chains

In our first lesson, we used: prompt = f"Tell me a joke about {topic}"

This is fine for scripts, but terrible for apps.

  1. Security injection: What if {topic} contains instructions to ignore the prompt?
  2. No Type Checking: You don't know what variables are missing until runtime.
  3. No Serialization: You can't save an f-string to a file and load it later.

LangChain has two types of templates, mirroring the two types of models.

Used for older "Instruction" models (like GPT-3 davinci) or raw text completion.

string_prompt.py
from langchain_core.prompts import PromptTemplate

template = PromptTemplate.from_template("Tell me a joke about {topic}.")
formatted = template.invoke({"topic": "bears"})
# Output: StringPromptValue(text="Tell me a joke about bears.")

Used for Chat Models (GPT-4, Claude). This is what you will use 99% of the time.

chat_prompt.py
from langchain_core.prompts import ChatPromptTemplate

template = ChatPromptTemplate.from_messages([
  ("system", "You are a specialized AI."),
  ("human", "Tell me a joke about {topic}.")
])

formatted = template.invoke({"topic": "bears"})
# Output: ChatPromptValue(messages=[
#   SystemMessage(content="You are a specialized AI."),
#   HumanMessage(content="Tell me a joke about bears.")
# ])

By using ChatPromptTemplate, you are working with Message Objects, not just strings. This means:

  1. Validation: It checks if you forgot to pass {topic} logic before calling the API.
  2. Modularity: You can reuse the "System Message" across 10 different chains.
  3. Partial Formatting: You can "pre-fill" variables.
partial.py
def get_joke_chain(tone):
  # Pre-fill the 'tone' variable, leave 'topic' for later
  partial = template.partial(tone=tone)
  return partial | model

Stop concatenating strings. Use ChatPromptTemplate to structure your inputs. It’s safer, cleaner, and strictly typed.

Key Intuition: "Prompts are software components, not just text."

Track your progressSign in and your progress follows you across devices.
Sign in to track progress Next lesson
← Previous lessonRunnableParallel & BranchingNext lesson →System, Human, AI Messages