dspy vs guidance: a pipeline compiler against a constrained generator
dspy compiles a declarative pipeline and hands it to an optimizer that rewrites prompts and demonstrations, while guidance steers one model call inside a program you already wrote. They sit at different layers, so the real question is whether you need a compiled pipeline or a constrained generation step.
At a glance
| Project | stanfordnlp/dspy | guidance-ai/guidance |
|---|---|---|
| Licence | MITPermissive: commercial use allowed | MITPermissive: commercial use allowed |
| Maintenance | Commits in the last six monthsLast push October 23, 2026 | Commits in the last six monthsLast push May 21, 2026 |
| Language | Python | Jupyter Notebook |
| GitHub stars | 38,770 | 21,806 |
| Read more | Our analysisGitHub | Our analysisGitHub |
Which one to choose
Choose dspy if you are building a classifier, a retrieval pipeline or an agent loop as code and want an optimizer to tune the prompts and demonstrations from a metric, and you can accept a Linux classifier, alpha metadata and a pinned optimizer in your dependency set.
Choose guidance if you need the output of one model call to match a regex, a fixed list of choices or a grammar, and you would rather keep the surrounding program in plain Python than move it into a compiled pipeline.
Two different layers of the same stack
Neither library is a model client, and neither is an application framework. dspy sits above the model. You write modules that describe a task, dspy turns them into a pipeline, and an optimizer rewrites the prompts and demonstrations until a metric improves. guidance sits inside a single call. Your program already exists, and you ask the model for text that has to satisfy a shape while it is being produced. That difference decides almost everything else. dspy changes how your code is written and how it is tuned. guidance changes how one part of it behaves. A team can run both, since a guidance-constrained call fits naturally inside a dspy module, but the combination only earns its keep when the shape of the output matters more than the wording of the prompt.
dspy compiles modules and lets an optimizer rewrite them
The dspy README describes the framework as programming rather than prompting language models, and expands the name as Declarative Self-improving Python. You write compositional Python code, and dspy supplies the algorithms for optimising prompts and weights, whether the target is a simple classifier, a sophisticated retrieval pipeline or an agent loop. The optimizer is the heart of it. It takes a metric and revises instructions and demonstrations until the measured behaviour of the program improves. That is a different order of work from writing a prompt by hand, because the revision loop is the product and your metric defines what good means. The README points at dspy.ai for the documentation itself and lists the papers the design comes from, among them GEPA on reflective prompt evolution. The trade-off is that you now depend on an optimizer whose behaviour you do not fully control, and our analysis of dspy notes that the repository pins the GEPA optimizer to an exact version.
guidance constrains the tokens inside a running program
guidance takes the opposite route. The model object is immutable, and the API is built from context managers: `system()`, `user()` and `assistant()` scope each piece of text, and `lm += gen(...)` appends to a copy of the model. Constraints attach at the point of generation. A regular expression can be attached to `gen()`, `select()` narrows the answer to one entry from a list you supply, and the README states that any context free grammar can be enforced so long as the backend has full support. Enforcement happens while tokens are chosen, so an illegal value is never produced at all. A `Mock` model lets you match candidate strings against a grammar and run the flow without a model call, and the `@guidance` decorator lets your own functions take part in generation. The cost of that approach is scope. guidance does not look at your metrics, and it rewrites nothing.
Getting each one running for the first time
dspy installs with a single pip line, and the README also gives the command that tracks the main branch. The first thing you will look for is the API, and it is not in the repository: the README sends readers to dspy.ai for documentation, so the shape of a module has to be learned from the hosted docs before anything runs. guidance installs with `pip install guidance`, and the README says that is enough when you already have the backend your model needs. Its backends include Transformers, llama.cpp and OpenAI, and the first script is visible in the README itself: build a model object, wrap the conversation in the role blocks, and read a named result back out. In practice dspy is the larger first step, because the concepts are new, while guidance is a smaller first step with one decision attached, namely which backend to run against.
What each one costs to run and to depend on
dspy's runtime cost is not the interesting part. The optimizer is. Every optimisation pass issues a batch of model calls against your metric, and our analysis of dspy points out that LiteLLM sits in the middle of those model calls, so one more component stands between your code and the provider. That is a reasonable trade for cross-provider reach and a poor one when you need a provider-specific feature. guidance's cost is per token, and it drops into a process you already own. The dependency picture differs on each side as well. dspy's own metadata declares alpha status, a Linux classifier and an exact pin on the GEPA optimizer, so our analysis of dspy advises reading the operating system classifier and checking that the Python range you deploy on sits inside the declared bounds. guidance's optional extras are the smaller decision: our analysis of guidance says to check which extra matches your backend, and whether that backend honours the constraint system.
Same MIT licence, different maturity signals
Both projects are MIT licensed, so neither forces a copyleft obligation or a per-seat agreement on you, and either can sit inside a commercial product. The maturity signals are not the same. The last push to dspy was on 2026-10-21, with tagged releases 3.3.0 and 3.3.1 in August 2026. The last push to guidance was on 2026-05-21, and its most recent release was 0.3.2 on 2026-03-18. dspy's version numbers and release cadence arrive alongside declared alpha status, which is a statement about the project's own expectations rather than about the quality of the code. guidance's smaller numbers and the longer gap between pushes say something similar about how fast that interface is expected to change. Neither fact is a reason to avoid a project. Both are reasons to pin a version and read the release notes before you let either one into a pipeline you cannot easily rebuild.
Which one to pick for a concrete job
Choose dspy when the hard part of your system is that the prompt is not good enough. You have a task, a way to score the output, and a pipeline you would rather not tune by hand, and you are prepared to spend model calls to make it better. That covers classifiers, retrieval pipelines and agent loops where the structure of the program matters. Choose guidance when the hard part is that the output has to be exactly a certain shape: a number, a date in a fixed format, a label from a list, a fragment of a larger grammar. Writing that as a prompt and hoping is a poor plan, and validating it afterwards is worse than enforcing it during generation. If you need both, use guidance to fix the shape inside a dspy module, and treat the optimizer as the thing that tunes wording rather than structure.
Bottom line
Start with dspy if the bottleneck is prompt quality and you have a metric to optimise against, and check that the pinned optimizer and the Linux classifier match your deployment. Choose guidance when the bottleneck is the shape of one response, and confirm your backend enforces the constraint. On an existing pipeline the smaller change that solves the real problem is usually guidance.
Sources
Was this useful?