nodes-ui-flow / README.md
markitzeroo
Restore Hugging Face Space metadata
87118dc
metadata
title: Nodes UI Flow
emoji: 🤖
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false

Nodes UI Flow

Визуальный редактор интерактивных AI-сценариев: сценарий собирается из нод, запускается пошагово, задает вопросы пользователю, сохраняет ответы в память, ветвится по смыслу и может отвечать по knowledge-файлам.

Проект сейчас содержит пример для RosUpack 2026, но ноды сделаны универсальными: такой же граф можно собрать для другого стенда, продукта или процесса.

Что внутри

  • React + React Flow интерфейс для сборки графов.
  • FastAPI backend для LLM-запросов, классификации, извлечения памяти и ответов по файлам.
  • Выбор LLM provider в настройках: Ollama или DeepInfra.
  • Перефразирование реплик ассистента при запуске нод, чтобы сценарий не звучал одинаково каждый раз.
  • LLM Test режим: LLM сама проходит сценарий, а evaluator проверяет вопросы и ответы ассистента.
  • Сохранение workflow в JSON.
  • Knowledge-файлы, привязанные к конкретной Knowledge Answer ноде.

Быстрый запуск на Windows

Ollama запускается отдельно вручную.

start_interface.bat

Скрипт откроет два окна:

  • backend: http://localhost:8000
  • frontend: http://localhost:5173

Остановить интерфейс можно закрытием этих двух окон.

Ручной запуск

Backend:

cd backend
python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt
python main.py

Frontend:

npm install
npm run dev

Production build:

npm run build

Структура проекта

backend/                 FastAPI backend
public/                  frontend config and presets
scenarios/
  dialog/                markdown versions of scenario scripts
  knowledge/             curated knowledge bases for Knowledge Answer nodes
  source/                original source documents
src/                     React app, nodes and workflow runtime
workflows/               saved workflow JSON graphs
  archive/               old or experimental workflow snapshots
start_interface.bat      one-click Windows launcher

Runtime/generated folders are intentionally ignored by git:

dist/
node_modules/
backend/.venv/
knowledge_contexts/
test_logs/
transcript_logs/

Основной workflow

Главный пример:

workflows/full_workflow.json

Knowledge base для него:

scenarios/knowledge/rosupack_2026_knowledge_base.md

В Knowledge Answer ноде путь к файлу сохраняется прямо в JSON workflow, поэтому граф можно открыть после clone и продолжить использовать без повторного upload, если файл лежит в репозитории.

Как устроен интерактивный сценарий

Типичный поток:

Question -> Save Memory -> Assistant Message -> Semantic Branch -> Question/Message/... -> Knowledge Answer -> Restart

Runtime идет до первой Question, показывает вопрос в нижней панели и ждет ответ пользователя. Ответ можно:

  • ввести руками;
  • сгенерировать кнопкой LLM answer;
  • включить Auto LLM answer, чтобы LLM отвечала сама на каждый новый вопрос.

Если у ноды включена галочка Перефразировать при запуске, backend перед показом реплики отправит текст в выбранный LLM provider и вернет новую формулировку с тем же смыслом. В transcript и дальше по графу попадет именно показанная пользователю версия.

LLM provider

Provider выбирается в Настройки:

  • Ollama — локальный режим, backend обращается к http://localhost:11434.
  • DeepInfra — облачный OpenAI-compatible endpoint.

Для DeepInfra в настройках появляется поле API key. Ключ сохраняется локально в backend/.deepinfra_api_key, этот файл игнорируется git. Если ключ уже сохранен, поле можно оставить пустым, чтобы не менять его.

Thinking/reasoning в LLM-вызовах отключен: для Ollama backend отправляет think: false, для DeepInfra используется reasoning_effort: none.

Основные типы портов

Порты окрашиваются по типу/смыслу, а не по цвету ноды.

  • turn — объект одного шага диалога: вопрос, ответ и накопленный dialog.
  • dialog / dialog-in — история сообщений.
  • question — текст вопроса.
  • answer — текст ответа пользователя.
  • string — обычный текст.
  • object — структурированные данные.

Один input может принимать несколько входящих связей. Это используется, когда несколько веток сходятся в общий блок, например в общий Еще вопросы?.

Ключевые ноды

Question

Задает вопрос ассистента и ставит workflow на паузу до ответа пользователя.

Используйте turn output, если дальше нужна вся пара вопрос/ответ. Используйте dialog или dialog-in, если важно сохранить историю реплик.

Опция Перефразировать при запуске заставляет LLM переписать вопрос перед показом пользователю.

Assistant Message

Показывает реплику ассистента без ожидания пользовательского ответа.

Подходит для коротких объяснений, переходов между ветками и финальных историй.

Опция Перефразировать при запуске работает так же, как в Question: смысл сохраняется, формулировка может меняться.

Save Memory

Извлекает значение из ответа пользователя и сохраняет его в память прогона.

Пример ключей:

name
role
industry
scale

Значения доступны в шаблонах через фигурные скобки:

{name}, хотели бы узнать что-то еще?

Если перед Save Memory был retry-переспрос, нода берет последний ответ пользователя из dialog-in, а не старый первый ответ из turn. Это важно для сценариев вроде проверки имени: пользователь может сначала ответить бессмыслицу, затем назвать имя, и в {name} сохранится именно последний корректный ответ.

