起因:关注列表已经读不完了
我在 X 上关注了一批质量很高的博主,大多聊美股、聊科技。问题是关注久了以后,信息流变成了负担:
- 量太大,几十个人一天几百条,翻完就到中午了;
- 英文读起来慢,遇到长推文更容易直接划过去;
- 真正重要的消息被淹没在转推、回复和日常闲聊里;
- 隔天就忘了昨天大家在讨论什么,更别说「这个话题已经连着聊了三天」这种跨天信号。
而这类信息偏偏有时效性。某些账号提一句某只票,盘前就能看出反应——这种消息晚看两小时和实时看到,完全是两件事。
所以我想要的东西其实很简单:只推原创推文,自动翻成中文,重要的给我一段摘要,第二天早上再给我一份昨天的汇总。
后面这套东西我用 Vibe Coding 的方式断断续续写了下来,现在已经稳定跑了一段时间,代码开源在这里:
github.com/datazhy/x-monitor-feishu —— MIT,欢迎 Star / Issue / PR
第一个坑:官方 API 直接把我劝退了
最开始我理所当然地去看了 X 官方 API。结论是:对个人开发者来说,这条路基本走不通。
免费档的读取额度低到没有实用价值,往上一档就是每月两百美元起,再往上是每月几千美元的量级。我要做的只是盯几十个账号的更新,为此每月付几百美元显然不合理——这个价格已经够我买不少别的东西了。
于是转向第三方数据源,最后选定了 TwitterAPI.io:按量计费,没有起步门槛,并且支持 Filter Rule + webhook——这点很关键,意味着我不需要自己写轮询逻辑去反复拉取,它匹配到符合规则的推文会主动回调我的服务。
实测下来,整套系统跑一个月大约 $2,其中还包含了 AI 翻译和分析的钱。和每月 200 美元相比,差了两个数量级。
它最终长什么样
实时推文推送——英文推文只显示中文译文(保留原文的段落排版),长推文附一段 AI 分析:
每天早上 9 点的「昨日信号」早报——顶部先列昨天被提及的股票,然后是一句话主线、三件最重要的事、主题热度和跨天趋势:
以上两张为示意图,内容是演示用的虚构数据,排版与真实推送一致。
整体架构
1
2
3
4
5
6
7
8
9
10
11
TwitterAPI.io Filter Rule (webhook)
│ HTTPS + 长随机 secret
▼
FastAPI 接收端 ──► SQLite(tweet_id 去重 + delivery 幂等)
│
├─► 实时推送流:翻译 + AI 分析(DeepSeek)→ 飞书(可按博主路由到不同群)
│
└─► 每天北京时间 09:00 生成早报:
全量去噪 / 分类 / 聚合(便宜的小模型)
→ Python 算硬指标(热度 / 趋势 / 连续 / 异常 / 提及股票)
→ 写作(较强的模型)→ 飞书交互卡片
技术栈没什么花活:FastAPI + SQLite + APScheduler + Docker,一台 1C1G 的小机器就能跑。整个 LLM 部分只需要一个 DeepSeek key,翻译、逐条分析、早报写作全用它。
三条我认为值得说的设计原则
1. 贵的模型只看筛选后的重点,便宜的模型处理全量。
早报生成分两步:先用便宜的 flash 模型把昨天几十条推文做去噪、分类、聚合,再把压缩后的结果交给更强的模型去写。如果无脑把全量推文喂给强模型,成本会翻好几倍,而输出质量并不会好多少。
2. 确定性的数字一律由 Python 算,不让模型碰。
热度、连续天数、发推量突增这些指标全部是代码算出来的。「提及股票」也是用正则从原文里抠 $MU 这种 cashtag,按提及频次排序,模型只负责补一个公司名。
这条是我踩过坑之后加的硬规则:模型很擅长把数字写得像模像样,然后编一个不存在的值给你。凡是能算的,就绝不让它猜。
3. 在 API 侧就把噪音过滤掉,而不是拿回来再筛。
Filter Rule 里直接写 -is:retweet -is:reply -is:quote,转推、回复、引用在数据源那边就被排除了。这既让推送干净(我只想看原创),也顺带省钱——返回的推文越少,账单越低。本地再做一次过滤作为兜底。
成本实测:大头不是 AI,是轮询
这部分是我觉得最值得分享的一个反直觉发现。
TwitterAPI.io 按量计费,但有个容易忽略的点:规则「检查」这个动作本身就要扣费,实测约 14 credits 一次,哪怕这次返回 0 条推文也照扣。
这意味着成本公式其实是:规则数 × 检查频率。间隔调短是要花钱的,不存在「反正按推文数算,那我调到 1 分钟一次好了」这回事。
一份真实账单(18 位博主、4 条规则、10 分钟间隔、每天约 55 条推文):
| 项目 | 7 天花费 | 占比 |
|---|---|---|
| TwitterAPI 规则检查 | $0.24 | 59% |
| TwitterAPI 返回推文 | $0.06 | 15% |
| DeepSeek(翻译 + 分析 + 早报) | $0.10 | 26% |
| 合计 | $0.40 | 折合月度 约 $1.7 |
六成的钱花在了「问一句有没有新推文」上,AI 只占四分之一。
所以想继续降成本,正确的做法是拉长检查间隔、合并规则,而不是去换更便宜的模型——后者省下来的是那 26% 里的一部分,杯水车薪。
我在项目里写了个 cost.py,按实测 token 用量和检查次数核算,每 7 天往告警群推一份成本报告;模型单价也可以在 .env 里按真实账单校准。自托管的东西,账单可见比什么都重要,否则很容易某天发现钱在悄悄漏。
可靠性上做的那些事
自托管服务最怕的不是跑不起来,是跑着跑着悄悄挂了而你不知道。所以这块花的功夫比功能本身还多:
- 去重与幂等:
tweet_id唯一索引 + delivery 幂等记录,容器重启不会重复推送同一条; - 失败重试:推送失败按 1 / 5 / 15 / 30 / 60 分钟递增退避,重试到底还不行就进 dead-letter 并告警;
- 每日心跳体检:检查规则状态、API key、账户余额、webhook 连通性、推送队列,任何一项异常就报警;
- handle 改名检测:每月比对一次
user_id,博主改了用户名不会导致静默失联; - 独立告警群:所有运维消息(心跳、成本、失败)走单独的飞书机器人,不污染正常的推文群。
部署
前置需要:一台装了 Docker 的服务器(1C1G 足够)、一个托管在 Cloudflare 的域名、TwitterAPI.io 的 key、DeepSeek 的 key、一个飞书群机器人。
然后一条命令:
1
2
3
git clone https://github.com/datazhy/x-monitor-feishu.git x-monitor
cd x-monitor
bash deploy/install.sh
脚本会检查 Docker 环境、生成 .env、自动生成 webhook secret、逐项提示填配置、构建启动容器并做健康检查。
HTTPS 证书由 Caddy 通过 Cloudflare DNS-01 自动签发和续期,监听独立端口(默认 8443),不占用 80/443——服务器上已经跑着别的服务也不影响。
剩下三步外部配置(在 Cloudflare 加一条 A 记录、在 TwitterAPI.io 控制台填回调地址、编辑 config/rules.yml 填博主名单),README 里有详细说明,这里就不展开了。
有个坑提前说一下:Cloudflare 那条 A 记录必须是灰云(DNS only),开橙云代理会挡掉非标准端口,webhook 就收不到了。我在这上面卡过一会儿。
限制与说明
- 存储用的是 SQLite,单机自托管完全够用;量级大了可以换 PostgreSQL,改
db.py即可。 - 推送渠道目前以飞书为一等公民,其它渠道预留了扩展位但没做深。
- LLM 默认全用 DeepSeek,但每类任务(翻译 / 分析 / 早报)都可以独立换 provider,任何兼容 OpenAI
/chat/completions协议的服务改个 base URL 就能接。 - 这套东西只做信息聚合与摘要。提示词里明确禁止模型给出买卖建议或编造数字,但 AI 生成的内容仍然可能有误,重要的信息请自己点回原推核实。
写在最后
这个项目的出发点其实很个人化——我只是不想错过几个博主的更新。但做下来发现,真正花时间的从来不是「调通 API」,而是成本怎么算、挂了怎么发现、模型胡说八道怎么防这些事。
如果你也有类似的需求(不一定是盯美股,追任何领域的 X 博主都适用),欢迎试试看,也欢迎提 Issue 和 PR:
相关资料
- datazhy/x-monitor-feishu — 本项目源码(MIT)
- TwitterAPI.io — 本文使用的第三方推文数据源,按量计费
- DeepSeek 开放平台 — 翻译、逐条分析与早报写作所用的 LLM
文中成本数据来自我自己账户的实测账单(18 位博主、4 条规则、10 分钟检查间隔), 不同配置下的费用会有明显差异。