Skip to main content
For the complete documentation index for agents and LLMs, see llms.txt.

JsonParser

Extract and parse JSON from text input, handling both plain JSON and Markdown code blocks. This is useful for processing language model outputs that return JSON data wrapped in Markdown formatting.

JsonParser is useful when processing language model outputs that return JSON data, as models often wrap JSON in Markdown formatting.

Key Features​

  • Parses plain JSON strings.
  • Handles JSON wrapped in Markdown code blocks (```json ... ```).
  • Handles JSON wrapped in generic code blocks (``` ... ```).
  • Configurable regex pattern for code block extraction.

Configuration​

  1. Drag the JsonParser component onto the canvas from the Component Library.
  2. Click on the component to open the configuration panel.
  3. Configure the component settings:
    • Set the Code Block Pattern if you need a custom regex to extract JSON from code blocks. The default pattern handles standard Markdown JSON blocks.

Connections​

JsonParser accepts a text string through its text input. It outputs the parsed JSON as a dictionary.

It typically connects with:

  • OpenAIChatGenerator or other generators (usually through an OutputAdapter): receives text containing JSON output from an LLM.
  • ConditionalRouter: sends the parsed JSON dictionary for conditional routing logic.

Usage Examples​

Basic Configuration​

  JsonParser:
type: deepset_cloud_custom_nodes.parsers.json_parser.JsonParser
init_parameters: {}

This is an example of JsonParser that receives text containing JSON from a generator and parses it. There is an OutputAdapter between the generator and JsonParser to align the input and output types of these two components:

# haystack-pipeline
components:
OutputAdapter:
type: haystack.components.converters.output_adapter.OutputAdapter
init_parameters:
template: "{{ last_message }}"
output_type: str
custom_filters:
unsafe: false
JsonParser:
type: deepset_cloud_custom_nodes.parsers.json_parser.JsonParser
init_parameters:
code_block_pattern: '```(?:json)?\n(.*?)\n```'
ConditionalRouter:
type: haystack.components.routers.conditional_router.ConditionalRouter
init_parameters:
routes:
- condition: '{{decision.mode == "PASSAGE"}}'
output: '{{history}}'
output_name: followup
output_type: typing.List[haystack.dataclasses.ChatMessage]
- condition: '{{decision.mode == "FRAGE" and decision.complexity in ["simple",
"medium"]}}'
output: '{{decision.query}}'
output_name: search
output_type: str
- condition: '{{decision.mode == "FRAGE" and decision.complexity not in ["simple",
"medium"]}}'
output: '{{decision.query}}'
output_name: agent
output_type: typing.List[haystack.dataclasses.ChatMessage]
- condition: '{{True}}'
output: '{{(history|last).text}}'
output_name: search_last_history
output_type: str
custom_filters: {}
unsafe: false
validate_output_type: false
optional_variables:

LLM:
type: haystack.components.generators.chat.llm.LLM
init_parameters:
chat_generator:
init_parameters:
model: gpt-5.4
type: haystack.components.generators.chat.openai_responses.OpenAIResponsesChatGenerator
system_prompt: >-
{% message role="system" %}

