支持私有化部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


MCP for 可观测2.0,6个让MCP开发更高效的小妙招

发布日期:2025-05-16 08:52:03 浏览次数: 1555 作者:阿里云开发者
推荐语

掌握可观测2.0时代的关键技术,让系统分析与问题定位更高效。

核心内容:
1. 可观测2.0与MCP的融合优势
2. MCP的定义和组成要素
3. 6个MCP开发的最佳实践与工具推荐

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家

阿里妹导读


可观测近年来已经成为一个关键概念,它不仅仅局限于监控,还包括了日志记录、指标收集、分布式追踪等技术手段,旨在帮助团队更好地理解系统运行状况、快速定位问题以及优化性能。可观测2.0融合 MCP,可以让用户更好地感知系统、分析问题——用自然语言开启与系统的对话!本文将分享6个设计 MCP Server 的亲身实践,帮助大家更好地融合与使用。

一、MCP 简述

MCP 是一种开放协议,用于标准化应用程序如何向 LLM 提供上下文。可以将 MCP 视为 AI 应用程序的 USB-C 端口,就像 USB-C 提供了一种将设备连接到各种外围设备和配件的标准化方式一样,MCP 提供了一种将 AI 模型连接到不同数据源和工具的标准化方式。

  • MCP 主机 (MCP Hosts)例如 Claude Desktop、IDE 或希望通过 MCP 访问数据的 AI 工具等程序;

  • MCP 客户端 (MCP Clients)与服务器保持 1:1 连接的协议客户端;

  • MCP 服务器 (MCP Servers)轻量级程序,每个程序通过标准化的模型上下文协议 (MCP) 公开特定的功能;

  • 本地数据源 (Local Data Sources)您的计算机的文件、数据库和 MCP 服务器可以安全访问的服务;

  • 远程服务 (Remote Services)可通过互联网访问的外部系统(例如,通过 API),MCP 服务器可以连接到这些系统;

1.1 快速开始

把MCP框架理解为“大模型插件”,并且你也可以很方便地编写自己的“插件”功能。

  • [必须] 首先你需要一个支持 MCP 的 Client,参考下一章节。在本文中,使用的是 Cherry Studio [1]和DeepChat Client [2]

  • [必须] 需要准备LLM API,并准备好 API - Key。在本文中,使用的是阿里云百炼[3]。如果没有API - Key,也可以使用本地化大模型(Ollama)本地化相关功能。

  • [可选] 按需添加 MCP Server,参考下两章节。

  • [可选] 编写属于自己的 MCP Server。在 https://github.com/modelcontextprotocol仓库下,选择您期望的 SDK。添加自定义功能的 Tools,就可以启动 Server 供大模型调用了。

配置如下:

1.2 Awesome MCP Clients 推荐

完整列表参考:https://github.com/punkpeye/awesome-mcp-clients

对比参考:https://modelcontextprotocol.io/clients

笔者推荐:

1.Cherry Studio

2.DeepChat

3.AIaW

4.Cursor

5.Continue

1.3.Awesome MCP Servers 推荐

完整列表参考:

https://github.com/punkpeye/awesome-mcp-servers

文档实例列表:

https://modelcontextprotocol.io/examples

官方列表:

https://github.com/modelcontextprotocol/servers

按需添加即可。

二、MCP Server for 阿里云可观测2.0

2.1 可观测2.0

过去一年,我们迈向了通用可观测之路。从“监控”到“可观测”,不仅是技术升级,更是对复杂系统认知的深化。通过因果推理的三个层级(关联、干预、反事实),可观测性能够实现从被动观测到主动预测的能力提升。企业数字化需要将黑盒系统转化为白盒,通过采集、存储和分析多模态数据(如Log、Trace、Metric等),优化运营效率。

随着分布式系统和技术栈的复杂化,可观测性成为确保系统稳定性和性能的关键。然而,许多企业面临可观测数据混乱的问题,如缺乏标准化、数据存储分散、分析效率低及知识难以沉淀。为解决这些问题,我们提出了UModel——可观测数据之魂,一种通用的可观测“交互语言”。

UModel 基于本体论思想,通过 Set 和 Link 组成的图模型描述IT世界,定义了EntitySet、LogSet、MetricSet 等核心类型,以及 EntitySetLink、DataLink 等关联关系。它支持灵活扩展,引入 CommonSchema 降低使用门槛,并提供 Explorer、告警与事件集等功能提升易用性。UModel 不仅实现了数据的标准化和统一建模,还支持算法和大模型对数据的高效利用,助力构建全新的“可观测2.0”体系。

2.2 融合 MCP 能力

在可观测2.0中融合 MCP 能力,是一种很合适的尝试,一定程度上可以通过对话的方式,让用户对可观测2.0整体使用方式有更好的感知,并且可以协助用户感知系统、分析问题——只用自然语言交流。

