生产环境异常时,告警往往只有一行「504 Gateway Timeout」。把 Claude Code 接进告警链路后,日志分析、原因归纳、修复建议都能由 AI 先做一轮「急诊」,再推到钉钉或飞书群。TaoToken 负责给这套链路供模型通道,API Key 去 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 创建;随后把 Base URL 填成 https://taotoken.net/api,Claude Code 的 Skill 与 on-alert.sh 推送逻辑保持原样即可。这篇文章会在「监控通知集成」的骨架上,先把模型通道的切换单独拎出来讲清楚,再按照 send-alert.md、CLAUDE.md、on-alert.sh 的顺序,把告警分析链路在本地和钉钉群里完整跑通。
1. 生产环境告警为什么需要 AI 先做一轮「急诊」
1.1 传统监控只回答「什么坏了」
Prometheus + Alertmanager、Zabbix、CloudWatch 这类系统擅长的,是在指标越界时发出告警:CPU 飙到 95%、错误率上升、Nginx 突然冒出大量 504。它会在第一时间把你叫醒,但告警内容通常只有一行「服务挂了」。真正要回答的「为什么挂」「怎么修」,仍然需要值班工程师登录服务器、翻日志、看上下游依赖状态,才能拼出全貌。遇到日志量大或服务链路复杂的情况,这一轮排查少则十几分钟,多则一小时。
1.2 接入 Claude Code 后,告警链路能做四件事
把 Claude Code 放进通知链路后,这十几分钟的排查可以压缩成一次 AI 分析:
- 自动分析:告警触发时,Claude Code 读取最近的日志、错误栈和指标,先做一轮初步归因;
- 结构化推送:把可能原因、影响范围、建议操作整理成 Markdown 报告,推到钉钉或飞书群;
- 交互式修复:团队成员在群里触发建议请求,AI 生成具体修复命令,人工确认后执行;
- 事后总结:问题解决后,AI 根据整个排查过程生成复盘记录,方便团队沉淀根因。
这里有一个绕不开的前提:Claude Code 本身是本地 CLI,真正做分析的是模型请求,每轮分析都在消耗 Token。之前团队共用 Anthropic 官方配额,容易出现额度到达上限后告警分析静默失败,或者几个人各管各的 Key、切模型时还要逐个改环境变量。TaoToken 在这条链路里只做一件事:统一承接模型请求的出入。钉钉和飞书机器人的 Webhook 推送逻辑,完全不需要为它改动。
2. 架构与准备材料:钉钉/飞书机器人、TaoToken 的 Key
2.1 架构总览
先看整条链路的模样:
监控系统 → Webhook → on-alert.sh → claude --print 分析日志 → send-alert Skill → 钉钉/飞书机器人 → 群消息
和「用 MCP Server 让 Claude Code 主动拉取 Prometheus 指标」的深度集成相比,这条轻量级链路最容易落地:监控系统负责发现异常并把告警信息交给脚本,脚本调用 claude --print 做分析,分析结果通过 Skill 发到群聊。TaoToken 要改的只是 claude --print 背后的模型通道,其他环节原样保留。
2.2 钉钉机器人:拿 Webhook URL 和安全加签
在钉钉群里打开「群设置」→「智能群助手」→「添加机器人」,选择自定义机器人,命名成「Claude Code 告警」。安全设置推荐选「加签」,这样 Webhook 地址只有团队自己知道;如果团队里有人习惯直接复制地址分享,也可以选「自定义关键词」并把关键词设为「告警」这类稳定词。配置完成后,你会得到形如 https://oapi.dingtalk.com/robot/send?access_token=xxx 的 Webhook 地址,以及一个加签密钥。把这两项存到服务器的环境变量里,不要提交进 Git 仓库。
2.3 飞书机器人:签名校验与 IP 白名单二选一
飞书群里的路径是「群设置」→「群机器人」→「添加机器人」,同样选自定义机器人。安全设置可以选「签名校验」或「IP 白名单」:签名校验适合出口 IP 不固定的开发机,IP 白名单适合固定部署的监控服务器。配置完成后复制形如 https://open.feishu.cn/open-apis/bot/v2/hook/xxx 的 Webhook 地址。飞书机器人的权限模型比钉钉简单,不需要额外申请 token,直接把地址存到 FEISHU_WEBHOOK 环境变量即可。
2.4 在 TaoToken 创建 API Key
这是本次改造唯一要动的「模型通道」部分。打开 TaoToken 注册账号,在控制台创建一把 API Key,记作 YOUR_API_KEY。之后所有 Claude Code 请求都走 https://taotoken.net/api 这个 Base URL,注意末尾不要加 /v1。模型 ID 不要凭记忆填,以模型广场当时列表为准;同一把 Key 可以用于多台服务器,团队共用时不需要再轮流分发各种来源的密钥。
3. 让 Claude Code 走 TaoToken:环境变量与 settings.json 两种接法
3.1 环境变量方式
Claude Code 通过读取环境变量来决定模型通道。在服务器上执行:
export ANTHROPIC_BASE_URL="https://taotoken.net/api"
export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY"
export ANTHROPIC_MODEL="<模型ID>"
export DINGTALK_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=xxx"
ANTHROPIC_MODEL 的值一定要去模型广场核对,填一个不存在的模型 ID 会在首次请求时直接报 model not found,而不是等到分析完成才出错。DINGTALK_WEBHOOK 在模型通道之外,属于钉钉推送配置,和 TaoToken 无关;Claude Code 在执行 send-alert Skill 时会自动从环境变量里读取它。
3.2 用 ~/.claude/settings.json 持久化
环境变量在 SSH 会话断开或 cron 环境下容易丢失,更稳的方式是把配置写进 Claude Code 的用户配置文件:
{
"env": {
"ANTHROPIC_BASE_URL": "https://taotoken.net/api",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY",
"ANTHROPIC_MODEL": "<模型ID>",
"DINGTALK_WEBHOOK": "https://oapi.dingtalk.com/robot/send?access_token=xxx"
}
}
这样之后无论从交互式终端启动,还是由 cron 或 systemd 拉起 claude --print,Claude Code 都能读到同一套模型通道配置,不必在每个调用脚本里重复 export。需要提醒的是,任何包含密钥的文件都不要放进 Git 仓库,服务器上的 ~/.claude/settings.json 建议用 chmod 600 限制权限。
3.3 先验证通道再写 Skill
模型通道改动后,先用一条最小指令验证:
echo "只回复 OK" | claude --print
如果返回 OK,说明 TaoToken 通道已经打通。返回 401 时,优先检查 ANTHROPIC_AUTH_TOKEN 是多少把 Key 拼错了,或者 ANTHROPIC_BASE_URL 是否误写成了 https://taotoken.net/api/v1。确认无误后再继续写 Skill,可以避免后续排查时分不清问题出在模型通道还是发送逻辑。
4. 定义 send-alert.md Skill:告警报告怎么推到钉钉/飞书群
4.1 创建 Skill 文件
在 Claude Code 的项目目录或用户目录下创建 .claude/skills/send-alert.md。frontmatter 声明 name 和参数,正文告诉 AI 按平台拼 payload,再调用 curl 发送。钉钉使用 markdown 类型,飞书使用 text 类型即可满足告警推送场景。为了让消息里的引号和换行不破坏 JSON,推荐把完整 payload 写入临时文件,再用 curl -d @file 发送,而不是在命令行里手拼内联 JSON。
---
name: send-alert
description: 发送告警消息到钉钉或飞书群
parameters:
- name: message
description: 要发送的文本,支持 Markdown
required: true
- name: platform
description: dingtalk 或 feishu
required: true
---
# Skill: 发送告警
1. 从环境变量读取 webhook:
- platform=dingtalk 时读取 DINGTALK_WEBHOOK
- platform=feishu 时读取 FEISHU_WEBHOOK
2. 钉钉使用 markdown 类型,payload 为:
{"msgtype":"markdown","markdown":{"title":"Claude Code 告警","text":message}}
飞书使用 text 类型,payload 为:
{"msgtype":"text","content":message}
3. 将完整 payload 写入 /tmp/alert_payload.json,再执行:
curl -X POST "$webhook_url" -H 'Content-Type: application/json' -d @/tmp/alert_payload.json
4. 响应中出现 errcode 非 0 或 HTTP 状态码非 200 时重试一次,仍失败就把响应原文写进最终回复。
这段 Skill 的关键点在于:webhook 地址始终从环境变量读取,不在 Skill 里硬编码;AI 只负责组装 message 和选择平台,发送动作通过 curl 完成。Claude Code 在分析完日志后,会主动查找名为 send-alert 的 Skill 并执行发送。
4.2 在 CLAUDE.md 里告诉 AI 变量来源
Skill 描述的是「怎么发」,Webhook 的值则是运行环境提供的。为了便于 Claude Code 在长对话中准确定位变量来源,在 CLAUDE.md 中追加一节:
## 通知配置
- 钉钉 Webhook:环境变量 DINGTALK_WEBHOOK
- 飞书 Webhook:环境变量 FEISHU_WEBHOOK
- Webhook 只从环境变量读取,不要硬编码到代码或 Markdown
AI 在执行时看到 DINGTALK_WEBHOOK 这个变量名,就会从当前环境中读取。这样即使换一台服务器部署,也只需要修改环境变量或 settings.json,不需要改动 Skill 和 CLAUDE.md。
5. on-alert.sh:把告警触发、AI 分析、Webhook 推送串起来
5.1 告警处理脚本
脚本负责接收告警标题、告警详情、日志文件路径,把它们拼成提示词,再交给 claude --print 处理。--allowedTools 中只放开 Read 和 Bash:前者让 AI 能读取日志文件,后者让 AI 能调用 curl 完成 Webhook 发送。不要把 Edit 或更危险的工具放进去,避免 AI 在分析过程中顺手修改服务器配置。
#!/bin/bash
# 使用:ALERT_TITLE、ALERT_MESSAGE、ALERT_LOGS_FILE 作为输入
exec echo "请分析告警:标题=$ALERT_TITLE,详情=$ALERT_MESSAGE。相关日志在 @$ALERT_LOGS_FILE。请提取关键错误、给出可能原因和解决建议,然后用 send-alert Skill 把报告发到钉钉群。" | \
claude --print --allowedTools "Read,Bash"
exec 的作用是让脚本的退出码等于 claude 的退出码:如果模型请求失败,外层监控能感知到,而不是脚本静默退出并返回 0。claude --print 会读取日志内容、生成结论,再调用 send-alert Skill,整个过程不涉及数据库连接,也不修改任何系统文件。
5.2 日志检测脚本:发现 504 高频就触发分析
以 nginx 504 为例,检测脚本负责判断「最近一段时间内 504 是否出现得过于频繁」。一旦超过阈值,就导出告警环境变量并调用 on-alert.sh:
#!/bin/bash
export PATH="/usr/local/bin:$PATH"
export HOME="/root"
COUNT=$(tail -n 1000 /var/log/nginx/error.log | grep "504 Gateway Timeout" | wc -l)
if [ "$COUNT" -gt 10 ]; then
export ALERT_TITLE="Nginx 504 高频告警"
export ALERT_MESSAGE="最近检测到 $COUNT 次 504 Gateway Timeout"
export ALERT_LOGS_FILE="/var/log/nginx/error.log"
./on-alert.sh
fi
这段脚本有两个容易踩的坑。第一,cron 环境变量极简,不显式设置 PATH 会找不到 claude 命令;不设置 HOME 会导致 Claude Code 找不到 ~/.claude 配置。第二,告警消息只传日志文件路径而不是整个日志内容,避免单次请求携带过多 Token;AI 需要分析时自己读取文件,效率更高。
5.3 Alertmanager 触发方式
如果你已经在用 Prometheus + Alertmanager,可以在 receiver 里配置 webhook:
receivers:
- name: claude-code
webhook_configs:
- url: http://127.0.0.1:5000/alert
再写一个极简 Node 服务接收 Alertmanager 的 POST,把告警字段转成环境变量后调用 on-alert.sh:
const http = require('http');
const { execFileSync } = require('child_process');
http.createServer((req, res) => {
let body = '';
req.on('data', (c) => (body += c));
req.on('end', () => {
const alert = JSON.parse(body);
process.env.ALERT_TITLE = alert.title || 'Unknown';
process.env.ALERT_MESSAGE = alert.message || '';
execFileSync('./on-alert.sh', { stdio: 'inherit' });
res.end('ok');
});
}).listen(5000);
这个服务本身没有任何鉴权,正式使用时要加一层内部 token 校验,否则内网任意 POST 都能触发一次 AI 分析和一次钉钉推送。
6. 实战:自动分析 nginx 504 错误日志并推送
6.1 组合成完整告警链路
把 5.1 和 5.2 的脚本放在同一目录,检测脚本通过 cron 每分钟执行一次。命中告警后,claude --print 会拿到日志文件路径,AI 读取、分析、生成结论,再调用 send-alert Skill 推送到钉钉群。这个流程中,模型请求走的是 TaoToken,每次分析产生的费用和调用记录可以在 TaoToken 控制台里查到。
6.2 钉钉群收到的报告长这样
一条典型的告警推送大致是:
[Claude Code 告警] Nginx 504 高频告警
- 最近检测到 23 次 504 Gateway Timeout
- 高频错误:upstream timed out (110: Connection timed out) while connecting to upstream
- 可能原因:后端 192.168.20.15:8080 响应慢,当前连接数偏高
- 建议:检查后端负载,临时调大 proxy_read_timeout,必要时扩容
这个报告不是模板生成的,而是 AI 基于实际日志内容归纳的。不同时段日志里的错误分布可能不同,AI 会优先挑选出现频率最高的错误行,再结合上游状态码做归因。告警标题、错误消息、建议命令三项的内容都会随日志变化,而不是每次固定输出同一句话。
6.3 三个常见坑
- 钉钉机器人返回 403:启用加签后,Webhook 请求必须带
timestamp和sign参数,只复制access_token会一直 403。send-alert Skill 里需要让 AI 先去环境变量读取DINGTALK_SECRET,按钉钉加签规则生成签名参数。 claude --print返回 401:检查ANTHROPIC_AUTH_TOKEN是否真的来自 TaoToken 控制台,以及ANTHROPIC_BASE_URL是否误写成了https://taotoken.net/api/v1。- 请求报 model not found:模型 ID 填错。请到 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 模型广场核对当时的模型名称,不要凭记忆填。
7. 交互式修复与 MCP 扩展:群里回复 /suggest-fix 的安全边界
7.1 建议模式而不是执行模式
从钉钉或飞书群里直接触发 AI 执行修复命令,权限风险很高。更稳妥的做法是让 AI 只生成建议命令,例如用户回复 /suggest-fix,AI 根据告警生成:
sudo sed -i 's/proxy_read_timeout 60s;/proxy_read_timeout 120s;/' /etc/nginx/nginx.conf && sudo nginx -s reload
然后由 SRE 在服务器上确认后执行。这个模式的好处是:AI 负责推理和命令生成,人工负责变更执行,责任边界清晰。原文提到的「群里回复 /fix 自动修复」需要机器人接收消息回调,涉及群消息读取权限、命令白名单、确认码机制,复杂度高出不少,不建议在告警场景直接使用。
7.2 用 MCP Server 封装 send_dingtalk 工具
如果团队希望把告警通知做成可复用的通用能力,可以写一个极简 MCP Server,只暴露一个 send_dingtalk 工具。工具接收 message 参数,内部读取环境变量 DINGTALK_WEBHOOK,POST 到钉钉机器人,工具结构大致如下:
{
"name": "send_dingtalk",
"description": "发送消息到钉钉群",
"inputSchema": {
"type": "object",
"properties": {
"message": { "type": "string" }
},
"required": ["message"]
}
}
这个 MCP Server 只封装 Webhook 发送,不接数据库、不做文件操作、不执行系统命令,权限面很小。相比让 AI 每次都理解和拼接 curl,MCP 方式把发送逻辑固化成工具调用,参数更明确,也更容易被反复使用。
7.3 授权机制的三层设计
如果未来要做「从群里触发 AI 命令」,建议至少做三层。第一,机器人消息回调地址要有 token 校验,不接受任何未包含正确 token 的请求。第二,能触发 AI 分析的群成员要维护白名单,不能让所有群成员都能叫停或触发告警分析。第三,AI 生成的每条命令都要回显到群里,由人工确认后才执行。缺任何一层,告警机器人最后都会变成生产服务器上无人值守的后门。前期用「建议模式」跑几周,确认 AI 生成的命令足够稳定后,再考虑是否需要自动化执行。
8. 成本、安全与完整案例:飞书 + Prometheus + Claude Code
8.1 控制 Token 成本的手段
Claude Code 每次分析都在消耗模型 Token,成本主要由日志大小和模型单价决定。控制成本的思路有三个:加冷却窗口,10 分钟内相同告警只分析一次,防止告警风暴连带触发 AI 风暴;预过滤日志,只把 grep 出来的错误行交给 AI,而不是把整个 error.log 倒进去;模型选择以 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 模型广场当时列表为准,不同模型定价不同,高频小告警选更经济的模型,深度复盘时再换更大模型。这三个手段可以组合使用,重复告警走冷却,频繁小告警走小模型,严重告警才升级到深度分析。
8.2 Webhook 安全
钉钉机器人的加签、飞书机器人的签名校验或 IP 白名单,都是必须做的。Webhook 地址一律存环境变量,任何 Skill、脚本、Markdown 文档里都不要硬编码。一旦发现某个 Webhook 地址被提交到公开仓库,要立刻到管理后台重置机器人并换地址,不要指望删除 commit 来补救,因为地址可能已经被爬虫收录。send-alert Skill 中读取 Webhook 的逻辑,也尽量优先使用环境变量,而不是要求 AI 从会话上下文中猜测。
8.3 完整案例:飞书 + Prometheus + Claude Code
最后把整条链路串起来看一个完整场景。Prometheus 检测到 http_requests_total{status=500} 在 5 分钟内增长 500%,Alertmanager 触发 webhook,本地服务读取最近 2000 行 error.log 并 grep 出 500 相关记录,交给 claude --print。Claude Code 分析后给出结论:空指针异常位于 src/OrderController.java:57,原因是未校验用户输入,建议增加判空。飞书机器人把结论推到 #production-alerts 群,SRE 看到消息后直接根据建议修改代码并上线。从告警触发到群里出现分析结果,通常在一分钟以内;这一轮分析产生的模型请求经由 TaoToken 进出,控制台可以清晰看到对应的调用记录和 Token 消耗。
这次告警分析跑完后,回 TaoToken 控制台 看一眼刚才 claude --print 的调用记录,核对模型 ID 与消耗是否符合预期。要在浏览器里先用同一把 Key 发一条消息验证模型效果,可以打开 模型对话;团队要长期跑告警分析和后续的 GitHub 接入,建议看看 Coding Plan 的套餐是否够用;Claude Code 环境变量与 settings.json 的完整对照,见 接入文档。




被折叠的 条评论
为什么被折叠?



