💡 摘要: 每天早上花1小时写运维日报------采集监控数据、整理指标、做PPT、发邮件,这是很多运维同学的日常。本文基于我在某电商平台运维团队的真实项目,介绍如何使用腾讯云 WorkBuddy + CodeBuddy 双引擎协作,实现运维日报全自动化:CodeBuddy Code(CLI) 编写数据采集分析脚本,WorkBuddy 定时执行采集任务、自动生成PPT日报,Claw 远程触发让外出也能随时查看。从人工1小时到AI全自动5分钟,日报生成效率提升92%。包含4个实操步骤、3张架构图、4个踩坑案例,适合运维工程师、DevOps和技术负责人阅读。
📅 技术栈版本: WorkBuddy v5.1+ | CodeBuddy Code v4.21+ | Python 3.11 | Prometheus | 更新时间: 2026-06
一、背景:每天1小时的运维日报之痛
1.1 一个运维人的早晨
每天早上8:30,我的工作从打开 Grafana 面板开始。然后是:
| 步骤 | 操作 | 耗时 |
|---|---|---|
| 采集数据 | 登录5套监控系统,截图关键指标 | 15分钟 |
| 整理数据 | 把数据填入Excel,计算同比环比 | 20分钟 |
| 制作PPT | 把截图和表格贴进日报模板 | 15分钟 |
| 发送邮件 | 写邮件正文,附上PPT,发送给团队 | 10分钟 |
每天1小时,每月22小时,每年264小时------相当于33个工作日,整整一个多月的时间,全部花在了重复性的日报工作上。
更让人崩溃的是,有一次我请假,同事代写日报时数据采集遗漏了Redis集群的指标,导致线上Redis内存告警被延迟发现,差点引发故障。
1.2 为什么不用现成的自动化工具?
市面上确实有不少运维报表工具,但我们的场景有几个特殊需求:
- 数据源分散:Prometheus + Grafana + 腾讯云云监控 + 自研日志平台,4套系统
- 格式要求严格:日报必须用公司统一PPT模板,包含特定图表和文字格式
- 灵活性强:不同日期关注的指标不同(大促期间加关注支付成功率,平时关注CPU/内存)
- 远程触发:外出时需要通过微信快速查看当日日报
这些需求,单一工具很难覆盖。而 WorkBuddy + CodeBuddy 的组合,恰好能互补解决。
1.3 效率对比
| 指标 | 人工模式 | 双引擎自动化 | 改善 |
|---|---|---|---|
| 日报生成时间 | 60分钟 | 5分钟 | 缩短92% |
| 数据遗漏率 | 15% | 0% | 彻底消除 |
| PPT格式一致性 | 70% | 100% | 模板化保证 |
| 人力成本/月 | 22小时 | 1小时(维护) | 省21小时 |
💡 腾讯云成本提示 : 运维日报自动化后,每月节省21小时人力。按运维工程师月薪18K(时薪约103元)计算,月节省约2,163元。更重要的是,数据遗漏率降为0,避免了因遗漏告警导致的线上故障风险------一次P2故障的平均处理成本约5,000元。
二、架构设计:双引擎协作方案
2.1 整体架构
#mermaid-svg-0KqvB09XlGh1Q6le{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0KqvB09XlGh1Q6le .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0KqvB09XlGh1Q6le .error-icon{fill:#552222;}#mermaid-svg-0KqvB09XlGh1Q6le .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0KqvB09XlGh1Q6le .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0KqvB09XlGh1Q6le .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0KqvB09XlGh1Q6le .marker.cross{stroke:#333333;}#mermaid-svg-0KqvB09XlGh1Q6le svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0KqvB09XlGh1Q6le p{margin:0;}#mermaid-svg-0KqvB09XlGh1Q6le .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0KqvB09XlGh1Q6le .cluster-label text{fill:#333;}#mermaid-svg-0KqvB09XlGh1Q6le .cluster-label span{color:#333;}#mermaid-svg-0KqvB09XlGh1Q6le .cluster-label span p{background-color:transparent;}#mermaid-svg-0KqvB09XlGh1Q6le .label text,#mermaid-svg-0KqvB09XlGh1Q6le span{fill:#333;color:#333;}#mermaid-svg-0KqvB09XlGh1Q6le .node rect,#mermaid-svg-0KqvB09XlGh1Q6le .node circle,#mermaid-svg-0KqvB09XlGh1Q6le .node ellipse,#mermaid-svg-0KqvB09XlGh1Q6le .node polygon,#mermaid-svg-0KqvB09XlGh1Q6le .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0KqvB09XlGh1Q6le .rough-node .label text,#mermaid-svg-0KqvB09XlGh1Q6le .node .label text,#mermaid-svg-0KqvB09XlGh1Q6le .image-shape .label,#mermaid-svg-0KqvB09XlGh1Q6le .icon-shape .label{text-anchor:middle;}#mermaid-svg-0KqvB09XlGh1Q6le .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0KqvB09XlGh1Q6le .rough-node .label,#mermaid-svg-0KqvB09XlGh1Q6le .node .label,#mermaid-svg-0KqvB09XlGh1Q6le .image-shape .label,#mermaid-svg-0KqvB09XlGh1Q6le .icon-shape .label{text-align:center;}#mermaid-svg-0KqvB09XlGh1Q6le .node.clickable{cursor:pointer;}#mermaid-svg-0KqvB09XlGh1Q6le .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0KqvB09XlGh1Q6le .arrowheadPath{fill:#333333;}#mermaid-svg-0KqvB09XlGh1Q6le .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0KqvB09XlGh1Q6le .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0KqvB09XlGh1Q6le .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0KqvB09XlGh1Q6le .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0KqvB09XlGh1Q6le .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0KqvB09XlGh1Q6le .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0KqvB09XlGh1Q6le .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0KqvB09XlGh1Q6le .cluster text{fill:#333;}#mermaid-svg-0KqvB09XlGh1Q6le .cluster span{color:#333;}#mermaid-svg-0KqvB09XlGh1Q6le div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0KqvB09XlGh1Q6le .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0KqvB09XlGh1Q6le rect.text{fill:none;stroke-width:0;}#mermaid-svg-0KqvB09XlGh1Q6le .icon-shape,#mermaid-svg-0KqvB09XlGh1Q6le .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0KqvB09XlGh1Q6le .icon-shape p,#mermaid-svg-0KqvB09XlGh1Q6le .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0KqvB09XlGh1Q6le .icon-shape .label rect,#mermaid-svg-0KqvB09XlGh1Q6le .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0KqvB09XlGh1Q6le .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0KqvB09XlGh1Q6le .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0KqvB09XlGh1Q6le :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Claw - 远程触发
WorkBuddy - 自动化执行
CodeBuddy Code - 脚本开发
数据源层
Prometheus
应用指标
腾讯云监控
基础设施指标
自研日志平台
业务指标
数据采集脚本
fetch_metrics.py
数据分析脚本
analyze_metrics.py
定时任务
每天8:00触发
数据采集
调用Python脚本
PPT生成
填充模板+图表
邮件发送
自动发送日报
微信消息触发
实时查看日报

