Большинство AI-ассистентов — это чат: написал вопрос, получил ответ. Coreness Flow изначально был построен иначе. Это локальное Windows-приложение, где агент реБольшинство AI-ассистентов — это чат: написал вопрос, получил ответ. Coreness Flow изначально был построен иначе. Это локальное Windows-приложение, где агент ре

Coreness Flow: локальный AI-агент без облака и без лишнего кода

2026/03/03 12:57
11м. чтение
Для обратной связи или замечаний по поводу данного контента, свяжитесь с нами по адресу crypto.news@mexc.com

Большинство AI-ассистентов — это чат: написал вопрос, получил ответ. Coreness Flow изначально был построен иначе. Это локальное Windows-приложение, где агент реагирует на события — сообщение, webhook, cron — и выполняет цепочки действий, описанные в YAML. Хочешь поменять поведение агента — меняешь конфиг, не код. Никакой облачной части: всё работает на своей машине.

Репозиторий: github.com/Vensus137/Coreness-Flow

Идея: не «вопрос–ответ», а «событие → цепочка»

Стандартный AI-чат — это синхронный цикл: пользователь что-то написал, модель ответила. Coreness Flow разрывает этот цикл.

Здесь центральная единица — событие. Пришло сообщение в чат — событие. Сработал cron в 9 утра — событие. Прилетел webhook от внешнего сервиса — тоже событие. Движок сценариев находит подходящий сценарий по триггеру и выполняет цепочку шагов: читает данные, вызывает LLM, ищет по базе знаний, отправляет ответ. Один и тот же механизм — для разных источников.

Это открывает сценарии, которые в обычном чат-боте требуют написания кода — здесь всё описывается в YAML: ежедневная сводка по расписанию, автоматический ответ на webhook, реакция на конкретную команду с разветвлённой логикой — всё описывается в YAML.

Event Flow
Event Flow

Архитектура: три слоя, одна шина

Приложение разделено на три слоя, которые не знают друг о друге напрямую — только общаются через API Bus.

  • UI Layer — Electron + React. Фронт — это просто отображение. Он подключается к Python-бэкенду по WebSocket, отправляет действия и получает события. Никакой бизнес-логики в React-коде нет — только рендер и вызовы шины.

  • Backend Layer — плагины на Python. Вся логика живёт здесь: обработка сообщений, вызовы LLM, работа с базой, RAG, планировщик. Каждый плагин изолирован и общается с остальными только через API Bus.

  • API Bus — единый контракт между всеми участниками. Два режима:

    • call — вызов с ожиданием ответа (нужен, когда следующий шаг зависит от результата)

    • call_nowait — запуск в фоне без блокировки (длинные цепочки, внешние запросы)

Единый формат ответа у всех вызовов: { result, error, response_data }. Движок сценариев не делает различий — он просто вызывает действия по имени и читает результат.

Api Bus
Api Bus

Почему такое разделение

Самый частый архитектурный грех в подобных приложениях — UI знает про базу данных, а бизнес-логика вызывает компоненты напрямую. Стоит добавить новую фичу — начинается хирургия в трёх местах одновременно.

В Coreness Flow UI вообще не знает, какие плагины загружены. Фронт при старте запрашивает у бэкенда описание того, что плагины добавляют в интерфейс, и строит экран по этим данным. Новый плагин — новая вкладка без правок во фронтенде.

Lifecycle: как запускается приложение

Electron main process ↓ spawn Python backend ↓ API Bus инициализируется ↓ Контейнер сканирует plugins/, мержит конфиги, создаёт экземпляры ↓ Тяжёлая инициализация плагинов (splash показывает прогресс) ↓ Фоновые задачи плагинов ↓ WebSocket-сервер поднимается ↓ Главное окно открывается, фронт подключается ↓ Сбор описаний от плагинов → UI строит сайдбар, вкладки, настройки

Каждый этап изолирован. Если плагин падает при инициализации — остальные продолжают загружаться. Graceful shutdown: таймауты на завершение плагинов и воркеров задаются в app.json, приложение корректно закрывается при выходе или обновлении.

Плагины: VS Code-like, но для десктопного приложения