Semantic Branch

LLM выбирает один выход по смыслу ответа пользователя.

Один choice = один output. Альтернативы внутри одного choice пишутся через точку с запятой:

да; хочу еще; давай; есть вопрос
нет; хватит; вернуться в начало

Точка с запятой означает альтернативные формулировки, а не условие, что все фразы должны встретиться одновременно.

Если ответ непонятен, retry on unclear может сразу переспросить пользователя на этой же точке сценария.

У retry-вопроса есть отдельная галочка Перефразировать unclear-вопрос, чтобы повторный вопрос звучал живее при нескольких неудачных ответах подряд.

Knowledge Answer

Отвечает на вопрос пользователя по файлу, привязанному к конкретной ноде.

Поддерживаются:

  • .md
  • .txt
  • .docx
  • .doc как best-effort text extraction

При upload backend сохраняет оригинал и extracted text. Для репозиторных сценариев лучше хранить curated .md knowledge base в scenarios/knowledge/ и указывать этот относительный путь в contextPath.

Restart

Перезапускает интерактивный сценарий с начала.

Удобно для выставочного сценария: если пользователь больше не хочет задавать вопросы, можно вернуть ассистента в стартовое состояние.

Request to LLM

Отправляет system и user prompt на backend.

Используйте для универсальных LLM-операций, которые не покрыты готовыми специализированными нодами.

Component

Сворачивает часть графа во вложенный компонент.

Подходит для повторяющихся блоков, когда сценарий начинает разрастаться.

Как соединять ноды

Сохранить имя

Question(turn) -> Semantic Branch(turn)
Question(turn) -> Save Memory(turn)
Semantic Branch(has-name) -> Save Memory(dialog-in)
Save Memory(dialog) -> Assistant Message(dialog-in)

Semantic Branch проверяет, есть ли в ответе имя. Если ответа недостаточно, retry on unclear сразу переспросит. Save Memory получает старый turn и свежий dialog-in; приоритет отдается последнему ответу пользователя из dialog-in, поэтому после переспроса сохраняется корректное имя.

Ветвление по смыслу

Question(turn) -> Semantic Branch(turn)
Semantic Branch(choice A) -> Node A(dialog-in)
Semantic Branch(choice B) -> Node B(dialog-in)
Semantic Branch(unclear) -> retry или fallback

Общий финальный блок

Branch A final message(dialog) -> Shared Question(dialog-in)
Branch B final message(dialog) -> Shared Question(dialog-in)
Branch C final message(dialog) -> Shared Question(dialog-in)

Так несколько веток сходятся в один общий вопрос без дублирования нод.

Зацикливание knowledge-вопросов

Question "Что узнать?"(turn) -> Knowledge Answer(turn)
Knowledge Answer(dialog) -> Question "Еще вопросы?"(dialog-in)

Так пользователь может задавать вопросы по файлу, пока не ответит, что больше вопросов нет.

LLM answer и LLM Test

LLM answer

Разово генерирует ответ пользователя на текущий вопрос.

Auto LLM answer

Автоматически отвечает на каждый новый вопрос тем же prompt-ом тестового пользователя.

Prompt хранится в workflow JSON:

{
  "settings": {
    "llmRolePrompt": "..."
  }
}

LLM Test

Отдельный режим тестирования сценария:

  1. LLM проходит сценарий как пользователь.
  2. После вопросов/ответов ассистента evaluator проверяет адекватность.
  3. Если evaluator видит проблему, в JSONL-лог первым событием пишется причина.
  4. Полный trace LLM-запросов сохраняется в test_logs/.

LLM Test можно остановить кнопкой Stop LLM Test.

Логи

UI logs

Правая панель показывает служебные события, ошибки, проверки evaluator и пути к файлам логов.

При Auto LLM answer и LLM Test обычные реплики не дублируются в правый служебный log, потому что они уже видны в transcript.

Write logs

Галочка Write logs пишет простой текстовый transcript:

ASSISTANT: ...

USER: ...

Файлы создаются в:

transcript_logs/<workflow-name>/

Эта папка не коммитится.

Test logs

LLM Test пишет подробные JSONL trace-файлы:

test_logs/<workflow-name>/

Если evaluator считает вопрос или ответ плохим, первая строка файла будет evaluation_failure_summary с причиной.

Скриншоты

Скриншоты UI лучше хранить отдельно от runtime-логов, например:

scenarios/screenshots/

Рекомендуемые скрины для README:

  • общий вид canvas с RosUpack workflow;
  • нижняя interactive panel во время прогона;
  • пример Knowledge Answer ноды с привязанным файлом;
  • пример Semantic Branch с альтернативами через ;.

Git hygiene

В репозиторий должны попадать:

  • src/
  • backend/main.py
  • backend/requirements.txt
  • public/
  • workflows/
  • scenarios/
  • конфиги приложения

В репозиторий не должны попадать:

  • node_modules/
  • dist/
  • backend/.venv/
  • knowledge_contexts/
  • test_logs/
  • transcript_logs/

GitHub

Repository:

https://github.com/markitzeroo/nodes-ui-flow

Repository is private.