178 lines
70 KiB
Markdown
178 lines
70 KiB
Markdown
# 00. Провайдерские грабли — справочник для адаптеров
|
||
|
||
Назначение: единый список практических особенностей LLM-провайдеров, найденных полигоном при живых вызовах. **Бэкенд-сессия читает это напрямую** при написании/правке адаптеров `internal/llm`, чтобы не переоткрывать в Go то, что уже поймано в Python. Дата: 2026-07-04, проверять при смене версий моделей.
|
||
|
||
Разделение ролей: полигон (`eval/`, Python) — тупой замерочный зонд, характеризует **сырое поведение** провайдера (отказ/качество/латентность); бэкенд (`backend/internal/llm`, Go) — продакшн-адаптеры (retry/failover/ledger). Код не общий (разные языки) и не должен быть — но знание о граблях общее и живёт здесь.
|
||
|
||
**⚠ ПРАВИЛО ДВУХ НАПРАВЛЕНИЙ (решение владельца 10.07, после Gemini-кейса):** (1) клейм о поведении модели → проверяй живой пробой (уже было правилом); (2) **аномалия на проводе (интермиттентные 4xx/5xx, «model no longer available», новый/неожиданный `finish_reason`, молча игнорируемые параметры) → СНАЧАЛА официальная дока вендора (deprecations / changelog / status page) + свежий /models-листинг, ПОТОМ диагноз.** Не гадать и не абсорбировать интерпретацию аномалии в доки/промты/адаптеры без вендор-сверки с датой и URL. Прецедент: 404-флейки gemini-2.5-flash интерпретировались вслепую, а офиц. дока сразу давала ответ — вся 2.5-серия EOL 16.10.2026 (см. календарь ниже).
|
||
|
||
## Эндпоинты и модели (OpenAI-совместимые, если не указано иное)
|
||
|
||
| Провайдер | base_url | Модель (на 2026-07-04) | env-ключ |
|
||
|---|---|---|---|
|
||
| DeepSeek | `https://api.deepseek.com/v1` | **`deepseek-v4-flash`** + `deepseek-v4-pro` — и это **ВЕСЬ** листинг (live 25.07.2026). **Катовер ИСПОЛНЕН:** `deepseek-chat`/`deepseek-reasoner` сняты не только из листинга, но и из реестра — `GET /v1/models/deepseek-chat` → **404 `Model Not Found`**, алиас-оговорка календаря на них больше НЕ распространяется. Цены пост-катовера НЕ изменились (25.07: flash $0.14/$0.28 cache-hit $0.0028 · pro $0.435/$0.87 cache-hit $0.003625) — `models.yaml` актуален. Эхает zh — см. ниже, брать v4-flash с thinking | `DEEPSEEK_API_KEY` |
|
||
| xAI Grok | `https://api.x.ai/v1` | **`grok-4.3`** *(→ D30.1: из роли РЕДАКТОРА reasoning-off СНЯТ — no-op, exp12; grok — эскалация канала B reasoning-ON и судья 18+, не дефолт-редактор)* (для thinking-OFF слать явный `reasoning_effort:"none"` — см. thinking-таблицу ниже; слаг НЕ меняем на non-reasoning вариант — он = grok-4.3+`none` под капотом, ретайр 15.05.2026). `grok-4-fast` не в /v1/models, но работает как алиас (HTTP 200). | `XAI_API_KEY` |
|
||
| GLM (Z.ai) | `https://api.z.ai/api/paas/v4` | `glm-4.5-air` (дёшево) / `glm-4.6`; в /models: glm-4.7, glm-5, glm-5.1, glm-5.2 | `ZAI_API_KEY` |
|
||
| Gemini | `https://generativelanguage.googleapis.com/v1beta/openai` | `gemini-2.5-flash`, `gemini-2.5-pro`, `gemini-3.1-pro-preview` | `GEMINI_API_KEY` |
|
||
| Kimi (Moonshot) | `https://api.moonshot.ai/v1` (intl, **не** `.cn`) | `kimi-k2.6` (доступны k2.5, k2.7-code) | `KIMI_API_KEY` |
|
||
| OpenAI | `https://api.openai.com/v1` | `gpt-5-mini` | `OPENAI_API_KEY` |
|
||
| Qwen (DashScope intl) | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `qwen-flash` | `DASHSCOPE_API_KEY` |
|
||
| OpenRouter | `https://openrouter.ai/api/v1` | зависит от хостера | `OPENROUTER_API_KEY` |
|
||
| Локаль (ollama) | `http://localhost:11434/v1` (chat) или `/api/generate` | тег модели | не нужен |
|
||
|
||
## Thinking / reasoning — главный источник граблей
|
||
|
||
У всех современных моделей режим «размышления» включён по умолчанию и **ломает роль переводчика**: рассуждения съедают бюджет вывода → перевод обрезается или пустой, латентность ×3–5. **Для роли переводчика/редактора reasoning обязателен к управлению.** Как — зависит от провайдера:
|
||
|
||
| Провайдер | Поведение по умолчанию | Как управлять (для перевода) |
|
||
|---|---|---|
|
||
| **DeepSeek v4-flash** | гибридная reasoning-модель, thinking ON по умолчанию | **Управление (официальные доки, api-docs.deepseek.com/guides/thinking_mode, проверено 04.07): в body `extra_body={"thinking":{"type":"enabled"\|"disabled"}}`** (дефолт enabled). Т.е. выключить МОЖНО, параметр есть. НО для роли ПЕРЕВОДЧИКА не выключать: `disabled`→non-thinking режим, который на плотном CJK **ЭХАЕТ исходник**. Оставлять thinking ВКЛ; reasoning→`reasoning_content`, `content` чистый; ~~`max_tokens` ≥8000~~ **→ см. строку 0731 ниже: флор 8000 ПРОБИТ**. ⚠ **thinking-режим НЕ поддерживает `temperature`/`top_p`/penalties** (шлём — молча игнорируются). ~~`reasoning_effort`: только `high`/`max` (low/medium→high, xhigh→max)~~ **→ УСТАРЕЛО, см. строку 0731**; `none` в OpenAI-формате НЕ существует → 400. Для дешёвой роли ЭКСТРАКЦИИ (не перевод) thinking можно выключить — echo бьёт по переводу, не по JSON-выводу (перепроверить). |
|
||
| GLM-4.5-air / 4.6 | thinking ON, не влезал в 180с | отключить: `extra_body: {"thinking": {"type": "disabled"}}` |
|
||
| Gemini 2.5 Flash | thinking ON, съедал `max_tokens`, **молча обрезал перевод** | отключить: `extra_body.google.thinking_config.thinking_budget: 0` |
|
||
| **Gemini 3.1 Pro** | thinking **обязателен** | `thinking_budget:0` → HTTP 400 «only works in thinking mode». НЕ отключать; дать большой `max_tokens` (≥8000) |
|
||
| gpt-5-mini (reasoning) | reasoning ON, выжигал бюджет → пустой ответ | `reasoning_effort: "minimal"`; **без `temperature`**; `max_completion_tokens` вместо `max_tokens` |
|
||
| **gpt-5.4 (reasoning)** | ⚠ **`reasoning_effort:"medium"` РЕПРОДУЦИРУЕМО ОБРЕЗАЕТ ВЫВОД на длинной редактуре** (exp14b: reasoning съел бюджет → `content` 223 out-ток ≈ 602 симв из ~5000, `finish=stop` — выглядит как валидный короткий ответ, НЕ length-обрыв → тихо портит результат) | В роли РЕДАКТОРА/переводчика (длинный выход) слать **`reasoning_effort:"low"`** (exp14b: тот же чанк → 5137 симв, полный); `max_completion_tokens` (не `max_tokens`), без `temperature`. reasoning⊆completion (subset-биллинг). Слаг live-фактчек 2026-07-11: `gpt-5.4-2026-03-05`. *(Верифицировано span-читкой D38; self-review полигона поймал живьём.)* |
|
||
| **Kimi K2.6** | думающая, **очень многословная**: ~11k reasoning-токенов на абзац; reasoning в `reasoning_content`, ответ в `content`; при малом бюджете reasoning съедает лимит → `content` **пуст** (finish=length, не ошибка!) | дать `max_tokens` ≥16000; ответ из `content`. **Дорогой в роли редактора** — reasoning биллится как выход |
|
||
| **grok-4.3 (xAI)** | reasoning **ON по дефолту = `low`** (must-be-explicit: не задал → думает) | **Off-switch (Chat Completions) — ПЛОСКИЙ `reasoning_effort:"none"` в теле** (`reasoning_effort` ∈ {none,low,medium,high}). ⚠ **Вложенная форма `extra_body.reasoning.effort:"none"` — это Responses API; Chat Completions её МОЛЧА ГЛОТАЕТ** (остаётся дефолт `low`) — из-за этого exp08-проба ложно решила «не отключается». Проверено 05.07: `reasoning_effort:"none"`→`usage.reasoning_tokens=0`, дефолт→444, `low`→384 (на правке ~2000 ток.). reasoning у xAI **аддитивен к completion** (billed = completion+reasoning). `grok-4.20-0309-non-reasoning` = grok-4.3 + `effort:none` под капотом (ретайр 15.05.2026) → слаг не нужен, слать `none` явно. ⚠ **Для роли РЕДАКТОРА reasoning-off СНЯТ (D30.1): grok reasoning-off — no-op-редактор** (exp12 §2.2: активность 0.001, 3/6 чанков байт-идентичны черновику; exp04-ранг был на дефолт-reasoning + БИЛИНГВ). Если grok когда-либо вернётся в редакторы — только reasoning-ON (D6.2-буфер). Для роли ПЕРЕВОДЧИКА на плотном CJK reasoning-off НЕПРИГОДЕН (D19.1: эхо 4/10 + дегенеративный луп; ⚠ языковой констрейнт в system при `none` ИНВЕРТИРУЕТ эхо 3/10→9/10 — research/15 P4) — эскалация канала B идёт reasoning-ON. *(Сужено оркестратором по D19.1/D21; было «editor/translator».)* Источник: docs.x.ai/developers/model-capabilities/text/reasoning. |
|
||
| Qwen3.5 / локальные | thinking ON | ollama: `think: false` + `num_predict` cap. Иначе рассуждения (в поле `thinking`, не `response`) забивают контекст |
|
||
|
||
### ⚠ `deepseek-v4-flash` → `DeepSeek-V4-Flash-0731`: слаг стабилен, ВЕСА СМЕНИЛИСЬ (полигон, 2026-07-31)
|
||
|
||
**Вендор-факт** (`api-docs.deepseek.com/updates`, запись `Date: 2026-07-31`; снято `curl`, счёт вхождений = 1 по копии без пробелов): *«The official release of the DeepSeek-V4-Flash API is now in public beta. The API calling method remains unchanged — simply set the model name to `deepseek-v4-flash` to use the latest version.»* · *«DeepSeek-V4-Flash-0731 keeps the same model architecture and size as DeepSeek-V4-Flash-Preview, and was only re-post-trained.»* · *«Significantly enhanced **agent** capabilities…»* · *«Note: This update only upgrades the DeepSeek-V4-Flash API. The DeepSeek-V4-Pro API and the APP/WEB models are unchanged.»* ⇒ **v4-pro (редактор, эскалационный хоп) ВЕСАМИ не тронут.** В `/v1/models` ничего не изменилось — там прежние два слага. **Урок календаря: «слаг живой» ≠ «модель та же»; версию проверять поведением, а не листингом.**
|
||
⚠ **У «v4-pro не тронут» есть срок годности (вписано оркестратором 02.08, D39.86):** та же страница `guides/thinking_mode` несёт сноску *«We will update the actual mapped effort of `deepseek-v4-pro` in early August 2026»* — то есть ПРЯМО СЕЙЧАС. Веса пока прежние, но вендор объявил смену МАППИНГА ЭФФОРТА у pro; любой довод формы «берём pro, он не тронут» обязан нести эту оговорку и пере-проверяться пробой, а не changelog'ом (changelog на 02.08 новее 31.07 записей не имеет — сверено оркестратором `curl`, HTTP 200).
|
||
|
||
1. **ФЛОР 8000 ПРОБИТ — боевая форма отдаёт ПУСТОЙ `content`.** Живьём 31.07 18:54 UTC: черновая волна боевым `translator.md` при `max_tokens=8000` дала `finish=length`, `completion_tokens=8000`, `content` = 0 символов на **4 чанках из 4**. ⚠ **Сравнение с холодным прогоном (2 из 68) НЕ является чистым контролём и понижено до индикативного:** тот ехал ДРУГИМ промптом (`translator-banknote.md`) и с ДРУГИМ потолком (`max_tokens=8496`). Несущая улика — не оно, а СОБСТВЕННЫЕ пробы провода: **один и тот же чанк, один и тот же рендер, cap 8000 → `length`+пусто, cap 16000 → `stop`+перевод** (таблица п.2). *(Испр. 31.07 по ревью.)*
|
||
2. **Механизм — не дегенеративный луп, а многословная обдумка.** 20 025 симв. `reasoning_content` = 122 строки, все уникальны: модель пере-переводит фразу за фразой внутри размышления и не доходит до ответа. Наблюдённый `reasoning_tokens` **на одном и том же чанке** (`chunk-1-0`, дефолтный эффорт): **98 · 8000⌐ · 14014 · 16000⌐** (⌐ = упор в потолок) — разброс ×163 при побайтно одном входе. На двух других чанках: 3117 и 16001⌐. **Хвост тяжёлый: при потолке 16000 упор случился в 2 пробах из 5.** *(Испр. 31.07 по ревью: прежняя формулировка смешивала три чанка в один ряд и пробу с потолком 8000 в знаменатель 16000.)*
|
||
3. **`reasoning_effort` — запись 04.07 устарела.** Вендор-дока `guides/thinking_mode` (снята 31.07, счёт = 3) разделяет **тумблер** `{"thinking":{"type":"enabled/disabled"}}` и **эффорт** `{"reasoning_effort":"low/high/max"}`: `low` — отдельный документированный уровень. Замер: `low` при потолке 8000 и temperature 0.3 → `finish=stop`, reasoning **170–313** ток., **$0.00036–0.00091** за вызов (без ручки — $0.0022–0.0045 за пустой ответ).
|
||
**3а. ДЕФОЛТ ЭФФОРТА = `high`, и маппинг per-модельный** (дословно с той же страницы, снято `curl` HTTP 200 бэкендом 02.08 и пере-снято оркестратором при приёмке): *«Thinking mode is enabled by default, **with the default effort being high**»*. Таблица маппинга «запрошенный эффорт → фактический»:
|
||
|
||
| Запрошено | `deepseek-v4-flash` | `deepseek-v4-pro` |
|
||
|---|---|---|
|
||
| `low` | **`low`** | **`high`** |
|
||
| `high` | `high` | `high` |
|
||
| `xhigh` | `high` | `max` |
|
||
| `max` | `max` | `max` |
|
||
|
||
⇒ (i) **не слать `reasoning_effort` = ехать на `high`** — вот почему боевая форма упирается в стену (п.10); (ii) **на `deepseek-v4-pro` ручка `low` — НЕ РАБОТАЕТ** (маппится в `high`): рычаг бюджета размышления существует ТОЛЬКО у flash, и любой план «перевести роль на pro и придушить эффорт» несостоятелен; (iii) `none` в OpenAI-формате у DeepSeek не существует вовсе (колонка `reasoning.effort:"none"` — Anthropic-формат), запись 04.07 «`none` → 400» в силе.
|
||
4. **⚠ `effort:"low"` ПЕРЕ-ВООРУЖАЕТ эхо-мину:** 1 чистый китайский выход из 16 базовых вызовов (`cjk_share 0.83`, `finish=stop`). **Уточнение рамки D19.2: защита от эха деградирует НЕПРЕРЫВНО с эффортом, а не скачком на «выключено».** ⚠ **Хвост «движок эту ручку слать не может — `echoMineViolation`» ОТОЗВАН (оркестратор 02.08 по коду, D39.86): движок её слать МОЖЕТ.** Гейт (`config/models.go:485-501`) инспектирует МЕХАНИЗМ (`capabilities.reasoning.control` ∈ {`extra_body_disable`, `effort`} + thinking-ключ в `extra_body`), а не значение `stage.reasoning`; у deepseek `control = ReasoningNone`, где `off`/`""` — осознанный no-op, а `low|medium|high` уходят на провод как есть (`llm/capability.go:167-171`). Конфиг `stages[draft].reasoning: "low"` грузится без ошибки и доезжает до провода — проверено исполнением (coldrun-b §3.3). ⇒ **вопрос «включать ли `low`» — экономико-качественный (эхо растёт), а не «нельзя технически»; амендмент гейта для этого НЕ нужен.**
|
||
5. **Микро-few-shot: ⚠ ПРЕЖНЯЯ ФОРМУЛИРОВКА ОТОЗВАНА (31.07, адверсариальное ревью).** Числа «reasoning ×1.9» и «постинструкция дешевле на 23.3%» получены НЕПАРНЫМ сравнением средних на распределении, чей разброс ×163 (п.2). **Парный пересчёт по тем же 12 фрагментам:** few-shot думает МЕНЬШЕ базы на **7 из 12** (медиана Δ **−65** ток., знаковый тест p=0.77); постинструкция думает БОЛЬШЕ базы на **9 из 12** (медиана Δ **+208**, p=0.15). «+91%» — артефакт четырёх попаданий в хвост. Скидка постинструкции на 58% состоит из ПРЕФИКСНОГО КЭША (её `system` побайтно равен базовому — sha `e9ea1ae7dae0`, постинструкция уходит в USER-хвост; кэш 95.0% против 27.5% у базы); при пересчёте по некэшированной цене остаётся −9.0%. **Что устояло:** суммарная цена арма few-shot на этой выборке +28.4% и без кэш-эффекта, и **единственный за 48 вызовов выход НА АНГЛИЙСКОМ** (5 770 симв, `finish=stop`) — его. Эхо в том же арме НЕ атрибутируется few-shot (см. п.6).
|
||
6. **⚠ ЭХО НА 0731 СТОХАСТИЧНО ПО ВЫЗОВУ, а не детерминировано по фрагменту** — прямая улика: два вызова с **побайтно идентичным запросом** (sha `5c304c9b3cf4`, `effort:low`, cap 8000, temp 0.3) дали `cjk_share 0.000` и `cjk_share 0.831`. **Это отменяет посылку строки ниже («ретраи не помогают — детерминировано для фрагмента»), снятую на `deepseek-chat`, и посылку комментария `disposition.go:138-148` («retry just re-produces them»), из-за которой `cjk_artifact` идёт СРАЗУ в эскалацию.** Арифметика ремонта перевернулась: эскалация на v4-pro = **$0.007335 за ОДНО эхо** ($0.014670 холодного прогона — это ДВА эха на разных чанках, id 58 и 62), простой ре-ген на flash при `effort:low` = **$0.00096** (**≈7.6×** дешевле). Предложение бэкенду: N=1 ре-ген ПЕРЕД эскалацией. Гейт не ослабляется — D19.2 цел.
|
||
7. **Разгон думания привязан к ПЛОТНОМУ ХАНЬСКОМУ ВХОДУ, не к модели вообще.** Тот же промпт и параметры (cap 8000, дефолтный эффорт): **en** (877 ток. входа) → `stop`, reasoning **435**; **zh короткий** (776 ток.) → `stop`, reasoning **3393**; **zh длинный** (1679 ток.) → `length`, reasoning **8000⌐**, `content` пуст. При сопоставимом входе zh требует **×7.8** размышления против en ⇒ конфаунд длины закрыт. Границы: en n=1, zh-короткий n=1, zh-длинный n=8; **ja не проверялся**.
|
||
8. **Вендорская рамка бюджета вывода** (`quick_start/pricing`): контекст 1M, **max output 384K**, и *«For the high and max reasoning effort levels, a maximum output length of 384K tokens is recommended»*. Наш флор 8000 — **на два порядка ниже** вендорской нормы для высокого эффорта ⇒ дело не в «поломке», а в смещении ДЕФОЛТНОГО эффорта при нашей калибровке под прежний чекпойнт. Багрепортов о регрессии в открытом поиске нет (31.07).
|
||
9. **Движковый леджер `reasoning_tokens` для deepseek держит 0 СОЗНАТЕЛЬНО** (`provider_openai.go:22-24`, `ReasoningSubset` — thinking внутри `completion_tokens`, иначе двойной счёт). Длину думания видно только на сыром проводе — при диагностике идти туда, а не в `request_log`.
|
||
10. **БОЕВАЯ ФОРМА, замер бэкенда 02.08 (coldrun-b, ре-проба строки 74; принято D39.86).** Всё ниже снято САМИМ боевым путём `tmctl translate`, не ригом:
|
||
- **«Поднять флор до 16000» ФАЛЬСИФИЦИРОВАНО.** При боевом `max_tokens=8496` (флор 8000 + `bankTokenBudget` 496) — **0 из 9** свежих вызовов пригодны (8 пусто + 1 обрывок 993 симв., все `finish=length`, `completion` ровно в потолок). На движковом удвоении до 16992 — **4 из 5 тоже пустые**; сырые тела: `reasoning_content` 15 424 → 21 528 симв., то есть добавка потолка уходит в думание. Механизм п.2 подтверждён на боевой форме при ~100% частоте. Сходиться некуда: вендорская норма вывода для `high` — 384K (п.8), ×45 к флору.
|
||
- **`reasoning_effort:"low"` возвращает волну к жизни:** 20 из 22 свежих черновых вызовов `finish=stop`, 18 из 20 чанков отгружено, латентность 9–44 с против 67–190 с. Цена — ниже; эхо — выше (см. следующий пункт).
|
||
- **⚠ ЭХО-МИНА ПРИ ВЫКЛЮЧЕННОМ THINKING ЖИВА НА ВЕСАХ 0731 — клейм пере-подтверждён, а не унаследован** (проба C, вендорский тумблер `extra_body {"thinking":{"type":"disabled"}}` в КАРАНТИННОЙ копии models.yaml вне git; боевой конфиг и гейт не тронуты): **эхо 4/20** против 3/20 у `effort:low` и 0 пустых из 22 вызовов. Это важно: вся прежняя эмпирика флага `echoes_when_thinking_off` была снята на весах `V4-Flash-Preview`, которых больше нет (п. «Вся эмпирика P4» ниже) — теперь клейм имеет носителя на ЖИВЫХ весах. Флаг остаётся оправданным. На N=20 разница 15% vs 20% статистически неразличима: направление согласуется с «непрерывной деградацией защиты» (п.4), но не разделяет её.
|
||
- **Новый класс дефекта: выход на ТРЕТЬЕМ языке.** При `effort:low` 1 черновик из 18 пришёл полным связным переводом **на английский** (`finish=stop`, кириллица 0.000) и прошёл гейт черновой стадии как `ok` — `classify` экранирует ИСХОДНУЮ письменность, пустоту, обрыв и отказ, а «не исходный и не целевой» не ловит ни один предикат (движковая сторона — бэклог 46). При `high` и при thinking-off таких 0/18. Класс совпадает с единственным английским выходом 31.07 (п.5).
|
||
- **Терминолог 0731 упирается в ту же стену и ручкой НЕ лечится:** 4 батча из 5 вернулись `length` с `completion=8000` ровно и пустым телом (на coldrun-a до смены весов было 21/21 `stop`), банк консолидировал 1 терм из 81. Причина движковая, не вендорская: бэнк-роли не имеют ручки эффорта вовсе (бэклог 104) ⇒ **всегда едут вендор-дефолтом `high`**. При выключенном thinking стадия здорова (5/5) — это единственная из трёх замеренных конфигураций, где банк работает без правки Go.
|
||
|
||
*(Полигон, отчёт `archive/reports/POLYGON_PROMPTLANG_ANTIECHO_2026-07-31.md`; харнесс `eval/promptlang/`. Пункты 3а и 10 — бэкенд-сессия coldrun-b, `archive/reports/COLDRUN_B_DEBUG_2026-08-02.md`, внесено оркестратором при приёмке D39.86. Развилка «поднять флор / разрешить `low` / ждать / сменить модель» — за подписью владельца.)*
|
||
|
||
**Находка (эксп. 03):** reasoning реально улучшает реалии/имена в переводе (羅生門: «Радзёмон»→«Рашо-мон»), но локально нежизнеспособен (8.6 мин/фрагмент). **Открытый вопрос для бэкенда: проверить think-ON на быстром облачном черновике/редакторе как рычаг качества.**
|
||
|
||
### Эхо как свойство КЛАССА, не квирк вендора (обобщение D19.2 / D21.9)
|
||
|
||
**«reasoning-off + плотный CJK-вход = зона эха».** Это свойство **класса** reasoning-моделей, а НЕ квирк отдельного вендора: воспроизведено на deepseek (non-thinking режим, `00`-эхо-бюллетень выше) и на **обоих** слагах grok при `reasoning_effort:"none"` (exp10/D19.1: 4/10 verbatim-эхо + 1 дегенеративный луп на zh-фрагментах насилия, `reasoning_tokens=0`; контроль тех же фрагментов при reasoning-ON — 0/10 эха, `reasoning_tokens>0`). Механика одна: без цепочки рассуждений модель на плотной CJK-прозе возвращает исходник вместо перевода — **валидный HTTP 200 с неправильным содержимым** (не ошибка API, не `content_filter`; ретраи не спасают, эхо стохастично per-fragment). Следствия:
|
||
- **Для роли ПЕРЕВОДЧИКА на плотном CJK reasoning-off непригоден в принципе** (не только у одного вендора) — канал B переводит reasoning-ON (grok) либо не-reasoning-моделью без эхо-мины (Mistral: проба zh→ru чисто, `cjk_share=0`). ⚠ **Register-оговорка (exp11/D22, дописано оркестратором):** reasoning-ON снимает эхо на СОВРЕМЕННОЙ прозе (совр. zh-вебновелла 0/10, совр. ja 1/6, en 0/6), но НЕ на архаичной плотно-ханьской (金瓶梅, минский байхуа: grok-ON эхо 4/6 при `reasoning_tokens` 349–847; ON vs OFF там неразличимы) — эскалацию на grok-ON не считать лекарством от эха на архаичных zh-текстах; Mistral на той же архаике чист 6/6.
|
||
- **Downstream echo-гейт (`untranslated_echo`, `cjk_share>0.15`) обязателен НАВСЕГДА** и промпт-митигациями НЕ заменяется — это последняя линия против тихого провала.
|
||
- ⚠ **thinking-ON НЕ исключает эхо даже на современной прозе (живой прогон 31.07, D39.58):** 2/20 черновиков `deepseek-v4-flash` thinking-ON вернулись чистым исходником (`han_share=0.999`, 蛊真人 гл.5/9, современный zh). Гейт поймал оба, эскалация на dspro вылечила ($0.0147). thinking-ON снижает ЧАСТОТУ эха, но не до нуля; «echo 0» пере-прогона 23.07 (D39.20) был свойством выборки. Практика: закладывать в смету черновой волны ~10% на эскалации. *(Внесено оркестратором по D39.58.)*
|
||
- ✅ **FIDELITY-ГЕЙТ ПЕТЛИ D21 п.6 ПРОЙДЕН, направление ОБРАТНОЕ (31.07, судейский риг на готовых парах P4, $0.2855).** Судьи ЧУЖИХ семейств (grok-пары судит `deepseek-v4-pro`, deepseek-пары — `grok-4.3`), полные окна, оба порядка, **floor на идентичных текстах 4/4 «tie» у обоих**. На 16 судимых парах митигация лучше базы в обоих порядках в 10 случаях, база — в 1. ⚠ **Но 16 пар выросли из 6 базовых текстов; по НЕЗАВИСИМЫМ кластерам 5 из 6 смешанные, знаковый тест p=1.0** — «митигации вернее» НЕ установлено. Дефекты, нормированные на базовый текст: база 41.3 против 22.3 (сырые 106/59 завышают базу троекратным повтором); на 2 базах из 6 направление обратное. Конфаунд длины не исключён (митигации чуть длиннее, судья считает пропуски). ⇒ **Читать так: ЦЕНЫ ВЕРНОСТИ У МИТИГАЦИЙ НЕ ОБНАРУЖЕНО** — это ровно то, что гейт D21 п.6 спрашивал; «митигации лучше» — нет. Границы: 21 из 24 пар — grok (вне скоупа wiring D21 п.6), базы — «выжившие» после эха (смещение работает ПРОТИВ найденного направления), 8 пар не куплены (кап).
|
||
- ⚠ **Пере-читка 24 готовых пар P4 (31.07, $0):** ни одна митигация (инстр.-ПОСЛЕ / few-shot / комбо / префилл) **не даёт подписи ПРОПУСКА** — все митигированные выходы доходят до того же конца исходника, что база; Δlen_ratio медианно +0.02…+0.13, то есть митигации чуть МНОГОСЛОВНЕЕ, а не короче. Найден один дефект формы: 1 из 3 выходов «инстр.-ПОСЛЕ» на deepseek дописал **сноски переводчика `[1]…[6]`** вопреки «Выведи ТОЛЬКО перевод» (класс output-санитайзера D30.3). Ось «искажение при сохранённом объёме» детерминированно не берётся — нужен судья.
|
||
- ⚠ **Вся эмпирика P4 (research/15, 09.07) снята на весах `V4-Flash-Preview`, которых больше нет** (катовер 31.07 — секция выше). «0/29 против базы 30–67%» — про прежнюю модель; на 0731 база даёт 0/12 эха при `effort:low`, а по few-shot вердикта НЕТ — первая формулировка «вреден» отозвана самой сессией (п.5 секции катовера; докорректировано оркестратором 01.08 по §12.5 отчёта). Цитировать P4 как текущую эмпирику канала нельзя. *(Полигон, 31.07.)*
|
||
- ⚠ **Инверсия языкового констрейнта (research/15 P4):** языковая строка в `system` у reasoning-off модели может **УСИЛИВАТЬ** эхо, а не гасить его — на grok `reasoning_effort:none` одна формулировка констрейнта подняла эхо 3/10→9/10. Проверена **одна** формулировка на одном слаге; чувствительность к формулировке/модели неизвестна. → **Запрет (D21.6): не вносить языковые констрейнты в промпты reasoning-off путей без per-model замера.** (Латентное: `translator.md:10` уже несёт языковую строку, но едет только на thinking-ON DeepSeek — вне зоны инверсии; при заводке Mistral-канала B прогнать P4-реплику на боевом промпте.)
|
||
|
||
## Параметры сэмплинга
|
||
|
||
| Провайдер | Грабля |
|
||
|---|---|
|
||
| **Kimi K2.6** | принимает **только `temperature: 1`**; иное → HTTP 400 «only 1 is allowed for this model» |
|
||
| gpt-5-mini | `temperature` не принимается вовсе (см. выше) |
|
||
| Локаль (ollama `/v1`) | `top_k`/`min_p`/`repeat_penalty` **не пробрасываются** (ollama issue #11325) → запекать в Modelfile (паттерн `qwen3-vojo`). Для llama-server — расширить запрос этими полями |
|
||
| Локаль (ollama) | `max_tokens`/`num_predict` покрывает **thinking + ответ вместе** (в отличие от xAI, где thinking сверх лимита) |
|
||
|
||
## Контент-фильтры / safety
|
||
|
||
- **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). ⚠ **В роли редактора Gemini течёт сервис-преамбулой в выход («Вот отредактированный…», 6/6 чанков — exp12) → за output-санитайзером D30.3.**
|
||
- **Qwen Model Studio**: внешний фильтр `data_inspection_failed` на вход/выход, неотключаем (риск молчаливых вырезаний) — не тестировано (нет ключа).
|
||
- Детект отказов/вырезаний — см. `eval/refusal_bench.py` (паттерны soft-отказа + coverage-гейт по len_ratio/sent_cov, пороги в эксп. 02).
|
||
|
||
## Право по ToS/AUP: провайдер × content-label (ось ПРАВА — НЕ ось поведения)
|
||
|
||
> **Внесено полигоном, пакет-5, дата проверки 2026-07-25.**
|
||
> **РЕ-ЧЕК 2026-07-31 по календарному триггеру «головной Google ToS 30.07.2026» (D39.32 п.4, строка 4 бэклога): пере-сняты по первоисточникам `gemini` · `mistral` · `xai` · `deepseek` · `zai` — все пять на ПРЕЖНИХ объявленных ревизиях, ДЕЛЬТ ВЕРДИКТОВ НЕТ. `kimi` / `openai` / `local` в ре-чек НЕ входили и остаются на дате 25.07.** Подробности, дословные цитаты и рекомендация по строке 6 — `docs/archive/reports/TOS_RECHECK_2026-07-31.md`.
|
||
> **Следующая пере-проверка: 2026-10-25 (квартально) И безусловно перед заводкой первой лейблованной книги** (плюс при любой правке `accepts_labels`).
|
||
> Питает `accepts_labels` в `backend/configs/models.yaml` (D39.25–D39.28). **Строки данных применяет оркестратор ТОЛЬКО после подписи владельца** — здесь зафиксированы ФАКТЫ, не юридическое заключение.
|
||
|
||
**⚠ Эта секция — про ДРУГУЮ ось, чем секция «Контент-фильтры / safety» выше. Не смешивать:**
|
||
|
||
| | Что меряет | Чем меряется | Что делает движок |
|
||
|---|---|---|---|
|
||
| **Право** (эта секция) | вправе ли мы по договору ОТПРАВИТЬ такой контент на эндпойнт | чтение ToS/AUP первоисточника | проактивный роутинг по лейблу до вызова (`accepts_labels`) |
|
||
| **Поведение** (секция выше) | ответит ли модель или откажет | живой вызов | обработка отказа причино-агностично (D12/D39.25) |
|
||
|
||
Оси эмпирически расходятся **в обе стороны**, и у нас есть по случаю на каждую: Gemini fail-closed `PROHIBITED_CONTENT` на графичной эротике (D22.6, wire-verified) — это фильтр, а не запрет в договоре; DeepSeek в exp11 переводил explicit-фрагменты **против собственного ToS** — готовность модели не даёт права. Маршрутизируем по ПРАВУ.
|
||
|
||
**Флаг `permissive` как значение конфига НЕ СУЩЕСТВУЕТ** (отставлен D39.26/D39.27; загрузка падает громко). Способность объявляется пер-лейблу через `accepts_labels`. Слово «пермиссивный тир» в тексте ниже/выше — характеристика ПОВЕДЕНИЯ по эмпирике, не флаг и не право.
|
||
|
||
### Вердикты (вокабуляр владельца D39.27 п.5)
|
||
|
||
`ALLOWED` = право есть · `FORBIDDEN` = прямой запрет · `UNCLEAR` = однозначного пункта нет (**честный результат; оставляет fail-closed, что безопасно**). Основание: `explicit-prohibition` · `contrastive-absence` (грант + перечень, где СОСЕДНИЙ более узкий класс назван, а наш — нет) · `ambiguous-term` (пункт есть, но термин/глагол не даёт прочитать однозначно) · `no-clause` (класс не упомянут вовсе) · `scope` (непонятно, какой документ применим).
|
||
|
||
| Провайдер | `violence` | `sexually-explicit` | Применимый первоисточник (объявленная вендором ревизия) |
|
||
|---|---|---|---|
|
||
| **deepseek** | UNCLEAR `ambiguous-term` | **FORBIDDEN** | DeepSeek **Terms of Use** §3.4(5)/(6) — *Last Update: March 27, 2026*; втянут в API через Open Platform ToS §3.1 (*Effective date: April 29, 2026*) |
|
||
| **zai** | **FORBIDDEN** | **FORBIDDEN** | Z.ai **Terms of Use** п. f)/g) — *Last Update: April 14, 2026*; scope прямо `z.ai/model-api` |
|
||
| **kimi** | UNCLEAR `ambiguous-term` | UNCLEAR `no-clause` + катч-олл | **Terms of Service for Kimi OpenPlatform** §3.1(1)/(5) — *Last Updated: May 27th, 2026* (Moonshot AI PTE. LTD.) |
|
||
| **xai** | UNCLEAR `no-clause` (**чистое молчание**) | **ALLOWED** `contrastive-absence` | **xAI AUP** — *Effective: June 26, 2026*; договор API = **Enterprise ToS** *Last Updated: May 12, 2026* |
|
||
| **gemini** | UNCLEAR `ambiguous-term` | ~~FORBIDDEN~~ → **UNCLEAR** ⚠ | **Generative AI Prohibited Use Policy** — *Last Modified: December 17, 2024*; втянут **Gemini API Additional ToS** (*Effective March 23, 2026*), а над ним **Google APIs ToS** (*Last modified: November 9, 2021*) — головной договор API |
|
||
| **openai** | UNCLEAR `ambiguous-term` | UNCLEAR `ambiguous-term` | **Usage Policies** *Effective: October 29, 2025* + **Sharing & publication policy** *Updated: November 14, 2022* (инкорпорирована Services Agreement §17) |
|
||
| **mistral** | UNCLEAR `ambiguous-term` | **ALLOWED** `contrastive-absence` | **Usage Policy** — *Effective: June 11, 2026* (`legal.mistral.ai`, НЕ `mistral.ai/terms/*` — там 404) |
|
||
| **local** | UNCLEAR `scope` | UNCLEAR `scope` | вендор-API нет; веса Apache-2.0 (0 контентных ограничений), но Ollama ToS §4 (*Last updated: May 2026*) формально говорит о «software» |
|
||
|
||
⚠ **Клетка `gemini` × `sexually-explicit` — амендмент D39.32 п.2, а не находка ре-чека.** Текст PUP не менялся; изменилось его ратифицированное ЧТЕНИЕ: оговорка «`-- for example, content created for the purpose of pornography or sexual gratification`» читается владельцем как СУЖЕНИЕ (запрет адресован контенту, созданному РАДИ порнографии), поэтому `FORBIDDEN` снят. Но по доктрине D39.29 («молчание и „нас не запрещает“ ≠ разрешение») клетка становится **`UNCLEAR`, а не `ALLOWED`**: строки в `accepts_labels` Gemini НЕ получает, маршрут не меняется, судья 18+ остаётся grok. Право даст только отдельная подпись владельца — **строка 6 бэклога**. *(Рассинхрон таблицы с D-логом обнаружен ре-чеком 31.07 и помечен, а не переписан молча.)*
|
||
|
||
> **ГЛАВНЫЙ ВЫВОД, который надо прочитать целиком: по `violence` ПРАВА НЕТ НИ У ОДНОГО вендора.** Причина структурная, а не про наши книги: AUP регулируют **пропаганду** насилия («promotes, incites, glorifies, facilitates»), а **нейтральное художественное изображение** не называет НИ ОДИН документ — ни чтобы запретить, ни чтобы разрешить. Z.AI — единственный, кто пишет «violent content» плоско (→ FORBIDDEN); xAI — единственный, у кого слова `violen*` в AUP **нет вообще** (0 вхождений → чистое молчание, а молчание по доктрине не даёт ALLOWED). Следствие: **экономическая посылка D14 п.1 («violence-книга не теряет dspro-редактора») первоисточниками НЕ подтверждается** — под fail-closed violence-книга не поедет никуда. Это решение владельца, не сессии: детали и три варианта — в отчёте `docs/archive/reports/POLYGON_TOS_LABELS_REPORT_2026-07-25.md`.
|
||
|
||
### Доказательства (дословно; каждая цитата подтверждена счётом вхождений = 1 по сохранённой копии — форму проверки см. «Как это добывалось», 31.07 она исправлена)
|
||
|
||
- **deepseek** · *Terms of Use* §3.4 «You will not use the Services to generate, express or promote content or a chatbot that:» → **(5)** `is pornographic, obscene, or sexually explicit (e.g., sexual chatbots);` → SE = FORBIDDEN. **(6)** `facilitates, promotes, incites or glorifies violence or terrorist/extremism content;` → violence = UNCLEAR (глаголы = пропаганда, не изображение). Привязка к API двойная и явная: преамбула Open Platform ToS `serves as a Specific Agreement to the "DeepSeek Terms of Use" and specifically applies to your use of the application programming interface`, плюс §3.1 `you should procure that both of you and your end users comply with the requirements of the "DeepSeek Terms of Use"`; сам ToU §1.1 включает `application programming interfaces (APIs)` в определение «the Services». ⚠ **Поправка к D14 п.1: пункт «§3.4(5)» верен дословно, но он в Terms of Use, а НЕ в «Open Platform Terms of Service» — в последнем §3.4 про оргтехмеры безопасности.**
|
||
- **zai** · *Terms of Use*, «You are prohibited from engaging in or facilitating any of the following actions … including but not limited to:» → **f)** `Creating or disseminating obscene, pornographic, violent, murderous, terroristic, or criminal incitement content.` **g)** `Submitting, creating or disseminating content that is sexually explicit, suggestive, visually shocking, or otherwise disturbing.` Оба лейбла названы ПЛОСКО (без глагола-пропаганды), g) покрывает и **вход** («Submitting») → **FORBIDDEN/FORBIDDEN**. Scope: `as a user of the Z.ai accessible via z.ai/model-api ("Services")`.
|
||
- **kimi** · *OpenPlatform ToS* §3.1 вводится «For example, you will not…» (перечень ЯВНО неисчерпывающий) → contrastive-absence неприменим. §3.1(5) `To spam, bully, harass, defame, sexualize children, or promote violence, hatred or the suffering of others.` (пропаганда, не изображение) + широкий катч-олл §3.1(1) `For purposes that may have a harmful impact on physical or spiritual health or that violate ethical principles.` — «spiritual health»/«ethical principles» не определены → **UNCLEAR/UNCLEAR**.
|
||
- **xai** · *AUP*, грант: `You are free to use our Service so long as you use it to be a good human, act safely and responsibly, comply with the law, not harm people, and respect our guardrails:`. В сексуальной семье названы ТОЛЬКО узкие соседи — реальные лица и дети: `Depicting likenesses of persons in a pornographic manner`, «Undressing or nudifying real persons…», «Sexualizing or exploiting children» → взрослая художественная эротика не названа → **SE = ALLOWED**. По насилию: `grep -c -i violen` по AUP = **0** → **violence = UNCLEAR/no-clause**. Договор API — Enterprise ToS: `these terms are for enterprise (business) users of the xAI API and related xAI Services who are at least 18 years old` (0 контентных пунктов; консьюмерский ToS к нам не применим).
|
||
- **gemini** · *PUP*: `Do not engage in sexually explicit, violent, hateful, or harmful activities. This includes generating or distributing content that facilitates:` → буллит `Sexually explicit content -- for example, content created for the purpose of pornography or sexual gratification.` (класс назван своим именем; «for example» — иллюстрация, не сужение) → **SE = FORBIDDEN**; буллит `Violence or the incitement of violence.` под стемом «facilitates» → **violence = UNCLEAR**. Художественная оговорка НЕ carve-out — это дискреция: `We may make exceptions to these policies based on educational, documentary, scientific, or artistic considerations, or where harms are outweighed by substantial benefits to the public.` Привязка: Gemini API Additional ToS `you must comply with our Prohibited Use Policy`.
|
||
**Добор ре-чека 31.07.2026** (цепочка договора пере-проверена целиком): головной документ API — **не** потребительский `policies.google.com/terms`, а `Google APIs Terms of Service`: Additional ToS дословно требует `you must accept (1) the Google APIs Terms of Service (the " API Terms "), and (2) these Gemini API Additional Terms of Service`. Потребительский ToS цепляется лишь КОСВЕННО, через API ToS §b `You will not violate any other terms of service with Google (or its affiliates).`, и по нашим двум классам он ПУСТ (`violen*` = 0, `sexual*` = 0 вхождений и в ревизии 22.05.2024, и в новой 30.07.2026). Перечень «a. API Prohibitions» в Google APIs ToS по нашей оси тоже пуст (ближайшее — `Defame, abuse, harass, stalk, or threaten others.`, про поведение к людям, не про изображение в вымысле). **Единственная контентная вставка ревизии 30.07.2026** — `Some content may not be suitable for everyone.` в разделе о генерируемом контенте: это дисклеймер о ВЫХОДЕ Google, не разрешение на наш ВХОД, и по D39.29 права не даёт. **Два пункта Additional ToS, прежде не цитированные, важны для судьи Ф2:** `The Services include safety features to block harmful content, such as content that violates our Prohibited Use Policy . You may not attempt to bypass these protective measures…` и `Applications with less restrictive safety settings may be subject to Google's review and approval.` ⇒ обход фильтра запрещён ДОГОВОРОМ, что смыкается с D22.6 (фильтр `PROHIBITED_CONTENT` неконфигурируем) и означает: подпись под строкой 6 даёт ПРАВО, но работающего судьи эротики не даёт.
|
||
- **openai** · *Usage Policies* (взрослый перечень) `terrorism or violence, including hate-based violence` — конструкция «use our services FOR …» = деяние; слово «violent **content**» встречается ТОЛЬКО в минорной секции: `exposing minors to age-inappropriate content, such as graphic self-harm, sexual, or violent content`. Само по себе это тянет на ALLOWED, НО в договор через Services Agreement §17 инкорпорирована *Sharing & publication policy* (2022), чей раздел «Content co-authored with the OpenAI API» бьёт ровно в наш кейс: `are not related to adult content, spam, hateful content, content that incites violence, or other uses that may cause social harm` — «adult content» не определён, хвост «other uses that may cause social harm» открыт → **UNCLEAR по обоим**. ⚠ §17 привязывает применимую редакцию политик к дате НАШЕГО договора/продления, а не к сегодняшнему сайту.
|
||
- **mistral** · *Usage Policy*: в сексуальной семье названы CSAM, `You shall not use the Mistral AI Products to generate intimate images of any person without the explicit consent of all individuals involved` (NCII) и «sexual services»/трафикинг — взрослая художественная эротика не названа → **SE = ALLOWED** (подтверждает репо-клейм «policy 11.06.2026 без запрета adult»). Насилие: `promotes, incites, threatens, or glorifies violence is not permitted` → **UNCLEAR**. Scope-оговорка: `This Usage Policy does not apply to Mistral AI Products deployed on a customer's infrastructure…` — наш путь через платформу покрыт.
|
||
- **local** · Вендор-API нет: инференс на стенде, наружу ничего не уходит. Веса `huihui_ai/qwen3-abliterated:8b` ← `Qwen/Qwen3-8B` и `huihui-ai/Qwen3-8B-abliterated`, обе карточки HF `license: apache-2.0`; в самом LICENSE **0 вхождений** контентных ограничений (`grep -c -iE "sexual|pornograph|violence|acceptable use"` = 0) — Apache-2.0 не ограничивает область применения. Остаётся Ollama Inc. ToS (*Last updated: May 2026*) §4 «You may not: … `Transmit harmful, offensive, or illegal content`»: «offensive» не определён, а «Service» определён через «software», из-за чего непонятно, накрывает ли он локальный `ollama serve` → **UNCLEAR `scope`, вердикт владельца** («н/п» тоже его право).
|
||
|
||
### Как это добывалось (норма «заявление = команда»; приёмка ре-ранит)
|
||
|
||
- Прямой `curl` с браузерными заголовками; текст — стандартным питон-стриппером; **каждая цитата проверена счётом вхождений = 1 по сохранённому файлу**.
|
||
- ⚠ **ПОПРАВКА 31.07.2026: `grep -c -F` по стриппнутому тексту даёт ЛОЖНЫЕ НУЛИ — так проверять больше нельзя.** Пойманы два механизма, оба на DeepSeek: ToU верстает жёсткими переносами (`<br>` рвёт предложение пополам), а Open Platform ToS держит кавычки в отдельных тегах, из-за чего стриппер выдаёт `" DeepSeek Terms of Use "` с пробелами внутри. Три ВЕРНЫЕ цитаты показали `0`, что читалось бы как дельта вендора. **Рабочая форма: сверять по копии с УДАЛЁННЫМИ пробелами с обеих сторон** (`re.sub(r'\s+','',…)` и к цитате, и к документу) — нечувствительно к вёрстке, последовательность символов не трогает.
|
||
- **Cloudflare-403 на `x.ai` и `openai.com`** (воспроизводится и в WebFetch): обход — Wayback `https://web.archive.org/web/<ts>id_/<url>` (суффикс `id_` = оригинальные байты; добавлять `--compressed`, иначе приходит gzip-мусор). **Timestamp снимка ≠ дата ревизии документа** — не путать.
|
||
- ⚠ **`r.jina.ai` как ВТОРОЙ путь МЁРТВ (31.07.2026): 403** и на `x.ai`, и на `ai.google.dev`. Правило пакета-5 «цитата засчитана только при совпадении Wayback и jina» в прежней форме неисполнимо. **Замена, применённая 31.07:** два НЕЗАВИСИМЫХ захвата Wayback разных дат + сверка тел построчно (для xAI: снимки 25.07 и 28.07 побайтно идентичны). Честная граница такой замены — оба снимка в ПРОШЛОМ, живого подтверждения на дату чека нет; писать это явно. Прямой egress (`--noproxy '*'`) от Cloudflare-403 тоже не спасает — проверено.
|
||
- ⚠ **`ai.google.dev` БОЛЬШЕ НЕ ТРЕБУЕТ Wayback (31.07.2026).** Прежняя запись «редиректит в OAuth, curl умирает на 50 редиректах» верна по симптому; причина — петля на cookie `signin=autosignin`. **Лечится cookie-jar + явный язык: `curl -L --compressed -c jar -b jar 'https://ai.google.dev/gemini-api/terms?hl=en'` → HTTP 200 живьём.** Живая копия сверена со снимком Wayback: тело договора построчно идентично, расходится только навигация сайта.
|
||
- ✅ **ФОРМА РЕ-ЧЕКА ВПРЕДЬ (усиление 31.07): «дельты нет» доказывать не объявленной датой ревизии, а ПОСТРОЧНЫМ ДИФОМ тела документа против снимка Wayback на дату ПРОШЛОГО чека.** Объявленная дата — заявление вендора, оно бывает несвежим (тот же класс, что сноска DeepSeek о катовере, оставшаяся в будущем времени уже после катовера). Так закрыты 31.07 оба документа фокуса: тело PUP (снимок 26.07 vs живая 31.07) — идентично построчно, 27 строк против 27; тело Gemini Additional ToS (снимок 29.07 vs живая) — идентично, расходится только навигация сайта.
|
||
- **Головной Google ToS отдаётся по СТРАНОВЫМ версиям** (`?hl=en-US&gl=us` = Google LLC, дефолт с нашего egress = Google Ireland Limited) — версии текстуально разные, дату ревизии смотреть на нужной. Архив ревизий: `policies.google.com/terms/archive`, редлайн между ревизиями — `…/archive/<от>-<до>` (`<ins>`/`<del>` в разметке). **Редлайн вендора использовать как перекрёстную проверку, а дельту строить своим дифом архивной и живой копий.**
|
||
- ⚠ **`mistral.ai/terms/usage-policy` отдаёт HTTP 404** (и снимков в Wayback нет) — рабочий хост **`legal.mistral.ai/terms/usage-policy`**. Наш egress — прокси, так что 404 может быть edge-специфичным; при пере-проверке начинать с `legal.` .
|
||
- ⚠ **WebFetch для цитат НЕ годится** — режет цитату ~125 символами и переходит на пересказ. Только `curl` + `grep -F`.
|
||
|
||
- **Прокси на localhost**: в env стенда webshare-прокси, `NO_PROXY=<local>` — WinINET-нотация, которую curl/urllib/Go **не понимают** → запрос к 127.0.0.1 уходит на прокси и получает **403**. Лечение: явный `NO_PROXY="localhost,127.0.0.1,0.0.0.0,::1"` + в коде обходить прокси для loopback/172.x (бэкенд: local-адаптер с no-proxy транспортом — уже сделано).
|
||
- **DeepSeek cache-поля**: в `usage` два варианта именования (бэкенд обрабатывает оба).
|
||
- **«Эхо» черновика (тихий отказ)**: deepseek-chat на плотной CJK-прозе **воспроизводимо** (3 из 3 ретраев на zh-фрагменте Лу Синя «祝福») возвращает **оригинал вместо перевода** (82% CJK в «переводе»). Не ошибка API — валидный ответ с неправильным содержимым; ретраи не помогают (детерминировано для фрагмента). Митигация в `eval/editor_bench.py`: детектор доли CJK (порог 15%) → фолбэк на другого провайдера (GLM перевёл тот же текст чисто). **Бэкенд/гейт: детектор CJK-артефактов в русском выходе обязателен** (смыкается с anti-omission coverage-гейтом Р7 и уже запланированным «детектором CJK-артефактов» — 7 из 18 моделей грешат); эскалация на другого провайдера, а не ретрай. NB: проверено на deepseek-chat; актуальную роль-модель `deepseek-v4-flash` перепроверить.
|
||
- **Таймауты**: книжные чанки на локали занимают **63–278 с** (не 45 с как в чат-vojo). Нужен per-роль лег-таймаут ~300–600 с + стриминг как keep-alive. Донорский транспорт vojo имел скрытый per-attempt потолок 60 с.
|
||
- **`mistral-large-latest` — агрессивный rate-limiter (тир-зависим, пере-замерить на прод-тире).** Судейский eval-риг exp15 §7.6 REV.2 (N-параллельные вызовы): **~48% retry-fails @1.3s интервала**, max latency **64.7s**; `grok-*` в том же риге — 0%. Расширение интервала 1.3→2.6s эффекта НЕ дало (49.5→48.2%) → лимитер похож на **токен-бакет/конкуренц-кап**, не per-request-пейсинг. Пер-вызовный 429/`Retry-After` в адаптере есть (`httpllm.go`, кап `maxRetryAfterWait`); гэп — N-параллельность волнового раннера → **пер-модельный семафор конкуренции конфигом `models.yaml`** (план 11 WS1(б); заведён — `rate_limit: {max_concurrency: 2, min_interval_ms: 0}` у `mistral-large-2512`). ⚠ **Оговорка «mistral-editor-арм не идёт через прод-путь до этого guard» (D39.12, гейтнутый арм №4) СНЯТА — superseded D39.20:** mistral исключён как несущий РЕДАКТОР (анти-корреляция гладкость↔верность, воспроизведена ×3), гейтнутого арма больше не существует. **Цифры rate-limit ОСТАЮТСЯ в силе и продолжают гейтить прод-путь:** mistral жив как **переводчик под лейблом** (D19.1), а семафор охраняет именно этот путь. Правило двух направлений: цифры из eval-рига, НЕ офиц. доки — при прод-тир-замере запинить вендор-страницу rate-limits. *(Внесено оркестратором при лендинге D39.12; оговорка снята полигоном, пакет-5 25.07.2026; черновик — план 11 §12.)*
|
||
|
||
## Календарь деприкаций / цен (мониторить ежеквартально)
|
||
|
||
- ~~`deepseek-chat` → `deepseek-v4-flash` к **24.07.2026**~~ → **КАТОВЕР ПРОШЁЛ, пункт закрыт (полигон, пакет-5, 25.07.2026).** Вендор-дока (`api-docs.deepseek.com/quick_start/pricing`, сноска (1); тот же текст в Change Log): *«The model names deepseek-chat and deepseek-reasoner will be deprecated on 2026/07/24 15:59 UTC. For compatibility, they correspond to the non-thinking mode and thinking mode of deepseek-v4-flash, respectively»* (⚠ сноска осталась в будущем времени — это несвежесть доки, не отсрочка). Live-проба $0 25.07.2026: `GET /v1/models` → ровно `deepseek-v4-flash` + `deepseek-v4-pro`; `GET /v1/models/deepseek-chat` и `/deepseek-reasoner` → **HTTP 404 `{"message":"Model Not Found","type":"not_found_error"}`**. Это сильнее «нет в /models»: слаг отсутствует и в пер-слаговом реестре, т.е. алиас-урок календаря («нет в /models ≠ не работает») здесь **исчерпан**. ⚠ Честная граница: `chat/completions` этими слагами НЕ дёргался — платные вызовы в пакете-5 не санкционированы; реестр-404 — сильная, но формально не тождественная улика. **Цены пост-катовера не изменились** (flash $0.14/$0.28, cache-hit $0.0028; pro $0.435/$0.87, cache-hit $0.003625) → `prices_checked` в `models.yaml` можно продлить до 25.07.2026 без правки чисел. Заодно с той же страницы: контекст **1M**, max output **384K**, конкуренц-кап **2500** (flash) / **500** (pro).
|
||
- **Gemini 2.5-серия (pro/flash/flash-lite) — shutdown 16.10.2026** («earliest possible date», офиц. deprecations-страница; live-фактчек оркестратора 09.07). Замены по вендору: 3.1-pro-preview / 3.5-flash / 3.1-flash-lite. ⚠ До даты на 2.5-flash уже наблюдён **интермиттентный 404 «model no longer available» при наличии слага в /models** (research/15, сырьё) — вендором не документирован; судья fidelity `memory_eval` сидит на 2.5-flash → мигрировать (D21.9). Отдельно: `finish_reason=PROHIBITED_CONTENT` на Gemini 3.x — **НЕконфигурируемый фильтр-класс** (safety_settings не влияют, в отличие от `SAFETY`); наблюдён на violence-сцене → вывод exp07 «content_filter мёртв» на Gemini 3.x не переносится. *(Добавлено оркестратором по research/15 + фактчеку.)*
|
||
- **Grok 4.1 Fast retired 15.05.2026** → слаги молча редиректят на `grok-4.3` (цена ×9). Ретайрнулся дешёвый тир, НЕ сам xAI: grok-4.3 остаётся основным пермиссивным тиром канала B.
|
||
- **Аудит /models 04.07.2026 (воркфлоу) — с поправкой на перепроверку:** и `deepseek-chat`, и `grok-4-fast` НЕ в списках /models (там v4-flash/v4-pro у DeepSeek; версионные слаги у xAI), НО **оба работают как алиасы** (перепроверено вживую: HTTP 200, переводят). Агент-аудитор написал «сняты» — это была неточность: «нет в /models» ≠ «не работает». deepseek-chat депрекируется 24.07.2026. У xAI есть мигрированные слаги-обёртки (`grok-4.20-0309-non-reasoning` / `-reasoning` / `-multi-agent`, ретайр 15.05.2026), но **для перевода/редактуры берём `grok-4.3` + явный `reasoning_effort:"none"`** (слаг не меняем; non-reasoning вариант = grok-4.3+`none` под капотом — см. thinking-таблицу). xAI `usage` отдаёт нестандартные `cost_in_usd_ticks`/`num_sources_used` — игнорировать. **Урок: имя модели проверять не только `/models`, но и пробным вызовом — алиас может работать, даже если его нет в списке; и наоборот.** Реальная причина сменить deepseek на v4-flash — не «chat умер», а ЭХО на zh (лечится thinking-on), см. раздел thinking.
|
||
- Claude Sonnet 5 промо $2/$10 до **31.08.2026** (не закладывать в долгий прайс).
|
||
- **ПОПРАВКА (04.07, владелец): удалён только Anthropic (за дороговизну). OpenAI ОСТАЁТСЯ** (ключ есть — GPT-5 nano/mini). Живой набор ключей у бэкенда и полигона: DEEPSEEK, ZAI, KIMI, OPENAI, GEMINI, XAI, MISTRAL (добавлен 09.07, 6ab92b5). Источник истины по стеку — `architecture/05-decisions-log.md` (D3) и Р4. Ранее эта строка ошибочно исключала OpenAI — исправлено оркестратором.
|
||
|
||
## Провенанс
|
||
|
||
Кто что нашёл: эндпоинты/thinking/temp/safety — полигон (эксп. 02, 03, 04, живые вызовы); Grok-retired/cache-write Anthropic/per-attempt-60с — бэкенд (шаг 0 валидации); localhost-прокси — оба стенда независимо.
|