ai-l1-support-agent
MCP server for AI-native L1 support: triages tickets, answers from a knowledge base, escalates to L2 via Telegram/GitHub, and manages feedback, with a LangGraph workflow and safety guardrails.
README
AI L1 Support Agent
Контролируемый AI-native процесс первой линии поддержки. Текущий статус:
- этап 1: архитектура и доменные контракты — готово;
- этап 2: MCP-инструменты и тестовые интеграции — готово;
- этап 3: первичная классификация (triage), правила безопасности, ответы из KB и оценка качества — готово;
- этап 4: LangGraph-оркестратор, контрольные точки и полный процесс обработки — готово;
- этап 5: E2E-демонстрация, безопасная наблюдаемость и расширенная оценка качества — готово;
- этап 6: формальный критерий качества, проверка стабильности и тестовая матрица Linux — готово;
- этап 7: автономный wheel, CI и подготовка публичного репозитория — готово.
По умолчанию проект работает полностью локально: читает зафиксированный снимок тикетов,
пишет только в data/runtime/ и не изменяет публичный MockAPI.
Быстрый запуск: два сценария
Требования: Python 3.10–3.13 и uv.
uv sync --locked
Сценарий 1: воспроизводимый локальный запуск
Это основной режим для проверки логики, демонстрации и разработки. Он читает зафиксированный
снимок заявок, не требует сети и сохраняет все изменения только в data/runtime/.
TICKET_SOURCE=fixture уже является безопасным значением по умолчанию.
# Обработать одну заявку из локального снимка
uv run support-agent-workflow poll --limit 1
# Прогнать пять изолированных сквозных сценариев
uv run support-agent-demo --run-id quick-start
Повтор с тем же рабочим каталогом восстанавливает состояние из SQLite и не дублирует
побочные действия. Для полностью нового прогона используйте другой --run-id демонстрации
или задайте новые RUNTIME_PATH и SQLITE_PATH.
Сценарий 2: чтение реальной очереди MockAPI
Этот режим подтверждает интеграцию с открытым API из задания. Агент получает настоящую заявку по сети, но ответы, статусы, Telegram-сообщения и GitHub Issues по-прежнему записывает только локально. Удалённая очередь не изменяется.
$env:TICKET_SOURCE = "remote"
$env:TICKETS_API_URL = "https://6a7ad74c8c69b3eb4a179621.mockapi.io/tickets/tickets"
$env:ALLOW_REMOTE_WRITES = "false"
$env:RUNTIME_PATH = "data/runtime/remote-quick-start"
$env:SQLITE_PATH = "data/runtime/remote-quick-start/agent.sqlite3"
uv run support-agent-workflow poll --limit 1
Для следующего запуска в том же терминале можно вернуться к локальному снимку:
$env:TICKET_SOURCE = "fixture"
RemoteTicketSource намеренно поддерживает только чтение. ALLOW_REMOTE_WRITES=false
зафиксирован как дополнительный предохранитель; удалённый адаптер записи в проекте вообще
не реализован. Локальный overlay не синхронизируется с MockAPI, поэтому состояние разных
экземпляров агента не является общим.
MockAPI является внешним сервисом. Если он или сеть недоступны, команда намеренно завершится
ошибкой ticket API is unavailable, не переключаясь незаметно на локальные данные. В таком
случае проверьте URL и повторите сетевой запуск позднее; автономный сценарий остаётся доступен.
Запуск MCP-сервера
uv run support-agent-mcp
Команда запускает MCP-сервер support-tools через stdio. Для локальной разработки .env
необязателен: безопасные значения уже являются значениями по умолчанию. Для изменения
настроек скопируйте .env.example в .env; секреты и рабочие файлы исключены из Git.
Установка собранного пакета
Wheel содержит локальные тестовые заявки, набор оценочных сценариев, демонстрацию и
тестовую базу знаний, поэтому команды работают и вне исходного репозитория. Изменяемое
состояние создаётся в data/runtime/ текущего каталога или по путям из окружения.
uv build
uv venv .wheel-venv
uv pip install --python .wheel-venv/Scripts/python.exe dist/*.whl
.wheel-venv/Scripts/support-agent-eval.exe --runs 2
Исходный архив и wheel собираются в dist/; каталог намеренно не хранится в Git.
Полный процесс обработки
Команда support-agent-workflow запускает LangGraph с сохраняемыми контрольными точками
поверх тех же сервисов, которые опубликованы как MCP-инструменты:
# Один тикет или вся очередь новых тикетов
uv run support-agent-workflow start 3
uv run support-agent-workflow poll --limit 10
# Состояние после рестарта процесса
uv run support-agent-workflow status 3
# Безопасная хронология метаданных контрольных точек и инструментов без содержимого заявки
uv run support-agent-workflow trace 3
# Возобновление ожидания пользователя или инженера
uv run support-agent-workflow user <ticket-id> "Уточнённые симптомы"
uv run support-agent-workflow engineer <ticket-id> "Подтверждённое решение" --author l2 --confirmed
Одна заявка всегда использует идентификатор потока support-ticket:<ticket-id>.
Контрольные точки хранятся в SQLite, а все записи в заявки, Telegram, GitHub и черновики
дополнительно защищены стабильными ключами идемпотентности. Поэтому восстановление
контрольной точки и повтор узла не создают дубликаты побочных действий.
Воспроизводимая демонстрация
support-agent-demo запускает пять синтетических E2E-сценариев в отдельном каталоге,
не затрагивая обычный data/runtime/agent.sqlite3:
uv run support-agent-demo
uv run support-agent-demo --run-id interview-demo
Покрыты ответ из KB, эскалация L2 и одноразовое решение, отчёт об ошибке и переиспользуемое
решение, уточнение пользователя с повторной классификацией, низкая уверенность и
safe_review. Завершённый запуск повторно читает сохранённый demo-report.json;
незавершённый каталог с тем же ID не перезаписывается. В отчёте есть фазы, количество
контрольных точек и событий аудита, но нет текстов заявок и содержимого вызовов инструментов.
Проверка
uv run ruff format --check .
uv run ruff check .
uv run mypy
uv run pytest --cov --cov-report=term-missing
uv run support-agent-eval --runs 3 --output data/runtime/evaluation.json
uv run support-agent-eval --case-id http-500-software-bug
GitHub Actions проверяет форматирование, Ruff, строгий mypy, pytest с покрытием ветвей и стабильность тестового провайдера на Python 3.10 и 3.13. Отдельное задание собирает sdist/wheel, устанавливает wheel вне исходного репозитория и запускает оценку качества, демонстрацию и CLI процесса. Проверка через LM Studio не входит в CI, потому что требует локальную модель; её зафиксированный прогон описан ниже.
Тесты используют официальный MCP-клиент в памяти и отдельно запускают точку входа stdio.
Оценка качества прогоняет 20 подготовленных бизнес-сценариев классификации и решения через
выбранный LLM_PROVIDER, измеряет время каждого сценария и всего запуска; по умолчанию
используется воспроизводимый провайдер на основе правил.
Из 20 сценариев 13 помечены как safety_critical. Критерий качества выполнен, только если
доля успешных попыток не ниже 90%, все критические попытки успешны, ошибки провайдера и
схемы отсутствуют, а повторные запуски каждого сценария дают одинаковый смысловой
результат. --runs 3 проверяет не 20, а 60 попыток; хэш исходного набора сохраняется в
JSON-отчёте.
Первичная классификация и база знаний
Первичная классификация возвращает строгий TriageDecision: достаточность и перечень
недостающих фактов, категорию, приоритет, маршрут, оценку уверенности (confidence),
извлечённые факты и флаги риска. После ответа
модели детерминированная политика отдельно проверяет:
- недостаток фактов — запросить конкретное уточнение;
- низкую уверенность при достаточных фактах —
safe_review; - модельный priority — нормализовать независимой бизнес-политикой по явным признакам;
- инъекцию инструкций — проигнорировать и отметить флагом;
- лимит уточнений — передать в безопасную очередь исключений.
Поиск в KB выполняется до эскалации. Автоматический ответ разрешён только при совпадении
категории, порога релевантности и отсутствии exclusions статьи. Ответ состоит из текста
статьи и обязательной ссылки KB:<article_id>; свободной генерации решения нет.
Проверенные ответы пользователя не теряются после повторной классификации: они участвуют
в поиске и проверке применимости статьи, добавляются в выжимку для L2, отчёт об ошибке и
контекст будущего черновика статьи. Telegram-эскалация и GitHub Issue всегда содержат ссылку
на исходную заявку, построенную от настроенного TICKETS_API_URL.
LM Studio
Адаптер LM Studio уже реализован через совместимый с OpenAI строго структурированный ответ:
LLM_PROVIDER=lmstudio
LLM_BASE_URL=http://127.0.0.1:1234/v1
LLM_MODEL=google/gemma-4-12b-qat
LLM_API_KEY=
LLM_REASONING=none
После запуска локального сервера выбранную модель можно проверить командой
uv run support-agent-eval. google/gemma-4-12b-qat Q4_0 прошла текущий набор 20/20
за 74,9 секунды и E2E-демонстрацию 5/5 за 22,9 секунды при контексте 13 056 токенов.
Провайдер на основе правил остаётся безопасным значением по умолчанию для тестов и
воспроизводимой демонстрации. Подробнее:
проверка LM Studio.
MCP-инструменты
| Группа | Инструменты |
|---|---|
| Заявки | tickets_list_new, tickets_get, tickets_update_classification, tickets_add_reply, tickets_change_status |
| База знаний | knowledge_search, knowledge_get_article, knowledge_create_draft |
| Эскалация | telegram_notify_l2, github_create_bug |
| Обратная связь | feedback_add, feedback_list |
Входные и выходные JSON Schema формируются MCP SDK из строгих Pydantic-моделей. Все
изменяющие инструменты требуют стабильный idempotency_key, журналируются в SQLite и
имеют соответствующие MCP annotations. knowledge_create_draft создаёт только черновик
со статусом pending_human_review; инструмента автоматической публикации намеренно нет.
Данные и безопасность
TICKET_SOURCE=fixture— воспроизводимый режим по умолчанию.TICKET_SOURCE=remote— чтение публичного MockAPI без права записи.ALLOW_REMOTE_WRITES=false— зарезервированный явный предохранитель; текущий адаптер вообще не реализует удалённые записи.data/runtime/— SQLite, локальные изменения, исходящие сообщения и тестовые Issues; каталог исключён из Git.data/knowledge_base/— опубликованные тестовые статьи, которые входят в репозиторий.data/fixtures/— зафиксированные входные данные для тестов.data/demo/— пять синтетических заявок для изолированной E2E-демонстрации.traceнамеренно возвращает только метаданные. Полное состояние контрольной точки остаётся локально в SQLite и должно защищаться как рабочие данные поддержки.
Документы
- Финальная архитектура
- Устройство проекта и руководство по защите
- ADR-001: управляемый процесс и модульный MCP-сервер
- Контракты домена
- Правила первичной классификации и маршрутизации
- Отчёт по этапу 1
- Отчёт по этапу 2
- Отчёт по этапу 3
- Отчёт по этапу 4
- Отчёт по этапу 5
- Отчёт по этапу 6
- Отчёт по этапу 7
- Сценарий демонстрации и сдачи
- Проверка модели в LM Studio
- ADR-002: LangGraph и сохраняемые контрольные точки
Проект распространяется по лицензии MIT. Правила безопасного сообщения об уязвимостях описаны в SECURITY.md.
Машиночитаемые контракты
Локальный снимок данных находится в data/fixtures/tickets.snapshot.json. Он используется
для воспроизводимых тестов; удалённый MockAPI рассматривается как источник только для чтения.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。