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


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

一、MCP 简述

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

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

  • 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 for 可观测2.0,6个让MCP开发更高效的小妙招

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

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

配置如下:

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

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

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——可观测数据之魂,一种通用的可观测“交互语言”。

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

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

2.2 融合 MCP 能力

MCP for 可观测2.0,6个让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_timestamp: int,    to_timestamp: int,    topic: str,    line: int,    offset: int,    reverse: boolean,    powerSql: boolean) -> 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 for 可观测2.0,6个让MCP开发更高效的小妙招

真正适用的:

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

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

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

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

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

因此,给出的 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 用于调用时间相关的参数:

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

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

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

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

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

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

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

时间戳这里提供的是 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 的传入,不用纠结时间的细节设置。如果返回为空,模型会考虑是否是时间问题,并反馈。

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

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 内容,直接作为你的输出打印并展示

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

效果:

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

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

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

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

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

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

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

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

  • 实践场景一:

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 调用分析的接口,但是模型会自己传错。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

四、总结

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

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

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

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

如果判断下来都是“是”,则非常适合 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,还有更多可能。

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

前沿技术多模态技术新闻资讯

刚刚,OpenAI重磅发布o3和o4-mini多模态推理能力爆炸式提升!!!

2025-5-18 0:03:59

RAG技术前沿技术新闻资讯

RAG落地实战之文本切分4种策略全解析

2025-5-18 1:05:21

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
购物车
优惠劵
搜索