ticket-triage-mcp
AI-агент триажа тикетов — LangGraph + MCP
Производственный рабочий процесс поддержки, который классифицирует неструктурированные запросы, извлекает доказательства из PDF-вложений, обращается к двум внутренним системам через MCP, составляет обоснованный ответ и направляет неоднозначные случаи человеку, а не угадывает.
Таблица оценки
Этап | Результат |
Точность классификации | 100% (20/20) |
F1 извлечения полей | 100% |
Проверки черновика по политикам | 100% |
Заведомо неразрешимые случаи эскалированы | 100% (5/5) |
Причины эскалации по каждому случаю | 100% (5/5) |
Доля ложных эскалаций | 0% (0/15) |
Доля ошибок выполнения | 0% |
Офлайн-задержка | 4.6 мс p50 / 6.7 мс p95 |
Это воспроизводимые результаты на зафиксированном синтетическом корпусе, измеренные на локальной машине разработки под Windows. Задержка зависит от оборудования; оценщик сообщает результат по каждому случаю в artifacts/scorecard.json. Пять сложных случаев покрывают отсутствие доказательств, конфликтующие идентификаторы, нечитаемое вложение, неоднозначный запрос и запись, отсутствующую во внутренней системе. Артефакт также фиксирует время генерации, хэш корпуса, версию Python, идентификатор коммита и транспорт инструментов, чтобы устаревшие результаты были заметны.
Related MCP server: reach-dispute-mcp
Зачем существует этот проект
Большинство демо агентов показывают только счастливый путь. Этот делает воздержание от ответа тестируемым поведением. Агент может вернуть один из двух ограниченных результатов:
drafted— необходимые идентификаторы извлечены, обе проверки MCP только на чтение выполнены, и предоставленные ссылки проверены.escalated— уверенность или доказательства не прошли политику, поэтому агент выдаёт необязывающий ответ-ожидание, очередь для человека, недостающие доказательства и проверяемую причину.
Это решение не спрятано в промпте. Это явное условное ребро в конечном автомате LangGraph и метрика в CI.
Что он делает
Email + PDF
│
▼
classify ──► extract ──► intake safety gate
│
unsafe ───┴─── safe
│ │
▼ ▼
human queue MCP tool 1: customer account
│
MCP tool 2: billing / incident
│
post-tool safety gate
│ │
unverified verified
│ │
▼ ▼
human queue grounded draftДва MCP-инструмента намеренно узкие и только на чтение:
lookup_customer_accountвыполняет точное совпадение по аккаунту/электронной почте.lookup_billing_or_incidentпроверяет биллинг, инцидент обслуживания или ограниченный контекст поддержки.
Граф всегда использует один транспортно-нейтральный контракт MCP-инструмента. Офлайн-оценка использует быстрый внутрипроцессный адаптер; Docker Compose запускает портфельный UI против постоянного реального MCP-сервера JSON-RPC-over-stdio. Оба транспорта покрыты интеграционными тестами, поэтому оркестрация никогда не зависит от выбора развёртывания.
Запуск локально
Предварительные требования: Python 3.11–3.13 и uv.
git clone https://github.com/Mohemed-Amine-Chalhy/ai-ticket-triage.git
cd ai-ticket-triage
uv sync --extra dev --locked
uv run uvicorn ai_ticket_triage.web:app --reloadОткройте http://127.0.0.1:8000. Веб-UI включает все 20 размеченных примеров, загрузчик PDF, трассировку графа, извлечённые поля, доказательства вызовов MCP, итоговое решение и таблицу оценки.
Команда выше использует быстрый внутрипроцессный адаптер. Чтобы запустить именно тот UI, что показан в MCP-демо, запустите зафиксированный контейнер; Compose по умолчанию включает постоянный stdio-сервер:
docker compose up --buildПерегенерируйте все четыре портфельных доказательных изображения из текущей таблицы оценки и реального подробного тестового запуска:
make proofAPI-ключ не требуется. Все имена, адреса электронной почты, аккаунты, счета, услуги и инциденты вымышлены; письма используют зарезервированный домен example.test.
CLI-демо
Запустите разрешимый фикстур:
uv run ticket-triage triage --case billing_duplicate_chargeЗапустите случай с ошибкой и проверьте передачу человеку:
uv run ticket-triage triage --case failure_unreadable_attachmentЗапустите реальный PDF:
uv run ticket-triage triage \
--text "I was charged twice; details are attached." \
--pdf data/sample_attachments/duplicate-charge.pdfПроверьте реальную границу stdio MCP:
uv run ticket-triage triage \
--case billing_duplicate_charge \
--transport stdioВоспроизведение таблицы оценки
uv run ticket-triage-eval \
--output artifacts/scorecard.json \
--markdown-output artifacts/scorecard.md \
--fail-on-runtime-error \
--enforce-portfolio-targetsОценщик оценивает каждый этап независимо: точное совпадение категории, микро-F1 на уровне полей, декларативные проверки черновика, семантическую обоснованность причины передачи, точность/полноту эскалации, ложные эскалации, ошибки выполнения и задержку p50/p95/max. См. Методология оценки.
Использование MCP-сервера независимо
Запустите встроенный сервер официального SDK через stdio:
uv run ticket-triage-mcpПример конфигурации для локального stdio MCP-хоста:
{
"mcpServers": {
"ticket-triage-tools": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/ai-ticket-triage",
"run",
"ticket-triage-mcp"
]
}
}
}Это транспортно-нейтральная граница инструментов: другой совместимый агент или настольный хост может использовать те же два контракта без импорта приложения LangGraph. Для удалённых хостов разместите сервер за аутентифицированным развёртыванием Streamable HTTP; портфельное демо намеренно предоставляет только локальные stdio и внутрипроцессный транспорты.
Инженерные решения
Аспект | Реализация |
Оркестрация | Скомпилированный |
Безопасность | Два шлюза политик; низкая уверенность, конфликты, отсутствие доказательств, нечитаемые файлы, ошибки инструментов и промахи — всё эскалируется |
Документы | Извлечение через |
Граница инструментов | Официальный MCP Python SDK, ровно два инструмента только на чтение, нормализованные конверты ошибок, таймауты |
Контракты | Модели Pydantic с запрещёнными дополнительными полями и JSON-безопасными публичными результатами |
Оценка | 20 версионированных JSON-меток, метрики по этапам, диагностика случаев, перехват ошибок выполнения |
API | FastAPI, сгенерированная документация OpenAPI, ограничения загрузки, ID запросов, безопасные ответы об ошибках, заголовки безопасности |
Эксплуатация | Зафиксированные зависимости, Docker health check, структурированные логи, CI-шлюзы lint/type/test/coverage |
Конфиденциальность | Только синтетические фикстуры; сырые байты PDF исключены из сериализации моделей |
Детерминированность по замыслу
Классификатор, экстрактор и составитель черновика по умолчанию детерминированы. Это делает регрессии безопасности воспроизводимыми, сохраняет публичное демо без учётных данных и отделяет качество рабочего процесса от вариативности моделей. Размещённая модель может заменить эти узлы за теми же типизированными контрактами; в реальном развёртывании её кандидатные выходы всё равно должны проходить через те же шлюзы доказательств и инструментов. Этот репозиторий не утверждает, что синтетический бенчмарк из 20 случаев предсказывает качество на живых данных.
Карта репозитория
src/ai_ticket_triage/
├── agent.py # LangGraph state machine and tool orchestration
├── classifier.py # deterministic category scoring with evidence
├── extractor.py # PDF/text extraction and conflict detection
├── confidence.py # bounded-failure policy gates
├── drafting.py # grounded replies and safe holding responses
├── mcp_server.py # official MCP server; exactly two tools
├── mcp_client.py # in-process and real stdio MCP gateways
├── internal_api.py # mock read-only service adapters
├── evaluation.py # corpus runner and scorecard metrics
├── web.py # FastAPI application
└── static/ # responsive portfolio UI
data/cases/ # 20 synthetic labelled fixtures
tests/ # unit, API, workflow, evaluator, and MCP integration tests
artifacts/ # committed scorecard and proof outputs
assets/ # portfolio-ready architecture and result images
docs/ # architecture, evaluation, security, runbook, portfolio copyКоманды контроля качества
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv run pytest --cov=ai_ticket_triage --cov-report=term-missing
uv run ticket-triage-eval --fail-on-runtime-error --enforce-portfolio-targets
docker compose up --buildДокументация
Известные ограничения
Только текстовые PDF; отсканированные документы требуют OCR и конвейер проверки на вредоносное ПО.
Синтетические внутренние системы с точным совпадением, а не живая CRM или биллинговая платформа.
Англоязычные фикстуры и таксономия из четырёх классов.
Нет постоянной очереди, аутентификации, ограничения частоты запросов или распределённой трассировки в этом локальном демо.
Детерминированная языковая логика — это базовый уровень надёжности, а не замена оценки на репрезентативном, проверенном на конфиденциальность производственном наборе данных.
Эти упущения — намеренные границы проекта выходного дня. Интерфейсы изолируют каждую отсутствующую производственную задачу, чтобы её можно было добавить без переписывания графа.
Лицензия
Available Tools
2 toolslookup_billing_or_incidentC
Read-only billing or service-incident lookup over synthetic data. Also returns bounded workflow guidance for account/other requests.
| Name | Required | Description | Default |
|---|---|---|---|
| product | No | ||
| category | Yes | ||
| order_id | No | ||
| ticket_id | No | ||
| account_id | No | ||
| error_code | No | ||
| invoice_id | No | ||
| service_id | No | ||
| incident_id | No | ||
| account_number | No | ||
| invoice_number | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It declares 'Read-only' and 'over synthetic data', which is useful, but it does not explain error handling, limits, what 'bounded workflow guidance' means, or how the output varies with input combinations. The behavioral description is minimal and undetailed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the core purpose ('Read-only billing or service-incident lookup') and then adds the supplementary workflow guidance. It is well-structured and avoids unnecessary verbosity, though it could be more detailed without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the schema (11 optional parameters, only 1 required) and the absence of annotations and parameter descriptions, the description is heavily underspecified. It does not explain how to select parameters based on the category, what 'bounded workflow guidance' entails, or what the output schema contains. An agent would face significant ambiguity in correctly forming a request.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for missing parameter documentation. It does not explain the meaning or usage of any of the 11 parameters, nor does it clarify which parameters are relevant for 'billing' vs 'service-incident' or how the 'category' field drives the lookup. The parameter names are self-explanatory, but the description adds no additional semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('lookup') and resource ('billing or service-incident'), and also mentions additional workflow guidance. It implicitly distinguishes from the sibling `lookup_customer_account` by domain, though without naming it explicitly. The purpose is specific and understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any explicit guidance on when to use this tool versus alternatives, nor does it mention exclusions or conditions. The phrase 'for account/other requests' is vague and does not clarify selection criteria. No alternatives are referenced.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_customer_accountC
Read-only exact lookup in the synthetic customer account system. Use returned misses or mismatches as escalation evidence.
| Name | Required | Description | Default |
|---|---|---|---|
| No | |||
| ticket_id | No | ||
| account_id | No | ||
| account_number | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full burden. It discloses the read-only nature and that it returns misses or mismatches, which is useful. However, it does not explain how multiple parameters combine, whether authentication is needed, or any other behavioral details beyond these basics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with the key fact 'Read-only exact lookup' front-loaded. Every clause earns its place, and there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 4 optional parameters, zero required, and no parameter documentation, the description is inadequate. It does not explain how to construct a valid lookup, what happens if multiple params are provided, or what escalation evidence looks like. The output schema exists but the description offers no context on call semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the lack of parameter documentation. It does not mention email, ticket_id, account_id, or account_number at all, nor does it explain whether at least one is required, how they interplay, or which is preferred. The agent has no guidance on parameter usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource ('Read-only exact lookup in the synthetic customer account system'), which distinguishes it from the sibling tool by resource. However, it doesn't explicitly name the sibling, so differentiation is implied rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus the sibling lookup_billing_or_incident. The only usage-related hint is 'Use returned misses or mismatches as escalation evidence,' which concerns result handling, not tool selection. It lacks any exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v1.0.0- First observed
lookup_billing_or_incident - First observed
lookup_customer_account
TDQS
Scored across 2 tools
The two tools target distinct data domains (customer accounts vs. billing/incidents), and their descriptions clearly differentiate them. However, since both are lookups and the second tool's name is broader, there is slight potential for an agent to confuse them when deciding which to use.
Both tools follow the same 'lookup_*' verb-noun pattern, with the resource type clearly indicated. This is perfectly consistent and predictable.
With only two tools, the server feels thin for a 'triage' purpose, but the scope might be intentionally limited to read-only lookups. This is borderline on the low end of the range.
The tool surface consists solely of lookups and does not include any actions to actually triage or resolve tickets (e.g., update status, assign, escalate). Even if the second tool returns guidance, the lack of write or workflow-management tools leaves significant gaps for a triage-focused server.
Maintenance
Related MCP Connectors
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Read-only XH Agents MCP connector: service catalogue, payment info, verification checks.
Read-only Frasma MCP: profile, knowledge search, diagnostic handoff. No email.
One governed MCP endpoint for 40+ business systems. Read-only, source-cited answers.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables customer support operations such as order lookup, store credit, refunds, and audit log review through an agent using safe, typed MCP tools.-
- FlicenseNot gradedqualityCmaintenanceProvides read-only MCP tools to diagnose customer billing disputes by analyzing billing records, identifying contradictions, citing evidence, and scoring confidence to auto-resolve or escalate.-
- FlicenseNot gradedqualityBmaintenanceProvides MCP tools that let an agent retrieve customer account, product usage, interaction, and support summaries, and create follow-up tasks after user approval.-
- FlicenseNot gradedqualityCmaintenanceEnables IT helpdesk operations such as retrieving user and device information, checking device status, and creating, retrieving, and updating support tickets through MCP tools.-