Parsers
Goal: parse structured model or tactic output without depending on a runtime.
Prerequisites
python -m pip install -e ".[dev]"
Files Used
lllm/
parsers.py
tests/
test_parsers.py
Parse
from lllm.parsers import DefaultTagParser
parser = DefaultTagParser(
required_xml_tags=["answer"],
required_md_tags=["json"],
signal_tags=["DONE"],
)
parsed = parser.parse("<answer>Hello</answer>\n```json\n{}\n```\n<DONE>")
assert parsed["xml_tags"]["answer"] == ["Hello"]
assert parsed["signal_tags"]["DONE"] is True
Contract
Parser configuration is Pydantic-schema-compatible, so it can be serialized in runtime config or inspected by tools:
schema = DefaultTagParser.model_json_schema()
assert "required_xml_tags" in schema["properties"]
The parser fails fast with ParseError when required blocks are missing.
Repair loops, retries, or partial-output recovery should live in the tactic or
runtime adapter that owns the model call.
In A Tactic
The same parser can be attached to native prompts or used directly around Pydantic AI/plain-Python tactic outputs:
from lllm import Tactic
from lllm.parsers import DefaultTagParser
parser = DefaultTagParser(required_xml_tags=["answer"], signal_tags=["DONE"])
class ParseAnswerTactic(Tactic[str, dict[str, object]]):
name = "parse_answer"
input_type = str
output_type = dict[str, object]
def _run(self, input_value, *, context=None):
return parser.parse(input_value)
parsed = ParseAnswerTactic().run("<answer>Hello</answer><DONE>")
assert parsed["xml_tags"]["answer"] == ["Hello"]
Verify
python -m pytest tests/test_parsers.py -q
Expected output:
17 passed
Next, attach the parser to a native prompt or wrap Pydantic AI output before
returning through a Tactic.