
本文含有AI辅助生成内容,请读者结合自身需求甄别参考。
| 每天 02:00 自动送达 |
简报由两大块组成:主流品牌价格趋势(内存 / SSD / 显卡各 4 个品牌,共 12 个固定 SKU)和月度 / 年度综合价格指数(基期 2025-03 = 100)。所有内容渲染成一张长图,微信里点开就能看。

最终推送到微信的长图简报:标题、摘要、KPI、三类品牌趋势、月度/年度综合指数一图到底
| 验证通过的架构 |
整条链路的分工原则只有一句话:Python 负责计算,Qwen 只负责文字表达,OpenClaw 负责调度与发送。分工清晰是后面所有环节稳定的前提。
| 开工前备齐 |
| 约 20 分钟 |
先装 Node.js,再装 OpenClaw。首次启动进入Crestodian 初始化界面,按 QuickStart 走完:确认 workspace、gateway、systemd user service。装完还不算完——此时 Agent 还不会说话。
解法:改用 Qwen provider(阿里云百炼凭据),装好插件并重启 gateway:
openclaw plugins install @openclaw/qwen-provider openclaw gateway restart然后把默认模型切到qwen/qwen3.7-plus,重启并重新进入 TUI。当 TUI 顶部显示该模型、发一句话能正常回复,模型链路就通了。
| 最小化验证 |
用 OpenClaw 的Weixin channel绑定微信。绑定成功后,微信里会出现一个可聊天的机器人会话——"你 → 机器人"方向已通。但每日简报需要反方向:机器人无人值守时主动发消息。

绑定成功后,微信里出现了“芝士虾1号”——这是它和主人的第一次对话

实际聊天记录:吩咐“2 分钟后发一条定时推送测试成功,执行后删除”,23:18 准点收到
| 核心设计决策 |
数据源选Keepa:成熟的 Amazon 价格历史生态,直接拿到历史价格序列,不用自己写爬虫长期蹲守。比数据源更重要的是篮子设计——三固定原则:
| 内存 RAM | |
| 固态 SSD | |
| 显卡 GPU |
12 个 SKU 固化在products.json里,之后每次采集都原样复用这份清单。

同一 SKU 的三种价格口径:Amazon 自营 / New / Buy Box,最终以 Buy Box 为准

单个 SKU 的历史价格序列(Samsung 990 PRO 2TB),验证数据链路可用
环境方面记得先apt install python3.12-venv,重建 .venv 后装依赖。最后跑 fetch_prices.py,12 个 ASIN 全部 Validation OK(tokensConsumed: 36),原始响应落盘,采集层完成。
| Python 计算层 |
第一块产出:3 张过去 12 个月的品牌价格趋势图。

DDR5 32GB 6000 · 四品牌 12 个月走势

2TB PCIe 4.0 NVMe · 四品牌 12 个月走势

RTX 5070 12GB · 四品牌 12 个月走势
第二块产出:综合价格指数。基期固定为2025-03 = 100,各类别先算类别指数,三类再等权合成 Overall。就在这一步,踩了全项目最有价值的一个坑:
核心逻辑在 build_summary.py 的 load_daily() 里,值得逐行看懂:
# Keepa 事件序列 → 连续每日价格 state = df["price_usd"].fillna(-1.0) # -1 表示明确无 Buy Box series = pd.Series(state.values, index=df["datetime_utc"]).sort_index() daily = series.resample("1D").last().ffill() # 价格没变化时 Keepa 不会每天重复写记录,# 因此把最后状态延续到今天。 today = pd.Timestamp.now(tz="UTC").normalize() if len(daily) and daily.index.max() < today: full_index = pd.date_range( daily.index.min(), today, freq="D", tz="UTC") daily = daily.reindex(full_index).ffill()
修正后,月度 Overall 从 2025-03 起连续不断档。年度图还要明确标注2025 partial和2026 YTD,避免把不完整年份当完整年度解读。以 2026-08 为例:

月度综合指数:RAM 与 SSD 拉升,GPU 回落