2.3 效果展示

2.3.1 服务全链路分析

注:此案例部分接口使用虚拟数据。

特性如下:

  • 根据某服务,检索服务上下游、依赖的中间件和基础设施

  • 分析某服务的指标情况

  • 查询某服务是否存在错误请求trace id,并进一步智能分析

2.3.2 可观测基础信息能力查询

特性如下:

查询可观测2.0中多类信息:

  • 获取可用区

  • 查找workspace

  • 查询entity 和 topo能力

  • 查询 Umodel Schema 并生成图片展示

三、设计好 MCP Server 的亲身实践(血泪踩坑)

3.1 经验一:Tools 接口精简化、原子化

写在前面:MCP Server ≠ SDK API,是和人打交道的接口。

这里的“和人打交道”,是全方面的,无论是接口的理解,参数,还是返回,都要求简洁易懂。“三岁小孩都能懂”的 MCP Server Tools 才是好 Tools。

举个例子?:

SLS 的 getLogs SDK API 是这样的

def get_logs(    ak: str,    sk: str,    region_id: str,    project: str,    logstore:str,    query: str,    from_timestampint,    to_timestampint,    topic: str,    lineint,    offsetint,    reverseboolean,    powerSqlboolean) -> list[Any]:

这个接口如果直接给到大模型作为 Tools,可以说调用的成功率为0,因为这是一个非常复杂的接口:

1.主要的瓶颈在 query 怎么写,语法是怎样的,对模型挑战非常大。这种场景适合 A2A(Agent协作),生成可靠的 SLS query 作为一个 Agent,此处不过多展开。

2.假设我们解决了query的问题,API中的很多基础信息需要多轮对话获得:aksk、region、project、logstore,实际使用上这种环境变量级别的参数重复性非常高。

3.参数中带了时间窗口,这一点需要谨慎,详情见经验二。

4.参数中带了 topic、line、offset、reverse、powerSql 这种不常用参数,使用默认值能搞定大部分请求的参数就不带。

对于这些问题,在整体的实践后,认为在阿里云上,使用 MCP Server 和用户交互的架构,可能需要做一些改变。

朴素想法:

真正适用的:

首先,这里的 MCP Server 的生命周期应该是在用户进入到 Workspace 后,才创建。阿里云提供给用户的 MCP 交互 Client + MCP Server 是非常轻量的,一个用户、一次 Workspace 访问就是一次生命周期。而此时 MCP Server 是带上 aksk、Workspace name、region id 等环境变量信息的,里面的各种 Tools 无需关心这种基础的参数了。

然后,随着用户业务的范围,可以创建若干对应模块的 Tools 以供用户按需调用。

最后,需要把常用的操作封装 MCP Tools,而不是给出一个万能的 “query” 接口。

因此,给出的 getLogs,优化过后的 MCP Server Tools 版本应该是这样的:

A2A 模式:

def get_log_tool(    query: str,    from_timestamp: int = Field(        int(datetime.now().timestamp()) - 3600, description="from timestamp,unit is second"    ),    to_timestamp: int = Field(        int(datetime.now().timestamp()), description="to timestamp,unit is second"    )) -> list[Any]:
def gen_sls_query(    text: str,) -> str:

功能模块化模式(仅示例):

# 获取logstore的index信息def get_index():  pass
# 获得fields字段聚合的统计信息def get_fields_desc(    filterstr,    fields: List[str],    from_timestamp: int = Field(        int(datetime.now().timestamp()) - 3600, description="from timestamp,unit is second"    ),    to_timestamp: int = Field(        int(datetime.now().timestamp()), description="to timestamp,unit is second"    )) -> list[Any]:  # * and upstream_status >= 400 | SELECT request_uri, upstream_status, COUNT (*) AS cnt  # FROM log  # GROUP BY request_uri, upstream_status  # ORDER BY cnt DESC  # LIMIT 10

# 统计UVdef get_uv(    filterstr,    field: str    from_timestamp: int = Field(        int(datetime.now().timestamp()) - 3600, description="from timestamp,unit is second"    ),    to_timestamp: int = Field(        int(datetime.now().timestamp()), description="to timestamp,unit is second"    )) -> list[Any]:  # * | SELECT COUNT(DISTINCT client_ip) AS unique_visitors FROM log

这里不需要 ak、sk、project、logstore 信息的原因是,这里的 MCP 应该是在 logstore 打开的时候启动的,因此已经知道基础环境信息了。

这样的功能模块划分仅为示例,仅作说明。

3.2 经验二:Tools 接口参数默认化。慎用时间参数

案例:一个查询 SQL Query的Tools,接口是这样的:

def o11y_list_entities(    ctx: Context,    query: str = Field(default=None, description="query"),    from_timestamp: int = Field(        ..., description="from timestamp,unit is second"    ),    to_timestamp: int = Field(        ..., description="to timestamp,unit is second"    )) -> list[str]:

为了方便大模型使用,特意增加了一个 tool 用于调用时间相关的参数:

想法很好,现实很骨感,实际使用中,经常出现传入并不合法的 from to 的情况:

导致接口直接报错,因为传入不合法的参数,这种场景甚至必须重启 client 和Server。

有时也会传入离谱的时间参数,导致后续的回答并不理想:

时间戳这里提供的是 2023-06-25 00:00:00。大模型对“现在的时间”概念模糊。提供的示例对于一个只保存30天的 LogStore 来说仍然查不出数据。

更好的方式:

def o11y_list_entities(    ctx: Context,    query: str = Field(default=None, description="query"),    from_timestamp: int = Field(        int(datetime.now().timestamp()) - 3600, description="from timestamp,unit is second"    ),    to_timestamp: int = Field(        int(datetime.now().timestamp()), description="to timestamp,unit is second"    ),) -> list[str]:

直接给出最近1小时的默认值,极大概率都可以覆盖期望的查询,只需考虑 query 的传入,不用纠结时间的细节设置。如果返回为空,模型会考虑是否是时间问题,并反馈。


3.3 经验三:精简输出,避免过长的上下文输出

一些不好的例子:查询 workspace 的 list(返回500个workspace),查询某个 workspace 下接入的 entity 类型(返回200个)

MCP Server 和 SDK API 的功能不能完全等价看待,MCP 本质上是给人作为终端显示的,因此人眼看不过来(体感:大于20个的数量)都是意义不大的内容。每个接口的输出都应该控制 limit。可以考虑通过加入筛选检索,或者直接截断输出到10个。

除了体感之外,过长的 json response 会严重卡慢后续模型的输出速度、影响上下文理解效果。

以上是一般 json 接口的经验。在实践中,我们还会遇到这类场景:希望 Tools 返回一幅图(以 svg 或 png 的形式)。尝试了几种方案:

  • 直接返回<svg></svg> 的 data xml:client 不会正常显示。且会因为返回数据较大而卡慢速度。

  • 使用 MCP SDK 的 Image 类,返回"url": f"data:image/png;base64,{tool_result.data}":多数 client 不会正常显示,且需要模型是多模态模型。

  • 使用图片辅助服务,直接返回 markdown 的 url 格式:效果较好。

