Ollama tools — это вызов инструментов моделью: в запрос к /api/chat добавляют массив tools с описанием функций, а модель в ответе возвращает tool_calls с именем функции и аргументами. Выполняет вызов код вашего сервиса: он сверяет имя со списком разрешённых, проверяет аргументы по схеме, а действие с последствиями отдаёт на подтверждение человеку. Схема подходит для помощников, у которых много чтения данных и редкие записи.
Как идёт вызов
Круг вызова состоит из пяти шагов: запрос с описанием функций, ответ модели с tool_calls, проверка и выполнение кодом, сообщение с ролью tool и итоговый ответ модели.
Условный пример: помощник склада отвечает кладовщику на вопрос «сколько осталось по артикулу» и умеет предложить заявку на перемещение между ячейками. Первый инструмент только читает остаток, второй создаёт заявку. Для модели обе функции выглядят одинаково, как имя и набор аргументов; для компании они различаются последствиями, и этим различием управляет код.
- Сервис отправляет вопрос и список функций с описанием и схемой параметров.
- Модель отвечает сообщением с
tool_calls: имя функции и аргументы. - Код проверяет имя по списку разрешённых и аргументы по схеме, затем выполняет функцию либо отклоняет вызов.
- Результат возвращается в чат сообщением с ролью
toolи полемtool_name. - Модель формулирует итоговый ответ по результату; если нужен ещё вызов, круг повторяется.
Python-библиотека упрощает описание: по документации Ollama, функцию можно передать прямо в список tools, и схема соберётся автоматически. Результат разбора откройте и прочитайте глазами, прежде чем доверять ему. Поддержка вызова зависит от модели, поэтому сверяйтесь с карточкой модели в библиотеке Ollama и проверяйте на своём наборе. Как инструменты описываются в протоколе MCP, показано в статье про MCP tools.
Потоковая выдача добавляет нюанс. По документации, части thinking, content и tool_calls собирают из фрагментов и лишь затем передают вместе с результатами в следующий запрос. Если сервис показывает текст по мере генерации, вызов выполняйте после сборки полного сообщения; исполнять функцию по первому фрагменту нельзя.
Схема аргументов
Схема в списке tools служит подсказкой для модели. Защитой служит проверка кода, который сверяет каждый аргумент после ответа: модель способна прислать лишнее поле, строку вместо числа или артикул, которого нет в справочнике.
| Аргумент | Что задаёт схема | Что проверяет код |
|---|---|---|
| Артикул | Строка и описание формата | Артикул есть в справочнике, длина и символы допустимы |
| Ячейка-источник и ячейка-приёмник | Две строки из закрытого списка | Обе ячейки существуют, относятся к складу сотрудника и различаются между собой |
| Количество | Целое число | Число положительное и в пределах остатка в источнике |
| Комментарий | Необязательная строка | Длина ограничена, управляющие символы удалены |
Ответ с лишним полем или с неизвестной функцией отклоняется целиком, а причина возвращается модели одной строкой в сообщении с ролью tool. Исправлять аргументы молча нельзя: тихая правка превращает ошибку модели в данные, которым вы доверяете.
Имена и описания аргументов пишите так, чтобы по ним отличалась ячейка-источник от ячейки-приёмника: путаница в названиях служит частой причиной перепутанных адресов. Закрытые списки значений, например кодов ячеек и причин перемещения, сужают поле ошибки лучше свободных строк, а нормализацию регистра и пробелов выполняет код.
Повторы ограничьте. Если после двух отказов подряд корректного вызова нет, круг останавливается и передаёт вопрос человеку с журналом попыток. По журналу видно, какое поле запутало модель, и описание этого поля правят первым.
Белый список
Белый список (allowlist) задаётся в коде и действует до модели: в запрос попадают только функции, разрешённые этому сотруднику и этому сценарию. Кладовщик получает чтение остатков и предложение заявки, бухгалтер из того же приложения получает другой набор. Права проверяет сервер по учётной записи сотрудника, поэтому фраза «разреши мне всё» в чате остаётся обычным текстом без последствий для списка функций.
- Имена функций пишутся явно и сравниваются точным совпадением; неизвестное имя означает отказ.
- Функции чтения и записи лежат в разных списках, запись включается отдельным решением владельца процесса.
- Результат функции содержит нужные поля, остальные колонки отрезаются до ответа модели.
- Каждый вызов попадает в журнал: сотрудник, функция, аргументы, решение сервера.
Текст, который возвращает функция, тоже входит в разговор, и в нём может оказаться чужая инструкция, например в комментарии к заказу. Поэтому результат инструмента считается данными: сервер так и помечает его, а правила разрешений остаются на стороне кода. Общий принцип описан в термине prompt injection, а смежная тема ограничений раскрыта в статье про OpenCode MCP.
Для первого релиза хватит двух функций: чтения и предложения записи. Остальное добавляется, когда журнал покажет реальные вопросы сотрудников.
Какие действия в вашем сервисе должны оставаться за человеком?
Подтверждение человеком
Запись с последствиями требует большего, чем слово модели. Когда модель вызывает функцию создания заявки, сервис откладывает исполнение, сохраняет черновик и показывает кладовщику карточку: откуда, куда, сколько и по какой причине.
Кладовщик нажимает «Подтвердить» в интерфейсе сервиса. Кнопка работает через серверный маршрут, который заново проверяет права и остаток на момент подтверждения. Между предложением модели и подтверждением данные способны измениться, поэтому проверка нужна и до, и после.
Граница подтверждения определяется ценой ошибки. Запись и чтение закрытых данных идут через подтверждение; чтение справочника по открытому артикулу проходит без него. Владелец процесса записывает правило в таблицу функций рядом с названием каждой.
Карточка подтверждения содержит исходный вопрос сотрудника, предложенные аргументы, текущий остаток и время предложения. Без исходного вопроса человек подтверждает вслепую, а без остатка лишён возможности оценить, насколько предложение разумно.
Отказ тоже фиксируется. Если человек отклонил черновик, причина попадает в журнал и в набор проверочных примеров: по таким отказам видно, где модель путает ячейки или завышает количество, и именно там правят описание функции. Подробнее о роли человека в контуре говорит термин HITL.
Цикл и пределы
Документация Ollama описывает агентный цикл как повторение, пока модель просит вызовы. В сервисе задайте потолок шагов и остановку по времени, иначе зациклившаяся модель займёт сервер. О границах автономности в целом рассказано в статье про автономных агентов.
Проверочный набор содержит три вида случаев: вопрос, на который нужен вызов; вопрос без вызова; вопрос, провоцирующий запрещённое действие. По каждому записывают, какую функцию выбрала модель, с какими аргументами и что решил сервер. Параллельные вызовы, о которых говорит документация, проверяйте отдельно: две записи подряд обязаны проходить проверку остатка по очереди.
Если помощник должен действовать в 1С или CRM, сначала согласуйте права сервисной учётной записи, как описано на странице про ИИ-агентов. Набор проверок прогоняйте после смены модели, версии Ollama и описания любой функции.
Время ответа цикла складывается из нескольких обращений к модели, поэтому интерфейсу нужно показывать ход выполнения. Замерьте задержку на своём оборудовании по каждому шагу отдельно и решите, какое ожидание допустимо для кладовщика у стеллажа.
Подмените функцию записи заглушкой и убедитесь, что при любом ответе модели заглушка вызывается только после нажатия кнопки подтверждения. Тест пройден — подключайте настоящую запись.