laya-mcp
Click on "Deploy 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., "@laya-mcpassess code change risk and tell me if I can auto-merge"
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.
laya-mcp
把 Laya System-1 决策模型封装成一个工程化的 MCP Server(FastAPI 宿主)
一次前向传播回答一组「带类型的问题」,返回校准概率 + 可直接分支执行的决策契约, 让任意支持 MCP 的 Agent(Claude Code / Codex / Cursor / 自研 Agent)都能在毫秒级完成自动决策。
目录
Related MCP server: laya-mcp
这是什么
laya-mcp 把 Laya(一个 System-1 决策模型族)
包装成一个常驻服务,同时对外暴露两种接口:
接口 | 地址 | 面向谁 |
MCP Streamable HTTP |
| 任意 MCP 客户端 / Agent |
REST API |
| 脚本、看板、健康检查、非 MCP 调用方 |
OpenAPI 文档 |
| 人 |
它不是「又一个 LLM 接口」。Laya 是非生成式的:一次 forward pass 回答一组结构化问题, 输出的是校准过的概率分布,而不是一段文本。这使得它可以在 10~50ms 内做出「该走哪条路」的判断, 成本约为调用一次完整 LLM 的千分之一。
与传统做法对比
laya-test.py(见 examples/quickstart_router.py)演示了最小用法:
加载 Router → 构造问题 → router.predict() → 用阈值手写 if。
这个工程把它产品化了:
关注点 |
|
|
模型驻留 | 每次进程启动重新加载 | 常驻单例 + 启动预热(warmup) |
阈值策略 | 每个调用方自己写 | 决策契约,由服务统一输出 |
并发 | 单线程阻塞 | 线程池 + 事件循环不阻塞 + 结果缓存 |
接入方式 | 只能进程内 Python 调用 | MCP / REST / CLI 三种入口共用同一套逻辑 |
可观测性 |
| 结构化日志 + 指标(计数 / 延迟分位) + |
错误处理 | 直接抛异常 | 统一错误码 + HTTP 状态映射 |
配置 | 硬编码 |
|
Agent 可发现性 | 无 | 工具自描述 + resources 知识库 + prompt 模板 |
核心概念:决策契约(Contract)
这是整个项目最重要的设计。 模型给出的是概率,但 Agent 需要的是策略: 「我现在可以直接执行吗?还是必须找人确认?」
原始概率无法直接回答这个问题——两个策略 0.79 / 0.78 时,最高分看起来很高,但它不是一个决策。
因此每次调用都会额外返回一个 contract 块,把概率翻译成 4 种 grade,Agent 直接分支即可:
| 含义 | Agent 应该做什么 |
✅ | 置信度越过阈值,且与次优有明显差距 | 直接执行,不要再花 token 重新推理 |
⚠️ | 高置信但存在近距平局,或问题本身语义上就该由人拍板 | 不要仅凭模型答案行动,走完整 LLM 分析或请人确认 |
🛑 | 低置信 + 高风险场景 | 必须转人工 |
🔁 | 低置信 + 低风险 | 可以重试:换更精确的 criteria、增加候选、或交给 LLM |
grade 由三个信号共同决定(而不是单一置信度)
信号 | 作用 | 为什么单独看它不行 |
| 校准后的置信度 | 候选数量多时 softmax 会被抬高,必须用 Laya 的温度校准值 |
| top1 − top2 | 0.79 / 0.78 的两条相邻策略,不管最高分多高都不构成决策 |
| 模型自带的「需人工复核」头 | 对语义上就要求人拍板的问题,高置信也依然是 escalate |
契约结构示例
{
"grade": "auto_execute",
"autonomous": true,
"requires_human": false,
"threshold": 0.8,
"margin_threshold": 0.05,
"decisions": {
"selected_strategy": {
"value": "redis_cache",
"confidence": 0.9231,
"margin": 0.41,
"grade": "auto_execute",
"reason": "confidence 0.92 clears 0.80 and beats the runner-up by 0.41",
"requires_human": false
}
},
"grade_counts": { "auto_execute": 1, "escalate": 0, "ask_human": 0, "reconsider": 0 },
"reasons": [],
"summary": "all 1 answers clear the auto-execute bar; proceed",
"routing": { "model": "english", "reason": "English Latin text" }
}聚合规则:一个被卡住的问题会卡住整个请求。 整体
grade取所有问题中最「保守」的那个 (优先级ask_human>escalate>reconsider>auto_execute), 因为对 Agent 而言「部分可执行」比「整体不可执行」更危险。
Agent 典型分支伪代码
result = mcp.call("decide", state=diff, preset="code_change_risk")
grade = result["contract"]["grade"]
if grade == "auto_execute":
merge_pull_request() # 直接干,零推理成本
elif grade == "escalate":
run_full_llm_review(diff) # 花 token 深挖
elif grade == "ask_human":
notify_reviewer(result["contract"]["reasons"])
else: # reconsider
result = mcp.call("decide", state=diff, preset="code_change_risk",
threshold="critical") # 换阈值 / 换问题重试为什么值得用
大幅降低 Agent 决策成本:把「要不要做 / 走哪条路」交给 System-1 模型,避免为此唤起完整 LLM 的 CoT。
不引入幻觉风险:非生成式,输出是封闭候选集上的概率,不会「编造」答案。
策略集中在服务端:阈值、margin、风险等级都是配置,不用在每个 Agent 里重复实现。
对 Agent 友好:工具自带详细 description 与
structuredContent,另有laya://guide等资源做知识注入。一套逻辑三种入口:MCP / REST / CLI 共用
laya_mcp.core,不会出现行为漂移。生产可用:健康检查、指标、结构化日志、超时与体积上限、线程安全、优雅降级(模型加载失败时
/healthz返回degraded而非崩溃)。
架构
┌─────────────────────────────┐
MCP Agent ────────► │ /mcp StreamableHTTP │
(Claude Code / │ (9 tools / 4 resources / │
Codex / Cursor) │ 2 prompts) │
├─────────────────────────────┤
脚本 / 看板 ────────► │ /v1/... REST (FastAPI) │
└──────────────┬──────────────┘
│ 共用同一套实现
┌──────────────▼──────────────┐
│ laya_mcp.core │
│ settings / schema / preset │
│ engine(常驻+池+缓存) │
│ contract(决策契约) / metrics │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ laya.Router (System-1) │
│ english / multilingual / │
│ typed-decisions │
└─────────────────────────────┘目录结构
laya-mcp/
├── src/laya_mcp/
│ ├── core/ # 与传输方式无关的领域层
│ │ ├── settings.py # LAYAMCP_* 配置、阈值等级
│ │ ├── schema.py # 公开问题 schema ↔ Laya 原生格式
│ │ ├── presets.py # 5 个内置问题集
│ │ ├── contract.py # ★ 概率 → grade 的决策契约
│ │ ├── engine.py # 单例 Router + 线程池 + LRU 缓存
│ │ ├── errors.py # 统一错误分类与 HTTP 映射
│ │ └── metrics.py # 计数 / 延迟分位
│ ├── api/ # FastAPI 层
│ │ ├── app.py # create_app(),挂载 /mcp 与 /v1
│ │ ├── routes.py # REST 端点(不含决策逻辑)
│ │ ├── schemas.py # 请求 / 响应模型
│ │ └── dependencies.py # DI:engine / settings / metrics
│ ├── mcp_server/ # MCP 层
│ │ ├── server.py # 工具 / 资源 / Prompt 注册
│ │ └── questions.py # 问题解析(inline / preset / 快捷参数)
│ ├── cli.py # 命令行入口
│ └── logging_config.py # 结构化日志
├── examples/quickstart_router.py # 原始 laya-test.py 用法
├── tests/
└── pyproject.toml关键实现说明
模型只加载一次:
DecisionEngine进程级单例。启动时预热(LAYAMCP_WARMUP=true), 之后每次请求都是热态,毫秒级返回。不阻塞事件循环:推理跑在有界线程池里(
LAYAMCP_WORKER_THREADS), torch 内部会释放 GIL,因此 CPU 上并发也有收益。结果缓存:对相同
(state, questions)做进程内 LRU 缓存(默认 256 条), Agent 重试同样的问题几乎零成本;响应中cached=true可辨别。MCP 挂载方式(容易踩坑):不能用
streamable_http_app()再mount到 FastAPI—— Starlette 不会为子应用执行 lifespan,session manager 起不来,/mcp会全部失败。 正确做法是在本应用的 lifespan 里进入 session manager:manager = StreamableHTTPSessionManager(app=server._lowlevel_server, ...) app.mount("/mcp", StreamableHTTPASGIApp(manager)) # lifespan: async with manager.run(): yield参见
src/laya_mcp/api/app.py的模块注释。MCP SDK 版本:基于 mcp 2.x(
from mcp.server.mcpserver import MCPServer)。 与 1.x 的mcp.server.fastmcp.FastMCP不兼容,升级时注意导入路径变化。
快速开始
环境要求
Python 3.13+
uv(推荐)
磁盘约 3 GB(三个 checkpoint 合计约 2.2 GB)
CPU 即可运行;有 CUDA / Apple MPS 会自动加速
首次运行需要联网从 HuggingFace 下载权重,之后可完全离线
安装
git clone <your-repo-url> laya-mcp
cd laya-mcp
uv sync # 创建 .venv 并安装依赖自检
uv run laya-mcp doctor输出示例:
laya-mcp 0.2.0
python: 3.13.x
settings: models=['english', 'multilingual'] device=auto port=8077
laya: 0.3.5 -> .../laya/__init__.py
torch: 2.x.x cuda=False
HF 缓存: 2.20 GB,包含 laya 检查点: True
fastapi: ok
uvicorn: ok
mcp: ok
pydantic_settings: ok
结论: 环境可用启动服务
uv run laya-mcp serveINFO laya_mcp.engine loading laya router models=['english','multilingual'] device=cpu
INFO laya_mcp.engine laya router ready loaded=['english','multilingual']
INFO laya_mcp.api engine ready in 67.8s
INFO mcp.server... StreamableHTTP session manager started
Uvicorn running on http://127.0.0.1:8077OpenAPI 文档:http://127.0.0.1:8077/docs
MCP 端点:
http://127.0.0.1:8077/mcp
⏳ 首次启动约 60~90 秒(在 CPU 上加载两个 checkpoint)。之后所有请求都是热态, 单次决策通常 10~50ms。
第一条请求
curl -s http://127.0.0.1:8077/v1/decide \
-H 'content-type: application/json' \
-d '{
"state": "Fix a typo in README, one file, no interface change",
"preset": "code_change_risk"
}' | python -m json.tool或者完全不启服务,直接一次性决策:
uv run laya-mcp ask \
--state "Fix a typo in README, one file, no interface change" \
--preset code_change_risk接入 MCP Agent
服务启动后,任何支持 MCP 的客户端都可以直接接入。关键信息只有一条:
MCP Streamable HTTP 端点:http://127.0.0.1:8077/mcpClaude Code
claude mcp add --transport http laya http://127.0.0.1:8077/mcpCodex / Cursor / 通用 mcp.json
{
"mcpServers": {
"laya": {
"type": "streamable-http",
"url": "http://127.0.0.1:8077/mcp"
}
}
}只给单个 Agent 用(stdio,无 HTTP)
不想起 HTTP 服务时,可以用 stdio 传输,由客户端自己拉起进程:
{
"mcpServers": {
"laya": {
"command": "uv",
"args": ["run", "--directory", "/abs/path/to/laya-mcp", "laya-mcp", "serve", "--transport", "stdio"]
}
}
}stdio 模式下进程由客户端按需拉起,建议启动后先让 Agent 调一次
preload_warmup, 否则第一次决策会等待模型加载。HTTP 模式则无需关心——服务启动时已预热。
让 Agent「自动决策」的推荐接入方式
在系统提示里注入用法。服务已经在 MCP
instructions里写了使用指南, 另外可以让 Agent 读取laya://guide资源获取完整的问题编写规范。强制 Agent 先查契约。约定:任何有副作用的动作前,先调用
decide/should_escalate, 并只在contract.grade == "auto_execute"时直接执行。按风险等级传
threshold。删库、发钱、改线上配置这类动作,传"high"或"critical"。用
preset起步,再按需内联问题。preset 与内联questions会合并到同一次前向传播, 边际成本几乎为零。
MCP 工具参考
共 9 个工具,全部返回结构化结果(文本 + structuredContent 字段同名)。
工具 | 用途 | 是否加载模型 | 典型耗时 |
| 主力工具:对 | 是 | 10~50ms |
| 最省成本:单个是非问题 + 契约 | 是 | ~10ms |
| 候选标签极多(几十~上百)时,先 embedding 粗筛 top-k 再决策 | 是 | 20~80ms |
| 只做路由:判断语言 / 脚本 / 工作流,返回该用哪个 checkpoint 及原因 | 否 | <1ms |
| 列出全部内置问题集及其 question id | 否 | <1ms |
| 回显并校验一组问题(id、kind、候选、等级),不推理 | 否 | <1ms |
| 一站式:给定动作,直接回答「是否需要人工介入」 | 是 | 10~50ms |
| 就绪状态、已加载 checkpoint、缓存条数、延迟分位 | 否 | <1ms |
| 强制加载 checkpoint(仅 stdio 或关闭预热时需要) | 是(慢) | 30~90s |
调用顺序建议(先便宜后昂贵)
route_request < list_presets / describe_questions < decide_yes_no < decide < decide_shortlist
(<1ms) (<1ms) (~10ms) (10~50ms) (20~80ms)decide 参数速查
参数 | 类型 | 说明 |
| string | object | array | 必填。模型真正读到的上下文:代码 / diff / 工单 / trace / 工具返回值。放原始材料,不要放摘要,摘要会掉准确率 |
| object | array | 内联问题集,见 Question Schema |
| string | 内置问题集名;可与 |
| number | string |
|
| string | 强制 checkpoint: |
| string | 提示 |
| string | 强制使用 |
| bool | 是否复用相同请求的缓存结果,默认 |
返回值结构
{
"contract": { /* 见上文「决策契约」 */ },
"grade": "auto_execute", // 整体 grade,Agent 只需看这个
"autonomous": true, // 是否可完全自主执行
"requires_human": false,
"summary": "all 5 answers clear the auto-execute bar; proceed",
"answers": {
"blast_radius": {
"kind": "choice",
"value": "single_file",
"confidence": 0.9642,
"margin": 0.8713,
"grade": "auto_execute",
"reason": "confidence 0.96 clears 0.80 and beats the runner-up by 0.87",
"requires_human": false,
"probabilities": { "single_file": 0.9642, "module": 0.0929, "...": 0.0 },
"raw": { /* Laya 原始返回,未加工 */ }
}
},
"routing": { "model": "english", "reason": "English Latin text", "repo": "convaiinnovations/laya" },
"latency_ms": 31.4,
"cached": false,
"usage": {}
}Resources 与 Prompts
除了工具,服务还暴露 MCP Resources(可被 Agent 当知识库读取)与 Prompts(可复用模板)。
Resources
URI | 内容 |
| 问题编写指南、kind 说明、grade 语义(强烈建议 Agent 读取) |
|
|
| 全部内置问题集(JSON) |
| 实时就绪状态与延迟,等同 |
Prompts
名称 | 用途 |
| 把「打算执行的动作」转成一组问题集的填空模板 |
| 对一条用户消息做分诊(意图 / 紧急度 / 情绪 / 流失风险) |
内置问题集(Preset)
Preset 是问题的骨架,不是答案。它们覆盖了 Agent 最常遇到的五类场景:
名称 | 问题数 | 适用场景 | 包含的 question id |
| 5 | 代码改动 前置风险评审:爆炸半径、可回滚性、数据影响、测试覆盖、是否需人工 |
|
| 4 | 客服工单分诊:意图、紧急度、情绪、流失风险 |
|
| 5 | 不可信输入的护栏:越狱、提示注入、敏感数据、危害程度、话题 |
|
| 4 | 模型/算力路由:难度、领域、是否需要工具、敏感性 |
|
| 5 | Agent trace 可观测性(与 |
|
# 查看全部 preset
uv run laya-mcp presets
# 查看单个 preset 的完整问题定义
curl -s http://127.0.0.1:8077/v1/presets/code_change_risk | python -m json.toolpreset + 自定义问题可以合并,一次前向传播全部回答:
{
"state": "<diff 或工单>",
"preset": "code_change_risk",
"questions": {
"target_release": {
"kind": "choice",
"instructions": "这个改动更适合进哪个版本?",
"criteria": {
"hotfix": "紧急修复,必须立刻发",
"next_minor": "下个小版本即可",
"backlog": "不急,排入待办"
}
}
}
}问题(Question)Schema
Laya 原生词汇是 choice / score / noul(且使用 t / ins / crit 短键)。
本工程定义了一套稳定、自描述的公开 schema,调用方不需要了解底层格式:
{
"question_id": {
"kind": "choice", // choice | score | yes_no
"instructions": "选哪个方案?", // 给模型的指令
"criteria": { // 见下方「三种 kind」
"redis_cache": "适合读多写少、容忍秒级延迟",
"db_index": "适合查询条件固定、数据量中等"
},
"weight": 1.0, // 可选,建议性权重
"description": "..." // 可选,仅在罗列时展示
}
}三种 kind
| 对应 Laya 类型 |
| 说明 |
|
|
| N 选 1。每个候选的适用条件要写具体、可区分 |
|
|
| 有序等级列表,返回等级下标 |
|
|
| 是非问题。陈述句要正向表述(true 表示「可以继续」) |
编写要点(直接影响准确率)
一个问题只问一件事。不要问「这个改动安全吗」,而是拆成爆炸半径 / 可回滚 / 数据影响。
候选之间必须互斥且穷尽。留一个
other兜底往往比硬选更好。criteria 写判定条件,不写形容词。✅「涉及共享 schema,会被其他团队消费」 ❌「影响很大」。
state放原始材料,代码、diff、完整工单原文,不要放你自己的总结。问题数量 2~6 个最佳(上限由
LAYAMCP_MAX_QUESTIONS控制,默认 32), 每个问题的边际成本极低——多问一个几乎不增加耗时。不要用 Laya 做生成任务。它只做分类/打分,不是写作模型。
校验问题集
写好后先让服务回显校验,避免把无效问题发到模型:
curl -s http://127.0.0.1:8077/v1/questions/describe \
-H 'content-type: application/json' \
-d '{"preset": "input_guard"}' | python -m json.toolREST API
Base path:/v1。完整交互式文档见 /docs。
决策
方法 | 路径 | 说明 |
|
| 回答一组带类型的问题(等同 MCP |
|
| 单个是非问题 |
|
| 大规模候选:embedding 粗筛 + 决策 |
|
| 只做路由,不推理(微秒级) |
目录 / 运维
方法 | 路径 | 说明 |
|
| 全部内置问题集(含问题定义) |
|
| 单个问题集(规范化后的最终形态) |
|
| 校验并回显一组问题 |
|
| 可用 checkpoint 及加载状态 |
|
| 存活检查(模型加载失败返回 200 + |
|
| 引擎状态、阈值、缓存、延迟分位 |
|
| 原始计数与延迟数据(供 Prometheus 等抓取) |
|
| 服务版本与 laya 版本 |
示例
# 1) 是非问题:这个动作能直接执行吗?
curl -s http://127.0.0.1:8077/v1/decide/yes-no \
-H 'content-type: application/json' \
-d '{
"state": {"action": "DROP TABLE users", "env": "production"},
"statement": "this action is safe to run without human review",
"threshold": "critical"
}' | python -m json.tool
# 2) 中文工单分诊(自动路由到 multilingual checkpoint)
curl -s http://127.0.0.1:8077/v1/decide \
-H 'content-type: application/json' \
-d '{"state": "客户反馈发票被重复扣款,语气很急", "preset": "support_triage"}' \
| python -m json.tool
# 3) 只路由,不推理
curl -s http://127.0.0.1:8077/v1/route \
-H 'content-type: application/json' \
-d '{"state": "给我翻译一下这段中文"}' | python -m json.tool
# {"model":"multilingual","reason":"non-Latin script (han, 100% of letters); ..."}统一错误格式
所有错误都是同一形状,并带 request_id 便于排查:
{
"error": "invalid_question",
"message": "at most 32 questions per call",
"details": { "count": 40, "limit": 32 },
"request_id": "0f3a9c1b2d4e5f60"
}命令行 CLI
uv run laya-mcp --help命令 | 说明 |
| 启动服务(默认 FastAPI + MCP Streamable HTTP) |
| 仅提供 MCP,走标准输入输出,适合本地 Agent |
| 一次性决策,不启服务(等价于 |
| 列出内置问题集 |
| 列出 MCP 工具(不加载模型) |
| 检查环境、依赖与 checkpoint 缓存 |
serve 常用参数
uv run laya-mcp serve \
--host 0.0.0.0 \
--port 8077 \
--models english,multilingual,typed-decisions \
--device auto \
--log-level INFO参数 | 说明 |
|
|
| 监听地址与端口(默认 |
| 常驻 checkpoint,逗号分隔,或 |
|
|
| 开发热重载(仅 HTTP) |
| 启动时不加载模型(首次请求会变慢) |
ask 示例
# N 选 1(--choices 是快捷写法)
uv run laya-mcp ask \
--state "高并发下数据库查询变慢,Query 全表扫描,QPS 5000/s" \
--instructions "根据性能瓶颈选择最合适的优化方案" \
--choices "redis_cache,db_index,read_write_split,search_engine"
# 读取文件作为 state(@ 前缀)
uv run laya-mcp ask --state @./diff.patch --preset code_change_risk
# 输出完整 JSON(含契约)
uv run laya-mcp ask --state "..." --preset input_guard --json
# 是非问题
uv run laya-mcp ask --state "<发布计划>" \
--statement "this can ship without human approval"ask 的可读输出示例:
5/5 answers fail the auto-execute bar (...): ask a human before acting
blast_radius: single_file (choice, confidence 0.64, margin 0.82, ask_human)
needs_human_review: True (yes_no, confidence 0.60, margin 0.21, ask_human)
checkpoint: english - English Latin text配置项(环境变量)
所有配置项前缀为 LAYAMCP_,也可写在项目根目录的 .env 里
(见 .env.example)。
服务
变量 | 默认值 | 说明 |
|
| 监听地址 |
|
| 监听端口 |
|
|
|
|
| MCP 挂载路径 |
|
| REST 前缀 |
|
| 是否开启 |
推理
变量 | 默认值 | 说明 |
|
| 常驻 checkpoint,逗号分隔或 |
|
|
|
|
| 默认 checkpoint |
|
| 自动识别语言/脚本/工作流并路由 |
|
| 启动时预热加载模型 |
|
| 推理线程池大小(负载高时调大) |
| 无 | 私有镜像或受限下载时使用 |
策略(决策契约的阈值)
变量 | 默认值 | 说明 |
|
| 达到此置信度才可能判为 |
|
| top1−top2 低于此值视为「近距平局」→ |
|
|
|
|
| 单次调用最大问题数 |
|
| 单个 choice 问题最大候选数 |
日志与指标
变量 | 默认值 | 说明 |
|
|
|
|
| 结构化 JSON 日志(接入 ELK / Loki 时保留) |
|
| 是否采集指标 |
|
| 请求 id 头名称 |
置信度等级
threshold 参数/配置支持用名字代替数字,便于按风险分级:
等级 | 数值 | 建议场景 |
| 0.60 | 无副作用的分类、打标签 |
| 0.70 | 内部草稿、低风险建议 |
| 0.80(默认) | 常规 Agent 决策 |
| 0.90 | 生产变更、影响用户的操作 |
| 0.95 | 删数据、动钱、安全相关 |
Docker 部署
# 参考 Dockerfile
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
WORKDIR /app
ENV UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
LAYAMCP_HOST=0.0.0.0 \
LAYAMCP_PORT=8077 \
HF_HOME=/models
COPY pyproject.toml uv.lock README.md ./
RUN uv sync --frozen --no-dev --no-install-project
COPY src ./src
RUN uv sync --frozen --no-dev
EXPOSE 8077
CMD ["uv", "run", "--no-dev", "laya-mcp", "serve"]docker build -t laya-mcp .
docker run --rm -p 8077:8077 -v laya-models:/models \
-e LAYAMCP_MODELS=english,multilingual \
laya-mcp建议把
/models挂成 volume:首次下载约 2.2 GB,重建镜像不必重下。 生产环境请在服务前置反向代理并加鉴权——MCP 端点本身无内建认证。
开发与测试
uv sync
uv run laya-mcp doctor # 环境自检
uv run laya-mcp tools # 列出工具(不加载模型,适合快速验证)
uv run pytest -q # 运行测试不加载模型做冒烟测试
# 仅启动 app,不预热(秒级返回)
LAYAMCP_WARMUP=false uv run python -c "
from fastapi.testclient import TestClient
from laya_mcp.api.app import create_app
with TestClient(create_app()) as c:
print(c.get('/').json())
print(c.get('/v1/healthz').json())
"扩展新工具
在
src/laya_mcp/core/里实现与传输无关的逻辑。在
src/laya_mcp/mcp_server/server.py里注册@server.tool(...),返回 Pydantic 模型。若要暴露 REST,在
src/laya_mcp/api/routes.py加端点,复用同一函数,不要重写逻辑。补充
laya://guide里的说明,让 Agent 知道何时该用这个新工具。
常见问题 FAQ
正常。CPU 上加载 english + multilingual 两个 checkpoint 约需 6090 秒。
这是一次性成本——服务预热后单次决策仅 1050ms。
临时验证接口、不想等加载:--no-warmup(或 LAYAMCP_WARMUP=false),
此时首次决策会变慢。只验证工具列表可用 uv run laya-mcp tools(完全不加载模型)。
检查 routing.model 是否为 multilingual。Laya 的 english checkpoint 是
ModernBERT-large(512 token,只懂英文),中文会被自动路由到 multilingual(mmBERT-base,1024 token)。
若自动路由不符合预期,可显式指定:model="multilingual" 或 lang="zh"。
注意 multilingual 上下文更长(1024)但推理略慢,纯英文场景用 english 更快更准。
Laya 返回的是校准后的置信度,但候选数量多时原始 softmax 仍会被抬高,
contract.py 里的 confidence_from_probs 已经做了校正。
另外注意启动时的告警:
laya: this checkpoint ships temperatures outside [0.5, 5] ... Treat confidence
from the affected buckets as uncalibrated.命中这类 bucket 时,不要只看 confidence,务必参考 margin 与整体 grade——
这正是契约存在的意义。
两个常见原因:
挂载方式错误。不能用
streamable_http_app()再mount到 FastAPI(子应用 lifespan 不会执行, session manager 起不来)。请直接用create_app()。客户端连接方式不对。MCP 是有状态的 Streamable HTTP,客户端要用
streamable-http传输类型 指向http://<host>:<port>/mcp;用 SSE 或旧版 HTTP 传输连不上。
若前置了反向代理,请确保允许流式响应(关闭 buffering、开启 chunked、放行 mcp-session-id 头)。
可以。权重下载一次后会缓存在 HF_HOME(默认 ~/.cache/huggingface)。
用 uv run laya-mcp doctor 确认 包含 laya 检查点: True,之后设置 HF_HUB_OFFLINE=1 即可离线。
不会。模型是进程级单例,推理跑在有界线程池里,相同请求命中 LRU 缓存。 横向扩展只需多起几个进程/容器(每个进程会各自加载模型,注意 CPU/显存与内存占用)。
场景 | 用 Laya | 用 LLM |
「走哪条路 / 是不是 X / 严重程度几级」 | ✅ | ❌ 太贵太慢 |
需要生成文本、写代码、长链推理 | ❌ | ✅ |
高频、对延迟敏感(<100ms) | ✅ | ❌ |
候选集封闭、要求可复现 | ✅ | ⚠️ 不稳定 |
实践上两者是互补关系:用 Laya 做前置判断与分流,只在 grade != auto_execute 时才唤起 LLM。
直接把 questions 内联传给 decide 即可,无需改代码:
{
"state": "...",
"questions": {
"priority": {
"kind": "choice",
"instructions": "这条需求应该排什么优先级?",
"criteria": {
"p0": "线上故障,立刻处理",
"p1": "本周内必须完成",
"p2": "可以排入下个迭代"
}
}
}
}需要长期复用时,在 src/laya_mcp/core/presets.py 的 PRESETS 中注册一个新条目。
GET /v1/healthz— 存活(模型失败也返回 200,status=degraded)GET /v1/status— 就绪、已加载 checkpoint、缓存、延迟分位GET /v1/metrics— 原始计数与延迟,可直接被抓取所有响应带
x-request-id与x-response-time-ms头
参考
许可证
见仓库根目录 LICENSE。使用 Laya 权重时请同时遵守其 HuggingFace 页面上的许可条款。
This server cannot be deployed
Maintenance
Related MCP Connectors
Decision Layer for AI Agents — 58+ tools, Advisor, MCP. Free key: POST /v1/register {}.
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAgent-to-agent reasoning-as-a-service providing structured reasoning, data analysis, decision support, and code/document review via REST API and MCP protocol.MIT
- AlicenseNot gradedqualityBmaintenanceEnables coding agents to make confident decisions using calibrated probabilistic tools for screening, verification, ranking, classification, and gating, fully self-hosted as an optional MCP server.686 npm1MIT

Jev MCPofficial
AlicenseNot gradedqualityAmaintenanceProvides MCP clients with typed, probabilistic decisions (choices, probabilities, scores) from TypeSafe's System One model, offering validated outputs and flexible provider support.2Apache 2.0- AlicenseNot gradedqualityAmaintenanceProvides an MCP interface to the Laya decision model, enabling typed queries (yes/no, multiple choice, score) with preflight token-budget reporting, honest confidence calibration, and structured error handling.Apache 2.0