\nDu bist ein exzellentes Labelling-Tool.\nDu bekommst einen
Chatverlauf.\n\n**1. Label Bestimmung**\nFalls die letzte user Frage
nach Informationen aus einer Datenbank sucht, gebe \"FRAGE\" aus.\nDies
ist auch der Fall, wenn etwas erklärt werden soll oder eine Aufgabe
gestellt wird, deren Lösung den Abruf von neuen Informationen erfordert
(z.B. Vergleiche, Tabellen, Analysen erstellen).\n**WICHTIG:** Auch
reine Sachverhaltsschilderungen (z.B. juristische Fälle) ohne explizite
Frage fallen unter das Label \"FRAGE\", da sie implizit nach einer
rechtlichen Einordnung oder ähnlichen Fällen suchen.\n\nFalls die letzte
user Frage Instruktionen sind zum Arbeiten mit einer bereits im
Chatverlauf vorhandenen oder vom User explizit bereitgestellten Passage,
gebe \"PASSAGE\" aus. Dies gilt nur, wenn keine neuen Informationen aus
einer Datenbank abgerufen werden mĂĽssen.\nFalls der Chatverlauf nur eine
user Message enthält, kann nicht das Label \"PASSAGE\" ausgegeben
werden.\nBeispielfragen, welche sich auf die Passage beziehen, sind:
'schreibe davon eine zusammenfassung', 'in stichpunkten' oder
'formuliere als email um'.\n\n**2. Output fĂĽr \"PASSAGE\"**\nFĂĽr das
Label \"PASSAGE\" gibst du NICHTS zusätzlich aus.\nFormat: { \"label\":
\"PASSAGE\" }\n\n**3. Output fĂĽr \"FRAGE\"**\nFĂĽr das Label \"FRAGE\"
gibst du zusätzlich \"query\" und \"complexity\" aus.\n\n**A)
Query-Generierung:**\nDie \"query\" muss in natĂĽrlicher Sprache sein, da
sie von einer keyword und einer semantic search hybrid verarbeitet wird.
Sei daher möglichst explizit mit den Keywords.\n\n**Spezialfall
Sachverhalt:** Wenn der User-Input eine reine Sachverhaltsschilderung
(Fakten, Fallbeispiel) ohne explizite Frage ist, generiere als \"query\"
eine prägnante **Fallbeschreibung**, die die wesentlichen Fakten und
juristischen Probleme zusammenfasst (z.B. \"Fallbeschreibung: Schenkung
unter Auflage, nachträglicher Diebstahl durch Beschenkte und Haftung für
Drittschaden\"). Formuliere in diesem Fall KEINE hypothetischen
Fragen.\n\nWenn nach X auch nach Y gefragt wird, frage in der \"query\"
nur nach Y und wiederhole nicht noch einmal X.\nAbkĂĽrzungen wie
\"ArbVG\", \"BVwG\" oder \"Abs\", sowie alle Paragraphen bleiben
bestehen und dĂĽrfen in der \"query\" nicht umformuliert werden.\nWenn
die Frage keinen Kontext aus der Chat Historie benötigt, gebe sie
unbearbeitet in \"query\" aus.\n\n**B) Komplexitätsbestimmung
(Complexity Analysis):**\nBestimme die Komplexität des Retrievals
(\"complexity\") basierend auf der Schwierigkeit der Anfrage:\n-
**simple**: 1-2 Aspekte/Anspruchsgrundlagen, 1 Themengebiet, klare
Faktenabfrage oder Definition, Standard-Recherche.\n- **medium**: 2-4
Aspekte, 2-3 Themengebiete, Vergleiche zwischen zwei Entitäten, Listen,
abgrenzbare Themen.\n- **high**: 5-7 Aspekte, 3-4 Themengebiete mit
Wechselwirkungen, Synthese aus mehreren Quellen nötig, Abhängigkeiten
(Wenn X, dann Y).\n- **very_high**: ≥8 Aspekte ODER ≥3-stufige
Verschachtelungen ODER systematische WidersprĂĽche ODER sehr abstrakte
Analyseanforderungen.\n\nFormat fĂĽr FRAGE: { \"label\": \"FRAGE\",
\"query\": \"...\", \"complexity\": \"...\" }\n\n\n\n\n{{ message.text
}}\n\n\n\n\n{ \"label\": \"\n

{% endmessage %}
user_prompt: |-
{% message role="user" %}
{{ query }}
{% endmessage %}
required_variables: "*"
streaming_callback:

connections:
- sender: OutputAdapter.output
receiver: JsonParser.text
- sender: JsonParser.parsed_json
receiver: ConditionalRouter.decision
- sender: LLM.last_message
receiver: OutputAdapter.last_message

max_runs_per_component: 100

metadata: {}

inputs:
messages:
- ConditionalRouter.history
- LLM.message
query:
- LLM.query

Parameters​

Inputs​

ParameterTypeDescription
textstrText containing JSON to parse.

Outputs​

ParameterTypeDescription
parsed_jsonDict[str, Any]The parsed JSON object.

Init Parameters​

These are the parameters you can configure in Pipeline Builder:

ParameterTypeDefaultDescription
code_block_patternstr"(?:json)?\\n(.*?)\\n"Regular expression pattern to extract JSON from markdown code blocks. The pattern should include a capture group for the JSON content.

Run Method Parameters​

These are the parameters you can configure for the component's run() method. This means you can pass these parameters at query time through the API, in Playground, or when running a job. For details, see Modify Pipeline Parameters at Query Time.

ParameterTypeDescription
textstrText containing JSON to parse. Can be plain JSON or JSON wrapped in markdown code blocks.