Плагинная система — одна из самых интересных частей архитектуры. Идея взята из VS Code: плагин не просто добавляет бэкенд-логику, он декларирует свой вклад в приложение через config.json.

Каждый плагин — папка с двумя ключевыми файлами: config.json (что плагин умеет и что добавляет в UI) и Python-модуль (как это реализовано). Контейнер при старте рекурсивно сканирует plugins/ и загружает все папки, где есть config.json. Имя папки становится идентификатором плагина. Никакого реестра, никакого перечисления модулей в коде ядра.

Config.json — центр тяжести плагина

Конфиг описывает четыре вещи:

  • metadata — имя и описание плагина.

  • settings — схема настроек с дефолтами. При старте контейнер мержит дефолты из конфига с переопределениями пользователя из user_settings.json. Плагин всегда получает уже готовый merged-конфиг.

  • actions — список действий, которые плагин регистрирует в API Bus. Для каждого действия описан input (payload-схема) и output (что вернёт).

  • contributes — что плагин добавляет в UI. Это самая интересная часть.

Методы Python-класса с именами, совпадающими с ключами в actions, автоматически становятся обработчиками вызовов — отдельная регистрация не нужна. Описал действие в конфиге и реализовал метод с тем же именем — движок сам подвяжет их при загрузке плагина.

Contributes: интерфейс из конфига

Четыре точки контрибьюта:

Точка

Что добавляет

workspace

Вкладка в основном контенте с виджетом (список, форма настроек и т.д.)

settings

Секция на общей вкладке «Настройки»

sidebar

Пункт в сайдбаре (клик вызывает action)

menus

Пункты в выпадающих меню

Тип виджета вкладки описывается дескриптором: settingsForm, list — фронт рендерит контент без кастомного кода. Колонки списка, источник данных через action, поля формы — всё в JSON-конфиге плагина. Вкладка «Векторное хранилище» со списком чанков и кнопками удаления задаётся в том же плагине так:

"contributes": { "workspace": { "id": "vector_store_admin", "label": "Векторная база", "title": "Векторная база", "content": {"widget": "vectorStoreAdmin"} } }

vectorStoreAdmin — встроенный тип виджета, зарегистрированный во фронтенде; плагин только ссылается на него по имени. Ни одной строки React в плагине — только конфиг.

Такой подход даёт чёткую границу ответственности: бэкенд-разработчик пишет плагин и его конфиг, UI-слой адаптируется сам. Хочешь убрать вкладку — убери папку плагина. Хочешь переименовать — поменяй label в конфиге.

Hot reload настроек

Отдельная приятная деталь: когда пользователь меняет настройки в UI, бэкенд уведомляет затронутый плагин — тот пересоздаёт клиенты, сбрасывает кэши без перезапуска приложения. Сменил API-ключ или модель — плагин подхватил изменения сразу.

Сценарии: оркестрация без кода

Если плагины — это сервисы с действиями, то сценарии — это способ эти действия оркестрировать без написания кода.

Все сценарии живут в YAML-файлах в config/scenarios/. Движок подхватывает их рекурсивно из всех подпапок. Можно организовать как угодно: commands/, system/, scheduled/ - имена сценариев глобальны: из любого сценария можно вызвать другой по имени.

Базовая структура:

daily_report: schedule: "0 9 * * *" # Ежедневно в 9:00 step: - action: "get_storage" params: group_key: "report_config" _response_key: "config" - action: "completion" params: prompt: "Сформируй утреннюю сводку. Контекст: {_cache.config}" model: "{_cache.config.model}" - action: "send_chat_message" params: text: "{_cache.response}"

Каждый шаг — вызов action плагина. Результат кладётся в _cache под ключом _response_key. Следующий шаг берёт данные через плейсхолдер {_cache.ключ}.

Плейсхолдеры — маленькая шаблонизация

Плейсхолдеры работают во всех параметрах шагов и поддерживают цепочку модификаторов:

  • {event_text} — текст события

  • {_cache.system.routing_model} — вложенное поле из кэша

  • {now|format:datetime} — текущее время с форматированием

  • {_cache.field|fallback:default} — значение с дефолтом, если поле пустое

  • {_cache.result|exists} — булево: есть ли поле

Это позволяет строить достаточно гибкие цепочки без написания Python-кода — просто подстановка значений через шаблоны.

Триггеры: от простого к сложному

Самая простая форма триггера — тип события плюс текст:

trigger: - event_type: "message" event_text: "/help"

Сложная форма — поле condition с выражением на мини-языке (операторы: ==, ~ — «содержит», regex, is_null и др.; поля через $event_text, $event_type):

trigger: - event_type: "message" condition: "$event_text ~ '/'"

Несколько триггеров в списке работают по логике ИЛИ. Поля внутри одного триггера — И. Не нужно дублировать сценарий под каждый вариант — достаточно добавить триггер в список.

Переходы и ветвления

После шага можно задать transition — список правил: по результату действия (action_result: success, error и т.д.) выполняется переход (transition_action и при необходимости transition_value). Например, переход в другой сценарий:

- action: "search_chunks" params: query: "{event_text}" _response_key: "rag_result" transition: - action_result: "success" transition_action: "jump_to_scenario" transition_value: "step_with_rag" - action_result: "error" transition_action: "jump_to_scenario" transition_value: "step_without_rag"

Нашёл что-то в RAG — идём в один сценарий, не нашёл — в другой. Всё в конфиге.

Типичный сценарий-инструмент: по ссылке загрузить документ, разбить на чанки и положить в векторное хранилище; при ошибке — переход в сценарий обработки ошибки.

Конфигурация: мерж без магии

Схема конфигурации намеренно простая и одинаковая для всего:

  • Дефолты приложенияconfig/app.json

  • Дефолты плагина — секция settings в его config.json

  • Пользовательские переопределения%APPDATA%\CorenessFlow\user_settings.json (только изменённые ключи)

При старте контейнер мержит дефолты с пользовательскими значениями и передаёт плагину готовый конфиг. Секреты и API-токены хранятся в SQLite в %APPDATA% — в репозиторий не попадают.

Один и тот же формат config.json у приложения и у каждого плагина — код контейнера унифицирован, документация однородна.

Storage: ключ–значение для конфигурации агента

Плагин database даёт сценариям простое ключ–значение хранилище с группировкой: group_key + key → значение. Но интереснее другое: начальные данные задаются прямо в YAML-файлах в config/storage/ и при старте синхронизируются в SQLite.

Это делает поведение агента конфигурируемым без правки сценариев. Системный промпт роутера, список доступных инструментов, параметры моделей, лимиты — всё хранится в storage, сценарии читают эти данные при выполнении. Поменять модель для простых запросов — правка в storage, без изменений в YAML сценариев.

Роутинг агента: как один запрос превращается в цепочку решений

Агентский роутинг в Coreness Flow — это не встроенная в ядро функция, а набор системных сценариев поверх общего механизма. Пользователь видит: отправил сообщение → «Обрабатываю...» → ответ. За кадром — цепочка из нескольких сценариев и нескольких вызовов LLM.

Конвейер обработки сообщения

AI-routing
AI-routing

Когда приходит сообщение из чата, выполняется такая последовательность:

  1. Загрузка контекста — из хранилища читаются настройки: системный промпт, список инструментов и сценариев ответа, лимит шагов.

  2. Сборка истории — берётся история чата с лимитом по объёму, при необходимости подмешиваются найденные фрагменты из RAG.

  3. Роутинг — запрос к LLM с промптом и описанием «инструментов». Модель решает: вызвать один из инструментов (например, поиск по базе знаний) или сразу сформировать ответ.

  4. Выполнение — если выбран инструмент, запускается соответствующий сценарий, затем снова роутинг (цикл до лимита шагов).

  5. Финализация — итоговый запрос к модели, ответ отправляется в чат.

Инструменты — это те же YAML-сценарии: добавить новый значит описать его в конфиге хранилища и добавить файл сценария. Ядро приложения не трогается.

Чат
Чат

RAG локально: никаких серверов, никакого облака

Векторное хранилище в Coreness Flow — отдельный плагин с несколькими принципиальными решениями.

RAG
RAG

BGE-M3 в формате ONNX, квантизация INT8

Мультиязычная модель, которая умеет генерировать и dense, и sparse векторы одновременно. Модель запускается через ONNX Runtime — без PyTorch и CUDA. INT8-квантизация снижает потребление памяти примерно в 4 раза по сравнению с float32 при минимальной потере качества. Работает на обычном CPU.

Qdrant в embedded-режиме

Qdrant поднимается внутри процесса приложения и хранит данные на диске. Отдельный сервис, порты и docker не нужны.

Гибридный поиск с RRF

BGE-M3 даёт и dense-векторы (семантика), и sparse-векторы (ключевые слова). Поиск по обоим типам и слияние результатов через Reciprocal Rank Fusion даёт лучшее качество, чем один семантический поиск — особенно для запросов с конкретными терминами и именами.

В сценариях это два действия: add_chunks для индексации и search_chunks для поиска. Результат поиска кладётся в _cache и подставляется в промпт следующего шага. Документы не покидают машину.

Загрузка модели и splash-экран

BGE-M3 — тяжёлая модель, и её загрузка при старте требует отдельного решения. Она выполняется до показа главного окна: пользователь видит splash с прогрессом инициализации, главное окно открывается, только когда всё готово. Без замораживания интерфейса.

Сплеш при запуске
Сплеш при запуске

Асинхронность без боли

Actions в API Bus выполняются в пуле воркеров — отдельных потоках с собственным event loop. Число воркеров настраивается. Это значит, что долгий вызов LLM не блокирует обработку другого входящего события.

call_nowait — отдельно приятная штука. Запускаешь длинную цепочку сценариев, не ждёшь завершения, продолжаешь. Результат придёт через событие в UI. Так работает весь чат: пользователь отправил сообщение, бэкенд запустил цепочку через call_nowait, UI показывает индикатор загрузки и не блокируется.

Плагины подписываются на события шины. Так можно организовать реакцию на любые события системы без прямых зависимостей между плагинами.

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

Coreness-Flow/ ├── run_backend.py # Точка входа бэкенда ├── app/ │ ├── runtime/ │ │ ├── container.py # Сканирование плагинов, мерж конфигов, создание экземпляров │ │ ├── api_bus.py # Шина: actions, events, воркеры │ │ └── ... │ ├── settings.py # Загрузка и мерж конфигов │ └── ws_server.py # WebSocket для фронта ├── frontend/ # Electron + React ├── plugins/ │ ├── core/ # Ключевые модули: chats, database, ai_service, vector_store, ... │ ├── base/ # Некритичные плагины │ └── extensions/ # Кастомные расширения └── config/ ├── app.json # Дефолты приложения ├── scenarios/ # YAML-сценарии └── storage/ # Начальные данные storage

В core/ — основа: чаты, база данных, вызовы LLM, векторное хранилище, движок сценариев. В base/ — дополнительные плагины, без них приложение тоже работает. В extensions/ — место для своих расширений.

Быстрый старт

Из исходников (Python 3.11, Node.js, Windows):

pip install -r requirements.txt cd frontend && npm install && cd .. .\scripts\run-dev.ps1

Бэкенд и окно поднимаются одной командой. В dev-режиме: hot reload при изменении конфигов и кода плагинов.

Из релизов: установщик под Windows в разделе Releases — Python и Node на целевой машине не нужны.

После первого запуска — задать AI-провайдера в настройках (любой OpenAI-совместимый API), при желании загрузить документы в векторное хранилище и настроить storage под свои нужды.

Стек

Компонент

Технология

Frontend

Electron + React

Backend

Python 3.11, async/await

UI ↔ Backend

WebSocket + API Bus

LLM

OpenAI-совместимый API (OpenRouter, Polza.AI и др.)

RAG

BGE-M3 ONNX INT8 + Qdrant embedded

Хранилище

SQLite + JSON (конфиг) + YAML (сценарии, storage)

Сборка

Electron Builder + Python backend

Ключевые решения

Чем по сути отличается Coreness Flow:

  • Плагины без реестра — папка с конфигом и модулем, контейнер подхватывает при старте; единый контракт для всех.

  • Интерфейс из конфига — плагины декларируют вкладки, настройки, пункты меню; фронт собирает UI по этим данным, без перечисления плагинов в коде.

  • Сценарии вместо кода — оркестрация действий в YAML: триггеры, шаги, переходы по результату; движок вызывает действия по имени.

  • Локальный RAG — эмбеддинги и векторная база на своей машине, ONNX и Qdrant в процессе приложения, офлайн.

  • События и шина — плагины общаются только через API Bus, подписываются на события; нет прямых вызовов между модулями.

