На этой странице
Управляйте выводом LLM с помощью регулярных выражений и грамматик, гарантируйте генерацию валидного JSON/XML/кода, обеспечивайте соблюдение структурированных форматов и создавайте многошаговые рабочие процессы с Guidance — фреймворком ограниченной генерации от Microsoft Research
Метаданные навыка¶
|
|---|---
Источник| Опционально — установка с помощью hermes skills install official/mlops/guidance
Путь| optional-skills/mlops/guidance
Версия| 1.0.0
Автор| Orchestra Research
Лицензия| MIT
Зависимости| guidance, transformers
Теги| Prompt Engineering, Guidance, Constrained Generation, Structured Output, JSON Validation, Grammar, Microsoft Research, Format Enforcement, Multi-Step Workflows
Справочник: полный SKILL.md¶
info
Ниже приведено полное определение навыка, которое Hermes загружает при его активации. Это то, что агент видит в качестве инструкций, когда навык активен.
Guidance: Ограниченная генерация LLM¶
Когда использовать этот навык¶
Используйте Guidance, когда вам нужно:
- Контролировать синтаксис вывода LLM с помощью регулярных выражений или грамматик
- Гарантировать генерацию валидного JSON/XML/кода
- Снизить задержку по сравнению с традиционными подходами с промптами
- Обеспечить соблюдение структурированных форматов (даты, email, ID и т.д.)
- Создавать многошаговые рабочие процессы с Python-подобным управлением потоком
- Предотвращать невалидный вывод с помощью грамматических ограничений
GitHub Stars: 18 000+ | От: Microsoft Research
Установка¶
[code] # Базовая установка pip install guidance
# С конкретными бэкендами
pip install guidance[transformers] # Модели Hugging Face
pip install guidance[llama_cpp] # Модели llama.cpp
[/code]
Быстрый старт¶
Базовый пример: Структурированная генерация¶
[code] from guidance import models, gen
# Загрузка модели (поддерживает OpenAI, Transformers, llama.cpp)
lm = models.OpenAI("gpt-4")
# Генерация с ограничениями
result = lm + "The capital of France is " + gen("capital", max_tokens=5)
print(result["capital"]) # "Paris"
[/code]
С Anthropic Claude¶
[code] from guidance import models, gen, system, user, assistant
# Настройка Claude
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# Использование контекстных менеджеров для чат-формата
with system():
lm += "You are a helpful assistant."
with user():
lm += "What is the capital of France?"
with assistant():
lm += gen(max_tokens=20)
[/code]
Основные концепции¶
1. Контекстные менеджеры¶
Guidance использует Python-подобные контекстные менеджеры для чат-взаимодействий.
[code] from guidance import system, user, assistant, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# Системное сообщение
with system():
lm += "You are a JSON generation expert."
# Сообщение пользователя
with user():
lm += "Generate a person object with name and age."
# Ответ ассистента
with assistant():
lm += gen("response", max_tokens=100)
print(lm["response"])
[/code]
Преимущества:
- Естественный чат-поток
- Чёткое разделение ролей
- Легко читать и поддерживать
2. Ограниченная генерация¶
Guidance гарантирует, что вывод соответствует заданным шаблонам с помощью регулярных выражений или грамматик.
Ограничения с помощью Regex¶
[code] from guidance import models, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# Ограничение до валидного формата email
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
# Ограничение до формата даты (YYYY-MM-DD)
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}")
# Ограничение до номера телефона
lm += "Phone: " + gen("phone", regex=r"\d{3}-\d{3}-\d{4}")
print(lm["email"]) # Гарантированно валидный email
print(lm["date"]) # Гарантированно формат YYYY-MM-DD
[/code]
Как это работает:
- Regex преобразуется в грамматику на уровне токенов
- Невалидные токены отфильтровываются во время генерации
- Модель может производить только соответствующие результаты
Ограничения с помощью выбора¶
[code] from guidance import models, gen, select
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# Ограничение до конкретных вариантов
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")
# Множественный выбор
lm += "Best answer: " + select(
["A) Paris", "B) London", "C) Berlin", "D) Madrid"],
name="answer"
)
print(lm["sentiment"]) # Один из: positive, negative, neutral
print(lm["answer"]) # Один из: A, B, C или D
[/code]
3. Токен-хилинг (Token Healing)¶
Guidance автоматически "исцеляет" границы токенов между промптом и генерацией.
Проблема: Токенизация создаёт неестественные границы.
[code] # Без токен-хилинга prompt = "The capital of France is " # Последний токен: " is " # Первый сгенерированный токен может быть " Par" (с ведущим пробелом) # Результат: "The capital of France is Paris" (двойной пробел!)
[/code]
Решение: Guidance отступает на один токен и регенерирует.
[code] from guidance import models, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# Токен-хилинг включён по умолчанию
lm += "The capital of France is " + gen("capital", max_tokens=5)
# Результат: "The capital of France is Paris" (правильные пробелы)
[/code]
Преимущества:
- Естественные текстовые границы
- Нет проблем с неудобными пробелами
- Лучшая производительность модели (видит естественные последовательности токенов)
4. Генерация на основе грамматик¶
Определяйте сложные структуры с помощью контекстно-свободных грамматик.
[code] from guidance import models, gen
lm = models.Anthropic("claude-sonnet-4-5-20250929")
# JSON грамматика (упрощённая)
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>
}
"""
# Генерация валидного JSON
lm += gen("person", grammar=json_grammar)
print(lm["person"]) # Гарантированно валидная JSON-структура
[/code]
Варианты использования:
- Сложные структурированные выводы
- Вложенные структуры данных
- Синтаксис языков программирования
- Предметно-ориентированные языки
5. Функции Guidance¶
Создавайте переиспользуемые шаблоны генерации с помощью декоратора @guidance.
[code] from guidance import guidance, gen, models
@guidance
def generate_person(lm):
"""Сгенерировать человека с именем и возрастом."""
lm += "Name: " + gen("name", max_tokens=20, stop="\n")
lm += "\nAge: " + gen("age", regex=r"[0-9]+", max_tokens=3)
return lm
# Использование функции
lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = generate_person(lm)
print(lm["name"])
print(lm["age"])
[/code]
Функции с состоянием:
[code] @guidance(stateless=False) def react_agent(lm, question, tools, max_rounds=5): """ReAct агент с использованием инструментов.""" lm += f"Question: {question}\n\n"
for i in range(max_rounds):
# Мысль
lm += f"Thought {i+1}: " + gen("thought", stop="\n")
# Действие
lm += "\nAction: " + select(list(tools.keys()), name="action")
# Выполнение инструмента
tool_result = tools[lm["action"]]()
lm += f"\nObservation: {tool_result}\n\n"
# Проверка завершения
lm += "Done? " + select(["Yes", "No"], name="done")
if lm["done"] == "Yes":
break
# Финальный ответ
lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
return lm
[/code]
Конфигурация бэкенда¶
Anthropic Claude¶
[code] from guidance import models
lm = models.Anthropic(
model="claude-sonnet-4-5-20250929",
api_key="your-api-key" # Или установите переменную окружения ANTHROPIC_API_KEY
)
[/code]
OpenAI¶
[code] lm = models.OpenAI( model="gpt-4o-mini", api_key="your-api-key" # Или установите переменную окружения OPENAI_API_KEY )
[/code]
Локальные модели (Transformers)¶
[code] from guidance.models import Transformers
lm = Transformers(
"microsoft/Phi-4-mini-instruct",
device="cuda" # Или "cpu"
)
[/code]
Локальные модели (llama.cpp)¶
[code] from guidance.models import LlamaCpp
lm = LlamaCpp(
model_path="/path/to/model.gguf",
n_ctx=4096,
n_gpu_layers=35
)
[/code]
Типовые шаблоны¶
Шаблон 1: Генерация JSON¶
[code] 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) # Гарантированно валидный JSON
[/code]
Шаблон 2: Классификация¶
[code] 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']}%")
[/code]
Шаблон 3: Многошаговые рассуждения¶
[code] from guidance import models, gen, guidance
@guidance
def chain_of_thought(lm, question):
"""Сгенерировать ответ с пошаговыми рассуждениями."""
lm += f"Question: {question}\n\n"
# Генерация нескольких шагов рассуждений
for i in range(3):
lm += f"Step {i+1}: " + gen(f"step_{i+1}", stop="\n", max_tokens=100) + "\n"
# Финальный ответ
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"])
[/code]
Шаблон 4: ReAct Агент¶
[code] from guidance import models, gen, select, guidance
@guidance(stateless=False)
def react_agent(lm, question):
"""ReAct агент с использованием инструментов."""
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):
# Мысль
lm += f"Thought: " + gen("thought", stop="\n") + "\n"
# Выбор действия
lm += "Action: " + select(["calculator", "search", "answer"], name="action")
if lm["action"] == "answer":
lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
break
# Ввод действия
lm += "\nAction Input: " + gen("action_input", stop="\n") + "\n"
# Выполнение инструмента
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"])
[/code]
Шаблон 5: Извлечение данных¶
[code] from guidance import models, gen, guidance
@guidance
def extract_entities(lm, text):
"""Извлечь структурированные сущности из текста."""
lm += f"Text: {text}\n\n"
# Извлечение человека
lm += "Person: " + gen("person", stop="\n", max_tokens=30) + "\n"
# Извлечение организации
lm += "Organization: " + gen("organization", stop="\n", max_tokens=30) + "\n"
# Извлечение даты
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}", max_tokens=10) + "\n"
# Извлечение места
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']}")
[/code]
Лучшие практики¶
1. Используйте Regex для проверки формата¶
[code] # ✅ Хорошо: Regex обеспечивает валидный формат lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}")
# ❌ Плохо: Свободная генерация может дать невалидные email
lm += "Email: " + gen("email", max_tokens=50)
[/code]
2. Используйте select() для фиксированных категорий¶
[code] # ✅ Хорошо: Гарантированно валидная категория lm += "Status: " + select(["pending", "approved", "rejected"], name="status")
# ❌ Плохо: Может сгенерировать опечатки или невалидные значения
lm += "Status: " + gen("status", max_tokens=20)
[/code]
3. Используйте токен-хилинг¶
[code] # Токен-хилинг включён по умолчанию # Никаких специальных действий не требуется — просто соединяйте естественно lm += "The capital is " + gen("capital") # Автоматическое исцеление
[/code]
4. Используйте стоп-последовательности¶
[code] # ✅ Хорошо: Остановка на новой строке для однострочных выводов lm += "Name: " + gen("name", stop="\n")
# ❌ Плохо: Может сгенерировать несколько строк
lm += "Name: " + gen("name", max_tokens=50)
[/code]
5. Создавайте переиспользуемые функции¶
[code] # ✅ Хорошо: Переиспользуемый шаблон @guidance def generate_person(lm): lm += "Name: " + gen("name", stop="\n") lm += "\nAge: " + gen("age", regex=r"[0-9]+") return lm
# Использование несколько раз
lm = generate_person(lm)
lm += "\n\n"
lm = generate_person(lm)
[/code]
6. Балансируйте ограничения¶
[code] # ✅ Хорошо: Разумные ограничения lm += gen("name", regex=r"[A-Za-z ]+", max_tokens=30)
# ❌ Слишком строго: Может не сработать или быть очень медленным
lm += gen("name", regex=r"^(John|Jane)$", max_tokens=10)
[/code]
Сравнение с альтернативами¶
| Особенность | Guidance | Instructor | Outlines | LMQL |
|---|---|---|---|---|
| Regex-ограничения | ✅ Да | ❌ Нет | ✅ Да | ✅ Да |
| Поддержка грамматик | ✅ CFG | ❌ Нет | ✅ CFG | ✅ CFG |
| Pydantic-валидация | ❌ Нет | ✅ Да | ✅ Да | ❌ Нет |
| Токен-хилинг | ✅ Да | ❌ Нет | ✅ Да | ❌ Нет |
| Локальные модели | ✅ Да | ⚠️ Ограничено | ✅ Да | ✅ Да |
| API-модели | ✅ Да | ✅ Да | ⚠️ Ограничено | ✅ Да |
| Python-синтаксис | ✅ Да | ✅ Да | ✅ Да | ❌ SQL-подобный |
| Порог входа | Низкий | Низкий | Средний | Высокий |
Когда выбирать Guidance:
- Нужны ограничения с помощью regex/грамматик
- Нужен токен-хилинг
- Создание сложных рабочих процессов с управлением потоком
- Использование локальных моделей (Transformers, llama.cpp)
- Предпочтение Python-синтаксиса
Когда выбирать альтернативы:
- Instructor: Нужна Pydantic-валидация с автоматическими повторами
- Outlines: Нужна валидация JSON-схем
- LMQL: Предпочтение декларативного синтаксиса запросов
Характеристики производительности¶
Снижение задержки:
- На 30-50% быстрее, чем традиционный промптинг для ограниченного вывода
- Токен-хилинг уменьшает ненужную регенерацию
- Грамматические ограничения предотвращают генерацию невалидных токенов
Использование памяти:
- Минимальные накладные расходы по сравнению с неограниченной генерацией
- Компиляция грамматик кэшируется после первого использования
- Эффективная фильтрация токенов во время инференса
Эффективность токенов:
- Предотвращает трату токенов на невалидный вывод
- Не требует циклов повторных попыток
- Прямой путь к валидному выводу
Ресурсы¶
- Документация: https://guidance.readthedocs.io
- GitHub: https://github.com/guidance-ai/guidance (18k+ звёзд)
- Notebooks: https://github.com/guidance-ai/guidance/tree/main/notebooks
- Discord: Доступна поддержка сообщества
См. также¶
references/constraints.md— Полные шаблоны regex и грамматикreferences/backends.md— Конфигурация для конкретных бэкендов-
references/examples.md— Примеры для production - Справочник: полный SKILL.md
- Когда использовать этот навык
- Установка
- Быстрый старт
- Основные концепции
- Конфигурация бэкенда
- Типовые шаблоны
- Лучшие практики
- Сравнение с альтернативами
- Характеристики производительности
- Ресурсы
- См. также