ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

LLM、Tools、MCP、Skills 统一网关 tsm-hub 实战:架构设计与踩坑指南

2026/9/30 0:49:36 拓冰建站 浏览量
LLM、Tools、MCP、Skills 统一网关 tsm-hub 实战:架构设计与踩坑指南 1. 为什么要把 LLM、Tools、MCP、Skills 塞进同一个网关第一次看到 tsm-hub 这个项目名的时候我脑子里冒出来的第一个念头是又是一个大一统的抽象层。做后端和 AI 应用的人对统一网关这四个字应该都不陌生API Gateway、服务网格、BFF 层本质上都是在解决同一个问题——当系统里的组件越来越多、协议越来越杂、调用方越来越懒的时候你需要一个中间人把脏活累活全接过去。但 tsm-hub 要收拢的东西有点特殊LLM、Tools、MCP、Skills。这四个词放在一起其实代表了当前 AI 应用开发里四条完全不同的技术脉络。LLM 是模型本身是那个会说话的大脑。Tools 是模型能调用的外部函数比如查天气、算数学、读数据库。MCP 是 Model Context Protocol一套让模型和外部工具、数据源之间用标准方式对话的协议。Skills 则是更高层的封装是把一组工具、提示词、执行逻辑打包成一个可复用的能力单元比如帮我做数学建模或者帮我写漫剧脚本。问题在于这四样东西在传统架构里是各管各的。模型走一套 API工具走另一套注册中心MCP 服务端单独部署Skills 又散落在各个项目的 prompt 目录里。你每接一个新模型就要重写一遍工具调用逻辑每加一个 MCP server就要改一遍路由配置每换一个 Skills 库就要重新对齐参数格式。tsm-hub 的核心价值就在这里它把模型、工具、协议、技能四层抽象收敛到一个统一的入口。调用方只需要面对一个网关地址至于背后是哪个模型、走的是原生 function call 还是 MCP 协议、加载的是哪套 Skills全部由网关内部消化。我实测下来的感受是这种设计对两类人特别友好。一类是快速做原型的独立开发者不想在基础设施上花时间只想把模型和工具拼起来跑通业务。另一类是团队里的平台工程师需要给多个业务线提供统一的 AI 能力出口但又不想让每个业务线都去理解 MCP 和 Skills 的细节。注意统一网关不是银弹。它解决的是接入复杂度问题不解决模型能力问题。如果你的场景只需要调一个模型做文本生成硬上网关反而是过度设计。2. tsm-hub 的四层抽象到底各自管什么要理解 tsm-hub 的设计得先把 LLM、Tools、MCP、Skills 这四层各自的职责边界划清楚。很多人第一次接触这些概念时容易混淆尤其是 MCP 和 Tools看起来都是让模型调用外部能力但它们的抽象层级完全不同。2.1 LLM 层模型接入与路由LLM 层负责的是模型本身的接入。tsm-hub 在这一层做的事情包括统一不同厂商的 API 格式、管理模型列表、处理鉴权、做请求路由和降级。举个实际场景。你手上有三个模型来源一个本地部署的开源模型、一个云端商用模型、一个专门做代码补全的小模型。如果没有网关你的业务代码里会散落着三套不同的 SDK 调用逻辑每套的请求体格式、返回结构、错误码都不一样。tsm-hub 的做法是在这一层做适配器模式把不同来源的模型统一成一套内部接口。路由策略是这一层的重点。我见过比较实用的几种策略策略类型适用场景实现要点按任务类型路由代码任务走代码模型对话走通用模型在请求里带 task_type 字段按成本路由简单任务走便宜模型复杂任务走贵模型需要预估 token 量或复杂度按可用性降级主模型超时自动切备用模型设置超时阈值和重试次数按上下文长度路由长文本走长窗口模型请求前统计 token 数这一层最容易踩的坑是错误码不统一。不同厂商对限流的返回码不一样有的是 429有的是自定义错误码。网关必须把这些统一映射否则上层业务没法做统一的异常处理。2.2 Tools 层函数注册与调用Tools 层管的是模型可以调用的外部函数。这一层的核心是注册机制和参数校验。一个工具在 tsm-hub 里的生命周期大概是这样的先注册工具定义名称、描述、参数 schema然后模型在对话中决定调用哪个工具并生成参数网关校验参数后执行实际函数最后把结果回传给模型。参数校验这一步特别关键。模型生成的参数经常不靠谱比如该传数字的传了字符串该传枚举值的传了个不存在的选项。如果不在网关层拦住错误会一路传到业务函数里排查起来非常痛苦。tsm-hub 在这一层用 JSON Schema 做校验不通过的直接返回错误给模型让它重新生成。我自己的经验是工具描述写得好不好直接决定模型调用准确率。描述里要明确说清楚这个工具做什么、什么时候用、参数是什么含义、返回什么格式。我见过太多人把工具描述写成一句话然后抱怨模型老是调错工具。2.3 MCP 层协议适配与连接管理MCP 是这一层里最容易被误解的。很多人第一次听到 MCP会以为它是某种硬件协议或者网络传输协议。其实 MCP 是 Model Context Protocol是一套应用层协议规定的是模型和外部上下文提供者之间怎么交换信息。tsm-hub 在 MCP 层做的事情本质上是协议转换。因为 MCP 有自己的消息格式和交互流程而网关内部用的是统一的工具调用接口所以需要一个适配层把 MCP 的请求翻译成内部格式再把内部结果翻译回 MCP 格式。这一层的连接管理是个技术难点。MCP server 可能是本地进程也可能是远程服务连接方式可能是 stdio也可能是 HTTP 或 WebSocket。网关需要维护这些连接的生命周期处理断线重连、超时、并发调用等问题。提示如果你在配置 MCP 连接时遇到握手失败先检查两件事——协议版本是否匹配以及 server 端是否真的在监听。我踩过好几次坑最后发现是 server 启动脚本里的端口写错了。2.4 Skills 层能力封装与复用Skills 层是最高层的抽象。一个 Skill 可以理解为一个技能包里面包含了一组工具、一段系统提示词、一套执行流程甚至一些示例对话。为什么需要 Skills 这一层因为 Tools 和 MCP 解决的是模型能做什么而 Skills 解决的是模型应该怎么做。同样是调用搜索工具做学术调研和做新闻摘要的调用方式、结果处理、输出格式完全不同。Skills 就是把这些领域知识固化下来让模型不用每次从零开始理解任务。tsm-hub 在 Skills 层的设计思路是声明式加载。你只需要在配置里声明要加载哪些 Skills网关会自动把 Skill 里的工具注册到 Tools 层把提示词注入到对话上下文把执行流程编排好。这一层最实用的特性是Skills 组合。比如你可以把数学建模Skill 和数据可视化Skill 组合起来模型就能同时具备建模和画图的能力。组合的时候要注意工具命名冲突两个 Skill 里如果有同名工具需要做命名空间隔离。3. 从零搭一个 tsm-hub 实例的完整路径光讲概念没意思我把自己搭 tsm-hub 的完整过程拆一遍。这套流程我在不同环境里跑过三次每次都会遇到一些新问题下面把关键步骤和踩坑点都列出来。3.1 环境准备与依赖确认第一步是确认运行环境。tsm-hub 本身是个服务需要 Node.js 或 Python 运行时取决于你选的实现版本还需要能访问模型 API 的网络环境。我建议在动手之前先列一个清单运行时版本Node.js 18 或 Python 3.10包管理器npm/pnpm 或 pip/uv模型 API 凭证至少一个可用的模型来源存储如果需要持久化配置和日志准备一个 SQLite 或 PostgreSQL网络确认能访问模型 API 和 MCP server 地址这里有个容易忽略的点时区和字符编码。我有一次在容器里跑日志时间全是 UTC排查问题时对不上业务时间。还有一次 Skills 里的中文提示词出现乱码最后发现是环境变量里的 LANG 没设置。3.2 配置文件的结构与关键字段tsm-hub 的配置一般分几块模型配置、工具配置、MCP 配置、Skills 配置、服务配置。我用一个简化版的结构说明server: port: 8080 log_level: info models: - name: default-chat provider: openai-compatible base_url: https://api.example.com/v1 api_key: ${MODEL_API_KEY} model: gpt-4o-mini timeout: 30s tools: - name: get_weather description: 查询指定城市的当前天气 parameters: type: object properties: city: type: string description: 城市名称 required: [city] handler: ./handlers/weather.js mcp: servers: - name: filesystem transport: stdio command: npx args: [-y, modelcontextprotocol/server-filesystem, /data] skills: - name: math-modeling path: ./skills/math-modeling enabled: true几个关键字段的说明provider字段决定用哪个适配器。如果是标准 OpenAI 兼容接口用openai-compatible就行。如果是特殊厂商可能需要自定义适配器。timeout一定要设。我见过太多因为没设超时导致请求挂死的情况。建议根据模型响应速度设一般 30 到 60 秒。transport字段在 MCP 配置里很关键。stdio 适合本地进程http 和 websocket 适合远程服务。选错了连不上。3.3 启动与首次连通性验证配置写完后启动服务。启动日志里会打印加载了哪些模型、注册了哪些工具、连接了哪些 MCP server、启用了哪些 Skills。这一步一定要仔细看日志很多配置错误在启动阶段就会暴露。验证连通性我一般分三步先调一个最简单的对话接口确认模型层通了再调一个带工具调用的请求确认 Tools 层通了最后调一个需要 MCP 或 Skills 的复杂请求确认全链路通了第三步最容易出问题。我遇到过一次模型层和工具层都正常但一走到 MCP 就超时。排查了半天发现是 MCP server 的启动命令里路径写的是相对路径而网关的工作目录和我想的不一样。注意首次验证时把日志级别调到 debug能看到完整的请求和响应链路。确认没问题后再调回 info否则日志量会很大。3.4 接入第一个真实业务场景跑通 demo 之后下一步是接真实业务。我建议从一个具体的、边界清晰的任务开始不要一上来就做通用助手。比如根据用户输入的城市名查询天气并生成出行建议就是一个好场景。它涉及模型调用、工具调用、结果格式化但逻辑不复杂出问题容易定位。接入过程中要重点关注错误处理。模型调用可能超时工具执行可能抛异常MCP 连接可能断开。这些错误在网关层怎么处理、怎么返回给调用方需要提前设计好。我的做法是定义一套统一的错误码上层业务根据错误码决定是重试、降级还是提示用户。4. 那些文档里不会写的踩坑记录这一节是我最想写的部分。官方文档和 README 通常只讲怎么用不讲哪里会炸。下面这些坑都是我实际踩过的希望能帮你省点时间。4.1 MCP 连接握手失败的排查链路MCP 连接失败是最常见的问题而且报错信息往往很模糊。我的排查链路是这样的先看网关日志里 MCP 相关的输出确认是连接阶段失败还是握手阶段失败。连接阶段失败通常是地址或命令不对握手阶段失败通常是协议版本或初始化参数不匹配。如果是 stdio 传输检查启动命令能不能在命令行里手动跑通。我有一次配的 MCP server 需要特定环境变量网关启动时没带上导致 server 启动就崩了。如果是 HTTP 或 WebSocket 传输先用 curl 或 websocket 客户端工具直接连一下确认服务端是活的。这一步能排除掉一半的问题。最后检查协议版本。MCP 协议在演进不同版本的 server 和 client 可能不兼容。网关配置里如果有版本协商选项确认两边对得上。4.2 工具参数校验的边界情况JSON Schema 校验看起来简单实际用起来边界情况很多。模型有时候会传null给一个非必填但类型是 string 的参数。严格校验会拒绝但模型的本意可能是不传这个参数。这种情况我一般在校验前先做一层清洗把null转成 undefined。还有枚举值的问题。模型可能传一个语义相近但不在枚举列表里的值。比如枚举是[北京, 上海, 广州]模型传了北京市。严格校验会失败但用户意图是明确的。我的做法是在校验失败时先尝试做一次模糊匹配匹配不上再返回错误让模型重试。数字类型也有坑。模型可能把数字传成字符串25或者传成浮点数25.0而 schema 要求 integer。这些都需要在校验层做兼容处理。4.3 Skills 加载顺序与覆盖规则Skills 加载顺序会影响最终行为这一点很多人没注意到。如果两个 Skill 都定义了同名工具后加载的会覆盖先加载的。如果两个 Skill 都注入了系统提示词提示词会拼接在一起但拼接顺序会影响模型的理解。我的建议是显式声明加载顺序不要依赖默认顺序。在配置里按优先级从低到高排列高优先级的 Skill 放后面。同时给每个 Skill 的工具加命名空间前缀避免冲突。还有一个坑是 Skills 的依赖关系。有的 Skill 依赖另一个 Skill 提供的工具如果加载顺序不对依赖的工具还没注册Skill 初始化就会失败。这种情况需要在配置里声明依赖让网关按依赖顺序加载。4.4 高并发下的连接池与限流单机跑 demo 没问题一上并发就原形毕露。MCP 连接是长连接如果每个请求都新建连接很快就会把 server 端打满。网关需要维护连接池复用连接。连接池的大小要根据 server 端的承载能力设置太小会排队太大会把 server 压垮。模型 API 一般都有速率限制。网关需要做限流超过限制的请求要么排队要么降级。我一般用令牌桶算法桶的大小根据 API 的配额设置。还有一个容易忽略的点是超时传递。如果调用方设了 10 秒超时网关内部调模型设了 30 秒那调用方早就超时了网关还在等模型。正确的做法是网关的超时时间要小于调用方的超时时间留出处理余量。5. 把 tsm-hub 用出花来的几个进阶思路基础功能跑通之后可以玩一些进阶的。这些思路有的是我自己实践过的有的是看到社区里别人分享的都挺有意思。5.1 用 Skills 做领域知识的固化Skills 最大的价值不是封装工具而是固化领域知识。举个例子做医疗问答场景。通用模型对医学术语的理解可能不够准确但如果你把一套医学知识库的检索工具、一套医学术语的标准化处理流程、一套回答格式规范打包成一个 Skill模型的表现会好很多。再比如做法律文书生成。不同文书的格式要求、引用规范、措辞习惯都不一样。把这些做成 Skills模型就不用每次从零学习。我自己的做法是每做一个新场景先花时间把领域知识整理成 Skill。前期投入大但后面复用的时候非常省事。5.2 多模型协同的路由策略tsm-hub 支持多模型这给了做协同路由的空间。一种思路是大小模型配合。简单任务走小模型复杂任务走大模型。判断任务复杂度可以用规则也可以用一个小模型做分类。另一种思路是多模型投票。同一个问题发给多个模型取多数一致的结果。适合对准确性要求高的场景但成本会翻倍。还有一种是模型接力。第一个模型做初步处理第二个模型做精修。比如先让模型生成大纲再让另一个模型根据大纲写正文。这些策略在 tsm-hub 里都可以通过路由配置实现不需要改业务代码。5.3 可观测性建设日志、指标、追踪网关是流量的必经之路天然适合做可观测性。日志方面我建议记录每个请求的完整链路调了哪个模型、用了哪些工具、走了哪些 MCP、加载了哪些 Skills、各阶段耗时多少。这些信息在排查问题时非常有用。指标方面关注几个核心数据请求量、成功率、平均延迟、各模型的调用分布、各工具的调用频率。这些指标能帮你发现瓶颈和异常。追踪方面如果团队有分布式追踪系统把网关的调用链路接进去。一个请求从进入到返回中间经过了哪些环节一目了然。提示日志里不要记录完整的请求和响应内容尤其是涉及用户隐私的场景。记录摘要和元数据就够了。5.4 安全边界鉴权、审计、内容过滤网关作为统一入口也是做安全控制的好地方。鉴权方面可以在网关层做 API Key 校验、JWT 验证、权限控制。不同调用方给不同的权限能访问哪些模型、哪些工具、哪些 Skills都在网关层控制。审计方面记录谁在什么时候调了什么用于事后追溯。合规要求高的场景审计日志是必须的。内容过滤方面可以在请求进入模型之前和响应返回调用方之前做过滤。输入过滤防止恶意提示词注入输出过滤防止敏感内容泄露。这些安全能力如果散落在各个业务里维护成本很高。收敛到网关层统一管理省事很多。6. 关于统一网关这件事我的真实看法写到这里我想说点掏心窝的话。统一网关这个思路在工程上是对的。它确实能降低接入复杂度提高复用率让业务方专注于业务逻辑。tsm-hub 把 LLM、Tools、MCP、Skills 四层收拢到一个入口设计上是清晰的。但网关不是没有代价的。它引入了一个额外的抽象层意味着多一跳网络开销多一个故障点多一层需要维护的配置。如果团队规模小、场景简单硬上网关可能是负优化。我的判断标准是当你发现同样的接入逻辑在三个以上的地方重复出现时就该考虑抽网关层了。如果只有一个业务在用直接在业务里调模型和工具反而更简单。另外网关的抽象要适度。我见过一些网关设计得过于通用配置项多到没人能看懂最后大家还是绕过网关直接调底层。好的网关应该是默认配置就能用高级配置才需要看文档。tsm-hub 目前给我的感觉是抽象层级把握得还不错四层各司其职没有过度设计。但具体到每个团队还是要根据自己的场景做取舍。工具是死的人是活的适合自己的才是最好的。最后分享一个小技巧搭网关的时候先别急着接所有模型和工具。先用一个模型、一个工具、一个 Skill 把全链路跑通确认架构没问题再逐步扩展。我见过太多人一上来就配一大堆结果出了问题根本不知道是哪一层的事。从最小可用开始逐步迭代这个原则在网关搭建上同样适用。