Skip to main content
Glama

FAQ RAG MCP Server

Небольшое приложение для генерации с дополнением поиском (Retrieval-Augmented Generation, RAG), созданное для технического упражнения Glean Solutions Engineering. Оно индексирует предоставленные FAQ-файлы в Markdown, находит релевантные фрагменты с помощью косинусной близости, формирует обоснованный ответ через LLM и предоставляет результат в виде одного локального MCP-инструмента: ask_faq.

Проект полностью кроссплатформенный: все команды настройки и запуска используют uv и одинаковы на Windows, macOS и Linux. Передаёте это пользователю Windows с Claude Code? Начните с START_HERE_WINDOWS.md. В репозитории есть CLAUDE.md — runbook по настройке, который Claude Code читает автоматически, а также переносимое определение .mcp.json в области проекта для сервера faq-rag.

Объяснение за тридцать секунд

При запуске процесса Python читает FAQ-файлы, разбивает их на фрагменты примерно по 200 символов, создаёт эмбеддинги, нормализует их и кэширует индекс в памяти. На каждый вопрос он создаёт эмбеддинг вопроса, ранжирует фрагменты по косинусной близости, отправляет четыре лучших текстовых фрагмента настроенной LLM и возвращает только готовый ответ и имена файлов-источников.

flowchart LR
  A[FAQ Markdown files] --> B[~200-character chunks]
  B --> C[Document embeddings cached in RAM]
  Q[Question] --> D[Query embedding]
  C --> E[Cosine similarity]
  D --> E
  E --> F[Top 4 text chunks]
  F --> G[Grounded LLM generation]
  G --> H[answer + sources]
  H --> I[MCP client]

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

Related MCP server: faq-rag

Точный MCP-контракт

Инструмент: ask_faq

Вход:

{
  "question": "How do I reset my password?",
  "top_k": 4
}

Выход — без дополнительных ключей:

{
  "answer": "Use the reset link on the login page [faq_auth.md].",
  "sources": ["faq_auth.md", "faq_sso.md"]
}

top_k принимает целые числа от 1 до 10 и по умолчанию равен 4.

Почему MCP, а не предложенный HTTP-вариант?

Ядро RAG было бы одинаковым под любой обёрткой. MCP выбран потому, что ИИ-клиент может обнаружить схему инструмента, решить, когда его вызывать, запустить локальный Python-процесс и получить структурированные результаты без собственного HTTP-клиента, порта, URL или health-эндпоинта. MCP улучшает интероперабельность; сам по себе он не улучшает качество поиска.

В этой реализации используется требуемый в задании транспорт stdio. MCP-клиент запускает mcp_server.py как локальный дочерний процесс и обменивается MCP-сообщениями через стандартный ввод и вывод процесса. Сервер не пишет обычные логи в stdout, потому что этот канал зарезервирован для протокольного трафика.

Настройка (любая ОС: Windows, macOS, Linux)

Требования:

  • Git

  • uv — он автоматически загружает совместимую версию Python, поэтому отдельная установка Python не нужна. Windows: winget install -e --id astral-sh.uv; macOS: brew install uv.

  • Ключ OpenAI API с доступными кредитами

  • MCP-клиент, например Claude Code или Cursor

Команды одинаковы в PowerShell, zsh и bash:

git clone https://github.com/cq2wgwtzb5-lgtm/glean-faq-rag-mcp.git
cd glean-faq-rag-mcp
uv sync

Создайте .env.local, скопировав .env.example, затем добавьте в него ключ API в своём редакторе:

OPENAI_API_KEY=your_key_here

.env.local игнорируется Git. Никогда не коммитьте и не передавайте его.

Запустите детерминированные тесты (без вызовов API):

uv run pytest -q

Запустите прямой сквозной smoke-тест перед подключением MCP:

uv run rag_core.py

Claude Code автоматически обнаруживает включённый в репозиторий .mcp.json при запуске сессии в этой папке. Следуйте инструкциям docs/WINDOWS_MCP_SETUP.md, чтобы одобрить, проверить и вызвать его (шаги применимы к любой ОС). Пользователи Windows могут также запустить setup_windows.ps1, который оборачивает те же команды uv.

Использование из любого чата на машине

.mcp.json в области проекта загружается только в сессиях, запущенных внутри этой папки. Чтобы сделать ask_faq доступным в каждой сессии Claude Code на машине, зарегистрируйте сервер один раз в области пользователя с абсолютным путём к клону (та же команда на любой ОС):

