Публичная жалоба: повод для теста, а не установленный диагноз
На странице DeepSeek-V4-Flash-0731 в Hugging Face опубликовано обсуждение с заголовком «This model has many tool_call errors». Пользователь связывает заметное снижение точности вызовов инструментов с контекстом свыше 161 тыс. токенов и описывает случаи, когда агенту требовались дополнительные сообщения, чтобы продолжить работу. Это инженерный сигнал, но не опубликованный бенчмарк и не подтверждённый разработчиком баг-репорт.
Одно пользовательское сообщение не позволяет считать 161 тыс. токенов техническим лимитом модели или объявлять релиз непригодным для агентных задач. В доступном сигнале нет полной методики измерений, сырого вывода модели, параметров генерации, версии inference-сервера и описания обработки стриминга.
Для команды, внедряющей агента, это различие принципиально. Модель может сформировать корректный вызов, который middleware не распознает. Аргументы могут прийти в JSON, но не пройти проверку прав или бизнес-правил. И наоборот, исправная инфраструктура не поможет, если модель выдала текст вместо обязательного действия.
Корректный вывод пока ограничен: существует публичный пользовательский сигнал о проблемах tool_call в DeepSeek-V4-Flash-0731, который требует воспроизводимой проверки. Документация DeepSeek прямо требует валидировать аргументы функций до исполнения, поскольку модель может вернуть невалидный JSON или поля вне схемы. Эта защита нужна независимо от конкретного релиза и жалобы.
Цитата в переводе«Обычно точность tool_call заметно падает, когда контекст превышает 161 тыс. токенов.»
Tool call: последовательность контрактов, а не одна способность модели
Вызов инструмента позволяет модели предложить приложению структурированную команду: запросить данные, создать заявку или отправить сообщение. При этом модель не должна получать неограниченный доступ к системам организации. Исполнение остаётся за оркестратором, который принимает решение модели, проверяет его и вызывает разрешённую функцию.
В API-сценарии приложение передаёт описание доступных функций, модель возвращает tool call, приложение исполняет функцию и добавляет результат в диалог. Внутри процесса действуют независимые контракты. Модель должна выбрать инструмент, ответ должен корректно передаваться и распознаваться, аргументы должны соответствовать схеме, действие должно быть разрешено, а повтор запроса не должен создавать второй побочный эффект.
Поэтому ответ с причиной завершения tool_calls ещё не означает успешного результата. Вызов может содержать неизвестное имя функции, неразбираемые аргументы или формально корректный, но недопустимый запрос. Для информационного бота это означает недоставленный ответ. Для агента с доступом к заявкам, сообщениям или операциям последствия серьёзнее: одного успешно распарсенного JSON недостаточно, чтобы разрешить действие.
- Способность модели: выбрать инструмент и предложить аргументы.
- Протокольная надёжность: корректно передать и распознать вызов между компонентами.
- Схемная надёжность: проверить структуру, типы и допустимые поля.
- Операционная надёжность: подтвердить права, политику и результат действия.
Форматный сбой: вызов есть в выводе, но агент его не увидел
Один из наиболее сложных классов ошибок возникает на границе генерации и разбора. Модель может вывести фрагмент, который по смыслу представляет вызов инструмента, но сервер или клиентская библиотека оставят его в обычном content. Для агента это уже не команда: функция не запускается, а причина сбоя может остаться незамеченной.
Особенно уязвим потоковый режим. Ответ приходит частями, и граница чанка может оказаться внутри имени функции, экранированной строки или JSON-объекта. Промежуточный gateway способен потерять идентификатор вызова, а адаптер совместимости может неверно сопоставить внутреннюю разметку с полем tool_calls. Такой сбой нельзя автоматически приписывать модели: он мог возникнуть уже после генерации.
В issue проекта MLX описан показательный случай: сервер возвращал тег tool call в обычном тексте, а структурированное поле tool_calls оставалось пустым. В обсуждении причиной считалась работа детектора на уровне токенов: закрывающий маркер оказался объединён со следующим символом и не совпал с ожидаемой последовательностью. Эпизод не доказывает дефект DeepSeek-V4-Flash-0731, но показывает, почему утверждение «модель не вызвала функцию» требует изучения raw completion и поведения парсера.
Практический минимум: сохранять сырой ответ до преобразования SDK, результат сборки стрима и итог разбора. Если в raw output присутствует корректный вызов, а в tool_calls его нет, расследовать нужно serving stack. Если в сыром выводе находится обычный текст при обязательном вызове, следует проверять поведение модели, инструкцию и режим выбора инструмента.
Схемный сбой: JSON есть, но выполнять его нельзя
Документация DeepSeek предупреждает: поле arguments генерируется моделью и может содержать невалидный JSON либо параметры, которых нет в описании функции. Структурированный интерфейс сам по себе не делает вызов безопасным. Проверка аргументов до исполнения остаётся обязанностью приложения.
Надёжный оркестратор последовательно проверяет имя функции по белому списку, разбирает arguments как JSON, применяет схему и затем запускает бизнес-валидацию. Последний этап необходим: схема может подтвердить тип поля, но не устанавливает, существует ли объект, есть ли у пользователя полномочия и допустима ли операция в текущем статусе.
DeepSeek предлагает strict для инструментов через beta endpoint. Режим предназначен для проверки схемы функции и формирования аргументов в согласованной структуре. Документация указывает на ограничения поддерживаемого подмножества JSON Schema: для объектов все свойства должны быть обязательными, additionalProperties нужно установить в false, а часть ограничений длины и размера не поддерживается.
Принципиальна разница между формальной и смысловой корректностью. JSON с допустимыми по схеме полями всё равно может содержать неверный объект или действие, которое нельзя исполнять без дополнительной проверки. Strict снижает риск части форматных ошибок, но не заменяет правила доступа, контроль последствий и подтверждение результата.
Цитата в переводе«Модель не всегда генерирует валидный JSON и может выдумывать параметры, не определённые в схеме вашей функции. Проверяйте аргументы в коде до вызова функции.»
Семантический сбой: модель ответила текстом вместо обязательного действия
Отдельная проблема возникает, когда инструмент не вызван вовсе, хотя этого требует логика приложения. В пользовательском обсуждении описан IM-агент, который должен направлять каждый видимый пользователю ответ через функцию отправки. По сообщению автора, при tool_choice=auto модель дважды вернула обычный текст и лишь затем сформировала вызов send_text. Это единичное наблюдение, а не оценка частоты, но оно точно описывает тип сбоя.
Если интерфейс доставляет пользователю только результат функции, прямой текст модели фактически пропадает. Задача не выполнена, хотя модель могла сформулировать содержательный ответ. Исправить только JSON здесь не получится: JSON отсутствует. Ошибка относится к выбору действия, потому что модель повела себя так, как если бы текстовый ответ был допустим, тогда как внешний контракт ожидал инструмент.
tool_choice=auto подходит для сценариев, где допустимы и текст, и вызов функции. Для шага с обязательным действием нужен другой подход: в коде следует определить приемлемые инструменты, а свободный content без допустимого tool_calls считать нарушением протокола, а не успешным завершением.
После такого нарушения возможны один контролируемый повтор с коротким требованием, смена режима или fallback-маршрут. Повтор не должен превращаться в бесконечный цикл: его число и условия зависят от критичности сценария, стоимости попытки и наличия безопасной альтернативы.
Цитата в переводе«Только на третьей попытке модель сформировала вызов функции send_text.»
Длинный контекст: правдоподобная гипотеза, но не объяснение механизма
Связь проблем с контекстом свыше 161 тыс. токенов, о которой говорится в пользовательском посте, остаётся гипотезой для проверки, а не установленной причиной. В многошаговом агенте контекст растёт не только из-за диалога: в него входят описания инструментов, схемы, результаты предыдущих вызовов, системные правила и документы. Для диагностики недостаточно знать лишь число реплик.
В тестах полезно независимо менять размер полного prompt, число и сложность инструментов, объём tool results, streaming, параметры генерации и версию сервера. Нужно сравнивать точки ниже, около и выше заявленного значения. Если проблема возникает только при stream=true, это усиливает гипотезу о транспортном или парсерном слое. Если raw output перестаёт содержать требуемый вызов и без стриминга, проверять нужно модельное поведение или сформулированный контракт.
Этот подход применим к командам, строящим собственные агентные контуры. Нельзя подменять воспроизводимый тест общим выводом, что длинный контекст ломает tool calls. Вместе с длиной контекста могут меняться конкурирующие инструкции, состав схем, история неудачных попыток и результаты внешних инструментов. Корреляция сама по себе не объясняет причину.
- Фиксируйте размер полного prompt, а не только число реплик.
- Проверяйте stream=true и stream=false как разные режимы.
- Разделяйте метрики генерации, парсинга, валидации и исполнения.
- Тестируйте обязательный tool-only сценарий отдельно от свободного диалога.
Контракт tool calls для production: валидация, ретраи и fallback
Надёжная интеграция начинается с явного контракта между моделью и оркестратором. Он должен быть реализован в коде и тестах, а не существовать лишь как пожелание в системной инструкции. На каждом шаге контракт отвечает на два вопроса: какой результат допустим и как действовать при конкретном типе отклонения.
Первое правило: не исполнять функцию по тексту, похожему на команду. Оркестратор принимает только структурированный вызов, прошедший разбор, проверку имени, JSON, схемы и бизнес-ограничений. Для обязательного инструмента отсутствие допустимого вызова является нарушением протокола. Такое разделение не позволяет выдать неисполненную задачу за завершённую.
Второе правило: разделять ретраи по причинам. Подозрение на потерю вызова при стриминге можно проверить повтором без стриминга. При невалидных аргументах модели можно вернуть структурированную ошибку валидации и попросить исправить поля. Отсутствие обязательного tool call допускает ограниченный repair-ретрай или fallback-маршрут. Но операция, отклонённая политикой или правами, не является временным сбоем и не должна повторяться автоматически.
Третье правило: считать вызовы с побочным эффектом потенциально выполненными даже при таймауте. Статус сетевого запроса не всегда показывает, принял ли внешний сервис операцию. Поэтому нужны idempotency key, журнал операции и проверка фактического outcome, иначе ретрай может продублировать сообщение, заявку или другое действие.
Fallback следует выбирать по классу сбоя. При parser failure уместен non-streaming или другой адаптер; при нарушении tool-only контракта нужна модель либо режим, лучше соблюдающий структурированный вывод. Для критичных действий fallback не отменяет контроль политики: решение об исполнении в любом случае остаётся у приложения.
Телеметрия: как превратить жалобу в диагностируемый инцидент
Сообщение «сломался tool call» мало полезно без трассировки. Для каждого хода агента имеет смысл фиксировать model ID, endpoint, версию сервера и SDK, режим стриминга, параметры генерации, хэш набора tools, размер схемы и полного контекста, а также raw output до parsing. Эти данные позволяют отделить изменение модели от изменения инфраструктуры.
После генерации следует записывать отдельные состояния: был ли вызов в сыром выводе, увидел ли его парсер, разобрался ли JSON, прошла ли схема, прошли ли бизнес-проверки, был ли инструмент запущен и подтверждён ли результат. Тогда место сбоя становится наблюдаемым. Разрыв между raw call и parser detection указывает на интеграцию; отказ после схемы указывает на правила приложения, а не обязательно на модель.
Коды ошибок API также нужно классифицировать отдельно. Временная ошибка сервиса, невалидные аргументы и отклонённая бизнес-операция требуют разных реакций. Только такое разделение позволяет не превратить механизм восстановления в источник повторных или небезопасных действий.
Что это означает на практике
Публичная жалоба на DeepSeek-V4-Flash-0731 не устанавливает дефект модели и не подтверждает единый порог контекста. Но она показывает разрыв между способностью модели предложить вызов инструмента и гарантией, что агент безопасно выполнит нужное действие в production.
Надёжный агент опирается не на доверие к одному полю API, а на контракт tool calls, валидацию, наблюдаемость, идемпотентность и проверенный fallback. При таком подходе проблемный ответ становится диагностируемым инцидентом, а не необъяснимой пропажей действия.
- Не считайте finish_reason: tool_calls доказательством успешного действия: отдельно проверяйте вызов, имя функции, JSON, схему, бизнес-правила и результат внешнего сервиса.
- Для обязательных инструментов задайте кодовый инвариант: свободный текст без допустимого tool_calls является нарушением протокола, а не успешным ответом.
- Сохраняйте raw completion до парсинга: это позволяет отличить отказ модели вызвать функцию от ошибки стриминга, токенизации или адаптера.
- Проверяйте strict на собственных схемах, но не принимайте его за защиту от неверного по смыслу действия: режим не заменяет бизнес-валидацию.
- Разделяйте ретраи: non-streaming повтор для parser failure, repair-попытка для невалидных аргументов, fallback для tool-only violation и никаких слепых повторов потенциально выполненных операций.
- Используйте idempotency key и журнал операций для инструментов с побочным эффектом.
- Проверяйте гипотезу о длинном контексте контролируемой матрицей: размер prompt, streaming, набор инструментов и сервер должны меняться независимо.
Практический чек-лист для команды
Этот чек-лист помогает подготовить воспроизводимый тест и не смешать модельные, протокольные и операционные сбои в одном диагнозе.
До запуска теста
Зафиксируйте конфигурацию, на которой наблюдается проблема. Это создаёт точку сравнения для повторных прогонов и изменений инфраструктуры.
- Сохранить model ID, endpoint, версию сервера и SDK.
- Зафиксировать параметры генерации, режим стриминга и хэш доступного набора tools.
- Измерить полный размер prompt, включая системные инструкции, схемы, историю и tool results.
- Разделить сценарии, где текст допустим, и сценарии с обязательным вызовом инструмента.
При разборе неудачного хода
Проверяйте событие в порядке прохождения по цепочке. Это не позволяет объяснить инфраструктурный сбой поведением модели без данных.
- Сопоставить raw output с итоговым полем tool_calls.
- Проверить сборку потокового ответа и работу парсера.
- Проверить имя инструмента по белому списку.
- Разобрать arguments как JSON и применить схему.
- Выполнить бизнес-валидацию прав, объекта операции и допустимого статуса.
- Зафиксировать факт запуска функции и подтверждённый outcome.
При восстановлении
Реакция должна соответствовать классу ошибки. Повторный запрос не является универсальным способом исправления любого отклонения.
- Для предполагаемой ошибки стриминга проверить контролируемый повтор без стриминга.
- Для невалидных аргументов вернуть модели структурированную ошибку валидации.
- Для отсутствия обязательного tool call использовать ограниченный repair-ретрай или fallback.
- Не повторять автоматически операцию, отклонённую политикой или правами.
- Для действий с побочным эффектом применять idempotency key, журнал операции и проверку фактического результата.
Источники
Частые вопросы
Доказывает ли жалоба на Hugging Face дефект DeepSeek-V4-Flash-0731?
Нет. Это публичный пользовательский сигнал, в котором нет полной методики, raw output, параметров генерации, версии inference-сервера и описания стриминга. Он является основанием для воспроизводимого теста, но не установленным диагнозом модели.
Почему tool_calls не гарантирует, что действие выполнено?
Структурированный вызов ещё должен быть распознан, пройти проверку имени функции, JSON, схемы, бизнес-правил и прав доступа. После этого приложение должно подтвердить фактический результат внешнего сервиса.
Что проверять, если агент не увидел вызов инструмента?
Нужно сохранить raw completion до преобразования SDK, результат сборки стрима и итог разбора. Корректный вызов в raw output при пустом tool_calls указывает на необходимость расследовать serving stack, парсер или адаптер.
Нужна ли валидация аргументов при использовании strict?
Да. Strict предназначен для согласованной структуры аргументов в пределах поддерживаемого подмножества JSON Schema, но не заменяет проверку прав, существования объекта, допустимого статуса операции и её последствий.
Как безопасно повторять tool call с побочным эффектом?
Нужно считать операцию потенциально выполненной даже при таймауте. Для повторов нужны idempotency key, журнал операции и проверка фактического outcome, иначе можно продублировать сообщение, заявку или другое действие.
Практический чек-лист
Практический чек-лист для команды
Чек-лист вынесен в отдельный PDF для сохранения и использования при расследовании сбоев tool calls.
До запуска теста
- Сохранить model ID, endpoint, версию сервера и SDK.
- Зафиксировать параметры генерации, режим стриминга и хэш доступного набора tools.
- Измерить полный размер prompt, включая системные инструкции, схемы, историю и tool results.
- Разделить сценарии, где текст допустим, и сценарии с обязательным вызовом инструмента.
При разборе неудачного хода
- Сопоставить raw output с итоговым полем tool_calls.
- Проверить сборку потокового ответа и работу парсера.
- Проверить имя инструмента по белому списку.
- Разобрать arguments как JSON и применить схему.
- Выполнить бизнес-валидацию прав, объекта операции и допустимого статуса.
- Зафиксировать факт запуска функции и подтверждённый outcome.
При восстановлении
- Для предполагаемой ошибки стриминга проверить контролируемый повтор без стриминга.
- Для невалидных аргументов вернуть модели структурированную ошибку валидации.
- Для отсутствия обязательного tool call использовать ограниченный repair-ретрай или fallback.
- Не повторять автоматически операцию, отклонённую политикой или правами.
- Для действий с побочным эффектом применять idempotency key, журнал операции и проверку фактического результата.
Вопросы и ответы
Доказывает ли жалоба на Hugging Face дефект DeepSeek-V4-Flash-0731?
Нет. Это публичный пользовательский сигнал, в котором нет полной методики, raw output, параметров генерации, версии inference-сервера и описания стриминга. Он является основанием для воспроизводимого теста, но не установленным диагнозом модели.
Почему tool_calls не гарантирует, что действие выполнено?
Структурированный вызов ещё должен быть распознан, пройти проверку имени функции, JSON, схемы, бизнес-правил и прав доступа. После этого приложение должно подтвердить фактический результат внешнего сервиса.
Что проверять, если агент не увидел вызов инструмента?
Нужно сохранить raw completion до преобразования SDK, результат сборки стрима и итог разбора. Корректный вызов в raw output при пустом tool_calls указывает на необходимость расследовать serving stack, парсер или адаптер.
Нужна ли валидация аргументов при использовании strict?
Да. Strict предназначен для согласованной структуры аргументов в пределах поддерживаемого подмножества JSON Schema, но не заменяет проверку прав, существования объекта, допустимого статуса операции и её последствий.
Как безопасно повторять tool call с побочным эффектом?
Нужно считать операцию потенциально выполненной даже при таймауте. Для повторов нужны idempotency key, журнал операции и проверка фактического outcome, иначе можно продублировать сообщение, заявку или другое действие.