Skip to main content
Glama
qinshoudawang

Followin MCP

Followin-MCP

Обзор проекта

Этот проект можно рассматривать как прототип событийной системы рекомендаций для сферы криптоновостей:

  • Источник: получение исходного контента через Followin API + adapters.py

  • normalizer.py: нормализация исходного контента в структурированные ContentItem

  • service.py: в методе get_personal_feed сначала выполняется явный многоканальный отбор (recall), затем семантическое дополнение

  • clustering.py: объединение нескольких элементов контента в EventCluster (событийный кластер)

  • ranking.py: генерация персонализированной ленты с помощью эвристического ранжирования по нескольким сигналам + переранжирование MMR

Краткое резюме:

Прототип Followin MCP для криптоновостей: нормализация исходного контента в структурированные элементы, последующий многоканальный отбор, семантическое дополнение, кластеризация событий и персонализированное ранжирование для создания событийной ленты для пользователя.

Related MCP server: Daily News MCP Server

Структура каталогов

  • followin_mcp/ Точка входа пакета Python

  • followin_mcp/core/ Основная бизнес-логика: адаптеры, модели, нормализатор, ранжирование, сервис

  • followin_mcp/mcp/ Точка входа MCP-сервера

  • followin_mcp/demo/ Тестовый агент и Web-демо

  • scripts/start_dev.sh Скрипт для локального запуска

  • web/ Статические ресурсы фронтенда

Основные модули

  • followin_mcp/core/adapters.py Слой адаптации Followin API

  • followin_mcp/core/models.py Модели данных

  • followin_mcp/core/taxonomy_rules.py Конфигурация таксономии / правил

  • followin_mcp/core/normalizer.py Нормализация исходного контента, извлечение сущностей, распознавание типов событий

  • followin_mcp/core/clustering.py Кластеризация событий

  • followin_mcp/core/ranking.py Персонализированное ранжирование и пояснения

  • followin_mcp/core/semantic_recall.py Индексация эмбеддингов, семантический отбор, сходство элементов

  • followin_mcp/core/service.py Сервисная точка входа для MCP / прикладного уровня

Последовательность обработки запросов

sequenceDiagram
    participant U as MCP client / agent
    participant M as mcp/server.py
    participant S as service.py
    participant A as adapters.py
    participant F as Followin API
    participant N as normalizer.py
    participant SR as semantic_recall.py
    participant C as clustering.py
    participant R as ranking.py

    U->>M: call tool
    M->>S: get_latest / search / get_personal_feed ...

    S->>A: fetch raw content
    A->>F: HTTP request
    F-->>A: raw payload
    A-->>S: raw items

    loop per raw item
        S->>N: normalize(raw)
        N-->>S: ContentItem\nentities / event_type / scores
    end

    S->>SR: enqueue normalized items
    SR-->>S: background indexing

    opt personal feed / semantic supplement
        S->>SR: recall(query, candidate pool)
        SR-->>S: semantic candidates / similarity
    end

    opt personal feed
        S->>C: cluster_same_event(items)
        Note over C: uses item embedding similarity
        C-->>S: EventCluster list
        S->>R: rank_for_user(user, clusters)
        Note over R: uses semantic_match_score
        R-->>S: ranked clusters
    end

    S-->>M: tool payload
    M-->>U: MCP response

Цепочка обработки

1. Точка входа MCP

  • mcp/server.py

    • Предоставляет 7 инструментов MCP

    • Преобразует входные параметры MCP в вызовы service.py

    • Отвечает за сериализацию ContentItem / EventCluster в структуру ответа MCP

2. Получение исходного контента

  • service.py -> adapters.py

    • get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics Прямая передача возможностей пагинации вышестоящего API

    • get_trending_feeds / search_content Возврат текущего снимка результатов

    • get_personal_feed Сначала выполняет явный многоканальный отбор и семантическое дополнение, затем переходит к кластеризации событий и персонализированному ранжированию

3. Нормализация контента

  • normalizer.py

    • normalize(raw) преобразует один исходный элемент в ContentItem

    • Источники извлечения сущностей:

      • теги

      • ключевые слова блокчейнов

      • псевдонимы проектов

      • псевдонимы токенов

      • псевдонимы тем

      • динамические псевдонимы (легковесное обнаружение сущностей / побочный NER)

    • Результат:

      • projects / tokens / chains / topics

      • entity_sources

      • entity_confidence (сила метода сопоставления)

      • event_type

      • credibility_score (достоверность источника)

      • importance_score (расчет по заданным правилам)

4. Отбор (Recall)

  • Под «отбором» здесь понимается:

    • Извлечение набора кандидатов ContentItem из общего пула контента

    • Использование для последующей кластеризации, ранжирования и пагинации

  • service.py в personal feed сначала выполняет явный многоканальный отбор:

    • latest

    • trending

    • project

    • search

  • Результаты многоканального отбора сначала дедуплицируются по item.id

    • Если один и тот же элемент найден несколькими путями, приоритет отдается версии с более сильным семантическим соответствием, более высокой важностью и более свежей датой

