微信扫码
添加专属顾问
我要投稿
高德运营同学半年内从零搭建自动化日报系统,用AI解放人力,实现数据到阅读仅需10分钟。核心内容: 1. 运营日报的痛点与AI化契机 2. 从静态站点开始的CI初体验与踩坑历程 3. 自动化流水线的完整搭建与实战效果
阿里妹导读
文章内容基于作者个人技术实践与独立思考,旨在分享经验,仅代表个人观点。
摘要
作为一名高德打车的区域运营同学,和常规运营同学一样,日常工作中需要大量时间和精力在盯数据、写日报、做分析上。半年前,我对"CI/CD"这个词一无所知,甚至不理解代码库、git存在的意义——认为那些都是开发同学才需要懂的东西。
但现在,我独立搭建了一套完整的日报自动化流水线:每天定时从ODPS取数、用Qwen大模型生成日报解读、自动推送钉钉群、自动部署到在线站点。整个流程无需人工干预,从数据到阅读只需要10分钟。
这篇文章不是技术科普,而是一个运营视角的真实实战记录——我是怎么从零开始,一步步踩坑、一步步用AI解决技术问题,最终把整套系统跑起来的。
一、背景:为什么运营要搞CI
1.1 日报的痛点
运营团队应该都需要有这样一份日报,要覆盖前一天的目标达成、大盘数据、商户异动、城市峰值、分时应答情况等诸多模块。以前这份日报的制作流程是这样的:
打开ODPS进行SQL取数
把数据复制到Excel里整理
手动写分析解读
排版成文档,发到钉钉群
如果要留档,还得手动上传到某个地方
每天至少花1小时,而且依赖人工读数和业务经验,分析质量高度依赖处理人的经验和细心程度。
1.2 团队AI化的契机
2026年初,我们团队开始全面推进AI工具落地。Qwen Code、提示词工程、自动化流程……大家都在探索怎么用AI把重复性工作自动化。
我的leader提出了一个想法:日报能不能自动化? 每天的数据结构是固定的,分析框架是固定的,唯一变化的是数字本身——这不就是最适合自动化的场景吗?
1.3 为什么选Aone CI
说实话,一开始我根本不知道用什么工具。我尝试过几个方案:
方案 | 优点 | 缺点 |
本地Python脚本 | 简单直接 | 每天要手动跑,电脑关了就无法运行 |
定时任务(crontab) | 能定时 | 依赖某台机器,不透明 |
Aone CI流水线 | 云端运行、有日志、能定时触发 | YAML语法,零基础有学习成本 |
最终选Aone CI的原因很简单:我们的代码仓库就在Aone上,CI是现成的能力,不用额外搭环境。 而且团队里已经有同学在用CI做静态站点托管,有现成的经验可以参考。
二、第一次接触CI:从静态站点开始
2.1 第一个任务:让HTML能被在线访问
我的CI之旅不是从日报开始的,而是从一个更简单的需求开始——把HTML文件放到在线站点上。
在Aone代码库里有一个静态站点(Aone Pages),可以把HTML文件托管成在线页面。团队里其他同学已经搭好了这个站点,我需要做的是:把我生成的HTML文件推送到仓库的public/目录下,它就能自动部署到在线地址。
听起来很简单对吧?但实际操作起来,坑一个接一个。
2.2 第一个坑:实战中理解代码库的分支隔离
我在master分支的public/文件夹里放了一个HTML文件,然后发现——我自己的分支能看到这个文件夹,但其他同学的分支看不到。
我当时很困惑:明明在master里建了文件夹,为什么别人的分支没有?
后来问了AI才知道,这是Git分支隔离的正常现象。每个分支是独立的,public/文件夹只存在于创建或合并了它的那些分支上。要让别人的分支也有,需要每个人自己执行一次git pull origin master。
2.3 第二个坑:master是保护分支
更头疼的问题来了。我们仓库的master分支是受保护分支,不能直接push。每次往public/目录合入新的HTML文件,都需要提MR(Merge Request)审核。
这意味着:
每次上传HTML → 提MR → 等审核 → 合入master → 手动更新README(生成新的访问链接)
流程繁琐,效率很低
2.4 用CI解决:自动更新README
如果能配置一条流水线,在每次push HTML文件后自动生成README索引并推送回去,不就不用手动更新了吗?
这是我第一次真正动手配置CI流水线。 整个过程是在AI的辅助下一步步完成的,大致分为以下几步:
CI容器里要往仓库push代码,需要一个"通行证"——PAT(Personal Access Token)。CI自带的Token是只读的,不能push。
操作路径:打开 code.alibaba-inc.com → 右上角头像 → 设置 → Private Token → 重置并复制。
PAT不能明文写在YAML里(会泄露到日志中),需要通过仓库的变量管理配置为Secrets类型。
类型 | 引用语法 | 适用场景 |
Secrets |
| 敏感信息(Token、密码、API Key) |
Variables |
| 非敏感配置(项目名、端点地址) |
千万别混用——用secrets语法引用Variables类型的变量,值会是空字符串。
这是我写的第一条YAML流水线(.aoneci/update-readme.yaml),核心逻辑是:
检测本次push是否涉及public/*.html文件变更
如果有,执行scripts/update-readme.sh脚本重新生成README
用PAT把更新后的README推回当前分支
写YAML的过程充满了挫折感——语法错误不会报错,只是流水线不触发。比如trigger要写成triggers(复数),run: |要写成数组格式,checkout要写成- uses: checkout而不是- checkout。这些调试过程全部依赖AI读取运行日志,一步一步和AI共创问题的解决方案。在这个过程中,我深刻体会到网上那个梗——"我和AI对话的时候,就像绝望的李鸿章,不管他端上来什么,只能无能地点【接受并运行】"......
由此我总结出一个经验:不要从零写YAML,先复制仓库里已经跑通的流水线,再改。
2.5 跑通的那一刻
当我第一次看到流水线执行成功、README被自动推回分支的时候,那种成就感是真实的。
[] 当前分支: qioyue_370902[] Token 长度: 20[] 检测到 HTML 变更: public/test_ci.html[] 推送到 origin/qioyue_370902(用户: judy.qy)[] README 已自动推回 qioyue_370902
虽然只是一个简单的README自动更新,但它让我理解了CI的基本工作原理:触发条件 → 执行步骤 → 产出结果。这为后面搭建日报流水线打下了基础。
三、搭建日报自动化流水线
3.1 整体架构设计
有了CI的基础认知后,我开始设计日报自动化流水线。整体思路是:
定时触发 → 取数 → 生成日报 → 转HTML → 推钉钉 → 推仓库 → 自动部署具体来说,分为7个步骤:
步骤 | 动作 | 工具/技术 |
1 | FBI数据抓取 | DataClaw API |
2 | ODPS SQL执行 | MaxCompute(5个模块各配专属SQL) |
3 | AI生成日报 | Qwen大模型(自然语言总结) |
4 | Markdown转HTML | Python脚本 |
5 | 推送钉钉 | Webhook + 加签 |
6 | HTML留档 | git push到个人分支的public/目录 |
7 | 自动部署 | 触发deploy-pages流水线 |
3.2 变量配置:一次配好,全仓库共享
日报流水线需要很多配置:ODPS的AccessKey、Qwen的API Key、钉钉Webhook地址等等。
好消息是:代码库的变量配置是仓库级别共享的。只要在Aone CI的变量管理中配置一次,同仓库的所有YAML流水线都可以通过相同语法调用。
我配置的变量包括:
变量名 | 类型 | 用途 |
ODPS_ACCESS_ID | Secret | MaxCompute AccessKey ID |
ODPS_ACCESS_KEY | Secret | MaxCompute AccessKey Secret |
DASHSCOPE_API_KEY | Secret | Qwen大模型API Key |
DINGTALK_WEBHOOK | Secret | 钉钉机器人Webhook URL |
GIT_PUSH_TOKEN | Secret | PAT(用于HTML推送回仓库) |
ODPS_PROJECT | Variable | ODPS项目名 |
这里有一个值得分享的经验:ODPS权限建议用团队公共账号。申请一个公共AccessKey,授权所需的数据表,然后统一配置到仓库Secrets中。这样:
避免个人AK泄露风险
人员变动无需更换凭证
新人上手零配置
3.3 两条流水线的分离设计
最终我搭建了两条独立的流水线:
流水线一:daily-report-auto(日报生成)
镜像:python:3.11
触发:工作日10:30定时 + 个人分支push
职责:取数 → 生成日报 → 推钉钉 → 推HTML到public/
流水线二:deploy-pages(站点部署)
镜像:alios-8u(自带jq + git)
触发:push到public/时实时触发 + 每天17:00定时兜底
职责:合并所有分支的public/内容 → 部署到生产站点
为什么要拆成两条?因为Aone CI的uses:组件运行在隔离容器中,python:3.11镜像缺少deploy-pages需要的jq工具,而且无法在流水线中补装。所以把"生成"和"发布"拆开,各用各的镜像,互不干扰。
四、并发问题:多人协作的终极挑战
日报流水线跑通后,我以为大功告成了。但很快遇到了一个更棘手的问题——多人协作时HTML互相覆盖。
4.1 问题是怎么发生的
我们团队只有一个Aone Pages静态站点,deploy-pages每次部署是全量替换(不是增量追加)。
场景还原:
我在个人分支生成了日报HTML → 推到public/daily-report/ → 触发部署 → 站点上有了日报 ✅
其他同学往master分支合入了一个活动页面 → 触发master的deploy-pages → 用master的public/全量替换站点
我的日报消失了 ❌(因为master的public/里没有我的daily-report/)
核心矛盾:所有人都在各自分支生成HTML,但站点只有一份,每次部署都是全量替换。
4.2 解决方案:每次部署前合并所有分支
思路很明确:每次部署前,先把所有远程分支的**public/**内容合并到一起,再部署完整集合。
具体实现是在deploy-pages.yaml的部署步骤前加一个"合并"环节:
# 动态发现所有远程分支git fetch origin --depth=1ALL_BRANCHES=$(git branch -r | grep -v 'HEAD' | sed 's|origin/||' | tr -d ' ')# 逐一拉取每个分支的public/内容for branch in$ALL_BRANCHES; dogit fetch origin $branch --depth=12>/dev/null || truegit checkout origin/$branch -- public/ 2>/dev/null || truedone# 当前触发分支的内容最后覆盖(保证最新变更优先)git checkout HEAD -- public/ 2>/dev/null || true
这样无论谁触发部署,所有人的HTML都会先合并进来,再一起部署。
4.3 为什么每个分支都要有deploy-pages.yaml
Aone CI读取的是被推送分支上的YAML。如果你的分支上没有deploy-pages.yaml,你推public/时不会触发任何部署。
好消息是:所有分支的YAML内容完全一样,不用各自定制。 如果你是从master新建的分支,这个文件已经自动继承了。
4.4 防护机制
我设计了几层防护,确保系统健壮:
异常场景 | 防护措施 |
新分支没放yaml | 不会触发部署,不会覆盖别人(无害) |
新分支放了正确yaml | 自动合并所有分支内容后部署(安全) |
新分支放了错误yaml | 下次正确分支部署时自动恢复 |
站点被意外覆盖 | 每天17:00定时部署自动恢复完整内容 |
17:00的定时任务是一个兜底机制,应对极端情况。正常情况下,每次push触发的实时部署就已经包含了所有分支的内容。
4.5 为什么不用[skip ci]防循环
最初我想用[skip ci]标记来防止部署流水线重复触发,但后来发现[skip ci]会杀死所有流水线(包括日报生成流水线)。
更好的方案是用paths过滤:只在public/**有变更时才触发deploy-pages。这样不该跑的流水线不会被误杀。
五、经验总结与可复用模板
5.1 新人接入最容易踩的坑(实战总结)
以下是搭建CI流水线过程中真实踩过的坑,涵盖语法陷阱、环境隔离和平台机制差异,按配置流程顺序排列:
# | 坑点 | 现象 | 根因 | 正确做法 |
1 | YAML触发器关键字写错 | push后流水线列表无新任务 | 必须写 |
|
2 | Secrets/Variables语法混用 | 环境变量为空,脚本报"key not found" | 两种类型引用语法不同,混用取空 | Secrets用 |
3 | git push报403 |
| 阿里内网不支持 | 必须用 |
4 | uses:组件看不到前面装的工具 |
|
| 拆成两条流水线,各用各的镜像 |
5 | $CI_COMMIT_BRANCH不存在 |
| Aone CI没有此内置变量(不是GitLab CI) | 用 |
6 | 定时任务写在个人分支不触发 | cron配了但到点无反应 | schedule调度器只从master分支读取配置 | YAML必须push到master;job内 |
7 | cron时间差8小时 | 想10:30触发,凌晨2:30跑了 | Aone CI cron按北京时间CST解释,不是UTC | 直接写北京时间,如 |
8 | [skip ci]杀全局 | 循环解决了但日报流水线也不跑了 |
| 用 |
9 | 手动重跑用旧配置 | 改了YAML但重跑还是旧逻辑 | 重跑加载的是所选commit对应的YAML | 改完YAML先push新commit(不含[skip ci]),再触发新commit |
10 | run:多行语法报错 | YAML解析通过但执行报语法错误 | Aone CI的 | 写成 |
总结心法: 遇到CI问题别自己死磕。把完整的报错日志复制给AI,让它帮你分析定位。配置CI的效率不取决于你记住了多少语法,而是你能不能快速定位问题。
5.2 调试CI的正确姿势
善用调试三板斧:查官方手册 → 对比已跑通的YAML → 加诊断输出。
遇到报错不要慌,把完整的日志信息复制给AI,让它帮你分析。 这是我整个CI搭建过程中最高效的调试方式。
5.3 关键设计决策回顾
决策 | 为什么这么做 |
全部部署在个人分支 | master有保护,无法直接push;个人分支无限制,PAT即可跑全流程 |
用独立流水线做部署 | 日报流水线的环境缺少发布所需的工具且无法补装,拆开后互不干扰 |
用paths而不是[skip ci]防循环 | [skip ci]会杀死所有流水线;paths只拦不该跑的 |
用团队公共ODPS账号 | 避免个人AK泄露风险,人员变动无需换凭证,新人零配置 |
SQL取数+AI总结 | 数据准确性由SQL保证(0幻觉),AI只负责自然语言解读 |
5.4 关键代码文件清单
如果你也想搭建类似的日报自动化流水线,以下是你需要关注的文件:
文件 | 职责 |
| 主流水线:触发器 + 环境变量注入 + 日报生成全流程 |
| 部署流水线:push public/实时触发 + 定时兜底 |
| 统一配置:路径、URL、开关、仓库信息 |
| ODPS SQL执行 + Qwen prompt组装 + Markdown生成 |
| Markdown → 自包含HTML转换 |
| 钉钉Webhook推送(加签 + 精简格式) |
| HTML推送到public/ + 触发Pages部署 |
| 各模块专属SQL文件 |
| 各模块Qwen prompt模板 |
写在最后
回头看这半年的经历,从一个连YAML是什么都不知道的运营,到能独立搭建和维护CI自动化流水线,最大的感触是:
AI不会替代运营,但会用AI的运营会替代不会用的。
搭建CI的过程中,我遇到的每一个技术问题——YAML语法、Git认证、ODPS权限、多分支并发——都是在AI的辅助下解决的。我不需要记住每一个技术细节,我只需要知道我要实现什么效果,然后把报错信息告诉AI,让它帮我找到解决方案。
当然,有些东西是需要自己理解的:
业务逻辑:哪些数据重要、怎么分析、怎么呈现——这是运营的核心能力
系统设计:为什么要拆两条流水线、为什么要合并分支——这些决策需要理解业务场景
质量把控:AI生成的内容需要人工校验,数据准确性需要机制保障
技术工具在变,但运营的核心价值没变:用数据驱动决策,用效率创造价值。 CI只是帮我把重复性工作自动化了,让我有更多时间去做真正需要人判断的事情。
如果你也是一个想用技术提效的运营同学,我的建议是:不要怕,从最简单的开始,一步步来,遇到问题就问AI,与AI协同找到解决方案。 你会发现,那些看起来很"技术"的东西,其实并没有那么难。
本文是「火种&起源」系列的一部分,记录一线运营同学在AI工具实践中的真实故事。
千问云-为Agent而生,驱动AI生产力
扫描下方二维码,直达千问云体验
点击阅读原文即可体验!
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-06-29
员工提效不等于组织提效:真正的解法是构建数字员工
2026-06-28
企业可以这样落地 AI 能力(五):价值闭环
2026-06-26
企业微信的AI,在玩一种很新的东西
2026-06-24
继微信小微后,企微内测 Agent 大圆
2026-06-24
麦肯锡:80%都在用AI,为什么0%跑通?
2026-06-24
AI产品经理不仅仅是做交互,你得知道智能体做出来以后,如何接进业务系统?
2026-06-23
一个AI销冠数字员工上岗后,销售团队会发生什么变化?
2026-06-23
当 Agent 替你值班:基于 Devix 构建 7x24 自动化运维 Harness Engineering
2026-04-24
2026-04-08
2026-04-08
2026-06-08
2026-05-15
2026-05-15
2026-04-01
2026-04-23
2026-04-07
2026-05-06
2026-06-24
2026-06-24
2026-06-23
2026-06-17
2026-06-10
2026-06-08
2026-05-29
2026-05-27