Show HN: GPT-JSON – Structured and typehinted GPT responses in Python (github.com)
Hey HN, I've been using GPT a lot lately in some side projects around data generation and benchmarking. During the course of prompt tuning I ended up with a pretty complicated request: the value that I was looking for, an explanation, a criticism, etc. JSON was the most natural output format for this but results would often be broken, have wrong types, or contain missing fields.
There's been some positive movement in this space, like with jsonformer (https://github.com/1rgs/jsonformer) the other day. But nothing that was plug and play with GPT.
This library consolidates the separate logic that I built across 5 different projects. It lets you prompt the model for how it should return fields, inject variable prompts, handle common formatting errors, then cast to pydantic when you're done for typehinting and validation in your IDE. If you're able to play around with it, let me know what you think.
74 comments
[ 0.34 ms ] story [ 143 ms ] threadWhat we've found useful in practice in dealing with similar problems:
- Use json5 instead of json when parsing. It allows trailing commas.
- Don't let it respond in true/false. Instead, ask it for a short sentence explaining whether it is true or false. Afterwards, use a small embedding model such as sbert to extract true/false from the sentence. We've found that GPT is able to reason better in this case, and it is much more robust.
- For numerical scores, do a similar thing by asking GPT for a description, then with the small embedding model write a few examples matching your score scale, and for each response use the score of the best matched example. If you let GPT give you scores directly without explanation, 20% of the time it will give you nonsense.
Have you tried just getting it to do both? It reasons far better given some space to think, so I often have it explain things first then give the answer. You're effectively then using gpt for the extraction too.
This hugely improved the class hierarchies it was creating for me, significantly improving the reuse of classes and using better classes for fields too.
The tips on booleans and numerics are interesting! Will keep them in mind if I ever need to do that. I've definitely experienced a few quirks like that (E.g. ChatGPT 'helpfully' responding with "Here's your JSON" instead of just giving me JSON).
https://github.com/jiggy-ai/pydantic-chatcompletion/blob/mas...
What is the failure rate?
And in fact it is only one line, not 40:
Someone had to come along and spoil the fun.
Next it'll be ChatGPT/XML.
However I've found it to be generally unreliable and adds a lot of text to each call.
I suspect this can be improved by: - Only writing the parts of the spec which are needed, rather than the full JSON schema spec - Including relevant examples rather than arbitrary JSON schema examples
It takes the expected return type of a function, translates it into a JSON Schema, queries OpenAI, validates the response, and then magically returns the response as typed output.
[0]https://github.com/jumploops/magic
"Yes, integrating the CUE language with GPT-JSON can potentially lead to improvements in its capability. CUE, short for Configuration, Unification, and Environment, is an open-source data constraint language designed to simplify the definition, generation, and validation of data in structured formats, like JSON, YAML, and others.
Integrating CUE with GPT-JSON can bring several benefits:
1) Validation: By using CUE, you can define schemas for the input and output JSON, which helps in validating the data structure and ensuring it adheres to the expected format. This can help reduce errors and improve the quality of the interaction with the GPT model.
2) Simplification: CUE can help simplify the process of defining and generating JSON inputs and outputs for GPT-JSON. By providing a more concise and expressive syntax, CUE can make it easier to craft structured inputs and outputs, which can be especially helpful when working with complex data structures.
3) Interoperability: Integrating CUE can improve the interoperability between GPT-JSON and other systems or applications. With CUE's ability to work with multiple data formats (such as JSON, YAML, or HCL), it becomes easier to integrate GPT-JSON with various tools and platforms.
To integrate CUE with GPT-JSON, you would need to follow these general steps:
1) Define CUE schemas for the input and output JSON structures used by GPT-JSON.
2) Use the CUE language to validate and generate input JSON for GPT-JSON.
3) Process the output JSON generated by GPT-JSON using CUE to ensure it adheres to the defined schema and transform it as needed.
Integrating CUE with GPT-JSON can improve the overall robustness and ease of use of the library, making it more accessible and useful for a wider range of applications."
Also, this: https://bitfieldconsulting.com/golang/cuelang-exciting
It integrates very nicely with go and can convert between go structs into cue structs and vice versa.
One thing we have seen is that you need to adjust your prompts when OpenAI updates their model. Given they only support their dated models for so long, it seems increasingly difficult to make the case to build on top of LLMs you cannot control the life cycle for.
1. Is cue's validation a material improvement from something like pydantic or zod, which defines schema as code versus in .cue files? I see their docs argue that this can allow for client-side validation and lighter weight schema files which doesn't seem to totally address the library side of things.
2. Have you used the scripting layer before and do you find it useful in practice? I'm struggling a bit to see how I or GPT would use this in my day-to-day.
Despite what GPT said above, its Configure, Unify, Execute. The Execute aspect is powerful but you have to be ok with functional programming and immutability.
Pairs up really nicely with Go.
The important part is that the way messages types are defined is very heavy, and you can get them to be lighter without sacrificing type safety.
I've had luck doing chain-of-thought prompting in the JSON payload as you've described, too. Cheers, really validating to see someone taking a similar approach.
Why do you think they will be obsolete in 6 weeks?
> Generate some TOML for me, surround the output with a pair of triple equal signs (===).
I see a ton of code in this project, and I don't know what most of it does. As far as GPT troubles with JSON, I'll add a couple: sometimes it likes to throw comments in there as if it was JS. And sometimes it'll triple-quote the JSON string as if it was Python.
My approach to solve these problems was via prompt engineering - using the system message part of the API call. Asking it to "return valid json, do not wrap it in text, do not preface it with text, do not include follow-up explanations, make sure it's valid json, do not include comments" - seems to work 99% of the time. For the remainder, a try-and-catch block with some fallback code that "extracts" json (via dumb REs) from whatever text was returned. Hasn't failed yet.
It's fascinating to watch the new paradigm arrive, and people using old habits to deal with it. This entire project is kind of pointless, you can just ask GPT to return the right kind of thing.
Why do we need a library for this?
Also note that the output still depends on a random sampling of the next token according to the distribution that the net gives you - so there is a lot of genuine randomness in the model's behaviour. And because each sampled token influences the rest of the response, this randomness will become stronger the longer the response is.
So if you already know you're only interested in a particular subset of tokens, it makes sense to me to clamp the distribution to only those tokens and keep the model from getting onto the "wrong path" in the first place.
Also, pragmatically, if you can get the model to restrict itself to JSON without telling it in the prompt, you're saving that part if the context window for better uses.
To answer "why not both?" -- bottom line, the effort involved. I don't want to deal with yet another library, the bugs in it, and the inevitable -changes-. GPT's capacity for bridging the gap between structured and human languages is an enormous boon. It bridges a gap so large, we most of the time can't span it with our imaginations. I don't need to write code to tell GPT what to do, I can direct it in plain english.
I'm not worried about the size of the context window the same way we're not worried about memory or disk space - there will be more.
JSON is admittedly way easier to work with up front, but markdown seems to be a more scaleable choice.
Of course, this is all very much an opinion and highly anecdotal at the moment.
"Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.
{
} "https://github.com/knowsuchagency/struct-gpt
I tried to make the API as intuitive as possible and added the ability to provide examples to improve the reliability and quality of the LLM's output.