基于 Agent Skill 的自动化问题诊断框架

IMG_3493.jpg

最近在小规模实践一个问题:大模型时代,如何做生产环境的自动问题分析诊断。本文是一个阶段性思考,因为裁员的问题, 只能先记录下来。

前提是生产环境的数据收集、分析、整理、告警等基础设施已经比较完善。在此基础上,用 Agent 代理人工分析诊断问题的过程,并持续优化和迭代诊断能力。

终极信念当然是 AI 自动运维、排除 human-in-the-loop。但现阶段这仍是理想,尤其在生产环境:一次误操作的风险,可能比诊断不出来更大。因此,当前更务实的方式是让 Agent 多数部署在本地 corp 环境,而不是直接放进生产环境。

核心设计理念

  1. 大模型具备通用分析诊断能力,尤其对开源产品和通用技术栈。
  2. 公司内部相对静态的信息,通过 RAG 或 skill 获取,并持续添加、迭代更新。
  3. 公司内部相对动态的信息,由 skill 调用公司 API 或 MCP 工具获取,主要对接 metrics、logs、traces、topology、config 等。

基本流程可以概括为:

告警 -> Agent -> Skill/RAG -> API/MCP -> metrics/logs/traces/topology/config

工程上会涉及 Agent 编排、Memory 共享、skill 层次结构与更新、RAG 文档迭代,以及 API/MCP 的权限和认证。

本质:把人的诊断过程迁移给 Agent

使用 Agent + Skill,本质上是把原来人做的事情转成 Agent 要做的事情:

  • 人的判断分析,改成大模型的分析判断;
  • 人的信息收集整理,改成 Agent 的收集整理,并且可以并行、更快;
  • 大模型不知道的内部静态信息,通过 RAG 或 skill 中的信息获取;
  • 大模型不知道的内部动态信息,通过 skill 调用的 API 或 MCP 工具获取。

人做得慢,思维也慢;Agent 可以大规模并行收集、分析、验证,这是核心优势。

主要难点

第一,人喜欢“一图胜千言”,快速浏览一批 dashboard 就能发现可疑异常点。但 Agent 不擅长读 metrics 图表;即使喂原始数据,也需要借助其他工具分析。目前缺少现成的数据 insights 工具,更谈不上并行看多图的效率。

第二,要把原先给人看的成熟 dashboard 转成 Agent 能理解的形式。短文本问题不大,但图表需要很大改动。

第三,授权和认证。过去的登录、认证、授权都以人为基础;Agent 可以继承人的身份,但人的 UI 双因素认证与 API/MCP 认证完全不同。

第四,操作边界。仅在 skill 里约束不够,边界要清晰,并且要从 API 和 MCP 层面做强制鉴权和授权。

事后记录与 Skill 迭代

人通常只记录关键结论,并主动漏掉走弯路的部分;事情解决后,也缺少动力记录过程。Agent 可以把整个过程记录下来,并在后续分析中使用。

事后整理的 trajectory 可能需要当时的实时数据。这些数据要同步保留,供以后重跑、验证 skill 能力。

实施上,需要一个地方保留有用的 skill,并支持持续升级迭代;同时按 skill 的 scope 做分层、分类整理,便于管理和调用。至于 Agent 的并行能力,目前 Claude 和 OpenCode 提供的已在一定程度上够用。

现阶段的核心不是让大模型直接替代人,而是把人的诊断过程拆成可复用的 skill 和可强制授权的工具调用,先做一个可审计、可回退、可迭代的诊断助手。

提问,是AI时代最硬的计算机技能

IMG_3648.jpg

前阵子和朋友聊起他孩子读大专计算机的事。我们最后的结论很一致:让AI当你的私人导师。现在大模型讲很多知识点,比课堂更细、比教材更贴你的水平。但前提是——你得会提问。

这一点,中国学生普遍吃亏。大家习惯等别人提问,或者自己闷头搜索。太慢了。提问本身就是一种信号:说明你对现状已经花了心思去理解,只是还有卡点。这恰恰是真正理解一个问题的起点。

