LLM Structured Outputs Handbook

(nanonets.com)

63 points | by vitaelabitur 1 day ago

7 comments

  • FlyingLawnmower 4 minutes ago
    Very nicely written guide!

    If the authors or readers are interested in some of the more technical details of how we optimized guidance & llguidance, we wrote up a little paper about it here: https://guidance-ai.github.io/llguidance/llg-go-brrr

  • HanClinto 1 hour ago
    This is a seriously beautiful guide. I really appreciate you putting this together! I especially love the tab-through animations on the various pages, and this is one of the best explanations that I've seen. I generally feel I understand grammar-constrained generation pretty well (I've merged a handful of contributions to the llama.cpp grammar implementation), and yet I still learned some insights from your illustrations -- thank you!

    I'm also really glad that you're helping more people understand this feature, how it works, and how to use it effectively. I strongly believe that structured outputs are one of the most underrated features in LLM engines, and people should be using this feature more.

    Constrained non-determinism means that we can reliably use LLMs as part of a larger pipeline or process (such as an agent with tool-calling) and we won't have failures due to syntax errors or erroneous "Sure! Here's your output formatted as JSON with no other text or preamble" messages thrown in.

    Your LLM output might not be correct. But grammars ensure that your LLM output is at least _syntactically_ correct. It's not everything, but it's not nothing.

    And especially if we want to get away from cloud deployments and run effective local models, grammars are an incredibly valuable piece of this. For practical examples, I often think of Jart's example in her simple LLM-based spam-filter running on a Raspberry Pi [0]:

    > llamafile -m TinyLlama-1.1B-Chat-v1.0.f16.gguf \ > --grammar 'root ::= "yes" | "no"' --temp 0 -c 0 \ > --no-display-prompt --log-disable -p "<|user|> > Can you say for certain that the following email is spam? ...

    Even though it's a super-tiny piece of hardware, by including a grammar that constrains the output to only ever be "yes" or "no" (it's impossible for the system to produce a different result), then she can use a super-small model on super-limited hardware, and it is still useful. It might not correctly identify spam, but it's never going to break for syntactic reasons, which gives a great boost to the usefulness of small, local models.

    * [0]: https://justine.lol/matmul/

    • fragmede 5 minutes ago
      What does it do when the model wants to return something else, and what's better/worse about doing it in llamafile vs whatever wrapper that's calling it? How do I set retries? What if I want JSON and a range instead?
  • dfajgljsldkjag 39 minutes ago
    I agree that building agents is basically impossible if you cannot trust the model to output valid json every time. This seems like a decent collection of the current techniques we have to force deterministic structure for production systems.
  • shmolyneaux 1 hour ago
    Are there output formats that are more reliable (better adherence to the schema, easier to get parse-able output) or cheaper (fewer tokens) than JSON? YAML has its own problems and TOML isn't widely adopted, but they both seem like they would be easier to generate.

    What have folks tried?

    • marquesine 1 hour ago
      Yes, that's the purpose of TOON.

      https://github.com/toon-format/toon

      • koakuma-chan 7 minutes ago
        Is there evidence that LLMs adhere to this format better than to JSON? I doubt that.
      • prats226 27 minutes ago
        Nice, it would be good idea to develop CFG for this as well so can embed it into all these constrained decoding libraries
  • roywiggins 49 minutes ago
    > We use a lenient parser like ast.literal_eval instead of the standard json.loads(). It will handle outputs that deviate from strict JSON format. (single quotes, trailing commas, etc.)

    A nitpick: that's probably a good idea and I've used it before, but that's not really a lenient json parser, it's a Python literal parser and they happen to be close enough that it's useful.

  • tehnub 1 hour ago
    This is a nice guide. I especially like the masked decoding diagrams on this page https://nanonets.com/cookbooks/structured-llm-outputs/basic-....

    edit: Somehow that link doesn't work... It's the diagram on the "constrained method" page

    • prats226 1 hour ago
      One of the authors here, will checkout the diagram link.

      Every commercial model provider is adding structured outputs so will keep updating the guide.

  • earth2mars 43 minutes ago
    BAML