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

Structured Output with JSON Mode

Taming the chatbot to speak machine code. Why text is not enough.

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

You ask the model for JSON. It replies: "Sure! Here is the JSON file: json* *{ "answer": 42 }* * Hope that helps!"

This breaks your app. Your JSON parser crashes because of the text "Sure! Here is..." Text is for humans. JSON is for systems.

OpeAI (and many others) support a response_format parameter. It forces the model to output only valid JSON.

json_mode.py
model = ChatOpenAI(model="gpt-4o", model_kwargs={"response_format": {"type": "json_object"}})

chain = prompt | model

# IMPORTANT: You MUST mention "json" in the prompt for this to work
prompt = ChatPromptTemplate.from_template(
  "Output a JSON object with a field 'joke' about {topic}"
)

res = chain.invoke({"topic": "bears"})
print(res.content)
# Output: { "joke": "Why did the bear..." } (No extra text)

Getting a string that looks like JSON is good. Getting a Python dictionary is better.

json_parser.py
from langchain_core.output_parsers import JsonOutputParser

chain = prompt | model | JsonOutputParser()

res = chain.invoke({"topic": "bears"})
print(type(res)) 
# Output: <class 'dict'> -> {"joke": "..."}

If your code needs to read the answer, use JSON mode. Never rely on "prompt begging" (e.g. "Please don't say anything else"). Enforce it at the API level.

Key Intuition: "If software consumes it, structure it."

Track your progressSign in and your progress follows you across devices.
Sign in to track progress Next lesson
← Previous lessonPrompt Architecture & ReusabilityNext lesson →PydanticOutputParser