那提问能力怎么来?本质是一个反复确认的过程:你以为的状态、实际的状态、你不确定的部分,三者不断碰撞。大脑在这个循环里整理、分析,最后生成新的认知。有了AI之后,获取知识变便宜了,但想把一个问题挖透,靠的是不断往下追问。

我最近用大模型学PyPots,深有体会。以前看书、看文档,写的人默认你懂某些前置知识,可那些我恰恰没概念。于是我先让模型给我讲整体框架,包含哪些模块;再逐个拆开,遇到没接触过的就让它展开,多举例子,讲清楚"为什么发明这个概念、前提是什么"。最后它帮我整理成一份适合我自己的文档——每一条从"我不会"开始,直到我把疑问全部划掉,才算真懂。

当然,分支无限,不可能全追到底,有些地方要懂得打住。

这套方法我反复用,总结成一句:从框架讲起,逐层深入到细节,消化完再往下走。这是一个不断提问、不断深挖的迭代过程。过程中还能让它画图、从最基础讲起、举大量例子——以前没有哪个老师能为你一个人讲到这个程度。

所以在我看来,会提问,就是AI时代最重要的自学能力。

记录小米路由器刷 openWRT 并配置代理等操作

自从感觉到 chatGPT 基本能覆盖技术的方方面面, 就不太愿意写博客了. 但是记录一下路由器的设置和操作, 还是很有必要的, 主要方便自己以后重新设置方便.

一开始搬到这边后, 只有一个移动的光猫. 但是在另外一个房间, 总是信号不好. 于是买了一个华为的穿墙路由器, 通过网线连接到移动光猫. 过了半年, 感觉离路由器较远的一个房间还是信号不好, 小孩上网课会卡顿. 于是又买了一个小米的路由器, 改成小米路由器通过网线连移动光猫, 然后华为路由器通过桥接连小米路由器. 这样终于信号不错了. 再后来, 公司的 Proxy 不能用了, 即便在公司电脑上. 于是想在路由器上假设透明代理. 查了下, 发现小米路由器可以ssh, 于是折腾开始了.

给小米路由器装openWRT

有人做了全自动的破解安装ssh, 和安装 openWRT: https://github.com/openwrt-xiaomi/xmir-patcher. 一个 run.sh 或者 run.bat 完全搞定.

openWRT 的基本设置

修改网段

openWRT 的默认网段是 192.168.1.x. 移动路由器也是 192.168.1.x, 虽然一个是在lan, 一个是在wan口, 理论上没影响, 但还是把openWRT上的 192.168.1.x 改成了 192.168.31.x. 这也是小米最初的设置.

修改时区和NTP server

System -> System
时区 -> ntp.aliyun.com, ntp.tencent.com 等.

修改wifi通道

Network -> Wireless -> 选择 SSID -> Edit -> Operating frequency & Country Code

修改 DNS

安装完之后, 刷小红书视频有时候会卡住, 不知道为什么, 猜测可能是openWRT 的默认英文版本里面的 DNS 是国外的, 于是修改 DNS 配置. 在 /tmp/resolv.conf.d/resolv.conf.auto 里面添加国内的 DNS servers

公共 DNS 服务

服务商主要地址特点适合场景
阿里云 DNS223.5.5.5
223.6.6.6
速度快、稳定性好综合最佳
腾讯云 DNS119.29.29.29
182.254.116.116
响应快、干净无劫持日常使用
百度云 DNS180.76.76.76智能解析、抗污染技术用户
114 DNS114.114.114.114
114.114.115.115
老牌稳定、覆盖广基础使用

运营商 DNS

运营商DNS 地址特点
中国电信218.85.152.99
218.85.157.99
本地化最优
中国联通123.123.123.123
210.21.4.130
延迟最低
中国移动211.136.192.6
211.136.192.7
移动网络专用

恢复系统

