# Как задать грамматику GBNF для llama.cpp server

Источник: https://modelium.tech/zhurnal/llama-cpp-grammatika-gbnf/

GBNF задаёт допустимую форму ответа модели в llama.cpp: например, только YES или NO. Сначала проверьте грамматику на заведомо подходящей и неподходящей строке, затем передайте её в поле grammar запроса к /completion. Форма ответа не доказывает его правильность; этот путь сверен по исходникам, но сервер с моделью редакция не запускала.

Нужно, чтобы локальная модель отвечала **только YES или NO**, а не добавляла объяснение? В llama.cpp это можно задать грамматикой GBNF — короткими правилами допустимого текста. Это инструкция **инженерного уровня**: понадобятся терминал, локальный сервер и уже скачанная совместимая модель в формате GGUF. Грамматика ограничивает форму ответа, но не проверяет, верно ли модель поняла вопрос. [s1](#src-s1) [s2](#src-s2)

**Проверено по исходникам llama.cpp на ревизии a0e6dc7 от 14 октября 2026 года.** Ни модель, ни сервер редакция не запускала; приведённые ниже YES/NO — ожидаемые варианты, не полученные ответы. Пример для Linux и командной строки, не домашний рецепт с гарантированным запуском. [s1](#src-s1) [s2](#src-s2)

## Что подготовить перед запросом?

Нужны Linux, скачанный совместимый GGUF-файл, сборка llama.cpp той же ревизии, CMake и компилятор. Сборка и скачивание требуют сети, если исходники и модель ещё не получены; запрос к серверу на `127.0.0.1` после подготовки адресован вашему компьютеру. Документы здесь **не устанавливают минимальную оперативную память для вашего файла**: проверьте доступную память и модель отдельно, не выводите её из размера файла. Начните с [гайда по llama.cpp](/zhurnal/llama-cpp/), если сервер ещё не установлен. [s2](#src-s2)

Из корня закреплённых исходников подготовьте тестовую программу и сервер: `cmake -S . -B build -DLLAMA_BUILD_TESTS=ON`, затем `cmake --build build --target test-gbnf-validator llama-server -j 2`. Если сборка не проходит, проверьте сообщения CMake и установленный компилятор, прежде чем пытаться отправлять запросы. Эта сборочная процедура следует указанным исходникам; на машине редакции она не воспроизводилась. [s2](#src-s2) [s4](#src-s4)

## Как проверить грамматику на коротких строках?

Создайте файл в текущем каталоге командой `printf '%s' 'root ::= "YES" | "NO"' > answer.gbnf`. `root` — правило для **всего** ответа; `|` означает «или». Такой файл допускает ровно один из двух вариантов без пробелов и пояснений. Это собственный учебный пример по синтаксису авторского справочника, не скопированный фрагмент чужой статьи. [s1](#src-s1)

Создайте строки без завершающего перевода строки: `printf '%s' YES > good.txt` и `printf '%s' MAYBE > bad.txt`. По очереди запустите `./build/bin/test-gbnf-validator answer.gbnf good.txt` и `./build/bin/test-gbnf-validator answer.gbnf bad.txt`. По исходному коду первая должна вывести `Input string is valid according to the grammar.`, вторая — `Input string is invalid according to the grammar.`; это **ожидание по коду**, а не протокол запуска редакции. Важно: программа возвращает код 0 даже при сообщении `invalid`, поэтому смотрите на текст диагностики, а не только на `$?`. [s3](#src-s3) [s4](#src-s4)

Если обе строки проходят, проверьте содержимое `answer.gbnf` и то, что `bad.txt` действительно содержит `MAYBE`. Если тестовая программа не запускается, проверьте, что собирали цель `test-gbnf-validator`, а не только `llama-server`. [s3](#src-s3) [s4](#src-s4)

## Как передать правило локальному серверу?

Запустите сервер с **вашим** проверенным GGUF-файлом: `./build/bin/llama-server -m /путь/к/модели.gguf --host 127.0.0.1 --port 8080`. Подставьте реальный путь; в логах дождитесь загрузки модели, а при ошибке загрузки сначала проверьте сам файл и ресурсы компьютера. Не публикуйте этот порт наружу ради учебного примера. [s2](#src-s2)

В другом терминале отправьте запрос: `curl --fail-with-body -sS http://127.0.0.1:8080/completion -H 'Content-Type: application/json' -d '{"prompt":"Ответь YES, если кошка относится к млекопитающим, иначе NO.","grammar":"root ::= \"YES\" | \"NO\"","n_predict":8,"stream":false}'`. Здесь `grammar` передаётся прямо текстом в JSON-запросе, а `prompt` объясняет задачу модели. Ожидается JSON-ответ сервера с полем `content`; в удачном случае его значение точно `YES` либо `NO`. **Это не результат редакционного запуска.** Маршрут `/completion` не является OpenAI-совместимым; не переносите эту команду без изменений на иной сервер. [s1](#src-s1) [s2](#src-s2) [s5](#src-s5)

Проверьте два свойства **по отдельности**: (1) `content` совпадает с одним разрешённым словом без добавок; (2) слово по смыслу соответствует вопросу. Для нашего учебного вопроса верное слово — `YES`; если пришло `NO`, форма выдержана, но ответ неверен. Если сервер сообщает об ошибке грамматики, сверяйте кавычки и экранирование JSON, а не ослабляйте правило наугад. Не добавляйте одновременно `json_schema`: сервер обрабатывает эту настройку отдельно. Для JSON-объектов удобнее [гайд по JSON Schema](/zhurnal/structured-output-lokalno-json-schema/). [s1](#src-s1) [s2](#src-s2) [s5](#src-s5)

Остановите учебный сервер в его терминале через Ctrl+C. Тестовые `answer.gbnf`, `good.txt` и `bad.txt` можно удалить после проверки. Правило YES/NO не подходит для объяснений, длинных текстов или проверки достоверности фактов; по-настоящему полезный результат требует тестов на ваших данных и отдельной проверки ответа человеком. [s1](#src-s1)

## Источники

1. [llama.cpp — GBNF Guide (закреплённый исходник)](https://github.com/ggml-org/llama.cpp/blob/a0e6dc7384edb8f5d927155e1d26c10b4a310e6d/grammars/README.md) — получено 2026-10-15
2. [llama.cpp — server README (закреплённый исходник)](https://github.com/ggml-org/llama.cpp/blob/a0e6dc7384edb8f5d927155e1d26c10b4a310e6d/tools/server/README.md) — получено 2026-10-15
3. [llama.cpp — test-gbnf-validator.cpp (закреплённый исходник)](https://github.com/ggml-org/llama.cpp/blob/a0e6dc7384edb8f5d927155e1d26c10b4a310e6d/tests/test-gbnf-validator.cpp) — получено 2026-10-15
4. [llama.cpp — CMakeLists.txt и тестовая цель](https://github.com/ggml-org/llama.cpp/blob/a0e6dc7384edb8f5d927155e1d26c10b4a310e6d/tests/CMakeLists.txt) — получено 2026-10-15
5. [llama.cpp — server-schema.cpp (закреплённый исходник)](https://github.com/ggml-org/llama.cpp/blob/a0e6dc7384edb8f5d927155e1d26c10b4a310e6d/tools/server/server-schema.cpp) — получено 2026-10-15
