[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71AH9JAGH2Q12FVT2KJP9YF":3,"skill-same:01M71AH9JAGH2Q12FVT2KJP9YF":96},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":62,"commitSha":63,"skillDirectory":64,"forksCount":14,"repositoryHtmlUrl":65,"repositoryHomepageUrl":6,"ownerHtmlUrl":66,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":67,"install":68,"resources":81},"01M71AH9JAGH2Q12FVT2KJP9YF","guidance",null,"Control LLM output with regex and grammars, guarantee valid JSON\u002FXML\u002Fcode generation, enforce structured formats, and build multi-step workflows with Guidance - Microsoft Research's constrained generation framework","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fhermes\u002Fguidance\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[5,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"enforce","orchestra","formats","Multi-Step Workflows","Format Enforcement","Microsoft Research","JSON Validation","Constrained Generation","structured output","regex","valid","enforcement","prompt","grammar","Transformers","Code Generation","framework","code","workflows","2026-11-10 10:12:30",false,"---\nname: guidance\ndescription: Control LLM output with regex and grammars, guarantee valid JSON\u002FXML\u002Fcode generation, enforce structured formats, and build multi-step workflows with Guidance - Microsoft Research's constrained generation framework\nversion: 1.0.0\nauthor: Orchestra Research\nlicense: MIT\ndependencies: [guidance, transformers]\nmetadata:\n  hermes:\n    tags: [Prompt Engineering, Guidance, Constrained Generation, Structured Output, JSON Validation, Grammar, Microsoft Research, Format Enforcement, Multi-Step Workflows]\n\n---\n\n# Guidance: Constrained LLM Generation\n\n## When to Use This Skill\n\nUse Guidance when you need to:\n- **Control LLM output syntax** with regex or grammars\n- **Guarantee valid JSON\u002FXML\u002Fcode** generation\n- **Reduce latency** vs traditional prompting approaches\n- **Enforce structured formats** (dates, emails, IDs, etc.)\n- **Build multi-step workflows** with Pythonic control flow\n- **Prevent invalid outputs** through grammatical constraints\n\n**GitHub Stars**: 18,000+ | **From**: Microsoft Research\n\n## Installation\n\n```bash\n# Base installation\npip install guidance\n\n# With specific backends\npip install guidance[transformers]  # Hugging Face models\npip install guidance[llama_cpp]     # llama.cpp models\n```\n\n## Quick Start\n\n### Basic Example: Structured Generation\n\n```python\nfrom guidance import models, gen\n\n# Load model (supports OpenAI, Transformers, llama.cpp)\nlm = models.OpenAI(\"gpt-4\")\n\n# Generate with constraints\nresult = lm + \"The capital of France is \" + gen(\"capital\", max_tokens=5)\n\nprint(result[\"capital\"])  # \"Paris\"\n```\n\n### With Anthropic Claude\n\n```python\nfrom guidance import models, gen, system, user, assistant\n\n# Configure Claude\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Use context managers for chat format\nwith system():\n    lm += \"You are a helpful assistant.\"\n\nwith user():\n    lm += \"What is the capital of France?\"\n\nwith assistant():\n    lm += gen(max_tokens=20)\n```\n\n## Core Concepts\n\n### 1. Context Managers\n\nGuidance uses Pythonic context managers for chat-style interactions.\n\n```python\nfrom guidance import system, user, assistant, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# System message\nwith system():\n    lm += \"You are a JSON generation expert.\"\n\n# User message\nwith user():\n    lm += \"Generate a person object with name and age.\"\n\n# Assistant response\nwith assistant():\n    lm += gen(\"response\", max_tokens=100)\n\nprint(lm[\"response\"])\n```\n\n**Benefits:**\n- Natural chat flow\n- Clear role separation\n- Easy to read and maintain\n\n### 2. Constrained Generation\n\nGuidance ensures outputs match specified patterns using regex or grammars.\n\n#### Regex Constraints\n\n```python\nfrom guidance import models, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Constrain to valid email format\nlm += \"Email: \" + gen(\"email\", regex=r\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\")\n\n# Constrain to date format (YYYY-MM-DD)\nlm += \"Date: \" + gen(\"date\", regex=r\"\\d{4}-\\d{2}-\\d{2}\")\n\n# Constrain to phone number\nlm += \"Phone: \" + gen(\"phone\", regex=r\"\\d{3}-\\d{3}-\\d{4}\")\n\nprint(lm[\"email\"])  # Guaranteed valid email\nprint(lm[\"date\"])   # Guaranteed YYYY-MM-DD format\n```\n\n**How it works:**\n- Regex converted to grammar at token level\n- Invalid tokens filtered during generation\n- Model can only produce matching outputs\n\n#### Selection Constraints\n\n```python\nfrom guidance import models, gen, select\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Constrain to specific choices\nlm += \"Sentiment: \" + select([\"positive\", \"negative\", \"neutral\"], name=\"sentiment\")\n\n# Multiple-choice selection\nlm += \"Best answer: \" + select(\n    [\"A) Paris\", \"B) London\", \"C) Berlin\", \"D) Madrid\"],\n    name=\"answer\"\n)\n\nprint(lm[\"sentiment\"])  # One of: positive, negative, neutral\nprint(lm[\"answer\"])     # One of: A, B, C, or D\n```\n\n### 3. Token Healing\n\nGuidance automatically \"heals\" token boundaries between prompt and generation.\n\n**Problem:** Tokenization creates unnatural boundaries.\n\n```python\n# Without token healing\nprompt = \"The capital of France is \"\n# Last token: \" is \"\n# First generated token might be \" Par\" (with leading space)\n# Result: \"The capital of France is  Paris\" (double space!)\n```\n\n**Solution:** Guidance backs up one token and regenerates.\n\n```python\nfrom guidance import models, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Token healing enabled by default\nlm += \"The capital of France is \" + gen(\"capital\", max_tokens=5)\n# Result: \"The capital of France is Paris\" (correct spacing)\n```\n\n**Benefits:**\n- Natural text boundaries\n- No awkward spacing issues\n- Better model performance (sees natural token sequences)\n\n### 4. Grammar-Based Generation\n\nDefine complex structures using context-free grammars.\n\n```python\nfrom guidance import models, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# JSON grammar (simplified)\njson_grammar = \"\"\"\n{\n    \"name\": \u003Cgen name regex=\"[A-Za-z ]+\" max_tokens=20>,\n    \"age\": \u003Cgen age regex=\"[0-9]+\" max_tokens=3>,\n    \"email\": \u003Cgen email regex=\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}\" max_tokens=50>\n}\n\"\"\"\n\n# Generate valid JSON\nlm += gen(\"person\", grammar=json_grammar)\n\nprint(lm[\"person\"])  # Guaranteed valid JSON structure\n```\n\n**Use cases:**\n- Complex structured outputs\n- Nested data structures\n- Programming language syntax\n- Domain-specific languages\n\n### 5. Guidance Functions\n\nCreate reusable generation patterns with the `@guidance` decorator.\n\n```python\nfrom guidance import guidance, gen, models\n\n@guidance\ndef generate_person(lm):\n    \"\"\"Generate a person with name and age.\"\"\"\n    lm += \"Name: \" + gen(\"name\", max_tokens=20, stop=\"\\n\")\n    lm += \"\\nAge: \" + gen(\"age\", regex=r\"[0-9]+\", max_tokens=3)\n    return lm\n\n# Use the function\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = generate_person(lm)\n\nprint(lm[\"name\"])\nprint(lm[\"age\"])\n```\n\n**Stateful Functions:**\n\n```python\n@guidance(stateless=False)\ndef react_agent(lm, question, tools, max_rounds=5):\n    \"\"\"ReAct agent with tool use.\"\"\"\n    lm += f\"Question: {question}\\n\\n\"\n\n    for i in range(max_rounds):\n        # Thought\n        lm += f\"Thought {i+1}: \" + gen(\"thought\", stop=\"\\n\")\n\n        # Action\n        lm += \"\\nAction: \" + select(list(tools.keys()), name=\"action\")\n\n        # Execute tool\n        tool_result = tools[lm[\"action\"]]()\n        lm += f\"\\nObservation: {tool_result}\\n\\n\"\n\n        # Check if done\n        lm += \"Done? \" + select([\"Yes\", \"No\"], name=\"done\")\n        if lm[\"done\"] == \"Yes\":\n            break\n\n    # Final answer\n    lm += \"\\nFinal Answer: \" + gen(\"answer\", max_tokens=100)\n    return lm\n```\n\n## Backend Configuration\n\n### Anthropic Claude\n\n```python\nfrom guidance import models\n\nlm = models.Anthropic(\n    model=\"claude-sonnet-4-5-20250929\",\n    api_key=\"your-api-key\"  # Or set ANTHROPIC_API_KEY env var\n)\n```\n\n### OpenAI\n\n```python\nlm = models.OpenAI(\n    model=\"gpt-4o-mini\",\n    api_key=\"your-api-key\"  # Or set OPENAI_API_KEY env var\n)\n```\n\n### Local Models (Transformers)\n\n```python\nfrom guidance.models import Transformers\n\nlm = Transformers(\n    \"microsoft\u002FPhi-4-mini-instruct\",\n    device=\"cuda\"  # Or \"cpu\"\n)\n```\n\n### Local Models (llama.cpp)\n\n```python\nfrom guidance.models import LlamaCpp\n\nlm = LlamaCpp(\n    model_path=\"\u002Fpath\u002Fto\u002Fmodel.gguf\",\n    n_ctx=4096,\n    n_gpu_layers=35\n)\n```\n\n## Common Patterns\n\n### Pattern 1: JSON Generation\n\n```python\nfrom guidance import models, gen, system, user, assistant\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\nwith system():\n    lm += \"You generate valid JSON.\"\n\nwith user():\n    lm += \"Generate a user profile with name, age, and email.\"\n\nwith assistant():\n    lm += \"\"\"{\n    \"name\": \"\"\" + gen(\"name\", regex=r'\"[A-Za-z ]+\"', max_tokens=30) + \"\"\",\n    \"age\": \"\"\" + gen(\"age\", regex=r\"[0-9]+\", max_tokens=3) + \"\"\",\n    \"email\": \"\"\" + gen(\"email\", regex=r'\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\"', max_tokens=50) + \"\"\"\n}\"\"\"\n\nprint(lm)  # Valid JSON guaranteed\n```\n\n### Pattern 2: Classification\n\n```python\nfrom guidance import models, gen, select\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\ntext = \"This product is amazing! I love it.\"\n\nlm += f\"Text: {text}\\n\"\nlm += \"Sentiment: \" + select([\"positive\", \"negative\", \"neutral\"], name=\"sentiment\")\nlm += \"\\nConfidence: \" + gen(\"confidence\", regex=r\"[0-9]+\", max_tokens=3) + \"%\"\n\nprint(f\"Sentiment: {lm['sentiment']}\")\nprint(f\"Confidence: {lm['confidence']}%\")\n```\n\n### Pattern 3: Multi-Step Reasoning\n\n```python\nfrom guidance import models, gen, guidance\n\n@guidance\ndef chain_of_thought(lm, question):\n    \"\"\"Generate answer with step-by-step reasoning.\"\"\"\n    lm += f\"Question: {question}\\n\\n\"\n\n    # Generate multiple reasoning steps\n    for i in range(3):\n        lm += f\"Step {i+1}: \" + gen(f\"step_{i+1}\", stop=\"\\n\", max_tokens=100) + \"\\n\"\n\n    # Final answer\n    lm += \"\\nTherefore, the answer is: \" + gen(\"answer\", max_tokens=50)\n\n    return lm\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = chain_of_thought(lm, \"What is 15% of 200?\")\n\nprint(lm[\"answer\"])\n```\n\n### Pattern 4: ReAct Agent\n\n```python\nfrom guidance import models, gen, select, guidance\n\n@guidance(stateless=False)\ndef react_agent(lm, question):\n    \"\"\"ReAct agent with tool use.\"\"\"\n    tools = {\n        \"calculator\": lambda expr: eval(expr),\n        \"search\": lambda query: f\"Search results for: {query}\",\n    }\n\n    lm += f\"Question: {question}\\n\\n\"\n\n    for round in range(5):\n        # Thought\n        lm += f\"Thought: \" + gen(\"thought\", stop=\"\\n\") + \"\\n\"\n\n        # Action selection\n        lm += \"Action: \" + select([\"calculator\", \"search\", \"answer\"], name=\"action\")\n\n        if lm[\"action\"] == \"answer\":\n            lm += \"\\nFinal Answer: \" + gen(\"answer\", max_tokens=100)\n            break\n\n        # Action input\n        lm += \"\\nAction Input: \" + gen(\"action_input\", stop=\"\\n\") + \"\\n\"\n\n        # Execute tool\n        if lm[\"action\"] in tools:\n            result = tools[lm[\"action\"]](lm[\"action_input\"])\n            lm += f\"Observation: {result}\\n\\n\"\n\n    return lm\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = react_agent(lm, \"What is 25 * 4 + 10?\")\nprint(lm[\"answer\"])\n```\n\n### Pattern 5: Data Extraction\n\n```python\nfrom guidance import models, gen, guidance\n\n@guidance\ndef extract_entities(lm, text):\n    \"\"\"Extract structured entities from text.\"\"\"\n    lm += f\"Text: {text}\\n\\n\"\n\n    # Extract person\n    lm += \"Person: \" + gen(\"person\", stop=\"\\n\", max_tokens=30) + \"\\n\"\n\n    # Extract organization\n    lm += \"Organization: \" + gen(\"organization\", stop=\"\\n\", max_tokens=30) + \"\\n\"\n\n    # Extract date\n    lm += \"Date: \" + gen(\"date\", regex=r\"\\d{4}-\\d{2}-\\d{2}\", max_tokens=10) + \"\\n\"\n\n    # Extract location\n    lm += \"Location: \" + gen(\"location\", stop=\"\\n\", max_tokens=30) + \"\\n\"\n\n    return lm\n\ntext = \"Tim Cook announced at Apple Park on 2024-09-15 in Cupertino.\"\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = extract_entities(lm, text)\n\nprint(f\"Person: {lm['person']}\")\nprint(f\"Organization: {lm['organization']}\")\nprint(f\"Date: {lm['date']}\")\nprint(f\"Location: {lm['location']}\")\n```\n\n## Best Practices\n\n### 1. Use Regex for Format Validation\n\n```python\n# ✅ Good: Regex ensures valid format\nlm += \"Email: \" + gen(\"email\", regex=r\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\")\n\n# ❌ Bad: Free generation may produce invalid emails\nlm += \"Email: \" + gen(\"email\", max_tokens=50)\n```\n\n### 2. Use select() for Fixed Categories\n\n```python\n# ✅ Good: Guaranteed valid category\nlm += \"Status: \" + select([\"pending\", \"approved\", \"rejected\"], name=\"status\")\n\n# ❌ Bad: May generate typos or invalid values\nlm += \"Status: \" + gen(\"status\", max_tokens=20)\n```\n\n### 3. Leverage Token Healing\n\n```python\n# Token healing is enabled by default\n# No special action needed - just concatenate naturally\nlm += \"The capital is \" + gen(\"capital\")  # Automatic healing\n```\n\n### 4. Use stop Sequences\n\n```python\n# ✅ Good: Stop at newline for single-line outputs\nlm += \"Name: \" + gen(\"name\", stop=\"\\n\")\n\n# ❌ Bad: May generate multiple lines\nlm += \"Name: \" + gen(\"name\", max_tokens=50)\n```\n\n### 5. Create Reusable Functions\n\n```python\n# ✅ Good: Reusable pattern\n@guidance\ndef generate_person(lm):\n    lm += \"Name: \" + gen(\"name\", stop=\"\\n\")\n    lm += \"\\nAge: \" + gen(\"age\", regex=r\"[0-9]+\")\n    return lm\n\n# Use multiple times\nlm = generate_person(lm)\nlm += \"\\n\\n\"\nlm = generate_person(lm)\n```\n\n### 6. Balance Constraints\n\n```python\n# ✅ Good: Reasonable constraints\nlm += gen(\"name\", regex=r\"[A-Za-z ]+\", max_tokens=30)\n\n# ❌ Too strict: May fail or be very slow\nlm += gen(\"name\", regex=r\"^(John|Jane)$\", max_tokens=10)\n```\n\n## Comparison to Alternatives\n\n| Feature | Guidance | Instructor | Outlines | LMQL |\n|---------|----------|------------|----------|------|\n| Regex Constraints | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes |\n| Grammar Support | ✅ CFG | ❌ No | ✅ CFG | ✅ CFG |\n| Pydantic Validation | ❌ No | ✅ Yes | ✅ Yes | ❌ No |\n| Token Healing | ✅ Yes | ❌ No | ✅ Yes | ❌ No |\n| Local Models | ✅ Yes | ⚠️ Limited | ✅ Yes | ✅ Yes |\n| API Models | ✅ Yes | ✅ Yes | ⚠️ Limited | ✅ Yes |\n| Pythonic Syntax | ✅ Yes | ✅ Yes | ✅ Yes | ❌ SQL-like |\n| Learning Curve | Low | Low | Medium | High |\n\n**When to choose Guidance:**\n- Need regex\u002Fgrammar constraints\n- Want token healing\n- Building complex workflows with control flow\n- Using local models (Transformers, llama.cpp)\n- Prefer Pythonic syntax\n\n**When to choose alternatives:**\n- Instructor: Need Pydantic validation with automatic retrying\n- Outlines: Need JSON schema validation\n- LMQL: Prefer declarative query syntax\n\n## Performance Characteristics\n\n**Latency Reduction:**\n- 30-50% faster than traditional prompting for constrained outputs\n- Token healing reduces unnecessary regeneration\n- Grammar constraints prevent invalid token generation\n\n**Memory Usage:**\n- Minimal overhead vs unconstrained generation\n- Grammar compilation cached after first use\n- Efficient token filtering at inference time\n\n**Token Efficiency:**\n- Prevents wasted tokens on invalid outputs\n- No need for retry loops\n- Direct path to valid outputs\n\n## Resources\n\n- **Documentation**: https:\u002F\u002Fguidance.readthedocs.io\n- **GitHub**: https:\u002F\u002Fgithub.com\u002Fguidance-ai\u002Fguidance (18k+ stars)\n- **Notebooks**: https:\u002F\u002Fgithub.com\u002Fguidance-ai\u002Fguidance\u002Ftree\u002Fmain\u002Fnotebooks\n- **Discord**: Community support available\n\n## See Also\n\n- `references\u002Fconstraints.md` - Comprehensive regex and grammar patterns\n- `references\u002Fbackends.md` - Backend-specific configuration\n- `references\u002Fexamples.md` - Production-ready examples\n\n\n","# Guidance: Constrained LLM Generation\n\n## When to Use This Skill\n\nUse Guidance when you need to:\n- **Control LLM output syntax** with regex or grammars\n- **Guarantee valid JSON\u002FXML\u002Fcode** generation\n- **Reduce latency** vs traditional prompting approaches\n- **Enforce structured formats** (dates, emails, IDs, etc.)\n- **Build multi-step workflows** with Pythonic control flow\n- **Prevent invalid outputs** through grammatical constraints\n\n**GitHub Stars**: 18,000+ | **From**: Microsoft Research\n\n## Installation\n\n```bash\n# Base installation\npip install guidance\n\n# With specific backends\npip install guidance[transformers]  # Hugging Face models\npip install guidance[llama_cpp]     # llama.cpp models\n```\n\n## Quick Start\n\n### Basic Example: Structured Generation\n\n```python\nfrom guidance import models, gen\n\n# Load model (supports OpenAI, Transformers, llama.cpp)\nlm = models.OpenAI(\"gpt-4\")\n\n# Generate with constraints\nresult = lm + \"The capital of France is \" + gen(\"capital\", max_tokens=5)\n\nprint(result[\"capital\"])  # \"Paris\"\n```\n\n### With Anthropic Claude\n\n```python\nfrom guidance import models, gen, system, user, assistant\n\n# Configure Claude\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Use context managers for chat format\nwith system():\n    lm += \"You are a helpful assistant.\"\n\nwith user():\n    lm += \"What is the capital of France?\"\n\nwith assistant():\n    lm += gen(max_tokens=20)\n```\n\n## Core Concepts\n\n### 1. Context Managers\n\nGuidance uses Pythonic context managers for chat-style interactions.\n\n```python\nfrom guidance import system, user, assistant, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# System message\nwith system():\n    lm += \"You are a JSON generation expert.\"\n\n# User message\nwith user():\n    lm += \"Generate a person object with name and age.\"\n\n# Assistant response\nwith assistant():\n    lm += gen(\"response\", max_tokens=100)\n\nprint(lm[\"response\"])\n```\n\n**Benefits:**\n- Natural chat flow\n- Clear role separation\n- Easy to read and maintain\n\n### 2. Constrained Generation\n\nGuidance ensures outputs match specified patterns using regex or grammars.\n\n#### Regex Constraints\n\n```python\nfrom guidance import models, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Constrain to valid email format\nlm += \"Email: \" + gen(\"email\", regex=r\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\")\n\n# Constrain to date format (YYYY-MM-DD)\nlm += \"Date: \" + gen(\"date\", regex=r\"\\d{4}-\\d{2}-\\d{2}\")\n\n# Constrain to phone number\nlm += \"Phone: \" + gen(\"phone\", regex=r\"\\d{3}-\\d{3}-\\d{4}\")\n\nprint(lm[\"email\"])  # Guaranteed valid email\nprint(lm[\"date\"])   # Guaranteed YYYY-MM-DD format\n```\n\n**How it works:**\n- Regex converted to grammar at token level\n- Invalid tokens filtered during generation\n- Model can only produce matching outputs\n\n#### Selection Constraints\n\n```python\nfrom guidance import models, gen, select\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Constrain to specific choices\nlm += \"Sentiment: \" + select([\"positive\", \"negative\", \"neutral\"], name=\"sentiment\")\n\n# Multiple-choice selection\nlm += \"Best answer: \" + select(\n    [\"A) Paris\", \"B) London\", \"C) Berlin\", \"D) Madrid\"],\n    name=\"answer\"\n)\n\nprint(lm[\"sentiment\"])  # One of: positive, negative, neutral\nprint(lm[\"answer\"])     # One of: A, B, C, or D\n```\n\n### 3. Token Healing\n\nGuidance automatically \"heals\" token boundaries between prompt and generation.\n\n**Problem:** Tokenization creates unnatural boundaries.\n\n```python\n# Without token healing\nprompt = \"The capital of France is \"\n# Last token: \" is \"\n# First generated token might be \" Par\" (with leading space)\n# Result: \"The capital of France is  Paris\" (double space!)\n```\n\n**Solution:** Guidance backs up one token and regenerates.\n\n```python\nfrom guidance import models, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# Token healing enabled by default\nlm += \"The capital of France is \" + gen(\"capital\", max_tokens=5)\n# Result: \"The capital of France is Paris\" (correct spacing)\n```\n\n**Benefits:**\n- Natural text boundaries\n- No awkward spacing issues\n- Better model performance (sees natural token sequences)\n\n### 4. Grammar-Based Generation\n\nDefine complex structures using context-free grammars.\n\n```python\nfrom guidance import models, gen\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\n# JSON grammar (simplified)\njson_grammar = \"\"\"\n{\n    \"name\": \u003Cgen name regex=\"[A-Za-z ]+\" max_tokens=20>,\n    \"age\": \u003Cgen age regex=\"[0-9]+\" max_tokens=3>,\n    \"email\": \u003Cgen email regex=\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}\" max_tokens=50>\n}\n\"\"\"\n\n# Generate valid JSON\nlm += gen(\"person\", grammar=json_grammar)\n\nprint(lm[\"person\"])  # Guaranteed valid JSON structure\n```\n\n**Use cases:**\n- Complex structured outputs\n- Nested data structures\n- Programming language syntax\n- Domain-specific languages\n\n### 5. Guidance Functions\n\nCreate reusable generation patterns with the `@guidance` decorator.\n\n```python\nfrom guidance import guidance, gen, models\n\n@guidance\ndef generate_person(lm):\n    \"\"\"Generate a person with name and age.\"\"\"\n    lm += \"Name: \" + gen(\"name\", max_tokens=20, stop=\"\\n\")\n    lm += \"\\nAge: \" + gen(\"age\", regex=r\"[0-9]+\", max_tokens=3)\n    return lm\n\n# Use the function\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = generate_person(lm)\n\nprint(lm[\"name\"])\nprint(lm[\"age\"])\n```\n\n**Stateful Functions:**\n\n```python\n@guidance(stateless=False)\ndef react_agent(lm, question, tools, max_rounds=5):\n    \"\"\"ReAct agent with tool use.\"\"\"\n    lm += f\"Question: {question}\\n\\n\"\n\n    for i in range(max_rounds):\n        # Thought\n        lm += f\"Thought {i+1}: \" + gen(\"thought\", stop=\"\\n\")\n\n        # Action\n        lm += \"\\nAction: \" + select(list(tools.keys()), name=\"action\")\n\n        # Execute tool\n        tool_result = tools[lm[\"action\"]]()\n        lm += f\"\\nObservation: {tool_result}\\n\\n\"\n\n        # Check if done\n        lm += \"Done? \" + select([\"Yes\", \"No\"], name=\"done\")\n        if lm[\"done\"] == \"Yes\":\n            break\n\n    # Final answer\n    lm += \"\\nFinal Answer: \" + gen(\"answer\", max_tokens=100)\n    return lm\n```\n\n## Backend Configuration\n\n### Anthropic Claude\n\n```python\nfrom guidance import models\n\nlm = models.Anthropic(\n    model=\"claude-sonnet-4-5-20250929\",\n    api_key=\"your-api-key\"  # Or set ANTHROPIC_API_KEY env var\n)\n```\n\n### OpenAI\n\n```python\nlm = models.OpenAI(\n    model=\"gpt-4o-mini\",\n    api_key=\"your-api-key\"  # Or set OPENAI_API_KEY env var\n)\n```\n\n### Local Models (Transformers)\n\n```python\nfrom guidance.models import Transformers\n\nlm = Transformers(\n    \"microsoft\u002FPhi-4-mini-instruct\",\n    device=\"cuda\"  # Or \"cpu\"\n)\n```\n\n### Local Models (llama.cpp)\n\n```python\nfrom guidance.models import LlamaCpp\n\nlm = LlamaCpp(\n    model_path=\"\u002Fpath\u002Fto\u002Fmodel.gguf\",\n    n_ctx=4096,\n    n_gpu_layers=35\n)\n```\n\n## Common Patterns\n\n### Pattern 1: JSON Generation\n\n```python\nfrom guidance import models, gen, system, user, assistant\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\nwith system():\n    lm += \"You generate valid JSON.\"\n\nwith user():\n    lm += \"Generate a user profile with name, age, and email.\"\n\nwith assistant():\n    lm += \"\"\"{\n    \"name\": \"\"\" + gen(\"name\", regex=r'\"[A-Za-z ]+\"', max_tokens=30) + \"\"\",\n    \"age\": \"\"\" + gen(\"age\", regex=r\"[0-9]+\", max_tokens=3) + \"\"\",\n    \"email\": \"\"\" + gen(\"email\", regex=r'\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\"', max_tokens=50) + \"\"\"\n}\"\"\"\n\nprint(lm)  # Valid JSON guaranteed\n```\n\n### Pattern 2: Classification\n\n```python\nfrom guidance import models, gen, select\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\n\ntext = \"This product is amazing! I love it.\"\n\nlm += f\"Text: {text}\\n\"\nlm += \"Sentiment: \" + select([\"positive\", \"negative\", \"neutral\"], name=\"sentiment\")\nlm += \"\\nConfidence: \" + gen(\"confidence\", regex=r\"[0-9]+\", max_tokens=3) + \"%\"\n\nprint(f\"Sentiment: {lm['sentiment']}\")\nprint(f\"Confidence: {lm['confidence']}%\")\n```\n\n### Pattern 3: Multi-Step Reasoning\n\n```python\nfrom guidance import models, gen, guidance\n\n@guidance\ndef chain_of_thought(lm, question):\n    \"\"\"Generate answer with step-by-step reasoning.\"\"\"\n    lm += f\"Question: {question}\\n\\n\"\n\n    # Generate multiple reasoning steps\n    for i in range(3):\n        lm += f\"Step {i+1}: \" + gen(f\"step_{i+1}\", stop=\"\\n\", max_tokens=100) + \"\\n\"\n\n    # Final answer\n    lm += \"\\nTherefore, the answer is: \" + gen(\"answer\", max_tokens=50)\n\n    return lm\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = chain_of_thought(lm, \"What is 15% of 200?\")\n\nprint(lm[\"answer\"])\n```\n\n### Pattern 4: ReAct Agent\n\n```python\nfrom guidance import models, gen, select, guidance\n\n@guidance(stateless=False)\ndef react_agent(lm, question):\n    \"\"\"ReAct agent with tool use.\"\"\"\n    tools = {\n        \"calculator\": lambda expr: eval(expr),\n        \"search\": lambda query: f\"Search results for: {query}\",\n    }\n\n    lm += f\"Question: {question}\\n\\n\"\n\n    for round in range(5):\n        # Thought\n        lm += f\"Thought: \" + gen(\"thought\", stop=\"\\n\") + \"\\n\"\n\n        # Action selection\n        lm += \"Action: \" + select([\"calculator\", \"search\", \"answer\"], name=\"action\")\n\n        if lm[\"action\"] == \"answer\":\n            lm += \"\\nFinal Answer: \" + gen(\"answer\", max_tokens=100)\n            break\n\n        # Action input\n        lm += \"\\nAction Input: \" + gen(\"action_input\", stop=\"\\n\") + \"\\n\"\n\n        # Execute tool\n        if lm[\"action\"] in tools:\n            result = tools[lm[\"action\"]](lm[\"action_input\"])\n            lm += f\"Observation: {result}\\n\\n\"\n\n    return lm\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = react_agent(lm, \"What is 25 * 4 + 10?\")\nprint(lm[\"answer\"])\n```\n\n### Pattern 5: Data Extraction\n\n```python\nfrom guidance import models, gen, guidance\n\n@guidance\ndef extract_entities(lm, text):\n    \"\"\"Extract structured entities from text.\"\"\"\n    lm += f\"Text: {text}\\n\\n\"\n\n    # Extract person\n    lm += \"Person: \" + gen(\"person\", stop=\"\\n\", max_tokens=30) + \"\\n\"\n\n    # Extract organization\n    lm += \"Organization: \" + gen(\"organization\", stop=\"\\n\", max_tokens=30) + \"\\n\"\n\n    # Extract date\n    lm += \"Date: \" + gen(\"date\", regex=r\"\\d{4}-\\d{2}-\\d{2}\", max_tokens=10) + \"\\n\"\n\n    # Extract location\n    lm += \"Location: \" + gen(\"location\", stop=\"\\n\", max_tokens=30) + \"\\n\"\n\n    return lm\n\ntext = \"Tim Cook announced at Apple Park on 2024-09-15 in Cupertino.\"\n\nlm = models.Anthropic(\"claude-sonnet-4-5-20250929\")\nlm = extract_entities(lm, text)\n\nprint(f\"Person: {lm['person']}\")\nprint(f\"Organization: {lm['organization']}\")\nprint(f\"Date: {lm['date']}\")\nprint(f\"Location: {lm['location']}\")\n```\n\n## Best Practices\n\n### 1. Use Regex for Format Validation\n\n```python\n# ✅ Good: Regex ensures valid format\nlm += \"Email: \" + gen(\"email\", regex=r\"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\")\n\n# ❌ Bad: Free generation may produce invalid emails\nlm += \"Email: \" + gen(\"email\", max_tokens=50)\n```\n\n### 2. Use select() for Fixed Categories\n\n```python\n# ✅ Good: Guaranteed valid category\nlm += \"Status: \" + select([\"pending\", \"approved\", \"rejected\"], name=\"status\")\n\n# ❌ Bad: May generate typos or invalid values\nlm += \"Status: \" + gen(\"status\", max_tokens=20)\n```\n\n### 3. Leverage Token Healing\n\n```python\n# Token healing is enabled by default\n# No special action needed - just concatenate naturally\nlm += \"The capital is \" + gen(\"capital\")  # Automatic healing\n```\n\n### 4. Use stop Sequences\n\n```python\n# ✅ Good: Stop at newline for single-line outputs\nlm += \"Name: \" + gen(\"name\", stop=\"\\n\")\n\n# ❌ Bad: May generate multiple lines\nlm += \"Name: \" + gen(\"name\", max_tokens=50)\n```\n\n### 5. Create Reusable Functions\n\n```python\n# ✅ Good: Reusable pattern\n@guidance\ndef generate_person(lm):\n    lm += \"Name: \" + gen(\"name\", stop=\"\\n\")\n    lm += \"\\nAge: \" + gen(\"age\", regex=r\"[0-9]+\")\n    return lm\n\n# Use multiple times\nlm = generate_person(lm)\nlm += \"\\n\\n\"\nlm = generate_person(lm)\n```\n\n### 6. Balance Constraints\n\n```python\n# ✅ Good: Reasonable constraints\nlm += gen(\"name\", regex=r\"[A-Za-z ]+\", max_tokens=30)\n\n# ❌ Too strict: May fail or be very slow\nlm += gen(\"name\", regex=r\"^(John|Jane)$\", max_tokens=10)\n```\n\n## Comparison to Alternatives\n\n| Feature | Guidance | Instructor | Outlines | LMQL |\n|---------|----------|------------|----------|------|\n| Regex Constraints | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes |\n| Grammar Support | ✅ CFG | ❌ No | ✅ CFG | ✅ CFG |\n| Pydantic Validation | ❌ No | ✅ Yes | ✅ Yes | ❌ No |\n| Token Healing | ✅ Yes | ❌ No | ✅ Yes | ❌ No |\n| Local Models | ✅ Yes | ⚠️ Limited | ✅ Yes | ✅ Yes |\n| API Models | ✅ Yes | ✅ Yes | ⚠️ Limited | ✅ Yes |\n| Pythonic Syntax | ✅ Yes | ✅ Yes | ✅ Yes | ❌ SQL-like |\n| Learning Curve | Low | Low | Medium | High |\n\n**When to choose Guidance:**\n- Need regex\u002Fgrammar constraints\n- Want token healing\n- Building complex workflows with control flow\n- Using local models (Transformers, llama.cpp)\n- Prefer Pythonic syntax\n\n**When to choose alternatives:**\n- Instructor: Need Pydantic validation with automatic retrying\n- Outlines: Need JSON schema validation\n- LMQL: Prefer declarative query syntax\n\n## Performance Characteristics\n\n**Latency Reduction:**\n- 30-50% faster than traditional prompting for constrained outputs\n- Token healing reduces unnecessary regeneration\n- Grammar constraints prevent invalid token generation\n\n**Memory Usage:**\n- Minimal overhead vs unconstrained generation\n- Grammar compilation cached after first use\n- Efficient token filtering at inference time\n\n**Token Efficiency:**\n- Prevents wasted tokens on invalid outputs\n- No need for retry loops\n- Direct path to valid outputs\n\n## Resources\n\n- **Documentation**: https:\u002F\u002Fguidance.readthedocs.io\n- **GitHub**: https:\u002F\u002Fgithub.com\u002Fguidance-ai\u002Fguidance (18k+ stars)\n- **Notebooks**: https:\u002F\u002Fgithub.com\u002Fguidance-ai\u002Fguidance\u002Ftree\u002Fmain\u002Fnotebooks\n- **Discord**: Community support available\n\n## See Also\n\n- `references\u002Fconstraints.md` - Comprehensive regex and grammar patterns\n- `references\u002Fbackends.md` - Backend-specific configuration\n- `references\u002Fexamples.md` - Production-ready examples\n\n\n",{"name":5,"author":51,"license":15,"version":52,"metadata":53,"description":7,"dependencies":60},"Orchestra Research","1.0.0",{"hermes":54},{"tags":55},[56,57,34,58,33,59,32,31,30],"Prompt Engineering","Guidance","Structured Output","Grammar",[5,61],"transformers","main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fhermes\u002Fguidance","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":69,"prompt":79,"zipAvailable":80},[70,73,76],{"tool":71,"command":72},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill guidance",{"tool":74,"command":75},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill guidance",{"tool":77,"command":78},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill guidance","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fhermes\u002Fguidance\u002FSKILL.md",true,[82,88,92],{"path":83,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":86,"sourceHtmlUrl":87},"references\u002Fbackends.md","REFERENCE","参考文档",12010,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fhermes\u002Fguidance\u002Freferences\u002Fbackends.md",{"path":89,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":90,"sourceHtmlUrl":91},"references\u002Fconstraints.md",15886,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fhermes\u002Fguidance\u002Freferences\u002Fconstraints.md",{"path":93,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":94,"sourceHtmlUrl":95},"references\u002Fexamples.md",20079,"https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fhermes\u002Fguidance\u002Freferences\u002Fexamples.md",[97,121,147,157,170,185],{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":108,"publishedAt":46},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[103],{"categoryNo":104,"categoryName":105,"taxonomyType":106,"taxonomyTypeDesc":107},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[109,110,111,112,113,114,115,116,117,118,119,120],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch","with",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":46},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[128,129,130,131,132,133,111,134,135,136,137,138,139,140,141,142,143,144,145,146],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","when","brew","live","data","google","install","read","across","api",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":46},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[154,155,128,139,140,141,142,132,111,144,156,145,146,138,136,135,134,143,133,131],"trend radar","radar","pulse",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":46},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[164,165,166,167,168,169],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":177,"publishedAt":46},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[176],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[172,117,178,179,180,120,139,181,182,183,130,184,143],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":186,"name":187,"nameZh":6,"description":188,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":189,"categories":190,"keywords":191,"publishedAt":46},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[187,192,193,194,143,195,182,196,197,198,199,200],"status","play","go","latest","github","discover","control","cmd","volume"]