Correct the erratum I published an hour ago: the engine hole it declared open was closed on 28 August, so only the cost of the pre-fix defect changes
This commit is contained in:
parent
d7a202edc6
commit
3fff642a43
2 changed files with 31 additions and 12 deletions
|
|
@ -155,7 +155,9 @@
|
|||
## Контент-фильтры / safety
|
||||
|
||||
- ⛔⛔ **Gemini, ДВА СИСТЕМНЫХ СООБЩЕНИЯ = ПРОМТ ТЕРЯЕТСЯ МОЛЧА (полигон 22.08, живая проба `eval/dovodka/proba_gemini.py`).** **МЕХАНИЗМ НАЗВАН** (вендор-дока `ai.google.dev/api/generate-content`): в нативном API `systemInstruction` — это ОДИН объект `Content`, поэтому слой ФИЗИЧЕСКИ не может пронести больше одного системного, и уход на нативный API проблемы НЕ решает — там пришлось бы склеивать так же. При двух и более лишние выбрасываются без ошибки. ⛔ **УСТАНОВЛЕНО 29.08: ВЫЖИВАЕТ ПОСЛЕДНЕЕ СИСТЕМНОЕ, ВЫБРАСЫВАЕТСЯ ПЕРВОЕ** (полигон, Д35.3 отчёта 23; $0, детерминированно, на 16 уже купленных клетках). Доказательство арифметическое: у арма `RE` первое системное (ролевой промт) **побайтно одинаково на всех 16 главах**, второе (глоссарий) — **разное** (255–404 знака, термины из текста главы); разность `RE.prompt_tokens − RQ.prompt_tokens` равна **2436 РОВНО на каждой из 16 глав, sd = 0.00** ⇒ выброшено сообщение ПОСТОЯННОГО размера, а таково только первое; будь выброшены оба, разность росла бы вместе с глоссарием. Побочно: `prompt_tokens` карантинных клеток коррелируют с длиной глоссария +0.52 и с длиной исходника +0.04 — глоссарий внутри них физически есть. ~~⚠ КАКОЕ именно выживает — НЕ УСТАНОВЛЕНО~~ — форум Google (discuss.ai.google.dev/t/86097, 30.05.2025) был ПРАВ, наша прошлая интерпретация «не выжило НИ ОДНО» неверна: она сравнила 535 токенов с «размером одного user-сообщения» на глаз, а при шкале 0.324 ток/знак русского глоссарий в 300 знаков весит ~100 токенов и в такой оценке теряется. Документированного вендором ограничения в разделе «Current limitations» НЕТ. Замер на одном и том же системном тексте в 7970 знаков: ОДНИМ сообщением → `prompt_tokens` 2994 и маркерная инструкция ИСПОЛНЕНА; ДВУМЯ → **535 токенов (это размер одного user-сообщения) и инструкция НЕ исполнена**. Ответ приходит с `finish=stop` и выглядит правильным переводом — отказа нет, есть тихая потеря инструкции, невидимая всем гейтам годности. ⚠ Так были куплены 16 клеток арма `RE` (промт-роль на gemini): они переведены ВООБЩЕ БЕЗ ИНСТРУКЦИИ, и вердикт о переносимости из них был бы ложным. Лечение: склеивать системные в одно ДЛЯ ЭТОГО ВЕНДОРА (`rol.ONE_SYSTEM`/`fit_msgs`) — общая склейка сменила бы форму запроса у всех моделей и рассогласовала бы уже купленные клетки. ⚠ Проверено, что у `deepseek-v4-pro`, `gpt-5.6-luna`, `glm-5` и `grok-4.3` два системных доезжают целиком.
|
||||
- ⛔⛔ **ТОТ ЖЕ ДЕФЕКТ ЖИВЁТ В ДВИЖКЕ, А НЕ ТОЛЬКО В ПОЛИГОНЕ (аудит 22.08).** `backend/internal/pipeline/render.go:256-258` штатно строит ВТОРОЕ системное сообщение — инъекцию банка памяти (глоссарий/STM), `backend/internal/llm/httpllm.go:517-522` копирует сообщения дословно, склейки под Gemini нет нигде, а `gemini-3.1-pro-preview` стоит в ратифицированной цепочке эскалации во ВСЕХ арм-конфигах (`pipeline-c1.yaml:129`, `pipeline-arm-glm.yaml:61`, `pipeline-arm-deepseek-pro.yaml:62`, `pipeline-arm-mistral.yaml:61`). ⇒ ~~**любой эскалационный хоп на Gemini при непустой инъекции ТИХО теряет глоссарий.**~~ ⛔⛔ **ФОРМУЛИРОВКА ИСПРАВЛЕНА 29.08 И СТАЛА ХУЖЕ, А НЕ МЯГЧЕ.** По установленному выше правилу выживает ПОСЛЕДНЕЕ системное, а `render.go:247-258` кладёт первым **сам промт стадии**, вторым — инъекцию банка. ⇒ **на эскалационном хопе в Gemini при непустой инъекции движок теряет НЕ глоссарий, а ВЕСЬ ПРОМТ СТАДИИ, и оставляет глоссарий.** Модель получает список канонных форм и текст — без единого слова о том, что с ними делать. Ровно так выглядят 16 клеток `RE`: перевод есть, `finish=stop`, русский, правильной длины, инструкции за ним нет. **Тихая потеря промта не отличима от нормального ответа ничем, кроме счётчика входных токенов.** Лечение прежнее (склейка системных под этого вендора), приоритет — выше. Оговорка D22.3 «экспозиция Ф1 нулевая» держится только на том, что до Gemini в дефолте не доходят. ⚠ Класс в проекте уже был решён рядом: `backend/internal/llm/provider_anthropic.go:169-179` сворачивает ведущий system-префикс в одно поле и падает громко на system посреди диалога — просто не обобщён на Gemini. **Зона бэкенда, пинг оркестратору отправлен.**
|
||||
- ⛔⛔ **ТОТ ЖЕ ДЕФЕКТ ЖИВЁТ В ДВИЖКЕ, А НЕ ТОЛЬКО В ПОЛИГОНЕ (аудит 22.08).** `backend/internal/pipeline/render.go:256-258` штатно строит ВТОРОЕ системное сообщение — инъекцию банка памяти (глоссарий/STM), `backend/internal/llm/httpllm.go:517-522` копирует сообщения дословно, склейки под Gemini нет нигде, а `gemini-3.1-pro-preview` стоит в ратифицированной цепочке эскалации во ВСЕХ арм-конфигах (`pipeline-c1.yaml:129`, `pipeline-arm-glm.yaml:61`, `pipeline-arm-deepseek-pro.yaml:62`, `pipeline-arm-mistral.yaml:61`). ⇒ **любой эскалационный хоп на Gemini при непустой инъекции ТИХО терял текст.** Оговорка D22.3 «экспозиция Ф1 нулевая» держалась только на том, что до Gemini в дефолте не доходят.
|
||||
✅ **ДЕФЕКТ ДВИЖКА ЗАКРЫТ 28.08 лендингом `7d0c6f2`** — проверено кодом 29.08, а не пересказано: у провайдера `gemini` объявлено `system_messages: single` (`backend/configs/models.yaml:137`=`system_messages: single`), адаптер склеивает ВЕДУЩИЙ system-ран в одно сообщение и падает громко на системном ходе после не-системного (`backend/internal/llm/httpllm.go:528`=`func toOpenAIMessages`), инвариант запинен тестом (`backend/internal/llm/systemmessages_test.go:78`=`TestSystemMessagesSingleCarriesTheInjection`). ⇒ строки выше про движок — ИСТОРИЯ, а не открытый долг.
|
||||
⛔ **НО ЦЕНА ДЕФЕКТА ДО ПОЧИНКИ ОЦЕНИВАЛАСЬ НЕВЕРНО, и это правится здесь (полигон 29.08, Д35.3).** По установленному выше правилу выживает ПОСЛЕДНЕЕ системное, а `render.go:247-258`=`Role: "system"` кладёт первым **сам промт стадии**, вторым — инъекцию банка. ⇒ до 28.08 хоп в Gemini терял **не глоссарий, а ВЕСЬ ПРОМТ СТАДИИ**, оставляя глоссарий: модель получала список канонных форм и текст — без единого слова о том, что с ними делать. Ровно так выглядят 16 клеток `RE` полигона: перевод есть, `finish=stop`, русский, правильной длины, инструкции за ним нет. **Тихая потеря промта не отличима от нормального ответа ничем, кроме счётчика входных токенов.** ⇒ решение «склеивать самим» было единственно верным и при неизвестном тогда чтении квирка; а любой ИСТОРИЧЕСКИЙ вывод, снятый на Gemini-хопе до 28.08, надо читать как «стадия работала без своего промта». ⚠ Класс в проекте уже был решён рядом: `backend/internal/llm/provider_anthropic.go:169-179` сворачивает ведущий system-префикс в одно поле и падает громко на system посреди диалога — просто не обобщён на Gemini. **Зона бэкенда, пинг оркестратору отправлен.**
|
||||
- **Gemini**: `safety_settings` через OpenAI-совместимый слой **не передаются** (HTTP 400 «Unknown name safety_settings»). Дефолт фильтров у 2.5/3 — OFF (gap-2). Для явного контроля фильтров (роль судьи 18+) нужен **нативный** Gemini API, не OpenAI-слой. ⚠ **D22.6: на ГРАФИЧНОЙ эротике Gemini 3.x fail-closed `PROHIBITED_CONTENT` (8× wire-verified, exp11) — фильтр НЕконфигурируем, нативный API не спасает; судья эротики — только Grok. На violence/SFW Gemini-судья жив.** `finish_reason` приходит СОСТАВНОЙ строкой `'content_filter: PROHIBITED_CONTENT'` (точные матчеры мертвы — D22.8а). Биллинг Gemini: thinking ТОЛЬКО в `total_tokens` → `reasoning: additive_total`, иначе недоучёт 146×/вызов (D22.3). Нативное имя поля — `usageMetadata.thoughtsTokenCount`; слой AI-Studio `completion_tokens_details.reasoning_tokens` не отдаёт ВОВСЕ, тогда как Vertex AI то же поле отдаёт (форум 15.01.2026) — при переезде на Vertex учёт менять. ⚠⚠ **`reasoning_tokens=0` у Gemini — НОРМА, а не измерение: вывод «размышление выключено» из этого поля НЕДЕЙСТВИТЕЛЕН.** Полигон 22.08 на этом и поскользнулся, объявив «вендор-дефолт flash-lite = размышление ВЫКЛ (замерено)»; считать надо `total − prompt − completion`. ⚠ **В роли редактора Gemini течёт сервис-преамбулой в выход («Вот отредактированный…», 6/6 чанков — exp12) → за output-санитайзером D30.3.** ⚠ **Дополнение эксп-21 (08.08):** fail-closed ответ OpenAI-слоя приходит вовсе БЕЗ объекта `message` (не с пустым `content`) — парсер обязан переживать его отсутствие; на вебновелльном violence-материале срабатывания массовые (10 клеток судейского прогона с `content_filter: PROHIBITED_CONTENT`) ⇒ оговорка «на violence/SFW Gemini-судья жив» целиком НЕ держится — Gemini непригоден как ЕДИНСТВЕННЫЙ второй контур на этом материале (эксп-21 §1/§8).
|
||||
- **Qwen Model Studio**: внешний фильтр `data_inspection_failed` на вход/выход, неотключаем (риск молчаливых вырезаний) — не тестировано (нет ключа).
|
||||
- Детект отказов/вырезаний — см. `eval/refusal_bench.py` (паттерны soft-отказа + coverage-гейт по len_ratio/sent_cov, пороги в эксп. 02).
|
||||
|
|
|
|||
|
|
@ -5172,7 +5172,7 @@ fable-5: медиана ρ +0.52 · среднее +0.55 · глав согла
|
|||
|
||||
### Д35.2 ⛔ ПЕРЕЕЗД ОБНУЛИЛ mtime, И ОДИН ГЕЙТ ФАЗЫ БОЛЬШЕ НЕ ПЕРЕ-СНИМАЕТСЯ
|
||||
|
||||
`eval/tenant_panel/verify22.py:174-185` выводит верхнюю границу двойной оплаты Ф2 как «сумма
|
||||
`eval/tenant_panel/verify22.py:174-185`=`граница двойной оплаты` выводит верхнюю границу двойной оплаты Ф2 как «сумма
|
||||
клеток, купленных ДО коммита атомарного замка `fd3e522`», и отделяет «до» от «после»
|
||||
**временем файла на диске**. После переезда **все 335 клеток Ф2 имеют ОДИН И ТОТ ЖЕ mtime**
|
||||
(проверено: `уникальных mtime: 1`), причём поздний. ⇒ граница считается как `$0.000000`,
|
||||
|
|
@ -5184,7 +5184,7 @@ fable-5: медиана ρ +0.52 · среднее +0.55 · глав согла
|
|||
из сырья больше НЕ ВЫВОДИМА ничем.
|
||||
⇒ **R71 объявляется НЕ ПЕРЕ-СНИМАЕМЫМ на этой машине.** Гейт не правится под зелень (D39.121):
|
||||
подгонка спрятала бы ровно тот факт, что провенанс покупок держался на файловой системе.
|
||||
⚠ **Класс шире одного гейта:** `runs.py:166` и `role_topology/absjudge.py:323` атрибутируют
|
||||
⚠ **Класс шире одного гейта:** `eval/dovodka/runs.py:166`=`def judge_of` и `eval/role_topology/absjudge.py:323`=`path.stat().st_mtime` атрибутируют
|
||||
судью ответу тем же способом — по mtime файла ответа. Для БУДУЩИХ чтений это работает (файлы
|
||||
пишутся сейчас), для исторических — атрибуция утрачена там же и тогда же.
|
||||
⇒ **Норма на будущее: время покупки и время ответа писать ПОЛЕМ В АРТЕФАКТ.** Файловая система —
|
||||
|
|
@ -5217,20 +5217,37 @@ RE.prompt_tokens − RQ.prompt_tokens = 2436 на КАЖДОЙ из 16 гла
|
|||
user-сообщения» на глаз. 2 436 токенов на 7 525 знаков русского — это 0.324 ток/знак; при такой
|
||||
шкале глоссарий в 300 знаков весит ~100 токенов и в оценке «на глаз» просто теряется.
|
||||
|
||||
**⛔ И это меняет вывод про ДВИЖОК в худшую сторону.** `backend/internal/pipeline/render.go:247-258`
|
||||
кладёт первым `system` — **сам промт стадии**, вторым `system` — инъекцию банка (глоссарий/STM).
|
||||
Записанное следствие звучало как «эскалационный хоп на Gemini тихо теряет глоссарий»
|
||||
(`00-provider-quirks.md:158`). По установленному правилу всё наоборот:
|
||||
**⛔ И это правит записанную ЦЕНУ движкового дефекта — но не открывает его заново.**
|
||||
`backend/internal/pipeline/render.go:247-258`=`Role: "system"` кладёт первым `system` — **сам промт
|
||||
стадии**, вторым `system` — инъекцию банка (глоссарий/STM). Записанное следствие звучало как
|
||||
«эскалационный хоп на Gemini тихо теряет глоссарий» (`00-provider-quirks.md:158`). По
|
||||
установленному правилу всё наоборот:
|
||||
|
||||
> **на эскалационном хопе в Gemini при непустой инъекции банка движок теряет НЕ глоссарий, а ВЕСЬ
|
||||
> ПРОМТ СТАДИИ, и оставляет глоссарий.**
|
||||
> **до починки эскалационный хоп в Gemini при непустой инъекции терял НЕ глоссарий, а ВЕСЬ ПРОМТ
|
||||
> СТАДИИ, и оставлял глоссарий.**
|
||||
|
||||
То есть модель получает список канонных форм и текст — без единого слова о том, что с ними делать.
|
||||
То есть модель получала список канонных форм и текст — без единого слова о том, что с ними делать.
|
||||
Ровно это и произошло с 16 клетками `RE`, и ровно так они выглядят: перевод есть, `finish=stop`,
|
||||
русский, правильной длины — и никакой инструкции за ним. **Тихая потеря промта не отличима от
|
||||
нормального ответа ничем, кроме счётчика входных токенов.**
|
||||
⇒ Пинг оркестратору (зона бэкенда): лечение прежнее — склейка системных под этого вендора, — но
|
||||
**приоритет и формулировка дефекта в бэклоге неверны и подлежат правке**.
|
||||
|
||||
✅ **ДЕФЕКТ ДВИЖКА УЖЕ ЗАКРЫТ, И Я ЭТО ПРОВЕРИЛ КОДОМ, А НЕ ПРЕДПОЛОЖИЛ.** Лендинг `7d0c6f2`
|
||||
(28.08) ввёл ось `Capability.SystemMessages`: у провайдера `gemini` стоит
|
||||
`backend/configs/models.yaml:137`=`system_messages: single`, адаптер склеивает ВЕДУЩИЙ system-ран в
|
||||
одно сообщение и громко падает на системном ходе после не-системного
|
||||
(`backend/internal/llm/httpllm.go:528`=`func toOpenAIMessages`), инвариант запинен тестом
|
||||
(`backend/internal/llm/systemmessages_test.go:78`=`TestSystemMessagesSingleCarriesTheInjection`).
|
||||
⚠ Первая редакция ЭТОГО ЖЕ абзаца, написанная час назад, объявляла дефект живым и слала пинг в
|
||||
бэкенд — она стояла на строке `00-provider-quirks.md:158`, устаревшей на один день.
|
||||
**Класс ошибки тот же, что фаза ловит у себя постоянно: доверился заголовку дока вместо кода.**
|
||||
Поймано собственной сверкой до публикации вывода, но ПОСЛЕ того, как формулировка уже уехала
|
||||
в коммит `a6c50fc` — поэтому исправление стоит здесь, а история не переписывается.
|
||||
|
||||
⇒ **Что находка меняет по существу:** (а) закрывает открытое расхождение в квирк-доке;
|
||||
(б) подтверждает, что «склеивать самим» было верным решением и при тогда ещё неизвестном чтении
|
||||
квирка — оно не могло потерять текст ни при каком ответе на вопрос «какое выживает»;
|
||||
(в) **любой ИСТОРИЧЕСКИЙ результат, снятый на Gemini-хопе до 28.08, надо читать как «стадия
|
||||
работала без своего промта»** — включая 16 клеток `RE` этой фазы.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue