Что такое «Свой» и какие проблемы он решает
«Свой» - это опенсорсный AI-ассистент, построенный на стеке Go, Vue 3 и PostgreSQL 17. Он объединяет долговременную память на pgvector, поддержку локальных и облачных LLM и гибкую систему тематических помощников. Ключевое отличие от большинства ассистентов - архитектурно встроенная приватность: модуль «Мой ПК» реализует E2E-шифрованный retrieval-augmented generation, при котором бекенд и языковая модель работают как слепой ретранслятор шифртекста, не имея доступа к содержимому пользовательских файлов.
Проект адресован разработчикам и ML-инженерам, которым нужен контролируемый, модульный ассистент без компромиссов по безопасности данных. Вы получаете агентный веб-поиск через SearXNG, анализ изображений с двухслойным фото-промптом и возможность расширять функциональность через специализированных помощников. Эта статья - технический deep dive: разберём архитектурные решения, криптографический протокол RAG и детали реализации каждого компонента.
Если вы проектируете собственного AI-агента, материал о самостоятельной разработке агентов на Python с LangChain и LiteLLM даст практическую базу для сравнения подходов.
Архитектура проекта: бекенд, фронтенд и база данных
«Свой» спроектирован как классическое трёхкомпонентное приложение с чётким разделением ответственности. Go-бекенд обрабатывает всю бизнес-логику, маршрутизацию запросов к LLM-провайдерам и взаимодействие с PostgreSQL 17. Vue 3 отвечает за реактивный интерфейс. База данных выступает единым источником истины для диалогов, эмбеддингов и конфигураций помощников.
Обмен между фронтендом и бекендом идёт по REST API. При отправке сообщения бекенд извлекает релевантный контекст из pgvector, при необходимости активирует инструменты (поиск, анализ изображений), формирует промпт и направляет его выбранной LLM. Ответ модели проходит постобработку и возвращается в интерфейс. Такая архитектура позволяет заменять любой компонент независимо - от модели до поискового движка.
Бекенд на Go: ручной SQL и circuit breaker для LLM-провайдеров
Выбор Go обусловлен сочетанием производительности, низкого потребления памяти и удобства развёртывания единым бинарником. Бекенд не использует ORM - все запросы написаны вручную. Это даёт полный контроль над планами выполнения, позволяет применять специфичные для PostgreSQL 17 возможности (включая индексы pgvector) и исключает накладные расходы абстракции.
Пример ручного запроса для поиска ближайших эмбеддингов в памяти ассистента:
SELECT content, metadata, 1 - (embedding <=> $1) AS similarity
FROM memory_embeddings
WHERE session_id = $2
AND 1 - (embedding <=> $1) > 0.75
ORDER BY embedding <=> $1
LIMIT 10;
Оператор <=> - это косинусное расстояние pgvector. Запрос возвращает до десяти наиболее релевантных фрагментов с порогом схожести 0.75. Никакого посредника между кодом и базой - только подготовленные выражения и явная обработка ошибок.
Circuit breaker защищает ассистент от деградации при сбоях LLM-провайдеров. Паттерн реализован как конечный автомат с тремя состояниями: Closed (нормальная работа), Open (запросы блокируются) и Half-Open (пробные запросы для проверки восстановления). Порог срабатывания - пять последовательных ошибок за 30-секундное окно. После перехода в Open бекенд ждёт 60 секунд, затем пропускает один пробный запрос. Успешный ответ возвращает автомат в Closed, ошибка - снова в Open с удвоением таймаута. Для пользователя это означает автоматический фолбек на резервного провайдера вместо бесконечного ожидания ответа.
Фронтенд на Vue 3 и генерация палитры через LLM
Фронтенд построен на Composition API Vue 3. Состояние диалогов, активный помощник и настройки хранятся в Pinia-сторах. Компоненты чата, загрузки файлов и предпросмотра изображений изолированы - каждый можно дорабатывать независимо.
Интересное решение - детерминированная генерация цветовой палитры интерфейса. При первом запуске бекенд отправляет LLM промпт с инструкцией: «Сгенерируй три HEX-цвета для UI ассистента: основной, акцентный и фоновый. Ответ - строго JSON {primary, accent, background}». Модель возвращает три значения, которые проходят валидацию на соответствие формату и контрастности. Результат кешируется в localStorage - палитра не меняется между сессиями, сохраняя визуальную консистентность. Если сгенерированные цвета не проходят проверку доступности (WCAG AA для текста), применяется запасная палитра.
Долговременная память на pgvector
Вместо отдельной векторной базы данных «Свой» использует расширение pgvector внутри PostgreSQL 17. Решение устраняет необходимость синхронизации между хранилищами: диалоги, метаданные пользователей и эмбеддинги живут в одной транзакционной системе. Схема хранения включает три ключевые таблицы:
- sessions - идентификатор сессии, временные метки, активный помощник;
- messages - текст сообщения, роль (user/assistant/tool), ссылка на сессию;
- memory_embeddings - вектор размерности 1536 (OpenAI embedding) или 1024 (локальный эмбеддер), исходный текст, метаданные, внешний ключ к сессии.
При каждом обмене репликами бекенд генерирует эмбеддинг пользовательского сообщения и выполняет поиск по косинусному сходству среди предыдущих записей сессии. Найденные фрагменты добавляются в системный промпт перед отправкой LLM. Это позволяет ассистенту ссылаться на факты из истории диалога без пересказа всего контекста - критично для длинных сессий, где полный лог превышает контекстное окно модели.
Для проектов, где важна детерминированность контекста, полезен подход из обзора Archex - инструмента для построения ранжированного контекста из репозитория с recall 0.95.
E2E-шифрованный RAG «Мой ПК»: как данные не покидают устройство
Модуль «Мой ПК» решает задачу, которая останавливает многих от использования AI-ассистентов для работы с личными файлами: как дать модели доступ к содержимому документов, не раскрывая его облачному провайдеру. Архитектурный ответ - сквозное шифрование, при котором бекенд и LLM выступают слепым ретранслятором. Они передают шифртекст между клиентом и моделью, не имея возможности его расшифровать.
Поток данных выглядит так: пользователь задаёт вопрос, требующий поиска по локальным файлам. Десктоп-агент на Go выполняет векторный поиск по индексу sqlite-vec, находит релевантные фрагменты, шифрует их вместе с запросом и отправляет на бекенд. Бекенд передаёт шифртекст LLM-провайдеру. Модель получает расшифрованный контекст (ключ есть только у клиента и модели в рамках защищённого канала), генерирует ответ, шифрует его и возвращает по цепочке обратно. Клиент расшифровывает ответ локально.
Десктоп-агент на Go и локальное индексирование в sqlite-vec
Агент устанавливается на машину пользователя как фоновый процесс. При запуске он сканирует указанные директории и индексирует поддерживаемые типы файлов: PDF, DOCX, TXT, Markdown, исходный код. Для каждого файла вычисляется SHA-256 хеш - повторное индексирование запускается только при изменении содержимого.
Индексация использует sqlite-vec - расширение SQLite для векторного поиска, работающее полностью локально. Эмбеддинги генерируются на устройстве через локальную модель (например, sentence-transformers в режиме ONNX), поэтому содержимое файлов никогда не покидает машину. Метаданные (имя файла, путь, дата модификации) хранятся открыто для отображения в интерфейсе, но содержимое индексируется только в векторном представлении.
Агент поддерживает инкрементальное обновление индекса и работает с файловой системой через кроссплатформенное API Go - один бинарник собирается для Linux, macOS и Windows.
Криптографический протокол: ECDH, HKDF и AES-256-GCM
Защищённый канал между клиентом и LLM устанавливается за четыре шага:
- Генерация эфемерных ключей. Клиент и модель генерируют пары ключей на кривой ECDH P-256. Открытые ключи публикуются, приватные остаются на сторонах.
- Вычисление общего секрета. Каждая сторона выполняет скалярное умножение своего приватного ключа на открытый ключ противоположной стороны. Результат - 256-битный общий секрет, одинаковый у клиента и модели.
- Деривация сессионного ключа. Общий секрет прогоняется через HKDF-SHA256 с солью (случайные 32 байта, передаваемые открыто) и информационной строкой «svoy-rag-v1». На выходе - 256-битный сессионный ключ.
- Шифрование сообщений. Каждое сообщение шифруется AES-256-GCM с уникальным 96-битным nonce. GCM обеспечивает аутентифицированное шифрование - получатель проверяет целостность и подлинность данных.
Бекенд видит только шифртекст и метаданные (длину сообщения, временные метки). Расшифровать трафик он не может - общий секрет вычисляется на сторонах клиента и модели, сессионный ключ никогда не передаётся через сервер. Даже при компрометации бекенда история запросов остаётся защищённой.
Агентный веб-поиск на SearXNG и multi-turn tool calling
Для поиска в интернете «Свой» использует SearXNG - опенсорсный метапоисковый движок, агрегирующий результаты из десятков источников без трекинга пользователя. Выбор в пользу SearXNG вместо прямых API поисковых систем даёт два преимущества: приватность (запросы обезличиваются) и независимость от коммерческих квот.
Интеграция реализована через multi-turn tool calling. Когда пользователь задаёт вопрос, требующий актуальной информации из сети, LLM получает описание инструмента в системном промпте:
{
"tool": "web_search",
"description": "Поиск актуальной информации в интернете через SearXNG",
"parameters": {
"query": "строка поискового запроса",
"max_results": 5
}
}
Модель решает, что собственных знаний недостаточно, и возвращает вызов инструмента. Бекенд выполняет запрос к SearXNG, получает сниппеты, добавляет их в контекст и повторно вызывает LLM для формирования финального ответа. Цикл может повторяться: модель уточняет запрос, если первые результаты нерелевантны. Ограничение - максимум три итерации поиска на одно сообщение пользователя, чтобы избежать зацикливания.
Тематические помощники и анализ изображений
Система помощников позволяет специализировать ассистента под конкретные задачи. Каждый помощник - это конфигурация из системного промпта, набора доступных инструментов и опциональной базы знаний. Помощник «Код-ревьюер» получает промпт с акцентом на поиск уязвимостей и доступ к инструменту чтения файлов. Помощник «Медицинский аналитик» - инструкцию по интерпретации исследований и доступ к SearXNG для поиска актуальных публикаций.
При анализе изображений применяется двухслойный фото-промпт. Первый слой - универсальный: модель описывает содержимое снимка, выделяет объекты, текст, сцену. Второй слой накладывает специализацию активного помощника. Если включён технический помощник, второй слой добавляет инструкцию: «Опиши видимые компоненты оборудования, маркировку, возможные неисправности». Медицинский помощник получает: «Опиши видимые симптомы, локализацию, характер изменений». Оба слоя выполняются за один вызов vision-LLM - промпты конкатенируются, экономя токены и время инференса.
Ограничения, риски и сравнение с аналогами
Проект находится в активной разработке. Документация покрывает ядро, но некоторые детали реализации circuit breaker и генерации палитры раскрыты в коде, а не в статьях. Лицензия на момент написания не указана публично - перед внедрением в коммерческий продукт стоит уточнить условия.
Производительность локальных LLM остаётся узким местом. На GPU с 4 ГБ VRAM запуск модели и эмбеддера одновременно требует переключения по требованию, что добавляет задержку. Для понимания реальных ограничений полезен материал об ограничениях локального AI-воркспейса на 4 ГБ VRAM с бенчмарками Qwen на RTX 3050 Ti.
В сравнении с ChatGPT или Copilot «Свой» выигрывает в приватности и контроле: данные не покидают ваш контур, модель можно заменить на любую совместимую. Но экосистема плагинов и интеграций пока скромнее. Выбирайте «Свой», если критичны E2E-шифрование и возможность тонкой настройки под домен. Оставайтесь на коммерческих решениях, если нужен максимально широкий охват инструментов без затрат на самостоятельную настройку.
Для команд, внедряющих AI-агентов в рабочие процессы, практическое руководство по системе управления знаниями для AI-агентов содержит метрики роста производительности и архитектурные шаблоны.
Заключение: будущее проекта и как начать использовать
«Свой» демонстрирует, что AI-ассистент может быть одновременно функциональным и приватным. Стек Go + Vue 3 + PostgreSQL 17 обеспечивает производительность, pgvector даёт долговременную память без внешних зависимостей, а E2E-шифрованный RAG решает проблему доступа к личным файлам без компрометации данных. Тематические помощники и агентный поиск добавляют гибкости, не усложняя ядро.
Код проекта открыт, десктоп-агент и бекенд собираются из исходников стандартными инструментами Go. Для старта достаточно поднять PostgreSQL 17 с расширением pgvector, настроить конфигурацию LLM-провайдера и установить агент на машину с индексируемыми файлами. Сообщество принимает контрибуции - от новых помощников до улучшений криптографического протокола.