Show HN: MonkeyPatch – Cheap, fast and predictable LLM functions in Python (github.com)
For example, if you need to classify PDFs, extract product feedback from tweets, or auto-generate synthetic data, you can spin up an LLM-powered Python function in <5 minutes to power your application. Unlike existing LLM clients, these functions generate well-typed outputs with guardrails to mitigate unexpected behavior.
After about 200-300 calls, these functions will begin to get cheaper and faster. We've seen 8-10x reduction in cost and latency in some use-cases! This happens via progressive knowledge distillation - MonkeyPatch incrementally fine-tunes smaller, cheaper models in the background, tests them against the constraints defined by the developer, and retains the smallest model that meets accuracy requirements, which typically has significantly lower costs and latency.
As an LLM researcher, I kept getting asked by startups and friends to build specific LLM features that they could embed into their applications. I realized that most developers have to either 1) use existing low-level LLM clients (GPT4/Claude), which can be unreliable, untyped, and pricey, or 2) pore through LangChain documentation for days to build something.
We built MonkeyPatch to make it easy for developers to inject LLM-powered functions into their code and create tests to ensure they behave as intended. Our goal is to help developers easily build apps and functions without worrying about reliability, cost, and latency, while following best software engineering practices.
We're only available in Python currently but actively working on a Typescript version. The repo has all the instructions you need to get up and running in a few minutes.
The world of LLMs is changing by the day and so we're not 100% sure how MonkeyPatch will evolve. For now, I'm just excited to share what we've been working on with the HN community. Would love to know what you guys think!
Open-source repo: https://github.com/monkeypatch/monkeypatch.py
Sample use-cases: https://github.com/monkeypatch/monkeypatch.py/tree/master/ex...
Benchmarks: https://github.com/monkeypatch/monkeypatch.py#scaling-and-fi...
73 comments
[ 4.2 ms ] story [ 149 ms ] threadWe will keep you posted on when it'll be ready for trying out!
Please note: it requires the use of ttypescript or ts-patch, as Typescript transformers aren’t supported by default!
The magic functions library uses a transformer to take the TypeScript types and port them to JSON schema, such that they're available during runtime. This JSON schema is then used to validate that the response from the LLM matches the expected type signature of the function (and err if it doesn't).
Because TypeScript doesn't support 3rd party "transformers" by default, you're forced to hack around it (via ttypescript or ts-patch). This is especially problematic when TypeScript has a major version change, as the workarounds need to be modified accordingly; this often takes significant time.
Here's the long-lived Github issue: https://github.com/microsoft/TypeScript/issues/14419
And here's the newest proposal to add official support: https://github.com/microsoft/TypeScript/issues/54276
MonkeyPatch ensures reliability through what we call ‘test-driven alignment’, in which the tests that reference the patched functions are guaranteed to pass. The more align ‘tests’ you create, the more rigorous a contract that the functions have to fulfil.
The other way to increase consistency is using more constrained type annotations (i.e using pydantic field annotations), which is a similar concept to MarvinAI and Magentic.
However, there are a couple of big additions to Marvin as well, namely: Test Driven Alignment - by using ‘assert’ statements that declare the behavior of a patched function, we create a contract that makes invocations much more predictable, which makes it possible to use these functions in production settings.Automatic distillation - a combination of the function contract defined in function type signature and the alignment tests means we can automatically swap out bigger models for smaller ones. This saves up to 80% of the latency, and 90% of the cost of running these functions (check the benchmarks) Check out the readme, as there is more detail on these points there!
It's not to say this isn't a fucking great idea (because it is!). But you know, just don't piss in the community well.
Further, PostgreSQL means one and only one thing. But Monkey Patch means 2 now, apparently!
For reference: Here's the google ngram viewer link for "monkey patch" from 2000 to 2019.
https://books.google.com/ngrams/graph?content=monkey+patch&y...
Why not name it something like Gorillapatch? Gorillas are stronger than monkeys as a slogan or whatever.
The core issue is how am I supposed to talk about regular monkeypatching and your library in the same sentence.
MonkeySeeDo —> it sees what you’re doing and does it better
CutMonkey —> it’s a monkey patch that’s cut weight to lean fighting trim
TypeMonkey —> it uses types to intelligently monkey patch your code
MonkeyZipper —> monkey patches that compresses your code
MonkeyModels —> monkey patches your models
Learning Monkey —> learns how to improve your Large Models
Branching out from there…
SimianStudy —> it’s a monkey patch that learns
PyStill —> it distills your Python functions
AutoSqueeze —> automatically squeezes your AI code into efficient implications
Maybe it 'counts', I'm not meaning to be picky about the term, my point is more like even if this works by monkeypatching, I wouldn't personally use the term for the product which does something else by those means, if that makes sense? MonkeyLLM or MonkAIpatch or something, sure.
The other comment with a 'list comprehension' example puts it well I think.
(Seeing as you asked for name suggestions elsewhere, I think I prefer the 'stub' theme: Stubby, StubAI, Stubmonkey if you like monkeys/wanted an easier logo, something like that.)
Right now any ‘plug-in’ model needs to conform to the OpenAI API.
(P.S Carthago delenda est)
Monkeys have nothing to do with your project and were a meme over a decade ago, which makes your brand-new project look dated.
Apes are associated with being heavyweight and freakishly strong and have been long-associated with racial slurs in America. You're only ever one degree removed from coming out with "chimpout.py" or "statutoryape.py" or something else that'll get you cancelled for unintended racism.
Your tool seems like it's meant to be reliable, used for work, and possibly elegant in its code. Consider the name of a work animal for their efficiency or birds for lightweight, graceful maneuverability.
A new name is definitely in order. I will think about it over the weekend.
Thanks for the feedback, I appreciate it.
https://github.com/monkeypatch/monkeypatch.py/blob/master/sr...
Finally, other persistence layers like S3 and Redis, to support running on execution targets (like AWS Lambda and CloudFlare workers) that don’t have persistent storage.
I think it could be really interesting to support Vercel more tightly too. We currently support Vercel with Python, but I think Typescript + Redis would really enable serverless AI functions - which is where I think this project should go!
I would quite like a short and distinctive name!
Other suggestions, like PyMonkeyPatch, leave the reader to guess what is being monkey patched.
I think more details of where the data goes and when it goes from few-shot to fine-tune will be helpful.
1) The data for finetuning currently is saved on disk for low latency reading and writing. Both test statements and datapoints from the function execution are saved to the dataset. We also are aware that saving to disk is not the best option and limits many use-cases so we're currently working on creating persistence layers to allow communication with S3 / Redis / Cloudflare as the external data storage.
2) Currently starting the fine-tuning job happens after the dataset has at least 200 datapoints from GPT-4 executions and align statements. Once the finetuning is completed, the execution model for the function is automatically switched to the finetuned GPT 3.5 turbo model. Whenever the finetuned model breaks the constraints, the teacher (GPT4) is called upon to fix the datapoint and this datapoint will be saved back to the dataset for future iterative finetuning and improvements. We are also working on adding in ways for the user to include a "test-set" which could be used to evaluate if the finetuned model achieves the required performance before switching it as the primary executor of the function
Hope this makes it more clear, if you have any additional questions, let me know!