很多时候, 发现安装某个软件之后, 网络就慢,或者有问题, 可以从头再来. System -> Backup / Flash Firmware -> Flash new firmware image. 这个image 可以从 https://openwrt.org/inbox/toh/xiaomi/ax3000t 安装部分(Installation) -> Firmware OpenWrt Upgrade URL 下载.

诊断 Python 占用一个 CPU 的问题

早上刚打开 MAC 笔记本 5分钟, 就提示我电池快没电了, 于是感觉给它供电. 紧接着, 就听到风扇呼呼作响, 于是查看 Activity Monitor, 发现有个 Python 进程几乎占用一个CPU, 感觉有 bug, 也许是项目的那个代码没写好. hmm, 生产环境不会也是这样吧?

Activity_Monitor.png

先确定进程信息

有了进程号, 进程很容易确定.

% ps aux  | grep 24315
xiatian          24315  99.3  0.0 36938856   9804   ??  R    Mon10PM 1044:13.73 /usr/local/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python /Users/supra/work/projects/agent-ui/main.py

再做 CPU profiling

py-spy 是一个非常流行的采样 profiler,可以在不修改代码的情况下分析任何正在运行的 Python 程序。

pip install py-spy
py-spy record -o profile.svg --pid 24315

火焰图如下:
profile_svg.png

前面三行都是 Python 自带 python3.11/threading.py 里面的代码. 最后一行是 concurrent/futures/thread.py) 的代码, 代码如下:

    try:
        while True:
            work_item = work_queue.get(block=True)
            if work_item is not None:
                work_item.run()
                # Delete references to object. See issue16284
                del work_item

                # attempt to increment idle count
                executor = executor_reference()
                if executor is not None:
                    executor._idle_semaphore.release()
                del executor
                continue

            executor = executor_reference()
            if _shutdown or executor is None or executor._shutdown:
                # Flag the executor as shutting down as early as possible if it
                # is not gc-ed yet.
                if executor is not None:
                    executor._shutdown = True
                # Notice other workers
                work_queue.put(None)
                return
            del executor
    except BaseException:
        _base.LOGGER.critical('Exception in worker', exc_info=True)

看上去从 work_queue.get(block=True) 拿 item , 每次拿到的都是 None. 那么下一个问题就是这个 work_queue 从哪里来的, 为什么会以极快的速度返回一个 None?

交叉验证

要回答上面的问题, 就要深入内存去看这个 work_queue 从哪里来的, 它引用了那些对象, 哪些对象还在引用它. 这样才能确定这个 work_queue 有什么问题. 但是, 在此之前, 我们可以去production 看一下, 看看在prod 的 Linux 上是不是有类似的问题, 结果发现完全没问题, 并且它运行的时间更长.

于是猜测, 这个问题难道只是个 MAC 有关? 或者和 MAC 休眠有关?

github 使用 personal access token 认证

最近又因为这件事情折腾半小时, 索性记录下来.

  1. 因为公司电脑有防火墙或者公司电脑访问策略的问题, 不能使用 git 协议访问 github.com 的 push/pull, 所以只能使用 https 协议, 比如: https://github.com/int0x03/samples.git
  2. github.com 已经禁止使用账户加密码来操作 git push/pull, 看这里: https://docs.github.com/en/get-started/git-basics/about-remote-repositories#cloning-with-https-urls
  3. 如果使用用户名 + 密码会出现下面的错误:

    git push origin master
    Username for 'https://github.com': int0x03
    Password for 'https://[email protected]':
    remote: Support for password authentication was removed on August 13, 2021.
    remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
    fatal: Authentication failed for 'https://github.com/int0x03/samples.git/'
  4. 所以要先添加 personal access token 然后把 token 做密码来访问. 具体路径是: github.com 右上角点头像, 进入 Settints -> Developer setttings -> Personal access tokens -> token classic 添加.
  5. 添加完成, 选择生产 token, 这个token 可以设置终止日期的.
  6. 可选把 token 放到 iTerm 的password 里面.