LCEL & ChainsLesson 5

Output Formatting

Every chain ends with a parser — that is what invoke returns. The LCEL lesson used StrOutputParser for a plain string. This lesson adds PydanticOutputParser when you need fixed fields: tag, purpose, example. Same HTML tag question, two return types.

Parser sets the return type

The model replies with text. The parser at the end turns it into what your code expects — a str, a dict, or a Pydantic object.

Parser is the last step — it sets what invoke returns:

prompt

ChatPromptTemplate

|

model

ChatOpenAI

|

parser

OutputParser

|

result

str or object

chain = prompt | model | parser
Swap the parser — string, dict, or Pydantic object.

StrOutputParser vs PydanticOutputParser

StrOutputParser pulls out the text string. On langchain-core 1.0+ the type may print as TextAccessor — still a str subclass (isinstance(…, str) is True). PydanticOutputParser parses JSON into HtmlTagInfo — read fields with info.tag, etc.

StrOutputParser

text = str_chain.invoke(
    {"tag": "a"}
)
# type: TextAccessor (str-like)
# isinstance(text, str) → True
# "The <a> tag creates a hyperlink…"

Print or pass straight to the next prompt

PydanticOutputParser

info = struct_chain.invoke(
    {"tag": "a"}
)
# type: HtmlTagInfo
info.tag       # str
info.purpose   # str
info.example   # str

Typed fields — use dot notation

LCEL used StrOutputParser. Here you add PydanticOutputParser for named fields.

HtmlTagInfo schema

List the fields in a BaseModel. Pass it to PydanticOutputParser and put format_instructions in the prompt so the reply is JSON matching those fields.

HtmlTagInfo fields

class HtmlTagInfo(BaseModel):
    tag: str      # e.g. "a"
    purpose: str  # one-sentence explanation
    example: str  # minimal HTML snippet
parser.get_format_instructions() adds the JSON field rules to the prompt.
Parser checks the JSON reply against these three fields.

Building struct_chain

  • PydanticOutputParser(pydantic_object=HtmlTagInfo) — parser plus get_format_instructions().
  • .partial(format_instructions=…) — fixes the JSON hint in the prompt template.
  • struct_chain = prompt | model | parser — same pipe as other lessons; parser is the only change.

The demo script

output_formatting_demo.py runs both parsers on a and img.

output_formatting_demo.py
"""output_formatting_demo.py"""
class HtmlTagInfo(BaseModel): …
parser = PydanticOutputParser(pydantic_object=HtmlTagInfo)
struct_chain = prompt.partial(format_instructions=…) | model | parser
info = struct_chain.invoke({"tag": tag})
print(info.tag, info.purpose, info.example)

Download the code

output_formatting_demo.py

StrOutputParser + PydanticOutputParser

Download .py
Save into your langchain-course folder. Needs venv, .env, and packages from Project Setup.

Run it

Activate the venv from Project Setup, then:

python output_formatting_demo.py
PowerShell — (.venv) active
(.venv) PS C:\projects\langchain-course> python output_formatting_demo.py
=== StrOutputParser ===
Tag: <a>
Type: TextAccessor
is str: True
Value: The HTML <a> tag creates a hyperlink to another page.
Tag: <img>
Type: TextAccessor
is str: True
Value: The HTML <img> tag embeds an image in a web page.
=== PydanticOutputParser ===
Tag: <a>
Type: HtmlTagInfo
tag: a
purpose: Defines a hyperlink to another page or resource.
example: <a href="/home">Go home</a>
Tag: <img>
Type: HtmlTagInfo
tag: img
purpose: Embeds an image in the document.
example: <img src="logo.png" alt="Site logo">
Output includes both a and img — scroll the terminal box if needed.

Which parser to pick

  • StrOutputParser — one text block: print it or feed it to the next prompt (LCEL and the chain lessons so far).
  • PydanticOutputParser — fixed fields you read with dot notation, like info.purpose here.
  • Official reference: Output parsers concept.

What's Next

Next: RunnableParallel — two branches from one input.