Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when writing code with the guidance library (guidance-ai) for constrained or structured LLM generation — model construction under guidance.models, the lm += gen()/select() composition, with system()/user()/assistant() chat roles, @guidance components, and lm[...] captures: emit the current Python API, not the removed handlebars-template form cheaper models default to.
.claude/skills/guidance-api-idiom/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 3 |
| gemini-3.1-pro-previewlowest | 0% | 1 |
| Model | Lift | Δ tokens | Δ turns | Cases | Verified |
|---|---|---|---|---|---|
| gemini-3.6-flashbest | +30% | +129% | 0% | 23 | 54d ago |
| gemini-3.5-flash | pending re-run | — | |||
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | — | — |
| case-12 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-19 | ✗→✓ | ▲ Improved | — | — |
Enforces the CURRENT guidance (guidance-ai) library Python API whenever you write code that uses guidance for constrained / structured generation. The pre-0.1 handlebars-template API — a triple-quoted guidance('''... {{gen 'x'}} ...''') program, guidance.llms.OpenAI(...), the global guidance.llm, {{#user}}...{{/user}} role blocks — was removed. Emit the composition API below for any request to "use guidance" / "write guidance code."
generation helpers from the package: from guidance import models, gen, select, system, user, assistant, guidance (the model classes also import directly, e.g. from guidance.models import Transformers).
guidance.models.lm = models.Transformers("microsoft/Phi-4-mini-instruct") — a local Hugging Face checkpoint by id.lm = models.LlamaCpp("/path/to/model.gguf", n_ctx=4096) — a local GGUF file.lm = models.OpenAI("gpt-4o") — a remote endpoint.Never guidance.llm = guidance.llms.OpenAI(...) and never guidance.llms.<backend>(...): the guidance.llms namespace and the module-global guidance.llm were removed.
+ / += operator on the (immutable) model object. Add plainstrings for fixed text and gen(...) / select(...) for generated spans: lm += "Question: " + q + "\nAnswer: " + gen("answer"). A model object is immutable, so lm += x rebinds lm to a new object. Do NOT pass a triple-quoted string containing {{gen ...}} / {{select ...}} to guidance(...) — that handlebars program form no longer exists.
gen() function; the capture name is the FIRST argument.gen("city", max_tokens=10, stop="\n"), gen("zip", regex=r"\d{5}"). Options are keyword arguments: max_tokens, regex, stop, stop_regex, temperature. Never {{gen 'city'}}.
select(); the options list is the FIRST positional argument.select(["GET", "POST", "PUT", "DELETE"], name="method"). Never {{select 'method' options=...}}, and never a bare gen() you hope lands inside the set.
lm["city"]. The key is thename you passed to gen / select. There is no separate compile-then-execute step, so never build a program and read program["city"] after calling it.
with system(): lm += "...", with user(): lm += "...", with assistant(): lm += gen("reply"). Never {{#system}}...{{/system}} / {{#user}}...{{/user}} / {{#assistant}}...{{/assistant}}.
@guidance decorator. The decorated function takes lm as itsfirst parameter, adds to it, and returns it; then it composes like any other span: @guidance \ def rate(lm, item): lm += f"{item}: " + select(["low", "high"], name="r"); return lm, used as lm += rate("latency") (or lm = rate(lm, "latency")). Never save a handlebars template string as the "reusable" unit.
guidance.json(...). Pass a pydantic BaseModel (or aJSON schema) via schema=: lm += guidance.json("out", schema=Address). Never hand-roll a {{gen 'json'}} block or a free gen() and hope it parses.
Model construction (BEFORE = removed handlebars/llms form → AFTER = current):
python# BEFORE import guidance guidance.llm = guidance.llms.OpenAI("gpt-4") # AFTER from guidance import models lm = models.OpenAI("gpt-4o")
Generate + capture (BEFORE → AFTER):
python# BEFORE program = guidance('''The animal is a {{gen 'animal' max_tokens=5}}''') out = program() print(out["animal"]) # AFTER from guidance import models, gen lm = models.Transformers("microsoft/Phi-4-mini-instruct") lm += "The animal is a " + gen("animal", max_tokens=5) print(lm["animal"])
Fixed choice (BEFORE → AFTER):
python# BEFORE program = guidance('''Signal: {{select 'color' options=lights}}''') # AFTER from guidance import select lm += "Signal: " + select(["red", "yellow", "green"], name="color") print(lm["color"])
Chat roles (BEFORE → AFTER):
python# BEFORE program = guidance('''{{#system}}You are a tutor.{{/system}}{{#user}}What is 6*7?{{/user}}{{#assistant}}{{gen 'a'}}{{/assistant}}''') # AFTER from guidance import system, user, assistant, gen with system(): lm += "You are a tutor." with user(): lm += "What is 6*7?" with assistant(): lm += gen("a")
Reusable component + schema JSON:
pythonfrom guidance import guidance, gen, select, json from pydantic import BaseModel @guidance def yes_no(lm, question): lm += question + " " + select(["yes", "no"], name="verdict") return lm class Book(BaseModel): title: str year: int lm += yes_no("Is the sky blue?") lm += guidance.json("book", schema=Book)
gen: gen("date", regex=r"\d{4}-\d{2}-\d{2}"). Never aremoved {{gen 'date' pattern=...}} directive.
gen("line", stop="\n") (or stop_regex=...), passed as a keyword — not apositional trailing string.
select/gen list_append=True and read the list back fromlm[name]; or capture into distinct names. Still composed with +=, never a {{#geneach}} block.
guidance.models where supported; theconstrained primitives (gen, select, guidance.json) require a backend that exposes token control (local Transformers / LlamaCpp), so prefer those for regex / select guarantees.
(lm += f"User: {name}\n"), but generated spans always come from gen/select, never string formatting.
models.Transformers("id") / models.OpenAI("gpt-4o"). DON'T guidance.llms.OpenAI(...) or set guidance.llm.lm += "text" + gen("x"). DON'T pass a {{gen}} template to guidance('''...''').gen("x", max_tokens=…, regex=…). DON'T write {{gen 'x'}}.select(["a","b"], name="x") (options first). DON'T write {{select 'x' options=...}}.lm["x"]. DON'T execute a program(...) and index it.with system()/user()/assistant():. DON'T use {{#system}}...{{/system}}.@guidance def f(lm, ...): ...; return lm. DON'T store a template string.guidance.json("x", schema=Model). DON'T free-generate and hope it parses.guidance.llm = guidance.llms.OpenAI(...) — the global model and guidance.llms were removed.guidance('''... {{gen 'x'}} ...''') and calling the returned program — the handlebars program is gone; compose with +=.{{gen 'x'}} / {{select 'x' options=...}} / {{#user}}...{{/user}} directives anywhere.select by keyword (select(name="x", options=[...])) instead of options-first select([...], name="x").program["x"] after execution instead of lm["x"] on the composed model.gen() for JSON instead of guidance.json(..., schema=Model).models.Transformers/LlamaCpp/OpenAI(...) — no guidance.llms / global guidance.llm.lm += "text" + gen(...)/select(...) — no guidance('''...{{...}}...''').gen("name", …) with the capture name first; select(["…"], name="…") options-first.lm["name"].with system()/user()/assistant():.@guidance def f(lm, …): …; return lm; schema JSON via guidance.json(..., schema=…).| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +30 percentage points is the difference between those two pass rates over the 23 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.5-flash | verified | 7/9/2026 | +54% |
Other measured skills in the registry, with their headline benchmark lift.