Args:    ctx: MCP上下文,用于访问可观测客户端    workspace_name: Workspace 名称,必须完全匹配Workspace
Returns:    ![Schema](http://localhost:9688/xxx.svg})    Schema 的 markdown 内容,直接作为你的输出打印并展示

效果:

3.4 经验四:避免 Tools 和 Tools 输入输出的链式传递

好的实践:Tool 原子能力,一个 Tool 做独立一件事。

不好的实践:Tool1 -> output -> Tool2 input -> output -> Tool3

实践中链式传递也可以做到,但有一定概率传入的参数不符合预期,且不好控制。

有一些还不错的自我修复能力是,当大模型发现参数报错的时候,会调用依赖的上一个 Tools 验证一下参数正确性。这种情况有一定概率修复,但并非完全可以。有时会执拗地认为自己没错:

在同一次问题中,通常链式传递表现尚可。如果是在同一会话中第二次询问,并不会获得第一次询问调用的接口的每一个信息,或者判断错误。

  • 实践场景一:

Tool1:查询 service 的关联上下游,返回

[    {        "id""apm@apm.service:dc7495605d8395b3788f9b54defcb826",        "type""upstream",        "name""gateway",    },    {        "id""apm@apm.service:97cd7e28783143028d7e8e9c8dbce99c",        "type""downstream",        "name""checkout",    },]

然后其他一些分析……省略

对话上下文中,第二次询问,请帮我查询 checkout 服务的信息。

模型会直接把checkout直接传入 Tool2(参数只有一个 id,并在 Prompt 注释中说明很详细)

第二次对话必须复制

apm@apm.service:97cd7e28783143028d7e8e9c8dbce99c完整,才会正确传递参数。

  • 实践场景二:

有一个 Tool 返回 trace ids,返回了一个列表:

[    "93b9111f425a4b6cab6548aa68d18f04",    "e165fede431c4c178d1e7e399c92b70d",    "ce7d4e9f74634252969adfd62b509fd6",    "e824356ddf4f42d884abe7c6a2d55d66",]

每一个值是 trace id。

期望的是模型使用每一个 trace id 调用分析的接口,但是模型会自己传错。

3.5 经验五:在接口实现开工之前,首先以模拟数据作为尝试

模型使用接口的方式,可能和预期不一样。接口的设计可能需要大量改动,才能让模型按照你想要的方式运作,尤其涉及 Tools 链式调用的时候,更要谨慎。

在设计 MCP 接口的时候,首先定义 Tools 接口信息,然后编写 Tools 的注释说明(引导 Prompt),接着按照预期实现的返回数据,mock 一些假数据直接返回。在交互的过程中不断调整接口信息、注释信息,直到假数据可以按照预期正常工作,最后再开始接口的开发,否则如果先实现接口,返工率极高,十分心痛。

3.6 经验六:有时模型会“盲目自信”、“假装工作”。适当调低 temperature

这个 case 里面,trace id 传错是第一个问题,之前(经验四)已经讲过。

在之后,又遇到了时间的坑。(经验二)

在发生错误之后,模型并不会提示问题,而是结合一些正确的接口输入输出数据,自己悄悄生成假模假样的数据……像不像论文里瞎编数据的无良大学生[狗头]。

这里上下游的数据也是假的,从 id 也能看出来。

这个问题调低 tempreture 可以缓解,但是并非可以完全解决,MCP 本质上还是依赖生成模型,而生成模型是否适合一些严肃严格场景的接口,这里稍稍打一个问号。

除此之外,观察到如果在同一对话上下文中多次问类似实体,但id不同的实体,模型似乎并不会真正调用接口了,而是直接生成 tools 的输入参数,建议用户去调(谁是老板??)。

还有一种场景是受上下文影响过大,会参考上次的输出,然后新实体的关联、上下游也和上次调用的实体关联、上下游一样(糊弄我是吧??

四、总结

MCP 是标准化 LLM 上下文交互的开放协议,包含主机、客户端、服务器及数据源组件,支持连接本地/远程服务。用户需配置支持 MCP 的客户端(如Cherry Studio)和 LLM API(如阿里云百炼),并可扩展官方/自定义 MCP 服务器。阿里云可观测2.0通过 UModel 统一多模态数据交互,解决系统复杂性带来的观测难题,实现从被动监控到主动预测的升级。

4.1 MCP Server 设计注意事项和思考

MCP 作为人、LLM、业务场景融合的媒介和工具,是新一代交互工具的萌芽,但仍然存在很多设计场景上的注意点。

如果判断下来都是“是”,则非常适合 MCP 场景。

一些不适合的场景,通过某种转化,可以变成适合的场景。比如股票交易系统不提供交易接口,只提供股票代码查询的能力,规避安全性问题。提供股票查询后,规避返回股票信息具体细节,而引导模型输出报告,模型会输出对这支股票的看多看空思路和依据,提升宽容性。

同时也可以发现,MCP 天生适合理解业务短平快的需求场景,如果想解决一个非常复杂的任务,MCP 接口可能还不够,需要 A2A + 更高级的协作、超长上下文的理解。

4.2 一些优秀的 MCP 应用场景

1.bing 搜索、Github搜索、网盘搜索等各类搜索引擎 MCP

理由:独立、简洁(返回 Top5 相关)、宽容(一定程度上)、鲁棒、安全。

2.高德地图 MCP 生成旅游路线

理由:独立、宽容(每次不同甚至有新鲜感)、鲁棒(有高德地图稳定的系统为支持)、安全。

3.Web 浏览器自动化,相关爬取、统计、分析

理由:独立、简洁(输出约束一下)、宽容、鲁棒。

4.FileSystem

理由:独立、简洁、宽容(理由是 linux 命令行 llm 非常懂,不太可能写错)、安全(不提供 rm 能力)

5.Redis

理由:独立、简洁、宽容(非严肃 Redis 数据库)

4.3 可观测2.0 + AI的未来展望

MCP 适用于短平快的独立接口能力,对于复杂需求,更适合 A2A 或更强大的模式。更多结合AI的能力,不仅仅有 MCP,可观测2.0 + AI,还有更多可能。

参考:

[1]https://github.com/CherryHQ/cherry-studio
[2]https://deepchat.thinkinai.xyz/

[3]https://help.aliyun.com/zh/model-studio/get-api-key

[4]https://modelcontextprotocol.io/introduction

[5]https://github.com/punkpeye/awesome-mcp-clients

[6]https://modelcontextprotocol.io/clients

[7]https://deepchat.thinkinai.xyz/

[8]https://help.aliyun.com/zh/model-studio/get-api-key

[9]https://github.com/punkpeye/awesome-mcp-servers

[10]https://modelcontextprotocol.io/examples

[11]https://github.com/modelcontextprotocol/servers

使用Elasticsearch的向量检索能力进行个性化推荐


在电商领域,个性化推荐系统是提高用户满意度与销售转化率的关键工具。本文将探讨如何利用Elasticsearch的向量检索能力,实现商品个性化推荐,助力电商平台提升用户体验和业务增长。    


点击阅读原文查看详情。


53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询