DEV Community

Mukunda Rao Katta
Mukunda Rao Katta

Posted on

My Hermes agent kept returning JSON in a markdown code block. I kept writing the same regex. Then I stopped.

Hermes Agent Challenge Submission: Build With Hermes Agent

This is a submission for the Hermes Agent Challenge.

My Hermes research agent returned structured data in five different formats depending on which step of the pipeline it was in. The planner returned a numbered list of sub-tasks. The executor returned JSON in a code fence. The summarizer returned key-value pairs. Each format required its own parsing code. Most of it was the same regex written differently each time.

llm-response-parser is that regex, written once and tested.

Extract JSON from anywhere in the response

from llm_response_parser import extract_json

# Model returns JSON in a code fence
text = """
Here's the result:

Enter fullscreen mode Exit fullscreen mode


json
{"status": "done", "items": ["a", "b", "c"]}

"""

result = extract_json(text)
print(result.value)  # {"status": "done", "items": ["a", "b", "c"]}
print(result.ok)     # True
Enter fullscreen mode Exit fullscreen mode


markdown

Works on:

  • json ... fenced code blocks
  • ... unfenced code blocks
  • Inline code with JSON
  • Bare JSON objects embedded in prose

Extract a bulleted or numbered list

from llm_response_parser import extract_list

text = """
Here are the sub-tasks:

1. Search for recent papers
2. Filter by publication date
3. Extract key findings
4. Summarize results
"""

result = extract_list(text)
print(result.value)
# ["Search for recent papers", "Filter by publication date",
#  "Extract key findings", "Summarize results"]
Enter fullscreen mode Exit fullscreen mode

Handles 1. item, 1) item, - item, * item, • item.

Extract key-value pairs

from llm_response_parser import extract_key_value

text = """
Analysis:
Status: Complete
Confidence: High
Sources: 12
Cost: $0.08
"""

result = extract_key_value(text)
print(result.value)
# {"Status": "Complete", "Confidence": "High", "Sources": "12", "Cost": "$0.08"}
Enter fullscreen mode Exit fullscreen mode

Extract markdown sections

from llm_response_parser import extract_sections

text = """
## Summary
The research shows three main findings.

## Recommendations
Based on the above, we recommend...

## References
1. Smith et al. (2023)
"""

result = extract_sections(text)
for section in result.value:
    print(f"[{section.title}]\n{section.content[:50]}\n")
Enter fullscreen mode Exit fullscreen mode

Extract first paragraph

from llm_response_parser import extract_first_paragraph

text = """
<thinking>reasoning</thinking>

Based on my analysis, the main finding is...

Additional context follows.
"""

result = extract_first_paragraph(text)
print(result.value)  # "Based on my analysis, the main finding is..."
Enter fullscreen mode Exit fullscreen mode

Strict mode for required fields

result = extract_json(text, strict=True)       # raises ParseError if no JSON found
result = extract_list(text, strict=True, min_items=3)  # raises if < 3 items
result = extract_key_value(text, strict=True, required=["Status", "Cost"])
Enter fullscreen mode Exit fullscreen mode

The ParseResult

Every function returns a ParseResult:

@dataclass
class ParseResult:
    value: Any          # the extracted data
    raw: str | None     # the matched portion of the input
    ok: bool            # True if parsing succeeded
Enter fullscreen mode Exit fullscreen mode

No exceptions in non-strict mode — check result.ok first.

Zero dependencies

Standard library only: json, re, dataclasses. No third-party packages.

pip install llm-response-parser
Enter fullscreen mode Exit fullscreen mode

Repo: https://github.com/MukundaKatta/llm-response-parser

Top comments (0)