Привет, это Саша Константинов из Cloud.ru. Недавно в статье я рассказал, как после ухода Notion развернул базу знаний в облаке на Wiki-движке Outline, потому что хотел хранить данные и управлять ими самостоятельно и без ограничений, чего не может дать SaaS. И что самое главное, я хотел дорабатывать решение под свои требования.
В этой части истории сосредоточусь на том, как я еще упростил себе жизнь и добавил в базу знаний AI-помощника. Он помогает мне, когда нужно быстро просмотреть тезисы нескольких статей на общую тему или найти ответ на конкретный вопрос в документах по работе. Для доступа к базе я сделал Telegram-бота с подключением через MCP-сервер. Расскажу, как все устроено, поделюсь процессом настройки и интеграции компонентов.
В базе я храню техническую и продуктовую документацию по проектам, расшифровки онлайн-встреч, заметки о решениях, которые приняли при обсуждении функциональности, обучающие материалы. Кроме личных файлов, я добавил в базу и общедоступные данные по работе, например, информацию о сервисах Cloud.ru. Наполнение базы — индивидуальный процесс, он полностью зависит только от нужд и желаний пользователя, в данном случае моих.
В первой статье я подробно описывал, как делал базу знаний, а тут только кратко напомню:
Создал виртуальную машину Ubuntu 22.04, настроил для нее публичный IP-адрес, сделал бакет в облачном хранилище и настроил для него CORS.
На ВМ поднял Docker и развернул в нем Outline — та самая open source альтернатива Notion. Outline подключил к GitLab для бэкапов и синхронизации и к бакету, чтобы загружать картинки и файлы.
Поставил на ту же виртуалку nginx как обратный прокси, выпустил для него бесплатный SSL-сертификат в Let’s Encrypt для шифрования трафика по HTTPS.
Получилась небольшая база знаний, которой не нужен администратор и много денег на обслуживание. За использование виртуалки и S3-хранилища с free tier плачу 146 рублей в месяц. На таких условиях к базе можно подключить до 20 пользователей (правда, у моей только один — я сам) и хранить до 10 000 записей.
Вообще, база знаний довольно удобная, например, можно быстро найти ссылку на нужный вебинар или информацию по проекту. Только приходится держать в голове, что где хранится: ссылка в заметке к прочитанной статье или в расшифровке встречи? А может в списке «Посмотреть позже»? Когда я от этого окончательно устал, решил прикрутить к базе AI-агента. Сейчас расскажу, как я это делал и какая архитектура у агента.
Выделю пару вариантов интеграции:
RAG c векторной базой. Тут нужно вытащить данные из базы, разбить их на чанки, векторизовать через embedding и сохранить в векторной БД.
MCP-сервер для интеграции. MCP — это протокол, который позволяет AI-агентам подключаться к внешнему миру, взаимодействовать с ним, читать и записывать нужную информацию.
RAG дает более качественные ответы, но требует больше времени на настройку. Для него нужно сделать ETL-процесс, который синхронизирует данные из базы знаний с RAG-базой. Кроме того, появляются вопросы по RBAC разграничению прав для разных пользователей (если их больше одного). Может получиться так, что нужно поддерживать несколько баз.
Я выбрал второй вариант с MCP-сервером. AI-агент работает с токеном и в режиме реального времени получает ответы от базы по API. Причем токен у каждого пользователя свой, и по нему можно разграничить права, если необходимо. Получается проще, дешевле и надежнее.
Как выглядит подключение на практике:
Иду через AI-агента в LLM, вытаскиваю ключевые фразы, которые хочу найти в базе знаний.
Подключаюсь к базе знаний по API через MCP-сервер и получаю данные.
AI-агент формирует ответ через LLM.
Я все настроил в облаке с помощью сервиса для создания автономных AI-агентов. Работа сервиса основана на двух протоколах:
A2A для интеграции агентов, при котором можно создавать мультиагентные системы, где агенты общаются между собой.
MCP, при помощи которого агент может общаться с внешним миром, с различными интеграциями, с Wiki- и CRM-системами и не только.
Я уже написал агента, которого буду использовать, — это open source проект, лежит на GitHub, можно брать и модифицировать, как захочется. В решении два основных компонента: MCP-сервер для интеграции с Outline Wiki и AI-агент, который работает на поисковом сервере MCP и LLM. Проект написан на двух языках: AI-агент на Python, MCP-сервер на Node.js. Я сделал именно так, чтобы показать свободу в выборе технологий: от языка разработки проект не зависит.
Структура проекта выглядит так:
├── agent/ # AI-агент (Python) │ ├── assistant/ # Основной код ассистента │ ├── Dockerfile # Docker конфигурация для агента │ ├── requirements.txt # Python зависимости │ └── README.md # Документация агента ├── mcp-server/ # MCP-сервер (TypeScript/Node.js) │ ├── src/ # Исходный код сервера │ ├── dockerfile # Docker конфигурация для сервера │ ├── package.json # Node.js зависимости │ └── README.md # Документация сервера └── README.md # Общая документация проекта
Дополнительно в папке tg-bot найдете инструкцию, как прикрутить Telegram-бота и взаимодействовать с агентом через него. Можно сделать любой другой интерфейс, например, в вебе через FastAPI, или интегрировать MCP-сервер в корпоративный мессенджер, или работать с ним через терминал. Как больше нравится.
Итак, покажу, как все развернуть с помощью облачного сервиса, о котором говорил выше. Начну с MCP-сервера, его надо запустить перед деплоем агента. Из возможностей сервера выделю вот что:
Все интегрируется с Outline Wiki для поиска информации.
Двойная поддержка транспортов: Streamable HTTP (советую его) и SSE. Правда, SSE-транспорт уже не очень актуальный, но если нужна совместимость с устаревшими клиентами — подойдет.
Поддержка множественных MCP-сессий. Несколько пользователей смогут запрашивать данные одновременно.
MCP-сервер уже упакован в Docker-контейнер со всеми зависимостями.
TypeScript — полная типизация, код простой и предсказуемый.
CORS поддержка, которая настроена для веб-приложений. Сможете потом сделать веб-чат для агента на отдельном фронтенде, и ошибок не будет.
Для установки скачиваю код MCP-сервера и перехожу в редактор. Код находится в файле mcp-сервер → package.json.
Итак, у меня есть команда для деплоя. Она состоит из трех шагов: собрать решение в докере, присвоить ему тег и залить все в репозиторий:
Буду заливать решение в облачное хранилище артефактов. У меня уже есть репозиторий, поэтому я просто меняю плейсхолдер <package-name> на имя своего репозитория, перехожу в директорию mcp-server и запускаю деплой:
Так по очереди выполнятся все три команды: docker build, docker tag и docker push.
Перехожу в реестр и проверяю, что в моем репозитории (у вас это может быть, например, Repository MCP Server) появился новый тег с образом.
Далее захожу в сервис, в котором буду делать AI-агента. В разделе MCP-сервера создаю новый сервер. Для этого выбираю образ из репозитория — тот, который я только что загрузил. Затем задаю переменные окружения, как описано в README.md репозитория:
BASE_URL: URL моей базы Outline с путем /api — допустим, https://wiki.yourcompany.com/api.
SEARCH_RESULTS_LIMIT: количество документов за один поиск, например, три.
Добавляю секретную переменную — API-ключ для доступа к Outline. Для этого я использовал сервис для управления криптографическими ключами. Итак, чтобы получить API-ключ, надо:
Перейти в настройки базы знаний Outline: Параметры→ API и приложения.
Создать новый ключ и дать ему имя, например, MCP.
Создать новую переменную с секретом.
Выбрать ключ шифрования, который только что создан.
Задать ему имя, например, OUTLINE_TOKEN.
При создании можно задать срок действия — неделю, месяц — или ввести произвольное значение. Кроме того, можно ограничить область видимости документов для конкретного API-ключа: пригодится, если нужно раздать разные доступы к разделам базы знаний. К примеру, чтобы у дизайнеров не было доступа к конфиденциальным документам юристов. Мне не пригодилось, самого себя ограничивать не стал :-)
Дальше можно создать единый аккаунт, на котором установить доступ только к конкретной информации, и использовать API-ключ с этого аккаунта. Или задать каждому пользователю свой ключ доступа, чтобы разграничить права. Я, естественно, остановился на первом варианте.
В разделе Ресурсы MCP-сервера оставляю порт 8080. Жму Продолжить.
Дальше надо задать правила для создания MCP-сервера. Я использую режим serverless, когда при отсутствии нагрузки сервер отключается. И заплачу я, соответственно, только за время, когда действительно пользовался базой и ботом. Но если надо, чтобы сервер принимал запросы 24/7, можно активировать плашку Не выключать MCP-сервер:
В этом же разделе можно настроить аутентификацию, чтобы MCP-сервер был защищен токеном. Для простоты авторизацию я не делал, но для прод-решений она все-таки нужна.
Жму Создать.
Теперь пора проверить MCP-сервер через вкладку Тестирование. Копирую публичный URL для доступа к серверу:
Проверяю, как все работает, через MCP Inspector — open source проект специально для теста таких серверов:
Меня перекинуло в новую вкладку браузера. Вставляю публичный URL моего MCP-сервера и обязательно добавляю в конец ссылки путь /mcp. Далее жму Connect.
Пробую что-нибудь поискать с инструментом Tools → Search. Не буду показывать личные файлы, воспользуюсь базой с общедоступной информацией по работе. Ввожу ключевое слово, например, «телефон». По запросу подтянулся номер службы поддержки, а еще упомянуто, в каких случаях клиенту пригодится указать его мобильный. Работает :)
Перед тем как перейти к установке, расскажу, что вообще агент может делать:
искать по базе знаний через MCP с помощью инструмента search,
давать более релевантные ответы за счет ключевых слов,
обрабатывать ошибки и давать повторные ответы,
отслеживать историю диалога.
Из требований:
Python 3.8+ и новее,
запущенный MCP-сервер, который предоставляет инструмент search,
совместимая с OpenAI конечная точка LLM. Я использую облачный сервис готовыми LLM- и AI-моделями, доступными по API.
Чтобы задеплоить агента, выполняю такие же команды, как и для деплоя MCP-сервера, только их беру из файла README.md в папке agents. Далее захожу в сервис → жму Создать агента в правом верхнем углу:
Кликаю на Агент из Docker-образа и загружаю задеплоенного агента из репозитория артефактов:
В конфигурациях выбираю LLM, с которой буду работать. Все конфигурации передаются через параметры окружения, и сервер может их подцепить. Это удобно, так как не нужно идти в переменные окружения сервиса. Можно прямо в интерфейсе выбрать новую модель или MCP-сервер или задать переменную.
Порт контейнера указываю 10 000. Кроме того, нужно задать системный промпт, согласно которому будет работать AI-агент. В моем решении промпт уже вшит, и самостоятельно сочинять его не нужно — достаточно прописать «промпт не требуется». В конце выбираю задеплоенный в предыдущих шагах MCP-сервер, с которым будет работать агент.
После того как я задал нужные параметры, нажимаю Создать. Для создания потребуется несколько минут — провайдеру надо выделить ресурсы, чтобы агент заработал. После того как все готово, перехожу в AI Agents → Агенты и выбираю только что созданный. Его работоспособность буду проверять через примеры кода. Чтобы их увидеть, жму кнопку Использовать.
Подключение к агенту идет через A2A-протокол. В случае с Python, на котором написано мое решение, это a2a-sdk. Для подключения потребуется базовый URL — выделил его на скрине:
В моем решении есть Telegram-бот с преднастроенной конфигурацией. В нее включен TELEGRA_BOT_TOKEN, который можно получить через бота @Bot_Father в Telegram. А кроме того, конфиги самого агента: его URL и токен для аутентификации:
Я специально создал образец env.example для удобства. В нем заполняю поля и сохраняю как рабочий файл .env:
Далее запускаю бот командой, нахожу его по имени в Telegram и проверяю — задаю вопросы :-)
Моя база знаний и бот — небольшая попытка упростить себе жизнь и заодно сделать что-то полезное. Один раз потратив время на создание и настройку, я теперь вовсю пользуюсь его подсказками. Например, после ответа на конкретный вопрос AI-агент может предложить мне почитать статью на ту же тему, о которой сам я и не вспомнил бы.
Пока я не решил, что еще добавить, но есть несколько интересных мыслей. К примеру, можно сделать интеграцию с другими агентами. Дать агенту для разработки доступ к документации моего проекта прямо из IDE через интеграцию MCP-сервера.
Решение развернуто в open source, все есть на GitHub. Пользуйтесь им и модифицируйте, как сами захотите. И подключайтесь к обсуждению в комментариях, может, у вас остались вопросы или предложения.
Источник


