leave-copilot
Leave Copilot — от MCP к собственной агентной модели
Рабочая эталонная реализация: стандартизация набора намеренно усложнённых инструментов для отпусков/учёта рабочего времени с помощью MCP, создание агента, способного ими управлять, с помощью Google ADK, измерение недостатков базовой модели с помощью двойной оценки, а затем дообучение собственной модели, которая от природы умеет работать с этим набором инструментов.
Это сопутствующий код 30-дневной серии iThome Ironman 2026.
Почему инструменты «намеренно усложнены»
Обычно API проектируют так, чтобы они были интуитивно понятными, но этому проекту нужно противоположное.
Приёмка заключается в сравнении результатов до и после дообучения — если инструменты слишком интуитивны, базовая модель и так сможет правильно их вызывать, точность изначально будет близка к максимуму, и дообучение, естественно, не покажет никакого улучшения. Это не потому, что дообучение неэффективно, а потому что просто нет пространства для улучшения.
Поэтому критерий выбора только один: базовая модель почти наверняка ошибается, а дообучение может научить.
Четыре намеренно внедрённые сложности
# | Сложность | Реализация | Типичная ошибка модели |
① | Межвызовные зависимости | Номер в непредсказуемом формате ( | Пропускает запрос, сразу предполагает |
② | Три состояния Elicitation | Деструктивные операции через | После decline использует другой инструмент в обход |
③ | Ограничения конечного автомата | Состояние может продвигаться только | Перескакивает с draft сразу на approved |
④ | Ловушки параметров | Часы считаются в часах (полдня = 4, а не 0.5), | Передаёт |
Общая черта этих четырёх сложностей: все они — правила, которые невозможно выразить в JSON Schema. Schema может гарантировать, что status — одна из четырёх строк, но не может гарантировать, «откуда взялся этот номер».
Related MCP server: MCP Leave Management
Быстрый старт
Окружение
Пакет | Версия | Почему |
|
| В этой серии используется FastMCP версии 1.x, диапазон версий не опускайте |
|
| 1.x всё ещё поддерживается, но нет причин начинать новый проект со старой версии |
Python |
| Общий минимум для обоих |
Первый пункт особенно коварен, потому что официальный сайт MCP Python SDK по умолчанию показывает документацию другого API (
MCPServer), которая полностью отличается от используемого здесь синтаксисаFastMCP.
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txtЗапуск MCP Server
python -m mcp_server.server # streamable-http on 127.0.0.1:8090Проверка четырёх сложностей
python eval/verify_difficulties.pyРеально подключается к серверу, поочерёдно запускает все четыре сложности и проверяет сообщения об ошибках и семантику возвращаемых значений:
難點 ① 跨呼叫依賴
✓ 捏造的編號被擋下
✓ 錯誤訊息指出正確取得方式
✓ search_leaves 查得到真實編號
…
難點 ④ 參數陷阱
✓ 餘額欄位以小時命名
✓ 傳姓名而非員工編號被擋下
難點 ② Elicitation 三態
✓ accept → cancelled
✓ decline → aborted
✓ cancel → aborted
✓ accept_but_false → aborted
✓ 撤銷後時數退回餘額
✓ decline 的訊息明確禁止繞道
✓ cancel 的訊息與 decline 語意不同
──────────────────────────────────────────────
19/19 通過Сброс тестовых данных
update_leave_status, cancel_approved_leave реально изменяют данные. Перед каждым раундом оценки сброс обязателен, иначе предварительные условия второго раунда отличаются от первого, и результаты несопоставимы.
python eval/reset.pyНабор инструментов
Девять инструментов плюс один административный endpoint, предназначенный только для оценочного скрипта.
Категория | Инструмент |
|
Заявки на отпуск |
| ✅ |
Сотрудники |
| ✅ |
Согласование |
| ✗ |
Передача дел |
| ✗ |
Отзыв |
| ✗ (через Elicitation) |
Администрирование |
| ✗ |
readOnlyHint — это не просто документация — оценочный инструмент использует его для расчёта «соблюдения режима только для чтения»: использовал ли агент инструменты записи в задачах только для чтения.
_reset_fixturesна стороне агента обязательно исключить черезtool_filter. Инструмент под названием «сброс» обладает странной притягательностью для LLM.
Почему сообщения об ошибках написаны так подробно
Сообщения об ошибках инструментов возвращаются модели в неизменном виде и становятся основой для её следующего шага.
# ✗ 模型只知道錯了,得猜哪裡錯
raise ValueError("Invalid status transition")
# ✓ 模型知道錯在哪、也知道該改成什麼
raise ValueError(
f"狀態不可從 {current} 跳至 {target},下一個合法狀態為 {next_valid}"
)Это типичный приём компенсации возможностей модели за счёт дизайна инструментов, цена — всего несколько лишних слов.
Структура проекта
.
├── mcp_server/ # ✅ MCP Server:九個工具 + 四個難點
│ ├── server.py
│ ├── store.py # 模擬資料層
│ └── fixtures.py # 初始資料與 reset
├── eval/ # ✅ 驗證與重置腳本
│ ├── verify_difficulties.py # 19/19
│ ├── verify_agent.py # 架構驗證 10/10
│ └── reset.py
├── agents/leave_copilot/ # ✅ Google ADK Agent(含 elicitation callback)
├── plugins/ # ⏳ 軌跡記錄與生產防禦 Plugin
├── data/ # ⏳ 軌跡萃取與資料擴增
├── training/ # ⏳ SFT 訓練腳本
└── deploy/ # ⏳ 權重合併、量化、vLLM 部署✅ Готово и протестировано ⏳ В разработке
Распределение портов
⚠️ У FastMCP и Google ADK api_server порт по умолчанию — 8000, один из них обязательно нужно изменить. В этом проекте MCP Server перенесён на 8090.
Сервис | Порт |
MCP Server (streamable-http) | 8090 |
Google ADK api_server | 8000 |
Веб-интерфейс оценочного инструмента | 8080 |
vLLM | 8001 |
Ollama | 11434 |
Связанные проекты
ADEval — инструмент оценки агентов Google ADK (Apache-2.0)
Twinkle Eval — стандартная бенчмарк-оценка (MIT)
Лицензия
Apache-2.0
Проверенные части
eval/verify_difficulties.py и eval/verify_agent.py реально запускались,
это не «так написано в документации».
MCP Server 層(eval/verify_difficulties.py) 19/19
四個難點的錯誤訊息、Elicitation 四條路徑
Google ADK 層(eval/verify_agent.py,A 段架構驗證) 10/10
McpToolset 載入、tool_filter 排除管理端點
accept / decline / cancel / accept-but-false 四條路徑
都確認走到 Client callback,且語意正確回報Окружение: mcp 1.29.1 + google-adk 2.7.1 + gemini-3.7-flash.
Наблюдения за поведением базовой модели
Секция B в verify_agent.py не делает утверждений, только записывает — если модель отвечает неправильно, это не провал теста,
это как раз то, что нужно измерить. Самый примечательный паттерн отказа из реальных запусков:
Модель отвечает текстом вместо вызова инструмента. Столкнувшись с деструктивной операцией,
gemini-3.7-flashсклонен сам спрашивать в диалоге «Вы уверены?», вместо того чтобы вызватьcancel_approved_leaveи позволить серверу выдать Elicitation. В результате: процесс подтверждения опускается с уровня протокола на уровень диалога, а подтверждение на уровне диалога не имеет принудительной силы.
Более серьёзный вариант — галлюцинированный успех — модель отвечает «Я отправил заявку на согласование»,
но в последовательности вызовов инструментов вообще нет update_leave_status, и статус заявки не изменился. Пользователь думает, что всё сделано.
Такие сбои невозможно устранить с помощью промпта, потому что они проистекают из врождённой склонности модели к «безопасности». Именно это и предстоит обработать последующим дообучением.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Connect, monitor, and control AI agents — tasks, approvals, schedules, and governance.
Shared task queue for humans and AI agents: leases, handoffs, approvals and signed receipts.
Agentic workflow budget approvals with usage receipts.
The system of record for AI agent authority: playbooks, routed policy questions, reusable rules.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables employees to check leave balance, apply for leave, and view leave history through natural language using Claude Desktop.
- FlicenseNot gradedqualityCmaintenanceSimulates a leave management workflow for employees and managers, including leave application, balance checks, and approval processes.
- FlicenseBqualityCmaintenanceEnables HR teams to query and manage employee leave through natural language using Claude Desktop, with tools for checking balances, applying leave, and viewing history.3
- AlicenseAqualityCmaintenanceEnables LLM clients to handle leave applications by providing tools for initialization, organization selection, leave day calculation, attachment checks, uploads, and submission, with built-in business validation and environment switching.6MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/LiuYuWei/leave-copilot-agentic'
If you have feedback or need assistance with the MCP directory API, please join our Discord server