# Output Parsers
<Note>
If you haven't already, we recommend first reading the section on [Calls](/docs/v1/learn/calls)
</Note>
Output Parsers in Mirascope provide a flexible way to process and structure the raw output from Large Language Models (LLMs). They allow you to transform the LLM's response into a more usable format, enabling easier integration with your application logic and improving the overall reliability of your LLM-powered features.
## Basic Usage and Syntax
<Callout type="api">
[`mirascope.llm.call.output_parser`](/docs/v1/api/llm/call)
</Callout>
Output Parsers are functions that take the call response object as input and return an output of a specified type. When you supply an output parser to a `call` decorator, it modifies the return type of the decorated function to match the output type of the parser.
Let's take a look at a basic example:
<TabbedSection>
<Tab value="Shorthand">
```python
from mirascope import llm
def parse_recommendation(response: llm.CallResponse) -> tuple[str, str]:
title, author = response.content.split(" by ")
return (title, author)
@llm.call(provider="$PROVIDER", model="$MODEL", output_parser=parse_recommendation) # [!code highlight]
def recommend_book(genre: str) -> str:
return f"Recommend a {genre} book. Output only Title by Author"
print(recommend_book("fantasy"))
# Output: ('"The Name of the Wind"', 'Patrick Rothfuss') # [!code highlight]
```
</Tab>
<Tab value="Template">
```python
from mirascope import llm, prompt_template
def parse_recommendation(response: llm.CallResponse) -> tuple[str, str]:
title, author = response.content.split(" by ")
return (title, author)
@llm.call(provider="$PROVIDER", model="$MODEL", output_parser=parse_recommendation) # [!code highlight]
@prompt_template("Recommend a {genre} book. Output only Title by Author")
def recommend_book(genre: str): ...
print(recommend_book("fantasy"))
# Output: ('"The Name of the Wind"', 'Patrick Rothfuss') # [!code highlight]
```
</Tab>
</TabbedSection>
## Additional Examples
There are many different ways to structure and parse LLM outputs, ranging from XML parsing to using regular expressions.
Here are a few examples:
<TabbedSection>
<Tab value="Regular Expression">
```python
import re
from mirascope import llm, prompt_template
def parse_cot(response: llm.CallResponse) -> str:
pattern = r"<thinking>.*?</thinking>.*?<o>(.*?)</o>" # [!code highlight]
match = re.search(pattern, response.content, re.DOTALL)
if not match:
return response.content
return match.group(1).strip()
@llm.call(provider="$PROVIDER", model="$MODEL", output_parser=parse_cot) # [!code highlight]
@prompt_template(
"""
First, output your thought process in <thinking> tags. # [!code highlight]
Then, provide your final output in <o> tags. # [!code highlight]
Question: {question}
"""
)
def chain_of_thought(question: str): ...
question = "Roger has 5 tennis balls. He buys 2 cans of 3. How many does he have now?"
output = chain_of_thought(question)
print(output)
```
</Tab>
<Tab value="XML">
```python
import xml.etree.ElementTree as ET
from mirascope import llm, prompt_template
from pydantic import BaseModel
class Book(BaseModel):
title: str
author: str
year: int
summary: str
# [!code highlight:16]
def parse_book_xml(response: llm.CallResponse) -> Book | None:
try:
root = ET.fromstring(response.content)
if (node := root.find("title")) is None or not (title := node.text):
raise ValueError("Missing title")
if (node := root.find("author")) is None or not (author := node.text):
raise ValueError("Missing author")
if (node := root.find("year")) is None or not (year := node.text):
raise ValueError("Missing year")
if (node := root.find("summary")) is None or not (summary := node.text):
raise ValueError("Missing summary")
return Book(title=title, author=author, year=int(year), summary=summary)
except (ET.ParseError, ValueError) as e:
print(f"Error parsing XML: {e}")
return None
@llm.call(provider="$PROVIDER", model="$MODEL", output_parser=parse_book_xml) # [!code highlight]
@prompt_template(
"""
Recommend a {genre} book. Provide the information in the following XML format:
# [!code highlight:7]
<book>
<title>Book Title</title>
<author>Author Name</author>
<year>Publication Year</year>
<summary>Brief summary of the book</summary>
</book>
Output ONLY the XML and no other text.
"""
)
def recommend_book(genre: str): ...
book = recommend_book("science fiction")
if book:
print(f"Title: {book.title}")
print(f"Author: {book.author}")
print(f"Year: {book.year}")
print(f"Summary: {book.summary}")
else:
print("Failed to parse the recommendation.")
```
</Tab>
<Tab value="JSON Mode">
```python
import json
from mirascope import llm
def only_json(response: llm.CallResponse) -> str:
json_start = response.content.index("{") # [!code highlight]
json_end = response.content.rfind("}") # [!code highlight]
return response.content[json_start : json_end + 1] # [!code highlight]
@llm.call( # [!code highlight]
provider="$PROVIDER", model="$MODEL", json_mode=True, output_parser=only_json # [!code highlight]
) # [!code highlight]
def json_extraction(text: str, fields: list[str]) -> str:
return f"Extract {fields} from the following text: {text}"
json_response = json_extraction(
text="The capital of France is Paris",
fields=["capital", "country"],
)
print(json.loads(json_response))
```
</Tab>
</TabbedSection>
## Next Steps
By leveraging Output Parsers effectively, you can create more robust and reliable LLM-powered applications, ensuring that the raw model outputs are transformed into structured data that's easy to work with in your application logic.
Next, we recommend taking a look at the section on [Tools](/docs/v1/learn/tools) to learn how to extend the capabilities of LLMs with custom functions.