transit_functiongemma_mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@transit_functiongemma_mcp東京駅を検索して"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
transit_functiongemma_mcp
google/functiongemma-270m-it を乗換案内MCP専用のtool routerとしてLoRA/QLoRA SFTする最小実験環境です。モデルは経路や料金を回答せず、許可されたMCP tool callだけを生成します。経路・料金・所要時間・路線情報は常に https://api.transit.ls8h.com/mcp が返す値を使用します。
構成
scripts/fetch_tools.py: MCPtools/listを取得し、MCP形式とFunctionGemma形式で保存training/prepare_sft.py: synthetic JSONLをFunctionGemmaのmessages/tool_calls形式へ変換training/train_lora.py: fp16、batch size 1、gradient accumulation付きLoRA/QLoRA学習transit_functiongemma/infer.py: 決定的デコードでfunction callを生成scripts/mcp_client.py: callを厳格parse・schema検証後、MCPtools/callを実行evaluation/eval_toolcall.py: 指定された5指標を集計data/raw/synthetic_template.jsonl: 学習データの小さな雛形(本学習前に拡張必須)datagen/generate_synthetic_dataset.py: schema適合済みの拡張train/eval JSONLを決定的に生成datagen/generate_balanced_synthetic_dataset.py: 9 classを均等化したhard-negative付きデータを生成evaluation/analyze_dataset.py: 分布、重複、arguments、token長をJSON/Markdownで分析training/train_lora_plus.py: attention+MLP projectionを選択できる4GB向け追加実験transit_functiongemma/route_normalizer.py: MCP raw resultを事実のみの共通JSONへ正規化transit_functiongemma/route_constraints.py: 経路内の駅を抽出し、avoid/via条件を決定的に検査transit_functiongemma/route_renderer.py: 正規化済みJSONを追加LLMなしで日本語化transit_functiongemma/answer_pipeline.py: router、MCP、正規化、制約検査、rendererを接続transit_functiongemma/local_tools.py: MCPへ送らないローカル疑似tooltransit_functiongemma/station_resolver.py: 路線別IDを物理駅のgeo:地点へ安全に解決
Related MCP server: mcp-stm-montevideo
1. サーバーへ配置
モデル、venv、checkpoint、キャッシュは学習サーバー側の作業ディスクに置きます。<server> と /path/to は環境に合わせて読み替えてください。
rsync -av --exclude .venv --exclude outputs ./ <server>:/path/to/transit_functiongemma_mcp/
ssh <server>
cd /path/to/transit_functiongemma_mcp
bash scripts/setup_server.sh
source /path/to/venvs/transit-functiongemma/bin/activate
export HF_HOME=/path/to/huggingface
export XDG_CACHE_HOME=/path/to/cache
export PIP_CACHE_DIR=/path/to/pip-cacheGemmaの利用規約をHugging Faceで承認し、hf auth login でアクセストークンを設定してください。PyTorch wheelはサーバーのNVIDIA driver/CUDAに合うものを先に入れるのが安全です。
2. schema取得とデータ変換
python scripts/fetch_tools.py
python training/prepare_sft.py --schema-mode baked拡張データセットを再生成する場合:
python datagen/generate_synthetic_dataset.py --route-groups 80
python training/prepare_sft.py \
--input data/raw/synthetic_generated.jsonl \
--output data/processed/sft_generated.jsonl \
--schema-mode baked8ツールの完全な宣言は512 tokenを大幅に圧迫するため、既定はschemaを重みに覚えさせる baked です。compact / full も比較用に選べます。学習スクリプトはassistant targetまで512 tokenに収まらないrecordを除外し、全件超過なら停止します。
学習lossはdeveloper/user/tool responseをmaskし、最後のassistant function call(不足情報例では空のassistant turn)だけに適用します。これにより長いpromptの模倣よりtool call構文を優先します。512 token学習とprompt分布を一致させるため、推論も baked が既定です。
raw JSONLの1行は次の形です。駅名は直接 plan_journey に入れず、最初に suggest_stations で解決します。
{"id":"example","reference_datetime":"2026-06-28 09:00 Asia/Tokyo","user":"東京駅を検索","assistant":{"tool_name":"suggest_stations","arguments":{"q":"東京駅","limit":5}}}不足情報のnegative exampleは "assistant":{"no_tool_call":true} とします。変換後は空のassistant turnとなり、実行側も自然文をMCP callとして扱いません。
3. LoRA学習
GTX 1650 4GB向けの開始設定です。full fine-tune、bf16、batch size増加は実装していません。
python training/train_lora.py \
--dataset data/processed/sft_generated.jsonl \
--output-dir outputs/functiongemma-transit-lora \
--max-seq-length 512 \
--lora-rank 8 \
--epochs 3 \
--gradient-accumulation-steps 16通常のLoRAでも270Mモデルは小さいため、まず上記を試します。OOM時は指定どおり次へ落とします。
FunctionGemmaの一部RMSNorm重みはGTX 1650上でbase全体をfp16保存するとoverflowするため、通常LoRAは凍結baseをfp32保持し、学習演算をfp16 autocastで行います。fp16 GradScalerは初期scaleを1にしてNaNを防止します。bf16は使用しません。--qlora ではNF4量子化、fp32 norm、fp16 matrix computeを使用します。
python training/train_lora.py --max-seq-length 256 --lora-rank 4 \
--output-dir outputs/functiongemma-transit-lora-r4さらにbase modelの常駐量を減らす比較実験は --qlora を追加します。GTX 1650とbitsandbytesの組み合わせでは環境依存があるため、LoRAを既定にしています。
4. 推論とMCP実行
python -m transit_functiongemma.infer '東京駅を検索して' \
--adapter outputs/functiongemma-transit-lora
python scripts/mcp_client.py \
--model-output '<start_function_call>call:suggest_stations{q:<escape>東京駅<escape>,limit:5}<end_function_call>'scripts/mcp_client.py は次を満たさない出力を実行しません。
FunctionGemma形式で厳密にparseできる
自然文とcallが混在しない
callがちょうど1件
tool名が取得済みschemaの許可リスト内
argumentsがMCPのJSON Schemaに適合
完全なMCP envelopeは artifacts/mcp/ に保存されます。MCP Appsが返す structuredContent、埋め込みresource / resource link、_meta も欠落させず保存します。標準出力の自然文整形はMCP content[type=text] を表示するだけの決定的テンプレートです。
5. 評価
まず付属の正解形式predictionで評価器自体を確認できます。
python evaluation/eval_toolcall.py --predictions data/eval/predictions_example.jsonl学習済みadapterを直接評価する場合:
python evaluation/eval_toolcall.py --run-model \
--adapter outputs/functiongemma-transit-lora出力指標は parse_success_rate、tool_name_accuracy、required_arguments_satisfaction_rate、datetime_normalization_success_rate、no_call_when_missing_info_rate です。詳細は artifacts/eval_report.json に保存されます。
実運用経路はraw model、表記正規化+schema、実MCP final pipelineを必ず分離して評価します。
python scripts/run_three_stage_evaluation.py \
--adapter outputs/functiongemma-transit-intent-r5 \
--intent-dataset data/eval/operational_intent_raw_100.jsonl \
--final-dataset data/eval/operational_tokyo_routes_100.jsonl各段階の意味は次の通りです。
raw model: 元の日本語をFunctionGemmaへ直接入力し、
resolve_route_requestとslotを採点normalized: NFKCと空白だけを正規化し、schema-invalid callを拒否して採点
final pipeline: model slotを駅解決・実Transit MCP・filter/reranker/rendererまで通して採点
追加SFTのdata/raw/operational_intent_train.jsonlとraw holdout
data/eval/operational_intent_raw_100.jsonlは入力文重複ゼロです。前者は駅名を固定
ローテーションした同等表現、後者はユーザー作成の元100件です。
従来protocolの大規模holdoutと手書き実用評価は互換回帰として残しています。
旧regex意味評価を再現するときだけ--legacy-semantic-evalを明示してください。
python evaluation/validate_eval_datasets.py
python evaluation/eval_toolcall.py \
--dataset data/eval/independent_holdout_300.jsonl \
--run-model --adapter outputs/functiongemma-transit-ja-real-r4 \
--normalize-ja --schema-constraint \
--output artifacts/eval_independent_holdout_300.json \
--markdown-output artifacts/eval_independent_holdout_300.md \
--failures-output artifacts/failures_independent_holdout_300.jsonl
python evaluation/eval_toolcall.py \
--dataset data/eval/manual_practical_100.jsonl \
--run-model --adapter outputs/functiongemma-transit-ja-real-r4 \
--normalize-ja --schema-constraint \
--output artifacts/eval_manual_practical_100.json \
--markdown-output artifacts/eval_manual_practical_100.md \
--failures-output artifacts/failures_manual_practical_100.jsonlhistory付き行は解決済み駅IDを含む会話全体をrouterへ渡します。rawモデルのparse/tool
精度と、表記正規化・schema制約後の精度は分けて記録します。前段はユーザー文から
priority / avoid / via / mode / time_modeを抽出・補完しません。
実Transit MCPを使う固定7シナリオのE2E評価:
python evaluation/eval_pipeline.py \
--adapter outputs/functiongemma-transit-ja-real-r4 \
--max-routes 1raw envelope、normalized JSON、renderer回答、request/MCP latency、timeout、retryを
artifacts/e2e_*とartifacts/latency_report.jsonへ保存します。
--max-routes 1はレイテンシゲート用にMCPの探索候補数も1件へ制限します。Web UIは
3候補表示を維持します。
2026-06-29の最終実測では、independent_holdout_300はparse/tool/arguments包含/
required/no-call/schemaがすべて100%でした。manual_practical_100はclass/toolとno-callが
100%、intent slot macro F1が97.84%、avoid/viaと日時正規化が100%でした。固定7シナリオの
実MCP E2Eは7/7、p50 1.50秒、p95 4.06秒、timeout 0%、no-call無通信100%、rendererの
source-only検査100%です。詳細は artifacts/eval_independent_holdout_300.md、
artifacts/eval_manual_practical_100.md、artifacts/e2e_eval_report.md を参照してください。
評価器は、現行MCP schemaに存在しない期待引数と、user/historyから観測できない期待値を 件数付きで意味評価から除外します。これはモデルに入力外の値を推測させないためで、raw model指標、schema制約後の指標、除外件数を別々に保存します。
注意
synthetic_template.jsonl の20件は配線確認用です。通常学習にはschema検証済み470件の synthetic_generated.jsonl を使います。さらなる実験では各tool、言い換え、相対日時、曖昧駅名、誤誘導、required欠落、多段tool responseをtrain/evalで重複しないよう増やしてください。demo-feed:* は学習例内のtool responseから受け取った架空IDであり、実MCPへ送る値ではありません。
tool選択改善用のbalanced実験は NEXT_EXPERIMENT.md を参照してください。ask_clarification は任意のローカル疑似toolであり、scripts/mcp_client.py が必ずMCP送信前に処理します。
旧口語日本語実験の履歴は
JAPANESE_ROUTING_EXPERIMENT.mdを参照してください。
現在の--normalize-jaはNFKCと空白整理だけです。旧intent/slot regexは
semantic_fallback=Trueまたは--legacy-semantic-evalを明示した互換試験と、offlineの
annotation migrationに限定され、productionでは使いません。棚卸しは
artifacts/PARSER_RULE_AUDIT.mdにあります。
GTX 1650 4GBで口語日本語86件を加えた5 epochのLoRA本学習を完了しました。外部評価は
口語holdout 17件でparse/tool/arguments/no-call/schemaがすべて100%、9 class均等の
corrected eval 72件でparse/tool/no-call/schemaが100%、expected argumentsが81.25%です。
配備adapterはoutputs/functiongemma-transit-ja-real-r4です。
6. LLMを使わない日本語回答パイプライン
FunctionGemmaは自然文回答モデルではなく、MCP tool callを選ぶrouterとしてのみ使います。
経路、時刻、運賃、路線などの事実はTransit MCPが取得し、transit_functiongemma/route_normalizer.pyが
MCPのraw resultを共通JSONへ変換します。transit_functiongemma/route_constraints.pyは駅IDまたは保守的に
正規化した駅名で回避・経由条件を検査し、transit_functiongemma/route_renderer.pyがそのJSONに存在する値
だけをPythonテンプレートで日本語化します。
後段LLMを置かないのは、MCP結果にない経路・料金・時刻・路線名や、回避条件の成否を
生成モデルが補完してしまう余地をなくすためです。normalizer、constraints、rendererは
ネットワークを使用せず、オフラインで単体テストできます。ネットワークアクセスは
scripts/mcp_client.pyとtransit_functiongemma/answer_pipeline.pyに限定しています。
rendererだけをサンプルJSONで確認:
python -m transit_functiongemma.route_renderer --input data/examples/route_normalized_example.json
python -m transit_functiongemma.route_renderer --input data/examples/station_suggestions_example.json
python -m transit_functiongemma.route_renderer --input data/examples/place_suggestions_example.json学習済みadapterを使った一連の実行:
export FUNCTIONGEMMA_ADAPTER=outputs/functiongemma-transit-ja-real-r4
python -m transit_functiongemma.answer_pipeline "東京駅を検索して"
python -m transit_functiongemma.answer_pipeline "東京タワーを場所として探して"
python -m transit_functiongemma.answer_pipeline "町田から池袋まで、渋谷を避けて" \
--normalize-ja --save-normalized artifacts/normalized --debug現在のrouterは駅名を直接経路toolへ渡さず、まずsuggest_stationsで解決する段階式です。
経路要求ではtransit_functiongemma/answer_pipeline.pyがそのcallを物理駅解決へ切り替え、suggest_placesの
完全一致駅だけを残し、300m以内の同名Transit/OSM地点を1駅にまとめます。その代表
geo: endpointを多段tool履歴へ戻すため、東海道線・京浜東北線などのfeed IDを経路探索
前に選ぶ必要がありません。「横浜」と「新横浜」、同名の店舗などは一致扱いにしません。
同名の物理駅が離れた場所に複数ある場合だけ利用者へ確認します。
python -m transit_functiongemma.answer_pipeline "横浜から上野までの経路を探して"
python -m transit_functiongemma.answer_pipeline "横浜から上野まで、京浜東北線で行きたい"「京浜東北線で」のような明示路線は、MCPが返した経路の各legをクライアント側で検査し、 該当候補を優先表示します。サードパーティーMCPの検索条件自体は変更できないため、返却 候補に指定路線がなければ、その範囲では確認できなかったと表示し、経路を捏造しません。
transit_functiongemma/answer_pipeline.pyはrouter出力を厳格parseし、取得済みJSON Schemaで検証してから
MCPを呼びます。空callまたはask_clarificationの場合はMCPを呼ばず確認文を返します。
raw envelopeは既定でartifacts/mcp/へ保存され、--save-normalizedを指定すると正規化
JSONも保存されます。主なオプションは--adapter、--mcp-url、--schema-mode、
--save-raw、--save-normalized、--max-routes、--debugです。
実MCP保存物をオフラインで正規化する場合:
python -m transit_functiongemma.route_normalizer \
--input artifacts/mcp/example_plan_journey.json \
--tool-name plan_journey \
--output artifacts/normalized/example.json
python -m transit_functiongemma.route_renderer --input artifacts/normalized/example.json7. Web UI
静的UIはサーバーの/var/www/html/transit/に配置し、Apacheの内部プロキシから
127.0.0.1:8091の常駐APIへ接続します。APIは学習済みadapterを一度だけGPUへロードし、
各リクエストで同じToolRouterを再利用します。APIポート自体は外部公開しません。
https://<your-domain>/transit/サービス確認・再起動:
systemctl --user status transit-functiongemma-web.service
systemctl --user restart transit-functiongemma-web.service
journalctl --user -u transit-functiongemma-web.service -f実運用behavior log
数週間の表現揺れ・時刻解釈・tool選択を検証する場合は、systemd unitの
TRANSIT_BEHAVIOR_LOG=1とTRANSIT_BEHAVIOR_LOG_USER_QUERY=1を有効にします。
ログはJSTの日付ごとに次へ保存されます。
artifacts/behavior_logs/YYYY-MM-DD.jsonl各行はrequest ID、入力、router出力、モデルが出したmodel_route_intent、deterministic
planner step、parsed tool call、schema検証、
MCPへ送った最終引数、MCP status/attempt/latency、回答、全体latencyを持ちます。lat、lon、
geo: endpointと緯度経度文字列は常にマスクし、MCP raw resultとnormalized route本体は
behavior logへ保存しません。既定保持期間は45日で、期限切れの日次ファイルは起動時と
日付変更後の最初の記録時に削除されます。
# 今日のログを追う
tail -f artifacts/behavior_logs/$(date +%F).jsonl
# サーバーから回収する
rsync -av <server>:/path/to/transit_functiongemma_mcp/artifacts/behavior_logs/ \
artifacts/behavior_logs/検索文保存は検証期間だけ有効にし、終了後は
TRANSIT_BEHAVIOR_LOG_USER_QUERY=0またはTRANSIT_BEHAVIOR_LOG=0へ戻してください。
都内経路の実運用表現サンプルをまとめて実Web APIへ流す場合:
python scripts/run_operational_samples.py \
--dataset data/eval/operational_tokyo_routes_100.jsonl \
--url http://127.0.0.1:8091/query結果は artifacts/operational_tokyo_routes.json と
artifacts/operational_tokyo_routes.md に保存されます。HTTP応答だけでなく、behavior logの
モデルのresolve_route_requestと最終MCP引数を参照し、到着/出発、時刻、回避、経由、
優先条件がmodel extractionとexecutionの両段階を通ったかを採点します。元の日本語を
regexで再抽出して正解扱いにはしません。
同名の物理駅が複数ある場合、Web APIは15分間の対話セッションを作り、UIに候補ボタンを
表示します。選択した物理駅のgeo: endpointを保持して元の検索を再開し、目的地も曖昧
なら続けて候補を表示します。候補名・事業者に加えて座標も表示するため、同名駅を区別
できます。セッション情報はメモリ内だけに保持され、完了または期限切れで削除されます。
単独のsuggest_stations / suggest_places結果もボタン表示されます。候補を選ぶと駅IDを
確定して表示し、「出発地にする」「目的地にする」から次の検索文へつなげられます。経路
検索中の駅解決は路線別IDではなく物理駅geo:を使うため、候補選択が利用路線を不必要に
固定することはありません。
構成ファイルはweb/、APIはweb_api.py、systemd unitの原本は
deploy/transit-functiongemma-web.serviceです。
公開運用向けにclient単位rate limit、MCP timeout、指数backoff retry、短期cache、schema
hash変更検知、request ID、匿名監査ログを実装しています。user queryとraw座標の保存は
既定でOFFです。TRANSIT_WEB_SHOW_TRACE=1ではモデル出力、parse済みcall、schema検証、
MCP call、normalized JSON、renderer回答とlatencyを折り畳み表示できます。公開前の残作業は
NEXT_RELEASE_CHECKLIST.mdを参照してください。
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.
Latest Blog Posts
- 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/sasanokusa/transit_functiongemma_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server