做 AI Agent 的工程化做了快一年,我最直观的感受是:LLM、Tools、MCP、Skills 这四个词,单独拎出来每一个都不难理解,但当它们同时出现在一个真实项目里的时候,事情就开始失控了。模型要接好几个厂商的接口,工具是散落在代码里的几十个函数,MCP server 今天加一个明天挂一个,Skills 更是从各个 GitHub 仓库里捡回来的压缩包。每个东西都有自己的接入方式、鉴权方式和版本节奏,最后所有逻辑全堆在 Agent 主进程里,改一处就要全家桶回归。
所以我特别能理解 tsm-hub 这个项目想干什么——把 LLM、Tools、MCP、Skills 收进一个统一网关,让上层应用只关心"我要什么能力",不关心"能力到底在哪里、怎么调"。这篇文章我就从架构设计、模块拆解、落地配置、踩坑记录四个方面,把这类统一网关的完整方案盘一遍。文章面向正在做 Agent 平台、内部 AI 中台,或者单纯想把个人开发环境规整干净的朋友;如果你现在还分不清 MCP 和 Skill 的差异,我会在正文里把它讲透。
1. 为什么需要 tsm-hub:AI 应用开发正在被碎片化拖垮
1.1 三个真实的现场问题
先说说我在多个项目里反复遇到的三个问题,它们几乎是所有 Agent 工程化团队的共同痛点。
第一个是模型渠道割裂。同一个业务场景里,可能要同时用 OpenAI 的聊天模型、某家的 Embedding 模型、一个开源本地模型的推理服务,还要给不同 client 准备 fallback 链路。这些模型的请求格式、鉴权方式、限流策略各不相同,有些人为了省事,直接在代码里写死厂商 SDK,结果换一个模型供应商,就要改一遍核心调用代码。
第二个是工具定义散乱。支持 function calling 的框架越来越多,但每个工具都要单独维护一份 JSON Schema,工具之间的共享依赖、权限边界、调用频控、审计日志全都要自己设计。一开始只有三五个工具还好,工具超过二十个以后,光是保证每个工具的 description 和参数说明准确、不会被模型误导,就已经是一件很费精力的事情了。
第三个是 MCP 生态快速膨胀。MCP server 的数量这两年的增长幅度很大,但它们之间的传输方式、能力声明方式、启动方式差异实在太多。有的是 stdio 子进程,有的是 streamable HTTP,有的是 WebSocket。每个 server 的初始化握手、健康检查、崩溃重连、版本升级,都变成了 Agent 框架本身的负担。我真见过有人在生产环境里用一个脚本去管理十几个 MCP server,脚本里全是 sleep 和 grep 日志的 hack。
Skills 的问题更隐蔽。社区里流行的 Skill 本质上是一个"提示词模板 + 若干脚本 + 静态资源"的目录,没有统一安装机制,没有依赖管理,也没有版本声明。今天从仓库 A 复制一个 skill 进来,明天从仓库 B 复制另一个,两个 skill 里可能引用了同一个 Python 包的不同版本,过两周就忘了当初装过什么。时间一长,skill 目录就变成了无人敢动的沼泽。
1.2 网关模式的本质
要解决上面这些问题,直觉上会想到"把东西全塞到一个进程里统一处理"。但真这么做会发现,Agent 进程会变得越来越臃肿,而且换一个语言栈就得重新实现一遍。tsm-hub 的做法是典型的网关模式:用一个独立服务,在能力提供方和调用方之间做一层横向打通。
严格来说,tsm-hub 做的事情是把四类资源抽象成四种可管理对象。LLM 被抽象成可路由的模型资源,Tools 被抽象成带标准函数签名的可注册能力,MCP Server 被抽象成外部工具服务的连接代理,Skills 被抽象成可组合的技能包。上层 Agent 不再直接面对各家的 SDK 和协议,而是面对一套统一 API、一份配置文件和一套鉴权体系。
这样做最大的变化是:控制面和数据面分离了。模型接入、工具注册、MCP 连接、Skill 版本管理这些属于控制面操作;请求转发、上下文注入、工具调用、结果返回这些属于数据面操作。两件事分开以后,加一个新模型或者挂一个新 MCP server,就不再需要动 Agent 核心代码。
1.3 一套配置搞定所有能力
统一网关带来的直接收益是配置化的能力管理。比如我需要给我的 agent 增加一个浏览器自动化能力,传统做法是在代码里集成 Playwright,再手写浏览器控制函数,还要处理浏览器实例的生命周期。而在 tsm-hub 这种网关里,只需要注册一个 Playwright MCP server,然后在 skills 配置里允许某个技能使用它,剩下的工作就是写一条配置。
我在自己环境里落地这类方案时,最明显的感觉就是"加法变得安全了"。之前加一个工具,要担心会不会影响已有工具的 function calling 表现;现在每个工具的 Schema、可见性和调用通道都是独立管理的,新的能力进来,默认不开放给任何 agent,需要显式授权才会被上层看到。这种默认收敛的设计,帮我挡掉了很多潜在故障。
2. 整体架构拆解:网关模式背后的设计逻辑
2.1 TSM 的含义:控制面与数据面的分离
项目名里的 TSM,我理解为 Tool-Skill-Model 的缩写,也有人解释为 Tools、Skills、MCP 的统一管理。无论哪种理解,核心都是把"能力组织"这件事从应用层抽离出来。
整个架构最关键的是控制面和数据面的分离设计。控制面负责配置、注册、鉴权、版本管理;数据面负责实际的调用转发。我在设计这类系统时,习惯把配置存储在独立的配置中心或者一个 YAML 文件里,运行时只保存一份已加载的内存态。这样改配置不需要重启 Agent,只需要触发一次 reload。
数据面的转发链路是:请求进入网关 -> 鉴权与路由 -> 能力调度 -> 结果聚合 -> 返回。这里有个容易被忽略的细节:LLM 调用往往不是一次就结束的,Agent 会多次在模型和工具之间往返。所以网关的数据面必须支持会话级别的上下文保持,不能简单地把每次请求当成独立的 HTTP 调用。
2.2 统一抽象层:四种资源如何被归一化
为了让上层 Agent 能够用一致的方式处理四种资源,需要定义一套统一的资源描述规范。我给一个具体例子,这套规范我在实际项目里验证过,可以覆盖大多数场景:
每种资源都拥有全局唯一的 ID 和版本号,比如model:gpt-4o-mini:20250101或者skill:web-research:v3。每个资源都有一个元信息描述,包括名称、用途、依赖关系、权限标签。Tool 和 MCP Server 都向外暴露一组 OpenAI function calling 风格的 JSON Schema;Skill 编译后产生提示词片段和可见工具白名单;Model 则标记自己的能力位,比如是否支持聊天、是否支持 Embedding、是否支持视觉。
有了这层归一化,上层 Agent 看到的是一棵能力树,而不是一堆散落的接口。能力树的好处是可以做细粒度的授权。比如我可以让"数据分析"技能只能访问数据库查询工具和代码执行工具,让"网页研究"技能只能访问搜索工具和浏览器 MCP。这比在 Agent 代码里写一堆 if else 判断要干净得多。
2.3 三个关键设计取舍
这类统一网关在技术选型上,有几个绕不开的取舍。我逐个讲讲我的理解。
第一个取舍是"网关模式 vs SDK 模式"。很多人倾向于发一个 Python SDK,让各业务线直接调用。但 SDK 方案天然排斥非 Python 技术栈,而且工具注册、权限策略这些逻辑散落在各个服务的依赖里,很难统一升级。网关模式牺牲了一点性能(额外一跳的延迟),换来了跨语言复用和集中治理。我自己的经验是,一次内部 HTTP 调用在局域网里的延迟只有 1-3 毫秒,对于 AI 应用动辄数秒的模型推理时间来说,完全可以忽略。
第二个取舍是"能力 ID + 权限标签"。为什么不能让 Agent 直接用工具名去调用?因为在多团队场景里,工具名会有歧义。一个叫search的工具,在不同业务线下含义完全不同。所以我在设计里强制要求所有能力都有命名空间和版本号,比如mcp__playwright__browser_goto。权限标签则用于后续做策略引擎,比如"只读工具"和"写操作工具"的管控力度应该不同。
第三个取舍是"MCP 和原生 Tool 并存"。MCP 生态丰富,但网络链路更长,stdio 子进程还会增加进程管理复杂度。本地高频调用如果走 MCP 反而慢,而且不好调试。所以我把工具执行层设计成两种模式:本地进程内函数模式,和远程 MCP server 代理模式。两种模式对外暴露的都是同一套函数 Schema,Agent 不需要感受到差异。这个并存设计让系统的适用范围宽了很多。
3. 核心模块深度解析与实操要点
3.1 LLM 网关:模型路由、fallback 与统一接入格式
LLM 网关是整个 hub 里最"基础"的模块,因为它承载的是所有 Agent 的对话和补全请求。我把它拆成三部分:统一出口、模型抽象、路由策略。
统一出口很好理解,对外只暴露一个 OpenAI 兼容的/v1/chat/completions接口。这样上层任何支持 OpenAI SDK 的框架都能直接接入,我的 Django 服务、FastAPI 服务、命令行工具都不用改代码。在网关内部,再针对不同模型厂商的原始 API 做适配,把请求格式转换成各家需要的样子。
模型抽象层的任务是把"模型实例"变成"具有路由标签的资源"。我平时会在配置里给每个模型标上能力标签和成本档位,例如:
models: - name: gpt-4o-mini provider: openai-compatible base_url: https://api.example.com/v1 api_key_env: LLM_API_KEY tags: [chat, fast] cost_level: low - name: gpt-4o provider: openai-compatible base_url: https://api.example.com/v1 api_key_env: LLM_API_KEY tags: [chat, reasoning] cost_level: high路由策略是 LLM 网关里最有价值的部分。我常用三种策略:按成本路由、按能力路由、按兜底链路由。按成本路由就是默认使用cost_level: low的模型,当收到特定指令或者检测到任务复杂度偏高时,升级到reasoning模型;按能力路由则是根据请求里是否带图片、是否要求工具调用等信号分发到不同模型。兜底链是给每个路由目标配一条 fallback 列表,主模型返回 5xx 或者限流错误时,自动按顺序尝试下一个模型。
这里有个容易踩的坑:fallback 链设置不当会烧钱。我之前做过一个配置,把昂贵的强推理模型放在兜底链最后,结果因为主模型频繁超时,大量请求真被转到了贵模型上,月底账单直接翻倍。合理的做法是给 fallback 设置概率阈值和次数上限,并单独计量"被 fallback 消费的 token 数"。
3.2 Tools 标准化:从"临时函数"到"企业级资产"
Agent 里的 function calling 之所以难维护,是因为大家一开始都把工具当普通函数写,没人做登记和版本管理。tsm-hub 把 Tools 提升到了"资产管理"级别。
每个工具在网关里都对应一条注册记录,字段大致包括:全局唯一名称、用途描述、JSON Schema 参数定义、执行目标(本地函数还是远端 HTTP)、权限标签、调用频控限制、审计开关。注册完以后,工具不会自动对 Agent 可见,需要绑定到具体的 Skill 或显式授权给某个应用。
我在实际项目中强烈建议:工具的 description 要写得像"写给一个聪明的陌生人看",而不是写给同事看。因为模型通过 description 决定何时调用工具,描述太含糊,模型就会在不该调用的时候调用;描述太冗长,又浪费上下文 token。标准的做法是先用一两句话说明工具做什么,然后说明典型使用条件,必要时给出一个反例。比如:
{ "type": "function", "function": { "name": "search_web", "description": "搜索互联网并返回网页摘要。适用于需要外部实时信息的问题,不适用于用户已提供完整资料的情况。", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "搜索关键词" }, "max_results": { "type": "integer", "default": 5 } }, "required": ["query"] } } }工具标准化还有一个隐形收益:可以给工具做自动化测试。以前 agent 里的函数散在各种业务模块,想单独跑工具测试要 mock 一堆上下文;现在工具是独立注册的,每个工具都能在测试环境里单独调用,传入固定参数、断言输出格式,回归成本大幅下降。
3.3 MCP 接入:统一协议下的 server 生命周期管理
MCP(Model Context Protocol)本质上是一套基于 JSON-RPC 2.0 的协议,核心就三段调用:initialize完成握手,tools/list获取工具列表,tools/call执行工具调用。tsm-hub 在其中的角色,是当 MCP client 去连接外部 server。
我见过很多人在接入 MCP 时,只图"连上能用",完全不管生命周期,结果 server 进程崩了没人拉起,网络断了没有重连。在网关里我们至少要对 MCP server 做四件事:连接配置、健康检查、重连策略、能力校验。
一个典型的 MCP server 配置长这样:
mcp_servers: playwright: transport: streamable-http url: http://127.0.0.1:8931/mcp healthcheck: interval_sec: 30 timeout_sec: 5 capabilities: tools: true resources: false blender: transport: stdio command: npx args: ["-y", "@modelcontextprotocol/server-blender"]配置里值得注意的一点是capabilities字段。MCP 协议允许 server 声明自己支持 tools、resources、prompts 等能力。如果某个 server 只声明了 resources 没有声明 tools,但我们的 agent 却尝试调用它的工具,就会收到空列表。这类问题排查起来很费劲,所以我习惯在注册阶段就做一次主动握手:网关起来时逐个调用tools/list,把返回的工具名缓存下来,并且在健康检查报告里打印每个 server 的工具数量。数量异常的 server 一眼就能看到。
MCP 接入还有一个容易忽略的细节:工具名冲突。不同 MCP server 可能都暴露一个叫execute或run的工具,如果直接暴露给 agent,模型很容易选错。我的做法是统一加前缀,比如playwright__browser_goto、blender__mesh_create。这个前缀规则在网关内部强制实现,Agent 感知到的永远是重命名后的完整名称,不会再撞车。
3.4 Skills 管理:把提示词、脚本与资源打包成可复用技能
Skill 这个概念来自 Claude 生态,但现在已经成了 Agent 工程的通用概念。一个 Skill 的本质,是把完成某类任务所需的指令、参考脚本、资源模板、依赖说明打包成一个自包含的单元。搞过前端开发的朋友会发现,它特别像一个带 README 和 template 的 npm 包。
我在 tsm-hub 里,Skill 的标准目录结构是:
skills/ web-research/ SKILL.md scripts/fetch.py requirements.txt assets/templates/report.md.j2SKILL.md 是一个带 YAML frontmatter 的 Markdown 文件,里面写清技能名称、版本、用途描述、使用步骤、典型输出格式。网关在加载 Skill 时,会把 SKILL.md 里的指令编译成一段系统提示词,同时读取 Skill 声明需要的工具白名单和 MCP server 列表,把这些工具的 Schema 一起注入到上下文里。
Skill 版本管理是我踩过坑之后才补上的。早期我允许直接覆盖同名 Skill 目录,结果某次升级 web-research 技能后,同一套代码里的解析脚本行为变了,所有 report 都少了一节。后来我把 Skill 也纳入了版本策略:每个注册的 Skill 必须带语义化版本号,Agent 调用时明确指定skill=web-research@v3,网关才能把对应版本内容注入。
还有一个技巧分享给经常写 Skill 的人:不要在 SKILL.md 里写太长的工作流。模型读长流程指令时,执行靠前步骤的确定性尚可,越到后面越容易漂移。我把长流程拆分成了多个子 Skill,每个子 Skill 只负责一个动作,再通过主 Skill 里的"步骤编排规则"把它们串起来。实测下来,这种方式比一个巨型 SKILL.md 稳定得多。
4. 从零落地 tsm-hub:部署、配置与首次调用
4.1 开箱环境准备与基础部署
以我自己惯用的部署方式为例,我会准备一台 Linux 机器,安装 Python 3.11 以上版本和 Docker,然后通过一个仓库里的docker-compose.yml起服务。因为网关需要连接各种外部依赖,我强烈建议数据目录单独挂卷,至少包含config/和skills/两个子目录。
启动之前把环境变量准备好,主要是各类密钥。配置里我习惯用env:引用环境变量,而不是直接写明文 key。这样配置文件可以进 Git,密钥留在部署平台。
启动命令很简单:
docker compose up -d curl http://localhost:8080/healthz健康检查接口会返回当前加载的模型数量、工具数量、MCP server 连接状态和 Skill 数量。第一次启动如果看到 MCP server 状态为connecting,不要慌,很多 stdio 类型的 server 首启比较慢,等一会儿再看。
4.2 最小配置:接入一个 LLM 和注册一个本地 Tool
最小可用配置其实只需要一个 LLM 和一个本地 Tool。配置文件的重点是这样的,先声明模型:
models: - name: my-llm provider: openai-compatible base_url: https://api.example.com/v1 api_key_env: LLM_API_KEY tags: [chat]接着注册一个本地工具。你的代码里只需要写一个普通函数,比如实现"当前时间查询":
from tsm_hub import register_tool @register_tool( name="get_current_time", description="获取当前时间,适用于所有问'现在几点'的场景。", schema={ "type": "object", "properties": { "timezone": {"type": "string", "default": "Asia/Shanghai"} } } ) def get_current_time(timezone: str = "Asia/Shanghai") -> str: from datetime import datetime from zoneinfo import ZoneInfo return datetime.now(ZoneInfo(timezone)).isoformat()注意到.py文件不需要额外注册路由,网关启动时会扫描指定目录下的装饰器标签,自动把函数转换成标准的 function schema。我在本地运行时常用tsm-hub serve --config config.yaml --plugins ./plugins这条命令,插件目录里放的就是工具实现。
4.3 进阶配置:挂载外部 MCP server 并注册 Skill
最小闭环跑了以后,再挂 MCP server。以我最常用的 Playwright MCP 为例,先在外面把 MCP server 单独跑起来,再把地址写进网关配置。这里有个容易踩的坑:如果 MCP server 跑在 docker 里,而网关也跑在 docker 里,127.0.0.1会指向容器自己的回环地址,根本连不上。要用host.docker.internal或者其他容器名来解析。
Skill 的注册更直接,把 skill 目录放进skills/目录,然后执行一次 reload 命令:
curl -X POST http://localhost:8080/admin/reloadreload 之后,健康检查接口里如果出现skill: web-research@v3,就说明技能加载成功。这一步建议大家做成 CI 的一部分:任何提交到 skills 仓库的改动,合并后就自动触发 staging 环境 reload,跑一遍冒烟测试再发布,能避免大量"本地能跑,线上不认"的问题。
4.4 通过统一网关发起一次真实调用
一切都配置好之后,上层调用非常简单。用 Python 举个例子:
from tsm_hub import HubClient client = HubClient(base_url="http://localhost:8080", api_key="sk-local") resp = client.chat( query="帮我查一下 Playwright 这个开源项目的 star 增长趋势,并整理成简短的周报", model="my-llm", skill="web-research@v3", tools=["search_web", "mcp__playwright__browser_goto"], ) print(resp.text)这个请求里,我显式指定了模型、Skill 和允许使用的工具集合。网关收到请求后,会先加载web-research技能的系统提示词,再把两个工具的 Schema 挂到上下文里,最后调用模型。模型如果决定先调用搜索工具,网关负责执行工具并把结果作为后续消息传回模型,整个往返过程对调用方透明。
我建议初次使用时把响应里的trace_id存下来。后面排查问题的时候,网关的所有请求日志都会关联这个 trace_id,从模型调用到工具执行每一条都有记录,比在 Agent 侧拼日志要靠谱得多。
5. 常见问题速查与避坑经验
5.1 连接类问题
这类问题通常表现为 MCP server 一直connecting或者 Tool 调用超时。最常见的原因是网络链路不对。我在 docker 环境里被127.0.0.1坑过很多次,要记得跨容器访问目标服务时改用host.docker.internal。其次是防火墙和代理拦截,如果配置了全局代理,内部 HTTP 请求也可能被代理兜走,最好在启动环境里对内部网段设置 no_proxy。
另一个连接问题的隐蔽来源是 stdio 类型的 MCP server。它由网关拉起子进程,如果子进程启动时报错,日志却写到了 stderr 没被网关捕获,你会看到 server 状态一直是initializing。排查办法是先在命令行手动执行一遍 server 启动命令,如果命令行本身跑不出结果,那和网关无关,是 server 依赖或环境变量的问题。
5.2 协议与格式类问题
这类问题最典型的是:MCP server 已连接,tools/list能返回,但调用后返回的参数校验错误。原因是很多外部 server 的工具 Schema 写得并不严格,有些参数声明了必填但实现里并不需要,有些默认值没有声明在 Schema 里。模型按 Schema 传参,撞上不匹配的实现就会报错。
我的对策是在网关里加了一层"参数清洗":调用外部工具前,按照 Schema 里的default值补齐缺失字段,剔除 Schema 里没声明的多余字段。这样一来模型偶尔多传或者漏传参数,网关都能兜回来,实际错误率明显下降。
5.3 运行期效率与稳定性问题
运行期最常见的问题是上下文膨胀。Skill 注入的提示词太长,加上工具 Schema 太多,模型上下文被塞得满满的,不仅费用上涨,推理延迟也会变长。我建议给工具 Schema 做分级:高频常用工具始终注入,低频工具只保留名称和一句话描述,等模型明确表示需要时才通过二次请求拉取详细 Schema。虽然多了一次交互,但整体 token 省了很多。
稳定性方面,MCP server 出现偶发性崩溃很正常。网关里设置了自动重连,但重连间隔要调得保守一点,我目前用 30 秒起步、指数退避到 5 分钟。重连期间调用请求会失败,我在网关层会返回一个标准 error code,Agent 看到后可以提示用户"该能力暂时不可用",而不是直接把一个模棱两可的异常抛给用户。
5.4 问题速查表
| 现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| MCP server 一直 connecting | 网络隔离或端口不通 | telnet目标端口、查看 server 启动日志 | 改用 host.docker.internal 或修正防火墙 |
| tools/list 返回空列表 | server 未声明 tools 能力 | 查看 server 的 capabilities | 在配置里开启 tools 能力或换 server |
| 工具调用报参数校验错误 | Schema 与实现不一致 | 在网关侧打印实际落库参数 | 启用参数清洗,剔除多余字段并补默认值 |
| Skill 注入后回复质量下降 | SKILL.md 太长或工具白名单过宽 | 查看注入后的实际 token 量 | 拆分 Skill、缩小工具范围 |
| fallback 后费用飙升 | 兜底链次数无限制 | 查看 token 计量报表 | 设置 fallback 次数阈值和概率开关 |
| stdio 类型 server 启动失败 | server 依赖缺失 | 手动执行 server 启动命令 | 补依赖、修正 node/python 环境 |
6. 应用场景与后续进化方向
6.1 作为企业内部 AI 能力中台
统一网关最典型的归宿,是成为企业内部多个业务线共享的 AI 能力中台。不同部门都在做自己的 Agent,如果没有统一网关,每个部门都要自己对接模型厂商、维护工具服务、管理 MCP server,等于重复发明轮子。接上 tsm-hub 以后,模型密钥统一由平台方管理,工具由各业务线以插件形式注册,能力开放范围由平台统一审批。这样既保证了灵活性,又避免了模型账单和密钥权限失控。
在这个场景里,网关的运维价值甚至比开发价值更明显。因为所有能力都有注册记录和调用日志,安全审计、成本分摊、容量规划都能按资源 ID 维度来做。出问题的时候,说"是mcp__payment__query_balance这个工具最近三天成功率下降",比笼统说"agent 有问题"要高效得多。
6.2 作为个人与团队的 Agent 开发基础设施
小型团队或个人开发者也完全用得上这套模式。我认识的不少研究者,手头有几十个脚本工具和几个常用的 MCP server,以前每个项目都要复制一遍工具定义,现在只要维护一个统一的配置文件,所有项目通过同一个网关调用。对个人来说,最大的收益其实是"少写胶水代码":新项目接入模型和工具,只需要写一份 config 引用,不用再为每个新项目重新搭一遍 function calling 的管子。
此外,统一网关还给个人开发带来一个额外好处:可以安心升级。以前升级某个工具库,总担心影响正在跑的项目;现在工具以独立插件形式存在,升级时先在 staging 里跑回归测试,确认没问题再切换,做起来很顺手。
6.3 能力扩展:多租户、策略引擎与技能市场
再往后走,这类网关的进化方向也很明确。第一是多租户:每个业务线拥有独立的能力可见范围、独立的 token 配额和独立的审计视角。第二是策略引擎:不只做静态授权,还能基于上下文做动态判断,比如"包含财务关键词的请求禁止调用写操作工具"。第三是技能市场:把经过验证的 Skill 和 MCP server 做成可分享的内部包,团队之间维护一套公共资产仓库,而不是靠复制目录传播。
我个人在实际搭建这套东西时,最深的体会是别贪大。先跑通一个模型、一个工具、一个 MCP server 的最小闭环,把日志和 trace 体系建好,比一开始就追求大而全的配置要重要得多。我见过太多项目上来就接了十几个 MCP server,结果排查问题的时间远超开发时间。小步快跑,能力一个一个加,才是这类网关能长期稳定运转的节奏。