5. Кластеризация событий

  • clustering.py

    • Вход: список ContentItem

    • Выход: список EventCluster

    • Цель кластеризации — «одно событие», а не один проект или одна тема

    • Основные сигналы:

      • совместимость типов событий

      • временное окно

      • перекрытие сущностей с весами достоверности

      • сходство заголовков

      • опциональное семантическое сходство

6. Персонализированное ранжирование

  • ranking.py

    • Вход: EventCluster

    • Выход: отранжированная лента кластеров для пользователя

    • Основные сигналы:

      • importance_score

      • freshness_score

      • follow_affinity_score

      • interest_match_score

      • semantic_match_score

      • source_quality_score

      • risk_boost_score

    • mute_penalty

    • В конце выполняется переранжирование для диверсификации в стиле MMR

7. Эмбеддинги

  • semantic_recall.py

    • Нормализованный элемент сначала ставится в очередь (enqueue) асинхронного воркера эмбеддингов

    • Эмбеддинги элементов хранятся в локальной базе SQLite semantic_index.db

  • Эмбеддинги в настоящее время участвуют в трех процессах:

    • service.py в personal feed выполняет семантический отбор / дополнение с учетом запроса (query-aware)

    • clustering.py использует сходство эмбеддингов как один из сигналов кластеризации

    • ranking.py включает сигнал семантического соответствия в итоговое ранжирование через semantic_match_score

Personal Feed

  • get_personal_feed — единственный инструмент ленты с поддержкой сессий

  • Основной процесс:

    • явный многоканальный отбор

    • семантическое дополнение

    • кластеризация событий

    • персонализированное ранжирование

  • service.py поддерживает FeedSessionState, где хранятся:

    • pending_clusters

    • delivered_event_ids

    • delivered_item_ids

    • source_cursors

  • Результат содержит:

    • ranked_clusters

    • развернутые поддерживающие items

    • next_cursor

    • has_more

  • Семантика пагинации:

    • Первый запрос создает сессию ленты и заполняет pending_clusters отранжированными кластерами

    • Текущая страница берет первые max_items кластеров из начала pending_clusters

    • Возвращенные кластеры / элементы записываются в набор доставленных, чтобы избежать повторов

    • Последующие запросы «еще» продолжают потреблять оставшиеся pending_clusters

    • Когда буфер опускается ниже порога пополнения, запускается новый цикл отбора, семантического дополнения, кластеризации и ранжирования

Семантика инструментов и границы контекста

Текущие инструменты MCP можно разделить на две категории:

  • Инструменты запроса контента

    • get_latest_headlines

    • get_trending_feeds

    • get_project_feed

    • get_project_opinions

    • get_trending_topics

    • search_content

  • Инструменты рекомендаций

    • get_personal_feed

Инструменты запроса контента по умолчанию не имеют состояния:

  • get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics

    • Передают возможности пагинации вышестоящего API

    • Возвращают одну страницу результатов для текущего запроса

  • get_trending_feeds / search_content

    • Возвращают текущий снимок

    • Не поддерживают дополнительное состояние пагинации на уровне сервиса

get_personal_feed — единственный инструмент с состоянием:

  • service.py поддерживает FeedSessionState с коротким жизненным циклом

  • Внешне открыт только feed session cursor

  • Внутри сервера сохраняются:

    • pending_clusters

    • delivered_event_ids

    • delivered_item_ids

    • source_cursors

  • Последующие запросы «еще» продолжают потреблять pending_clusters из сессии

Разграничение ответственности:

  • Слой tool / service

    • Обеспечивает получение контента, отбор кандидатов, кластеризацию, ранжирование и управление сессией ленты

  • Слой agent

    • Отвечает за выбор инструментов в многоходовых диалогах и поддержание контекста

    • Например: продолжить предыдущую выдачу, развернуть предыдущий элемент, уточнить на основе предыдущего результата

Текущая семантика пагинации:

  • get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics

    • Возвращают метаданные курсора вышестоящего API

  • get_personal_feed

    • Возвращает next_cursor и has_more

    • Семантика cursor — продолжение сессии ленты, а не обычная пагинация списка

Используемые технологии / алгоритмы

  • Python + MCP (FastMCP)

  • Адаптер Followin API

  • Правиловое извлечение сущностей

    • сопоставление псевдонимов

    • сопоставление тегов источников

    • правила ключевых слов

  • Классификация событий

    • эвристический многосигнальный скоринг

  • Достоверность сущностей

    • strong / medium / weak

  • Семантический отбор

    • OpenAI embedding

    • косинусное сходство

    • векторная персистентность в SQLite

  • Кластеризация

    • жадная инкрементальная кластеризация

    • перекрытие Жаккара с весами достоверности

    • сходство заголовков по Жаккару

    • сходство эмбеддингов элементов

  • Ранжирование

    • эвристический линейный ранжировщик

    • переранжирование для диверсификации в стиле MMR

