Skip to main content
Glama
LiuYuWei

leave-copilot

by LiuYuWei

Leave Copilot — MCP에서 전용 Agentic 모델까지

실행 가능한 참조 구현: MCP의도적으로 어렵게 설계된 휴가/근태 도구를 표준화하고, Google ADK로 이를 조작할 수 있는 Agent를 만들고, 이중 평가로 기반 모델의 부족함을 측정한 뒤, 이 도구들을 원래 잘 다루는 전용 모델을 미세 조정합니다.

이것은 2026 iThome 철인전 30일 시리즈의 부속 코드입니다.


도구가 '의도적으로 어렵게 설계된' 이유

일반적으로 API 설계는 직관적이고 사용하기 쉽게 하는 것을 추구하지만, 이 프로젝트는 그 반대가 필요합니다.

검수 방식은 미세 조정 전후의 성능 차이를 비교하는 것입니다. 도구가 너무 직관적이면 기반 모델이 원래 올바르게 호출할 수 있어 정확도가 처음부터 만점에 가깝고, 미세 조정은 자연히 어떤 개선도 보여주지 못합니다. 미세 조정이 효과가 없어서가 아니라, 개선할 여지가 아예 없기 때문입니다.

따라서 선택 기준은 단 하나입니다: 기반 모델이 거의 반드시 틀리고, 미세 조정으로 가르칠 수 있는 것.

의도적으로 심은 네 가지 난점

#

난점

구현 방식

모델의 전형적인 오류

호출 간 의존성

번호를 추측 불가능한 형식(LV-7f3a91)으로 하고, 없으면 명시적으로 오류 보고

조회를 건너뛰고 LV-001로 추측

Elicitation 삼태

파괴적 작업은 ctx.elicit()를 거치며, accept/decline/cancel 의미가 각각 다름

decline 후 다른 도구로 우회

상태 머신 제약

상태는 draft → submitted → approved → taken 단계로만 진행

draft에서 approved로 직접 점프

매개변수 함정

시간은 시간(hour) 단위(반나절 = 4, 0.5 아님), employee_id는 이름이 아님, ISO 8601

hours=0.5, employee_id="林筱涵" 전달

이 네 가지 난점의 공통 특징: 모두 JSON Schema로 표현할 수 없는 규칙입니다. Schema는 status가 네 문자열 중 하나여야 한다는 것은 관리할 수 있지만, '이 번호가 어디서 왔는지'는 관리할 수 없습니다.


Related MCP server: MCP Leave Management

빠른 시작

환경

패키지

버전

이유

mcp

>=1.29,<2

이 시리즈는 1.x의 FastMCP를 사용하므로 버전 범위를 생략하지 마세요

google-adk

2.x

1.x도 유지보수되지만, 새 프로젝트가 구버전에서 시작할 이유는 없습니다

Python

>=3.10

둘의 공통 하한

첫 번째 항목은 특히 걸리기 쉽습니다. 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

실제로 Server에 연결하여 네 가지 난점을 하나씩 트리거하고 오류 메시지와 반환 의미를 확인합니다:

難點 ① 跨呼叫依賴
  ✓ 捏造的編號被擋下
  ✓ 錯誤訊息指出正確取得方式
  ✓ 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

도구 모음

아홉 개의 도구와 평가 스크립트 전용 관리 엔드포인트 하나가 있습니다.

카테고리

도구

readOnlyHint

휴가 신청

search_leaves, get_leave

직원

list_employees, get_leave_balance

결재

update_leave_status, add_comment

인수인계

schedule_handover

취소

withdraw_leave, cancel_approved_leave

✗(Elicitation 사용)

관리

_reset_fixtures

readOnlyHint는 단순한 문서가 아닙니다. 평가 도구가 이를 통해 '읽기 전용 준수성'을 계산합니다: Agent가 읽기 전용 작업에서 쓰기 도구를 사용했는지 여부입니다.

_reset_fixtures는 Agent 쪽에서 반드시 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 部署

✅ 완료 및 실측됨 ⏳ 구축 중


Port 할당

⚠️ FastMCP와 Google ADK api_server의 기본 port는 모두 8000이므로, 둘 중 하나를 반드시 변경해야 합니다. 이 프로젝트는 MCP Server를 8090으로 옮겼습니다.

서비스

Port

MCP Server(streamable-http)

8090

Google ADK api_server

8000

평가 도구 Web UI

8080

vLLM

8001

Ollama

11434


관련 프로젝트

  • ADEval — Google ADK Agent 평가 도구(Apache-2.0)

  • Twinkle Eval — 표준 Benchmark 평가(MIT)

라이선스

Apache-2.0


검증된 부분

eval/verify_difficulties.pyeval/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.

기반 모델의 행동 관찰

verify_agent.py의 B 섹션은 단언하지 않고 기록만 합니다 — 모델이 틀렸다고 해서 테스트가 실패하는 것이 아니며, 그것이 바로 측정하려는 대상입니다. 실제로 실행해 보면 가장 주목할 만한 실패 패턴은 다음과 같습니다:

모델이 도구 호출 대신 텍스트 응답을 사용합니다. 파괴적 작업에 직면했을 때 gemini-3.7-flashcancel_approved_leave를 호출하여 Server가 Elicitation을 발행하게 하는 대신, 스스로 대화에서 '정말입니까?'라고 묻는 경향이 있습니다. 결과적으로 확인 프로세스가 프로토콜 계층에서 대화 계층으로 떨어지며, 대화 계층의 확인은 강제력이 없습니다.

더 심각한 변형은 환각형 성공입니다 — 모델이 '휴가 신청서를 결재에 제출했습니다'라고 답하지만, 도구 시퀀스에 update_leave_status가 전혀 없고 휴가 신청서 상태도 변하지 않았습니다. 사용자는 완료된 줄 압니다.

이런 실패는 Prompt로 제거할 수 없습니다. 모델의 '안전'에 대한 내장된 성향에서 비롯되기 때문입니다. 이것이 바로 이후에 미세 조정으로 처리할 대상입니다.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables employees to check leave balance, apply for leave, and view leave history through natural language using Claude Desktop.
  • F
    license
    Not graded
    quality
    C
    maintenance
    Simulates a leave management workflow for employees and managers, including leave application, balance checks, and approval processes.
  • A
    license
    A
    quality
    C
    maintenance
    Enables 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.
    6
    MIT

Latest Blog Posts

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