云计算百科
云计算领域专业知识百科平台

AI Agent 工具发现与调用流程——路由注册表与四阶段调用编排

27-工具发现与调用流程——路由注册表与四阶段调用编排

第 1 章 文档定位与阅读指引

1.1 本篇在 55 篇中的位置

本系列围绕《AI Agent 智能体分层架构全景图深度拆解》展开。前 26 篇已完成认知层(17–24)与连接协议层定位/协议规范(25–26)。本篇承接源文档 6.4 工具发现与调用流程,回答一个承上启下的工程问题:协议规范(26 篇)已经定义了 tools/list、tools/call 这些方法,但 Agent 在实际运行时,到底是怎么从"不知道有哪些工具"走到"精确调用某个工具并拿到结果"的?

  • 25 篇:连接协议层为什么存在(N×M → N+M 降维)。
  • 26 篇:MCP 协议本身怎么定义(JSON-RPC、三原语、会话)。
  • 本篇:工具发现与调用的完整流程编排(路由注册表 + 四阶段)。
  • 28 篇:典型 MCP Server 详解(GitHub/数据库/浏览器)。
  • 29 篇:代码审查 Agent 案例 + MCP vs 传统 API + 第 6 章小结。

1.2 本篇要回答的核心问题

  • Agent 如何"知道"当前有哪些工具可用?(发现)
  • Agent 如何从多个 Server 中找到"该用哪个 Server 的哪个工具"?(路由)
  • 调用一个工具时,参数、结果、错误怎么流转?(调用)
  • 多 Server 场景下,路由注册表怎么设计才不串线?(注册表)
  • 工具发现/调用在真实工程中会踩哪些坑、怎么解?(挑战)
  • 1.3 读者对象与前置

    • 读者:AI 应用架构师、Agent 平台开发者、MCP 集成工程师、对"AI 如何调用工具"好奇的产品经理。
    • 前置:建议先读 25(连接协议层定位)与 26(MCP 协议规范);本篇会在用到方法名时直接引用其定义。

    1.4 阅读方法建议

    • 想快速理解骨架:读第 2、3 章(概念 + 四阶段全景)。
    • 想落地实现:重点读第 4、5、6、7 章(注册表/发现/调用/多 Server)。
    • 想避坑:读第 8 章(技术挑战)。
    • 想直观感受:读第 9 章(通俗案例)。
    • 想验收成果:读第 10 章(小结、自测、清单)。

    1.6 本篇与行动层的衔接

    工具发现与调用是"认知层决定做什么、连接协议层负责怎么执行"的接缝处:

    • 认知层(17–24 篇):Agent 规划、决策,决定"要调用哪个工具"。
    • 连接协议层(25–29 篇):提供工具清单与调用通道。
    • 行动层(30 篇起,源第 7 章):工具背后的真实执行器(API、代码沙箱、数据库)。

    本篇是"决策与执行之间的路由层":它不替 Agent 做决策,也不替 Server 干活,只保证"决策了就能精准、可靠地到达正确的执行者"。

    1.7 本篇的知识地图

    #mermaid-svg-My0EAzqQXw4Ynhtn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-My0EAzqQXw4Ynhtn .error-icon{fill:#552222;}#mermaid-svg-My0EAzqQXw4Ynhtn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-My0EAzqQXw4Ynhtn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-My0EAzqQXw4Ynhtn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-My0EAzqQXw4Ynhtn .marker.cross{stroke:#333333;}#mermaid-svg-My0EAzqQXw4Ynhtn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-My0EAzqQXw4Ynhtn p{margin:0;}#mermaid-svg-My0EAzqQXw4Ynhtn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn .cluster-label text{fill:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn .cluster-label span{color:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn .cluster-label span p{background-color:transparent;}#mermaid-svg-My0EAzqQXw4Ynhtn .label text,#mermaid-svg-My0EAzqQXw4Ynhtn span{fill:#333;color:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn .node rect,#mermaid-svg-My0EAzqQXw4Ynhtn .node circle,#mermaid-svg-My0EAzqQXw4Ynhtn .node ellipse,#mermaid-svg-My0EAzqQXw4Ynhtn .node polygon,#mermaid-svg-My0EAzqQXw4Ynhtn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-My0EAzqQXw4Ynhtn .rough-node .label text,#mermaid-svg-My0EAzqQXw4Ynhtn .node .label text,#mermaid-svg-My0EAzqQXw4Ynhtn .image-shape .label,#mermaid-svg-My0EAzqQXw4Ynhtn .icon-shape .label{text-anchor:middle;}#mermaid-svg-My0EAzqQXw4Ynhtn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-My0EAzqQXw4Ynhtn .rough-node .label,#mermaid-svg-My0EAzqQXw4Ynhtn .node .label,#mermaid-svg-My0EAzqQXw4Ynhtn .image-shape .label,#mermaid-svg-My0EAzqQXw4Ynhtn .icon-shape .label{text-align:center;}#mermaid-svg-My0EAzqQXw4Ynhtn .node.clickable{cursor:pointer;}#mermaid-svg-My0EAzqQXw4Ynhtn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-My0EAzqQXw4Ynhtn .arrowheadPath{fill:#333333;}#mermaid-svg-My0EAzqQXw4Ynhtn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-My0EAzqQXw4Ynhtn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-My0EAzqQXw4Ynhtn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-My0EAzqQXw4Ynhtn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-My0EAzqQXw4Ynhtn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-My0EAzqQXw4Ynhtn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-My0EAzqQXw4Ynhtn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-My0EAzqQXw4Ynhtn .cluster text{fill:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn .cluster span{color:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-My0EAzqQXw4Ynhtn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-My0EAzqQXw4Ynhtn rect.text{fill:none;stroke-width:0;}#mermaid-svg-My0EAzqQXw4Ynhtn .icon-shape,#mermaid-svg-My0EAzqQXw4Ynhtn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-My0EAzqQXw4Ynhtn .icon-shape p,#mermaid-svg-My0EAzqQXw4Ynhtn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-My0EAzqQXw4Ynhtn .icon-shape .label rect,#mermaid-svg-My0EAzqQXw4Ynhtn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-My0EAzqQXw4Ynhtn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-My0EAzqQXw4Ynhtn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-My0EAzqQXw4Ynhtn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    第2章 核心概念

    第3章 四阶段全景

    第4章 注册表

    第5章 发现机制

    第6章 调用机制

    第7章 多Server

    第8章 挑战

    第9章 案例

    第10章 小结

    1.8 与源文档的承接关系

    源文档 6.4 共 44 行(2517–2560),核心是一张四阶段 sequenceDiagram。本篇将其拆为:

    源内容本篇章节
    阶段1 初始化 第 3 章 3.11–3.14
    阶段2 工具发现 第 3 章 3.15–3.17 + 第 5 章
    阶段3 注册路由 第 3 章 3.18–3.19 + 第 4 章
    阶段4 工具调用 第 3 章 3.20–3.22 + 第 6 章
    多 Server(GitHub+Slack) 第 7 章

    1.9 阅读时长与篇幅

    • 全篇约 2500 行、30+ 图,按 10 章组织。
    • 每章内部用大量 ### 子节承载深度,不增加章数(符合系列规范)。

    1.10 本章小结(扩展版)

    本篇是"连接协议层"由静态规范走向动态运行的转折点:协议定义方法,流程编排方法。四阶段(初始化→发现→注册→调用)与路由注册表,是 Agent 工具能力的"运行时神经系统"。本篇衔接认知层决策与行动层执行,是"决策与执行之间的路由层"。


    第 2 章 核心概念:发现与调用的本质

    2.1 从"硬编码"到"动态发现"

    传统集成里,Agent 要用 GitHub 的搜索功能,开发者得先写死一段适配代码:

    def search_code(query, repo):
    token = get_token("github")
    return github_api.search_code(query=query, repo=repo, token=token)

    每个工具、每个 API 都要写一套这样的胶水代码。工具一多,代码里全是 N×M 的适配组合。MCP 的出现把"写死"变成"运行时发现":

    #mermaid-svg-BZ5xOGzRfBc9yvEw{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-BZ5xOGzRfBc9yvEw .error-icon{fill:#552222;}#mermaid-svg-BZ5xOGzRfBc9yvEw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BZ5xOGzRfBc9yvEw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .marker.cross{stroke:#333333;}#mermaid-svg-BZ5xOGzRfBc9yvEw svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-BZ5xOGzRfBc9yvEw p{margin:0;}#mermaid-svg-BZ5xOGzRfBc9yvEw .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .cluster-label text{fill:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .cluster-label span{color:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .cluster-label span p{background-color:transparent;}#mermaid-svg-BZ5xOGzRfBc9yvEw .label text,#mermaid-svg-BZ5xOGzRfBc9yvEw span{fill:#333;color:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .node rect,#mermaid-svg-BZ5xOGzRfBc9yvEw .node circle,#mermaid-svg-BZ5xOGzRfBc9yvEw .node ellipse,#mermaid-svg-BZ5xOGzRfBc9yvEw .node polygon,#mermaid-svg-BZ5xOGzRfBc9yvEw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .rough-node .label text,#mermaid-svg-BZ5xOGzRfBc9yvEw .node .label text,#mermaid-svg-BZ5xOGzRfBc9yvEw .image-shape .label,#mermaid-svg-BZ5xOGzRfBc9yvEw .icon-shape .label{text-anchor:middle;}#mermaid-svg-BZ5xOGzRfBc9yvEw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .rough-node .label,#mermaid-svg-BZ5xOGzRfBc9yvEw .node .label,#mermaid-svg-BZ5xOGzRfBc9yvEw .image-shape .label,#mermaid-svg-BZ5xOGzRfBc9yvEw .icon-shape .label{text-align:center;}#mermaid-svg-BZ5xOGzRfBc9yvEw .node.clickable{cursor:pointer;}#mermaid-svg-BZ5xOGzRfBc9yvEw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .arrowheadPath{fill:#333333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-BZ5xOGzRfBc9yvEw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-BZ5xOGzRfBc9yvEw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-BZ5xOGzRfBc9yvEw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-BZ5xOGzRfBc9yvEw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .cluster text{fill:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw .cluster span{color:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-BZ5xOGzRfBc9yvEw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-BZ5xOGzRfBc9yvEw rect.text{fill:none;stroke-width:0;}#mermaid-svg-BZ5xOGzRfBc9yvEw .icon-shape,#mermaid-svg-BZ5xOGzRfBc9yvEw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-BZ5xOGzRfBc9yvEw .icon-shape p,#mermaid-svg-BZ5xOGzRfBc9yvEw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-BZ5xOGzRfBc9yvEw .icon-shape .label rect,#mermaid-svg-BZ5xOGzRfBc9yvEw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-BZ5xOGzRfBc9yvEw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-BZ5xOGzRfBc9yvEw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-BZ5xOGzRfBc9yvEw :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    传统方式

    每个工具写适配代码

    工具列表硬编码

    API 变更要改代码

    MCP 方式

    Server 声明工具

    Client 运行时发现

    Schema 自动生成参数

    2.2 两个关键词的定义

    • 工具发现(Tool Discovery):Client 在运行时通过 tools/list 获取 Server 当前提供的工具清单(名称、描述、inputSchema)。Agent 不需要在编译期知道有哪些工具。
    • 工具调用(Tool Invocation):Agent 依据发现的 schema 构造参数,通过 tools/call 让 Server 执行,并拿到结构化结果。

    两者合在一起,构成"先侦察、后行动"的完整闭环——这正是 Agent 区别于传统程序的关键:传统程序调用什么函数是写死的,Agent 调用什么工具是思考后决定的。

    2.3 发现与调用的四阶段总览

    源文档 6.4 用一张 sequenceDiagram 完整展示了从启动到调用的全过程。我们把它提炼为四阶段:

    #mermaid-svg-cBiFnh4gIEe49KJS{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cBiFnh4gIEe49KJS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cBiFnh4gIEe49KJS .error-icon{fill:#552222;}#mermaid-svg-cBiFnh4gIEe49KJS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cBiFnh4gIEe49KJS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cBiFnh4gIEe49KJS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cBiFnh4gIEe49KJS .marker.cross{stroke:#333333;}#mermaid-svg-cBiFnh4gIEe49KJS svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cBiFnh4gIEe49KJS p{margin:0;}#mermaid-svg-cBiFnh4gIEe49KJS .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-cBiFnh4gIEe49KJS .cluster-label text{fill:#333;}#mermaid-svg-cBiFnh4gIEe49KJS .cluster-label span{color:#333;}#mermaid-svg-cBiFnh4gIEe49KJS .cluster-label span p{background-color:transparent;}#mermaid-svg-cBiFnh4gIEe49KJS .label text,#mermaid-svg-cBiFnh4gIEe49KJS span{fill:#333;color:#333;}#mermaid-svg-cBiFnh4gIEe49KJS .node rect,#mermaid-svg-cBiFnh4gIEe49KJS .node circle,#mermaid-svg-cBiFnh4gIEe49KJS .node ellipse,#mermaid-svg-cBiFnh4gIEe49KJS .node polygon,#mermaid-svg-cBiFnh4gIEe49KJS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cBiFnh4gIEe49KJS .rough-node .label text,#mermaid-svg-cBiFnh4gIEe49KJS .node .label text,#mermaid-svg-cBiFnh4gIEe49KJS .image-shape .label,#mermaid-svg-cBiFnh4gIEe49KJS .icon-shape .label{text-anchor:middle;}#mermaid-svg-cBiFnh4gIEe49KJS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cBiFnh4gIEe49KJS .rough-node .label,#mermaid-svg-cBiFnh4gIEe49KJS .node .label,#mermaid-svg-cBiFnh4gIEe49KJS .image-shape .label,#mermaid-svg-cBiFnh4gIEe49KJS .icon-shape .label{text-align:center;}#mermaid-svg-cBiFnh4gIEe49KJS .node.clickable{cursor:pointer;}#mermaid-svg-cBiFnh4gIEe49KJS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cBiFnh4gIEe49KJS .arrowheadPath{fill:#333333;}#mermaid-svg-cBiFnh4gIEe49KJS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cBiFnh4gIEe49KJS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cBiFnh4gIEe49KJS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cBiFnh4gIEe49KJS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cBiFnh4gIEe49KJS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cBiFnh4gIEe49KJS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cBiFnh4gIEe49KJS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cBiFnh4gIEe49KJS .cluster text{fill:#333;}#mermaid-svg-cBiFnh4gIEe49KJS .cluster span{color:#333;}#mermaid-svg-cBiFnh4gIEe49KJS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cBiFnh4gIEe49KJS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cBiFnh4gIEe49KJS rect.text{fill:none;stroke-width:0;}#mermaid-svg-cBiFnh4gIEe49KJS .icon-shape,#mermaid-svg-cBiFnh4gIEe49KJS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cBiFnh4gIEe49KJS .icon-shape p,#mermaid-svg-cBiFnh4gIEe49KJS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cBiFnh4gIEe49KJS .icon-shape .label rect,#mermaid-svg-cBiFnh4gIEe49KJS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cBiFnh4gIEe49KJS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cBiFnh4gIEe49KJS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cBiFnh4gIEe49KJS :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    新工具上线

    阶段1 初始化

    阶段2 工具发现

    阶段3 注册路由

    阶段4 工具调用

    返回结果

    • 阶段 1 初始化:Agent 启动,Client 与每个 Server 建立会话(initialize)。
    • 阶段 2 工具发现:Client 向各 Server 发 tools/list,拿回工具清单。
    • 阶段 3 注册路由:Client 把"工具名 → Server"的映射写入路由注册表。
    • 阶段 4 工具调用:Agent 发起 call_tool,Client 查注册表路由到正确 Server 执行。

    2.4 为什么需要路由注册表

    一个 Agent 可能同时连 GitHub、Slack、数据库等多个 Server,每个 Server 提供一批工具。如果没有注册表,Client 每次都要遍历所有 Server 找"哪个 Server 有 search_code",代价高且易错。注册表是一张"工具路由表":

    #mermaid-svg-AuFmGMIxCzycVPNi{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AuFmGMIxCzycVPNi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AuFmGMIxCzycVPNi .error-icon{fill:#552222;}#mermaid-svg-AuFmGMIxCzycVPNi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AuFmGMIxCzycVPNi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AuFmGMIxCzycVPNi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AuFmGMIxCzycVPNi .marker.cross{stroke:#333333;}#mermaid-svg-AuFmGMIxCzycVPNi svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AuFmGMIxCzycVPNi p{margin:0;}#mermaid-svg-AuFmGMIxCzycVPNi .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-AuFmGMIxCzycVPNi .cluster-label text{fill:#333;}#mermaid-svg-AuFmGMIxCzycVPNi .cluster-label span{color:#333;}#mermaid-svg-AuFmGMIxCzycVPNi .cluster-label span p{background-color:transparent;}#mermaid-svg-AuFmGMIxCzycVPNi .label text,#mermaid-svg-AuFmGMIxCzycVPNi span{fill:#333;color:#333;}#mermaid-svg-AuFmGMIxCzycVPNi .node rect,#mermaid-svg-AuFmGMIxCzycVPNi .node circle,#mermaid-svg-AuFmGMIxCzycVPNi .node ellipse,#mermaid-svg-AuFmGMIxCzycVPNi .node polygon,#mermaid-svg-AuFmGMIxCzycVPNi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AuFmGMIxCzycVPNi .rough-node .label text,#mermaid-svg-AuFmGMIxCzycVPNi .node .label text,#mermaid-svg-AuFmGMIxCzycVPNi .image-shape .label,#mermaid-svg-AuFmGMIxCzycVPNi .icon-shape .label{text-anchor:middle;}#mermaid-svg-AuFmGMIxCzycVPNi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AuFmGMIxCzycVPNi .rough-node .label,#mermaid-svg-AuFmGMIxCzycVPNi .node .label,#mermaid-svg-AuFmGMIxCzycVPNi .image-shape .label,#mermaid-svg-AuFmGMIxCzycVPNi .icon-shape .label{text-align:center;}#mermaid-svg-AuFmGMIxCzycVPNi .node.clickable{cursor:pointer;}#mermaid-svg-AuFmGMIxCzycVPNi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AuFmGMIxCzycVPNi .arrowheadPath{fill:#333333;}#mermaid-svg-AuFmGMIxCzycVPNi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AuFmGMIxCzycVPNi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AuFmGMIxCzycVPNi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AuFmGMIxCzycVPNi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AuFmGMIxCzycVPNi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AuFmGMIxCzycVPNi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AuFmGMIxCzycVPNi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AuFmGMIxCzycVPNi .cluster text{fill:#333;}#mermaid-svg-AuFmGMIxCzycVPNi .cluster span{color:#333;}#mermaid-svg-AuFmGMIxCzycVPNi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AuFmGMIxCzycVPNi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AuFmGMIxCzycVPNi rect.text{fill:none;stroke-width:0;}#mermaid-svg-AuFmGMIxCzycVPNi .icon-shape,#mermaid-svg-AuFmGMIxCzycVPNi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AuFmGMIxCzycVPNi .icon-shape p,#mermaid-svg-AuFmGMIxCzycVPNi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AuFmGMIxCzycVPNi .icon-shape .label rect,#mermaid-svg-AuFmGMIxCzycVPNi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AuFmGMIxCzycVPNi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AuFmGMIxCzycVPNi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AuFmGMIxCzycVPNi :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    路由注册表

    search_code → GitHub Server

    create_issue → GitHub Server

    send_message → Slack Server

    list_channels → Slack Server

    call_tool search_code

    路由到 GitHub Server

    2.5 路由表 vs DNS vs 服务发现

    可以把路由注册表类比为互联网世界的 DNS:

    维度DNSMCP 路由注册表
    解决什么 域名 → IP 工具名 → Server
    查询方式 解析请求 tools/call 前查表
    更新时机 TTL 过期刷新 tools/list 重新拉取
    缓存 本地 DNS 缓存 Client 内存缓存

    2.6 动态发现的三个好处

  • 免硬编码:新 Server 上线,Agent 无需改代码,重新发现即可用。
  • 随变随适配:Server 更新工具描述或 schema,Client 拉最新清单自动适配。
  • 能力协商:Agent 可以针对每个工具查看 inputSchema,自动构造合法参数。
  • 2.7 一个直觉类比:点菜

    把 Agent 想成顾客,MCP Server 想成餐厅:

  • 初始化:顾客落座,服务员确认"本店营业、支持扫码点餐"。
  • 发现:顾客扫码看菜单(tools/list),知道有哪些菜、每道菜有什么配料(schema)。
  • 注册:顾客在心里记下"这家店的招牌菜是红烧肉"。
  • 调用:顾客下单"红烧肉,少盐"(call_tool),后厨按单出菜(执行并返回结果)。
  • 如果顾客同时点了两家餐厅的外卖,心里得记着"红烧肉来自 A 家、披萨来自 B 家"——这就是路由注册表的作用。

    2.8 核心概念速记表

    概念一句话对应方法
    会话建立 打通与 Server 的通道 initialize
    工具发现 获取可用工具清单 tools/list
    路由注册 建立工具→Server 映射 Client 内部
    工具调用 让 Server 执行工具 tools/call
    结果返回 拿到结构化结果 tools/call 响应

    2.10 发现 vs 调用:一次对比

    维度发现(Discovery)调用(Invocation)
    方法 tools/list tools/call
    频率 低(缓存+通知) 高(每次行动)
    是否可写 只读 可读写
    结果 工具清单 执行结果
    失败影响 能力缺失 任务失败

    2.11 硬编码时代的痛苦

    假设 Agent 要接 3 个外部系统,每个系统 5 个 API,硬编码时代需要:

    • 15 段适配代码。
    • 15 份 API 文档的人工研读。
    • 每次 API 变更都要改代码 + 回归测试。
    • 新增系统 = 重复整套流程。

    MCP 时代:一套 Client,Server 声明即插即用。这就是"N×M → N+M"降维在运行时的体现。

    2.12 动态发现的"运行时才知道"意味着什么

    "运行时才知道有哪些工具"对 Agent 架构有深远影响:

  • Agent 的提示词是动态拼装的:工具清单在每次会话开始时注入,而非写死。
  • 能力即插即用:挂载新 Server 就能给 Agent 加能力,无需改 Agent 代码。
  • 行为可演化:同一 Agent 在不同 Server 配置下表现出不同能力边界。
  • #mermaid-svg-rRs9LNdqwhrBaq2d{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rRs9LNdqwhrBaq2d .error-icon{fill:#552222;}#mermaid-svg-rRs9LNdqwhrBaq2d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rRs9LNdqwhrBaq2d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rRs9LNdqwhrBaq2d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rRs9LNdqwhrBaq2d .marker.cross{stroke:#333333;}#mermaid-svg-rRs9LNdqwhrBaq2d svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rRs9LNdqwhrBaq2d p{margin:0;}#mermaid-svg-rRs9LNdqwhrBaq2d .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d .cluster-label text{fill:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d .cluster-label span{color:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d .cluster-label span p{background-color:transparent;}#mermaid-svg-rRs9LNdqwhrBaq2d .label text,#mermaid-svg-rRs9LNdqwhrBaq2d span{fill:#333;color:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d .node rect,#mermaid-svg-rRs9LNdqwhrBaq2d .node circle,#mermaid-svg-rRs9LNdqwhrBaq2d .node ellipse,#mermaid-svg-rRs9LNdqwhrBaq2d .node polygon,#mermaid-svg-rRs9LNdqwhrBaq2d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rRs9LNdqwhrBaq2d .rough-node .label text,#mermaid-svg-rRs9LNdqwhrBaq2d .node .label text,#mermaid-svg-rRs9LNdqwhrBaq2d .image-shape .label,#mermaid-svg-rRs9LNdqwhrBaq2d .icon-shape .label{text-anchor:middle;}#mermaid-svg-rRs9LNdqwhrBaq2d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rRs9LNdqwhrBaq2d .rough-node .label,#mermaid-svg-rRs9LNdqwhrBaq2d .node .label,#mermaid-svg-rRs9LNdqwhrBaq2d .image-shape .label,#mermaid-svg-rRs9LNdqwhrBaq2d .icon-shape .label{text-align:center;}#mermaid-svg-rRs9LNdqwhrBaq2d .node.clickable{cursor:pointer;}#mermaid-svg-rRs9LNdqwhrBaq2d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rRs9LNdqwhrBaq2d .arrowheadPath{fill:#333333;}#mermaid-svg-rRs9LNdqwhrBaq2d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rRs9LNdqwhrBaq2d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rRs9LNdqwhrBaq2d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rRs9LNdqwhrBaq2d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rRs9LNdqwhrBaq2d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rRs9LNdqwhrBaq2d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rRs9LNdqwhrBaq2d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rRs9LNdqwhrBaq2d .cluster text{fill:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d .cluster span{color:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rRs9LNdqwhrBaq2d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rRs9LNdqwhrBaq2d rect.text{fill:none;stroke-width:0;}#mermaid-svg-rRs9LNdqwhrBaq2d .icon-shape,#mermaid-svg-rRs9LNdqwhrBaq2d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rRs9LNdqwhrBaq2d .icon-shape p,#mermaid-svg-rRs9LNdqwhrBaq2d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rRs9LNdqwhrBaq2d .icon-shape .label rect,#mermaid-svg-rRs9LNdqwhrBaq2d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rRs9LNdqwhrBaq2d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rRs9LNdqwhrBaq2d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rRs9LNdqwhrBaq2d :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Server 配置

    动态发现

    能力地图

    Agent 提示词

    Agent 行为

    2.13 点菜类比的完整版

    把"点菜"类比展开成一张映射表:

    点菜工具调用关键词
    扫码看菜单 tools/list 发现
    记住哪家有什么 路由注册表 注册
    看菜看配料 inputSchema 协商
    下单 tools/call 调用
    后厨出菜 Server 执行 执行
    上菜 返回结果 反馈
    菜品下架 list_changed 通知 变更

    2.14 发现与调用的循环关系

    发现不是一次性的,它与调用构成持续循环:

    #mermaid-svg-xyXxZr45FeOsD4YS{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xyXxZr45FeOsD4YS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xyXxZr45FeOsD4YS .error-icon{fill:#552222;}#mermaid-svg-xyXxZr45FeOsD4YS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xyXxZr45FeOsD4YS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xyXxZr45FeOsD4YS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xyXxZr45FeOsD4YS .marker.cross{stroke:#333333;}#mermaid-svg-xyXxZr45FeOsD4YS svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xyXxZr45FeOsD4YS p{margin:0;}#mermaid-svg-xyXxZr45FeOsD4YS .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-xyXxZr45FeOsD4YS .cluster-label text{fill:#333;}#mermaid-svg-xyXxZr45FeOsD4YS .cluster-label span{color:#333;}#mermaid-svg-xyXxZr45FeOsD4YS .cluster-label span p{background-color:transparent;}#mermaid-svg-xyXxZr45FeOsD4YS .label text,#mermaid-svg-xyXxZr45FeOsD4YS span{fill:#333;color:#333;}#mermaid-svg-xyXxZr45FeOsD4YS .node rect,#mermaid-svg-xyXxZr45FeOsD4YS .node circle,#mermaid-svg-xyXxZr45FeOsD4YS .node ellipse,#mermaid-svg-xyXxZr45FeOsD4YS .node polygon,#mermaid-svg-xyXxZr45FeOsD4YS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xyXxZr45FeOsD4YS .rough-node .label text,#mermaid-svg-xyXxZr45FeOsD4YS .node .label text,#mermaid-svg-xyXxZr45FeOsD4YS .image-shape .label,#mermaid-svg-xyXxZr45FeOsD4YS .icon-shape .label{text-anchor:middle;}#mermaid-svg-xyXxZr45FeOsD4YS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xyXxZr45FeOsD4YS .rough-node .label,#mermaid-svg-xyXxZr45FeOsD4YS .node .label,#mermaid-svg-xyXxZr45FeOsD4YS .image-shape .label,#mermaid-svg-xyXxZr45FeOsD4YS .icon-shape .label{text-align:center;}#mermaid-svg-xyXxZr45FeOsD4YS .node.clickable{cursor:pointer;}#mermaid-svg-xyXxZr45FeOsD4YS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xyXxZr45FeOsD4YS .arrowheadPath{fill:#333333;}#mermaid-svg-xyXxZr45FeOsD4YS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xyXxZr45FeOsD4YS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xyXxZr45FeOsD4YS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xyXxZr45FeOsD4YS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xyXxZr45FeOsD4YS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xyXxZr45FeOsD4YS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xyXxZr45FeOsD4YS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xyXxZr45FeOsD4YS .cluster text{fill:#333;}#mermaid-svg-xyXxZr45FeOsD4YS .cluster span{color:#333;}#mermaid-svg-xyXxZr45FeOsD4YS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xyXxZr45FeOsD4YS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xyXxZr45FeOsD4YS rect.text{fill:none;stroke-width:0;}#mermaid-svg-xyXxZr45FeOsD4YS .icon-shape,#mermaid-svg-xyXxZr45FeOsD4YS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xyXxZr45FeOsD4YS .icon-shape p,#mermaid-svg-xyXxZr45FeOsD4YS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xyXxZr45FeOsD4YS .icon-shape .label rect,#mermaid-svg-xyXxZr45FeOsD4YS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xyXxZr45FeOsD4YS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xyXxZr45FeOsD4YS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xyXxZr45FeOsD4YS :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    新需求

    发现工具

    注册

    调用

    成功

    失败-工具不存在

    任务完成

    2.15 核心概念总结图

    #mermaid-svg-Z0cYnlJo7DIilFRn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Z0cYnlJo7DIilFRn .error-icon{fill:#552222;}#mermaid-svg-Z0cYnlJo7DIilFRn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Z0cYnlJo7DIilFRn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Z0cYnlJo7DIilFRn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Z0cYnlJo7DIilFRn .marker.cross{stroke:#333333;}#mermaid-svg-Z0cYnlJo7DIilFRn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Z0cYnlJo7DIilFRn p{margin:0;}#mermaid-svg-Z0cYnlJo7DIilFRn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn .cluster-label text{fill:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn .cluster-label span{color:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn .cluster-label span p{background-color:transparent;}#mermaid-svg-Z0cYnlJo7DIilFRn .label text,#mermaid-svg-Z0cYnlJo7DIilFRn span{fill:#333;color:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn .node rect,#mermaid-svg-Z0cYnlJo7DIilFRn .node circle,#mermaid-svg-Z0cYnlJo7DIilFRn .node ellipse,#mermaid-svg-Z0cYnlJo7DIilFRn .node polygon,#mermaid-svg-Z0cYnlJo7DIilFRn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Z0cYnlJo7DIilFRn .rough-node .label text,#mermaid-svg-Z0cYnlJo7DIilFRn .node .label text,#mermaid-svg-Z0cYnlJo7DIilFRn .image-shape .label,#mermaid-svg-Z0cYnlJo7DIilFRn .icon-shape .label{text-anchor:middle;}#mermaid-svg-Z0cYnlJo7DIilFRn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Z0cYnlJo7DIilFRn .rough-node .label,#mermaid-svg-Z0cYnlJo7DIilFRn .node .label,#mermaid-svg-Z0cYnlJo7DIilFRn .image-shape .label,#mermaid-svg-Z0cYnlJo7DIilFRn .icon-shape .label{text-align:center;}#mermaid-svg-Z0cYnlJo7DIilFRn .node.clickable{cursor:pointer;}#mermaid-svg-Z0cYnlJo7DIilFRn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Z0cYnlJo7DIilFRn .arrowheadPath{fill:#333333;}#mermaid-svg-Z0cYnlJo7DIilFRn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Z0cYnlJo7DIilFRn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Z0cYnlJo7DIilFRn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z0cYnlJo7DIilFRn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Z0cYnlJo7DIilFRn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z0cYnlJo7DIilFRn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Z0cYnlJo7DIilFRn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Z0cYnlJo7DIilFRn .cluster text{fill:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn .cluster span{color:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Z0cYnlJo7DIilFRn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Z0cYnlJo7DIilFRn rect.text{fill:none;stroke-width:0;}#mermaid-svg-Z0cYnlJo7DIilFRn .icon-shape,#mermaid-svg-Z0cYnlJo7DIilFRn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z0cYnlJo7DIilFRn .icon-shape p,#mermaid-svg-Z0cYnlJo7DIilFRn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Z0cYnlJo7DIilFRn .icon-shape .label rect,#mermaid-svg-Z0cYnlJo7DIilFRn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z0cYnlJo7DIilFRn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Z0cYnlJo7DIilFRn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Z0cYnlJo7DIilFRn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    本篇运行时

    协议定义 26篇

    methods: list/call

    原语: Tools

    initialize 建会话

    tools/list 发现

    注册表 路由

    tools/call 调用

    2.17 工具调用链路的全景图

    把本篇所有概念放进一张图:

    #mermaid-svg-tMF4hEDJQPT0MvrD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tMF4hEDJQPT0MvrD .error-icon{fill:#552222;}#mermaid-svg-tMF4hEDJQPT0MvrD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tMF4hEDJQPT0MvrD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tMF4hEDJQPT0MvrD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tMF4hEDJQPT0MvrD .marker.cross{stroke:#333333;}#mermaid-svg-tMF4hEDJQPT0MvrD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tMF4hEDJQPT0MvrD p{margin:0;}#mermaid-svg-tMF4hEDJQPT0MvrD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD .cluster-label text{fill:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD .cluster-label span{color:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD .cluster-label span p{background-color:transparent;}#mermaid-svg-tMF4hEDJQPT0MvrD .label text,#mermaid-svg-tMF4hEDJQPT0MvrD span{fill:#333;color:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD .node rect,#mermaid-svg-tMF4hEDJQPT0MvrD .node circle,#mermaid-svg-tMF4hEDJQPT0MvrD .node ellipse,#mermaid-svg-tMF4hEDJQPT0MvrD .node polygon,#mermaid-svg-tMF4hEDJQPT0MvrD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tMF4hEDJQPT0MvrD .rough-node .label text,#mermaid-svg-tMF4hEDJQPT0MvrD .node .label text,#mermaid-svg-tMF4hEDJQPT0MvrD .image-shape .label,#mermaid-svg-tMF4hEDJQPT0MvrD .icon-shape .label{text-anchor:middle;}#mermaid-svg-tMF4hEDJQPT0MvrD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tMF4hEDJQPT0MvrD .rough-node .label,#mermaid-svg-tMF4hEDJQPT0MvrD .node .label,#mermaid-svg-tMF4hEDJQPT0MvrD .image-shape .label,#mermaid-svg-tMF4hEDJQPT0MvrD .icon-shape .label{text-align:center;}#mermaid-svg-tMF4hEDJQPT0MvrD .node.clickable{cursor:pointer;}#mermaid-svg-tMF4hEDJQPT0MvrD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tMF4hEDJQPT0MvrD .arrowheadPath{fill:#333333;}#mermaid-svg-tMF4hEDJQPT0MvrD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tMF4hEDJQPT0MvrD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tMF4hEDJQPT0MvrD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tMF4hEDJQPT0MvrD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tMF4hEDJQPT0MvrD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tMF4hEDJQPT0MvrD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tMF4hEDJQPT0MvrD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tMF4hEDJQPT0MvrD .cluster text{fill:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD .cluster span{color:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tMF4hEDJQPT0MvrD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tMF4hEDJQPT0MvrD rect.text{fill:none;stroke-width:0;}#mermaid-svg-tMF4hEDJQPT0MvrD .icon-shape,#mermaid-svg-tMF4hEDJQPT0MvrD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tMF4hEDJQPT0MvrD .icon-shape p,#mermaid-svg-tMF4hEDJQPT0MvrD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tMF4hEDJQPT0MvrD .icon-shape .label rect,#mermaid-svg-tMF4hEDJQPT0MvrD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tMF4hEDJQPT0MvrD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tMF4hEDJQPT0MvrD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tMF4hEDJQPT0MvrD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent

    Client

    注册表

    校验器

    限流器

    审计

    Server A

    Server B

    结果处理

    2.18 本章小结(终版)

    发现与调用是 Agent 工具能力的"两条腿":发现解决"有什么可用",调用解决"怎么用起来"。路由注册表把多 Server 的复杂拓扑收敛为一张可查询的表,让 Agent 的调用从"遍历猜"变成"查表直达"。配套校验、限流、审计、结果处理,构成完整的调用链路。


    第 3 章 四阶段流程全景

    3.1 源文档时序图

    源文档 6.4 给出完整时序图,本篇第 3 章先原样承接并逐段解读,第 4–7 章再分别深拆。

    Slack MCP ServerGitHub MCP Server路由注册表MCP ClientAgent认知层Slack MCP ServerGitHub MCP Server路由注册表MCP ClientAgent认知层#mermaid-svg-x554nxnwWeqOZo8t{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-x554nxnwWeqOZo8t .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-x554nxnwWeqOZo8t .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-x554nxnwWeqOZo8t .error-icon{fill:#552222;}#mermaid-svg-x554nxnwWeqOZo8t .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-x554nxnwWeqOZo8t .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-x554nxnwWeqOZo8t .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-x554nxnwWeqOZo8t .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-x554nxnwWeqOZo8t .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-x554nxnwWeqOZo8t .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-x554nxnwWeqOZo8t .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-x554nxnwWeqOZo8t .marker{fill:#333333;stroke:#333333;}#mermaid-svg-x554nxnwWeqOZo8t .marker.cross{stroke:#333333;}#mermaid-svg-x554nxnwWeqOZo8t svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-x554nxnwWeqOZo8t p{margin:0;}#mermaid-svg-x554nxnwWeqOZo8t .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-x554nxnwWeqOZo8t text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-x554nxnwWeqOZo8t .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-x554nxnwWeqOZo8t .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-x554nxnwWeqOZo8t .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-x554nxnwWeqOZo8t .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-x554nxnwWeqOZo8t #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-x554nxnwWeqOZo8t .sequenceNumber{fill:white;}#mermaid-svg-x554nxnwWeqOZo8t #sequencenumber{fill:#333;}#mermaid-svg-x554nxnwWeqOZo8t #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-x554nxnwWeqOZo8t .messageText{fill:#333;stroke:none;}#mermaid-svg-x554nxnwWeqOZo8t .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-x554nxnwWeqOZo8t .labelText,#mermaid-svg-x554nxnwWeqOZo8t .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-x554nxnwWeqOZo8t .loopText,#mermaid-svg-x554nxnwWeqOZo8t .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-x554nxnwWeqOZo8t .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-x554nxnwWeqOZo8t .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-x554nxnwWeqOZo8t .noteText,#mermaid-svg-x554nxnwWeqOZo8t .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-x554nxnwWeqOZo8t .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-x554nxnwWeqOZo8t .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-x554nxnwWeqOZo8t .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-x554nxnwWeqOZo8t .actorPopupMenu{position:absolute;}#mermaid-svg-x554nxnwWeqOZo8t .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-x554nxnwWeqOZo8t .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-x554nxnwWeqOZo8t .actor-man circle,#mermaid-svg-x554nxnwWeqOZo8t line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-x554nxnwWeqOZo8t :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}阶段1:初始化阶段2:工具发现search_code → ServerAcreate_issue → ServerAsend_message → ServerB阶段3:工具调用执行GitHub API搜索阶段4:工具调用(另一个工具)启动,需要连接工具initialize()支持tools, resources, promptsinitialize()支持tools, resourcestools/list()[search_code, create_issue, list_prs, …]tools/list()[send_message, list_channels, …]注册工具路由表call_tool("search_code", {query:"auth", repo:"myrepo"})查找search_code → ServerAServerAtools/call("search_code", {query:"auth", repo:"myrepo"})结果:找到5个匹配文件返回搜索结果call_tool("send_message", {channel:"查找send_message → ServerBtools/call("send_message", {…})消息已发送返回发送结果

    3.2 阶段 1:初始化——建会话

    Agent 启动后,第一件事是向每个要连接的 Server 发起 initialize:

    • Client → ServerA:initialize()。
    • ServerA 回:支持 tools, resources, prompts(能力声明)。
    • Client → ServerB:initialize()。
    • ServerB 回:支持 tools, resources(注意:ServerB 没有声明 prompts)。

    关键点:每个 Server 的能力集可能不同。Client 在初始化阶段就知道"哪个 Server 能干什么",为后续路由提供依据。

    3.3 阶段 2:工具发现——拉清单

    初始化完成后,Client 逐个向 Server 发 tools/list:

    • ServerA 返回:[search_code, create_issue, list_prs, …]。
    • ServerB 返回:[send_message, list_channels, …]。

    发现结果不只是名字,还包括每个工具的 description 与 inputSchema——这是 Agent 后续"会正确调用"的前提。

    3.4 阶段 3:注册路由——建表

    Client 把发现结果写入路由注册表:

    • search_code → ServerA
    • create_issue → ServerA
    • send_message → ServerB

    从此以后,Client 看到 call_tool("search_code", …) 就知道该找 ServerA,无需再遍历。

    3.5 阶段 4:工具调用——执行

    Agent 发起调用:

  • call_tool("search_code", {query:"auth", repo:"myrepo"})。
  • Client 查注册表 → 找到 ServerA。
  • Client 转发 tools/call("search_code", {…}) 给 ServerA。
  • ServerA 执行 GitHub API 搜索,返回"找到 5 个匹配文件"。
  • Client 把结果回传给 Agent。
  • 再调 send_message 时走同一路径,但路由到 ServerB。

    3.6 四阶段的时序特征

    #mermaid-svg-FSNIzXDAFbsjiQMh{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FSNIzXDAFbsjiQMh .error-icon{fill:#552222;}#mermaid-svg-FSNIzXDAFbsjiQMh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FSNIzXDAFbsjiQMh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FSNIzXDAFbsjiQMh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FSNIzXDAFbsjiQMh .marker.cross{stroke:#333333;}#mermaid-svg-FSNIzXDAFbsjiQMh svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FSNIzXDAFbsjiQMh p{margin:0;}#mermaid-svg-FSNIzXDAFbsjiQMh defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-FSNIzXDAFbsjiQMh g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-FSNIzXDAFbsjiQMh g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-FSNIzXDAFbsjiQMh g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-FSNIzXDAFbsjiQMh g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-FSNIzXDAFbsjiQMh g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-FSNIzXDAFbsjiQMh .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-FSNIzXDAFbsjiQMh .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-FSNIzXDAFbsjiQMh .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-FSNIzXDAFbsjiQMh .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-FSNIzXDAFbsjiQMh .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-FSNIzXDAFbsjiQMh .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-FSNIzXDAFbsjiQMh .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-FSNIzXDAFbsjiQMh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FSNIzXDAFbsjiQMh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FSNIzXDAFbsjiQMh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FSNIzXDAFbsjiQMh .edgeLabel .label text{fill:#333;}#mermaid-svg-FSNIzXDAFbsjiQMh .label div .edgeLabel{color:#333;}#mermaid-svg-FSNIzXDAFbsjiQMh .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-FSNIzXDAFbsjiQMh .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-FSNIzXDAFbsjiQMh .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-FSNIzXDAFbsjiQMh .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-FSNIzXDAFbsjiQMh .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-FSNIzXDAFbsjiQMh .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FSNIzXDAFbsjiQMh .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FSNIzXDAFbsjiQMh #statediagram-barbEnd{fill:#333333;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FSNIzXDAFbsjiQMh .cluster-label,#mermaid-svg-FSNIzXDAFbsjiQMh .nodeLabel{color:#131300;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-FSNIzXDAFbsjiQMh .note-edge{stroke-dasharray:5;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-note text{fill:black;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram-note .nodeLabel{color:black;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagram .edgeLabel{color:red;}#mermaid-svg-FSNIzXDAFbsjiQMh #dependencyStart,#mermaid-svg-FSNIzXDAFbsjiQMh #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-FSNIzXDAFbsjiQMh .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FSNIzXDAFbsjiQMh :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    initialize 成功

    tools/list 返回

    注册表就绪

    新工具上线需重新发现

    会话关闭

    初始化

    发现

    注册

    调用

    3.7 四阶段各自的失败点

    阶段典型失败后果
    初始化 Server 不支持协议版本 无法建会话
    发现 tools/list 超时 工具清单不全
    注册 工具名冲突 路由错乱
    调用 参数不符合 schema 调用失败

    3.8 阶段耗时参考

    阶段典型耗时优化手段
    初始化 50–200ms/Server 并行 initialize
    发现 10–50ms/Server 缓存清单
    注册 <1ms 哈希表
    调用 取决于 Server 异步/批处理

    3.9 四阶段全景速记

    初始化建通道、发现拉清单、注册建路由、调用做执行——发现一次、调用多次是常态:Agent 启动时完成 1–3 阶段,运行中反复执行第 4 阶段。

    3.11 阶段 1 深挖:初始化做了什么

    initialize 不只是"打个招呼",它在交换三样东西:

  • 协议版本:Client 与 Server 各报支持的版本,取交集。
  • 能力声明:Server 告诉 Client 自己支持哪些原语(tools/resources/prompts)与特性(如流式进度)。
  • 实现信息:Client 与 Server 各报名称与版本,便于排障。
  • ServerClientServerClient#mermaid-svg-NyAqQVUMHr9tTc0b{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NyAqQVUMHr9tTc0b .error-icon{fill:#552222;}#mermaid-svg-NyAqQVUMHr9tTc0b .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NyAqQVUMHr9tTc0b .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NyAqQVUMHr9tTc0b .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NyAqQVUMHr9tTc0b .marker.cross{stroke:#333333;}#mermaid-svg-NyAqQVUMHr9tTc0b svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NyAqQVUMHr9tTc0b p{margin:0;}#mermaid-svg-NyAqQVUMHr9tTc0b .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NyAqQVUMHr9tTc0b text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-NyAqQVUMHr9tTc0b .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-NyAqQVUMHr9tTc0b .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-NyAqQVUMHr9tTc0b #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-NyAqQVUMHr9tTc0b .sequenceNumber{fill:white;}#mermaid-svg-NyAqQVUMHr9tTc0b #sequencenumber{fill:#333;}#mermaid-svg-NyAqQVUMHr9tTc0b #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-NyAqQVUMHr9tTc0b .messageText{fill:#333;stroke:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NyAqQVUMHr9tTc0b .labelText,#mermaid-svg-NyAqQVUMHr9tTc0b .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .loopText,#mermaid-svg-NyAqQVUMHr9tTc0b .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-NyAqQVUMHr9tTc0b .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-NyAqQVUMHr9tTc0b .noteText,#mermaid-svg-NyAqQVUMHr9tTc0b .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-NyAqQVUMHr9tTc0b .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NyAqQVUMHr9tTc0b .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NyAqQVUMHr9tTc0b .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NyAqQVUMHr9tTc0b .actorPopupMenu{position:absolute;}#mermaid-svg-NyAqQVUMHr9tTc0b .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-NyAqQVUMHr9tTc0b .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NyAqQVUMHr9tTc0b .actor-man circle,#mermaid-svg-NyAqQVUMHr9tTc0b line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-NyAqQVUMHr9tTc0b :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}会话进入就绪态initialize(protocolVersion, capabilities, clientInfo)InitializeResult(protocolVersion, capabilities, serverInfo)notifications/initialized

    3.12 阶段 1 深挖:能力差异的意义

    源时序图中 ServerA 声明了 prompts、ServerB 没有——这个细节很重要:

    • Client 会为 ServerA 开放 prompts 相关能力(prompts/list、prompts/get)。
    • 对 ServerB,Client 不会展示"模板调用"这类功能,避免 Agent 误用。

    能力协商的本质是避免协议双方互相假设:一切以声明为准。

    3.13 阶段 1 深挖:多个 Server 并行初始化

    多 Server 场景下,初始化应并行而非串行:

    #mermaid-svg-mXjNPB1QoVVxVxjX{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mXjNPB1QoVVxVxjX .error-icon{fill:#552222;}#mermaid-svg-mXjNPB1QoVVxVxjX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mXjNPB1QoVVxVxjX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mXjNPB1QoVVxVxjX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mXjNPB1QoVVxVxjX .marker.cross{stroke:#333333;}#mermaid-svg-mXjNPB1QoVVxVxjX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mXjNPB1QoVVxVxjX p{margin:0;}#mermaid-svg-mXjNPB1QoVVxVxjX .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX .cluster-label text{fill:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX .cluster-label span{color:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX .cluster-label span p{background-color:transparent;}#mermaid-svg-mXjNPB1QoVVxVxjX .label text,#mermaid-svg-mXjNPB1QoVVxVxjX span{fill:#333;color:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX .node rect,#mermaid-svg-mXjNPB1QoVVxVxjX .node circle,#mermaid-svg-mXjNPB1QoVVxVxjX .node ellipse,#mermaid-svg-mXjNPB1QoVVxVxjX .node polygon,#mermaid-svg-mXjNPB1QoVVxVxjX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mXjNPB1QoVVxVxjX .rough-node .label text,#mermaid-svg-mXjNPB1QoVVxVxjX .node .label text,#mermaid-svg-mXjNPB1QoVVxVxjX .image-shape .label,#mermaid-svg-mXjNPB1QoVVxVxjX .icon-shape .label{text-anchor:middle;}#mermaid-svg-mXjNPB1QoVVxVxjX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mXjNPB1QoVVxVxjX .rough-node .label,#mermaid-svg-mXjNPB1QoVVxVxjX .node .label,#mermaid-svg-mXjNPB1QoVVxVxjX .image-shape .label,#mermaid-svg-mXjNPB1QoVVxVxjX .icon-shape .label{text-align:center;}#mermaid-svg-mXjNPB1QoVVxVxjX .node.clickable{cursor:pointer;}#mermaid-svg-mXjNPB1QoVVxVxjX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mXjNPB1QoVVxVxjX .arrowheadPath{fill:#333333;}#mermaid-svg-mXjNPB1QoVVxVxjX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mXjNPB1QoVVxVxjX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mXjNPB1QoVVxVxjX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mXjNPB1QoVVxVxjX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mXjNPB1QoVVxVxjX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mXjNPB1QoVVxVxjX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mXjNPB1QoVVxVxjX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mXjNPB1QoVVxVxjX .cluster text{fill:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX .cluster span{color:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mXjNPB1QoVVxVxjX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mXjNPB1QoVVxVxjX rect.text{fill:none;stroke-width:0;}#mermaid-svg-mXjNPB1QoVVxVxjX .icon-shape,#mermaid-svg-mXjNPB1QoVVxVxjX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mXjNPB1QoVVxVxjX .icon-shape p,#mermaid-svg-mXjNPB1QoVVxVxjX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mXjNPB1QoVVxVxjX .icon-shape .label rect,#mermaid-svg-mXjNPB1QoVVxVxjX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mXjNPB1QoVVxVxjX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mXjNPB1QoVVxVxjX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mXjNPB1QoVVxVxjX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent 启动

    并行 initialize

    GitHub 就绪

    Slack 就绪

    数据库就绪

    全部就绪

    并行可把"3 × 100ms"压到"约 100ms"。但注意:部分 Server 初始化失败不应阻断整体启动,失败者标记降级即可。

    3.14 阶段 1 深挖:初始化失败的处理

    失败原因处理
    版本不兼容 提示升级 Client 或 Server
    认证失败 引导重新授权
    Server 不存在 从连接清单移除并告警
    网络不可达 标记离线,定时重试

    3.15 阶段 2 深挖:发现的内容不止名字

    tools/list 返回的每个工具都带完整元信息,Agent 的"认知"依赖这些元信息:

    • name:调用标识。
    • description:用途说明,是 Agent 选型依据。
    • inputSchema:参数结构,是 Agent 填参依据。
    • outputSchema(可选):返回结构,帮助 Agent 预判结果。
    • annotations(可选):危险程度、只读性等标注。

    3.16 阶段 2 深挖:发现结果如何变成 Agent 的"能力地图"

    Agent 看到发现结果后,会把它折叠进自己的提示词/上下文:“当前可用工具:GitHub 提供 search_code、create_issue……;Slack 提供 send_message……”。这就是 Agent"知道自己会什么"的来源——没有发现,Agent 就是"无手之人"。

    3.17 阶段 2 深挖:发现的频率控制

    策略适用场景代价
    启动一次 工具基本不变 可能错过变更
    定时刷新 工具会变化 额外请求
    通知驱动 支持变更通知的 Server 最省
    失败触发 调用报不存在 被动兜底

    3.18 阶段 3 深挖:注册表与"会话"的绑定

    路由注册表的值里为什么必须带会话句柄?因为同一 Server 可能被同一个 Client 以多个身份/权限建了多个会话:

    search_code → {server: GitHub, session: admin-s1}
    search_code → {server: GitHub, session: guest-s2}

    Agent 用什么身份说话,就路由到哪个会话——注册表是"工具 + 身份"的复合路由。

    3.19 阶段 3 深挖:注册时机与原子性

    注册应保证原子性:要么全部工具注册成功,要么回滚。避免出现"注册了一半,Agent 查表发现工具不完整"的中间态。实践上:先构建完整映射,再一次性替换旧表。

    3.20 阶段 4 深挖:Agent 如何决定"调哪个工具"

    Agent 不是随机选工具,而是依据任务与工具描述做匹配:

  • 任务:“看看代码里 auth 怎么实现的”。
  • 候选:search_code(搜代码)、create_issue(建问题)、list_pulls(列 PR)。
  • 匹配:search_code 的 description 最贴合 → 选中。
  • 填参:按 inputSchema 填 query=“auth”、repo=“myrepo”。
  • 这就是"能力协商"的完整闭环——描述写得越好,匹配越准。

    3.21 阶段 4 深挖:一次调用的完整生命周期

    #mermaid-svg-3FsNswZOiHI6wkv8{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3FsNswZOiHI6wkv8 .error-icon{fill:#552222;}#mermaid-svg-3FsNswZOiHI6wkv8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3FsNswZOiHI6wkv8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3FsNswZOiHI6wkv8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3FsNswZOiHI6wkv8 .marker.cross{stroke:#333333;}#mermaid-svg-3FsNswZOiHI6wkv8 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3FsNswZOiHI6wkv8 p{margin:0;}#mermaid-svg-3FsNswZOiHI6wkv8 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-3FsNswZOiHI6wkv8 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-3FsNswZOiHI6wkv8 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-3FsNswZOiHI6wkv8 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-3FsNswZOiHI6wkv8 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-3FsNswZOiHI6wkv8 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-3FsNswZOiHI6wkv8 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-3FsNswZOiHI6wkv8 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-3FsNswZOiHI6wkv8 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-3FsNswZOiHI6wkv8 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-3FsNswZOiHI6wkv8 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-3FsNswZOiHI6wkv8 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-3FsNswZOiHI6wkv8 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-3FsNswZOiHI6wkv8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3FsNswZOiHI6wkv8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3FsNswZOiHI6wkv8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3FsNswZOiHI6wkv8 .edgeLabel .label text{fill:#333;}#mermaid-svg-3FsNswZOiHI6wkv8 .label div .edgeLabel{color:#333;}#mermaid-svg-3FsNswZOiHI6wkv8 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-3FsNswZOiHI6wkv8 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-3FsNswZOiHI6wkv8 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-3FsNswZOiHI6wkv8 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-3FsNswZOiHI6wkv8 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-3FsNswZOiHI6wkv8 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3FsNswZOiHI6wkv8 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3FsNswZOiHI6wkv8 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3FsNswZOiHI6wkv8 .cluster-label,#mermaid-svg-3FsNswZOiHI6wkv8 .nodeLabel{color:#131300;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-3FsNswZOiHI6wkv8 .note-edge{stroke-dasharray:5;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-note text{fill:black;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagram .edgeLabel{color:red;}#mermaid-svg-3FsNswZOiHI6wkv8 #dependencyStart,#mermaid-svg-3FsNswZOiHI6wkv8 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-3FsNswZOiHI6wkv8 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3FsNswZOiHI6wkv8 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    合法

    不合法

    返回

    超时

    构造参数

    本地校验

    查注册表

    修正参数

    转发Server

    等待结果

    处理结果

    超时处理

    重试或放弃

    3.22 阶段 4 深挖:结果回传的两种形态

  • 文本结果:直接给 Agent 阅读(如"找到 5 个匹配文件")。
  • 结构化结果:JSON/表格,Agent 可继续程序化处理。
  • 资源引用:返回 resource URI,Agent 需要再读一次。
  • Agent 依据结果类型决定下一步:文本 → 融入推理;结构化 → 可计算;资源引用 → 二次读取。

    3.23 四阶段与"思考-行动"闭环的映射

    把四阶段映射到 Agent 的宏观闭环(感知-思考-行动-反馈):

    Agent 闭环四阶段说明
    思考 工具选择 Agent 决定用什么工具
    行动 调用 tools/call 执行
    反馈 结果处理 结果回流推理
    感知 发现 工具清单即"环境感知"

    3.24 四阶段的性能预算

    一次典型调用(本地 stdio Server)的总延迟构成:

    • 初始化(仅首次):50–200ms。
    • 查注册表:<1ms。
    • 参数校验:<1ms。
    • 网络/进程通信:1–5ms。
    • Server 执行:取决于业务(1ms 到分钟级)。
    • 结果序列化:<1ms。

    优化杠杆在 Server 执行本身,协议层的开销已经很小。

    3.25 四阶段的常见误区

    误区真相
    每次调用都重新发现 发现一次,缓存 + 通知驱动刷新
    注册表是永久不变的 工具会变,需失效机制
    initialize 只是握手 它还在交换能力与版本
    参数不校验直接转发 校验前置,失败本地拦截

    3.27 阶段 1 进阶:初始化与认证

    远程 Server 的 initialize 往往伴随认证:

    ServerClientServerClient#mermaid-svg-PWINVUFGUehv90oL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PWINVUFGUehv90oL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PWINVUFGUehv90oL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PWINVUFGUehv90oL .error-icon{fill:#552222;}#mermaid-svg-PWINVUFGUehv90oL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PWINVUFGUehv90oL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PWINVUFGUehv90oL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PWINVUFGUehv90oL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PWINVUFGUehv90oL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PWINVUFGUehv90oL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PWINVUFGUehv90oL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PWINVUFGUehv90oL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PWINVUFGUehv90oL .marker.cross{stroke:#333333;}#mermaid-svg-PWINVUFGUehv90oL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PWINVUFGUehv90oL p{margin:0;}#mermaid-svg-PWINVUFGUehv90oL .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-PWINVUFGUehv90oL text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-PWINVUFGUehv90oL .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-PWINVUFGUehv90oL .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-PWINVUFGUehv90oL .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-PWINVUFGUehv90oL .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-PWINVUFGUehv90oL #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-PWINVUFGUehv90oL .sequenceNumber{fill:white;}#mermaid-svg-PWINVUFGUehv90oL #sequencenumber{fill:#333;}#mermaid-svg-PWINVUFGUehv90oL #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-PWINVUFGUehv90oL .messageText{fill:#333;stroke:none;}#mermaid-svg-PWINVUFGUehv90oL .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-PWINVUFGUehv90oL .labelText,#mermaid-svg-PWINVUFGUehv90oL .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-PWINVUFGUehv90oL .loopText,#mermaid-svg-PWINVUFGUehv90oL .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-PWINVUFGUehv90oL .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-PWINVUFGUehv90oL .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-PWINVUFGUehv90oL .noteText,#mermaid-svg-PWINVUFGUehv90oL .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-PWINVUFGUehv90oL .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-PWINVUFGUehv90oL .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-PWINVUFGUehv90oL .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-PWINVUFGUehv90oL .actorPopupMenu{position:absolute;}#mermaid-svg-PWINVUFGUehv90oL .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-PWINVUFGUehv90oL .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-PWINVUFGUehv90oL .actor-man circle,#mermaid-svg-PWINVUFGUehv90oL line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-PWINVUFGUehv90oL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}initialize(无凭证)401/要求认证弹授权流程/OAuthinitialize(带token)就绪

    认证失败要有清晰引导,而不是神秘报错。

    3.28 阶段 2 进阶:发现与能力地图的生成

    发现结果生成"能力地图"的完整过程:

  • 拉取所有 Server 的 tools/list。
  • 合并、去重、冲突处理。
  • 按权限过滤。
  • 生成 Agent 友好的清单(分层/搜索)。
  • 注入 Agent 上下文。
  • 3.29 阶段 3 进阶:注册表与"默认 Server"

    无冲突时,同名工具可设默认 Server + 优先级。注册表支持:

    • 精确匹配(工具名唯一)。
    • 前缀匹配(namespace.tool)。
    • 默认路由(未指定时)。

    3.30 阶段 4 进阶:调用结果的四种走向

    结果Agent 下一步
    成功(文本) 融入推理继续
    成功(结构化) 程序化处理
    业务错误(isError) 修正重试/换工具
    系统错误 上报/降级

    3.31 四阶段的工程实现分工

    角色负责
    Agent 工具选择与参数意图
    Client 发现、注册、路由、校验
    注册表 工具→Server 映射
    Server 执行与返回

    3.32 四阶段的 SLA 参考

    阶段SLA 目标
    初始化 99.9% 成功
    发现 99.9%(缓存兜底)
    注册 100%(内存操作)
    调用 99.5%(按工具)

    3.33 本章小结(终版)

    四阶段是工具能力的完整生命周期:初始化建通道、发现拉清单、注册建路由、调用做执行。深挖覆盖初始化交换内容、能力差异、并行初始化、认证、能力地图生成、默认路由、结果走向、分工、SLA——源时序图的每一步都能落到工程实践。


    第 4 章 路由注册表深拆

    4.1 路由注册表的职责

    路由注册表是 Client 内部的组件,核心职责只有一个:给定工具名,返回该工具所属的 Server。它是四阶段中"注册"阶段的产物、"调用"阶段的前置。

    #mermaid-svg-Sn4EDZNtUjNEAVN0{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .error-icon{fill:#552222;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .marker.cross{stroke:#333333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 p{margin:0;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .cluster-label text{fill:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .cluster-label span{color:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .cluster-label span p{background-color:transparent;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .label text,#mermaid-svg-Sn4EDZNtUjNEAVN0 span{fill:#333;color:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .node rect,#mermaid-svg-Sn4EDZNtUjNEAVN0 .node circle,#mermaid-svg-Sn4EDZNtUjNEAVN0 .node ellipse,#mermaid-svg-Sn4EDZNtUjNEAVN0 .node polygon,#mermaid-svg-Sn4EDZNtUjNEAVN0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .rough-node .label text,#mermaid-svg-Sn4EDZNtUjNEAVN0 .node .label text,#mermaid-svg-Sn4EDZNtUjNEAVN0 .image-shape .label,#mermaid-svg-Sn4EDZNtUjNEAVN0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .rough-node .label,#mermaid-svg-Sn4EDZNtUjNEAVN0 .node .label,#mermaid-svg-Sn4EDZNtUjNEAVN0 .image-shape .label,#mermaid-svg-Sn4EDZNtUjNEAVN0 .icon-shape .label{text-align:center;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .node.clickable{cursor:pointer;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .arrowheadPath{fill:#333333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Sn4EDZNtUjNEAVN0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Sn4EDZNtUjNEAVN0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Sn4EDZNtUjNEAVN0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .cluster text{fill:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .cluster span{color:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Sn4EDZNtUjNEAVN0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .icon-shape,#mermaid-svg-Sn4EDZNtUjNEAVN0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .icon-shape p,#mermaid-svg-Sn4EDZNtUjNEAVN0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .icon-shape .label rect,#mermaid-svg-Sn4EDZNtUjNEAVN0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Sn4EDZNtUjNEAVN0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Sn4EDZNtUjNEAVN0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Sn4EDZNtUjNEAVN0 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    tools/list 结果

    注册表构建

    工具→Server 映射

    call_tool 查表

    路由到目标 Server

    4.2 注册表的数据结构

    最简单实现是哈希表:

    search_code → {server: GitHub, session: s1}
    create_issue → {server: GitHub, session: s1}
    send_message → {server: Slack, session: s2}
    list_channels → {server: Slack, session: s2}

    值里不仅要记 Server 标识,还要记会话句柄(因为同一个 Server 可能有多个会话)。

    4.3 注册流程

    #mermaid-svg-2IIw3a9iRh9XTV9o{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2IIw3a9iRh9XTV9o .error-icon{fill:#552222;}#mermaid-svg-2IIw3a9iRh9XTV9o .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2IIw3a9iRh9XTV9o .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2IIw3a9iRh9XTV9o .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2IIw3a9iRh9XTV9o .marker.cross{stroke:#333333;}#mermaid-svg-2IIw3a9iRh9XTV9o svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2IIw3a9iRh9XTV9o p{margin:0;}#mermaid-svg-2IIw3a9iRh9XTV9o .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o .cluster-label text{fill:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o .cluster-label span{color:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o .cluster-label span p{background-color:transparent;}#mermaid-svg-2IIw3a9iRh9XTV9o .label text,#mermaid-svg-2IIw3a9iRh9XTV9o span{fill:#333;color:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o .node rect,#mermaid-svg-2IIw3a9iRh9XTV9o .node circle,#mermaid-svg-2IIw3a9iRh9XTV9o .node ellipse,#mermaid-svg-2IIw3a9iRh9XTV9o .node polygon,#mermaid-svg-2IIw3a9iRh9XTV9o .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2IIw3a9iRh9XTV9o .rough-node .label text,#mermaid-svg-2IIw3a9iRh9XTV9o .node .label text,#mermaid-svg-2IIw3a9iRh9XTV9o .image-shape .label,#mermaid-svg-2IIw3a9iRh9XTV9o .icon-shape .label{text-anchor:middle;}#mermaid-svg-2IIw3a9iRh9XTV9o .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2IIw3a9iRh9XTV9o .rough-node .label,#mermaid-svg-2IIw3a9iRh9XTV9o .node .label,#mermaid-svg-2IIw3a9iRh9XTV9o .image-shape .label,#mermaid-svg-2IIw3a9iRh9XTV9o .icon-shape .label{text-align:center;}#mermaid-svg-2IIw3a9iRh9XTV9o .node.clickable{cursor:pointer;}#mermaid-svg-2IIw3a9iRh9XTV9o .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2IIw3a9iRh9XTV9o .arrowheadPath{fill:#333333;}#mermaid-svg-2IIw3a9iRh9XTV9o .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2IIw3a9iRh9XTV9o .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2IIw3a9iRh9XTV9o .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2IIw3a9iRh9XTV9o .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2IIw3a9iRh9XTV9o .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2IIw3a9iRh9XTV9o .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2IIw3a9iRh9XTV9o .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2IIw3a9iRh9XTV9o .cluster text{fill:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o .cluster span{color:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2IIw3a9iRh9XTV9o .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2IIw3a9iRh9XTV9o rect.text{fill:none;stroke-width:0;}#mermaid-svg-2IIw3a9iRh9XTV9o .icon-shape,#mermaid-svg-2IIw3a9iRh9XTV9o .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2IIw3a9iRh9XTV9o .icon-shape p,#mermaid-svg-2IIw3a9iRh9XTV9o .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2IIw3a9iRh9XTV9o .icon-shape .label rect,#mermaid-svg-2IIw3a9iRh9XTV9o .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2IIw3a9iRh9XTV9o .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2IIw3a9iRh9XTV9o .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2IIw3a9iRh9XTV9o :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    tools/list 返回

    工具名已存在?

    写入映射

    来自同一 Server?

    更新 schema/描述

    冲突处理: 前缀/优先级/告警

    注册完成

    4.4 工具名冲突处理

    多 Server 场景下,"同名工具"并不罕见(例如 GitHub 和 GitLab 都有 list_repos)。处理策略:

  • 命名空间前缀:github.list_repos / gitlab.list_repos。
  • 优先级路由:同名时按配置优先级选 Server。
  • 冲突告警:记录日志,提示用户或 Agent 显式指定。
  • 4.5 注册表的更新时机

    注册表不是一次建好就永不变。以下时机需要刷新:

    • Server 推送 notifications/tools/list_changed。
    • 定时重新 tools/list(长驻会话定期刷新)。
    • 调用失败后主动重新发现(怀疑清单过期)。

    4.6 缓存与失效

    发现结果缓存可省大量往返,但必须配套失效机制:

    失效触发处理
    Server 通知变更 立即重新拉取
    定时过期 TTL 到期刷新
    调用报 MethodNotFound 刷新后重试一次

    4.7 注册表与权限的联动

    注册表还应记录工具的"危险等级":

    delete_issue → {server: GitHub, destructive: true}
    search_code → {server: GitHub, destructive: false}

    调用 destructive 工具前,Client 可触发二次确认或策略拦截(详见 8 章安全部分)。

    4.8 注册表的可观测性

    工程上建议对注册表打点:

    • 工具总数、Server 数。
    • 每次查表的命中率。
    • 冲突次数、刷新次数。
    • 未命中(查不到工具)的错误次数——这是 Agent 幻觉调用工具的前兆。

    4.9 注册表实现示例

    class ToolRegistry:
    def __init__(self):
    self._map = {} # tool_name -> (server, session, meta)

    def register(self, tool_name, server, session, meta):
    if tool_name in self._map and self._map[tool_name][0] != server:
    self._handle_conflict(tool_name, server)
    self._map[tool_name] = (server, session, meta)

    def lookup(self, tool_name):
    return self._map.get(tool_name)

    def refresh(self, server, tools):
    for t in tools:
    self.register(t.name, server, server.session, t.meta)

    4.10 注册表性能

    查表是 O(1) 哈希查找,性能无忧;瓶颈在"建表"(发现)与"失效刷新"。因此工程重点是控制发现频率,而不是优化查表本身。

    4.12 注册表的数据模型(完整版)

    生产级注册表条目应包含:

    {
    "tool_name": "create_issue",
    "server": "github-server",
    "session_id": "s1",
    "meta": {
    "description": "创建 GitHub Issue",
    "input_schema": { "…": "…" },
    "destructive": false,
    "read_only": false,
    "timeout_ms": 30000,
    "idempotent": true,
    "requires_confirm": false
    }
    }

    meta 里的标注不只是给 Client 看,也是给 Agent 的安全提示——destructive=true 的工具,Agent 在规划时就应更谨慎。

    4.13 注册表的三种实现形态

    形态特点适用
    内存哈希表 最快,进程内 单 Client
    分布式 KV 跨进程共享 多 Client 复用发现结果
    带版本号快照 可回滚 需要灰度/回滚的场景

    4.14 注册表与"工具编排"的区别

    • 注册表:静态映射,回答"工具在哪个 Server"。
    • 编排:动态决策,回答"这次任务先调哪个、调完调哪个"。

    不要把两者混为一谈:注册表是基础设施,编排是 Agent 智能。编排层查注册表做路由,注册表不参与任务决策。

    4.15 冲突处理实战:前缀 vs 显式选择

    #mermaid-svg-3dKYry8e8x8XaX5e{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3dKYry8e8x8XaX5e .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3dKYry8e8x8XaX5e .error-icon{fill:#552222;}#mermaid-svg-3dKYry8e8x8XaX5e .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3dKYry8e8x8XaX5e .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3dKYry8e8x8XaX5e .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3dKYry8e8x8XaX5e .marker.cross{stroke:#333333;}#mermaid-svg-3dKYry8e8x8XaX5e svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3dKYry8e8x8XaX5e p{margin:0;}#mermaid-svg-3dKYry8e8x8XaX5e .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3dKYry8e8x8XaX5e .cluster-label text{fill:#333;}#mermaid-svg-3dKYry8e8x8XaX5e .cluster-label span{color:#333;}#mermaid-svg-3dKYry8e8x8XaX5e .cluster-label span p{background-color:transparent;}#mermaid-svg-3dKYry8e8x8XaX5e .label text,#mermaid-svg-3dKYry8e8x8XaX5e span{fill:#333;color:#333;}#mermaid-svg-3dKYry8e8x8XaX5e .node rect,#mermaid-svg-3dKYry8e8x8XaX5e .node circle,#mermaid-svg-3dKYry8e8x8XaX5e .node ellipse,#mermaid-svg-3dKYry8e8x8XaX5e .node polygon,#mermaid-svg-3dKYry8e8x8XaX5e .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3dKYry8e8x8XaX5e .rough-node .label text,#mermaid-svg-3dKYry8e8x8XaX5e .node .label text,#mermaid-svg-3dKYry8e8x8XaX5e .image-shape .label,#mermaid-svg-3dKYry8e8x8XaX5e .icon-shape .label{text-anchor:middle;}#mermaid-svg-3dKYry8e8x8XaX5e .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3dKYry8e8x8XaX5e .rough-node .label,#mermaid-svg-3dKYry8e8x8XaX5e .node .label,#mermaid-svg-3dKYry8e8x8XaX5e .image-shape .label,#mermaid-svg-3dKYry8e8x8XaX5e .icon-shape .label{text-align:center;}#mermaid-svg-3dKYry8e8x8XaX5e .node.clickable{cursor:pointer;}#mermaid-svg-3dKYry8e8x8XaX5e .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3dKYry8e8x8XaX5e .arrowheadPath{fill:#333333;}#mermaid-svg-3dKYry8e8x8XaX5e .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3dKYry8e8x8XaX5e .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3dKYry8e8x8XaX5e .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3dKYry8e8x8XaX5e .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3dKYry8e8x8XaX5e .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3dKYry8e8x8XaX5e .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3dKYry8e8x8XaX5e .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3dKYry8e8x8XaX5e .cluster text{fill:#333;}#mermaid-svg-3dKYry8e8x8XaX5e .cluster span{color:#333;}#mermaid-svg-3dKYry8e8x8XaX5e div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3dKYry8e8x8XaX5e .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3dKYry8e8x8XaX5e rect.text{fill:none;stroke-width:0;}#mermaid-svg-3dKYry8e8x8XaX5e .icon-shape,#mermaid-svg-3dKYry8e8x8XaX5e .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3dKYry8e8x8XaX5e .icon-shape p,#mermaid-svg-3dKYry8e8x8XaX5e .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3dKYry8e8x8XaX5e .icon-shape .label rect,#mermaid-svg-3dKYry8e8x8XaX5e .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3dKYry8e8x8XaX5e .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3dKYry8e8x8XaX5e .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3dKYry8e8x8XaX5e :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    发现同名工具

    可加前缀?

    github.list_repos

    自动消除冲突

    可配置优先级?

    按优先级路由

    告警 + Agent 显式选择

    4.16 注册表的失效刷新流程

    注册表ClientServer注册表ClientServer#mermaid-svg-nvVRcZV1mGxWcnqi{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nvVRcZV1mGxWcnqi .error-icon{fill:#552222;}#mermaid-svg-nvVRcZV1mGxWcnqi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nvVRcZV1mGxWcnqi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nvVRcZV1mGxWcnqi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nvVRcZV1mGxWcnqi .marker.cross{stroke:#333333;}#mermaid-svg-nvVRcZV1mGxWcnqi svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nvVRcZV1mGxWcnqi p{margin:0;}#mermaid-svg-nvVRcZV1mGxWcnqi .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nvVRcZV1mGxWcnqi text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nvVRcZV1mGxWcnqi .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-nvVRcZV1mGxWcnqi .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-nvVRcZV1mGxWcnqi #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-nvVRcZV1mGxWcnqi .sequenceNumber{fill:white;}#mermaid-svg-nvVRcZV1mGxWcnqi #sequencenumber{fill:#333;}#mermaid-svg-nvVRcZV1mGxWcnqi #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-nvVRcZV1mGxWcnqi .messageText{fill:#333;stroke:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nvVRcZV1mGxWcnqi .labelText,#mermaid-svg-nvVRcZV1mGxWcnqi .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .loopText,#mermaid-svg-nvVRcZV1mGxWcnqi .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nvVRcZV1mGxWcnqi .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-nvVRcZV1mGxWcnqi .noteText,#mermaid-svg-nvVRcZV1mGxWcnqi .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-nvVRcZV1mGxWcnqi .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nvVRcZV1mGxWcnqi .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nvVRcZV1mGxWcnqi .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nvVRcZV1mGxWcnqi .actorPopupMenu{position:absolute;}#mermaid-svg-nvVRcZV1mGxWcnqi .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-nvVRcZV1mGxWcnqi .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nvVRcZV1mGxWcnqi .actor-man circle,#mermaid-svg-nvVRcZV1mGxWcnqi line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-nvVRcZV1mGxWcnqi :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}notifications/tools/list_changed标记该 Server 清单过期tools/list(增量)变更后的工具集更新映射刷新完成

    4.17 注册表与可观测性打点

    建议对注册表打以下指标:

    • 工具总数、Server 数、会话数。
    • 查表命中率(未命中往往是幻觉调用的信号)。
    • 冲突次数、刷新次数、失效次数。
    • 平均查表耗时(正常应 <1ms,若升高查哈希退化)。

    4.18 注册表的安全设计

  • 工具访问控制:未授权工具的调用直接拒绝。
  • 会话隔离:不同身份会话持有不同注册表。
  • 审计:destructive 工具的路由与调用全记录。
  • 防篡改:注册表只允许 Client 内部写入。
  • 4.19 注册表与多 Server 的故障联动

    某 Server 熔断后,注册表应把该 Server 的工具标记为"不可用":

    • 查表命中但 Server 不可用 → 返回"暂不可用"而非路由失败。
    • 熔断恢复后自动恢复可用性。
    • 降级策略:同名工具可路由到备用 Server。

    4.21 注册表的查询 API

    Client 给上层(编排层/Agent)暴露的典型查询:

    class ToolRegistry:
    def list_servers(self) > list[str]: ...
    def list_tools(self, server=None) > list[str]: ...
    def lookup(self, tool_name) > RouteInfo | None: ...
    def search_by_keyword(self, keyword) > list[RouteInfo]: ...
    def is_destructive(self, tool_name) > bool: ...
    def status(self, server) > ServerStatus: ...

    search_by_keyword 是"工具搜索"的底层支撑,供 Agent 在工具很多时做描述级检索。

    4.22 注册表与工具描述的管理

    注册表里的描述不应只来自 Server,还可叠加平台层增强:

    • Server 原描述 + 平台补充(示例、常见坑)。
    • 按 Agent 画像裁剪(运维 Agent 只看运维相关)。
    • 统一去重、统一格式。

    4.23 注册表的快照与回滚

    发布新 Server/新工具前,给注册表打快照:

    • 版本号 + 时间戳 + 变更记录。
    • 出问题可一键回滚到旧快照。
    • 灰度场景按快照对比差异。

    4.24 注册表与 CI/CD

    注册表变更纳入 CI:

    • 契约测试:schema 变更检测。
    • 冲突检测:新工具名是否冲突。
    • 权限审核:destructive 工具需审批。
    • 发布流水线:变更先走灰度。

    4.25 注册表的容量规划

    规模工具数注册表形态
    <50 单机内存
    50–500 内存+缓存分层
    500+ 分布式+索引

    4.26 注册表与"工具下线"流程

    工具下线不是直接删,而是分步走:

  • 标记 deprecated(仍可用,告警)。
  • 通知 Agent 迁移到替代工具。
  • 观察期后移除。
  • 注册表清理 + 审计留痕。
  • #mermaid-svg-Tme58JJTCRUSWXHD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Tme58JJTCRUSWXHD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Tme58JJTCRUSWXHD .error-icon{fill:#552222;}#mermaid-svg-Tme58JJTCRUSWXHD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Tme58JJTCRUSWXHD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Tme58JJTCRUSWXHD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Tme58JJTCRUSWXHD .marker.cross{stroke:#333333;}#mermaid-svg-Tme58JJTCRUSWXHD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Tme58JJTCRUSWXHD p{margin:0;}#mermaid-svg-Tme58JJTCRUSWXHD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Tme58JJTCRUSWXHD .cluster-label text{fill:#333;}#mermaid-svg-Tme58JJTCRUSWXHD .cluster-label span{color:#333;}#mermaid-svg-Tme58JJTCRUSWXHD .cluster-label span p{background-color:transparent;}#mermaid-svg-Tme58JJTCRUSWXHD .label text,#mermaid-svg-Tme58JJTCRUSWXHD span{fill:#333;color:#333;}#mermaid-svg-Tme58JJTCRUSWXHD .node rect,#mermaid-svg-Tme58JJTCRUSWXHD .node circle,#mermaid-svg-Tme58JJTCRUSWXHD .node ellipse,#mermaid-svg-Tme58JJTCRUSWXHD .node polygon,#mermaid-svg-Tme58JJTCRUSWXHD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Tme58JJTCRUSWXHD .rough-node .label text,#mermaid-svg-Tme58JJTCRUSWXHD .node .label text,#mermaid-svg-Tme58JJTCRUSWXHD .image-shape .label,#mermaid-svg-Tme58JJTCRUSWXHD .icon-shape .label{text-anchor:middle;}#mermaid-svg-Tme58JJTCRUSWXHD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Tme58JJTCRUSWXHD .rough-node .label,#mermaid-svg-Tme58JJTCRUSWXHD .node .label,#mermaid-svg-Tme58JJTCRUSWXHD .image-shape .label,#mermaid-svg-Tme58JJTCRUSWXHD .icon-shape .label{text-align:center;}#mermaid-svg-Tme58JJTCRUSWXHD .node.clickable{cursor:pointer;}#mermaid-svg-Tme58JJTCRUSWXHD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Tme58JJTCRUSWXHD .arrowheadPath{fill:#333333;}#mermaid-svg-Tme58JJTCRUSWXHD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Tme58JJTCRUSWXHD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Tme58JJTCRUSWXHD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Tme58JJTCRUSWXHD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Tme58JJTCRUSWXHD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Tme58JJTCRUSWXHD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Tme58JJTCRUSWXHD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Tme58JJTCRUSWXHD .cluster text{fill:#333;}#mermaid-svg-Tme58JJTCRUSWXHD .cluster span{color:#333;}#mermaid-svg-Tme58JJTCRUSWXHD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Tme58JJTCRUSWXHD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Tme58JJTCRUSWXHD rect.text{fill:none;stroke-width:0;}#mermaid-svg-Tme58JJTCRUSWXHD .icon-shape,#mermaid-svg-Tme58JJTCRUSWXHD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Tme58JJTCRUSWXHD .icon-shape p,#mermaid-svg-Tme58JJTCRUSWXHD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Tme58JJTCRUSWXHD .icon-shape .label rect,#mermaid-svg-Tme58JJTCRUSWXHD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Tme58JJTCRUSWXHD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Tme58JJTCRUSWXHD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Tme58JJTCRUSWXHD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    标记deprecated

    迁移通知

    观察期

    移除

    审计留痕

    4.27 注册表的健康检查

    • 条目数与预期一致?
    • 所有 Server 可达?
    • 无过期条目?
    • 命中率正常?

    异常自动告警,避免"注册表静默损坏"。

    4.28 本章小结(终版)

    路由注册表是"发现"与"调用"之间的枢纽。深挖覆盖查询 API、描述增强、快照回滚、CI/CD 集成、容量规划、下线流程、健康检查,加上此前的完整数据模型、实现形态、冲突处理、失效刷新、可观测、安全设计、故障联动——从"能用"到"生产可用"再到"可治理"。


    第 5 章 工具发现机制深拆

    5.1 tools/list 的返回结构

    tools/list 是发现阶段的核心方法。它的响应是一个工具数组,每个工具包含:

    • name:工具名,Agent 调用时使用。
    • description:工具说明,直接决定 Agent 是否选中它。
    • inputSchema:JSON Schema,描述参数结构。

    {
    "jsonrpc": "2.0",
    "result": {
    "tools": [
    {
    "name": "search_code",
    "description": "在指定仓库中搜索代码,返回匹配文件列表",
    "inputSchema": {
    "type": "object",
    "properties": {
    "query": { "type": "string", "description": "搜索关键字" },
    "repo": { "type": "string", "description": "仓库名" }
    },
    "required": ["query"]
    }
    }
    ]
    }
    }

    5.2 description 是"销售文案"

    Agent 面对几十上百个工具,靠 description 决定用哪个。描述写得差,工具就"卖不出去":

    写法效果
    “搜索代码” 泛泛,Agent 难判断
    “在指定 GitHub 仓库中按关键字搜索代码,返回匹配文件路径列表,常用于定位某段逻辑的实现位置” 明确,Agent 易命中

    5.3 inputSchema 是"参数说明书"

    Schema 质量决定调用成功率。三条铁律:

  • 每个参数写清楚 description。
  • required 只列真正必填的。
  • 枚举值、默认值、格式(如 email/url)尽量标注。
  • 5.4 发现的时机

    时机场景备注
    启动时 首次连接 必做
    通知触发 Server 说工具变了 增量刷新
    定时 长驻会话 TTL 控制
    失败后 调用 MethodNotFound 刷新重试

    5.5 发现的优化:增量与缓存

    全量 tools/list 在工具多、Server 多时开销不小。优化思路:

    #mermaid-svg-lp9swTWmuJ2ugxv2{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lp9swTWmuJ2ugxv2 .error-icon{fill:#552222;}#mermaid-svg-lp9swTWmuJ2ugxv2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lp9swTWmuJ2ugxv2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .marker.cross{stroke:#333333;}#mermaid-svg-lp9swTWmuJ2ugxv2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lp9swTWmuJ2ugxv2 p{margin:0;}#mermaid-svg-lp9swTWmuJ2ugxv2 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .cluster-label text{fill:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .cluster-label span{color:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .cluster-label span p{background-color:transparent;}#mermaid-svg-lp9swTWmuJ2ugxv2 .label text,#mermaid-svg-lp9swTWmuJ2ugxv2 span{fill:#333;color:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .node rect,#mermaid-svg-lp9swTWmuJ2ugxv2 .node circle,#mermaid-svg-lp9swTWmuJ2ugxv2 .node ellipse,#mermaid-svg-lp9swTWmuJ2ugxv2 .node polygon,#mermaid-svg-lp9swTWmuJ2ugxv2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .rough-node .label text,#mermaid-svg-lp9swTWmuJ2ugxv2 .node .label text,#mermaid-svg-lp9swTWmuJ2ugxv2 .image-shape .label,#mermaid-svg-lp9swTWmuJ2ugxv2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-lp9swTWmuJ2ugxv2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .rough-node .label,#mermaid-svg-lp9swTWmuJ2ugxv2 .node .label,#mermaid-svg-lp9swTWmuJ2ugxv2 .image-shape .label,#mermaid-svg-lp9swTWmuJ2ugxv2 .icon-shape .label{text-align:center;}#mermaid-svg-lp9swTWmuJ2ugxv2 .node.clickable{cursor:pointer;}#mermaid-svg-lp9swTWmuJ2ugxv2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .arrowheadPath{fill:#333333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lp9swTWmuJ2ugxv2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lp9swTWmuJ2ugxv2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lp9swTWmuJ2ugxv2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lp9swTWmuJ2ugxv2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .cluster text{fill:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 .cluster span{color:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lp9swTWmuJ2ugxv2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lp9swTWmuJ2ugxv2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-lp9swTWmuJ2ugxv2 .icon-shape,#mermaid-svg-lp9swTWmuJ2ugxv2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lp9swTWmuJ2ugxv2 .icon-shape p,#mermaid-svg-lp9swTWmuJ2ugxv2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lp9swTWmuJ2ugxv2 .icon-shape .label rect,#mermaid-svg-lp9swTWmuJ2ugxv2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lp9swTWmuJ2ugxv2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lp9swTWmuJ2ugxv2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lp9swTWmuJ2ugxv2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    首次发现

    全量拉取+缓存

    运行中

    Server 通知变更

    按变更增量更新

    5.6 发现与权限

    某些 Server 的工具清单可能因身份而异(登录用户不同,可用工具不同)。Client 应把"发现结果"与"当前身份"绑定缓存,避免串权限。

    5.7 发现失败处理

    tools/list 失败(超时/网络断)时:

  • 若是首次:视为 Server 不可用,降级处理。
  • 若是刷新:沿用旧缓存,标记 stale。
  • 连续失败:熔断该 Server,不再反复请求。
  • 5.9 发现与 Agent 提示词的关系

    发现结果最终会进入 Agent 的上下文。工具多了之后,提示词会膨胀:

    #mermaid-svg-iTkHHxJ3Ub3s8bDy{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .error-icon{fill:#552222;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .marker.cross{stroke:#333333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy p{margin:0;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .cluster-label text{fill:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .cluster-label span{color:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .cluster-label span p{background-color:transparent;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .label text,#mermaid-svg-iTkHHxJ3Ub3s8bDy span{fill:#333;color:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .node rect,#mermaid-svg-iTkHHxJ3Ub3s8bDy .node circle,#mermaid-svg-iTkHHxJ3Ub3s8bDy .node ellipse,#mermaid-svg-iTkHHxJ3Ub3s8bDy .node polygon,#mermaid-svg-iTkHHxJ3Ub3s8bDy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .rough-node .label text,#mermaid-svg-iTkHHxJ3Ub3s8bDy .node .label text,#mermaid-svg-iTkHHxJ3Ub3s8bDy .image-shape .label,#mermaid-svg-iTkHHxJ3Ub3s8bDy .icon-shape .label{text-anchor:middle;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .rough-node .label,#mermaid-svg-iTkHHxJ3Ub3s8bDy .node .label,#mermaid-svg-iTkHHxJ3Ub3s8bDy .image-shape .label,#mermaid-svg-iTkHHxJ3Ub3s8bDy .icon-shape .label{text-align:center;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .node.clickable{cursor:pointer;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .arrowheadPath{fill:#333333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iTkHHxJ3Ub3s8bDy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iTkHHxJ3Ub3s8bDy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iTkHHxJ3Ub3s8bDy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .cluster text{fill:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .cluster span{color:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iTkHHxJ3Ub3s8bDy rect.text{fill:none;stroke-width:0;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .icon-shape,#mermaid-svg-iTkHHxJ3Ub3s8bDy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .icon-shape p,#mermaid-svg-iTkHHxJ3Ub3s8bDy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .icon-shape .label rect,#mermaid-svg-iTkHHxJ3Ub3s8bDy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iTkHHxJ3Ub3s8bDy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iTkHHxJ3Ub3s8bDy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iTkHHxJ3Ub3s8bDy :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    发现结果

    工具描述精简

    进入系统提示词

    Agent 选型

    调用

    优化手段:对大量工具做分层描述——热门工具给全描述,冷门工具给一句话 + 需要时再展开。

    5.10 发现结果去重与合并

    多 Server 提供同类工具时,Client 可以:

  • 原样暴露(Agent 自行选择)。
  • 合并成"统一工具"(Client 内部路由到不同 Server)。
  • 按场景折叠(只暴露当前任务相关的子集)。
  • 合并式发现对 Agent 最友好,但对 Client 实现要求高。

    5.11 发现的权限过滤

    Server 按身份返回不同工具集时,Client 应:

    • 缓存与身份绑定,不跨身份共享。
    • 权限变更后强制刷新。
    • 对降权工具调用返回明确错误而非"工具不存在"。

    5.12 发现的版本管理

    工具也有版本:Server 升级工具后,老会话可能还在用旧 schema。建议:

    • schema 带版本号或哈希。
    • Client 检测到变更时提示"工具已更新"。
    • 旧参数按兼容规则处理(新字段可选、删字段需迁移)。

    5.13 发现的批量与分页

    工具极多(上百个)时,tools/list 支持分页:

    { "method": "tools/list", "params": { "cursor": "next-page-key" } }

    Client 分批拉取,边拉边注册,避免一次性内存爆炸。

    5.14 发现与"工具搜索"

    Agent 端可以内置"工具搜索":不把全部工具塞进上下文,而是按任务关键字检索描述,只把最相关的几个工具给模型。这本质是发现结果之上的二级索引。

    5.15 发现结果的质量评估

    指标含义优化方向
    工具命中率 描述是否贴任务 重写 description
    参数错误率 schema 是否清晰 补全 inputSchema
    发现耗时 清单大小/网络 分页/缓存/增量
    冗余度 是否重复 合并/折叠

    5.17 发现的时序图(完整版)

    ServerClientAgentServerClientAgent#mermaid-svg-dZ70c3AEMpjlESaf{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dZ70c3AEMpjlESaf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dZ70c3AEMpjlESaf .error-icon{fill:#552222;}#mermaid-svg-dZ70c3AEMpjlESaf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dZ70c3AEMpjlESaf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dZ70c3AEMpjlESaf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dZ70c3AEMpjlESaf .marker.cross{stroke:#333333;}#mermaid-svg-dZ70c3AEMpjlESaf svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dZ70c3AEMpjlESaf p{margin:0;}#mermaid-svg-dZ70c3AEMpjlESaf .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-dZ70c3AEMpjlESaf text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-dZ70c3AEMpjlESaf .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-dZ70c3AEMpjlESaf .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-dZ70c3AEMpjlESaf .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-dZ70c3AEMpjlESaf .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-dZ70c3AEMpjlESaf #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-dZ70c3AEMpjlESaf .sequenceNumber{fill:white;}#mermaid-svg-dZ70c3AEMpjlESaf #sequencenumber{fill:#333;}#mermaid-svg-dZ70c3AEMpjlESaf #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-dZ70c3AEMpjlESaf .messageText{fill:#333;stroke:none;}#mermaid-svg-dZ70c3AEMpjlESaf .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-dZ70c3AEMpjlESaf .labelText,#mermaid-svg-dZ70c3AEMpjlESaf .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-dZ70c3AEMpjlESaf .loopText,#mermaid-svg-dZ70c3AEMpjlESaf .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-dZ70c3AEMpjlESaf .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-dZ70c3AEMpjlESaf .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-dZ70c3AEMpjlESaf .noteText,#mermaid-svg-dZ70c3AEMpjlESaf .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-dZ70c3AEMpjlESaf .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-dZ70c3AEMpjlESaf .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-dZ70c3AEMpjlESaf .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-dZ70c3AEMpjlESaf .actorPopupMenu{position:absolute;}#mermaid-svg-dZ70c3AEMpjlESaf .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-dZ70c3AEMpjlESaf .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-dZ70c3AEMpjlESaf .actor-man circle,#mermaid-svg-dZ70c3AEMpjlESaf line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-dZ70c3AEMpjlESaf :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}需要工具清单tools/list工具数组(含schema)校验/去重/权限过滤缓存 + 注册能力地图就绪

    5.18 发现结果的校验

    拿到清单后,Client 应校验:

    • 工具名合法性(命名规范)。
    • description 非空(空描述的工具形同虚设)。
    • inputSchema 是合法 JSON Schema。
    • 无重复工具名。

    不合规的工具标记告警,避免"带病上线"。

    5.19 发现的降级:清单不可用时的行为

    tools/list 失败时按场景降级:

    场景行为
    首次失败 该 Server 视为不可用
    刷新失败 沿用旧缓存(标 stale)
    连续失败 熔断 + 告警
    部分失败 已成功的 Server 正常用

    5.20 发现的幂等性

    tools/list 是只读方法,天然幂等。但"发现后注册"要防重复:同一工具重复注册应更新而非追加;注册过程支持重入。

    5.21 发现的审计

    记录发现行为本身:谁发起的、何时、哪个 Server、返回多少工具、耗时。审计数据用于:追踪权限异常、评估 Server 稳定性、优化发现策略。

    5.22 发现的测试

    • 单元:mock Server 返回固定清单,验证注册结果。
    • 集成:真实 Server 联调,验证 schema 解析。
    • 异常:Server 返回空清单/畸形 schema/超时。
    • 性能:100 个工具分页拉取的耗时。

    5.23 发现的配置项

    discovery:
    cache_ttl: 300s
    refresh_on_notify: true
    refresh_on_error: true
    lazy_enabled: false
    page_size: 50
    timeout_ms: 5000

    5.24 本章小结(终版)

    发现机制的核心是 tools/list + 缓存失效 + 失败降级,配套校验、幂等、审计、测试、配置。深挖覆盖描述与 schema 质量、分层描述、去重合并、权限过滤、版本管理、分页、工具搜索、质量评估——description 与 inputSchema 的质量直接决定工具命中率与调用成功率。


    第 6 章 工具调用机制深拆

    6.1 tools/call 的请求结构

    调用阶段的核心方法是 tools/call:

    {
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
    "name": "search_code",
    "arguments": { "query": "auth", "repo": "myrepo" }
    }
    }

    Server 执行后返回结果:

    {
    "jsonrpc": "2.0",
    "result": {
    "content": [
    { "type": "text", "text": "找到5个匹配文件" }
    ],
    "isError": false
    }
    }

    6.2 调用前的参数校验

    Client 在转发前,应先用 inputSchema 校验参数:

    #mermaid-svg-xmnxF0g9xhl94JQX{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xmnxF0g9xhl94JQX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xmnxF0g9xhl94JQX .error-icon{fill:#552222;}#mermaid-svg-xmnxF0g9xhl94JQX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xmnxF0g9xhl94JQX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xmnxF0g9xhl94JQX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xmnxF0g9xhl94JQX .marker.cross{stroke:#333333;}#mermaid-svg-xmnxF0g9xhl94JQX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xmnxF0g9xhl94JQX p{margin:0;}#mermaid-svg-xmnxF0g9xhl94JQX .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-xmnxF0g9xhl94JQX .cluster-label text{fill:#333;}#mermaid-svg-xmnxF0g9xhl94JQX .cluster-label span{color:#333;}#mermaid-svg-xmnxF0g9xhl94JQX .cluster-label span p{background-color:transparent;}#mermaid-svg-xmnxF0g9xhl94JQX .label text,#mermaid-svg-xmnxF0g9xhl94JQX span{fill:#333;color:#333;}#mermaid-svg-xmnxF0g9xhl94JQX .node rect,#mermaid-svg-xmnxF0g9xhl94JQX .node circle,#mermaid-svg-xmnxF0g9xhl94JQX .node ellipse,#mermaid-svg-xmnxF0g9xhl94JQX .node polygon,#mermaid-svg-xmnxF0g9xhl94JQX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xmnxF0g9xhl94JQX .rough-node .label text,#mermaid-svg-xmnxF0g9xhl94JQX .node .label text,#mermaid-svg-xmnxF0g9xhl94JQX .image-shape .label,#mermaid-svg-xmnxF0g9xhl94JQX .icon-shape .label{text-anchor:middle;}#mermaid-svg-xmnxF0g9xhl94JQX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xmnxF0g9xhl94JQX .rough-node .label,#mermaid-svg-xmnxF0g9xhl94JQX .node .label,#mermaid-svg-xmnxF0g9xhl94JQX .image-shape .label,#mermaid-svg-xmnxF0g9xhl94JQX .icon-shape .label{text-align:center;}#mermaid-svg-xmnxF0g9xhl94JQX .node.clickable{cursor:pointer;}#mermaid-svg-xmnxF0g9xhl94JQX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xmnxF0g9xhl94JQX .arrowheadPath{fill:#333333;}#mermaid-svg-xmnxF0g9xhl94JQX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xmnxF0g9xhl94JQX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xmnxF0g9xhl94JQX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xmnxF0g9xhl94JQX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xmnxF0g9xhl94JQX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xmnxF0g9xhl94JQX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xmnxF0g9xhl94JQX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xmnxF0g9xhl94JQX .cluster text{fill:#333;}#mermaid-svg-xmnxF0g9xhl94JQX .cluster span{color:#333;}#mermaid-svg-xmnxF0g9xhl94JQX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xmnxF0g9xhl94JQX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xmnxF0g9xhl94JQX rect.text{fill:none;stroke-width:0;}#mermaid-svg-xmnxF0g9xhl94JQX .icon-shape,#mermaid-svg-xmnxF0g9xhl94JQX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xmnxF0g9xhl94JQX .icon-shape p,#mermaid-svg-xmnxF0g9xhl94JQX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xmnxF0g9xhl94JQX .icon-shape .label rect,#mermaid-svg-xmnxF0g9xhl94JQX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xmnxF0g9xhl94JQX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xmnxF0g9xhl94JQX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xmnxF0g9xhl94JQX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent 构造参数

    按 schema 校验

    合法?

    路由+调用

    补充/修正参数

    校验不过时,Client 返回友好错误,而非直接打到 Server。

    6.3 结果处理

    Server 返回的内容类型多样(text/image/resource),Client 统一包装后交给 Agent:

    • isError: false:正常结果,Agent 继续推理。
    • isError: true:业务错误,Agent 需决定重试或换策略。

    6.4 调用超时与取消

    • 超时:按工具类型分级(快工具 10s、慢工具 60s+)。
    • 取消:Agent 中途反悔,发 notifications/cancelled 中止在途调用。

    6.5 调用的幂等性

    写操作(create_issue、send_message)在重试时可能重复执行。Server 应支持幂等键,Client 重试时带上同一幂等键,Server 去重。

    6.6 调用链路的可观测

    ServerClientAgentServerClientAgent#mermaid-svg-SxXtpTXLuIvPQTCa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SxXtpTXLuIvPQTCa .error-icon{fill:#552222;}#mermaid-svg-SxXtpTXLuIvPQTCa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SxXtpTXLuIvPQTCa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SxXtpTXLuIvPQTCa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SxXtpTXLuIvPQTCa .marker.cross{stroke:#333333;}#mermaid-svg-SxXtpTXLuIvPQTCa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SxXtpTXLuIvPQTCa p{margin:0;}#mermaid-svg-SxXtpTXLuIvPQTCa .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-SxXtpTXLuIvPQTCa text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-SxXtpTXLuIvPQTCa .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-SxXtpTXLuIvPQTCa .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-SxXtpTXLuIvPQTCa #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-SxXtpTXLuIvPQTCa .sequenceNumber{fill:white;}#mermaid-svg-SxXtpTXLuIvPQTCa #sequencenumber{fill:#333;}#mermaid-svg-SxXtpTXLuIvPQTCa #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-SxXtpTXLuIvPQTCa .messageText{fill:#333;stroke:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-SxXtpTXLuIvPQTCa .labelText,#mermaid-svg-SxXtpTXLuIvPQTCa .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .loopText,#mermaid-svg-SxXtpTXLuIvPQTCa .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-SxXtpTXLuIvPQTCa .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-SxXtpTXLuIvPQTCa .noteText,#mermaid-svg-SxXtpTXLuIvPQTCa .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-SxXtpTXLuIvPQTCa .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-SxXtpTXLuIvPQTCa .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-SxXtpTXLuIvPQTCa .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-SxXtpTXLuIvPQTCa .actorPopupMenu{position:absolute;}#mermaid-svg-SxXtpTXLuIvPQTCa .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-SxXtpTXLuIvPQTCa .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-SxXtpTXLuIvPQTCa .actor-man circle,#mermaid-svg-SxXtpTXLuIvPQTCa line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-SxXtpTXLuIvPQTCa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}call_tool(name, args)记录 traceId/耗时tools/call结果(isError)记录结果/错误码返回

    6.7 调用失败的类型与处理

    错误类型示例处理
    参数错误 缺必填字段 补参重试
    工具不存在 MethodNotFound 刷新清单后重试
    Server 错误 内部异常 上报,不自动重试
    限流 ResourceExhausted 退避后重试

    6.9 参数校验的自动化

    理想情况下,Client 用 JSON Schema 校验库(如 Python 的 jsonschema、JS 的 ajv)自动校验:

    import jsonschema

    schema = tool["inputSchema"]
    jsonschema.validate(arguments, schema) # 不合法抛异常

    校验失败时返回人可读的错误,Agent 才能据此修正:

    参数错误:缺少必填字段 "query"(search_code 需要 query 和可选的 repo)

    6.10 工具调用的重试策略矩阵

    错误类型是否重试策略
    InvalidParams 修正参数
    MethodNotFound 是(1次) 刷新清单
    InternalError 上报
    超时 退避重试
    限流 退避+抖动
    网络断 重连后重试

    6.11 调用的并发控制

    Agent 可能同时发起多个工具调用(并行编排)。Client 应:

    • 每个调用独立跟踪(request id)。
    • 按 Server/会话维度限制并发数。
    • 超时独立,不互相阻塞。

    #mermaid-svg-sRWY0pRnLyR8ompT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sRWY0pRnLyR8ompT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sRWY0pRnLyR8ompT .error-icon{fill:#552222;}#mermaid-svg-sRWY0pRnLyR8ompT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sRWY0pRnLyR8ompT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sRWY0pRnLyR8ompT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sRWY0pRnLyR8ompT .marker.cross{stroke:#333333;}#mermaid-svg-sRWY0pRnLyR8ompT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sRWY0pRnLyR8ompT p{margin:0;}#mermaid-svg-sRWY0pRnLyR8ompT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-sRWY0pRnLyR8ompT .cluster-label text{fill:#333;}#mermaid-svg-sRWY0pRnLyR8ompT .cluster-label span{color:#333;}#mermaid-svg-sRWY0pRnLyR8ompT .cluster-label span p{background-color:transparent;}#mermaid-svg-sRWY0pRnLyR8ompT .label text,#mermaid-svg-sRWY0pRnLyR8ompT span{fill:#333;color:#333;}#mermaid-svg-sRWY0pRnLyR8ompT .node rect,#mermaid-svg-sRWY0pRnLyR8ompT .node circle,#mermaid-svg-sRWY0pRnLyR8ompT .node ellipse,#mermaid-svg-sRWY0pRnLyR8ompT .node polygon,#mermaid-svg-sRWY0pRnLyR8ompT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sRWY0pRnLyR8ompT .rough-node .label text,#mermaid-svg-sRWY0pRnLyR8ompT .node .label text,#mermaid-svg-sRWY0pRnLyR8ompT .image-shape .label,#mermaid-svg-sRWY0pRnLyR8ompT .icon-shape .label{text-anchor:middle;}#mermaid-svg-sRWY0pRnLyR8ompT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sRWY0pRnLyR8ompT .rough-node .label,#mermaid-svg-sRWY0pRnLyR8ompT .node .label,#mermaid-svg-sRWY0pRnLyR8ompT .image-shape .label,#mermaid-svg-sRWY0pRnLyR8ompT .icon-shape .label{text-align:center;}#mermaid-svg-sRWY0pRnLyR8ompT .node.clickable{cursor:pointer;}#mermaid-svg-sRWY0pRnLyR8ompT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sRWY0pRnLyR8ompT .arrowheadPath{fill:#333333;}#mermaid-svg-sRWY0pRnLyR8ompT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sRWY0pRnLyR8ompT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sRWY0pRnLyR8ompT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sRWY0pRnLyR8ompT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sRWY0pRnLyR8ompT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sRWY0pRnLyR8ompT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sRWY0pRnLyR8ompT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sRWY0pRnLyR8ompT .cluster text{fill:#333;}#mermaid-svg-sRWY0pRnLyR8ompT .cluster span{color:#333;}#mermaid-svg-sRWY0pRnLyR8ompT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sRWY0pRnLyR8ompT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sRWY0pRnLyR8ompT rect.text{fill:none;stroke-width:0;}#mermaid-svg-sRWY0pRnLyR8ompT .icon-shape,#mermaid-svg-sRWY0pRnLyR8ompT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sRWY0pRnLyR8ompT .icon-shape p,#mermaid-svg-sRWY0pRnLyR8ompT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sRWY0pRnLyR8ompT .icon-shape .label rect,#mermaid-svg-sRWY0pRnLyR8ompT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sRWY0pRnLyR8ompT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sRWY0pRnLyR8ompT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sRWY0pRnLyR8ompT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent

    并发调用池

    call A

    call B

    call C

    结果聚合

    返回 Agent

    6.12 调用的进度反馈

    慢工具(长任务)应支持进度上报:

    • Server 通过 notifications/progress 推进度。
    • Client 展示进度或供 Agent 判断是否继续等待。
    • 超时阈值与进度挂钩(有进度就续期)。

    6.13 调用结果的后处理

    结果返回 Agent 前,Client 可以做:

  • 脱敏:隐藏密钥、PII。
  • 截断:超长结果摘要或截断。
  • 标注:标记来源 Server、可信度。
  • 转换:结构化结果转成 Agent 友好的格式。
  • 6.14 调用的审计日志

    每次调用记录:who(会话身份)、what(工具名)、args(脱敏后)、when、result(摘要)、latency、error。审计日志用于安全追溯与质量分析。

    6.15 调用的降级链路

    工具不可用时,按优先级降级:

  • 备用 Server(同名工具)。
  • 缓存结果(只读工具)。
  • 模拟/占位结果(测试环境)。
  • 明确告知 Agent 不可用。
  • 6.16 调用与上下文管理的配合

    调用结果进入上下文后,会占用 Token。建议:

    • 结果摘要化后再入上下文。
    • 超大结果存外部,只给 Agent 引用。
    • 历史调用结果按需淘汰。

    6.18 调用的完整时序(含校验与审计)

    Server注册表ClientAgentServer注册表ClientAgent#mermaid-svg-KCClHnQWLfOjFHAO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KCClHnQWLfOjFHAO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KCClHnQWLfOjFHAO .error-icon{fill:#552222;}#mermaid-svg-KCClHnQWLfOjFHAO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KCClHnQWLfOjFHAO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KCClHnQWLfOjFHAO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KCClHnQWLfOjFHAO .marker.cross{stroke:#333333;}#mermaid-svg-KCClHnQWLfOjFHAO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KCClHnQWLfOjFHAO p{margin:0;}#mermaid-svg-KCClHnQWLfOjFHAO .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KCClHnQWLfOjFHAO text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-KCClHnQWLfOjFHAO .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KCClHnQWLfOjFHAO .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-KCClHnQWLfOjFHAO .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-KCClHnQWLfOjFHAO .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-KCClHnQWLfOjFHAO #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-KCClHnQWLfOjFHAO .sequenceNumber{fill:white;}#mermaid-svg-KCClHnQWLfOjFHAO #sequencenumber{fill:#333;}#mermaid-svg-KCClHnQWLfOjFHAO #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-KCClHnQWLfOjFHAO .messageText{fill:#333;stroke:none;}#mermaid-svg-KCClHnQWLfOjFHAO .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KCClHnQWLfOjFHAO .labelText,#mermaid-svg-KCClHnQWLfOjFHAO .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-KCClHnQWLfOjFHAO .loopText,#mermaid-svg-KCClHnQWLfOjFHAO .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-KCClHnQWLfOjFHAO .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KCClHnQWLfOjFHAO .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-KCClHnQWLfOjFHAO .noteText,#mermaid-svg-KCClHnQWLfOjFHAO .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-KCClHnQWLfOjFHAO .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KCClHnQWLfOjFHAO .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KCClHnQWLfOjFHAO .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KCClHnQWLfOjFHAO .actorPopupMenu{position:absolute;}#mermaid-svg-KCClHnQWLfOjFHAO .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-KCClHnQWLfOjFHAO .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KCClHnQWLfOjFHAO .actor-man circle,#mermaid-svg-KCClHnQWLfOjFHAO line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-KCClHnQWLfOjFHAO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}call_tool(name, arguments)schema 校验查路由权限检查(二次确认?)tools/call结果/错误脱敏/摘要/审计返回

    6.19 调用的权限检查

    调用前检查:

  • 该工具在当前会话可用吗(注册表有吗)。
  • 是 destructive 吗(需要二次确认吗)。
  • 当前身份有调用权限吗(策略引擎)。
  • 任一不过 → 本地拦截,返回明确错误,不打扰 Server。

    6.20 调用的请求 ID 与追踪

    每个调用分配唯一 requestId:

    • 贯穿 Client → Server 全链路。
    • 日志、指标、审计都挂 requestId。
    • 用户反馈"某次调用出错"时可按 ID 秒查。

    6.21 调用的结果校验

    Server 返回后,Client 校验:

    • 是否符合 outputSchema(若声明)。
    • isError 是否正确设置。
    • 内容类型是否可解析。

    不合规的结果标记告警,防止"坏数据"污染 Agent 推理。

    6.22 调用的批量优化

    高频小调用可合并:

    • 相同 Server 的多个独立调用并行发送。
    • 支持 batch 的 Server 合并请求。
    • 减少往返,提升吞吐。

    6.23 调用的成本控制

    • 每工具/每 Server 配额。
    • 结果缓存(读多写少场景)。
    • 大结果摘要化,省 Token 与带宽。
    • 成本看板 + 超预算告警。

    6.24 调用的测试

    • 单元:mock Server 验证校验/路由/重试逻辑。
    • 集成:真实 Server 跑典型调用。
    • 异常:注入超时/限流/坏 schema。
    • 回归:工具更新后全量回归调用用例。

    6.25 调用的配置项

    call:
    validate_args: true
    retry_max: 2
    retry_backoff: [200ms, 800ms, 2s]
    timeout_default_ms: 10000
    idempotency_key: auto
    audit_log: true

    6.26 本章小结(终版)

    调用机制的核心:schema 校验前置、结果统一包装、超时/取消分级、写操作幂等、全链路可观测,配套权限检查、请求追踪、结果校验、批量优化、成本控制、测试、配置。调用成败的三要素:参数对不对、路由准不准、Server 稳不稳。


    第 7 章 多 Server 组合与编排

    7.1 多 Server 的价值

    同一个 Agent 同时连接 GitHub、Slack、数据库等多个 MCP Server,就能组合出复杂能力:查完代码(GitHub)→ 通知团队(Slack)→ 记录数据(数据库)。

    #mermaid-svg-fZKcgXSnN9iA86xi{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fZKcgXSnN9iA86xi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fZKcgXSnN9iA86xi .error-icon{fill:#552222;}#mermaid-svg-fZKcgXSnN9iA86xi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fZKcgXSnN9iA86xi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fZKcgXSnN9iA86xi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fZKcgXSnN9iA86xi .marker.cross{stroke:#333333;}#mermaid-svg-fZKcgXSnN9iA86xi svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fZKcgXSnN9iA86xi p{margin:0;}#mermaid-svg-fZKcgXSnN9iA86xi .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-fZKcgXSnN9iA86xi .cluster-label text{fill:#333;}#mermaid-svg-fZKcgXSnN9iA86xi .cluster-label span{color:#333;}#mermaid-svg-fZKcgXSnN9iA86xi .cluster-label span p{background-color:transparent;}#mermaid-svg-fZKcgXSnN9iA86xi .label text,#mermaid-svg-fZKcgXSnN9iA86xi span{fill:#333;color:#333;}#mermaid-svg-fZKcgXSnN9iA86xi .node rect,#mermaid-svg-fZKcgXSnN9iA86xi .node circle,#mermaid-svg-fZKcgXSnN9iA86xi .node ellipse,#mermaid-svg-fZKcgXSnN9iA86xi .node polygon,#mermaid-svg-fZKcgXSnN9iA86xi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fZKcgXSnN9iA86xi .rough-node .label text,#mermaid-svg-fZKcgXSnN9iA86xi .node .label text,#mermaid-svg-fZKcgXSnN9iA86xi .image-shape .label,#mermaid-svg-fZKcgXSnN9iA86xi .icon-shape .label{text-anchor:middle;}#mermaid-svg-fZKcgXSnN9iA86xi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fZKcgXSnN9iA86xi .rough-node .label,#mermaid-svg-fZKcgXSnN9iA86xi .node .label,#mermaid-svg-fZKcgXSnN9iA86xi .image-shape .label,#mermaid-svg-fZKcgXSnN9iA86xi .icon-shape .label{text-align:center;}#mermaid-svg-fZKcgXSnN9iA86xi .node.clickable{cursor:pointer;}#mermaid-svg-fZKcgXSnN9iA86xi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fZKcgXSnN9iA86xi .arrowheadPath{fill:#333333;}#mermaid-svg-fZKcgXSnN9iA86xi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fZKcgXSnN9iA86xi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fZKcgXSnN9iA86xi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fZKcgXSnN9iA86xi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fZKcgXSnN9iA86xi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fZKcgXSnN9iA86xi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fZKcgXSnN9iA86xi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fZKcgXSnN9iA86xi .cluster text{fill:#333;}#mermaid-svg-fZKcgXSnN9iA86xi .cluster span{color:#333;}#mermaid-svg-fZKcgXSnN9iA86xi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fZKcgXSnN9iA86xi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fZKcgXSnN9iA86xi rect.text{fill:none;stroke-width:0;}#mermaid-svg-fZKcgXSnN9iA86xi .icon-shape,#mermaid-svg-fZKcgXSnN9iA86xi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fZKcgXSnN9iA86xi .icon-shape p,#mermaid-svg-fZKcgXSnN9iA86xi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fZKcgXSnN9iA86xi .icon-shape .label rect,#mermaid-svg-fZKcgXSnN9iA86xi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fZKcgXSnN9iA86xi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fZKcgXSnN9iA86xi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fZKcgXSnN9iA86xi :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent

    MCP Client

    GitHub Server

    Slack Server

    数据库 Server

    文件系统 Server

    7.2 多 Server 的编排模式

  • 顺序编排:先 A 后 B(先查代码再发通知)。
  • 并行编排:A 和 B 同时调(同时查多个仓库)。
  • 条件编排:A 成功才调 B(发现问题才建 Issue)。
  • 7.3 多 Server 的隔离

    一个 Server 挂了不能拖垮全部:

    • 每 Server 独立会话、独立超时。
    • 熔断器按 Server 维度。
    • 舱壁模式:每 Server 独立线程池/队列。

    7.4 多 Server 的负载与配额

    • 每 Server 独立限流配额。
    • 慢 Server 的调用不阻塞快 Server。
    • 调度器优先执行关键路径工具。

    7.5 多 Server 组合案例

    DSlackGitHubClientAgentDSlackGitHubClientAgent#mermaid-svg-G1jUEEeNxsY9eQxJ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-G1jUEEeNxsY9eQxJ .error-icon{fill:#552222;}#mermaid-svg-G1jUEEeNxsY9eQxJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-G1jUEEeNxsY9eQxJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-G1jUEEeNxsY9eQxJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-G1jUEEeNxsY9eQxJ .marker.cross{stroke:#333333;}#mermaid-svg-G1jUEEeNxsY9eQxJ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-G1jUEEeNxsY9eQxJ p{margin:0;}#mermaid-svg-G1jUEEeNxsY9eQxJ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-G1jUEEeNxsY9eQxJ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-G1jUEEeNxsY9eQxJ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-G1jUEEeNxsY9eQxJ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-G1jUEEeNxsY9eQxJ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-G1jUEEeNxsY9eQxJ .sequenceNumber{fill:white;}#mermaid-svg-G1jUEEeNxsY9eQxJ #sequencenumber{fill:#333;}#mermaid-svg-G1jUEEeNxsY9eQxJ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-G1jUEEeNxsY9eQxJ .messageText{fill:#333;stroke:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-G1jUEEeNxsY9eQxJ .labelText,#mermaid-svg-G1jUEEeNxsY9eQxJ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .loopText,#mermaid-svg-G1jUEEeNxsY9eQxJ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-G1jUEEeNxsY9eQxJ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-G1jUEEeNxsY9eQxJ .noteText,#mermaid-svg-G1jUEEeNxsY9eQxJ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-G1jUEEeNxsY9eQxJ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-G1jUEEeNxsY9eQxJ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-G1jUEEeNxsY9eQxJ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-G1jUEEeNxsY9eQxJ .actorPopupMenu{position:absolute;}#mermaid-svg-G1jUEEeNxsY9eQxJ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-G1jUEEeNxsY9eQxJ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-G1jUEEeNxsY9eQxJ .actor-man circle,#mermaid-svg-G1jUEEeNxsY9eQxJ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-G1jUEEeNxsY9eQxJ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}call_tool(search_code)tools/call5 个文件call_tool(send_message)tools/call已发送call_tool(execute_query)tools/call

    7.7 多 Server 的会话管理

    每个 Server 一个(或多个)会话。会话管理要点:

    • 会话级配置独立(超时、权限、限流)。
    • 会话状态统一跟踪(connecting/ready/error/closed)。
    • 批量初始化失败不阻断整体。

    #mermaid-svg-YjC7OFIkHk47poMF{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YjC7OFIkHk47poMF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YjC7OFIkHk47poMF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YjC7OFIkHk47poMF .error-icon{fill:#552222;}#mermaid-svg-YjC7OFIkHk47poMF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YjC7OFIkHk47poMF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YjC7OFIkHk47poMF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YjC7OFIkHk47poMF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YjC7OFIkHk47poMF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YjC7OFIkHk47poMF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YjC7OFIkHk47poMF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YjC7OFIkHk47poMF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YjC7OFIkHk47poMF .marker.cross{stroke:#333333;}#mermaid-svg-YjC7OFIkHk47poMF svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YjC7OFIkHk47poMF p{margin:0;}#mermaid-svg-YjC7OFIkHk47poMF defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-YjC7OFIkHk47poMF g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-YjC7OFIkHk47poMF g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-YjC7OFIkHk47poMF g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-YjC7OFIkHk47poMF g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-YjC7OFIkHk47poMF g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-YjC7OFIkHk47poMF .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-YjC7OFIkHk47poMF .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-YjC7OFIkHk47poMF .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-YjC7OFIkHk47poMF .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-YjC7OFIkHk47poMF .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-YjC7OFIkHk47poMF .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-YjC7OFIkHk47poMF .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-YjC7OFIkHk47poMF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YjC7OFIkHk47poMF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YjC7OFIkHk47poMF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YjC7OFIkHk47poMF .edgeLabel .label text{fill:#333;}#mermaid-svg-YjC7OFIkHk47poMF .label div .edgeLabel{color:#333;}#mermaid-svg-YjC7OFIkHk47poMF .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-YjC7OFIkHk47poMF .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-YjC7OFIkHk47poMF .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-YjC7OFIkHk47poMF .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-YjC7OFIkHk47poMF .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-YjC7OFIkHk47poMF .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YjC7OFIkHk47poMF .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YjC7OFIkHk47poMF #statediagram-barbEnd{fill:#333333;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YjC7OFIkHk47poMF .cluster-label,#mermaid-svg-YjC7OFIkHk47poMF .nodeLabel{color:#131300;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-YjC7OFIkHk47poMF .note-edge{stroke-dasharray:5;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-note text{fill:black;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram-note .nodeLabel{color:black;}#mermaid-svg-YjC7OFIkHk47poMF .statediagram .edgeLabel{color:red;}#mermaid-svg-YjC7OFIkHk47poMF #dependencyStart,#mermaid-svg-YjC7OFIkHk47poMF #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-YjC7OFIkHk47poMF .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YjC7OFIkHk47poMF :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    连接

    连接

    连接

    initialize

    initialize

    initialize

    GitHub会话

    Slack会话

    数据库会话

    GitHub就绪

    Slack就绪

    数据库就绪

    7.8 多 Server 的组合策略

    策略描述案例
    顺序 结果作为下一步输入 查代码→发通知
    并行 互不依赖同时调 多仓库同时搜索
    条件 按结果决定分支 有问题才建 Issue
    汇总 多源结果聚合 多数据库对比

    7.9 多 Server 的路由优先级

    同名工具跨 Server 时,可配置路由优先级:

    list_repos:
    – github-server (priority 1)
    – gitlab-server (priority 2)

    优先路由到优先级高的;失败时降级到下一优先级的 Server。

    7.10 多 Server 的故障隔离实战

    #mermaid-svg-ZwBgKmPTH1moOCwV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZwBgKmPTH1moOCwV .error-icon{fill:#552222;}#mermaid-svg-ZwBgKmPTH1moOCwV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZwBgKmPTH1moOCwV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZwBgKmPTH1moOCwV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZwBgKmPTH1moOCwV .marker.cross{stroke:#333333;}#mermaid-svg-ZwBgKmPTH1moOCwV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZwBgKmPTH1moOCwV p{margin:0;}#mermaid-svg-ZwBgKmPTH1moOCwV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV .cluster-label text{fill:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV .cluster-label span{color:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV .cluster-label span p{background-color:transparent;}#mermaid-svg-ZwBgKmPTH1moOCwV .label text,#mermaid-svg-ZwBgKmPTH1moOCwV span{fill:#333;color:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV .node rect,#mermaid-svg-ZwBgKmPTH1moOCwV .node circle,#mermaid-svg-ZwBgKmPTH1moOCwV .node ellipse,#mermaid-svg-ZwBgKmPTH1moOCwV .node polygon,#mermaid-svg-ZwBgKmPTH1moOCwV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZwBgKmPTH1moOCwV .rough-node .label text,#mermaid-svg-ZwBgKmPTH1moOCwV .node .label text,#mermaid-svg-ZwBgKmPTH1moOCwV .image-shape .label,#mermaid-svg-ZwBgKmPTH1moOCwV .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZwBgKmPTH1moOCwV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZwBgKmPTH1moOCwV .rough-node .label,#mermaid-svg-ZwBgKmPTH1moOCwV .node .label,#mermaid-svg-ZwBgKmPTH1moOCwV .image-shape .label,#mermaid-svg-ZwBgKmPTH1moOCwV .icon-shape .label{text-align:center;}#mermaid-svg-ZwBgKmPTH1moOCwV .node.clickable{cursor:pointer;}#mermaid-svg-ZwBgKmPTH1moOCwV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZwBgKmPTH1moOCwV .arrowheadPath{fill:#333333;}#mermaid-svg-ZwBgKmPTH1moOCwV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZwBgKmPTH1moOCwV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZwBgKmPTH1moOCwV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZwBgKmPTH1moOCwV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZwBgKmPTH1moOCwV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZwBgKmPTH1moOCwV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZwBgKmPTH1moOCwV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZwBgKmPTH1moOCwV .cluster text{fill:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV .cluster span{color:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZwBgKmPTH1moOCwV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZwBgKmPTH1moOCwV rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZwBgKmPTH1moOCwV .icon-shape,#mermaid-svg-ZwBgKmPTH1moOCwV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZwBgKmPTH1moOCwV .icon-shape p,#mermaid-svg-ZwBgKmPTH1moOCwV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZwBgKmPTH1moOCwV .icon-shape .label rect,#mermaid-svg-ZwBgKmPTH1moOCwV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZwBgKmPTH1moOCwV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZwBgKmPTH1moOCwV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZwBgKmPTH1moOCwV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    熔断

    正常

    正常

    Agent

    Client

    GitHub Server

    Slack Server

    数据库 Server

    GitHub 降级

    继续服务

    继续服务

    Slack 挂了,GitHub 和数据库照常工作;Agent 仍能完成"查代码 + 记库",只是通知环节降级为"稍后重试"。

    7.11 多 Server 的配额管理

    每 Server 独立配额:

    • 每分钟调用上限。
    • 并发数上限。
    • 数据量上限。

    超配额返回 ResourceExhausted,由调度器排队或降级。

    7.12 多 Server 的可观测聚合

    多 Server 场景下,单 Server 的指标不够,需要聚合视图:

    • 按 Server 维度看延迟/错误率/配额。
    • 跨 Server 链路看一次任务的总耗时。
    • 定位瓶颈 Server(哪一步最慢)。

    7.13 多 Server 的配置中心

    建议用配置中心统一管理:

    servers:
    github:
    transport: stdio
    command: mcpgithub
    permissions: [read, write]
    slack:
    transport: http
    url: https://slackmcp.example.com
    token_env: SLACK_TOKEN
    database:
    transport: stdio
    command: mcppostgres
    dsn_env: PG_DSN

    7.14 多 Server 的版本协同

    多 Server 版本不同步时(一个 v1 一个 v2),Client 按会话分别协商:

    • 每个会话独立 protocolVersion。
    • 老版本 Server 的功能受限但可用。
    • 升级 Server 时灰度替换,避免一刀切。

    7.15 多 Server 的测试策略

    • 单 Server 冒烟:各 Server 独立可用。
    • 组合集成:多 Server 联合跑典型任务。
    • 故障演练:杀一个 Server 验证隔离。
    • 契约测试:schema 漂移检测。

    7.17 多 Server 的注册与编排分离

    • 注册层:每个 Server 独立发现、注册、维护会话。
    • 编排层:跨 Server 的任务调度(顺序/并行/条件/汇总)。

    注册层保证"每个 Server 可靠可用",编排层保证"多个 Server 协同成事"。两层解耦,故障域清晰。

    7.18 多 Server 的延迟优化

    优化收益
    并行初始化 启动快 N 倍
    懒发现冷门 Server 启动不被拖累
    连接池复用 减少握手
    结果缓存 读操作省往返
    就近路由 网络延迟低

    7.19 多 Server 的权限矩阵

    Server身份A身份B
    GitHub 读写 只读
    Slack 发消息 不可用
    数据库 查询 查询+写

    权限矩阵应在注册阶段落地:每个会话的注册表只包含该身份有权限的工具。

    7.20 多 Server 的优雅降级顺序

    Server 不可用时,按优先级降级:

  • 备用 Server(同名工具)。
  • 缓存结果(只读场景)。
  • 编排调整(换路径完成任务)。
  • 明确告知用户(人工兜底)。
  • 7.21 多 Server 的容量与扩展

    • 水平扩展:加 Server 实例,注册表按实例路由。
    • 垂直扩展:提升单 Server 配额。
    • 分片:不同工具集分到不同 Server。

    7.22 多 Server 的测试矩阵

    测试场景
    单 Server 冒烟 各自可用
    组合集成 多 Server 联合
    故障注入 杀一个验证隔离
    并发压测 高并发调用
    契约测试 schema 漂移检测

    7.23 本章小结(终版)

    多 Server 组合是 MCP"一套标准连所有工具"价值的集中体现。深挖覆盖注册与编排分离、延迟优化、权限矩阵、优雅降级、容量扩展、测试矩阵,加上此前的会话管理、组合策略、路由优先级、故障隔离、配额管理、可观测聚合、配置中心、版本协同——编排要点:路由准确、隔离可靠、配额公平、链路可查。


    第 8 章 技术挑战与解决方案

    8.1 挑战总览

    #mermaid-svg-tWMWOQMIjqkuW2eB{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tWMWOQMIjqkuW2eB .error-icon{fill:#552222;}#mermaid-svg-tWMWOQMIjqkuW2eB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tWMWOQMIjqkuW2eB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tWMWOQMIjqkuW2eB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tWMWOQMIjqkuW2eB .marker.cross{stroke:#333333;}#mermaid-svg-tWMWOQMIjqkuW2eB svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tWMWOQMIjqkuW2eB p{margin:0;}#mermaid-svg-tWMWOQMIjqkuW2eB .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB .cluster-label text{fill:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB .cluster-label span{color:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB .cluster-label span p{background-color:transparent;}#mermaid-svg-tWMWOQMIjqkuW2eB .label text,#mermaid-svg-tWMWOQMIjqkuW2eB span{fill:#333;color:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB .node rect,#mermaid-svg-tWMWOQMIjqkuW2eB .node circle,#mermaid-svg-tWMWOQMIjqkuW2eB .node ellipse,#mermaid-svg-tWMWOQMIjqkuW2eB .node polygon,#mermaid-svg-tWMWOQMIjqkuW2eB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tWMWOQMIjqkuW2eB .rough-node .label text,#mermaid-svg-tWMWOQMIjqkuW2eB .node .label text,#mermaid-svg-tWMWOQMIjqkuW2eB .image-shape .label,#mermaid-svg-tWMWOQMIjqkuW2eB .icon-shape .label{text-anchor:middle;}#mermaid-svg-tWMWOQMIjqkuW2eB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tWMWOQMIjqkuW2eB .rough-node .label,#mermaid-svg-tWMWOQMIjqkuW2eB .node .label,#mermaid-svg-tWMWOQMIjqkuW2eB .image-shape .label,#mermaid-svg-tWMWOQMIjqkuW2eB .icon-shape .label{text-align:center;}#mermaid-svg-tWMWOQMIjqkuW2eB .node.clickable{cursor:pointer;}#mermaid-svg-tWMWOQMIjqkuW2eB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tWMWOQMIjqkuW2eB .arrowheadPath{fill:#333333;}#mermaid-svg-tWMWOQMIjqkuW2eB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tWMWOQMIjqkuW2eB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tWMWOQMIjqkuW2eB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tWMWOQMIjqkuW2eB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tWMWOQMIjqkuW2eB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tWMWOQMIjqkuW2eB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tWMWOQMIjqkuW2eB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tWMWOQMIjqkuW2eB .cluster text{fill:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB .cluster span{color:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tWMWOQMIjqkuW2eB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tWMWOQMIjqkuW2eB rect.text{fill:none;stroke-width:0;}#mermaid-svg-tWMWOQMIjqkuW2eB .icon-shape,#mermaid-svg-tWMWOQMIjqkuW2eB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tWMWOQMIjqkuW2eB .icon-shape p,#mermaid-svg-tWMWOQMIjqkuW2eB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tWMWOQMIjqkuW2eB .icon-shape .label rect,#mermaid-svg-tWMWOQMIjqkuW2eB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tWMWOQMIjqkuW2eB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tWMWOQMIjqkuW2eB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tWMWOQMIjqkuW2eB :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    发现风暴

    解法: 缓存+通知

    路由冲突

    解法: 前缀+优先级

    schema 漂移

    解法: 哈希校验+重拉

    调用超时

    解法: 分级超时+重试

    写操作重复

    解法: 幂等键

    安全越权

    解法: 权限联动

    8.2 发现风暴

    问题:每个 Server 频繁重新 tools/list,造成大量无效请求。

    解法:

    • 缓存清单 + TTL。
    • 依赖 Server 的变更通知,而非定时轮询。
    • 增量更新而非全量重拉。

    8.3 路由冲突

    问题:多 Server 提供同名工具,查表可能路由错。

    解法:

    • 命名空间前缀(github.list_repos)。
    • 显式指定优先级。
    • 冲突时告警并让 Agent 显式选择。

    8.4 Schema 漂移

    问题:Server 改了 inputSchema 但 Client 缓存没更新,导致调用参数不合法。

    解法:

    • 为 schema 计算哈希,变更即刷新。
    • 调用失败(InvalidParams)时强制重拉清单。
    • Server 主动推送变更通知。

    8.5 调用超时与重试风暴

    问题:网络抖动引发批量重试,压垮 Server。

    解法:

    • 指数退避 + 抖动。
    • 写操作不自动重试(等幂键除外)。
    • 熔断器防止雪崩。

    8.6 安全:越权与注入

    问题:Agent 被诱导调用危险工具,或工具参数被注入恶意内容。

    解法:

    • 注册表标记 destructive 工具,调用前二次确认/策略拦截。
    • 工具结果中的外部内容做注入扫描。
    • 敏感操作要求 HITL(人在环)。

    8.7 可观测性

    问题:跨 Agent/Client/Server 的链路难追踪。

    解法:

    • 全链路 traceId。
    • 日志统一字段(sessionId/method/toolName/latency)。
    • 注册表命中率、发现频率、错误码分布等指标看板。

    8.8 排障决策树

    #mermaid-svg-hKdNgJME4XRiAM60{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hKdNgJME4XRiAM60 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hKdNgJME4XRiAM60 .error-icon{fill:#552222;}#mermaid-svg-hKdNgJME4XRiAM60 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hKdNgJME4XRiAM60 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hKdNgJME4XRiAM60 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hKdNgJME4XRiAM60 .marker.cross{stroke:#333333;}#mermaid-svg-hKdNgJME4XRiAM60 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hKdNgJME4XRiAM60 p{margin:0;}#mermaid-svg-hKdNgJME4XRiAM60 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-hKdNgJME4XRiAM60 .cluster-label text{fill:#333;}#mermaid-svg-hKdNgJME4XRiAM60 .cluster-label span{color:#333;}#mermaid-svg-hKdNgJME4XRiAM60 .cluster-label span p{background-color:transparent;}#mermaid-svg-hKdNgJME4XRiAM60 .label text,#mermaid-svg-hKdNgJME4XRiAM60 span{fill:#333;color:#333;}#mermaid-svg-hKdNgJME4XRiAM60 .node rect,#mermaid-svg-hKdNgJME4XRiAM60 .node circle,#mermaid-svg-hKdNgJME4XRiAM60 .node ellipse,#mermaid-svg-hKdNgJME4XRiAM60 .node polygon,#mermaid-svg-hKdNgJME4XRiAM60 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hKdNgJME4XRiAM60 .rough-node .label text,#mermaid-svg-hKdNgJME4XRiAM60 .node .label text,#mermaid-svg-hKdNgJME4XRiAM60 .image-shape .label,#mermaid-svg-hKdNgJME4XRiAM60 .icon-shape .label{text-anchor:middle;}#mermaid-svg-hKdNgJME4XRiAM60 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hKdNgJME4XRiAM60 .rough-node .label,#mermaid-svg-hKdNgJME4XRiAM60 .node .label,#mermaid-svg-hKdNgJME4XRiAM60 .image-shape .label,#mermaid-svg-hKdNgJME4XRiAM60 .icon-shape .label{text-align:center;}#mermaid-svg-hKdNgJME4XRiAM60 .node.clickable{cursor:pointer;}#mermaid-svg-hKdNgJME4XRiAM60 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hKdNgJME4XRiAM60 .arrowheadPath{fill:#333333;}#mermaid-svg-hKdNgJME4XRiAM60 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hKdNgJME4XRiAM60 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hKdNgJME4XRiAM60 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hKdNgJME4XRiAM60 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hKdNgJME4XRiAM60 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hKdNgJME4XRiAM60 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hKdNgJME4XRiAM60 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hKdNgJME4XRiAM60 .cluster text{fill:#333;}#mermaid-svg-hKdNgJME4XRiAM60 .cluster span{color:#333;}#mermaid-svg-hKdNgJME4XRiAM60 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hKdNgJME4XRiAM60 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hKdNgJME4XRiAM60 rect.text{fill:none;stroke-width:0;}#mermaid-svg-hKdNgJME4XRiAM60 .icon-shape,#mermaid-svg-hKdNgJME4XRiAM60 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hKdNgJME4XRiAM60 .icon-shape p,#mermaid-svg-hKdNgJME4XRiAM60 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hKdNgJME4XRiAM60 .icon-shape .label rect,#mermaid-svg-hKdNgJME4XRiAM60 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hKdNgJME4XRiAM60 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hKdNgJME4XRiAM60 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hKdNgJME4XRiAM60 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    调用失败

    路由命中?

    刷新注册表

    参数合法?

    按 schema 修正

    Server 可用?

    熔断/降级

    错误码?

    按码处理/上报

    8.10 挑战:Agent 幻觉调用

    问题:Agent 可能编造一个不存在的工具名(幻觉),或对工具能力过度想象。

    解法:

    • 注册表未命中 → 返回"工具不存在"并列出可用工具,纠正 Agent。
    • 工具描述写清楚边界(“本工具只支持 X,不支持 Y”)。
    • 对高频幻觉工具做提示词约束。

    #mermaid-svg-Xwhs18lvn7hm8OoZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Xwhs18lvn7hm8OoZ .error-icon{fill:#552222;}#mermaid-svg-Xwhs18lvn7hm8OoZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Xwhs18lvn7hm8OoZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .marker.cross{stroke:#333333;}#mermaid-svg-Xwhs18lvn7hm8OoZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Xwhs18lvn7hm8OoZ p{margin:0;}#mermaid-svg-Xwhs18lvn7hm8OoZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .cluster-label text{fill:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .cluster-label span{color:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .cluster-label span p{background-color:transparent;}#mermaid-svg-Xwhs18lvn7hm8OoZ .label text,#mermaid-svg-Xwhs18lvn7hm8OoZ span{fill:#333;color:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .node rect,#mermaid-svg-Xwhs18lvn7hm8OoZ .node circle,#mermaid-svg-Xwhs18lvn7hm8OoZ .node ellipse,#mermaid-svg-Xwhs18lvn7hm8OoZ .node polygon,#mermaid-svg-Xwhs18lvn7hm8OoZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .rough-node .label text,#mermaid-svg-Xwhs18lvn7hm8OoZ .node .label text,#mermaid-svg-Xwhs18lvn7hm8OoZ .image-shape .label,#mermaid-svg-Xwhs18lvn7hm8OoZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-Xwhs18lvn7hm8OoZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .rough-node .label,#mermaid-svg-Xwhs18lvn7hm8OoZ .node .label,#mermaid-svg-Xwhs18lvn7hm8OoZ .image-shape .label,#mermaid-svg-Xwhs18lvn7hm8OoZ .icon-shape .label{text-align:center;}#mermaid-svg-Xwhs18lvn7hm8OoZ .node.clickable{cursor:pointer;}#mermaid-svg-Xwhs18lvn7hm8OoZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .arrowheadPath{fill:#333333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Xwhs18lvn7hm8OoZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Xwhs18lvn7hm8OoZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Xwhs18lvn7hm8OoZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Xwhs18lvn7hm8OoZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .cluster text{fill:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ .cluster span{color:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Xwhs18lvn7hm8OoZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Xwhs18lvn7hm8OoZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-Xwhs18lvn7hm8OoZ .icon-shape,#mermaid-svg-Xwhs18lvn7hm8OoZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Xwhs18lvn7hm8OoZ .icon-shape p,#mermaid-svg-Xwhs18lvn7hm8OoZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Xwhs18lvn7hm8OoZ .icon-shape .label rect,#mermaid-svg-Xwhs18lvn7hm8OoZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Xwhs18lvn7hm8OoZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Xwhs18lvn7hm8OoZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Xwhs18lvn7hm8OoZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent 调用 call_tool

    注册表命中?

    返回可用工具列表

    Agent 重新选择

    正常调用

    8.11 挑战:工具参数注入

    问题:外部内容(网页、文件)被塞进工具参数,改变工具行为(提示注入的运行时变体)。

    解法:

    • 参数校验白名单(枚举、正则)。
    • 敏感字段(URL、命令)做消毒。
    • 工具结果中的外部内容标注"不可信",不入系统指令区。

    8.12 挑战:发现与调用的时序竞态

    问题:发现后工具被下架,注册表还没刷新,调用落空。

    解法:

    • 调用失败 MethodNotFound → 触发刷新 → 重试一次。
    • Server 在工具变更时立即推送通知。
    • 注册表条目带"获取时间",超龄强制刷新。

    8.13 挑战:大并发下的注册表一致

    问题:多线程/多 Agent 并发调用,注册表并发读写。

    解法:

    • 读写锁 / 原子替换。
    • 不可变快照 + 指针切换。
    • 分布式场景用版本号 CAS。

    8.14 挑战:跨 Server 的事务

    问题:任务需要"GitHub 建 Issue + Slack 通知 + 数据库记录",中间失败怎么办?

    解法:

    • 补偿事务:失败回滚已执行步骤(删除已建 Issue)。
    • 编排层记录任务状态,支持重入。
    • 幂等键保证重复执行不产生副作用。

    数据库GitHubClientAgent数据库GitHubClientAgent#mermaid-svg-go6J3h2VxdlH53XL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-go6J3h2VxdlH53XL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-go6J3h2VxdlH53XL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-go6J3h2VxdlH53XL .error-icon{fill:#552222;}#mermaid-svg-go6J3h2VxdlH53XL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-go6J3h2VxdlH53XL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-go6J3h2VxdlH53XL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-go6J3h2VxdlH53XL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-go6J3h2VxdlH53XL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-go6J3h2VxdlH53XL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-go6J3h2VxdlH53XL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-go6J3h2VxdlH53XL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-go6J3h2VxdlH53XL .marker.cross{stroke:#333333;}#mermaid-svg-go6J3h2VxdlH53XL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-go6J3h2VxdlH53XL p{margin:0;}#mermaid-svg-go6J3h2VxdlH53XL .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-go6J3h2VxdlH53XL text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-go6J3h2VxdlH53XL .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-go6J3h2VxdlH53XL .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-go6J3h2VxdlH53XL .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-go6J3h2VxdlH53XL .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-go6J3h2VxdlH53XL #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-go6J3h2VxdlH53XL .sequenceNumber{fill:white;}#mermaid-svg-go6J3h2VxdlH53XL #sequencenumber{fill:#333;}#mermaid-svg-go6J3h2VxdlH53XL #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-go6J3h2VxdlH53XL .messageText{fill:#333;stroke:none;}#mermaid-svg-go6J3h2VxdlH53XL .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-go6J3h2VxdlH53XL .labelText,#mermaid-svg-go6J3h2VxdlH53XL .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-go6J3h2VxdlH53XL .loopText,#mermaid-svg-go6J3h2VxdlH53XL .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-go6J3h2VxdlH53XL .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-go6J3h2VxdlH53XL .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-go6J3h2VxdlH53XL .noteText,#mermaid-svg-go6J3h2VxdlH53XL .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-go6J3h2VxdlH53XL .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-go6J3h2VxdlH53XL .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-go6J3h2VxdlH53XL .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-go6J3h2VxdlH53XL .actorPopupMenu{position:absolute;}#mermaid-svg-go6J3h2VxdlH53XL .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-go6J3h2VxdlH53XL .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-go6J3h2VxdlH53XL .actor-man circle,#mermaid-svg-go6J3h2VxdlH53XL line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-go6J3h2VxdlH53XL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}任务开始create_issue ✅insert_record ❌补偿: close_issue任务失败,已回滚

    8.15 挑战:发现结果过大

    问题:上百个工具的清单塞进上下文,Token 爆炸。

    解法:

    • 分页 + 按需加载。
    • 工具搜索(描述级检索)。
    • 分层描述(热门全量、冷门摘要)。

    8.16 挑战:Server 半死状态

    问题:Server 进程活着但卡死(假活),调用全部超时。

    解法:

    • 心跳探测。
    • 连续超时阈值触发重启。
    • 熔断 + 半开探测恢复。

    8.17 挑战:多版本协议并存

    问题:老 Server 只支持旧协议,新 Client 默认新协议。

    解法:

    • 会话级版本协商(每 Server 独立)。
    • 兼容层适配旧协议。
    • 升级排期管理,避免强制一刀切。

    8.18 挑战:工具链的循环依赖

    问题:工具 A 的结果需要工具 B,B 又需要 A(编排死锁)。

    解法:

    • 编排层检测循环依赖。
    • 限制调用深度。
    • 失败时明确报"依赖循环",不无限重试。

    8.19 挑战:成本失控

    问题:高频调用产生大量 API 费用(尤其 LLM 与外部付费 API)。

    解法:

    • 每 Server/每工具配额。
    • 结果缓存减少重复调用。
    • 成本看板 + 异常告警。

    8.20 挑战:安全性纵深的落实

    把安全落实到发现-调用全链路:

    环节安全措施
    发现 按身份过滤工具
    注册 destructive 标注
    调用 参数校验 + 二次确认
    结果 脱敏 + 注入扫描
    审计 全量调用留痕

    8.21 挑战:可观测的端到端

    #mermaid-svg-49reM8D04zms3rd9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-49reM8D04zms3rd9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-49reM8D04zms3rd9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-49reM8D04zms3rd9 .error-icon{fill:#552222;}#mermaid-svg-49reM8D04zms3rd9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-49reM8D04zms3rd9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-49reM8D04zms3rd9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-49reM8D04zms3rd9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-49reM8D04zms3rd9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-49reM8D04zms3rd9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-49reM8D04zms3rd9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-49reM8D04zms3rd9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-49reM8D04zms3rd9 .marker.cross{stroke:#333333;}#mermaid-svg-49reM8D04zms3rd9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-49reM8D04zms3rd9 p{margin:0;}#mermaid-svg-49reM8D04zms3rd9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-49reM8D04zms3rd9 .cluster-label text{fill:#333;}#mermaid-svg-49reM8D04zms3rd9 .cluster-label span{color:#333;}#mermaid-svg-49reM8D04zms3rd9 .cluster-label span p{background-color:transparent;}#mermaid-svg-49reM8D04zms3rd9 .label text,#mermaid-svg-49reM8D04zms3rd9 span{fill:#333;color:#333;}#mermaid-svg-49reM8D04zms3rd9 .node rect,#mermaid-svg-49reM8D04zms3rd9 .node circle,#mermaid-svg-49reM8D04zms3rd9 .node ellipse,#mermaid-svg-49reM8D04zms3rd9 .node polygon,#mermaid-svg-49reM8D04zms3rd9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-49reM8D04zms3rd9 .rough-node .label text,#mermaid-svg-49reM8D04zms3rd9 .node .label text,#mermaid-svg-49reM8D04zms3rd9 .image-shape .label,#mermaid-svg-49reM8D04zms3rd9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-49reM8D04zms3rd9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-49reM8D04zms3rd9 .rough-node .label,#mermaid-svg-49reM8D04zms3rd9 .node .label,#mermaid-svg-49reM8D04zms3rd9 .image-shape .label,#mermaid-svg-49reM8D04zms3rd9 .icon-shape .label{text-align:center;}#mermaid-svg-49reM8D04zms3rd9 .node.clickable{cursor:pointer;}#mermaid-svg-49reM8D04zms3rd9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-49reM8D04zms3rd9 .arrowheadPath{fill:#333333;}#mermaid-svg-49reM8D04zms3rd9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-49reM8D04zms3rd9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-49reM8D04zms3rd9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-49reM8D04zms3rd9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-49reM8D04zms3rd9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-49reM8D04zms3rd9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-49reM8D04zms3rd9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-49reM8D04zms3rd9 .cluster text{fill:#333;}#mermaid-svg-49reM8D04zms3rd9 .cluster span{color:#333;}#mermaid-svg-49reM8D04zms3rd9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-49reM8D04zms3rd9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-49reM8D04zms3rd9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-49reM8D04zms3rd9 .icon-shape,#mermaid-svg-49reM8D04zms3rd9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-49reM8D04zms3rd9 .icon-shape p,#mermaid-svg-49reM8D04zms3rd9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-49reM8D04zms3rd9 .icon-shape .label rect,#mermaid-svg-49reM8D04zms3rd9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-49reM8D04zms3rd9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-49reM8D04zms3rd9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-49reM8D04zms3rd9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent 调用

    Client 打点

    注册表命中率

    调用延迟

    错误码分布

    配额使用

    看板/告警

    8.22 挑战:排障手册速查

    症状可能原因排查步骤
    工具找不到 注册表过期 刷新清单
    调用全超时 Server 假活 心跳+重启
    参数被拒 schema 漂移 重拉清单
    结果乱码 编码问题 检查 UTF-8
    偶发失败 网络抖动 查重试日志

    8.23 挑战:清单(挑战对照)

    挑战一句话解法
    发现风暴 缓存+通知
    路由冲突 前缀+优先级
    Schema 漂移 哈希校验+重拉
    调用超时 分级超时+退避
    写操作重复 幂等键
    幻觉调用 未命中返回清单
    参数注入 白名单+消毒
    时序竞态 失败刷新重试
    并发一致 原子替换
    跨 Server 事务 补偿事务
    结果过大 分页+摘要
    Server 假活 心跳+熔断
    版本并存 会话级协商
    循环依赖 编排检测
    成本失控 配额+缓存
    越权 权限联动

    8.25 挑战:多 Server 的时钟与顺序

    分布式场景下,跨 Server 的事件顺序(先建 Issue 再通知)可能因时钟偏差错乱。解法:编排层用逻辑时钟/单调序号,不依赖墙钟排序;重要顺序操作串行化。

    8.26 挑战:工具结果的语言与格式

    Server 返回英文、中文、HTML 混杂,Agent 解析易错。解法:Client 统一转纯文本/标准结构;Server 声明结果语言;超长 HTML 转摘要。

    8.27 挑战:配额突增

    业务高峰所有 Agent 同时调工具,配额瞬间耗尽。解法:配额预留 + 优先级排队;关键任务优先;低优先级任务降级或延后。

    8.28 挑战:依赖外部 API 的 Server 抖动

    GitHub Server 本身依赖 GitHub API,外部抖动传导到工具调用。解法:Server 侧做外部调用缓存/熔断;Client 侧对慢 Server 限流;编排层容忍部分失败。

    8.29 挑战:测试环境与生产的工具差异

    测试 Server 和生产 Server 工具集不同,Agent 在测试环境学到的行为到生产失效。解法:环境对齐(工具集一致);契约测试覆盖两环境;配置中心统一管理环境差异。

    8.30 挑战:安全审计的合规要求

    金融/医疗场景要求工具调用可审计、可回溯、可解释。解法:全量审计 + 结果留档;destructive 操作双人复核(HITL);定期合规审查工具权限。

    8.31 挑战:本章小结(终版)

    工具发现与调用的挑战覆盖发现效率、路由准确性、契约一致性、调用韧性、安全、可观测、成本、事务,以及时钟顺序、语言格式、配额突增、外部依赖、环境差异、合规审计。解法组合:缓存+通知、前缀+优先级、哈希校验、退避+幂等、权限联动、补偿事务、全链路 trace、配额预留、环境对齐、审计留档。


    第 9 章 通俗案例深度解析

    9.1 案例全景:智能运维机器人

    以一个"运维机器人"为主线,演示完整四阶段。机器人连接 GitHub、Slack、数据库三个 Server,任务:检查线上仓库是否有高危漏洞,有则建 Issue 并通知运维群。

    Slack数据库GitHubMCP Client运维机器人Slack数据库GitHubMCP Client运维机器人#mermaid-svg-vbbhaoaL5Bh7N2IW{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vbbhaoaL5Bh7N2IW .error-icon{fill:#552222;}#mermaid-svg-vbbhaoaL5Bh7N2IW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vbbhaoaL5Bh7N2IW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vbbhaoaL5Bh7N2IW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vbbhaoaL5Bh7N2IW .marker.cross{stroke:#333333;}#mermaid-svg-vbbhaoaL5Bh7N2IW svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vbbhaoaL5Bh7N2IW p{margin:0;}#mermaid-svg-vbbhaoaL5Bh7N2IW .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vbbhaoaL5Bh7N2IW text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-vbbhaoaL5Bh7N2IW .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-vbbhaoaL5Bh7N2IW .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-vbbhaoaL5Bh7N2IW #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-vbbhaoaL5Bh7N2IW .sequenceNumber{fill:white;}#mermaid-svg-vbbhaoaL5Bh7N2IW #sequencenumber{fill:#333;}#mermaid-svg-vbbhaoaL5Bh7N2IW #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-vbbhaoaL5Bh7N2IW .messageText{fill:#333;stroke:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vbbhaoaL5Bh7N2IW .labelText,#mermaid-svg-vbbhaoaL5Bh7N2IW .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .loopText,#mermaid-svg-vbbhaoaL5Bh7N2IW .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-vbbhaoaL5Bh7N2IW .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-vbbhaoaL5Bh7N2IW .noteText,#mermaid-svg-vbbhaoaL5Bh7N2IW .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-vbbhaoaL5Bh7N2IW .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vbbhaoaL5Bh7N2IW .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vbbhaoaL5Bh7N2IW .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vbbhaoaL5Bh7N2IW .actorPopupMenu{position:absolute;}#mermaid-svg-vbbhaoaL5Bh7N2IW .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-vbbhaoaL5Bh7N2IW .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vbbhaoaL5Bh7N2IW .actor-man circle,#mermaid-svg-vbbhaoaL5Bh7N2IW line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-vbbhaoaL5Bh7N2IW :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}阶段1+2: 初始化与发现阶段3: 注册阶段4: 调用启动initialize + tools/listinitialize + tools/listinitialize + tools/list注册表: search_code→G, execute_query→D, send_message→Scall_tool(execute_query, 查漏洞)tools/call发现3个高危依赖call_tool(create_issue)tools/callIssuecall_tool(send_message)tools/call

    9.2 案例细节一:发现阶段的"菜单"

    机器人启动时,三个 Server 的"菜单"长这样:

    • GitHub:search_code、get_file_contents、create_issue、list_pulls、merge_pull…
    • 数据库:execute_query、explain_query、list_tables、describe_table…
    • Slack:send_message、list_channels、create_channel…

    机器人不需要预知这些名字——它运行起来看菜单(tools/list)才知道。

    9.3 案例细节二:路由的"秒查"

    调用 execute_query 时,Client 查注册表直接命中数据库 Server,耗时 <1ms。如果没注册表,Client 得问三个 Server"你有没有 execute_query",慢一个数量级。

    9.4 案例细节三:schema 帮机器人"学会填参数"

    机器人第一次调用 create_issue 时,靠 inputSchema 知道要填 repo/title/body,还知道 labels 是可选枚举。这就是"能力协商"——不需要写死调用代码。

    9.5 案例细节四:失败与重试

    第一次查数据库超时(慢查询),Client 按退避重试一次成功。如果连续失败,熔断器打开,机器人改为降级方案(用 GitHub 的 search_code 找配置确认)。

    9.6 案例细节五:安全问题

    create_issue 是写操作,注册表标记为非 destructive(可自动执行);而 delete_issue、merge_pull 等破坏性操作则要求二次确认,防止 Agent 误操作。

    9.7 微案例:新 Server 即插即用

    周五上线"日历 Server",机器人重新发现一次,注册表新增 list_events、create_event。周一开始,机器人已能"查漏洞→建 Issue→通知→顺手创建跟进日程"——零代码改动。

    9.8 微案例:工具更名

    GitHub Server 把 get_file_contents 改名为 read_file,并推送变更通知。Client 刷新注册表,旧名调用自动失效——Agent 重新发现后使用新名,全程无感。

    9.9 微案例:权限差异

    同一 Server 对"管理员会话"暴露 20 个工具,对"访客会话"只暴露 8 个。Client 按会话缓存不同注册表,访客机器人永远查不到危险工具——权限在发现层就隔离了。

    9.10 反例:硬编码工具名

    某 Agent 代码里写死 call_tool("get_file_contents"),Server 改名后直接报 MethodNotFound。修正:Agent 应基于最新发现结果选择工具名,而非写死。

    9.11 反例:无缓存疯狂发现

    某 Client 每次调用前都 tools/list 全量拉取,10 个 Server × 每次 50ms = 500ms 固定开销。修正:缓存 + TTL + 变更通知,把发现从"每次"降为"必要时"。

    9.12 反例:忽略 isError

    某 Agent 把 isError: true 的结果当成功继续推理,把"创建 Issue 失败"当成"已创建",通知群说完成了。修正:Agent 必须先检查 isError,再决定后续动作。

    9.14 案例深拆:多 Agent 协作中的共享注册表

    大型系统里,多个 Agent 共享一个 MCP Client 与路由注册表(如平台级编排)。此时注册表成为"公共设施":

    #mermaid-svg-IVMIHjGx2X3RuVhJ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IVMIHjGx2X3RuVhJ .error-icon{fill:#552222;}#mermaid-svg-IVMIHjGx2X3RuVhJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IVMIHjGx2X3RuVhJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .marker.cross{stroke:#333333;}#mermaid-svg-IVMIHjGx2X3RuVhJ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IVMIHjGx2X3RuVhJ p{margin:0;}#mermaid-svg-IVMIHjGx2X3RuVhJ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .cluster-label text{fill:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .cluster-label span{color:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .cluster-label span p{background-color:transparent;}#mermaid-svg-IVMIHjGx2X3RuVhJ .label text,#mermaid-svg-IVMIHjGx2X3RuVhJ span{fill:#333;color:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .node rect,#mermaid-svg-IVMIHjGx2X3RuVhJ .node circle,#mermaid-svg-IVMIHjGx2X3RuVhJ .node ellipse,#mermaid-svg-IVMIHjGx2X3RuVhJ .node polygon,#mermaid-svg-IVMIHjGx2X3RuVhJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .rough-node .label text,#mermaid-svg-IVMIHjGx2X3RuVhJ .node .label text,#mermaid-svg-IVMIHjGx2X3RuVhJ .image-shape .label,#mermaid-svg-IVMIHjGx2X3RuVhJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-IVMIHjGx2X3RuVhJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .rough-node .label,#mermaid-svg-IVMIHjGx2X3RuVhJ .node .label,#mermaid-svg-IVMIHjGx2X3RuVhJ .image-shape .label,#mermaid-svg-IVMIHjGx2X3RuVhJ .icon-shape .label{text-align:center;}#mermaid-svg-IVMIHjGx2X3RuVhJ .node.clickable{cursor:pointer;}#mermaid-svg-IVMIHjGx2X3RuVhJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .arrowheadPath{fill:#333333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IVMIHjGx2X3RuVhJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IVMIHjGx2X3RuVhJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IVMIHjGx2X3RuVhJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IVMIHjGx2X3RuVhJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .cluster text{fill:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ .cluster span{color:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IVMIHjGx2X3RuVhJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IVMIHjGx2X3RuVhJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-IVMIHjGx2X3RuVhJ .icon-shape,#mermaid-svg-IVMIHjGx2X3RuVhJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IVMIHjGx2X3RuVhJ .icon-shape p,#mermaid-svg-IVMIHjGx2X3RuVhJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IVMIHjGx2X3RuVhJ .icon-shape .label rect,#mermaid-svg-IVMIHjGx2X3RuVhJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IVMIHjGx2X3RuVhJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IVMIHjGx2X3RuVhJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IVMIHjGx2X3RuVhJ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent1 运维

    共享 Client/注册表

    Agent2 数据分析

    Agent3 客服

    GitHub Server

    Slack Server

    数据库 Server

    文件系统 Server

    好处:发现一次、全员复用;权限按 Agent 身份隔离;配额按 Agent 分配。这是"工具即服务(TaaS)"的雏形。

    9.15 案例深拆:注册表命中率与幻觉预防

    某平台观察到"工具未命中"错误率 12%,排查发现:Agent 在上下文里看到的工具清单是旧版,而注册表已更新。修复:

  • 每次会话开始时强制刷新工具清单。
  • 未命中时返回"当前可用工具:…"纠正 Agent。
  • 未命中率从 12% 降到 0.5%。
  • #mermaid-svg-jUVFmPcWMWioAEqV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jUVFmPcWMWioAEqV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jUVFmPcWMWioAEqV .error-icon{fill:#552222;}#mermaid-svg-jUVFmPcWMWioAEqV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jUVFmPcWMWioAEqV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jUVFmPcWMWioAEqV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jUVFmPcWMWioAEqV .marker.cross{stroke:#333333;}#mermaid-svg-jUVFmPcWMWioAEqV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jUVFmPcWMWioAEqV p{margin:0;}#mermaid-svg-jUVFmPcWMWioAEqV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jUVFmPcWMWioAEqV .cluster-label text{fill:#333;}#mermaid-svg-jUVFmPcWMWioAEqV .cluster-label span{color:#333;}#mermaid-svg-jUVFmPcWMWioAEqV .cluster-label span p{background-color:transparent;}#mermaid-svg-jUVFmPcWMWioAEqV .label text,#mermaid-svg-jUVFmPcWMWioAEqV span{fill:#333;color:#333;}#mermaid-svg-jUVFmPcWMWioAEqV .node rect,#mermaid-svg-jUVFmPcWMWioAEqV .node circle,#mermaid-svg-jUVFmPcWMWioAEqV .node ellipse,#mermaid-svg-jUVFmPcWMWioAEqV .node polygon,#mermaid-svg-jUVFmPcWMWioAEqV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jUVFmPcWMWioAEqV .rough-node .label text,#mermaid-svg-jUVFmPcWMWioAEqV .node .label text,#mermaid-svg-jUVFmPcWMWioAEqV .image-shape .label,#mermaid-svg-jUVFmPcWMWioAEqV .icon-shape .label{text-anchor:middle;}#mermaid-svg-jUVFmPcWMWioAEqV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jUVFmPcWMWioAEqV .rough-node .label,#mermaid-svg-jUVFmPcWMWioAEqV .node .label,#mermaid-svg-jUVFmPcWMWioAEqV .image-shape .label,#mermaid-svg-jUVFmPcWMWioAEqV .icon-shape .label{text-align:center;}#mermaid-svg-jUVFmPcWMWioAEqV .node.clickable{cursor:pointer;}#mermaid-svg-jUVFmPcWMWioAEqV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jUVFmPcWMWioAEqV .arrowheadPath{fill:#333333;}#mermaid-svg-jUVFmPcWMWioAEqV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jUVFmPcWMWioAEqV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jUVFmPcWMWioAEqV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jUVFmPcWMWioAEqV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jUVFmPcWMWioAEqV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jUVFmPcWMWioAEqV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jUVFmPcWMWioAEqV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jUVFmPcWMWioAEqV .cluster text{fill:#333;}#mermaid-svg-jUVFmPcWMWioAEqV .cluster span{color:#333;}#mermaid-svg-jUVFmPcWMWioAEqV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jUVFmPcWMWioAEqV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jUVFmPcWMWioAEqV rect.text{fill:none;stroke-width:0;}#mermaid-svg-jUVFmPcWMWioAEqV .icon-shape,#mermaid-svg-jUVFmPcWMWioAEqV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jUVFmPcWMWioAEqV .icon-shape p,#mermaid-svg-jUVFmPcWMWioAEqV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jUVFmPcWMWioAEqV .icon-shape .label rect,#mermaid-svg-jUVFmPcWMWioAEqV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jUVFmPcWMWioAEqV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jUVFmPcWMWioAEqV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jUVFmPcWMWioAEqV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    修复前: 未命中12%

    会话开始强制刷新

    未命中返回清单纠正

    修复后: 0.5%

    9.16 案例深拆:慢工具的超时与进度

    某 Agent 调用"数据分析"工具,预计 5 分钟。直接固定 10s 超时必然失败;不设超时又可能挂死。解法:

  • 工具 meta 声明 timeout_ms: 360000。
  • Server 每 30s 推进度通知。
  • Client 按"最后进度时间"动态续期超时。
  • 结果:Agent 能耐心等待长任务,且进度可见。

    9.17 案例深拆:权限差异下的发现隔离

    同一 GitHub Server:

    • 管理员会话发现 20 个工具(含 delete_repo)。
    • 只读会话发现 8 个工具(无写操作)。

    注册表按会话隔离后,只读 Agent 的上下文里根本不会出现 delete_repo——权限在源头(发现层)就被剪掉了,比"调用时拦截"更安全。

    9.18 微案例:工具灰度

    新工具 ai_code_review 先对 5% 会话暴露,观察调用成功率与耗时。灰度通过后全量;有问题则从名单移除——不重启 Server,只改发现策略。

    9.19 微案例:工具下线

    Server 要下架 legacy_export:先推送变更通知 → Client 刷新注册表 → 旧工具调用返回 MethodNotFound → Agent 改用新工具 export_v2。全程平滑过渡。

    9.20 微案例:网络分区下的降级

    Agent 与 Slack Server 网络分区,注册表中 Slack 工具全部标记"暂不可用"。Agent 改为"先记日志(文件系统 Server),网络恢复后补发"——编排层感知注册表可用性,自动走降级路径。

    9.21 微案例:多 Server 的负载均衡

    两个数据库 Server(主/读副本)提供同名 execute_query:

    execute_query → {server: db-master, weight: 10}
    execute_query → {server: db-replica, weight: 90}

    Client 按权重路由:读多写少,90% 查询走副本。写操作强制走主库(按工具 meta 的 read_only 判断)。

    9.22 推演一:如果发现延迟 10 倍

    场景:假设 tools/list 每次都要 500ms。启动时 3 个 Server = 1.5s 阻塞。若改为"懒发现"(用到才拉):

    • Agent 第一次要调用 search_code 时才拉 GitHub 清单。
    • 调用前多等 500ms,但启动不被阻塞。

    结论:懒发现适合"工具用得少"的场景,预发现适合"启动就要用"的场景。工程上常取折中:预发现热门 Server,懒发现冷门 Server。

    9.23 推演二:如果注册表没有失效机制

    场景:Server 把 create_issue 改名为 create_issue_v2,注册表不刷新。Agent 继续用旧名 → MethodNotFound → 任务失败。如果注册表有"失败触发刷新"机制:第一次失败 → 刷新 → 重试成功。失败驱动刷新是兜底保险。

    9.24 推演三:如果调用不校验参数

    场景:Agent 传了 repo 但漏了 query(search_code 必填)。不校验直接转发 → Server 报 InvalidParams → Agent 再修正 → 多一次往返。若 Client 本地校验:直接提示"缺 query",Agent 一次修正到位。校验前置省一次往返。

    9.25 推演四:如果所有 Server 共用一个会话

    场景:把 GitHub 和 Slack 塞进同一会话,工具清单混在一起。问题:权限无法区分(GitHub 的写权限泄露给 Slack 场景)、配额无法独立、故障互相牵连。会话隔离是安全底线——一个 Server 一个会话。

    9.26 反例:把发现结果写死在提示词里

    某团队把工具清单手工写进系统提示词,Server 更新后提示词没同步 → Agent 用旧工具名 → 全部 MethodNotFound。修正:清单必须来自运行时发现,提示词只描述"怎么选工具",不写死工具名。

    9.27 反例:注册表用线性扫描

    工具 200 个、Server 10 个,每次调用线性扫一遍 = 2000 次比较。虽然现代 CPU 下也不慢,但哈希表 O(1) 是底线工程素养,且扫描代码容易引入顺序 bug。

    9.28 反例:调用结果全量入上下文

    每次调用结果原样塞进上下文,20 次调用后 Token 爆掉。修正:结果摘要化、只保留关键字段、长结果外部存储。

    9.29 反例:超时一刀切

    所有工具统一 10s 超时:慢工具(数据分析)必失败,快工具(查表)浪费等待。修正:按工具 meta 分级超时。

    9.30 案例库总结

    本篇案例覆盖:四阶段主案例(运维机器人)、共享注册表、命中率优化、慢工具超时、权限隔离、工具灰度/下线、网络降级、负载均衡、四推演、六反例。结论:发现与调用的成败,80% 取决于注册表设计与描述质量,20% 取决于错误处理与降级。

    9.32 案例:跨系统工作流"代码审查到发布"

    Slack数据库GitHubClientAgentSlack数据库GitHubClientAgent#mermaid-svg-LWb6In3VHYgDb4rS{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LWb6In3VHYgDb4rS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LWb6In3VHYgDb4rS .error-icon{fill:#552222;}#mermaid-svg-LWb6In3VHYgDb4rS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LWb6In3VHYgDb4rS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LWb6In3VHYgDb4rS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LWb6In3VHYgDb4rS .marker.cross{stroke:#333333;}#mermaid-svg-LWb6In3VHYgDb4rS svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LWb6In3VHYgDb4rS p{margin:0;}#mermaid-svg-LWb6In3VHYgDb4rS .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LWb6In3VHYgDb4rS text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-LWb6In3VHYgDb4rS .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-LWb6In3VHYgDb4rS .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-LWb6In3VHYgDb4rS .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-LWb6In3VHYgDb4rS .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-LWb6In3VHYgDb4rS #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-LWb6In3VHYgDb4rS .sequenceNumber{fill:white;}#mermaid-svg-LWb6In3VHYgDb4rS #sequencenumber{fill:#333;}#mermaid-svg-LWb6In3VHYgDb4rS #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-LWb6In3VHYgDb4rS .messageText{fill:#333;stroke:none;}#mermaid-svg-LWb6In3VHYgDb4rS .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LWb6In3VHYgDb4rS .labelText,#mermaid-svg-LWb6In3VHYgDb4rS .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-LWb6In3VHYgDb4rS .loopText,#mermaid-svg-LWb6In3VHYgDb4rS .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-LWb6In3VHYgDb4rS .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-LWb6In3VHYgDb4rS .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-LWb6In3VHYgDb4rS .noteText,#mermaid-svg-LWb6In3VHYgDb4rS .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-LWb6In3VHYgDb4rS .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LWb6In3VHYgDb4rS .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LWb6In3VHYgDb4rS .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LWb6In3VHYgDb4rS .actorPopupMenu{position:absolute;}#mermaid-svg-LWb6In3VHYgDb4rS .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-LWb6In3VHYgDb4rS .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LWb6In3VHYgDb4rS .actor-man circle,#mermaid-svg-LWb6In3VHYgDb4rS line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-LWb6In3VHYgDb4rS :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}call_tool(list_pulls)tools/callPRcall_tool(get_file_contents)tools/call代码内容call_tool(execute_query, 查历史缺陷率)tools/call缺陷率 3.2%call_tool(create_review_comment)tools/call评论已加call_tool(send_message)tools/call已通知评审人

    亮点:Agent 在一次任务里横跨 3 个 Server、5 次调用,全部靠注册表路由 + schema 填参,无一行硬编码。

    9.33 案例:发现结果驱动 Agent 提示词

    某 Agent 的系统提示词在会话开始时自动拼装工具清单:

    当前可用工具:
    – GitHub: search_code(搜索代码), create_issue(创建Issue)…
    – Slack: send_message(发送消息)…
    – 数据库: execute_query(执行查询)…
    请根据任务选择合适的工具。

    工具清单随发现结果动态变化——这是"能力地图"最直接的落地。

    9.34 案例:注册表未命中的兜底体验

    Agent 幻觉调用 delete_repo(注册表无此工具,或权限不足),Client 返回:

    工具 delete_repo 不存在或不可用。当前可用工具:
    – search_code, create_issue, list_pulls, …
    请从可用工具中选择。

    Agent 据此纠正行为,任务继续而非中断——未命中兜底是 Agent 鲁棒性的关键一环。

    9.35 案例:慢工具的进度条

    "数据分析"工具运行 4 分钟,Server 每 30s 推进度:

    [进度 25%] 正在清洗数据…
    [进度 50%] 正在计算指标…
    [进度 100%] 分析完成

    Agent 看到进度后选择继续等待;Client 依据"有进度"动态续期超时。用户也能看到透明进展。

    9.36 微案例:工具搜索在 200 个工具中找"发邮件"

    Agent 不把 200 个工具全塞上下文,而是搜索"发邮件":

    search("发邮件") → [send_email(SMTP), send_slack_dm(通知)]

    只把命中工具的描述给模型,Token 省 90%,选型更准。

    9.37 微案例:灰度 5% 暴露新工具

    ai_summarize 工具先对 5% 会话暴露,A/B 观察调用成功率与耗时。通过后全量;失败则回滚名单——发现层灰度比部署灰度更轻量。

    9.38 微案例:断线重连后工具续用

    Agent 与 Server 断线,重连后重新 initialize + tools/list,注册表刷新。正在进行的任务用"幂等键 + 任务状态"续跑,不重复执行写操作。

    9.39 推演五:如果发现全部走懒加载

    场景:Agent 启动不做任何发现,用到才拉对应 Server 清单。好处:启动秒开。代价:首次调用慢。结论:混合策略最优——热门 Server 预发现,冷门懒发现。

    9.40 推演六:如果注册表命中率 80%

    场景:20% 调用未命中,每次都要"查表失败→刷新→重试"。任务耗时平均 +40%。结论:注册表命中率是核心健康指标,低于 99% 就要排查清单同步问题。

    9.41 反例:不区分身份缓存清单

    某 Client 把管理员会话的清单缓存给访客会话用 → 访客看到了危险工具名 → 尝试调用被拒。修正:缓存与身份绑定。

    9.42 反例:忽略工具下线通知

    Server 推送了 list_changed,Client 没处理 → 旧工具调用失败率上升。修正:实现变更通知处理。

    9.43 反例:审计日志为空

    出了安全事故想追责,发现没有调用审计。修正:启用全量审计(who/what/when/args 脱敏)。

    9.44 案例库总结(终版)

    案例覆盖:四阶段主案例、跨系统工作流、动态提示词、未命中兜底、慢工具进度、工具搜索、灰度暴露、断线续用、六推演、八反例。结论:发现与调用的成败,80% 取决于注册表设计与描述质量,20% 取决于错误处理与降级。

    9.45 本章小结(终版)

    通过运维机器人案例,四阶段流程从抽象变具体:初始化连菜单、发现看菜单、注册记菜单、调用点菜。深挖覆盖跨系统工作流、动态提示词、未命中兜底、进度反馈、工具搜索、灰度、断线续用、六推演、八反例——动态发现的三大价值(即插即用/变更无感/权限隔离)与完整避坑清单。


    第 10 章 本章小结与全链路衔接

    10.1 核心要点回顾

  • 四阶段:初始化→发现→注册→调用。
  • 路由注册表:工具名→Server+会话的映射,调用前查表直达。
  • 发现质量:description 与 inputSchema 决定工具命中率。
  • 调用成败:参数校验、结果处理、超时/取消、幂等。
  • 多 Server:组合出复杂能力,但需隔离与配额。
  • 挑战解法:缓存、前缀、哈希校验、退避、权限联动、trace。
  • 10.2 与 25/26 篇的衔接

    • 25 篇给了连接协议层的"骨架"(为什么有这层、谁来管)。
    • 26 篇给了协议"语法"(消息、方法、原语)。
    • 本篇给了运行时"编舞"(发现与调用的流程编排)。
    • 28 篇将深入三个典型 Server 的"工具树"长什么样。

    10.3 自测题

  • 四阶段分别是什么?每阶段的关键方法?
  • 路由注册表解决什么问题?冲突怎么处理?
  • description 为什么重要?举例说明。
  • 写操作重试怎么避免重复执行?
  • 多 Server 场景如何做故障隔离?
  • 10.4 工程检查单

    • 启动时对所有 Server 完成 initialize 与 tools/list。
    • 注册表覆盖全部工具,冲突已处理。
    • 缓存 + TTL + 变更通知已配置。
    • 调用前按 schema 校验参数。
    • 写操作支持幂等键。
    • 熔断/舱壁/限流按 Server 维度配置。
    • trace 覆盖发现与调用全链路。
    • destructive 工具二次确认已启用。

    10.6 四阶段速记卡

    阶段动作关键方法一句话
    初始化 建会话 initialize 打通通道
    发现 拉清单 tools/list 看菜单
    注册 建路由 Client 内部 记菜单
    调用 执行 tools/call 点菜

    10.7 关键设计决策清单(ADR 风格)

    决策点选项建议
    发现时机 启动/懒/定时/通知 通知驱动+启动预发现
    注册表存储 内存/分布式 单 Client 内存即可
    冲突处理 前缀/优先级/告警 前缀优先
    超时策略 统一/分级 按工具 meta 分级
    重试策略 统一/按错误 按错误类型矩阵
    写操作幂等 支持/不支持 必须支持

    10.8 常见面试题

  • MCP 如何解决 N×M 适配问题?
  • tools/list 与 tools/call 的关系?
  • 路由注册表里存什么?为什么带会话?
  • 两个 Server 有同名工具怎么处理?
  • Server 改了工具 schema,Client 怎么感知?
  • 写操作重试如何避免重复?
  • 多 Server 场景如何做故障隔离?
  • 如何防止 Agent 幻觉调用不存在的工具?
  • 10.9 FAQ

    Q1:发现一次还是每次都发现?
    缓存 + 通知驱动刷新;失败时强制刷新兜底。

    Q2:注册表放 Client 还是独立服务?
    小场景 Client 内;平台级可独立服务共享。

    Q3:同名工具一定冲突吗?
    不一定,可合并/折叠;冲突时前缀或优先级。

    Q4:调用失败就重试?
    看错误类型:参数错不重试,网络/限流退避重试。

    Q5:Server 挂了怎么办?
    熔断 + 降级 + 备用 Server;编排层感知可用性。

    10.10 端到端示例:一次完整的"查漏洞并通知"

    SlackGitHub数据库注册表ClientAgent用户SlackGitHub数据库注册表ClientAgent用户#mermaid-svg-Dy4qnSb7SmsyABtu{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Dy4qnSb7SmsyABtu .error-icon{fill:#552222;}#mermaid-svg-Dy4qnSb7SmsyABtu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Dy4qnSb7SmsyABtu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Dy4qnSb7SmsyABtu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Dy4qnSb7SmsyABtu .marker.cross{stroke:#333333;}#mermaid-svg-Dy4qnSb7SmsyABtu svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Dy4qnSb7SmsyABtu p{margin:0;}#mermaid-svg-Dy4qnSb7SmsyABtu .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Dy4qnSb7SmsyABtu text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Dy4qnSb7SmsyABtu .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Dy4qnSb7SmsyABtu .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Dy4qnSb7SmsyABtu #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Dy4qnSb7SmsyABtu .sequenceNumber{fill:white;}#mermaid-svg-Dy4qnSb7SmsyABtu #sequencenumber{fill:#333;}#mermaid-svg-Dy4qnSb7SmsyABtu #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Dy4qnSb7SmsyABtu .messageText{fill:#333;stroke:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Dy4qnSb7SmsyABtu .labelText,#mermaid-svg-Dy4qnSb7SmsyABtu .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .loopText,#mermaid-svg-Dy4qnSb7SmsyABtu .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Dy4qnSb7SmsyABtu .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Dy4qnSb7SmsyABtu .noteText,#mermaid-svg-Dy4qnSb7SmsyABtu .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Dy4qnSb7SmsyABtu .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Dy4qnSb7SmsyABtu .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Dy4qnSb7SmsyABtu .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Dy4qnSb7SmsyABtu .actorPopupMenu{position:absolute;}#mermaid-svg-Dy4qnSb7SmsyABtu .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Dy4qnSb7SmsyABtu .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Dy4qnSb7SmsyABtu .actor-man circle,#mermaid-svg-Dy4qnSb7SmsyABtu line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Dy4qnSb7SmsyABtu :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}检查线上高危漏洞启动/发现/注册(若未就绪)initialize + tools/listinitialize + tools/listinitialize + tools/list注册全部工具call_tool(execute_query, 查漏洞)命中 → 数据库tools/call3 个高危依赖call_tool(create_issue, 建Issue)tools/callIssuecall_tool(send_message, 通知群)tools/call已发送全部完成已建Issue并通知

    10.11 度量指标

    指标目标测量点
    注册表命中率 >99.5% Client
    发现耗时 <100ms Client
    调用成功率 >99% Client
    未命中率 <1% Client
    平均调用延迟 按工具 Server
    熔断次数 极少 Client

    10.12 工程落地建议(按优先级)

  • P0:四阶段跑通、注册表正确路由。
  • P0:参数校验前置、错误处理矩阵。
  • P1:缓存 + 通知刷新、幂等键。
  • P1:熔断/舱壁/配额(多 Server)。
  • P2:全链路 trace、指标看板。
  • P2:工具灰度、成本控制。
  • 10.13 反模式速查

    反模式修正
    每次调用都发现 缓存+通知
    工具名写死 动态发现
    忽略 isError 检查结果
    统一超时 分级超时
    无幂等键 写操作幂等
    全量入上下文 摘要化

    10.14 术语终表

    术语定义
    Discovery 工具发现
    Invocation 工具调用
    Registry 路由注册表
    Schema 参数结构描述
    Capability 能力声明
    Idempotency 幂等性

    10.15 本篇贡献

    源 6.4 扩展:核心概念、四阶段深挖、注册表深拆、发现/调用机制、多 Server 编排、16+ 挑战、案例库(1 主案例 + 10 深拆/微案例 + 4 推演 + 6 反例)。

    10.16 衔接下篇

    第 28 篇讲典型 MCP Server 详解(源 6.5):GitHub/数据库/浏览器的工具树长什么样,把本篇的"发现结果"落成具体清单。

    10.17 金句

    发现解决"有什么可用",调用解决"怎么用起来",注册表解决"找谁用"。

    10.18 新人计划

    读 2→3→4 理解流程;跑 9 章运维机器人案例;用 10.12 清单落地。

    10.19 性能调优

    缓存、懒发现、并行初始化、结果摘要、工具搜索。

    10.20 安全加固

    权限过滤、destructive 标注、参数校验、注入扫描、审计。

    10.21 故障演练

    杀 Server、断网络、改 schema、超时注入、限流触发。

    10.22 检查单总表

    初始化/发现/注册/调用/隔离/配额/可观测/安全(25 篇 9 扩展)。

    10.23 速记卡 v2

    四阶段、三要素(参数/路由/Server)、双保障(缓存/幂等)。

    10.24 结语

    工具发现与调用是 Agent"长出双手"的过程:协议给了手,流程让手听话。下一篇看三只典型的手长什么样。

    10.25 与行动层(第 7 章)的衔接

    源文档第 7 章(行动层,30 篇起)讲工具背后的真实执行器:API 调用、代码沙箱、数据库操作等。本篇的"调用"是协议层面的流转,行动层的"执行"是业务层面的落地——两者通过 tools/call 无缝衔接:Client 路由到位,Server 内部再把调用转成真实的执行器动作。

    10.26 全链路速览(一篇看懂)

    #mermaid-svg-F5lnXCPfLTHfqBmL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-F5lnXCPfLTHfqBmL .error-icon{fill:#552222;}#mermaid-svg-F5lnXCPfLTHfqBmL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-F5lnXCPfLTHfqBmL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-F5lnXCPfLTHfqBmL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-F5lnXCPfLTHfqBmL .marker.cross{stroke:#333333;}#mermaid-svg-F5lnXCPfLTHfqBmL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-F5lnXCPfLTHfqBmL p{margin:0;}#mermaid-svg-F5lnXCPfLTHfqBmL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL .cluster-label text{fill:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL .cluster-label span{color:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL .cluster-label span p{background-color:transparent;}#mermaid-svg-F5lnXCPfLTHfqBmL .label text,#mermaid-svg-F5lnXCPfLTHfqBmL span{fill:#333;color:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL .node rect,#mermaid-svg-F5lnXCPfLTHfqBmL .node circle,#mermaid-svg-F5lnXCPfLTHfqBmL .node ellipse,#mermaid-svg-F5lnXCPfLTHfqBmL .node polygon,#mermaid-svg-F5lnXCPfLTHfqBmL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-F5lnXCPfLTHfqBmL .rough-node .label text,#mermaid-svg-F5lnXCPfLTHfqBmL .node .label text,#mermaid-svg-F5lnXCPfLTHfqBmL .image-shape .label,#mermaid-svg-F5lnXCPfLTHfqBmL .icon-shape .label{text-anchor:middle;}#mermaid-svg-F5lnXCPfLTHfqBmL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-F5lnXCPfLTHfqBmL .rough-node .label,#mermaid-svg-F5lnXCPfLTHfqBmL .node .label,#mermaid-svg-F5lnXCPfLTHfqBmL .image-shape .label,#mermaid-svg-F5lnXCPfLTHfqBmL .icon-shape .label{text-align:center;}#mermaid-svg-F5lnXCPfLTHfqBmL .node.clickable{cursor:pointer;}#mermaid-svg-F5lnXCPfLTHfqBmL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-F5lnXCPfLTHfqBmL .arrowheadPath{fill:#333333;}#mermaid-svg-F5lnXCPfLTHfqBmL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-F5lnXCPfLTHfqBmL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-F5lnXCPfLTHfqBmL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-F5lnXCPfLTHfqBmL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-F5lnXCPfLTHfqBmL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-F5lnXCPfLTHfqBmL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-F5lnXCPfLTHfqBmL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-F5lnXCPfLTHfqBmL .cluster text{fill:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL .cluster span{color:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-F5lnXCPfLTHfqBmL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-F5lnXCPfLTHfqBmL rect.text{fill:none;stroke-width:0;}#mermaid-svg-F5lnXCPfLTHfqBmL .icon-shape,#mermaid-svg-F5lnXCPfLTHfqBmL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-F5lnXCPfLTHfqBmL .icon-shape p,#mermaid-svg-F5lnXCPfLTHfqBmL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-F5lnXCPfLTHfqBmL .icon-shape .label rect,#mermaid-svg-F5lnXCPfLTHfqBmL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-F5lnXCPfLTHfqBmL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-F5lnXCPfLTHfqBmL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-F5lnXCPfLTHfqBmL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Agent决策

    选择工具

    call_tool

    注册表路由

    Server执行

    结果回传

    Agent推理

    继续?

    任务完成

    10.27 关键成功因素(CSF)

  • 描述质量:工具被正确选中。
  • Schema 质量:参数一次填对。
  • 注册表准确:路由不串线。
  • 错误处理:失败可恢复。
  • 安全纵深:越权被拦截。
  • 10.28 团队协作分工

    角色职责
    Server 开发者 写好 description/schema
    Client 开发者 注册表/校验/重试
    平台运维 配额/灰度/可观测
    Agent 工程师 工具选择与编排

    10.29 版本演进建议

    • v1:单 Server,跑通四阶段。
    • v2:多 Server + 注册表 + 缓存。
    • v3:熔断/配额/灰度/可观测。
    • v4:工具搜索 + 成本控制 + 治理。

    10.30 本篇金句汇总

    • 发现解决"有什么可用",调用解决"怎么用起来"。
    • 描述是工具的销售文案,schema 是参数说明书。
    • 注册表让调用从"遍历猜"变成"查表直达"。

    10.32 速记卡 v3

    • 四阶段:初始化/发现/注册/调用。
    • 三要素:参数对、路由准、Server 稳。
    • 双保障:缓存刷新、幂等重试。
    • 一底线:权限过滤、审计留痕。

    10.33 结语

    工具发现与调用是 Agent"长出双手"的过程:协议给了手,流程让手听话。路由注册表是这双手的神经中枢——查表即达、失败可救、越权被拦。下一篇看三只典型的手(GitHub/数据库/浏览器 Server)长什么样。

    10.35 术语对照

    中文English备注
    工具发现 Tool Discovery tools/list
    工具调用 Tool Invocation tools/call
    路由注册表 Routing Registry 工具→Server
    能力协商 Capability Negotiation schema 填参

    10.36 三分钟回顾

  • 四阶段:初始化→发现→注册→调用。
  • 注册表:工具名→Server+会话。
  • 描述与 schema:Agent 选型与填参的依据。
  • 成败三要素:参数对、路由准、Server 稳。
  • 10.37 结语

    工具发现与调用是 Agent"长出双手"的过程:协议给了手,流程让手听话。路由注册表是神经中枢——查表即达、失败可救、越权被拦。下一篇看三只典型的手(GitHub/数据库/浏览器 Server)长什么样。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » AI Agent 工具发现与调用流程——路由注册表与四阶段调用编排
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!