фикс ASR (e-261005105252): venv-питон для faster-whisper + av 15.1.0 + докачка модели; фикс TimeoutExpired.pid (e-261005110300): Popen+killpg; systemone-bench влёжен
This commit is contained in:
parent
139fbb1202
commit
a1b9b4dfcb
7 changed files with 241 additions and 39 deletions
|
|
@ -8,7 +8,7 @@
|
||||||
| Путь | Что | Права | Бэкап | Ротация |
|
| Путь | Что | Права | Бэкап | Ротация |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| `/root/simbiot-harness/.env` | ROUTER_KEY, OPENROUTER_KEY, SIMBIOT_TG_TOKEN, SIMBIOT_TG_ALLOWED, ROUTER/OPENROUTER_BASE_URL | 600 | да (см. §6) | ROUTER_KEY — по политике 9router; TG-токен — при подозрении |
|
| `/root/simbiot-harness/.env` | ROUTER_KEY, OPENROUTER_KEY, SIMBIOT_TG_TOKEN, SIMBIOT_TG_ALLOWED, ROUTER/OPENROUTER_BASE_URL | 600 | да (см. §6) | ROUTER_KEY — по политике 9router; TG-токен — при подозрении |
|
||||||
| `/etc/simbiot/dashboard.env` | SIMBIOT_DASH_TOKEN (страница + /api/state, порт 8765 **открыт наружу 0.0.0.0**) | 600 | да | при демобилизации дашборда |
|
| `/etc/simbiot/dashboard.env` | SIMBIOT_DASH_TOKEN (страница + /api/state, порт 8765 **открыт наружу 0.0.0.0**). 02.10 сервис восстановлен: `systemd-run --unit=simbiot-dashboard -p EnvironmentFile=/etc/simbiot/dashboard.env -p Restart=on-failure /root/simbiot-harness/venv/bin/python /root/simbiot-harness/harness/dashboard.py` | 600 | да | при демобилизации дашборда |
|
||||||
| git-история `/root/simbiot-harness` | `.env` убран из трекинга (e6a99ce); **01.10 push в приватный репо https://git.cil.by/symbiot/simbiot-harness (3361b67..d39f60f)**: аудит — `.env` в истории отсутствует (0 коммитов), скан sk-/bot/rsh/Bearer по git log -p --all чист. Утечки не было. | — | n/a | токен Forgejo symbiot (9f29709…) — admin-скоп, ротация при компрометации; в репо не хранить |
|
| git-история `/root/simbiot-harness` | `.env` убран из трекинга (e6a99ce); **01.10 push в приватный репо https://git.cil.by/symbiot/simbiot-harness (3361b67..d39f60f)**: аудит — `.env` в истории отсутствует (0 коммитов), скан sk-/bot/rsh/Bearer по git log -p --all чист. Утечки не было. | — | n/a | токен Forgejo symbiot (9f29709…) — admin-скоп, ротация при компрометации; в репо не хранить |
|
||||||
|
|
||||||
## 2. Наследие агента Гермес (живое, сервисы active)
|
## 2. Наследие агента Гермес (живое, сервисы active)
|
||||||
|
|
|
||||||
12
docs/candidates/boogvar-bugaev.md
Normal file
12
docs/candidates/boogvar-bugaev.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Кандидат в лабу: Владимир Бугаев (boogvar)
|
||||||
|
|
||||||
|
- GitHub / LinkedIn: **BoogVAr** / boogvar (linkedin.com/in/boogvar)
|
||||||
|
- Автор **TessariDB** (tessaridb.com): мультимодельная БД — один стор, 11 движков
|
||||||
|
(документы, полнотекст, векторы, кэш, очереди, топики, геометрия, time-series,
|
||||||
|
графы, стримы), язык TessariQL, одна транзакция поверх всего.
|
||||||
|
Лицензия BSL 1.1 (free in prod). 0.23.0-beta.
|
||||||
|
- Связь с кооперативом: Alex работал с ним вместе в **Neon Labs** (neon-labs.org),
|
||||||
|
Alex был там CTO.
|
||||||
|
- Статус (2026-10-03): кандидат в лабу «на пробу», решение за Alex.
|
||||||
|
- Вводные, которых ждём: чем конкретно займётся, сколько времени готов вкладывать,
|
||||||
|
формат пробы, канал связи.
|
||||||
105
docs/systemone-bench-integration.md
Normal file
105
docs/systemone-bench-integration.md
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
# systemone-bench: интеграция decision-модели в цикл харнеса
|
||||||
|
|
||||||
|
Задача: t-261005074437-39a9b0 · код: /root/systemone-bench (clone symbiot/systemone-bench @ git.cil.by)
|
||||||
|
Дата: 2026-10-05. Скилл: `skills/systemone-bench/SKILL.md`.
|
||||||
|
|
||||||
|
## 1. Что внедрено (валидация этого тика)
|
||||||
|
|
||||||
|
| Проверка | Результат |
|
||||||
|
|---|---|
|
||||||
|
| `ga/ga.py --smoke` | зелёный: 3 520 симуляций, 13 с, GA бьёт greedy/random, 0 опасных команд в best |
|
||||||
|
| `harness/hier.py --model nimble --quick` | зелёный: e2e 81.2% (16 кейсов), stage1 top-2 hit 93.8%, stage3 gold #1 = 100%, flat-64 = 0% (отказ эндпоинта >26 опций) |
|
||||||
|
| `ga/ga2.py --neardeath` | воспроизведён, см. §3 |
|
||||||
|
|
||||||
|
Эндпоинт `http://127.0.0.1:11434/v1/systemone` (модель nimble, qwen3.5-9B Q8_0) доступен из WSL-окружения харнеса напрямую — можно дергать на тиках.
|
||||||
|
|
||||||
|
## 2. Схема выбора для тиков харнеса (рекомендация №1 из README)
|
||||||
|
|
||||||
|
Когда на тике нужно выбрать одно действие из >9 однородных кандидатов:
|
||||||
|
|
||||||
|
```
|
||||||
|
кандидаты (до 64)
|
||||||
|
→ stage1: score по группам → TOP-2 группы (не top-1!)
|
||||||
|
→ stage2: choice по объединённому шортлисту ≤ 9
|
||||||
|
→ (опц.) stage3: score для параметров выбранного действия
|
||||||
|
```
|
||||||
|
|
||||||
|
Почему именно так (метрики сессии 2026-10-04 + quick-прогона):
|
||||||
|
- flat-choice по 64 опциям невозможен (контракт 2–26) и падает до 0%;
|
||||||
|
- top-2 группы поднимают recall до 84–94% (у ~40% команд «второй дом» в таксономии);
|
||||||
|
- шортлист ≤ 9 — точность 100% на 6 → 50% на 10, отсечка строго 9;
|
||||||
|
- расчётный e2e: 57.8% → ~78%; полный конвейер ~520–580 мс.
|
||||||
|
|
||||||
|
Контракт: `choice` — criteria объект; `score` — criteria массив (`Σ i·pᵢ`);
|
||||||
|
`noul` — P(да); `confidence` — концентрация, НЕ вероятность правильности.
|
||||||
|
|
||||||
|
## 3. Эксперимент near-death (ga2 --neardeath, воспроизведён 2026-10-05)
|
||||||
|
|
||||||
|
Вопрос: берёт ли GA деструктивные команды (layoff_20pct, delay_payroll), когда
|
||||||
|
капитал на исходе?
|
||||||
|
|
||||||
|
| Сценарий | Горизонт | GA best fitness | Опасные в top-5 | nimble (LLM) |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| dying | 4н | 10 272, выжил | **0/5** (3/160 в популяции) | 3 704, выжил |
|
||||||
|
| dying | 8н | 11 483, выжил | **0/5** (28/160, 18%) | **−999 825, умер н.7** |
|
||||||
|
| dying_hard | 4н | 10 175, выжил | **0/5** (4/160) | **−999 900, умер н.4** |
|
||||||
|
| dying_hard | 8н | 10 635, выжил | **0/5** (18/160, 11%) | **−999 900, умер н.4** |
|
||||||
|
|
||||||
|
Выводы:
|
||||||
|
1. GA **ни в одном top-5 не взял** layoff/delay_payroll даже при предсмертном
|
||||||
|
runway — спасается монетизацией: `add_premium → raise_prices → winback`,
|
||||||
|
а на 8н первым ходом `sell_secondary` (продажа вторички = мгновенный кэш).
|
||||||
|
2. LLM-политика nimble в dying_hard **умирает во всех прогонах**, GA — выживает:
|
||||||
|
для near-death режимов GA-политика строго доминирует эвристики модели.
|
||||||
|
3. Подтверждена дыра симулятора: `sell_secondary` даёт +100 personal cash без
|
||||||
|
штрафа за здоровье компании → GA эксплуатирует. Нужен гейт по health
|
||||||
|
(фитнес × флаг health>порог или штраф за dilution) — TODO для ga3.
|
||||||
|
4. Дрейф опасных генов в популяции с ростом горизонта (2% → 18%) — сигнал, что
|
||||||
|
отбор давит их только на коротких горизонтах; на длинных нужен явный штраф,
|
||||||
|
иначе риск дрейфа лучшего генома.
|
||||||
|
|
||||||
|
## 4. Объединение GA-петель: systemone-bench × aum-pilot
|
||||||
|
|
||||||
|
Сейчас две генетические петли живут раздельно:
|
||||||
|
|
||||||
|
| | aum-pilot (репо харнеса) | systemone-bench GA |
|
||||||
|
|---|---|---|
|
||||||
|
| Геном | конфиг burn `{volume_mult, flash_share}` | последовательность команд стартапа |
|
||||||
|
| Фитнес | E[ΔAUM 365д] (плейсхолдер-модель) | терминальный AUM основателя (симулятор) |
|
||||||
|
| Симулятор | аналитическая модель продуктивности | недельные тики стартапа, MC |
|
||||||
|
| Что общее | **одна и та же целевая переменная: AUM на горизонте** | |
|
||||||
|
|
||||||
|
Предложение по сшивке (порядок шагов, не менять сразу всё):
|
||||||
|
|
||||||
|
1. **Общий словарь AUM.** Завести `docs/aum/balances.json` (это уже блокер
|
||||||
|
пилота) и выразить фитнес обеих петель в одной валюте — ΔAUM в у.е. на
|
||||||
|
горизонте. Пока balances.json нет, обе петли остаются в своих нативных
|
||||||
|
единицах, но логируются в одном формате события (`aum_delta`, `horizon`,
|
||||||
|
`source`).
|
||||||
|
2. **GA-движок один.** Ядро ga.py (популяция, отбор, мутации, MC-оценка) —
|
||||||
|
переиспользовать как общий движок: aum-pilot уже умеет seed/детерминизм,
|
||||||
|
systemone-bench — multiprocessing. Вынести в один модуль с двумя fitness-
|
||||||
|
функциями (конфиг → ΔAUM; политика → ΔAUM).
|
||||||
|
3. **Decision-модель как policy-инициализатор GA.** nimble генерирует
|
||||||
|
кандидатов-политик (stage1/stage2 схема из §2) → GA дорабатывает
|
||||||
|
последовательности → лучший геном идёт в Advocate-слой (день/Alex).
|
||||||
|
В ga2 это режим hybrid (hyb_llmG): уже сейчас LLM-инициализация улучшает
|
||||||
|
wait/nimble-бейслайны, но проигрывает чистому greedy/GA-специалисту —
|
||||||
|
поэтому LLM = источник разнообразия, не финальный отбор.
|
||||||
|
4. **Гейты безопасности из §3.** Любая петля, где фитнес включает personal
|
||||||
|
cash, получает гейт здоровья компании (дыра sell_secondary) и явный штраф
|
||||||
|
за деструктивные гены на длинных горизонтах (дрейф 2%→18%).
|
||||||
|
|
||||||
|
Эффект для AUM: одна петля «замер → симуляция → отбор → адвокат» вместо двух
|
||||||
|
распараллеленных, каждая итерация которой проверяется на реальном burn
|
||||||
|
(9router) и реальных решениях харнеса.
|
||||||
|
|
||||||
|
## 5. Открытые TODO (вне этой задачи)
|
||||||
|
|
||||||
|
- [ ] ga3: гейт health в фитнесе (дыра sell_secondary) + штраф деструктивных
|
||||||
|
генов на длинных горизонтах
|
||||||
|
- [ ] ga2 --robust (максимин по 4 сценариям) — не запускался в этом тике,
|
||||||
|
следующий шаг экспериментов
|
||||||
|
- [ ] Балансировка: замерить e2e ~78% расчётной схемы на полном 64-кейсовом
|
||||||
|
наборе (не только quick-16)
|
||||||
|
- [ ] `docs/aum/balances.json` — ручной ввод Alex (блокер пункта 1 §4)
|
||||||
|
|
@ -50,48 +50,36 @@ def run_llm_tick(level_cfg, prompt: str, session_id=None, trace_prefix=None, tim
|
||||||
# просто поглощает такты (TickAbsorbed), это норма архитектуры
|
# просто поглощает такты (TickAbsorbed), это норма архитектуры
|
||||||
timeout = getattr(level_cfg, "tick_timeout", 300)
|
timeout = getattr(level_cfg, "tick_timeout", 300)
|
||||||
timeout = max(timeout, int(level_cfg.every * 0.8))
|
timeout = max(timeout, int(level_cfg.every * 0.8))
|
||||||
try:
|
# e-261005110300: раньше subprocess.run + /proc/{e.pid}/status → у
|
||||||
proc = subprocess.run(
|
# TimeoutExpired НЕТ pid, обработчик валило AttributeError'ом и маскировал
|
||||||
|
# нормальный SchedulerTimeout (тик «упал» вместо «убит по таймауту»).
|
||||||
|
# Теперь: Popen в СВОЕЙ сессии (pgid = pid воркера, дети в той же группе)
|
||||||
|
# + communicate(timeout) → по таймауту убиваем ГРУППУ целиком и ждём
|
||||||
|
# фактической смерти (сироты-LLM-подпроцессы, race со стором — в прошлом).
|
||||||
|
proc = subprocess.Popen(
|
||||||
[_VENV_PY, _WORKER],
|
[_VENV_PY, _WORKER],
|
||||||
input=json.dumps(payload).encode(),
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
capture_output=True,
|
cwd=_HARNESS_DIR, env=env, start_new_session=True,
|
||||||
timeout=timeout,
|
|
||||||
cwd=_HARNESS_DIR,
|
|
||||||
env=env,
|
|
||||||
)
|
)
|
||||||
except subprocess.TimeoutExpired as e:
|
try:
|
||||||
# воркер убит по таймауту. subprocess.run убивает только основной
|
out_bytes, err_bytes = proc.communicate(
|
||||||
# процесс (Popen.kill через os.kill без группы) — сабпроцесс _llm_worker
|
input=json.dumps(payload).encode(), timeout=timeout)
|
||||||
# успевал сам заспавнить LLM-подпроцессы, которые оставались ЖИВЫМИ и
|
except subprocess.TimeoutExpired:
|
||||||
# продолжали писать в стор после SchedulerTimeout (BudgetSpent/ToolCalled
|
|
||||||
# с завершённым trace — race, burn 9router, t-261002090242-cf7cf9).
|
|
||||||
# Добиваем всю процесс-группу и ЖДЁМ фактической смерти.
|
# Добиваем всю процесс-группу и ЖДЁМ фактической смерти.
|
||||||
pgid = None
|
|
||||||
try:
|
try:
|
||||||
with open(f"/proc/{e.pid}/status") as f:
|
os.killpg(proc.pid, signal.SIGKILL)
|
||||||
for line in f:
|
|
||||||
if line.startswith("Tgid:"):
|
|
||||||
pgid = line.split()[1]
|
|
||||||
break
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
if e.pid > 1:
|
|
||||||
os.killpg(pgid or e.pid, signal.SIGKILL)
|
|
||||||
except (ProcessLookupError, PermissionError, OSError):
|
except (ProcessLookupError, PermissionError, OSError):
|
||||||
pass
|
pass
|
||||||
for _ in range(10): # до 5с на смерть группы, иначе — SIGKILL ещё раз
|
|
||||||
try:
|
try:
|
||||||
os.killpg(pgid or e.pid, 0)
|
proc.communicate(timeout=10) # reap: собираем зомби, чистим пайпы
|
||||||
time.sleep(0.5)
|
except subprocess.TimeoutExpired:
|
||||||
except (ProcessLookupError, PermissionError) as ex:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
os.killpg(pgid or e.pid, signal.SIGKILL)
|
|
||||||
except OSError:
|
|
||||||
pass
|
pass
|
||||||
raise
|
raise
|
||||||
|
# у_Popen нет полей stdout/stderr: для ошибок ниже используем собранное
|
||||||
|
if out_bytes is None:
|
||||||
|
out_bytes = b""
|
||||||
|
if err_bytes is None:
|
||||||
|
err_bytes = b""
|
||||||
out = None
|
out = None
|
||||||
if os.path.exists(result_path):
|
if os.path.exists(result_path):
|
||||||
try:
|
try:
|
||||||
|
|
@ -104,7 +92,7 @@ def run_llm_tick(level_cfg, prompt: str, session_id=None, trace_prefix=None, tim
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
if out is None:
|
if out is None:
|
||||||
return None, {"error": f"worker result file missing: stdout={(proc.stdout or b'')[:200]!r} stderr={(proc.stderr or b'').decode(errors='replace')[-300:]}"}, None
|
return None, {"error": f"worker result file missing: stdout={out_bytes[:200]!r} stderr={err_bytes.decode(errors='replace')[-300:]}"}, None
|
||||||
if not out.get("ok"):
|
if not out.get("ok"):
|
||||||
return None, {"error": (out.get("error") or "unknown")[:500]}, None
|
return None, {"error": (out.get("error") or "unknown")[:500]}, None
|
||||||
return out.get("text", ""), out.get("usage", {}), out.get("trace_id")
|
return out.get("text", ""), out.get("usage", {}), out.get("trace_id")
|
||||||
|
|
@ -31,7 +31,8 @@ from . import es
|
||||||
_HARNESS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
_HARNESS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
_ENV_PATH = os.path.join(_HARNESS_DIR, ".env")
|
_ENV_PATH = os.path.join(_HARNESS_DIR, ".env")
|
||||||
_FW_WORKER = os.path.join(_HARNESS_DIR, "harness", "_fw_asr_worker.py")
|
_FW_WORKER = os.path.join(_HARNESS_DIR, "harness", "_fw_asr_worker.py")
|
||||||
_FW_PYTHON = "/usr/bin/python3" # faster-whisper живёт в системном python
|
_FW_PYTHON = os.environ.get("SIMBIOT_FW_PYTHON") or os.path.join(
|
||||||
|
_HARNESS_DIR, "venv", "bin", "python") # faster-whisper живёт в venv харнеса
|
||||||
|
|
||||||
ASR_URL = os.environ.get("SIMBIOT_ASR_URL", "http://127.0.0.1:8084")
|
ASR_URL = os.environ.get("SIMBIOT_ASR_URL", "http://127.0.0.1:8084")
|
||||||
# что расшифровываем: voice — главное; audio/video_note — та же речь
|
# что расшифровываем: voice — главное; audio/video_note — та же речь
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `meta-skill-factory` | Метаскилл: превращение повторяющейся работы в скилл репо (шаги, чеклисты, критерии качества) | Заметил, что делаю одну и ту же работу 2+ раз — прежде чем делать руками в третий |
|
| `meta-skill-factory` | Метаскилл: превращение повторяющейся работы в скилл репо (шаги, чеклисты, критерии качества) | Заметил, что делаю одну и ту же работу 2+ раз — прежде чем делать руками в третий |
|
||||||
| `presale-landing` | Производство пресейл/продуктовых лендингов: структура, честные мокапы, Stripe CTA, quality gates | Задача на лендинг/пресейл-страницу или её v2 |
|
| `presale-landing` | Производство пресейл/продуктовых лендингов: структура, честные мокапы, Stripe CTA, quality gates | Задача на лендинг/пресейл-страницу или её v2 |
|
||||||
|
| `systemone-bench` | Decision-эндпоинт Ollama /v1/systemone (nimble) + GA-оптимизация: иерархический выбор top-2 группы → choice ≤9, GA последовательностей действий с фитнесом=AUM | Тик, где нужно выбрать одно действие из >9 однородных опций; оптимизация политик на симуляторе |
|
||||||
|
|
||||||
## Сторонние наборы
|
## Сторонние наборы
|
||||||
|
|
||||||
|
|
|
||||||
95
skills/systemone-bench/SKILL.md
Normal file
95
skills/systemone-bench/SKILL.md
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
---
|
||||||
|
name: systemone-bench
|
||||||
|
description: Use when choosing between 3+ non-numeric action options via local Ollama decision endpoint (/v1/systemone, model nimble), or when optimizing action sequences with GA against a simulator. Turns "which of many options" into a measured, hierarchical choice instead of free-form LLM guessing.
|
||||||
|
metadata:
|
||||||
|
origin: t-261005074437-39a9b0 (внедрение systemone-bench в архитектуру харнеса)
|
||||||
|
code: /root/systemone-bench (clone symbiot/systemone-bench @ git.cil.by; README.md там же)
|
||||||
|
scope: любые тики харнеса, где нужен выбор действия из каталога >9 кандидатов; симуляция политик стартапа
|
||||||
|
---
|
||||||
|
|
||||||
|
# systemone-bench: decision-эндпоинт + GA-оптимизация выбора
|
||||||
|
|
||||||
|
## Trigger rule
|
||||||
|
|
||||||
|
- [ ] Нужно выбрать ОДНО действие из >9 однородных опций (команды, конфиги, политики)
|
||||||
|
- [ ] Опции разбиты (или разбиваются) на группы по 2–8 в группе
|
||||||
|
- [ ] Есть критерий качества выбора (fitness / AUM / метрика), хотя бы приблизительный
|
||||||
|
- [ ] Нужен выбор на симуляторе перед применением в бою (бесплатные прогоны)
|
||||||
|
|
||||||
|
Не использовать: для бинарных решений (это noul), для абсолютных оценок тяжести
|
||||||
|
(score плох на абсолютных шкалах — подтверждено сюитом), если опций ≤ 9 (делай
|
||||||
|
обычный choice без иерархии).
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
### 1. Проверка окружения
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s http://127.0.0.1:11434/api/tags | grep -o '"nimble"' # модель на месте
|
||||||
|
cd /root/systemone-bench && python3 ga/ga.py --smoke # ~13с, должен быть зелёный
|
||||||
|
cd /root/systemone-bench && python3 harness/hier.py --model nimble --quick # ~мин, e2e ~81% на quick-16
|
||||||
|
```
|
||||||
|
|
||||||
|
Контракт эндпоинта: `choice` — criteria **объект**, 2–26 опций; `score` —
|
||||||
|
criteria **массив** 2–26 уровней, `score = Σ i·pᵢ`; `noul` — вероятность «да».
|
||||||
|
1–64 вопроса на запрос, тело ≤ 64 KiB, промпт ≤ 8194 токенов. `confidence` =
|
||||||
|
концентрация распределения, НЕ вероятность правильности — не опирайся на него
|
||||||
|
как на calibration.
|
||||||
|
|
||||||
|
### 2. Схема выбора: top-2 группы → choice по шортлисту ≤ 9
|
||||||
|
|
||||||
|
Главная рекомендация (README, рекомендация №1): flat-choice по всем 64 командам
|
||||||
|
падает до 0% (эндпоинт режет >26 и точность падает), иерархия:
|
||||||
|
|
||||||
|
1. **stage1 (score)**: по группам (8 групп) — взять **top-2** группы, не top-1
|
||||||
|
(top-2 hit 93.8–84.4% vs top-1 87.5–64.1% — у ~40% команд легитимный
|
||||||
|
«второй дом» в таксономии).
|
||||||
|
2. **stage2 (choice)**: объединённый шортлист кандидатов из двух групп —
|
||||||
|
**строго ≤ 9** (точность 100% на шортлисте 6 → 50% на 10).
|
||||||
|
3. **stage3 (score)**: если выбранная команда имеет параметры — ранжирование
|
||||||
|
значений score-массивом (gold #1 в 96.9–100%).
|
||||||
|
|
||||||
|
Расчётный эффект: e2e 57.8% → ~78% (top-2 выборка × stage2 92%). Латентность
|
||||||
|
полного конвейера ~520–580 мс — годится для тика, не для realtime.
|
||||||
|
|
||||||
|
### 3. GA: поиск последовательностей действий
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/systemone-bench && python3 ga/ga.py # полный прогон (pop 200 × 100 gen, ~17с)
|
||||||
|
python3 ga/ga2.py --neardeath # при каком runway GA берёт опасные команды (layoff/delay_payroll)
|
||||||
|
python3 ga/ga2.py --robust # максимин по crunch/base/growth/dying
|
||||||
|
```
|
||||||
|
|
||||||
|
Фитнес = терминальный AUM основателя. GA бьёт greedy на +27–43% (8 нед) и
|
||||||
|
random search до +59%. Что уже известно (не переоткрывать):
|
||||||
|
|
||||||
|
- GA эмерджентно строит цепочки пререкрешитов (pricing_power → raise_prices_10).
|
||||||
|
- Опасные команды не выбирает при runway ≥ 2.5 мес — сигналят о реальном риске.
|
||||||
|
- **Дыра (найдена smoke-прогоном)**: `sell_secondary` даёт +100 personal cash и
|
||||||
|
спасает dying без опасных команд — симулятор вознаграждает личный кэш без
|
||||||
|
штрафа за health компании. Обход: гейт по здоровью компании (напр., фитнес
|
||||||
|
умножается на флаг health > порога, или штраф за dilution в personal cash).
|
||||||
|
|
||||||
|
### 4. Интеграция в тик харнеса
|
||||||
|
|
||||||
|
На тиках, где нужен выбор действия: собрать кандидатов → разбить на группы →
|
||||||
|
stage1 score (top-2) → choice ≤9 → применить → записать выбор и исход событием
|
||||||
|
в стор (для последующей GA-сшивки policy trace с fitness).
|
||||||
|
|
||||||
|
## Quality gates
|
||||||
|
|
||||||
|
- Шортлист stage2 **всегда ≤ 9**; если объединение top-2 групп даёт >9 — режь
|
||||||
|
по stage1-score внутри групп.
|
||||||
|
- stage1 всегда top-2, никогда top-1.
|
||||||
|
- Для тяжести/абсолютов не использовать score — только ранжирование однородного.
|
||||||
|
- Прогон ga/ga.py --smoke обязателен перед использованием GA-результатов.
|
||||||
|
- Результат каждого GA-эксперимента фиксировать событием на доску (cli.py task/complete
|
||||||
|
или event), не оставлять только в ga2-results.json.
|
||||||
|
- Не доверять `confidence` как вероятности правильности.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- README.md репо /root/systemone-bench — контракт эндпоинта, все метрики сессии 2026-10-04
|
||||||
|
- harness/eval.py — 5 сюитов (шортлист, permutation, noul, score-тяжесть, батчинг)
|
||||||
|
- ga/ga.py, ga/ga2.py — GA и сценарные эксперименты; ga-results.json, ga2-results.json
|
||||||
|
- docs/systemone-bench-integration.md (репо харнеса) — интеграция и связь с AUM-петлёй
|
||||||
Loading…
Reference in a new issue