尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

LLM与工具融合:统一网关如何整合Tools、MCP与Skills调度

发布时间:2026/9/29 23:05:45

资讯中心
01
ARTICLE

LLM与工具融合:统一网关如何整合Tools、MCP与Skills调度

LLM与工具融合:统一网关如何整合Tools、MCP与Skills调度
1. 让 LLM、Tools、MCP、Skills 们停下来握手tsm-hub 的出发点1.1 模型、工具、协议、技能各玩各的项目熵增到失控我接手的 AI 应用项目从第一天起就注定要同时面对四类组件LLM 要对接多家供应商Tools 要以函数调用的形式暴露业务能力MCP 客户端要挂载各种服务端Skills 又要提炼团队里的高阶玩法。每一样单独拎出来都有成熟的方案可一旦放进同一个项目里它们就开始互相打架。最典型的场景是这样的产品经理要一个代码审查助手背后至少要串联一个代码补全模型、一个仓库文件搜索工具、一个合规扫描的 MCP Server还有一套沉淀下来的评审规则——这套规则本质上就是 Skills。传统做法是每个模块各起一个微服务LLM 走 A 端口Tools 走 B 接口MCP 走 C 协议Skills 干脆躺在 GitHub 仓库里靠人肉拷贝。结果就是调用链越拉越长配置散落各处任何一个组件升级都要连带排查另外三个。项目熵增的速度远远超过了我们写代码的速度。这种各玩各的状态持续了大概一个季度直到有一次线上事故让我下了决心。当时一个技能调用了三个工具其中某个工具因为模型返回的 JSON 参数格式变化导致超时而超时后又没有自动走另一个模型的兜底整个会话卡死了。我排查了半天才发现模型路由、工具调用、技能调度是三套独立的逻辑各自都不知道对方的存在。从那一刻起我意识到我需要一个统一的网关层把所有 AI 相关组件收编进去让它们在一个入口、一套规则、一张监控面板下协同工作。这就是 tsm-hub 的出发点。1.2 tsm-hub 解决的四个具体问题在动手之前我先把自己逼到墙角问了一个问题到底什么样的网关才值得自己写而不是直接上现成方案市面上模型网关不少有的能做 LLM 路由有的能接 MCP有的能管理 Agent但几乎没有一个能同时覆盖 LLM、Tools、MCP、Skills 四类对象并且让它们互相感知、配合调度。我需要的是一个AI 组件操作系统级别的中间层而不是又一个独立的代理服务。具体拆解下来tsm-hub 至少要解决四个层面的问题统一入口客户端无论发什么请求都只面对一个 API 地址由网关决定调哪个模型、加载哪些工具、挂哪个 MCP Server、套哪套技能模板。对外是一张干净的嘴对内是一张完整的调度图。统一注册中心模型供应商、工具函数、MCP Server、Skill 定义全部有结构化的注册表。想加一个新模型不用改业务代码注册表加一条再配好密钥就能上线。统一路由策略路由不能只看模型名称要看请求特征——是一轮对话还是长任务需要低延迟还是高精度允不允许调用外部工具这些信息决定了我把请求交给谁路由规则全部下放到网关层。统一可观测性模型调用的 token 消耗、工具的耗时与失败率、MCP 连接的稳定性、Skill 的命中率一切都要能在一张监控面板上拉出来对比。没有数据所谓优化就是拍脑袋。这四个问题表面上是技术问题本质上是平台化管理思维的问题。项目早期可以用脚本把模块串起来可走到多模型、多工具、多人协作的阶段没有统一网关代码里就会长满if 用 OpenAI else 用本地模型这样的屎山。tsm-hub 的存在就是让组件之间只剩下一种交互方式——全部通过网关。2. 统一网关的分层设计入口、路由、协议层、注册中心2.1 四大组件的边界划分设计统一网关第一步不是写代码而是划边界。这四类组件在 tsm-hub 里各有各的位置约束清楚之后后面的调度才能不打架。LLM 在架构里是最底层的能力提供者它的职责只有一件事把提示词变成输出。它不该去关心工具怎么调用也不该负责技能的编排。在 tsm-hub 里LLM 被抽象成一个标准的模型适配器每个供应商对应一个适配器实现统一暴露generate(prompt, context, options)这样的接口。适配器内部处理供应商的 API 差异、鉴权、超时、重试但对外部完全屏蔽。Tools 是业务能力的原子单元越简单越好。一个查询天气的工具、一个读写文件的工具、一个调用内部 API 的工具每个工具只做一件事。但在网关层面工具必须被标准化成统一的结构工具名称、描述、参数 JSON Schema、执行方式、超时时间、权限标签。有了这个标准模型才能通过 function calling 准确地选择工具网关才能对工具的调用做统一的日志和限流。MCP 是一个边界比较微妙的东西。MCP 本质上是一种协议它把工具暴露和调用的格式标准化了。所以在 tsm-hub 里我把它定位成一个协议适配层——MCP Server 提供的工具最终会被映射成网关内的标准工具结构也就是说在 LLM 的视角里MCP 工具和本地 Tools 没有任何区别。这样一来模型的 function calling 逻辑可以完全统一不用为 MCP 单独写一套调用分支。Skills 则处在这一整条链的最上层。一个 Skill 是一段可复用的经验包通常由指令模板、关联的工具列表、默认参数、以及后处理逻辑组成。例如代码审查技能这个 Skill它内部会声明使用仓库搜索工具读取代码、使用静态扫描 MCP 做检查、用 GPT-4o 生成评审意见、最后按团队模板格式输出。网关调度 Skill 时会把它展开成一系列对 LLM 和 Tools 的普通调用操作Skill 本身不产生新的调用类型。这四层的关系可以简单理解为Skills 指挥 LLMLLM 通过 Tools 和 MCP 工具执行动作网关负责把这一切串起来并发号施令。每一层的边界只要清晰出问题的时候定位起来就特别快。2.2 请求流转链路说清楚边界之后请求流转的链路就自然清晰了。我在 tsm-hub 里把一条典型请求拆成了七个阶段这个拆解值得每个想设计网关的人参考接入识别请求进来网关先认身份。是内部服务调用还是外部 AgentAPI Key 对应哪一级权限意图分类根据请求的路由参数判断这一次要走哪条链路——普通对话、工具调用任务、还是需要完整执行某个 Skill。Skill 匹配如果命中了某个 Skill网关把 Skill 模板加载进来注入会话上下文。路由决策根据模型策略、成本预算、当前可用状态选定具体模型供应商。上下文拼装把系统提示词、Skill 指令、历史对话、工具定义全部组装成一次模型请求。执行与循环模型可能返回 function call网关就去执行对应的工具把结果回填再继续调模型循环直到模型给出最终回答或达到最大轮次。记载与观测每一轮调用的 token 数、耗时、工具结果、失败原因全部写入日志存储。这个链路里最有技术含量的是第 6 步的执行与循环。因为这不是简单的一次请求-响应而是一个 Agent 式的循环。网关要自己去判断模型是不是想要调用工具然后跨层去执行工具、把结果装回上下文、再发起下一次模型调用。中间涉及的超时控制、上下文裁剪、轮次上限都必须做得非常保守否则一次任务消耗的 token 会超出预期好几倍。3. LLM 接入层多模型路由、重试与成本控制的实现思路3.1 模型注册与供应商适配LLM 接入层是 tsm-hub 里最基础也最不能出错的部分。任何模型要接入第一步都是在注册表里声明自己。我这里放一份真实项目里的注册配置作参考models: - id: gpt-4o-mini provider: openai model_name: gpt-4o-mini api_key_env: OPENAI_API_KEY default_params: temperature: 0.7 max_tokens: 2048 capabilities: function_calling: true vision: false context_window: 128000 cost_per_1k_tokens: input: 0.00015 output: 0.0006 - id: deepseek-chat provider: openai-compatible base_url: https://api.deepseek.com model_name: deepseek-chat api_key_env: DEEPSEEK_API_KEY default_params: temperature: 0.3 capabilities: function_calling: true vision: false cost_per_1k_tokens: input: 0.000014 output: 0.000028注意到第二个模型 provider 我写成了openai-compatible因为国内大多数模型厂商的 API 都在模仿 OpenAI 的格式。tsm-hub 里内置了这样的兼容适配器可以大幅减少对接成本。但兼容不等于完全一致实际测下来不同厂商对 function calling 的返回值格式仍有细微差异适配器里必须要做归一化处理把各家参数统一成内部结构否则任何一处差异都会在下游链路埋雷。注册时的cost_per_1k_tokens字段很重要很多网关会忽略它。但如果你想让路由策略做成本感知就必须把成本数据放进来。后面谈到的低成本优先路由靠的就是这个字段算出来的。3.2 基于权重和优先级的动态路由路由策略是统一网关最核心的价值。我一般不推荐简单的随机或轮询路由那种方式完全不会考虑请求的实际特点。tsm-hub 里我实现了三种策略实际用下来覆盖面很广优先级路由给每个模型配一个优先级数字数字小的优先。只有高优先级模型不可用时才 fallback 到下一个。这种策略适合生产环境——你希望尽量用强模型但如果强模型限流或者故障自动降级到弱模型保证服务不中断。成本优先路由网关根据注册表里的成本数据结合请求的预估输入长度动态计算哪个模型最便宜。适合对成本敏感但不要求绝对质量的批量任务比如日志分类、标题生成这类场景。语义路由其实我试过基于请求分类模型做语义路由但性能和开销都偏高最后放弃了对小项目来说性价比太低。如果你确实有这类需求注意要控制分类模型的调用频次绝对不能在路由这个环节就消耗掉大量 token。路由策略可以做成可设计的组合规则。比如日常请求优先 gpt-4o-mini遇到复杂推理请求自动切 deepseek-chat如果 5 秒内没有返回则 fallback 到本地 llama。这些规则在 tsm-hub 里都是 YAML 声明式的改配置不需要重新部署。实际运营中我发现fallback 触发条件和重试策略必须分开配置。重试是同一个模型再试一次fallback 是换一个模型试一次。很多网关把这俩混在一起结果模型明明已经崩了还在同样的模型上反复重试几十秒用户早就跑了。tsm-hub 里我对重试默认限制最多 2 次fallback 最多 3 级且每级 fallback 之前都会记录一次事件日志方便事后回溯。3.3 可观测性调用链与延迟数据这部分我要着重讲一下因为太多网关做出来之后调用很顺可一出了问题就抓瞎原因就是观测做得不够。tsm-hub 里我坚持每个请求都必须生成一条完整的调用链记录包含六个核心字段request_id全链路唯一 ID所有日志都带上它。route_path实际走了哪个模型经历了哪几次重试和 fallback按顺序记录下来。token_usage输入、输出、卡在哪个环节。tool_calls模型请求了几次工具每个工具的入参、出参、耗时。skill_id命中了哪个技能模板模板的版本号也记录下来。error_details失败的类型码、供应商返回的原始错误信息。有了这个结构你去查为什么昨天下午某些请求响应特别慢就能直接按时间窗口拉出所有请求的route_path一眼看到是不是某个模型供应商在那个时段限流了。这种排障速度是以前靠查日志关键字完全比不了的。还有一个容易被忽略的点token 用量统计必须按路由结果聚合。也就是说不仅要看总消耗还要看每个模型、每个技能分别消耗了多少。不这么统计成本优化就无从谈起——你根本不知道钱花在了哪个模型哪类任务上。我每周都会拉一张表按模型、按 Skill 汇总 token 消耗和延迟这是后续做模型选型和预算控制的决策依据。4. Tools 与 MCP 的桥接工具从硬编码到即插即用4.1 统一工具注册表LLM 接入层解决的是模型说话的问题而 Tools 层解决的是模型动手的问题。我见过太多项目把工具调用直接写在业务代码里每个工具一套调用方式参数校验写在各自的函数里连个统一入口都没有。这样做一两个工具没问题但一旦工具数量超过十个维护成本就开始指数增长。tsm-hub 的做法是维护一张统一工具注册表每个工具都按同一套标准登记入库# 工具注册的标准结构简化示例 tool_definition { name: search_repo, description: 在指定代码仓库中搜索关键词返回匹配的文件和行号, parameters: { type: object, properties: { keyword: {type: string}, repo: {type: string, enum: [core, web, mobile]}, limit: {type: integer, default: 10} }, required: [keyword] }, execution: { type: python_callable, target: tool_impl.search.search_repo, timeout_seconds: 15, auth: {required_permission: repo:read} } }这里的关键在于parameters必须是严格的 JSON Schema因为这条定义不光是给人看的它会被直接塞进模型的 system prompt作为 function calling 的参数约束。Schema 写得不严格模型返回的参数就乱七八糟工具执行必炸。我实践下来的经验是参数类型能窄就窄能用 enum 就不要用自由字符串description写得越具体模型选错工具的概率就越低。所有工具执行之前会先经过网关的统一校验层参数结构校验、权限校验、额度校验。校验通过才真正进入执行函数。这样任何一个工具都很难被绕过权限滥用模型的误调用也会被拦截在成本产生之前。4.2 MCP 客户端的接入MCP 的接入方式可以简单理解成把外部工具服务包成标准插件。一个 MCP Server 通常以子进程或远程 HTTP 服务的形式存在tsm-hub 内置了 MCP 客户端负责维护连接、发送请求、解析结果。拿最常用的 filesystem MCP Server 举例只需要在配置里声明一个条目mcp_servers: - name: filesystem transport: stdio command: npx args: - -y - modelcontextprotocol/server-filesystem workspaces: - /home/user/projects allowed_dirs: - /home/user/projects cache_ttl: 60启动后网关会主动向 MCP Server 发起tools/list请求拿到它暴露的所有工具然后批量映射成内部的统一工具结构自动完成注册。不用写一行代码LLM 立刻就能调用这些外部工具。这正是 MCP 最有价值的地方——工具的能力边界由外部服务决定网关这边只需要做好桥接。但我必须提醒MCP 工具的自动注册虽然方便也意味着所有暴露出来的工具都要过一个安全审核。默认配置里我将 MCP 工具全部标记为auto_registered: true并且要求人工确认后才可对 LLM 可见。否则万一某个 MCP Server 意外暴露了删除类工具而模型又被诱导调用了它后果可能会非常严重。4.3 安全边界控制MCP 桥接之后工具数量通常会一下子膨胀很多倍。本地工具加 MCP 工具轻松突破几十个。这么多工具一股脑全部塞给模型肯定不行。t-sm-hub 的做法是按会话动态裁剪工具列表。具体逻辑是每次请求进来时根据意图分类结果只加载与当前任务相关的工具。比如代码审查任务只加载仓库搜索、静态扫描、文件读取这几个工具日常问答任务只加载一两个基础工具就够了。工具裁剪不仅大幅减少了模型处理 function calling 时 token 的消耗还明显降低了模型选错工具的概率。实测中工具数从 40 个裁剪到 8 个后function call 准确率从 91% 提升到了 98%。安全这块我还做了几个兜底敏感工具白名单删除、写库、发送消息等危险操作必须在配置里显式加白才能被模型调用而且执行后强制要求人工复核。调用频率限制同一工具在同一会话中设置了最大调用次数防模型陷入死循环。超时熔断单个工具超过设置的超时时间直接熔断并把错误信息回传给模型让它调整策略而不是无限等下去。5. Skills 技能库将提示词与工具调用序列沉淀为资产5.1 Skill 的组成结构如果说 LLM 是大脑、Tools 是手、MCP 是外接的传感器那 Skills 就是已经训练好的肌肉记忆。一个 Skill 把一段复杂的操作流程封装成一行调用触发这是团队经验沉淀的最高效形式。我在 tsm-hub 里把 Skill 定义成一个结构化的包一个完整的 Skill 通常包含五个部分元信息名称、版本号、作者、描述、适用场景。版本号是硬性要求没有版本控制的技能库改来改去迟早要出事故。指令模板插入到系统提示词中的核心指令文本。这里要写得很有讲究既要任务导向清晰还不能太死板要给模型留出合理的判断空间。工具依赖该 Skill 需要调用哪些工具有严格的名称列表并且允许声明必须可选两级依赖。参数入口Skill 对外暴露的参数定义调用方只需传入核心参数其余由 Skill 内部消化。参数定义也用 JSON Schema保证调用体验一致。后处理钩子模型输出完成后允许插入一段自定义代码做后处理比如给回答追加引用来源、格式化输出、触发另一个流程等。我在项目里做的第一个成规模 Skill 叫新需求技术评估输入是一段需求描述输出是一份结构化的技术方案草稿。这个 Skill 内部声明了三个可选工具代码库搜索、依赖库查询、相似项目检索。实际跑起来之后团队不再需要每次从头开始分析需求只要把需求丢进来就能拿到初稿后续人工修一修就能用。节省的时间是非常直观的。5.2 网关如何调度 SkillsSkill 在网关里的调度本质上是一次模板展开。当请求命中某个 Skill网关并不是把它当作一个整体去调模型而是把它展开成一串标准的组件调用序列。我习惯把这个调度过程想象成解读菜谱——Skill 就是菜谱网关是厨师菜谱里写着要放盐、放糖、大火、小火厨师按照步骤一步步执行最后做出一道完整的菜。一个简化版的 Skill 调度配置如下skills: - name: code_review version: 2.1 description: 对指定代码变更进行系统性评审 parameters: type: object properties: diff_uri: { type: string } language: { type: string, default: python } steps: - action: load_context uri: {parameters.diff_uri} - action: call_tool tool: search_repo params: keyword: TODO|FIXME - action: call_tool tool: static_scan params: target: {steps.load_context.result.path} - action: llm_generate model_hint: strong # 由网关解析为具体模型策略 prompt_template: | 请基于以下代码变更和扫描结果输出评审意见。 变更内容{steps.load_context.result} 扫描发现{steps.call_tool.result} {{ skill_instructions.code_review }}调度器按steps顺序执行上一个步骤的输出可以作为下一个步骤的输入。model_hint: strong是一个路由提示网关会把它映射到当前可用的最强模型上同时也可以被成本控制策略改写成次强模型——Skill 定义里不写死具体模型而写模型档位这是我踩过坑之后总结出来的经验一旦在某次测试里觉得某个模型效果好就写死到 Skill 里后续模型升级、供应商调整时这个 Skill 就会被绑架。Skill 的执行结果同样会写进可观测日志里方便我在后续做效果复盘。我一般每月拉一次 Skill 使用报告看哪个 Skill 的调用成功率低、哪个 Skill 的平均延迟高、哪个 Skill 消耗 token 最多。一次调优可以让团队节省大量重复劳动时间。6. 实际跑通 tsm-hub一份可复现的配置与踩坑记录6.1 最小化部署配置讲完设计思路该聊落地了。我先把一份最小化部署配置放在最前面方便你直接照着上手# tsm-hub 最小化配置 server: port: 8080 api_prefix: /v1 api_keys: - key: ${ADMIN_API_KEY} models: - id: gpt-4o-mini provider: openai model_name: gpt-4o-mini api_key_env: OPENAI_API_KEY capabilities: { function_calling: true } - id: llama-3.1-8b provider: local base_url: http://localhost:11434/v1 model_name: llama3.1:8b capabilities: { function_calling: true } tools: - name: http_get description: 发起 HTTP GET 请求获取 URL 内容 parameters: type: object properties: url: { type: string } required: [url] - name: python_exec_sandbox description: 在受控沙箱中执行 Python 代码片段 parameters: type: object properties: code: { type: string } mcp_servers: - name: fetch transport: stdio command: npx args: [-y, modelcontextprotocol/server-fetch] cache_ttl: 30 skills_trunk: - name: web_search_followup version: 1.0 steps: - action: call_tool tool: http_get params: { url: {parameters.target_url} } - action: llm_generate model_hint: fast prompt_template: | 总结以下网页内容提取关键信息{steps.call_tool.result}这份配置跑起来之后我可以同时做三类基础验证直接对话调模型、让模型通过 function calling 调用 http_get 工具、挂载 MCP fetch 服务后让模型从指定 URL 拉取内容再总结。这一套通了tsm-hub 的核心链路就都验证完了后面再加新组件都只是往注册表里塞记录的事。6.2 踩过的坑我不想让这篇分享看起来一路顺风顺水实际上这个项目踩过的坑一点不少挑三个最有代表性的写出来第一个坑MCP Server 的子进程崩溃拉垮整个网关。stdio 模式的 MCP Server 作为子进程常驻某个 Server 代码里一个异常就能导致整个进程退出。第一次部署时一个不稳定 MCP Server 直接拖垮了网关进程所有请求全部 502。修复方案是给每个 MCP Server 独立进程托管并且加上崩溃自动拉起和健康检查发生故障时只影响自己不影响主链路。这个隔离思路所有想接多 MCP 的人都要提前考虑。第二个坑Skill 展开后的上下文爆炸。我第一次把 Skill 配了十几个步骤时每个步骤都把前一步完整输出塞进上下文结果跑到第五步上下文已经占了几万个 token模型都快忘了最初的指令。后来我做了上下文瘦身工具步骤之间只传摘要 关键字段并把历史中间结果存到外部缓存需要时再按 ID 取回。Skill 步骤越多上下文管理越要精心设计这不是可选项。第三个坑模型对工具描述里的长尾文字过度敏感。我给一个工具 description 写了一大段背景说明结果模型频繁在无关问题中去调用这个工具因为里面某些词触发了它的联想。后来我把 description 压缩成做什么 什么时候用 什么时候不要用三句话格式误调用率才降下来。工具描述不是文档是给模型看的路标越精炼越有效。每次掉进坑里我都会顺手把处理方案补回 tsm-hub 的默认配置模板里。一个网关是修出来的不是写出来就完事了。把这些容易踩的坑收敛成默认的护栏后来者就不需要重新经历一遍我踩过的那些糟糕体验。7. 我最后提醒自己的三件事项目从设计到跑通前后横跨了两个多月最后我的体会有三件事值得反复提醒自己和团队。第一件事统一网关的价值不是省代码而是省决策。它让团队不用再思考这个请求应该走哪条路而是把决策权集中到规则配置里。配置可以讨论、可以评审、可以灰度业务代码里不再散落着各种 if else 的分流逻辑。这比少写几个函数重要得多。第二件事组件之间最好用协议沟通而不是用代码沟通。MCP 之所以值得集成进去就是因为它把工具的暴露和调用方式标准化了让工具能力的边界可以动态伸缩。tsm-hub 里我尽量让所有交互都走标准结构哪怕多写几行适配代码也为未来的扩展留了余地。第三件事过段时间回头重构一下配置里的默认值。模型会出新版、工具会调整、Skill 会过时一套配置用上半年基本就不太合适了。我每个季度会做一次全量 review把成本、延迟、成功率这些指标翻出来重新调整路由策略和 Skill 模板。统一网关给了我们只改配置就能整体优化的底气这是最大的杠杆。如果你也在同时对接多个模型、维护一堆工具函数、尝试用 MCP 扩展能力、考虑沉淀团队技能库那 tsm-hub 这套思路大概率对你有参考价值。别急着上来就写代码先把你手上已有的组件列个清单想一想如果它们都要通过一个网关互相配合你会怎么划分边界——这个想清楚了后面都是水磨工夫。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。