* docs: deep audit — fix stale config keys, missing commands, and registry drift Cross-checked ~80 high-impact docs pages (getting-started, reference, top-level user-guide, user-guide/features) against the live registries: hermes_cli/commands.py COMMAND_REGISTRY (slash commands) hermes_cli/auth.py PROVIDER_REGISTRY (providers) hermes_cli/config.py DEFAULT_CONFIG (config keys) toolsets.py TOOLSETS (toolsets) tools/registry.py get_all_tool_names() (tools) python -m hermes_cli.main <subcmd> --help (CLI args) reference/ - cli-commands.md: drop duplicate hermes fallback row + duplicate section, add stepfun/lmstudio to --provider enum, expand auth/mcp/curator subcommand lists to match --help output (status/logout/spotify, login, archive/prune/ list-archived). - slash-commands.md: add missing /sessions and /reload-skills entries + correct the cross-platform Notes line. - tools-reference.md: drop bogus '68 tools' headline, drop fictional 'browser-cdp toolset' (these tools live in 'browser' and are runtime-gated), add missing 'kanban' and 'video' toolset sections, fix MCP example to use the real mcp_<server>_<tool> prefix. - toolsets-reference.md: list browser_cdp/browser_dialog inside the 'browser' row, add missing 'kanban' and 'video' toolset rows, drop the stale '38 tools' count for hermes-cli. - profile-commands.md: add missing install/update/info subcommands, document fish completion. - environment-variables.md: dedupe GMI_API_KEY/GMI_BASE_URL rows (kept the one with the correct gmi-serving.com default). - faq.md: Anthropic/Google/OpenAI examples — direct providers exist (not just via OpenRouter), refresh the OpenAI model list. getting-started/ - installation.md: PortableGit (not MinGit) is what the Windows installer fetches; document the 32-bit MinGit fallback. - installation.md / termux.md: installer prefers .[termux-all] then falls back to .[termux]. - nix-setup.md: Python 3.12 (not 3.11), Node.js 22 (not 20); fix invalid 'nix flake update --flake' invocation. - updating.md: 'hermes backup restore --state pre-update' doesn't exist — point at the snapshot/quick-snapshot flow; correct config key 'updates.pre_update_backup' (was 'update.backup'). user-guide/ - configuration.md: api_max_retries default 3 (not 2); display.runtime_footer is the real key (not display.runtime_metadata_footer); checkpoints defaults enabled=false / max_snapshots=20 (not true / 50). - configuring-models.md: 'hermes model list' / 'hermes model set ...' don't exist — hermes model is interactive only. - tui.md: busy_indicator -> tui_status_indicator with values kaomoji|emoji|unicode|ascii (not kawaii|minimal|dots|wings|none). - security.md: SSH backend keys (TERMINAL_SSH_HOST/USER/KEY) live in .env, not config.yaml. - windows-wsl-quickstart.md: there is no 'hermes api' subcommand — the OpenAI-compatible API server runs inside hermes gateway. user-guide/features/ - computer-use.md: approvals.mode (not security.approval_level); fix broken ./browser-use.md link to ./browser.md. - fallback-providers.md: top-level fallback_providers (not model.fallback_providers); the picker is subcommand-based, not modal. - api-server.md: API_SERVER_* are env vars — write to per-profile .env, not 'hermes config set' which targets YAML. - web-search.md: drop web_crawl as a registered tool (it isn't); deep-crawl modes are exposed through web_extract. - kanban.md: failure_limit default is 2, not '~5'. - plugins.md: drop hard-coded '33 providers' count. - honcho.md: fix unclosed quote in echo HONCHO_API_KEY snippet; document that 'hermes honcho' subcommand is gated on memory.provider=honcho; reconcile subcommand list with actual --help output. - memory-providers.md: legacy 'hermes honcho setup' redirect documented. Verified via 'npm run build' — site builds cleanly; broken-link count went from 149 to 146 (no regressions, fixed a few in passing). * docs: round 2 audit fixes + regenerate skill catalogs Follow-up to the previous commit on this branch: Round 2 manual fixes: - quickstart.md: KIMI_CODING_API_KEY mentioned alongside KIMI_API_KEY; voice-mode and ACP install commands rewritten — bare 'pip install ...' doesn't work for curl-installed setups (no pip on PATH, not in repo dir); replaced with 'cd ~/.hermes/hermes-agent && uv pip install -e ".[voice]"'. ACP already ships in [all] so the curl install includes it. - cli.md / configuration.md: 'auxiliary.compression.model' shown as 'google/gemini-3-flash-preview' (the doc's own claimed default); actual default is empty (= use main model). Reworded as 'leave empty (default) or pin a cheap model'. - built-in-plugins.md: added the bundled 'kanban/dashboard' plugin row that was missing from the table. Regenerated skill catalogs: - ran website/scripts/generate-skill-docs.py to refresh all 163 per-skill pages and both reference catalogs (skills-catalog.md, optional-skills-catalog.md). This adds the entries that were genuinely missing — productivity/teams-meeting-pipeline (bundled), optional/finance/* (entire category — 7 skills: 3-statement-model, comps-analysis, dcf-model, excel-author, lbo-model, merger-model, pptx-author), creative/hyperframes, creative/kanban-video-orchestrator, devops/watchers, productivity/shop-app, research/searxng-search, apple/macos-computer-use — and rewrites every other per-skill page from the current SKILL.md. Most diffs are tiny (one line of refreshed metadata). Validation: - 'npm run build' succeeded. - Broken-link count moved 146 -> 155 — the +9 are zh-Hans translation shells that lag every newly-added skill page (pre-existing pattern). No regressions on any en/ page.
592 lines
15 KiB
Markdown
592 lines
15 KiB
Markdown
---
|
|
title: "Guidance"
|
|
sidebar_label: "Guidance"
|
|
description: "Control LLM output with regex and grammars, guarantee valid JSON/XML/code generation, enforce structured formats, and build multi-step workflows with Guidanc..."
|
|
---
|
|
|
|
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
|
|
|
# Guidance
|
|
|
|
Control LLM output with regex and grammars, guarantee valid JSON/XML/code generation, enforce structured formats, and build multi-step workflows with Guidance - Microsoft Research's constrained generation framework
|
|
|
|
## Skill metadata
|
|
|
|
| | |
|
|
|---|---|
|
|
| Source | Optional — install with `hermes skills install official/mlops/guidance` |
|
|
| Path | `optional-skills/mlops/guidance` |
|
|
| Version | `1.0.0` |
|
|
| Author | Orchestra Research |
|
|
| License | MIT |
|
|
| Dependencies | `guidance`, `transformers` |
|
|
| Platforms | linux, macos, windows |
|
|
| Tags | `Prompt Engineering`, `Guidance`, `Constrained Generation`, `Structured Output`, `JSON Validation`, `Grammar`, `Microsoft Research`, `Format Enforcement`, `Multi-Step Workflows` |
|
|
|
|
## Reference: full SKILL.md
|
|
|
|
:::info
|
|
The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active.
|
|
:::
|
|
|
|
# Guidance: Constrained LLM Generation
|
|
|
|
## When to Use This Skill
|
|
|
|
Use Guidance when you need to:
|
|
- **Control LLM output syntax** with regex or grammars
|
|
- **Guarantee valid JSON/XML/code** generation
|
|
- **Reduce latency** vs traditional prompting approaches
|
|
- **Enforce structured formats** (dates, emails, IDs, etc.)
|
|
- **Build multi-step workflows** with Pythonic control flow
|
|
- **Prevent invalid outputs** through grammatical constraints
|
|
|
|
**GitHub Stars**: 18,000+ | **From**: Microsoft Research
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# Base installation
|
|
pip install guidance
|
|
|
|
# With specific backends
|
|
pip install guidance[transformers] # Hugging Face models
|
|
pip install guidance[llama_cpp] # llama.cpp models
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Basic Example: Structured Generation
|
|
|
|
```python
|
|
from guidance import models, gen
|
|
|
|
# Load model (supports OpenAI, Transformers, llama.cpp)
|
|
lm = models.OpenAI("gpt-4")
|
|
|
|
# Generate with constraints
|
|
result = lm + "The capital of France is " + gen("capital", max_tokens=5)
|
|
|
|
print(result["capital"]) # "Paris"
|
|
```
|
|
|
|
### With Anthropic Claude
|
|
|
|
```python
|
|
from guidance import models, gen, system, user, assistant
|
|
|
|
# Configure Claude
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
# Use context managers for chat format
|
|
with system():
|
|
lm += "You are a helpful assistant."
|
|
|
|
with user():
|
|
lm += "What is the capital of France?"
|
|
|
|
with assistant():
|
|
lm += gen(max_tokens=20)
|
|
```
|
|
|
|
## Core Concepts
|
|
|
|
### 1. Context Managers
|
|
|
|
Guidance uses Pythonic context managers for chat-style interactions.
|
|
|
|
```python
|
|
from guidance import system, user, assistant, gen
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
# System message
|
|
with system():
|
|
lm += "You are a JSON generation expert."
|
|
|
|
# User message
|
|
with user():
|
|
lm += "Generate a person object with name and age."
|
|
|
|
# Assistant response
|
|
with assistant():
|
|
lm += gen("response", max_tokens=100)
|
|
|
|
print(lm["response"])
|
|
```
|
|
|
|
**Benefits:**
|
|
- Natural chat flow
|
|
- Clear role separation
|
|
- Easy to read and maintain
|
|
|
|
### 2. Constrained Generation
|
|
|
|
Guidance ensures outputs match specified patterns using regex or grammars.
|
|
|
|
#### Regex Constraints
|
|
|
|
```python
|
|
from guidance import models, gen
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
# Constrain to valid email format
|
|
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
|
|
|
|
# Constrain to date format (YYYY-MM-DD)
|
|
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}")
|
|
|
|
# Constrain to phone number
|
|
lm += "Phone: " + gen("phone", regex=r"\d{3}-\d{3}-\d{4}")
|
|
|
|
print(lm["email"]) # Guaranteed valid email
|
|
print(lm["date"]) # Guaranteed YYYY-MM-DD format
|
|
```
|
|
|
|
**How it works:**
|
|
- Regex converted to grammar at token level
|
|
- Invalid tokens filtered during generation
|
|
- Model can only produce matching outputs
|
|
|
|
#### Selection Constraints
|
|
|
|
```python
|
|
from guidance import models, gen, select
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
# Constrain to specific choices
|
|
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")
|
|
|
|
# Multiple-choice selection
|
|
lm += "Best answer: " + select(
|
|
["A) Paris", "B) London", "C) Berlin", "D) Madrid"],
|
|
name="answer"
|
|
)
|
|
|
|
print(lm["sentiment"]) # One of: positive, negative, neutral
|
|
print(lm["answer"]) # One of: A, B, C, or D
|
|
```
|
|
|
|
### 3. Token Healing
|
|
|
|
Guidance automatically "heals" token boundaries between prompt and generation.
|
|
|
|
**Problem:** Tokenization creates unnatural boundaries.
|
|
|
|
```python
|
|
# Without token healing
|
|
prompt = "The capital of France is "
|
|
# Last token: " is "
|
|
# First generated token might be " Par" (with leading space)
|
|
# Result: "The capital of France is Paris" (double space!)
|
|
```
|
|
|
|
**Solution:** Guidance backs up one token and regenerates.
|
|
|
|
```python
|
|
from guidance import models, gen
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
# Token healing enabled by default
|
|
lm += "The capital of France is " + gen("capital", max_tokens=5)
|
|
# Result: "The capital of France is Paris" (correct spacing)
|
|
```
|
|
|
|
**Benefits:**
|
|
- Natural text boundaries
|
|
- No awkward spacing issues
|
|
- Better model performance (sees natural token sequences)
|
|
|
|
### 4. Grammar-Based Generation
|
|
|
|
Define complex structures using context-free grammars.
|
|
|
|
```python
|
|
from guidance import models, gen
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
# JSON grammar (simplified)
|
|
json_grammar = """
|
|
{
|
|
"name": <gen name regex="[A-Za-z ]+" max_tokens=20>,
|
|
"age": <gen age regex="[0-9]+" max_tokens=3>,
|
|
"email": <gen email regex="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}" max_tokens=50>
|
|
}
|
|
"""
|
|
|
|
# Generate valid JSON
|
|
lm += gen("person", grammar=json_grammar)
|
|
|
|
print(lm["person"]) # Guaranteed valid JSON structure
|
|
```
|
|
|
|
**Use cases:**
|
|
- Complex structured outputs
|
|
- Nested data structures
|
|
- Programming language syntax
|
|
- Domain-specific languages
|
|
|
|
### 5. Guidance Functions
|
|
|
|
Create reusable generation patterns with the `@guidance` decorator.
|
|
|
|
```python
|
|
from guidance import guidance, gen, models
|
|
|
|
@guidance
|
|
def generate_person(lm):
|
|
"""Generate a person with name and age."""
|
|
lm += "Name: " + gen("name", max_tokens=20, stop="\n")
|
|
lm += "\nAge: " + gen("age", regex=r"[0-9]+", max_tokens=3)
|
|
return lm
|
|
|
|
# Use the function
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
lm = generate_person(lm)
|
|
|
|
print(lm["name"])
|
|
print(lm["age"])
|
|
```
|
|
|
|
**Stateful Functions:**
|
|
|
|
```python
|
|
@guidance(stateless=False)
|
|
def react_agent(lm, question, tools, max_rounds=5):
|
|
"""ReAct agent with tool use."""
|
|
lm += f"Question: {question}\n\n"
|
|
|
|
for i in range(max_rounds):
|
|
# Thought
|
|
lm += f"Thought {i+1}: " + gen("thought", stop="\n")
|
|
|
|
# Action
|
|
lm += "\nAction: " + select(list(tools.keys()), name="action")
|
|
|
|
# Execute tool
|
|
tool_result = tools[lm["action"]]()
|
|
lm += f"\nObservation: {tool_result}\n\n"
|
|
|
|
# Check if done
|
|
lm += "Done? " + select(["Yes", "No"], name="done")
|
|
if lm["done"] == "Yes":
|
|
break
|
|
|
|
# Final answer
|
|
lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
|
|
return lm
|
|
```
|
|
|
|
## Backend Configuration
|
|
|
|
### Anthropic Claude
|
|
|
|
```python
|
|
from guidance import models
|
|
|
|
lm = models.Anthropic(
|
|
model="claude-sonnet-4-5-20250929",
|
|
api_key="your-api-key" # Or set ANTHROPIC_API_KEY env var
|
|
)
|
|
```
|
|
|
|
### OpenAI
|
|
|
|
```python
|
|
lm = models.OpenAI(
|
|
model="gpt-4o-mini",
|
|
api_key="your-api-key" # Or set OPENAI_API_KEY env var
|
|
)
|
|
```
|
|
|
|
### Local Models (Transformers)
|
|
|
|
```python
|
|
from guidance.models import Transformers
|
|
|
|
lm = Transformers(
|
|
"microsoft/Phi-4-mini-instruct",
|
|
device="cuda" # Or "cpu"
|
|
)
|
|
```
|
|
|
|
### Local Models (llama.cpp)
|
|
|
|
```python
|
|
from guidance.models import LlamaCpp
|
|
|
|
lm = LlamaCpp(
|
|
model_path="/path/to/model.gguf",
|
|
n_ctx=4096,
|
|
n_gpu_layers=35
|
|
)
|
|
```
|
|
|
|
## Common Patterns
|
|
|
|
### Pattern 1: JSON Generation
|
|
|
|
```python
|
|
from guidance import models, gen, system, user, assistant
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
with system():
|
|
lm += "You generate valid JSON."
|
|
|
|
with user():
|
|
lm += "Generate a user profile with name, age, and email."
|
|
|
|
with assistant():
|
|
lm += """{
|
|
"name": """ + gen("name", regex=r'"[A-Za-z ]+"', max_tokens=30) + """,
|
|
"age": """ + gen("age", regex=r"[0-9]+", max_tokens=3) + """,
|
|
"email": """ + gen("email", regex=r'"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"', max_tokens=50) + """
|
|
}"""
|
|
|
|
print(lm) # Valid JSON guaranteed
|
|
```
|
|
|
|
### Pattern 2: Classification
|
|
|
|
```python
|
|
from guidance import models, gen, select
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
|
|
text = "This product is amazing! I love it."
|
|
|
|
lm += f"Text: {text}\n"
|
|
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")
|
|
lm += "\nConfidence: " + gen("confidence", regex=r"[0-9]+", max_tokens=3) + "%"
|
|
|
|
print(f"Sentiment: {lm['sentiment']}")
|
|
print(f"Confidence: {lm['confidence']}%")
|
|
```
|
|
|
|
### Pattern 3: Multi-Step Reasoning
|
|
|
|
```python
|
|
from guidance import models, gen, guidance
|
|
|
|
@guidance
|
|
def chain_of_thought(lm, question):
|
|
"""Generate answer with step-by-step reasoning."""
|
|
lm += f"Question: {question}\n\n"
|
|
|
|
# Generate multiple reasoning steps
|
|
for i in range(3):
|
|
lm += f"Step {i+1}: " + gen(f"step_{i+1}", stop="\n", max_tokens=100) + "\n"
|
|
|
|
# Final answer
|
|
lm += "\nTherefore, the answer is: " + gen("answer", max_tokens=50)
|
|
|
|
return lm
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
lm = chain_of_thought(lm, "What is 15% of 200?")
|
|
|
|
print(lm["answer"])
|
|
```
|
|
|
|
### Pattern 4: ReAct Agent
|
|
|
|
```python
|
|
from guidance import models, gen, select, guidance
|
|
|
|
@guidance(stateless=False)
|
|
def react_agent(lm, question):
|
|
"""ReAct agent with tool use."""
|
|
tools = {
|
|
"calculator": lambda expr: eval(expr),
|
|
"search": lambda query: f"Search results for: {query}",
|
|
}
|
|
|
|
lm += f"Question: {question}\n\n"
|
|
|
|
for round in range(5):
|
|
# Thought
|
|
lm += f"Thought: " + gen("thought", stop="\n") + "\n"
|
|
|
|
# Action selection
|
|
lm += "Action: " + select(["calculator", "search", "answer"], name="action")
|
|
|
|
if lm["action"] == "answer":
|
|
lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
|
|
break
|
|
|
|
# Action input
|
|
lm += "\nAction Input: " + gen("action_input", stop="\n") + "\n"
|
|
|
|
# Execute tool
|
|
if lm["action"] in tools:
|
|
result = tools[lm["action"]](lm["action_input"])
|
|
lm += f"Observation: {result}\n\n"
|
|
|
|
return lm
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
lm = react_agent(lm, "What is 25 * 4 + 10?")
|
|
print(lm["answer"])
|
|
```
|
|
|
|
### Pattern 5: Data Extraction
|
|
|
|
```python
|
|
from guidance import models, gen, guidance
|
|
|
|
@guidance
|
|
def extract_entities(lm, text):
|
|
"""Extract structured entities from text."""
|
|
lm += f"Text: {text}\n\n"
|
|
|
|
# Extract person
|
|
lm += "Person: " + gen("person", stop="\n", max_tokens=30) + "\n"
|
|
|
|
# Extract organization
|
|
lm += "Organization: " + gen("organization", stop="\n", max_tokens=30) + "\n"
|
|
|
|
# Extract date
|
|
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}", max_tokens=10) + "\n"
|
|
|
|
# Extract location
|
|
lm += "Location: " + gen("location", stop="\n", max_tokens=30) + "\n"
|
|
|
|
return lm
|
|
|
|
text = "Tim Cook announced at Apple Park on 2024-09-15 in Cupertino."
|
|
|
|
lm = models.Anthropic("claude-sonnet-4-5-20250929")
|
|
lm = extract_entities(lm, text)
|
|
|
|
print(f"Person: {lm['person']}")
|
|
print(f"Organization: {lm['organization']}")
|
|
print(f"Date: {lm['date']}")
|
|
print(f"Location: {lm['location']}")
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Use Regex for Format Validation
|
|
|
|
```python
|
|
# ✅ Good: Regex ensures valid format
|
|
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
|
|
|
|
# ❌ Bad: Free generation may produce invalid emails
|
|
lm += "Email: " + gen("email", max_tokens=50)
|
|
```
|
|
|
|
### 2. Use select() for Fixed Categories
|
|
|
|
```python
|
|
# ✅ Good: Guaranteed valid category
|
|
lm += "Status: " + select(["pending", "approved", "rejected"], name="status")
|
|
|
|
# ❌ Bad: May generate typos or invalid values
|
|
lm += "Status: " + gen("status", max_tokens=20)
|
|
```
|
|
|
|
### 3. Leverage Token Healing
|
|
|
|
```python
|
|
# Token healing is enabled by default
|
|
# No special action needed - just concatenate naturally
|
|
lm += "The capital is " + gen("capital") # Automatic healing
|
|
```
|
|
|
|
### 4. Use stop Sequences
|
|
|
|
```python
|
|
# ✅ Good: Stop at newline for single-line outputs
|
|
lm += "Name: " + gen("name", stop="\n")
|
|
|
|
# ❌ Bad: May generate multiple lines
|
|
lm += "Name: " + gen("name", max_tokens=50)
|
|
```
|
|
|
|
### 5. Create Reusable Functions
|
|
|
|
```python
|
|
# ✅ Good: Reusable pattern
|
|
@guidance
|
|
def generate_person(lm):
|
|
lm += "Name: " + gen("name", stop="\n")
|
|
lm += "\nAge: " + gen("age", regex=r"[0-9]+")
|
|
return lm
|
|
|
|
# Use multiple times
|
|
lm = generate_person(lm)
|
|
lm += "\n\n"
|
|
lm = generate_person(lm)
|
|
```
|
|
|
|
### 6. Balance Constraints
|
|
|
|
```python
|
|
# ✅ Good: Reasonable constraints
|
|
lm += gen("name", regex=r"[A-Za-z ]+", max_tokens=30)
|
|
|
|
# ❌ Too strict: May fail or be very slow
|
|
lm += gen("name", regex=r"^(John|Jane)$", max_tokens=10)
|
|
```
|
|
|
|
## Comparison to Alternatives
|
|
|
|
| Feature | Guidance | Instructor | Outlines | LMQL |
|
|
|---------|----------|------------|----------|------|
|
|
| Regex Constraints | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes |
|
|
| Grammar Support | ✅ CFG | ❌ No | ✅ CFG | ✅ CFG |
|
|
| Pydantic Validation | ❌ No | ✅ Yes | ✅ Yes | ❌ No |
|
|
| Token Healing | ✅ Yes | ❌ No | ✅ Yes | ❌ No |
|
|
| Local Models | ✅ Yes | ⚠️ Limited | ✅ Yes | ✅ Yes |
|
|
| API Models | ✅ Yes | ✅ Yes | ⚠️ Limited | ✅ Yes |
|
|
| Pythonic Syntax | ✅ Yes | ✅ Yes | ✅ Yes | ❌ SQL-like |
|
|
| Learning Curve | Low | Low | Medium | High |
|
|
|
|
**When to choose Guidance:**
|
|
- Need regex/grammar constraints
|
|
- Want token healing
|
|
- Building complex workflows with control flow
|
|
- Using local models (Transformers, llama.cpp)
|
|
- Prefer Pythonic syntax
|
|
|
|
**When to choose alternatives:**
|
|
- Instructor: Need Pydantic validation with automatic retrying
|
|
- Outlines: Need JSON schema validation
|
|
- LMQL: Prefer declarative query syntax
|
|
|
|
## Performance Characteristics
|
|
|
|
**Latency Reduction:**
|
|
- 30-50% faster than traditional prompting for constrained outputs
|
|
- Token healing reduces unnecessary regeneration
|
|
- Grammar constraints prevent invalid token generation
|
|
|
|
**Memory Usage:**
|
|
- Minimal overhead vs unconstrained generation
|
|
- Grammar compilation cached after first use
|
|
- Efficient token filtering at inference time
|
|
|
|
**Token Efficiency:**
|
|
- Prevents wasted tokens on invalid outputs
|
|
- No need for retry loops
|
|
- Direct path to valid outputs
|
|
|
|
## Resources
|
|
|
|
- **Documentation**: https://guidance.readthedocs.io
|
|
- **GitHub**: https://github.com/guidance-ai/guidance (18k+ stars)
|
|
- **Notebooks**: https://github.com/guidance-ai/guidance/tree/main/notebooks
|
|
- **Discord**: Community support available
|
|
|
|
## See Also
|
|
|
|
- `references/constraints.md` - Comprehensive regex and grammar patterns
|
|
- `references/backends.md` - Backend-specific configuration
|
|
- `references/examples.md` - Production-ready examples
|