Этот урок не про математику модели. Он про то, как один раз записать ежемесячный запуск прогноза ML в навык, чтобы каждый цикл шёл одинаково: проверили данные → посчитали → сверили точность с прошлым запуском → выгрузили Excel → записали в журнал. И чтобы Claude сам останавливался, когда что-то не так.
This lesson is not about the model's math. It is about writing the monthly ML forecast run into a skill once, so every cycle goes the same way: check the data → calculate → compare accuracy with the last run → export Excel → write to the log. And so Claude stops by itself when something is wrong.
/ml-forecast KAZ 2026-11;/ml-forecast KAZ 2026-11;Каждый месяц вы заново пишете Claude: «возьми выгрузку, посчитай, проверь, сравни, выгрузи». Один раз забыли сравнить с прошлым циклом — и прогноз с ошибкой ушёл в S&OP. В отпуске вас никто не заменит: порядок в голове.
Every month you write to Claude again: "take the export, calculate, check, compare, export". Once you forget to compare with last cycle — and a faulty forecast goes to S&OP. When you are on leave, nobody can replace you: the routine lives in your head.
Как техкарта на заводе: шаги, нормы, «при отклонении — остановить линию и позвать мастера». Ночная смена делает по карте одинаково. Вы пишете /ml-forecast KAZ 2026-11 — и Claude идёт по карте, а на любом отклонении останавливается и зовёт вас.
Like a job card at a plant: steps, norms, "on a deviation — stop the line and call the supervisor". The night shift works by the card the same way. You type /ml-forecast KAZ 2026-11 — Claude follows the card and stops to call you on any deviation.
Читает выгрузку, склеивает коды, строит прогноз, считает бэктест и WMAPE, пишет Excel. Каждый раз одинаково.
Reads the export, glues codes, builds the forecast, runs the backtest and WMAPE, writes Excel. The same every time.
Запускает скрипты по порядку, проходит проверки, сравнивает с прошлым запуском и наивным прогнозом, останавливается на проблеме, пишет отчёт в 5 строк, объясняет, почему упала точность.
Runs the scripts in order, goes through the checks, compares with the last run and the naive forecast, stops on a problem, writes a 5-line report, explains why accuracy dropped.
Отдавать прогноз или нет. Что делать с худшими строками. Менять ли параметр — только осознанно, с записью в журнал изменений.
Whether the forecast goes out. What to do with the worst rows. Whether to change a parameter — only deliberately, with a record in the change log.
params.md, а Claude их только запускает. If you ask Claude to calculate a forecast "from scratch" in a conversation, it may pick a slightly different method each time — and two months' numbers can't be compared. So the method lives in the script and in params.md, and Claude only runs them. /baseline-clean (урок 15-30). Нет → стоп или запустить егоThe file from the /baseline-clean skill (lesson 15-30). No → stop or run itruns/runs_log.csv: дата, точность, итог, статусA row in runs/runs_log.csv: date, accuracy, total, statusparams.md, а не держится в голове. "5 p.p." is an example. Take the usual spread of accuracy between your cycles over half a year and set the threshold a little above it. The threshold is written in params.md, not kept in your head. | ФайлFile | Что в нёмWhat's in it | Кто меняетWho changes it |
|---|---|---|
SKILL.md | шаги «что делать и когда остановиться», формат отчётаsteps "what to do and when to stop", report format | вы, когда меняется процессyou, when the process changes |
params.md | горизонт, окно истории, модель, правила новинок и делистов, порогиhorizon, history window, model, new-product and delisting rules, thresholds | только по вашему решению, с записью «было → стало»only by your decision, with a "before → after" record |
checks.md | что должно сойтись в результатеwhat must reconcile in the result | вы, когда нашли новую ловушкуyou, when you find a new trap |
scripts/ | код расчёта. Claude его запускает, а не читает целиком каждый разthe calculation code. Claude runs it, it doesn't read it in full each time | Claude Code по вашей просьбе, с проверкой бэктестомClaude Code at your request, tested with a backtest |
runs/ | журнал: каждый запуск — строкаthe log: each run is a row | навык сам дописывает строкуthe skill appends a row itself |
Скрипты пишет Claude Code по вашему описанию методики (урок 15-27). Если у вас уже есть рабочий скрипт прогноза — положите его в scripts/, навык просто будет его запускать.
Claude Code writes the scripts from your description of the method (lesson 15-27). If you already have a working forecast script — put it into scripts/, the skill will just run it.
Навык для отдела планирования «Долины напитков». Скопируйте, поменяйте пути и пороги под себя. Разбор каждой строки шапки — в следующем разделе.
A skill for the Valley Beverages planning team. Copy it and change paths and thresholds to yours. Every header line is explained in the next section.
---
name: ml-forecast
description: Ежемесячный расчёт прогноза ML по стране и циклу — проверка данных, расчёт, бэктест, сравнение с прошлым запуском и наивным прогнозом, выгрузка в Excel и запись в журнал.
disable-model-invocation: true
arguments: [country, cycle]
argument-hint: [страна] [цикл ГГГГ-ММ]
allowed-tools: Bash(python ${CLAUDE_SKILL_DIR}/scripts/*)
---
# Прогноз ML: страна $country, цикл $cycle
## Состояние данных
!`python ${CLAUDE_SKILL_DIR}/scripts/data_status.py $country || true`
## Правила
- Параметры расчёта — в [params.md](params.md). Проверки — в [checks.md](checks.md). Без моей команды их не меняй.
- Исходные выгрузки только читай. Результаты прошлых циклов не перезаписывай.
- Прогноз не считай сам в разговоре — только скриптами из scripts/.
## Порядок работы
1. Прочитай «Состояние данных». Если последний закрытый месяц не равен месяцу перед циклом $cycle или есть ошибка — остановись и скажи, чего не хватает.
2. Проверь, что есть очищенная базовая линия data/baseline_<страна>_<цикл>.csv. Нет — остановись и предложи запустить /baseline-clean $country $cycle.
3. Запусти scripts/run_forecast.py --country $country --cycle $cycle. Скрипт склеивает коды по справочнику переключений. Все предупреждения скрипта покажи мне.
4. Запусти scripts/backtest.py --country $country --cycle $cycle: WMAPE на уровне город × SKU × месяц за 6 последних закрытых месяцев, после склейки кодов, для прогноза ML и наивного прогноза.
5. Сравни с прошлым запуском этой страны в runs/runs_log.csv. Остановись, если WMAPE ML не лучше наивного или вырос больше порога из params.md. Покажи 10 худших строк: город, SKU, факт, прогноз, ошибка. Ничего не исправляй сам — жди моего решения.
6. Пройди все проверки из checks.md. Любая не прошла — остановись и покажи строки.
7. Сохрани output/ML_forecast_<страна>_<цикл>.xlsx, например ML_forecast_KAZ_2026-11.xlsx: числа числами, без заливок, все города строками. Если такой файл уже есть — не перезаписывай, спроси меня.
8. Допиши строку в runs/runs_log.csv: дата, страна, цикл, WMAPE ML, WMAPE наивного, итог в тыс. л, итог прошлого цикла, статус (готово / остановлено и почему).
## Отчёт мне — ровно 5 строк
1. Данные: последний закрытый месяц, число рядов город × SKU, предупреждения.
2. Точность: WMAPE ML и наивного, разница с прошлым запуском в п.п.
3. Итог прогноза на горизонт в тыс. л и разница с прошлым циклом в %.
4. Проверки: сколько прошло из checks.md и какие нет.
5. Файл: путь. Вопросы ко мне, если есть.
Если что-то непонятно — спроси меня, по одному вопросу. ---
name: ml-forecast
description: Monthly ML forecast run by country and cycle — data check, calculation, backtest, comparison with the last run and the naive forecast, Excel export and a log entry.
disable-model-invocation: true
arguments: [country, cycle]
argument-hint: [country] [cycle YYYY-MM]
allowed-tools: Bash(python ${CLAUDE_SKILL_DIR}/scripts/*)
---
# ML forecast: country $country, cycle $cycle
## Data status
!`python ${CLAUDE_SKILL_DIR}/scripts/data_status.py $country || true`
## Rules
- Calculation parameters are in [params.md](params.md). Checks are in [checks.md](checks.md). Do not change them without my command.
- Only read the source exports. Never overwrite results of past cycles.
- Do not calculate the forecast yourself in the conversation — only with the scripts in scripts/.
## Routine
1. Read "Data status". If the last closed month is not the month before cycle $cycle, or there is an error — stop and tell me what is missing.
2. Check that the cleaned baseline data/baseline_<country>_<cycle>.csv exists. If not — stop and suggest running /baseline-clean $country $cycle.
3. Run scripts/run_forecast.py --country $country --cycle $cycle. The script glues codes using the code-switch list. Show me every warning the script prints.
4. Run scripts/backtest.py --country $country --cycle $cycle: WMAPE at city × SKU × month over the last 6 closed months, after gluing codes, for the ML forecast and the naive forecast.
5. Compare with this country's last run in runs/runs_log.csv. Stop if the ML WMAPE is no better than naive or rose by more than the threshold in params.md. Show the 10 worst rows: city, SKU, actual, forecast, error. Do not fix anything yourself — wait for my decision.
6. Go through all checks in checks.md. If any fails — stop and show the rows.
7. Save output/ML_forecast_<country>_<cycle>.xlsx, e.g. ML_forecast_KAZ_2026-11.xlsx: numbers as numbers, no fills, all cities as rows. If the file already exists — do not overwrite, ask me.
8. Append a row to runs/runs_log.csv: date, country, cycle, ML WMAPE, naive WMAPE, total in thousand litres, last cycle's total, status (done / stopped and why).
## Report to me — exactly 5 lines
1. Data: last closed month, number of city × SKU series, warnings.
2. Accuracy: ML and naive WMAPE, change vs the last run in p.p.
3. Forecast total over the horizon in thousand litres and change vs last cycle in %.
4. Checks: how many from checks.md passed and which did not.
5. File: the path. Questions for me, if any.
If anything is unclear — ask me, one question at a time. ---. Дальше три блока: Состояние данных (подставляется само до того, как Claude начнёт), Правила (что нельзя никогда) и Порядок работы (шаги со стопами). В конце — формат отчёта: так вы за 10 секунд видите, всё ли в порядке. On top — the header between ---. Then three blocks: Data status (filled in automatically before Claude starts), Rules (what is never allowed) and Routine (steps with stops). At the end — the report format: so in 10 seconds you see whether all is fine. | СтрокаLine | Что делаетWhat it does |
|---|---|
name: ml-forecast | имя команды: /ml-forecast. Латиница через дефисthe command name: /ml-forecast. Latin letters with hyphens |
description | что делает навык. Самое важное — в начале: в списке навыков описание обрезается после 1 536 символовwhat the skill does. Most important first: in the skill list the description is cut after 1,536 characters |
disable-model-invocation: true | навык запускается только вашей командой. Прогноз не должен стартовать «по догадке», когда вы просто спросили про точностьthe skill runs only on your command. A forecast must not start "on a guess" when you just asked about accuracy |
arguments: [country, cycle] | имена того, что вы пишете после команды. В /ml-forecast KAZ 2026-11 первое слово станет $country = KAZ, второе — $cycle = 2026-11names for what you type after the command. In /ml-forecast KAZ 2026-11 the first word becomes $country = KAZ, the second $cycle = 2026-11 |
argument-hint | подсказка, которая видна при наборе команды: что писать после неёa hint shown while typing the command: what to write after it |
allowed-tools | что Claude может запускать без вопроса во время навыка. Здесь — только Python-скрипты из папки навыка. Всё остальное он спроситwhat Claude may run without asking during the skill. Here — only Python scripts from the skill folder. Anything else it will ask about |
${CLAUDE_SKILL_DIR} | путь к папке навыка. Работает с любого ноутбука — без абсолютных путей вида C:\Users\…the path to the skill folder. Works from any laptop — no absolute paths like C:\Users\… |
!`…` | команда выполняется до того, как Claude прочитает навык, и её вывод встаёт на это место. Claude сразу видит, какие месяцы есть в выгрузкеthe command runs before Claude reads the skill, and its output takes its place. Claude sees at once which months are in the export |
|| true | если команда закончится с ошибкой, весь запуск навыка отменится. Эта приписка не даёт ему упасть: ошибка попадёт в текст, и шаг 1 остановит работу уже с объяснениемif the command ends with an error, the whole skill invocation is cancelled. This suffix keeps it from failing: the error lands in the text, and step 1 stops the work with an explanation |
[params.md](params.md) | ссылка на соседний файл. Claude откроет его, когда дойдёт до шага, — SKILL.md остаётся короткимa link to a neighbouring file. Claude opens it when it reaches that step — SKILL.md stays short |
--- в самой первой строке файла, имена полей — точно как в образце (disable-model-invocation, не disable_model_invocation): неизвестное поле молча игнорируется. 2) Сразу за $country не пишите букву или подчёркивание — надёжнее так, как в образце: имя файла словами «<страна>_<цикл>». 1) The header must start with --- on the very first line of the file, field names exactly as in the sample (disable-model-invocation, not disable_model_invocation): an unknown field is silently ignored. 2) Don't put a letter or underscore right after $country — it's safer as in the sample: the file name in words, "<country>_<cycle>". Держите SKILL.md до 500 строк. Всё длинное — методику, таблицы параметров — выносите в соседние файлы, как params.md и checks.md.
Keep SKILL.md under 500 lines. Anything long — method notes, parameter tables — goes into neighbouring files, like params.md and checks.md.
params.md — «паспорт» расчёта. Пока параметры одни и те же, точность двух циклов можно сравнивать. Внизу — журнал изменений: без него через три месяца никто не вспомнит, почему точность вдруг сдвинулась.
params.md is the "passport" of the calculation. While parameters stay the same, accuracy of two cycles can be compared. At the bottom — a change log: without it, in three months nobody will remember why accuracy suddenly moved.
# Параметры прогноза ML — менять только моей командой
- Уровень расчёта: город × SKU × месяц, единицы — тыс. л.
- Горизонт: 18 месяцев, начиная с месяца цикла.
- Окно истории: 36 последних закрытых месяцев.
- Модель: градиентный бустинг; признаки — месяц, праздники, цена, промо-флаги из коммерческого календаря.
- Вход: очищенная базовая линия от /baseline-clean.
- Новинка: меньше 6 месяцев истории — прогноз по аналогу из справочника новинок, флаг «новинка» в выгрузке.
- Делист: прогноз 0 с месяца делиста.
- Переключение кода: история старого кода переносится на новый по справочнику переключений.
- Бэктест: 6 последних закрытых месяцев, WMAPE после склейки кодов.
- Наивный прогноз: тот же месяц прошлого года × тренд последних 3 месяцев.
- Стоп-правила: WMAPE ML не лучше наивного ИЛИ вырос больше чем на 5 п.п. к прошлому запуску.
- Итог к прошлому циклу: в пределах ±8 %, иначе — объяснение в отчёте.
## Журнал изменений
| Дата | Параметр | Было → стало | WMAPE бэктеста до → после | Кто решил |
| 2026-09-15 | Окно истории | 24 → 36 мес. | 31,2 % → 29,8 % | планер KAZ | # ML forecast parameters — change only on my command
- Calculation level: city × SKU × month, units — thousand litres.
- Horizon: 18 months, starting from the cycle month.
- History window: the last 36 closed months.
- Model: gradient boosting; features — month, holidays, price, promo flags from the commercial calendar.
- Input: the cleaned baseline from /baseline-clean.
- New product: under 6 months of history — forecast from an analogue in the new-product list, flag "new" in the export.
- Delisting: forecast 0 from the delisting month.
- Code switch: the old code's history moves to the new code by the code-switch list.
- Backtest: the last 6 closed months, WMAPE after gluing codes.
- Naive forecast: the same month last year × the trend of the last 3 months.
- Stop rules: ML WMAPE no better than naive OR up by more than 5 p.p. vs the last run.
- Total vs last cycle: within ±8%, otherwise an explanation in the report.
## Change log
| Date | Parameter | Before → after | Backtest WMAPE before → after | Decided by |
| 2026-09-15 | History window | 24 → 36 months | 31.2% → 29.8% | KAZ planner | checks.md — что должно сойтись в результате. Каждая проверка — с действием «если не сошлось». Нашли новую ловушку — допишите строку, и она больше не повторится.
checks.md — what must reconcile in the result. Each check comes with an "if it fails" action. Found a new trap — add a line, and it won't happen again.
# Проверки результата прогноза ML
1. Сумма прогноза по городам = итог страны в каждом месяце. Расхождение больше 0 — стоп.
2. Нет отрицательных чисел. Есть — стоп, покажи строки.
3. В выгрузке все города страны из справочника городов. Пропал город — стоп.
4. У новинок с историей меньше 6 месяцев стоит флаг «новинка» и прогноз по аналогу. Нет флага — стоп.
5. У делистов прогноз = 0 с месяца делиста. Не 0 — стоп.
6. После переключения кода прогноз стоит на новом коде, на старом — 0. Иначе — стоп.
7. Итог на горизонт к прошлому циклу в пределах ±8 %. Больше — не стоп, но назови 5 строк, которые дали разницу.
8. Нет строк, где прогноз больше максимума истории ряда в 3 раза. Есть — покажи их мне. # ML forecast result checks
1. Sum of the forecast by city = the country total in every month. Any difference above 0 — stop.
2. No negative numbers. If there are — stop, show the rows.
3. The export has every city of the country from the city list. A city is missing — stop.
4. New products with under 6 months of history have the "new" flag and an analogue forecast. No flag — stop.
5. Delisted products have a forecast of 0 from the delisting month. Not 0 — stop.
6. After a code switch the forecast is on the new code, the old code has 0. Otherwise — stop.
7. Horizon total vs last cycle within ±8%. More — not a stop, but name the 5 rows that made the difference.
8. No rows where the forecast is above 3× the series' historical maximum. If there are — show them to me. Откройте Claude Code в папке проекта прогноза (урок 15-24) и наберите команду. Ниже — что примерно выведет Claude, если всё в порядке. Цифры учебные.
Open Claude Code in the forecast project folder (lesson 15-24) and type the command. Below is roughly what Claude prints when all is fine. The numbers are for training.
А так выглядит остановка — это нормальная, полезная работа навыка, а не сбой:
And this is what a stop looks like — normal, useful work of the skill, not a failure:
а) Написать навык по вашему процессу. Claude сам расспросит вас и соберёт папку. Лучше всего — сразу после того, как вы один раз прошли расчёт вместе.
a) Write the skill from your process. Claude will interview you and build the folder. Best done right after you've gone through the calculation together once.
Хочу упаковать мой ежемесячный расчёт прогноза ML в навык проекта .claude/skills/ml-forecast/. Сначала расспроси меня о процессе — по одному вопросу, жди ответа: откуда данные, какой скрипт считает, какие параметры, как я проверяю точность, когда я бы остановилась, куда кладу результат. Потом предложи: SKILL.md (запуск только моей командой, аргументы страна и цикл, стоп-правила на каждом шаге, отчёт в 5 строк), params.md с журналом изменений, checks.md с действием на каждую проверку. Покажи все тексты до сохранения. Исходные файлы не меняй.
I want to package my monthly ML forecast run into a project skill .claude/skills/ml-forecast/. First interview me about the process — one question at a time, wait for the answer: where the data comes from, which script calculates, what parameters, how I check accuracy, when I would stop, where I put the result. Then propose: SKILL.md (run only on my command, country and cycle arguments, stop rules at every step, a 5-line report), params.md with a change log, checks.md with an action for each check. Show me all texts before saving. Do not change source files.
б) После остановки: почему упала точность.
b) After a stop: why accuracy dropped.
Навык остановился: точность упала к прошлому запуску. Ничего не меняй. Разложи прирост ошибки: какие города, SKU и месяцы дали больше всего добавочной ошибки (абсолютно и долей от прироста). Для топ-10 строк проверь причины по порядку: неполная выгрузка, не склеенное переключение кода, новинка без флага, делист с прогнозом, разовое событие в факте (промо, дефицит). По каждой строке — одна вероятная причина и чем её подтвердить. Факты отдельно от догадок.
The skill stopped: accuracy dropped vs the last run. Change nothing. Break down the increase in error: which cities, SKUs and months added the most error (absolute and as a share of the increase). For the top 10 rows check the causes in order: incomplete export, unglued code switch, new product without a flag, delisted product with a forecast, a one-off event in the actual (promo, shortage). For each row — one likely cause and how to confirm it. Facts separate from guesses.
в) Изменить параметр осознанно. Никогда не «подкрутить, чтобы стало лучше» — только с проверкой «до/после» и записью.
c) Change a parameter deliberately. Never "tweak until it looks better" — only with a before/after test and a record.
Хочу проверить изменение параметра в params.md: окно истории 36 → 24 месяца. Сделай бэктест на тех же 6 месяцах с текущим и новым значением, рядом — наивный прогноз. Покажи WMAPE до и после по стране и по 5 крупнейшим городам. Результат текущего цикла не перезаписывай. Если я скажу «принимаю» — поменяй params.md и допиши строку в журнал изменений: дата, параметр, было → стало, WMAPE до → после, кто решил.
I want to test a parameter change in params.md: history window 36 → 24 months. Run the backtest on the same 6 months with the current and the new value, and the naive forecast alongside. Show WMAPE before and after for the country and for the 5 largest cities. Do not overwrite this cycle's result. If I say "accept" — change params.md and add a row to the change log: date, parameter, before → after, WMAPE before → after, decided by.
Прогноз считается от очищенной базовой линии. Поэтому навыков два, и они идут по порядку: сначала /baseline-clean (урок 15-30) — потом /ml-forecast. Каждый можно запустить отдельно и проверить отдельно.
The forecast is built from a cleaned baseline. So there are two skills, run in order: first /baseline-clean (lesson 15-30) — then /ml-forecast. Each can be run and checked separately.
Третий навык — «весь цикл». Когда оба работают чисто, можно сделать monthly-cycle: его SKILL.md — всего несколько шагов: «1. Выполни /baseline-clean $country $cycle. Остановился — стоп. 2. Выполни /ml-forecast $country $cycle. 3. Дай общий отчёт». Стоп-правила остаются внутри каждого навыка.
A third skill — "the whole cycle". Once both run cleanly, you can make monthly-cycle: its SKILL.md is just a few steps: "1. Run /baseline-clean $country $cycle. If it stopped — stop. 2. Run /ml-forecast $country $cycle. 3. Give a combined report". The stop rules stay inside each skill.
Для долгого расчёта есть поле context: fork: навык выполняется отдельным помощником (субагентом), а основной разговор остаётся свободным.
For a long calculation there is the context: fork field: the skill runs in a separate helper (sub-agent), and the main conversation stays free.
| ЧтоWhat | Что это значит для васWhat it means for you |
|---|---|
| Компьютер должен быть включёнThe computer must be on | Навык работает в Claude Code на вашем ноутбуке. Ноутбук уснул — расчёт всталThe skill runs in Claude Code on your laptop. The laptop slept — the run stopped |
| Библиотеки PythonPython libraries | Claude Code сам ставит нужные пакеты в отдельное окружение (venv). Если установка пакетов закрыта — попросите IT разрешить pipClaude Code installs the needed packages into a separate environment (venv). If package installs are blocked — ask IT to allow pip |
| Облачные задачи по расписаниюCloud scheduled tasks | Не видят ваш диск (урок 15-28). Для прогноза по файлам — задача в приложении или ручной запускCan't see your disk (lesson 15-28). For a forecast from files — a desktop app task or a manual run |
| Чат claude.aiclaude.ai chat | Навыки туда тоже загружают, но там разрешены только поля name, description, license, compatibility, metadata, allowed-tools. С arguments, argument-hint или disable-model-invocation загрузка выдаст ошибку, а команды !`…` там не выполняются. Этот навык — для Claude CodeSkills can be uploaded there too, but only the fields name, description, license, compatibility, metadata, allowed-tools are allowed. With arguments, argument-hint or disable-model-invocation the upload fails, and !`…` commands do not run there. This skill is for Claude Code |
| Команда /feedbackThe /feedback command | Никогда не вставляйте туда цифры компании: отзыв хранится у Anthropic 5 летNever paste company figures there: feedback is kept by Anthropic for 5 years |
Для каждой строки выберите файл навыка.
Choose the skill file for each line.
Правило из params.md: стоп, если WMAPE ML не лучше наивного или вырос больше чем на 5 п.п. к прошлому запуску.
The rule from params.md: stop if ML WMAPE is no better than naive or rose by more than 5 p.p. vs the last run.
Задача. «Долина напитков», страна учебная. Два запуска навыка: цикл 2026-10 (прошлый) и 2026-11 (текущий). Для простоты в файле один месяц бэктеста, тыс. л. В каждой строке — факт, прогноз ML и наивный прогноз. Нужно решить, отдаём ли прогноз 2026-11.
The task. Valley Beverages, a training country. Two skill runs: cycle 2026-10 (last) and 2026-11 (current). For simplicity the file has one backtest month, thousand litres. Each row has the actual, the ML forecast and the naive forecast. Decide whether the 2026-11 forecast goes out.
=ABS(E2-D2), затем сумма ошибок ÷ сумма факта. Или приложите CSV в чат и попросите Claude посчитать кодом. Calculate the WMAPE of the ML and the naive forecast for each run: Σ|forecast − actual| ÷ Σactual. In Excel: an error column =ABS(E2-D2), then the sum of errors ÷ the sum of actuals. Or attach the CSV to a chat and ask Claude to calculate it with code.| ЗапускRun | Σ фактΣ actual | Σ|ошибка| MLΣ|error| ML | WMAPE MLML WMAPE | Σ|ошибка| наивныйΣ|error| naive | WMAPE наивныйNaive WMAPE |
|---|---|---|---|---|---|
| 2026-10 | 3 200 | 284 | 8,9 %8.9% | 465 | 14,5 %14.5% |
| 2026-11 | 3 282 | 840 | 25,6 %25.6% | 988 | 30,1 %30.1% |
| 2026-11 после склейки2026-11 after gluing | 3 282 | 244 | 7,4 %7.4% | 448 | 13,6 %13.6% |
Задание 2 — стоп. ML лучше наивного (25,6 % против 30,1 %), но вырос к прошлому запуску на 16,7 п.п. (8,9 → 25,6) — больше порога 5 п.п. «Лучше наивного» само по себе не значит «можно отдавать».
Task 2 — stop. ML beats naive (25.6% vs 30.1%), but rose vs the last run by 16.7 p.p. (8.9 → 25.6) — above the 5 p.p. threshold. "Better than naive" alone doesn't mean "can go out".
Задание 3. Худшие: Каменск, Лимонад 1,5 л · код 218 — ошибка 300 (прогноз 0, факт 300); Каменск, Лимонад 1,5 л · код 117 — 298 (прогноз 388, факт 90); Каменск, Вода 0,5 л — 38. Первые две — одно переключение кода: продажи ушли на новый код, а прогноз остался на старом. Это ловит проверка 6 в checks.md, а лечит шаг 3 — склейка по справочнику переключений (новый код в справочник не внесли).
Task 3. The worst: Kamensk, Lemonade 1.5 L · code 218 — error 300 (forecast 0, actual 300); Kamensk, Lemonade 1.5 L · code 117 — 298 (forecast 388, actual 90); Kamensk, Water 0.5 L — 38. The first two are one code switch: sales moved to the new code, while the forecast stayed on the old one. Check 6 in checks.md catches it, and step 3 fixes it — gluing by the code-switch list (the new code wasn't added to the list).
Задание 4. Склеенная строка: факт 390, ML 388, наивный 360. WMAPE ML = 244 ÷ 3 282 = 7,4 % (точность 92,6 %), наивный — 448 ÷ 3 282 = 13,6 %. К прошлому запуску −1,5 п.п. — прогноз можно отдавать. Причину внесите в справочник переключений, а не правьте цифры руками.
Task 4. The glued row: actual 390, ML 388, naive 360. ML WMAPE = 244 ÷ 3,282 = 7.4% (accuracy 92.6%), naive — 448 ÷ 3,282 = 13.6%. vs the last run −1.5 p.p. — the forecast can go out. Fix the cause in the code-switch list, don't edit numbers by hand.
| ОшибкаMistake | Как правильноDo this instead |
|---|---|
| «Claude, посчитай прогноз» в разговоре каждый месяц"Claude, calculate the forecast" in a conversation every month | Расчёт — в скрипте и params.md, Claude только запускаетThe calculation lives in the script and params.md, Claude only runs it |
| Точность смотрят на уровне страныAccuracy is checked at country level | Город × SKU × месяц: на уровне страны ошибки городов гасят друг другаCity × SKU × month: at country level city errors cancel each other |
| Бэктест без склейки переключений кодовBacktest without gluing code switches | Склейка до расчёта и до бэктеста — на обе стороны: прогноз и фактGlue before calculating and before the backtest — on both sides: forecast and actual |
| Нет сравнения с наивным прогнозомNo comparison with the naive forecast | Наивный — обязательная линейка в каждом запускеNaive is a mandatory yardstick in every run |
| Параметр «подкрутили», и точность вырослаA parameter was "tweaked" and accuracy went up | Только запрос (в): бэктест до/после на тех же месяцах и строка в журнале измененийOnly request (c): before/after backtest on the same months and a row in the change log |
| Новый расчёт перезаписал файл прошлого циклаA new run overwrote last cycle's file | Имя файла несёт страну и цикл; существующий файл не перезаписыватьThe file name carries country and cycle; never overwrite an existing file |
| Остановку навыка считают сбоем и обходятA skill stop is treated as a failure and bypassed | Стоп — это работа навыка. Сначала причина (запрос б), потом решениеA stop is the skill doing its job. First the cause (request b), then the decision |
/ml-forecast KAZ 2026-11 → $country = KAZ, $cycle = 2026-11/ml-forecast KAZ 2026-11 → $country = KAZ, $cycle = 2026-11disable-model-invocation: truedisable-model-invocation: true!`python … || true` — вывод встаёт в текст навыка!`python … || true` — the output lands in the skill text${CLAUDE_SKILL_DIR} — без абсолютных путей${CLAUDE_SKILL_DIR} — no absolute paths/baseline-clean → /ml-forecast → по желанию /monthly-cycle/baseline-clean → /ml-forecast → optionally /monthly-cycle