From 08ad4bb42967c0fc388f387acd901813d9db74f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D1=82=D0=B0=D0=BB=D0=B8=D0=B9=20=D0=9D=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8=D1=82=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 25 Sep 2026 10:49:02 +0700 Subject: [PATCH] fix(glm): default effort xhigh, document real GLM 5.3 effort mapping Z.ai Anthropic endpoint reads output_config.effort and accepts all 5 Claude Code levels, but GLM 5.3 has only low/high/max natively: medium -> low, xhigh -> high (measured, not documented by Z.ai). ai-glm now starts on xhigh instead of max. Co-Authored-By: Claude Opus 5.5 --- EFFORT_MAPPING.md | 39 ++++++++++++++++++++++++++------------- scripts/ai-setup.sh | 16 +++++++++------- tests/test_fixes.sh | 11 +++++++++++ 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/EFFORT_MAPPING.md b/EFFORT_MAPPING.md index 23176ad..98b6567 100644 --- a/EFFORT_MAPPING.md +++ b/EFFORT_MAPPING.md @@ -15,11 +15,11 @@ | Claude Code `/effort` | Anthropic (`ai-claude`) | DeepSeek V4 (`ai-deepseek`) | Kimi K2.7/K2.6 (`ai-kimi`) | GLM 5.3 (`ai-glm`) | OpenRouter/GPT-5.5 (`ai-openrouter`) | OpenCode Go (`ai-opencode`) | |:---:|:---:|:---:|:---:|:---:|:---:|:---:| -| `low` | нативно `low` | нативно `low` | thinking on | на стороне сервера | без локального маппинга | без локального маппинга | -| `medium` | нативно `medium` | провайдер поднимает до `high` | thinking on | на стороне сервера | без локального маппинга | без локального маппинга | -| `high` | нативно `high` | нативно `high` | thinking on | на стороне сервера | без локального маппинга | без локального маппинга | -| `xhigh` | нативно `xhigh` | провайдер поднимает до `high` | thinking on | на стороне сервера | без локального маппинга | без локального маппинга | -| `max` | нативно `max` | нативно `max` | thinking on | на стороне сервера | без локального маппинга | без локального маппинга | +| `low` | нативно `low` | нативно `low` | thinking on | нативно `low` | без локального маппинга | без локального маппинга | +| `medium` | нативно `medium` | провайдер поднимает до `high` | thinking on | провайдер опускает до `low` | без локального маппинга | без локального маппинга | +| `high` | нативно `high` | нативно `high` | thinking on | нативно `high` | без локального маппинга | без локального маппинга | +| `xhigh` | нативно `xhigh` | провайдер поднимает до `high` | thinking on | провайдер опускает до `high` | без локального маппинга | без локального маппинга | +| `max` | нативно `max` | нативно `max` | thinking on | нативно `max` | без локального маппинга | без локального маппинга | Для OpenRouter текущий лаунчер не делает локального преобразования effort и отправляет значение дальше через Claude Code/OpenRouter. Конкретная интерпретация зависит от выбранной @@ -69,12 +69,22 @@ on / off ### GLM 5.3 (Zhipu AI) ```text -high / max +low -> high -> max ``` -- Маппинг выполняется на стороне Zhipu AI API. -- Текущий `ai-glm` не делает локального преобразования effort. -- Дефолт `ai-glm`: `high`. +- 3 реальных уровня, thinking выключить нельзя (`thinking.type=disabled` тоже даёт reasoning). +- Anthropic-endpoint Z.ai читает `output_config.effort` от Claude Code и принимает все 5 уровней + (невалидное значение -> HTTP 400 `reasoning_effort must be one of: none, minimal, low, medium, high, xhigh, max`). +- `medium` фактически опускается до `low`, `xhigh` - до `high`. +- Если effort не передан, Z.ai использует `max`. Поэтому `ai-glm` выставляет + `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1` - иначе Claude Code не считает `glm-5.3` effort-capable + и параметр не уходит. +- Маппинг выполняется на стороне Z.ai API, `ai-glm` локально effort не преобразует. +- Дефолт `ai-glm`: `xhigh` (= `high` у GLM), задаётся через CLI `--effort` при каждом запуске. +- Официально Z.ai маппинг `medium`/`xhigh` не документирует. Он выведен замером 2026-09-25: + по 3 запроса на уровень, средний `output_tokens` на счётной задаче - `low` ~1.5K, + `medium` ~1.1K, `high` ~3.4K, `xhigh` ~2.8K, `max` ~3.8K. `low`/`medium` уверенно короче + остальных, а `high` и `max` на такой выборке пересекаются по разбросу. ### OpenRouter / GPT-5.5 @@ -100,7 +110,7 @@ Effort не преобразуется локально — thinking budget не | Anthropic | Не нужен | - | | DeepSeek V4 | DeepSeek API | На стороне сервера | | Kimi K2.7/K2.6 | Moonshot API | На стороне сервера | -| GLM 5.3 | Zhipu AI API | На стороне сервера | +| GLM 5.3 | Z.ai API (`low,medium→low`, `high,xhigh→high`, `max`) | На стороне сервера | | OpenRouter/GPT-5.5 | Локального маппинга нет | `ai-openrouter` отправляет значение как есть | | OpenCode Go | Локального маппинга нет | `ai-opencode` отправляет значение через routatic-proxy | | Legacy GPT proxy | helper-маппинг `xhigh` -> `high` | `~/bin/claude-gpt-effort-proxy.py` или `~/.local/bin/claude-gpt-effort-proxy.py` | @@ -120,10 +130,13 @@ AI_EFFORT=high ai-deepseek # включить high ai-deepseek # без флага - использовать уровень из settings.json ``` -Дефолты: `xhigh` для `ai-claude`, `high` для остальных Claude Code лаунчеров. +Дефолты: `xhigh` для `ai-claude` и `ai-glm`, `high` для остальных Claude Code лаунчеров. +`ai-glm` передаёт уровень через CLI `--effort`, поэтому каждый запуск стартует на `xhigh` +(или на `AI_EFFORT`), а `/effort` внутри сессии действует до её конца. ## Рекомендации - Для повседневной работы: `high` или `xhigh`. -- `max` effort имеет реальный эффект у Anthropic и DeepSeek; у Kimi и GLM это всё тот же thinking on / маппинг на стороне сервера. -- `low`/`medium` у Kimi и GLM фактически не снижают reasoning; у DeepSeek `low` теперь даёт реальный уровень `low` и экономит бюджет. +- `max` effort имеет реальный эффект у Anthropic, DeepSeek и GLM; у Kimi это всё тот же thinking on. +- `low`/`medium` у Kimi фактически не снижают reasoning; у DeepSeek `low` и у GLM `low`/`medium` дают реальный уровень `low` и экономят бюджет. +- У GLM осмысленно выбирать только `low`, `high` (или `xhigh`) и `max`. diff --git a/scripts/ai-setup.sh b/scripts/ai-setup.sh index 77fc7f8..516ae16 100755 --- a/scripts/ai-setup.sh +++ b/scripts/ai-setup.sh @@ -1649,12 +1649,14 @@ export CLAUDE_CONFIG_DIR="$HOME/.config/ai-setup/cfg/glm" # Claude Code навязывает 3 слота; незаданный показал бы чужой Claude, поэтому # opus+sonnet+haiku = glm-5.3. Окно контекста у всех слотов задаёт env # CLAUDE_CODE_MAX_CONTEXT_TOKENS ниже — суффикс [1m] больше не нужен. -_setup_isolated_config glm opus high '' -# ai-glm стартует на /effort max. max невалиден в settings.json (там только -# low/medium/high/xhigh), поэтому задаём через CLI --effort, а не _apply_effort. +_setup_isolated_config glm opus xhigh '' +# ai-glm стартует на /effort xhigh через CLI --effort (перебивает effortLevel из +# settings.json при каждом запуске). Z.ai сворачивает 5 уровней Claude Code в 3 +# нативных GLM 5.3: low,medium→low; high,xhigh→high; max→max (см. EFFORT_MAPPING.md). # CLAUDE_CODE_ALWAYS_ENABLE_EFFORT заставляет Claude Code отправлять effort в API -# для GLM (иначе glm-5.3 не распознан как effort-capable и параметр не уходит). -# /effort внутри сессии работает; ручной override запуска: AI_EFFORT=high ai-glm. +# для GLM (иначе glm-5.3 не распознан как effort-capable и параметр не уходит, +# а Z.ai по умолчанию берёт max). +# /effort внутри сессии работает; ручной override запуска: AI_EFFORT=max ai-glm. # CLAUDE_CODE_DISABLE_1M_CONTEXT НЕ выставляем: GLM 5.3 реально держит 1M контекста, # а флаг заставлял бы счётчик ctx: считать окно = 200K (врал в ~5 раз). Прочие # лаунчеры (deepseek/kimi/openrouter/opencode) флаг оставляют — у них другой контекст @@ -1678,7 +1680,7 @@ CLAUDE_CODE_SUBAGENT_MODEL=glm-5.3 \ CLAUDE_CODE_MAX_CONTEXT_TOKENS=1000000 \ CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1 \ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \ -claude --dangerously-skip-permissions --effort "${AI_EFFORT:-max}" --system-prompt-file "$_PROMPT_FILE" "$@" +claude --dangerously-skip-permissions --effort "${AI_EFFORT:-xhigh}" --system-prompt-file "$_PROMPT_FILE" "$@" GLMEOF chmod +x "$BIN_DIR/ai-glm" @@ -1982,7 +1984,7 @@ chmod +x "$BIN_DIR/ai-opencode" source "$BIN_DIR/ai-api-helpers.sh" _setup_isolated_config deepseek opus high '' _setup_isolated_config kimi opus high '' -_setup_isolated_config glm opus high '' +_setup_isolated_config glm opus xhigh '' _setup_isolated_config openrouter "openai/gpt-5.5" high '' _setup_isolated_config opencode deepseek-v4-pro high '' diff --git a/tests/test_fixes.sh b/tests/test_fixes.sh index cd1862c..fba98d2 100755 --- a/tests/test_fixes.sh +++ b/tests/test_fixes.sh @@ -104,6 +104,16 @@ test_glm_official_api() { fi } +# ── ai-glm: default effort is xhigh (still overridable via AI_EFFORT) ───── +test_glm_default_effort() { + if echo "$GLM_SECTION" | grep -q -- '--effort "${AI_EFFORT:-xhigh}"' \ + && echo "$GLM_SECTION" | grep -q 'CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1'; then + ok "ai-glm: starts with --effort xhigh by default, effort sent to Z.ai" + else + fail "ai-glm: must start with --effort \"\${AI_EFFORT:-xhigh}\" and CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1" + fi +} + # ── ai-gemini: native launcher generation ───────────────────────────────── test_gemini_native_launcher() { if echo "$GEMINI_SECTION" | grep -q 'antigravity CLI (agy)' \ @@ -301,6 +311,7 @@ test_kimi_official_api test_kimi_no_artemox test_glm_claude_launcher test_glm_official_api +test_glm_default_effort test_gemini_native_launcher test_cursor_native_launcher test_global_rules_source_installed