From 83e75e7c2469484306daf4aa3eaca494cf04e5ae Mon Sep 17 00:00:00 2001 From: root Date: Sat, 25 Jul 2026 13:31:04 +0000 Subject: [PATCH] docs(tasks): add B11 (Anthropic -> local Ollama) and B12 (ISRID priors) Both are Section B (needs-context): B11 touches the AnalysisResult contract and the question of where an LLM is needed at all; B12 touches scoring coefficients and the DB schema, which project rules keep off limits to automated edits. B11 records the key finding that the LLM does not compute priorities -- the math already lives in geo_service/scoring_service/psychotype_service and analyze_with_fallback already returns a full AnalysisResult with no API. The only unique in-hot-path LLM role is parsing free-text reports, so a strict intake form and a local provider are independent levers. B12 notes ISRID supplies empirical priors for the currently hand-tuned zone weights, with the legal status of the database flagged as a blocking question to resolve before any data enters the repo. Summary table updated to B1-B12. Co-Authored-By: Claude Opus 5 (1M context) --- vector_tasks.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/vector_tasks.md b/vector_tasks.md index bab98bd..3252b76 100644 --- a/vector_tasks.md +++ b/vector_tasks.md @@ -627,6 +627,40 @@ sed -i 's/sar_mchs/vector_mchs/g; s#/root/sar-mchs#/root/vector#g' DEPLOY.md ## B10 — Секреты и деплой (`.env`) **Тип:** security/deploy, исключено из делегирования. `.env` содержит плейсхолдеры `ANTHROPIC_API_KEY=your_...` и слабый `JWT_SECRET=your_jwt_secret_here_change_in_production`. Установка реального ключа Claude (для выхода из fallback) и генерация стойкого `JWT_SECRET` — ручная операция с секретами. +## B11 — Переход с Anthropic API на локальный Ollama +**Тип:** архитектура / приватность, needs-context. Исключено из делегирования: затрагивает контракт `AnalysisResult` и границу «где вообще нужна LLM». + +**Мотив:** данные о пропавших без вести (особенно о детях) не должны покидать контур. Сейчас `backend/services/claude_service.py` ходит во внешний Anthropic API. Целевой провайдер — локальная Ollama (lxc200 на pve-node2, 192.168.0.17, уже поднята под OpenHands). + +**Ключевой факт для решения:** LLM НЕ считает приоритеты. Вся математика уже в `geo_service.build_search_zones` + `scoring_service.WeightedScorer` (7 взвешенных факторов + множители по возрасту/сезону/профилю) + `psychotype_service`. Метод `analyze_with_fallback` уже отдаёт полноценный `AnalysisResult` вообще без API. Единственная уникальная роль модели в hot-path — разбор неструктурированного текста донесения в поля `profiles`/`circumstances`; остальное (`behavioral_prediction`, `immediate_actions`, `summary`) — переупаковка уже отранжированного топ-5. + +**Отсюда два независимых рычага (не взаимоисключающие):** +1. Строгая категоризованная форма ввода (чипы/дропдауны/числа) — убирает саму НЕОБХОДИМОСТЬ в LLM, скоринг становится чистой математикой. Свободнотекстовое поле `circumstances` оставить для чтения человеком. +2. Локальная модель — сохраняет LLM, но переносит провайдера внутрь контура. Недетерминизм и риск галлюцинаций при этом НЕ исчезают. + +**Рекомендуемая слоёная схема:** скоринг ВСЕГДА детерминированный (то есть инвертировать текущую логику — сегодняшний fallback становится основным путём, а не аварийным); форма — способ ввода по умолчанию; Ollama — опциональный ЧЕРНОВОЙ парсер, который предзаполняет форму для подтверждения оператором, никогда не имеет решающего слова и никогда не считает приоритеты. + +**Объём работ:** абстрагировать провайдера за интерфейсом (сейчас класс жёстко завязан на пакет `anthropic`), вынести выбор в конфиг (`LLM_PROVIDER`, `OLLAMA_BASE_URL`, имя модели), учесть отсутствие у Ollama нативного tool-use и более слабое следование формату JSON (из-за этого B2 — устойчивое извлечение JSON — становится критичным), покрыть тестами оба провайдера. Отдельно решить судьбу `ANTHROPIC_API_KEY` в `.env` (см. B10). + +**Зависимости:** пересекается с B2 (парсинг JSON) и B10 (секреты). Делать после решения по B4 (мёртвая мобильная форма) — иначе неясно, какая форма ввода целевая. + +## B12 — Внесение данных из ISRID (международная база инцидентов ПСР) +**Тип:** данные / доменная модель, needs-context. Исключено из делегирования: напрямую затрагивает коэффициенты скоринга и схему БД. + +**Что это:** ISRID (International Search & Rescue Incident Database, Robert Koester, «Lost Person Behavior») — международная база инцидентов поисково-спасательных операций со статистикой поведения потерявшихся по категориям субъекта: кольцевые модели и модели рассеивания (дистанции по процентилям от точки потери), типовые места обнаружения, зависимость от рельефа и категории субъекта. + +**Зачем именно нам:** сейчас веса зонального скоринга (`forest 0.25`, `water 0.20`, …) и радиусы зон заданы вручную, экспертно. ISRID даёт внешние ЭМПИРИЧЕСКИЕ априорные значения для тех же величин по международной выборке — это позволяет заменить часть догадок статистикой и резко снижает объём собственных данных, нужный для калибровки. + +**Как стыкуется с планом по 14-летнему архиву спецдонесений:** ISRID — источник априорных значений, собственный архив — источник локальной калибровки (местная специфика: рельеф, климат, структура вызовов). Правильный порядок — сначала ISRID как базовая линия, затем поправки по своим данным. Именно эта комбинация делает переход к чисто статистической модели реалистичным. + +**Что нужно решить до начала:** +- **Правовой статус — блокирующий вопрос.** ISRID не является свободно распространяемой базой: доступ к данным и производным моделям регулируется автором/правообладателем. Условия использования (в частности, допустимость зашивать производные коэффициенты в наш продукт) нужно выяснить ДО внесения каких-либо данных в репозиторий. Вопрос не технический. +- **Единицы и категории.** Категории субъекта в ISRID (hiker, dementia, child по возрастным группам, autism, …) не совпадают один-к-одному с нашими профилями; дистанции даны в своих единицах и привязаны к типу местности. Нужны явные словари соответствия и решение, что делать с профилями без аналога. +- **Редкие профили.** По РАС и эпилепсии выборки малы даже в ISRID — там сохранить экспертные коэффициенты и помечать их как «не выведенные из данных». +- **Куда кладём.** Отдельный версионированный справочник априорных значений с указанием источника на каждую величину, а не правка констант в коде: нужно всегда понимать, какое число откуда взялось (ISRID / свой архив / эксперт). + +**Жёсткое правило:** ни ISRID, ни архив не дают права автоматически перезаписывать формулу весов — изменение коэффициентов проходит через ревью человека (см. B1 и «Жёсткие исключения» в начале файла). + --- # Сводка @@ -635,6 +669,6 @@ sed -i 's/sar_mchs/vector_mchs/g; s#/root/sar-mchs#/root/vector#g' DEPLOY.md |---|---|---| | Atomic (backend) | A1–A9 | локальной LLM | | Atomic (frontend) | A10–A16 | локальной LLM | -| Needs-context | B1–B10 | сильной модели / человеку | +| Needs-context | B1–B12 | сильной модели / человеку | **Рекомендуемый порядок для локальной модели:** A8 и A7 первыми (чистка мёртвого кода и зелёный CI дают чистую базу для проверки остальных), затем backend A1–A6, затем docs A9, затем frontend A10–A16. После каждой backend-задачи прогонять `PYTHONPATH=/root/vector python -m pytest backend/tests -q`.