年度视角:2025 partial · 2026 YTD
| AI 文案层 |
build_summary.py 把现价、7 日变化、月度指数、年度/YTD 指数全部算好,连同图路径写进 summary.json。然后 Qwen 读取它生成中文简报——但只允许做文字表达。约束全部写在 report_prompt.md 里,这几条硬规则是简报可信度的根基:
1. 只能使用 summary.json 中已有的数据, 不得自行搜索、猜测、补充或重新计算数字。 2. null 表示当前没有有效报价, 不得沿用旧价格冒充当前价格。 3. change_7d_pct 为 null 时,只能写"7日变化暂无数据" 或不讨论变化,绝对不能写"持平""上涨""下跌"。 4. 只有 change_7d_pct 明确等于 0.0 时,才允许写"持平"。 5. 不做购买建议,不写新闻,不扩展到其他硬件。 6. 正文中绝对不要输出 MEDIA:、本地文件路径。
Qwen 按硬规则生成的文字简报(微信内实际效果):有数据才说话,null 一律写"暂无数据"
| 本项目最大的坑 |
最初的需求很合理:简报要有标题、文字说明,每张图可单独点开。于是第一版方案是"正文 + 5 张独立图片"。接下来是一连串真实踩坑:
GatewayClientRequestError: OutboundDeliveryError: sendMessage ret=-2 errmsg=prepare failed
真实记录:Agent 回复“会话已刷新~”,但高清长图依然“Media failed.”
于是换思路:把所有文字和图片渲染成一张长图,只主动发送 1 次。对比 PDF、HTML 链接后选方案 A:Jinja2 模板 + HTML/CSS + Playwright 截图——排版质量顺便解决。实现只有三个文件,流水线是 summary.json → report.html → report.jpg:
CHROME = "/home/<USER>/.cache/chrome-for-testing/ chrome-linux64/chrome" browser = await p.chromium.launch( executable_path=CHROME, headless=True) page = await browser.new_page( viewport={"width": 1400, "height": 2000}, device_scale_factor=2.0) await page.goto(url, wait_until="networkidle") await page.screenshot(path=str(REPORT_IMAGE), full_page=True, type="jpeg", quality=92)| 最后一公里 |
发送脚本 send_test_report.sh 只有一件事:让 Agent 在指定微信会话里回复一条 MEDIA 并 deliver:
#!/usr/bin/env bash set -e openclaw agent \ --session-key 'agent:main:openclaw-weixin:direct:<WECHAT_TARGET>@im.wechat' \ --message '只回复下面这一行,不要任何其他文字: MEDIA:/home/<USER>/hardware-price-tracker/report/report_test_half.jpg' \ --deliver再用OpenClaw Cron挂到每天 02:00(注意显式指定时区):
# 每天 02:00(Asia/Shanghai) openclaw cron create "0 2 * * *" \ --name "每日硬件价格长图测试" \ --tz "Asia/Shanghai" \ --exact \ --command "./send_test_report.sh" \ --command-cwd "/home/<USER>/hardware-price-tracker" \ --no-deliver # 查看 / 清理 openclaw cron list openclaw cron remove <CRON_JOB_ID>

也可以直接在微信里吩咐 Agent 建排程——图中是另一个每日 00:00 的测试任务,创建后准点触发
| 7 个真实坑 |
| 照单组建即可 |
这条链路最值钱的不是某个具体命令,而是三个工程决策:固定 SKU 篮子保证指数不漂移,Python 算数 / Qwen 写字的分工保证数字可信,单张长图 + 单次发送绕开微信通道的可靠性雷区。
后续可扩展:国产品牌价格篮子(已留作下一步)、长图按版块切段兼顾清晰度、或把 products.json 换成你关心的任何品类——整条链路原样复用。
· 本文所有实施步骤、代码、报错与结果均整理自《OpenClaw 硬件价格每日简报——实施过程对话整理》(2026-08-26,脱敏版),敏感字段(API Key、微信内部 ID、IP、路径用户名等)已泛化处理。
· 价格数据口径:Amazon US · Keepa 历史价格 · Buy Box 含运费;指数基期 2025-03 = 100;2025 为 partial,2026 为 YTD。指数仅反映固定代表 SKU 篮子走势,不构成任何购买建议。
· 早期脚本(parse_price.py / fetch_prices.py / plot_categories.py / build_indices.py)在原始记录中已折叠,本文按记录保留其文件名与行为,未凭空补写源码。
本文含有AI辅助生成内容,请读者结合自身需求甄别参考。
夜雨聆风