Чего не хватает прототипу по сравнению с промышленными решениями

Возможности отбора / рекомендательной системы

  • В слое рекомендаций еще нет полноценного разделения долгосрочного / сессионного представления пользователя

  • Нет цепочки асинхронного обновления профиля пользователя на основе логов поведения

Понимание контента

  • Есть легковесное обнаружение сущностей / слабый NER (теги, псевдонимы, правила, извлечение с помощью LLM), но нет основной цепочки универсального онлайн-NER / связывания сущностей со смещением (span offset)

  • Таксономия событий все еще опирается на правила «холодного старта», не хватает калибровки на основе размеченных данных

  • Текущий credibility_score в основном зависит от типа источника / метаданных; из-за ограничений данных нет более детальной надежности на уровне источников и верификации по нескольким источникам

Кластеризация

  • Сходство эмбеддингов используется как сигнал, но в целом это эвристическая многосигнальная кластеризация, а не обученная модель классификации пар / слияния

  • Для перехода к онлайн-системе на базе постоянного хранилища кластеров нужны возможности назначения кластеров, а также жизненный цикл кластеров (эволюция, разделение, слияние)

Ранжирование

  • Используется semantic_match_score на базе эмбеддингов, но в основе лежит эвристический линейный ранжировщик с ручными весами, а не обучение ранжированию (LTR)

  • В слой рекомендаций не подключены поведенческие признаки (клики, время просмотра, шеринги)

  • Реализована только легкая диверсификация MMR, нет системного контроля квот и бизнес-ограничений

Текущие инструменты MCP

  • get_latest_headlines

  • get_trending_feeds

  • get_project_feed

  • get_project_opinions

  • get_trending_topics

  • search_content

  • get_personal_feed

Web Demo

Если вы хотите протестировать «случайный профиль пользователя + многоходовой диалог», можно запустить Web-демо:

python3 -m followin_mcp.demo.webapp

Или после установки:

followin-mcp-web

Затем откройте:

http://127.0.0.1:8000

Демо поддерживает:

  • Случайную генерацию профиля пользователя

  • Создание сессии LangChain-агента для текущего профиля

  • Сохранение контекста многоходового чата в одной сессии

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

  • Отображение вызовов инструментов, произошедших в каждом раунде

  • Отображение карточек с параметрами и результатами инструментов

Перед запуском убедитесь, что в .env настроено:

FOLLOWIN_API_KEY=your_api_key
OPENAI_API_KEY=your_openai_api_key

MCP Server

Следующие возможности уже представлены как инструменты MCP:

  • get_latest_headlines

  • get_trending_feeds

  • get_project_feed

  • get_project_opinions

  • get_trending_topics

  • search_content

  • get_personal_feed

Способ запуска:

python3 -m followin_mcp.mcp.server

Или после установки:

followin-mcp-server

ACP Agent

Если вы хотите использовать текущего агента как ACP stdio-агент для клиентов, поддерживающих ACP, запустите:

python3 -m followin_mcp.acp.server

Или после установки:

followin-acp-agent

Текущая обертка ACP напрямую использует FollowinChatAgent:

  • Сессия ACP соответствует сессии FollowinChatAgent

  • prompt() вызывает существующий chat_stream()

  • Текст ассистента передается клиенту ACP потоковыми чанками

  • Профиль пользователя по умолчанию считывается из FOLLOWIN_ACP_PROFILE_JSON, если не настроен — используется встроенный профиль по умолчанию

Для подключения к локальному acpx / OpenClaw, в ~/.acpx/config.json можно использовать минимальную конфигурацию:

{
  "agents": {
    "followin": {
      "command": "/path/to/python",
      "args": ["-m", "followin_mcp.acp.server"],
      "cwd": "/path/to/followin-mcp"
    }
  }
}

Здесь не нужно дополнительно прописывать env:

  • followin_mcp.acp.server при запуске выполняет load_dotenv()

  • Если cwd указывает на корень проекта, будет считан файл .env из репозитория

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    F
    maintenance
    Real-time cryptocurrency news, analysis, and price predictions for AI agents. 5 tools to search 50,000+ articles across 12 categories, filter by 120+ asset tickers, and access content with built-in attribution. Free with attribution. SSE and Streamable HTTP transport.
    4
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables querying and aggregating Chinese and international news along with multi-platform trending topics, featuring deduplication, event clustering, and article extraction for AI clients.
    7
    MIT