2.2 分工逻辑
| 组件 | 职责 | 为什么选它 |
|---|---|---|
| CodeBuddy Code | 编写数据采集/分析Python脚本 | 擅长代码生成,脚本开发效率高 |
| WorkBuddy | 定时任务、PPT生成、邮件发送 | 擅长文件操作和自动化流程 |
| Claw | 微信远程触发 | 随时随地查看日报 |
核心思路:CodeBuddy 负责"写代码",WorkBuddy 负责"跑流程",Claw 负责"远程控制"。三者各司其职,1+1+1 > 3。
三、Step1:CodeBuddy Code 编写监控数据采集脚本
3.1 用 CodeBuddy Code 生成采集脚本

打开终端,启动 CodeBuddy Code 的 CLI 模式:
bash
codebuddy code
输入需求描述:
编写一个Python脚本 fetch_metrics.py,功能如下:
1. 从 Prometheus API 采集以下指标:
- CPU使用率(node_cpu_seconds_total)
- 内存使用率(node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
- HTTP请求QPS(http_requests_total rate 5m)
- 接口平均响应时间(http_request_duration_seconds_sum rate 5m)
2. 从腾讯云监控API采集:
- CVM实例状态
- CDB连接数和慢查询数
3. 输出JSON格式的采集结果,保存到 /data/daily_metrics.json
4. 支持命令行参数指定日期范围
5. 异常处理:API超时重试3次,失败记录错误日志
CodeBuddy Code 生成的核心代码:
python
"""运维日报数据采集脚本 - 从多数据源采集监控指标"""
import requests
import json
import argparse
import logging
from datetime import datetime, timedelta
from typing import Dict, Any
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
PROMETHEUS_URL = "http://prometheus.internal:9090"
TENCENT_CLOUD_SECRET_ID = "${TENCENT_SECRET_ID}"
TENCENT_CLOUD_SECRET_KEY = "${TENCENT_SECRET_KEY}"
def fetch_with_retry(url: str, params: Dict = None, max_retries: int = 3) -> Dict:
"""带重试的HTTP请求"""
for attempt in range(max_retries):
try:
resp = requests.get(url, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
logger.warning(f"请求失败(第{attempt+1}次): {e}")
if attempt == max_retries - 1:
raise
return {}
def fetch_prometheus_metrics(end_time: datetime) -> Dict[str, Any]:
"""从Prometheus采集应用指标"""
start_time = end_time - timedelta(days=1)
metrics = {}
# CPU使用率
cpu_query = '100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)'
result = fetch_with_retry(
f"{PROMETHEUS_URL}/api/v1/query",
params={"query": cpu_query}
)
metrics["cpu_usage"] = parse_prometheus_result(result)
# 内存使用率
mem_query = '(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100'
result = fetch_with_retry(
f"{PROMETHEUS_URL}/api/v1/query",
params={"query": mem_query}
)
metrics["memory_usage"] = parse_prometheus_result(result)
# HTTP QPS
qps_query = 'sum(rate(http_requests_total[5m]))'
result = fetch_with_retry(
f"{PROMETHEUS_URL}/api/v1/query",
params={"query": qps_query}
)
metrics["http_qps"] = parse_prometheus_result(result)
# 平均响应时间
rt_query = 'avg(rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]))'
result = fetch_with_retry(
f"{PROMETHEUS_URL}/api/v1/query",
params={"query": rt_query}
)
metrics["avg_response_time"] = parse_prometheus_result(result)
return metrics
def fetch_tencent_cloud_metrics() -> Dict[str, Any]:
"""从腾讯云监控API采集基础设施指标"""
# 实际项目中使用 tencentcloud-sdk-python
# 此处简化展示核心逻辑
metrics = {
"cvm_instances": {
"running": 12,
"stopped": 1
},
"cdb_metrics": {
"active_connections": 156,
"slow_queries": 3
}
}
logger.info("腾讯云监控数据采集完成")
return metrics
def parse_prometheus_result(result: Dict) -> Any:
"""解析Prometheus查询结果"""
try:
return result["data"]["result"][0]["value"][1]
except (KeyError, IndexError):
return "N/A"
def main():
parser = argparse.ArgumentParser(description="运维日报数据采集")
parser.add_argument("--date", type=str, default=None,
help="采集日期,格式YYYY-MM-DD,默认昨天")
args = parser.parse_args()
end_time = datetime.strptime(args.date, "%Y-%m-%d") if args.date \
else datetime.now().replace(hour=0, minute=0, second=0)
logger.info(f"开始采集 {end_time.strftime('%Y-%m-%d')} 的监控数据")
# 采集数据
prom_metrics = fetch_prometheus_metrics(end_time)
cloud_metrics = fetch_tencent_cloud_metrics()
# 汇总结果
report = {
"date": end_time.strftime("%Y-%m-%d"),
"generated_at": datetime.now().isoformat(),
"prometheus": prom_metrics,
"tencent_cloud": cloud_metrics
}
# 保存结果
output_path = "/data/daily_metrics.json"
with open(output_path, "w", encoding="utf-8") as f:
json.dump(report, f, ensure_ascii=False, indent=2)
logger.info(f"数据采集完成,结果已保存到 {output_path}")
if __name__ == "__main__":
main()
脚本设计为命令行工具,方便 WorkBuddy 的定时任务调用。
--date参数支持指定日期,Claw 远程触发时可以灵活指定。重试机制确保网络抖动不会导致采集失败。
3.2 用 CodeBuddy Code 生成分析脚本
编写 analyze_metrics.py,读取 /data/daily_metrics.json,
计算同比环比变化,输出结构化的日报摘要。
CodeBuddy Code 生成的分析脚本,核心功能是将原始指标数据转化为日报所需的摘要信息,包含同比环比计算、异常标注、趋势判断。这里不再展开完整代码。
四、Step2:WorkBuddy 创建定时任务
4.1 配置定时采集

在 WorkBuddy 中创建定时任务,每天早上8:00自动执行数据采集:
请创建一个定时任务,每天早上8:00执行以下操作:
1. 运行 Python 脚本 /scripts/fetch_metrics.py
2. 运行分析脚本 /scripts/analyze_metrics.py
3. 如果采集失败,发送告警消息到企业微信群
WorkBuddy 会自动创建定时任务配置,支持 Cron 表达式和可视化编辑两种方式。
4.2 定时任务执行流程
WorkBuddy引擎 腾讯云监控 Prometheus API Python脚本 WorkBuddy定时器 WorkBuddy引擎 腾讯云监控 Prometheus API Python脚本 WorkBuddy定时器 #mermaid-svg-HEOth0DuU8jHBYFg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HEOth0DuU8jHBYFg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HEOth0DuU8jHBYFg .error-icon{fill:#552222;}#mermaid-svg-HEOth0DuU8jHBYFg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HEOth0DuU8jHBYFg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HEOth0DuU8jHBYFg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HEOth0DuU8jHBYFg .marker.cross{stroke:#333333;}#mermaid-svg-HEOth0DuU8jHBYFg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HEOth0DuU8jHBYFg p{margin:0;}#mermaid-svg-HEOth0DuU8jHBYFg .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HEOth0DuU8jHBYFg text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-HEOth0DuU8jHBYFg .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-HEOth0DuU8jHBYFg .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-HEOth0DuU8jHBYFg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-HEOth0DuU8jHBYFg .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-HEOth0DuU8jHBYFg #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-HEOth0DuU8jHBYFg .sequenceNumber{fill:white;}#mermaid-svg-HEOth0DuU8jHBYFg #sequencenumber{fill:#333;}#mermaid-svg-HEOth0DuU8jHBYFg #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-HEOth0DuU8jHBYFg .messageText{fill:#333;stroke:none;}#mermaid-svg-HEOth0DuU8jHBYFg .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HEOth0DuU8jHBYFg .labelText,#mermaid-svg-HEOth0DuU8jHBYFg .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-HEOth0DuU8jHBYFg .loopText,#mermaid-svg-HEOth0DuU8jHBYFg .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-HEOth0DuU8jHBYFg .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-HEOth0DuU8jHBYFg .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-HEOth0DuU8jHBYFg .noteText,#mermaid-svg-HEOth0DuU8jHBYFg .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-HEOth0DuU8jHBYFg .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HEOth0DuU8jHBYFg .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HEOth0DuU8jHBYFg .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HEOth0DuU8jHBYFg .actorPopupMenu{position:absolute;}#mermaid-svg-HEOth0DuU8jHBYFg .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-HEOth0DuU8jHBYFg .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HEOth0DuU8jHBYFg .actor-man circle,#mermaid-svg-HEOth0DuU8jHBYFg line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-HEOth0DuU8jHBYFg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 8:00 触发 fetch_metrics.py查询应用指标返回CPU/内存/QPS/RT数据查询基础设施指标返回CVM/CDB数据保存 daily_metrics.json执行 analyze_metrics.py保存 daily_summary.json触发PPT生成任务生成日报PPT触发邮件发送
五、Step3:WorkBuddy 自动生成 PPT 日报
5.1 PPT 模板设计
先准备好公司统一的日报PPT模板,包含以下占位符:
| 页面 | 占位符 | 数据来源 |
|---|---|---|
| 封面 | {{date}} | 采集日期 |
| 系统概览 | {{cpu_avg}}, {{mem_avg}}, {{qps_avg}} | Prometheus |
| 异常标注 | {{alerts}} | 分析脚本 |
| 基础设施 | {{cvm_status}}, {{cdb_status}} | 腾讯云监控 |
| 趋势对比 | {{trend_chart}} | 分析脚本 |
5.2 WorkBuddy 生成 PPT

在 WorkBuddy 中输入:
请根据 /data/daily_summary.json 的数据,使用 /templates/daily_report.pptx 模板,
生成今日运维日报PPT,保存到 /reports/ 目录。
要求:
1. 将数据填充到模板对应位置
2. CPU使用率超过80%的标红
3. 慢查询数超过10的标红
4. 生成趋势对比图表
WorkBuddy 会自动读取模板和数据,生成格式规范的PPT日报。关键指标异常时自动标红,一目了然。




5.3 自动发送邮件
PPT生成后,WorkBuddy 自动发送邮件:
请将 /reports/daily_report_20260623.pptx 发送给运维团队邮件组,
邮件标题:[运维日报] 2026-06-23 系统运行报告
邮件正文包含:关键指标摘要、异常告警列表
六、Step4:Claw 配置微信远程触发
6.1 场景:外出时需要查看日报
周末外出时,老板突然在微信群里问"今天系统有没有异常?"。传统做法是打开VPN→登录Grafana→截图→回复,至少5分钟。
6.2 Claw 远程触发方案
在 WorkBuddy 中配置 Claw 技能,绑定微信触发:
配置Claw技能:
触发词:日报 / 运维日报
执行动作:
1. 运行 fetch_metrics.py --date today
2. 运行 analyze_metrics.py
3. 生成日报摘要(文字版)
4. 将摘要发送到微信
配置完成后,在微信中发送"日报"两个字,Claw 自动执行采集和分析,30秒内返回当日运维摘要:
📊 运维日报 2026-06-23
━━━━━━━━━━━━━━━
🖥️ 系统概览:
CPU平均使用率:45.2% ✅
内存平均使用率:62.8% ✅
HTTP QPS:3,256 ✅
平均响应时间:128ms ✅
⚠️ 异常告警:
- CDB慢查询数:12(阈值10)🔴
- CVM实例10.0.1.15 CPU 85% 🔴
📋 基础设施:
CVM运行:12台 / 停止:1台
CDB连接数:156 / 慢查询:12
💡 建议:关注CDB慢查询,建议检查索引优化
七、效果对比:人工 vs AI 全自动
7.1 全流程耗时对比
| 环节 | 人工 | 双引擎自动化 | 节省 |
|---|---|---|---|
| 数据采集 | 15分钟 | 30秒(自动) | 14.5分钟 |
| 数据整理 | 20分钟 | 10秒(脚本) | 19.8分钟 |
| PPT制作 | 15分钟 | 2分钟(模板填充) | 13分钟 |
| 邮件发送 | 10分钟 | 20秒(自动) | 9.7分钟 |
| 总计 | 60分钟 | 约5分钟 | 55分钟 |

7.2 质量对比
| 维度 | 人工 | 自动化 |
|---|---|---|
| 数据完整性 | 偶尔遗漏 | 100%覆盖 |
| 格式一致性 | 因人而异 | 模板统一 |
| 异常发现及时性 | 依赖经验 | 阈值自动标注 |
| 远程可访问性 | 需VPN | 微信即查 |
八、进阶玩法:异常告警 + 周报月报汇总
8.1 异常告警自动推送
在定时任务中增加异常检测逻辑:
python
# 在 analyze_metrics.py 中增加异常检测
def check_alerts(metrics: Dict) -> List[str]:
"""检测异常指标并生成告警"""
alerts = []
if float(metrics.get("cpu_usage", 0)) > 80:
alerts.append(f"CPU使用率异常: {metrics['cpu_usage']}%")
if metrics.get("slow_queries", 0) > 10:
alerts.append(f"慢查询数异常: {metrics['slow_queries']}条")
return alerts
当检测到异常时,WorkBuddy 自动通过企业微信推送告警,无需等到日报时间。
8.2 周报月报自动汇总
请汇总本周(6.17-6.23)的日报数据,生成周报PPT:
1. 本周指标趋势图(7天折线图)
2. 异常事件汇总
3. 资源使用率变化
4. 下周关注事项
WorkBuddy 可以自动汇总多日数据,生成周报和月报,省去了人工汇总的工作量。
九、踩坑实录:4个常见问题
踩坑1:Prometheus API 超时导致采集失败
问题:大促期间 Prometheus 查询超时,脚本直接报错退出。
解决:在脚本中增加超时重试和降级策略:
python
def fetch_with_fallback(primary_url: str, fallback_value: Any = "N/A") -> Any:
"""带降级的查询:主查询失败时使用缓存数据"""
try:
return fetch_with_retry(primary_url)
except Exception as e:
logger.error(f"主查询失败,使用降级值: {e}")
return fallback_value
踩坑2:PPT模板占位符替换失败
问题:WorkBuddy 替换PPT占位符时,部分图表占位符无法正确替换。
解决:将图表占位符改为"图片占位符"类型,WorkBuddy 替换图片比替换图表更稳定。先用 matplotlib 生成图表图片,再插入PPT。
踩坑3:定时任务时区问题
问题:WorkBuddy 定时任务使用 UTC 时间,导致8:00的任务实际在北京时间16:00执行。
解决:在定时任务配置中显式指定时区:
定时任务配置:
Cron: 0 0 * * * (UTC)
等价于北京时间 8:00
或在配置中指定 timezone: Asia/Shanghai
踩坑4:Claw 微信触发词冲突
问题:配置的触发词"日报"和日常聊天中的"日报"冲突,导致误触发。
解决:使用更明确的触发词,如"#日报"或"#运维日报",加前缀符号避免误触发。
十、总结:AI Agent 协作的三个层次
通过这次双引擎协作实战,我总结出 AI Agent 协作的三个层次:
第一层:单点替代------用AI替代某个环节的重复劳动(如用脚本替代手工采集数据)
第二层:流程串联------用AI将多个环节串联成自动化流程(如采集→分析→生成→发送)
第三层:智能协作------多个AI Agent分工协作,各取所长(如CodeBuddy写代码+WorkBuddy跑流程+Claw远程控制)
WorkBuddy + CodeBuddy 的双引擎协作,已经达到了第三层。CodeBuddy 擅长代码生成,WorkBuddy 擅长流程自动化,Claw 擅长远程交互------三者组合,比任何单一工具都更强大。
📜 真实性声明: 本文所有内容均基于作者在2026年6月使用 WorkBuddy + CodeBuddy 双引擎的真实实践。运维日报自动化方案已在作者所在团队落地运行,技术细节和踩坑经验均来自实际使用过程。
互动话题:
- 你的团队有哪些重复性工作适合用 AI Agent 自动化?
- 你觉得 WorkBuddy 和 CodeBuddy 还能组合出什么玩法?
- 在运维自动化中,你最担心什么风险?欢迎评论区交流!