claude mcp add --scope user faq-rag -- uv run --directory "<absolute path to this repo>" mcp_server.py

Сессии внутри репозитория продолжают использовать запись в области проекта; все остальные сессии используют запись в области пользователя. Удалите её командой claude mcp remove --scope user faq-rag.

Оценка

Модульные тесты используют детерминированные фейковые эмбеддинги и не вызывают модели:

uv run pytest -q

Живой оценщик прогоняет пять показательных вопросов через реальные API моделей и проверяет ожидаемые источники, обязательные факты и поведение отказа от ответа:

uv run evaluate.py --output eval-results.json

eval-results.json намеренно игнорируется, потому что вывод модели и конфигурация аккаунта могут различаться. Захватите отчёт или покажите экран во время собеседования.

Важные проектные решения

Индекс NumPy в памяти

Предоставленный корпус создаёт лишь несколько фрагментов. Векторная база данных добавила бы сложность развёртывания и ревью без улучшения результата. Нормализованные векторы NumPy превращают косинусную близость в простое произведение матрицы на вектор.

Разбиение с учётом границ

Целевой размер остаётся примерно 200 символов, как требуется. Реализация предпочитает границы абзацев, строк, предложений и слов, чтобы текст не разрезался в произвольном месте только ради точного числа.

Один проход эмбеддингов при запуске

Эмбеддинги документов создаются один раз при запуске процесса и кэшируются в оперативной памяти. Каждый вопрос получает новый эмбеддинг запроса. Кэш — это общие данные корпуса, а не память разговора или пользовательской сессии. Когда процесс завершается, кэш исчезает и пересоздаётся при следующем запуске.

Обоснованная генерация и цитирование

Промпт генерации ограничивает модель извлечённым контекстом из FAQ, требует точных цитат с именами файлов и предписывает сообщать, когда FAQ не отвечают на вопрос. Список sources в ответе сохраняет порядок выдачи и содержит только имена файлов из извлечённых фрагментов.

Явное поведение при ошибках

Приложение немедленно завершается с ошибкой, если отсутствует OPENAI_API_KEY, отклоняет пустые вопросы и некорректные значения top_k, использует 30-секундный тайм-аут модели и допускает две повторы SDK. Ошибки остаются ошибками MCP, а не выдуманными ответами из FAQ.

Известные ограничения и развитие в production

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

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

Структура репозитория

  • rag_core.py — загрузка, разбиение, эмбеддинги, поиск и генерация

  • mcp_server.py — один MCP-инструмент ask_faq поверх stdio

  • faqs/ — предоставленный корпус FAQ

  • tests/ — детерминированные модульные тесты и тесты конфигурации

  • evals/cases.json — пять живых оценочных кейсов

  • evaluate.py — запуск живой оценки

  • pyproject.toml / uv.lock — закреплённое кроссплатформенное окружение (uv sync)

  • setup_windows.ps1 — удобная обёртка для Windows вокруг тех же шагов uv

  • CLAUDE.md — автоматическая настройка и обучающие инструкции для Claude Code

  • .mcp.json — переносимая конфигурация MCP для Claude Code в области проекта

  • START_HERE_WINDOWS.md — передача пользователю Windows одним промптом

  • docs/WINDOWS_MCP_SETUP.md — шаги подключения к Claude Code

  • docs/TALK_TRACK.md — презентация для собеседования и ожидаемые вопросы

  • docs/REQUIREMENTS_TRACEABILITY.md — карта соответствия задания и кода

  • docs/VALIDATION.md — пройденные проверки и оставшаяся граница живых тестов

Безопасность

Не коммитьте ключи API. Проверяйте MCP-серверы перед их включением; локальный stdio-сервер работает с правами пользователя, запустившего клиент. Этот сервер читает только настроенную директорию FAQ и вызывает настроенные модели OpenAI.

Подготовка к собеседованию

Используйте docs/TALK_TRACK.md. В нём объясняется архитектура, причины каждого выбора, чем MCP отличается от HTTP и как это небольшое упражнение соотносится с задачей корпоративного поиска и обоснованных ответов в Glean.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables answering natural-language questions from FAQ documents using vector search and LLM generation via an MCP tool.
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP clients to query a compiled Markdown knowledge base through a single ask tool, returning cited answers grounded in wiki articles over stdio or streamable HTTP.
    -