机缘、收获与憧憬:一个运维开发者的创作自述
一、机缘2021 年 11 月我在 CSDN 注册了账号。那时候写的东西很杂有 JetBrains IDE 接入 DeepSeek 的教程有 OpenWebUI 源码部署的踩坑记录也有 AnythingLLM 接入硅基流动的配置笔记。那时候我更像是一个工具配置记录员——哪个工具火就试着部署一下把过程写下来。真正的转折发生在去年。我在一个 AIOps 项目里负责日志告警分析模块。需求听起来不复杂让大模型从运维日志里提取服务名、日志级别、错误码然后自动查询 ELK、Zabbix生成一份告警报告。我一开始走的路很简单调 OpenAI API写一段 prompt把日志文本塞进去解析返回结果。但很快发现这条路走不通输出格式不稳定今天是 JSON明天是 markdown日志一复杂模型就开始 hallucination编出一些不存在的字段想接 Zabbix、Jenkins、JumpServer 这些系统时代码越写越乱正是在这个节点上我开始认真理解MCPModel Context Protocol和LangChain这些东西。不是为了追热点是因为手里的 AIOps 项目真的需要把大模型和运维系统连接起来。从那以后我的博客定位慢慢清晰了一个运维开发者记录自己怎么把 AI 落地到运维场景里。二、收获写到现在我的博客有 32 篇原创文章520 个点赞378 个收藏222 个粉丝总排名 25911。数据不算亮眼但对我自己来说这几件事很有价值1. 有了自己的知识库我建了几个专栏AIOps 实战笔记7 篇7403 阅读128 收藏核心专栏记录 Dify ELK/Zabbix/Jenkins/JumpServer 的实战架构LLM 工具与开源8 篇11535 阅读74 收藏dbskiter、K8sSkill、n8n、OpenWebUI 这些工具运维开发从 0 到 16 篇4789 阅读59 收藏K8s、Grafana、Zabbix-MCP 等基础能力运维人的发展3 篇偏思考比如《上线 AIOps 半年后告警变多了》《同事离职后我像个实习生》现在遇到问题我第一反应是去翻自己之前的文章。这比查搜索引擎快多了。2. 写作倒逼我把事情想明白很多方案脑子里想的时候觉得行真要写成文章给别人看就会发现漏洞。比如写 Zabbix-MCP 那篇时我原本以为只读查询这个原则很简单但写到权限控制、审计、自然语言解析这些细节时才发现要考虑的东西比想象中多。3. 收到了真实的反馈有几篇文章下面有朋友留言“您的工作流设计图能分享吗”“这些功能具体怎么操作实现的能写一下吗付费也行”这种反馈让我意识到写的东西真的有人在看、有人想用。这比点赞数字更让我有动力。三、日常我的主业是运维开发白天处理告警、写脚本、维护 AIOps 平台。学习和写博客主要靠晚上和周末。我的创作节奏很朴素工作日晚上如果当天解决了某个具体问题就把关键代码和报错记下来周末集中整理成文章补架构图和总结不追热点只写自己真实做过、真实踩过坑的东西平衡创作和工作的秘诀只有一个写作不是额外任务而是学习过程的一部分。我不为了发文而学习我因为学习而记录。四、成就过去这一年我觉得自己做得最扎实的一件事是慢慢搭起了一套AIOps 的 MCP 工具生态ELK-MCP让大模型通过自然语言查询 Elasticsearch 日志Zabbix-MCP告警数据的只读查询中台Grafana Query MCP把自然语言转成 Prometheus/Grafana 查询dbskiter开源的数据库运维 CLI 工具集K8sSkill基于自然语言的 Kubernetes 诊断工具这些工具都有一个共同特点不是 demo是为了解决真实运维场景里的具体问题。下面这段代码是我觉得最能代表这一年思路的片段——一个简单的 MCP 工具查询入口体现了只读、受控、可审计的设计原则 文件功能MCP 工具查询入口示例 主要类/函数MCPQueryHandler fromtypingimportDict,AnyclassMCPQueryHandler: MCP 工具统一查询处理器 设计原则 1. 只读禁止任何写入、删除、修改操作 2. 受控所有查询必须带用户身份和权限范围 3. 可审计每次查询记录日志便于回溯 def__init__(self,user:str,allowed_indices:list):self.useruser self.allowed_indicesallowed_indices self.audit_log[]defquery(self,tool_name:str,params:Dict[str,Any])-Dict[str,Any]:执行一次受控的 MCP 查询# 1. 记录审计日志self.audit_log.append({user:self.user,tool:tool_name,params:params,})# 2. 根据工具名分发iftool_nameelk_search:returnself._query_elk(params)eliftool_namezabbix_alert:returnself._query_zabbix(params)else:return{error:f未授权的工具:{tool_name}}def_query_elk(self,params:Dict[str,Any])-Dict[str,Any]:查询 ELK 日志indexparams.get(index)ifindexnotinself.allowed_indices:return{error:无权限访问该索引}# 实际项目中这里调用 Elasticsearch 客户端return{tool:elk_search,index:index,total:3,logs:[...],}def_query_zabbix(self,params:Dict[str,Any])-Dict[str,Any]:查询 Zabbix 告警return{tool:zabbix_alert,host:params.get(host),alerts:[...],}这段代码不复杂但它体现了我过去一年最核心的转变从调用大模型 API到搭建可落地的 AIOps 工具链。五、憧憬接下来几个月我有几个明确的计划深入学习 LangGraph不只是 LangChain而是把状态管理、持久化、多 Agent 协作这些概念补全扩展 MCP 生态把更多运维系统比如 Prometheus、Nacos、Jenkins通过 MCP 接入大模型把 dbskiter 做扎实从数据库运维 CLI 工具往智能化诊断方向再进一步继续写真实笔记不写空泛的教程只记录真实项目里的选择和取舍运维这条路做了五年我越来越觉得技术的价值不在于它有多新而在于它能帮上多少忙。写博客也是如此。如果我的文章能让另一个运维开发者在凌晨两点的告警群里少踩一个坑那这些文字就是有意义的。继续写下去。