---
name: investpilot-chat-advisor
description: КодИнвест — чат-консультант (свободный вопрос текстом → честный ответ на накопленных знаниях)
metadata: 
  node_type: memory
  type: project
  originSessionId: 6f344612-b945-4107-b457-8ad2163cd988
---

**КодИнвест ([[investpilot-overview]]) — чат-консультант, 2026-07-13.**

Владелец пишет в чат бота свободный вопрос («как из 1000 сделать миллион», «во что вложиться при ставке?») → бот отвечает на основе накопленного, НЕ хайпово.

- **`signals/advisor.py::answer_question(app, question)`** — grounding: текущий макро (macro_snapshot) + KB-тезисы/выдержки по семантике вопроса (`KnowledgeReader.context_for_query`) + уроки бота (`db.lessons_for("__GLOBAL__", horizons=None)` — scope global) + позиции песочницы → single-цепочка (codex-primary) с промптом `ADVISOR_SYSTEM`.
- **`ADVISOR_SYSTEM` честность железно:** не обещать доходность, нереалистичную цель разбирать арифметикой (1000→млн = ×1000 = риск разорения), опираться только на контекст, сравнивать с безрисковой ОФЗ. Проверено живьём: «1000→млн» отказался от хайпа + процитировал реальный урок (intraday SHORT 0/6 WIN).
- **Хендлер catch-all:** `@router.message(StateFilter(None), F.text & ~startswith("/"))` — регистрируется ПОСЛЕДНИМ, ловит любой текст вне FSM и не команду. Ответ plain-text (parse_mode=None — LLM-вывод не роняет HTML), разбивка под лимит TG 4096. Кнопка меню «💬 Спросить совет».
- **Грабля: codex упорно шлёт markdown вопреки промпту** → `_strip_markdown` чистит `|`-таблицы/`##`/`**` на стороне кода. Не полагаться на «модель послушает промпт про формат» — чистить кодом.
- 158 pytest (tests/test_advisor.py). Опирается на codex-primary из [[investpilot-universe-junk-fix]] (довесок LLM-надёжность).
