docs(history): AI-ассистент документации — эндпоинт, виджет, деплой

This commit is contained in:
Repinoid
2026-10-07 14:38:18 +03:00
parent c59f0245b5
commit ad2de6df62
+73
View File
@@ -0,0 +1,73 @@
# tf_docs: AI-ассистент документации (эндпоинт + виджет)
Дата: 2026-10-07
## Что сделано
Реализован AI-ассистент по документации Nubes: пользователь задаёт вопрос на сайте,
получает ответ по строгому шаблону со ссылками-источниками.
Схема:
```
Браузер (виджет assistant.js)
│ POST /<stand>/_api/assist {question}
▼
tf_docs (NodeJS, кластер nodejsk8s)
│-- validateInput / rate-limit / семафор / дедлайн / кэш / дедуп
│-- Этап 1: LLM → resource_type (по списку реальных nubes_* из индекса)
│-- Поиск: search_index.json (с VM) → объединение (П.8) → top-K
│-- Этап 2: LLM → ответ по шаблону Роль/Задача/Контекст/Требования/Ограничения
▼
Ответ {answer, sources[], meta}
```
Индекс тянется с `VM_DOCS_BASE_URL/<stand>/search/search_index.json` (ВМ 213 отдаёт
статику; в `tf_docs` — т.к. сервис теперь не только 302-роутер).
## Новые файлы (tf_docs)
| Файл | Назначение |
|---|---|
| `assist.js` | каркас: validateInput (413/415/400), rate-limit, семафор, llmChat, jsonError |
| `search.js` | лексический поиск: HTML-clean, буст страницам ресурсов, транслит кириллица→латиница, подресурс→родитель |
| `stage1.js` | этап 1: `resource_type` через LLM (`response_format: json_object`) |
| `stage2.js` | объединение поиска (П.8) + этап 2 (строгий шаблон, 502 при нарушении) |
| `orchestrator.js` | оркестратор: дедлайн 40с, rate-limit, семафор=4, дедуп одинаковых запросов, отмена по `req.close` |
| `llm_project/` | бриф, план по шагам, пробник api.aillm.ru, эталонные вопросы, оценки |
## Изменения существующих
- `server.js` — ветка `POST /<stand>/_api/assist` ДО проверки 405; загрузка `orchestrator.js` в try/catch (не роняет статику).
- `Dockerfile` — добавлены `assist.js search.js stage1.js stage2.js orchestrator.js`.
- `README.md` — эндпоинт и переменные окружения.
- `tf_provider`: `docs/30_registry/javascripts/assistant.js` (виджет), `extra.css` (стили), `mkdocs.yml` (`extra_javascript`).
## Переменные окружения (jsonEnv в ЛК)
```json
{
"VM_DOCS_BASE_URL": "http://5.172.178.213",
"LLM_BASE_URL": "https://api.aillm.ru",
"LLM_API_KEY": "<секрет>",
"LLM_MODEL": "gpt-oss-120b"
}
```
## Проверено живыми вызовами
- api.aillm.ru: `response_format json_object` ✅; `reasoning_effort` ❌ (400 UnsupportedParamsError) — не используется; `reasoning_content` есть → игнорируется; пустой `content` при малом `max_tokens` → повтор ×2.
- Этап 1: выдуманный `nubes_instance` → отбрасывается (`null`).
- Сквозной запрос на прод: `POST /nubes-test/_api/assist` → 200, ответ по шаблону, `sources` валидны, ~12 с.
- Виджет на `https://tf-docs.nodejsk8s.dev.nubes.ru/nubes-test/`: FAB + панель, полный цикл «вопрос → ответ → источники» работает.
- Оценка на 28 эталонных вопросах: этап 1 ≈ 79 %, поиск 71 % → **93 %** после улучшений.
## Деплой
1. `tf_docs`: push в `terraform/tf_docs` → redeploy/modyfy в ЛК (образ собирается из git).
2. `tf_provider`: push → сборка+публикация сайта (`TOOLS/scripts/04_build_and_publish_docs.sh --profile TOOLS/config/test`) → S3 → `mc mirror` на ВМ 213 (`/var/www/tf-docs/nubes-test/`).
## Открытые пункты
- Ротация ключа `LLM_API_KEY` (ключ засветился в логе) — отдельный сервисный ключ.
- Точность этапа 1 (79 %) можно поднять (промпт/примеры).