1. 为什么我要给 WorkBuddy 设一个“十点半闹钟”
每天早上到工位,第一件事不是打开编辑器,而是先刷一遍昨天夜里各个渠道冒出来的消息:项目群里有没有人 @ 我、待办列表里有没有逾期任务、昨天提交的几份材料有没有反馈、几个正在跑的数据任务有没有异常。这套动作熟练之后大概要花十五到二十分钟,问题是它完全靠人肉记忆驱动,一旦哪天起晚了或者被会议打断,就容易漏掉关键信息。
我用的协作工具是 WorkBuddy,它本身有工作台、任务流、消息聚合这些模块,日常协作够用。但它有个让我一直不太舒服的点:信息是被动推给我的,我得主动去看。工作台不会在早上主动告诉我“今天有三件事卡在你这里”,也不会把散落在不同项目里的动态汇总成一份可读的简报。于是我就想,能不能让 WorkBuddy 每天上午十点半,自动把一份整理好的 AI 日报送到微信里,我打开微信就能看完当天要处理的事。
这个想法落地之后,实际效果比我预期好很多。整条链路是:定时触发 → 拉取 WorkBuddy 数据 → 调用大模型生成日报 → 推送到微信。核心关键词就是WorkBuddy、AI日报、微信小程序、deepseek-v4-flash、自动化。它解决的问题很具体:把“人找信息”变成“信息找人”,把分散的协作动态压缩成一份三分钟能读完的日报。
适合谁来参考?如果你也在用 WorkBuddy 或者类似的协作平台,手头有基本的脚本能力,想让日常信息流自动化起来,这套方案可以直接抄。哪怕你完全没写过自动化脚本,跟着下面的步骤走一遍,也能跑通一个最小可用版本。我踩过的坑、参数怎么定、为什么这么选,都会在下面讲清楚。
2. 整体方案设计与技术选型拆解
2.1 为什么是“定时 + 拉取 + 生成 + 推送”这条链路
先把整件事拆成四个动作,每个动作对应一个独立的问题。
第一个动作是定时触发。日报要每天上午十点半送达,那就需要一个可靠的定时器。可选方案有三种:本机 crontab、服务器上的定时任务、以及云函数自带的定时触发器。我最终选的是服务器上的 crontab,原因很直接——WorkBuddy 的数据拉取需要保持登录态或者调用接口,放在一台长期在线的机器上最省心,本机可能关机,云函数冷启动和依赖管理反而更麻烦。
第二个动作是拉取 WorkBuddy 数据。这一步是整个链路里最需要小心的地方。WorkBuddy 有网页端和工作台,数据来源可以是页面接口,也可以是它开放出来的数据出口。我的做法是优先走稳定的数据接口,把当天需要关注的任务、消息、动态拉下来,存成一个结构化的 JSON。这里不追求拉全量,只拉“跟我相关且今天需要处理”的部分,否则日报会变成流水账。
第三个动作是调用大模型生成日报。原始数据是一堆字段,直接推给人看没有意义。需要一个大模型把 JSON 转成自然语言简报,按“今日重点、待办提醒、风险提示”这样的结构组织。模型选的是deepseek-v4-flash,选它的理由后面单独讲。
第四个动作是推送到微信。这里有个关键决策:是推送到个人微信,还是推送到微信小程序?个人微信推送受限于平台规则,稳定性和合规性都不好把握;而微信小程序是我自己可控的载体,用户打开小程序就能看到日报,还能做历史归档和已读标记。所以我最终把日报落在一个自建的微信小程序里,通过订阅消息或者小程序内的消息中心触达。
提示:整条链路的设计原则是“每个环节都可单独测试”。定时器能单独跑、拉取能单独跑、生成能单独跑、推送能单独跑。任何一环出问题,都不会把整条链路拖死。
2.2 模型为什么选 deepseek-v4-flash 而不是更大的模型
日报生成这个任务,本质上是一个“结构化数据转自然语言”的活,不需要模型有很强的推理能力,但对响应速度和成本很敏感。每天一次调用,看起来量不大,但如果日报要分多个板块、每个板块单独生成,调用次数就会上去。
deepseek-v4-flash 的定位就是快和便宜。我实测下来,一份包含二三十条原始记录的日报,生成耗时在几秒级别,输出质量足够把“任务 A 逾期两天、负责人是某某、建议今天跟进”这种信息说清楚。更大的模型当然能写得更漂亮,但在这个场景里属于杀鸡用牛刀,而且延迟会让整个链路变慢。
还有一个考虑是输出稳定性。日报需要固定结构,模型如果太“聪明”,容易自由发挥,把格式打乱。flash 版本在指令遵循上反而更听话,我给一个明确的输出模板,它基本能照着填。这一点在实际跑自动化的时候非常重要,格式一乱,小程序端解析就会出问题。
2.3 微信小程序作为载体的几个现实考量
把日报放进微信小程序,而不是直接发消息,主要是三个原因。
第一是可归档。日报是每天一份,时间长了就是一个信息库。小程序里可以做一个列表页,按日期倒序排列,想看上周三的日报随时能翻。如果只是发一条消息,翻历史记录很痛苦。
第二是可交互。日报里的任务条目可以做成可点击的,点进去跳到对应的详情或者标记已读。这种交互在纯消息里做不到。
第三是合规和稳定。小程序的消息触达走的是平台提供的订阅消息能力,用户主动订阅之后才能收到,这个边界很清楚。相比之下,直接往个人微信推消息的方案,稳定性和可持续性都要打问号。
当然,小程序也有它的成本:需要注册、需要年审、需要处理顶部导航栏高度这类适配问题。这些在后面实操部分会具体讲。
3. 核心细节解析与实操要点
3.1 WorkBuddy 数据拉取的三个关键点
拉数据这一步,我总结了三个必须处理好的点。
第一是身份认证。WorkBuddy 的接口通常需要登录态,直接裸调会被拒。我的做法是在服务器上维护一份有效的凭证,定期刷新。这里要注意,凭证不要硬编码在脚本里,放在环境变量或者单独的配置文件里,脚本只读不写。如果凭证过期,脚本要能检测到并发出告警,而不是静默失败。
第二是数据范围。一开始我拉的是全量数据,结果日报里塞了几百条记录,根本没法看。后来改成只拉三类:今天到期或已逾期的任务、过去 24 小时内 @ 我的消息、我负责的项目的状态变更。范围一收窄,日报的可读性立刻上来了。
第三是字段清洗。接口返回的原始数据里有很多冗余字段,比如各种内部 ID、时间戳、状态码。在送给模型之前,我会先做一轮清洗,把时间戳转成“今天/昨天/三天前”这种人类可读的表述,把状态码转成中文描述。清洗做得越干净,模型生成的质量越高,也越省 token。
# 数据清洗的简化示例 def clean_task(raw): return { "title": raw["title"], "owner": raw["assignee_name"], "due": humanize_time(raw["due_at"]), "status": STATUS_MAP.get(raw["status"], "未知"), "overdue_days": calc_overdue(raw["due_at"]) }3.2 日报提示词的设计:结构比文采重要
给模型写提示词,很多人一上来就追求“写得像人话”。但在日报这个场景里,结构稳定比文采重要得多。我的提示词分三部分:角色设定、输出结构、约束条件。
角色设定很简单:“你是一个协作助理,负责把原始任务数据整理成简洁的日报。”输出结构我会明确给出模板,比如固定三个板块:今日重点、待办提醒、风险提示。约束条件包括:每条不超过两行、不要编造数据、没有内容的板块直接省略。
这里有个实操心得:把输出格式写成 JSON 比写成 Markdown 更稳。因为小程序端要解析,JSON 解析失败会直接报错,而 Markdown 格式乱了不容易发现。我让模型输出 JSON,字段固定,小程序端按字段渲染,出问题的概率大大降低。
注意:提示词里一定要加一句“如果某条数据缺失,输出空字符串而不是猜测”。模型在信息不全的时候很容易脑补,日报里出现编造的内容是很严重的问题。
3.3 微信小程序端的两个适配细节
小程序端看起来简单,但有两个细节如果不处理,体验会很差。
第一个是顶部导航栏高度。小程序的顶部导航栏在不同机型上高度不一样,如果直接用固定像素做布局,在某些机型上内容会被挡住。正确做法是用wx.getSystemInfoSync()拿到状态栏高度和导航栏高度,动态计算内容区的起始位置。这个坑我踩过,日报标题被导航栏遮住了一半,排查了半天才发现是高度写死了。
第二个是缓存时间设置。日报数据每天更新一次,但用户可能一天内多次打开小程序。如果每次都重新请求,既浪费流量又慢。我的做法是设置一个合理的缓存时间,比如 30 分钟,在这个时间内直接读缓存,超过之后再请求新数据。缓存 key 里带上日期,避免跨天读到旧数据。
// 小程序端缓存示例 const CACHE_KEY = `daily_report_${today}`; const cached = wx.getStorageSync(CACHE_KEY); if (cached && Date.now() - cached.timestamp < 30 * 60 * 1000) { return cached.data; }3.4 定时任务的可靠性设计
crontab 看起来简单,但有几个坑必须提前想到。
时区问题。服务器如果是 UTC 时间,crontab 里的“十点半”就是 UTC 十点半,对应北京时间是下午六点半。我第一次跑的时候就是这个问题,日报晚上才到。解决办法是在 crontab 里显式指定时区,或者把服务器时间调成东八区。
失败重试。网络抖动、接口限流都可能导致某天的拉取失败。我的做法是脚本内部做三次重试,间隔递增。如果三次都失败,就发一条告警到我的备用渠道,而不是让这一天静默过去。
日志留存。每次执行都要写日志,记录开始时间、结束时间、拉取条数、生成耗时、推送结果。日志不用复杂,一个文本文件按天切分就够。出问题的时候,日志是唯一能还原现场的东西。
4. 完整实操流程与关键环节实现
4.1 环境准备与依赖安装
先说一下我的运行环境:一台长期在线的 Linux 服务器,Python 3.10,Node.js 18(小程序端开发用)。如果你用 Windows,整体流程一样,只是 crontab 换成任务计划程序。
Python 侧需要装的依赖不多,主要是 HTTP 请求库和 JSON 处理。我习惯用requests做请求,用标准库的json处理数据。如果要做更复杂的调度,可以引入schedule库,但既然用 crontab,就不需要了。
pip install requests小程序端需要安装微信开发者工具,这个去官方渠道下载即可。新建项目的时候选择“不使用云开发”,因为我们的后端逻辑都在服务器上,小程序只负责展示。
4.2 拉取脚本的编写与调试
拉取脚本是整个链路的地基,我建议单独写、单独测,不要和生成、推送混在一起。
脚本的核心逻辑是:读取凭证 → 请求接口 → 清洗数据 → 输出 JSON 文件。输出到文件而不是直接传给下一步,是为了方便调试。你可以随时打开这个 JSON 看看数据对不对,而不用每次都跑完整链路。
import requests, json, os from datetime import datetime def fetch_workbuddy_data(token): headers = {"Authorization": f"Bearer {token}"} resp = requests.get(API_URL, headers=headers, timeout=15) resp.raise_for_status() raw = resp.json() cleaned = [clean_task(t) for t in raw["tasks"]] return cleaned if __name__ == "__main__": token = os.environ["WORKBUDDY_TOKEN"] data = fetch_workbuddy_data(token) with open("raw_data.json", "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) print(f"拉取完成,共 {len(data)} 条")调试的时候,先手动跑一次,看输出的 JSON 里字段对不对、时间格式对不对、有没有空值。这一步花十分钟,能省掉后面大量的排查时间。
4.3 调用 deepseek-v4-flash 生成日报
生成脚本读上一步的 JSON,拼提示词,调模型,拿到结果后做一次校验。
提示词我放在一个单独的模板文件里,方便调整。模板里用占位符标记数据插入的位置。调用的时候把 JSON 转成紧凑的字符串塞进去。
def generate_report(tasks): prompt = PROMPT_TEMPLATE.format(data=json.dumps(tasks, ensure_ascii=False)) resp = requests.post( MODEL_ENDPOINT, json={"model": "deepseek-v4-flash", "messages": [{"role": "user", "content": prompt}]}, timeout=60 ) content = resp.json()["choices"][0]["message"]["content"] return json.loads(content) # 校验 JSON 合法性这里有个细节:模型返回的内容可能带 Markdown 代码块标记,比如 ```json 开头结尾。直接json.loads会失败。我的做法是先做一次字符串清洗,把代码块标记去掉再解析。这个坑很常见,第一次跑大概率会遇到。
4.4 推送到微信小程序的实现
推送这一步,我走的是小程序的消息中心方案:服务器把生成的日报写入一个数据存储,小程序端通过接口拉取。同时,如果用户订阅了通知,就发一条订阅消息提醒。
数据存储我用的是最简单的方案:服务器上一个按日期命名的 JSON 文件,小程序端通过一个只读接口访问。这个方案的好处是零依赖,坏处是不适合高并发。但对于个人日报这种场景,完全够用。
# 保存日报 def save_report(report): today = datetime.now().strftime("%Y-%m-%d") path = f"/data/reports/{today}.json" with open(path, "w", encoding="utf-8") as f: json.dump(report, f, ensure_ascii=False)小程序端做一个列表页和一个详情页。列表页展示历史日报的日期和摘要,详情页展示完整内容。顶部导航栏高度用动态计算,缓存用前面说的 30 分钟策略。
4.5 crontab 配置与整链路联调
所有环节单独测通之后,用 crontab 串起来。
# 每天上午 10:30 执行 30 10 * * * cd /path/to/project && /usr/bin/python3 main.py >> /var/log/workbuddy_daily.log 2>&1注意这里用了绝对路径,因为 crontab 的环境变量和登录 shell 不一样,用相对路径容易找不到文件。日志重定向到文件,方便排查。
联调的时候,我建议先把时间设成几分钟后,跑一次看整条链路通不通。通了之后再改成十点半。第一次联调大概率会在某个环节卡住,这时候日志就是你的救命稻草。
5. 常见问题与排查技巧实录
5.1 拉取失败:凭证过期与接口限流
最常见的两个拉取失败原因,一个是凭证过期,一个是接口限流。
凭证过期的表现是接口返回 401 或者类似的未授权状态。解决办法是脚本里加一个检测,遇到 401 就触发凭证刷新流程,刷新失败就告警。不要等到日报没收到才发现。
接口限流的表现是返回 429 或者响应变慢。解决办法是控制请求频率,拉取的时候加一个小的间隔,不要短时间内连续请求。如果数据量大,分页拉取,每页之间 sleep 一下。
| 问题现象 | 可能原因 | 排查方法 | 解决方式 |
|---|---|---|---|
| 返回 401 | 凭证过期 | 检查 token 有效期 | 刷新凭证并更新配置 |
| 返回 429 | 请求过于频繁 | 查看请求日志频率 | 增加请求间隔,分页拉取 |
| 响应超时 | 网络或服务端问题 | 检查网络连通性 | 增加超时时间,加重试 |
| 数据为空 | 接口参数错误 | 对比接口文档 | 修正查询参数 |
5.2 生成质量差:数据太脏或提示词太松
模型生成质量差,九成问题出在输入数据或者提示词上。
如果日报里出现“未知任务”“无负责人”这种内容,说明输入数据里有空值没清洗干净。回到拉取脚本,把空值处理掉,该给默认值的给默认值。
如果日报结构混乱、板块缺失,说明提示词约束不够。检查提示词里有没有明确输出结构,有没有加“不要编造”的约束。我一般会把提示词改到模型连续三次输出都符合预期,才算稳定。
提示:模型输出不稳定的时候,不要急着换模型。先把提示词和数据质量排查一遍,大部分问题都能解决。
5.3 推送延迟:时区与调度问题
日报没在十点半到,先查时区。服务器时间是不是东八区,crontab 里的时间是不是按服务器时间算的。这个问题我遇到过两次,都是时区没对齐。
如果时区没问题,查 crontab 有没有正常触发。看日志文件有没有当天的记录,没有记录说明任务根本没跑,检查 crontab 配置和脚本权限。
还有一种情况是任务跑了但很慢,导致实际送达时间晚于预期。这时候要看生成环节的耗时,如果模型响应慢,可以考虑把提示词精简一下,减少 token 数。
5.4 小程序端显示异常:缓存与适配
小程序端最常见的问题是缓存导致的数据不更新。用户看到的是昨天的日报,因为缓存没过期。解决办法是在缓存 key 里带上日期,跨天自动失效。
另一个是布局适配问题。不同机型导航栏高度不同,内容被遮挡或者留白过多。用动态计算的方式解决,不要写死像素值。
| 问题现象 | 可能原因 | 解决方式 |
|---|---|---|
| 显示旧日报 | 缓存未过期 | 缓存 key 带日期 |
| 内容被遮挡 | 导航栏高度写死 | 动态计算高度 |
| 列表空白 | 接口返回异常 | 检查接口和数据结构 |
| 点击无响应 | 事件绑定错误 | 检查 bindtap 配置 |
5.5 几个我踩过的坑和独家技巧
坑一:把凭证写进代码。一开始图省事,token 直接写在脚本里。后来 token 过期要改代码,改完还要重新部署,非常麻烦。现在全部走环境变量,改配置不用动代码。
坑二:日报内容太多。第一版日报把所有任务都列出来,结果每天几十条,根本没人看。后来砍到只保留“今天必须处理”的,条数控制在十条以内,阅读率立刻上来了。
技巧一:给日报加一个“一句话摘要”。在日报最顶部放一句模型生成的总结,比如“今天有三件逾期任务需要优先处理”。用户扫一眼就知道今天什么情况,不用往下翻。
技巧二:失败告警走独立渠道。日报推送失败的时候,不要指望日报本身来通知你。我单独配了一个告警渠道,链路任何一环失败都会收到提醒。
技巧三:保留原始数据。生成的日报存一份,拉取的原始数据也存一份。有时候日报生成有问题,回头对比原始数据就能快速定位是数据问题还是模型问题。
6. 后续可以怎么扩展这套方案
跑通最小版本之后,我陆续加了一些扩展,这里分享几个我觉得比较有价值的。
第一个是周报自动生成。日报的数据攒一周,周五下午自动生成一份周报,按项目维度汇总。这个只需要在生成脚本里加一个分支,读取过去七天的数据,换一套提示词。
第二个是异常主动提醒。日报是被动的,但有些情况需要主动提醒,比如某个任务逾期超过三天。我在拉取脚本里加了一个判断,命中条件就立即触发一次推送,不等日报。
第三个是多端适配。现在日报只在小程序里看,后面可以考虑同步一份到其他常用的协作工具里。核心逻辑不变,只是多一个输出通道。
这套方案的核心思路其实很简单:把重复的信息整理工作交给自动化,把人的精力留给真正需要判断的事。WorkBuddy 负责产生数据,脚本负责搬运和加工,模型负责翻译成人话,小程序负责呈现。每个环节都不复杂,串起来就是一个每天准时送达的 AI 日报。
我在实际使用中最大的体会是,自动化的价值不在于省了多少时间,而在于消除了“忘记看”这个风险。以前靠人肉记忆,总有漏的时候;现在每天十点半准时到,看不看是我的事,但信息一定在那里。这种确定性,比省下来的十几分钟值钱得多。