Ссылки

  • Репозиторий: github.com/Vensus137/Coreness-Flow

  • Документация: docs/ в репозитории

  • Связь с автором: @vensus137

Coreness — Create. Automate. Scale.

Источник

Возможности рынка
Логотип FLOW
FLOW Курс (FLOW)
$0.0343
$0.0343$0.0343
-1.69%
USD
График цены FLOW (FLOW) в реальном времени
Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу crypto.news@mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.

Вам также может быть интересно

Как мы с ИИ сделали локальный ИИ, который учится по моим книгам и пишет за меня отчёты

Как мы с ИИ сделали локальный ИИ, который учится по моим книгам и пишет за меня отчёты

Предыстория: зачем вообще это нужноКаждый семестр одна и та же история: кипа учебников, дедлайны, отчёты, которые нужно было сдать «вчера», и презентации, от од
Поделиться
ProBlockChain2026/03/05 03:06
Адам Уэйнрайт снова выходит на питчерскую горку почтить память Дэррила Кайла

Адам Уэйнрайт снова выходит на питчерскую горку почтить память Дэррила Кайла

Пост «Адам Уэйнрайт снова выходит на горку в честь Дэррила Кайла» появился на BitcoinEthereumNews.com. Адам Уэйнрайт из Сент-Луис Кардиналс в дагауте во время второго иннинга против Майами Марлинс на стадионе Буш 18 июля 2023 года в Сент-Луисе, Миссури. (Фото: Brandon Sloter/Image Of Sport/Getty Images) Getty Images Ветеран Сент-Луис Кардиналс Адам Уэйнрайт — довольно непринужденный парень, который не прочь поговорить с вами о бейсбольных традициях и барбекю или даже пошутить. Эта черта его характера проявилась на прошлой неделе во время нашего звонка в Zoom, когда я впервые упомянул, что я болельщик Чикаго Кабс. Он ответил на упоминание о моем фанатизме: «Пока что, я не думаю, что это интервью идет очень хорошо». Тем не менее, Уэйнрайт вернется на стадион Буш 19 сентября с более серьезной миссией — на этот раз, чтобы почтить память другого бывшего игрока Кардиналс и друга, покойного Дэррила Кайла. Уэйнрайт выйдет на горку не как стартовый питчер, а чтобы выполнить церемониальную первую подачу игры. К нему на горке присоединится дочь Кайла, Сьерра, и вместе они помогут запустить новую программу под названием «Играя сердцем». «Уход Дэррила напомнил нам, что болезни сердца не делают исключений, даже для элитных спортсменов в отличной физической форме», — сказал Уэйнрайт. «Эта программа направлена на то, чтобы помочь людям распознать риски, принять меры и, надеюсь, спасти жизни». Уэйнрайт, который выступал за Сент-Луис Кардиналс в качестве стартового питчера с 2005 по 2023 год, стремится объединить суть бейсбольной традиции с важным посланием о здоровье сердца. Кайл, любимый питчер Кардиналс, трагически скончался в 2002 году в возрасте 33 лет в результате раннего развития болезни сердца. Его внезапная смерть потрясла бейсбольный мир и оставила неизгладимый след на товарищах по команде, болельщиках и особенно на его семье. Теперь, более двух десятилетий спустя, Сьерра Кайл выступает вместе с Уэйнрайтом, чтобы...
Поделиться
BitcoinEthereumNews2025/09/18 02:08
Может ли номинант Трампа в ФРС Кевин Уорш поднять Bitcoin до $80 000?

Может ли номинант Трампа в ФРС Кевин Уорш поднять Bitcoin до $80 000?

Статья «Сможет ли номинант Трампа на пост главы ФРС Кевин Уорш вывести Bitcoin на уровень $80 000?» впервые появилась на Coinpedia Fintech News 4 марта президент США Дональд Трамп официально
Поделиться
CoinPedia2026/03/05 06:17