ESSAY
个人情报系统 v2:从能用到好用的三次迭代
“能用的系统只解决’有没有’,好用的系统解决’想不想用’。“
从 500 条 RSS 到 9 条搜索
如果你读过我上一篇《用 n8n + DeepSeek 搭建个人科技情报系统》,应该记得 v1 的核心架构:13 个 RSS 源 → n8n 工作流 → DeepSeek 分析 → Obsidian。它每天处理 500+ 条信息,压缩到 10 条精华,执行耗时 2.5 分钟。
它能工作。但用了三个月后,我发现了几个问题:
- RSS 源的局限性:我在意的不只是固定几个科技媒体的内容,而是整个领域正在发生什么。RSS 本质上是”订阅已知”,搜索才是”发现未知”。
- n8n 的运维成本:Docker 容器要维护,工作流要调试,凭证系统有奇怪的限制。一个每天跑 2.5 分钟的系统,不值得我在它身上花超过 2.5 分钟的维护时间。
- 输出缺乏可读性:每天十条长分析,每篇几百字。我看不看完——实际上经常不看。信息太多和没有信息,结果是相同的。
所以三个月后,我重写了整个系统。这次不是”再搭一套”,而是回答一个问题:什么样的情报系统,才会让我每天早上愿意打开?
答案是三条标准:
- 一眼看清价值 —— 不用读内容就知道哪条值得点
- 摘要先行 —— 每条 20 字,看完决定是否深入
- 零运维 —— 开机自动跑,跑完不用管
以下是实现这三条标准的三次迭代。
迭代一:价值评级系统
问题
v1 的输出是一篇长 Markdown,每条情报都有完整的 DeepSeek 分析:翻译、地缘政治洞察、评分。但问题是——所有条目看起来都很重要。每篇都是十行为单位的分析段落,扫读成本太高。
我真正需要的是:在扫读阶段就知道”这条和我有关吗?有多有关?“
方案
抛弃纯 AI 评分的黑盒思路,换成关键词匹配 + 三层分级的透明体系。
每个领域(AI 技术 / 国际政治 / 国际经济)定义三层关键词:
SCORING = {
"ai_tech": {
"high": { # ★★★ 工作相关
"keywords": ["claude", "gpt", "coding", "deploy", "mcp",
"agent", "docker", "github", ...],
"label": "工作相关",
"emoji": "💼",
},
"medium": { # ★★☆ 行业趋势
"keywords": ["llm", "benchmark", "reasoning",
"multimodal", "alignment", ...],
"label": "行业趋势",
"emoji": "📈",
},
"low": { # ★☆☆ 背景参考
"keywords": ["ethic", "regulation", "society", "impact", ...],
"label": "背景参考",
"emoji": "📖",
},
},
# politics 和 economics 同理
}
匹配逻辑极其简单:标题 + 描述中出现任意关键词即命中该层级,取最高分。没有权重计算,没有机器学习,就是把判断标准白纸黑字写出来。
为什么这样设计
关键词系统有两个 AI 评分无法替代的价值:
- 可预测 —— 我知道为什么一条新闻被标为 ★★★。因为标题里有 “claude” 或 “agent”,这是我的工作领域。我不会看到一条莫名其妙的低分或高分,然后质疑系统是不是坏了。
- 可调整 —— 觉得某类新闻权重不对?直接编辑关键词列表,改完立即生效,不需要重新训练任何模型。
这是我在 v1 中学到的教训:v1 用 DeepSeek 输出 0-10 的评分,但从来没解释过为什么给这个分。用户(我自己)不信任黑盒评分。而信任是”愿意看”的前提。
输出效果
每条情报在 Obsidian 中显示为:
1. 「★★★」[Claude Code 推出 MCP 支持](链接)
💼 工作相关
📝 Claude Code 新增 MCP 协议支持,提升开发工具集成能力。
三星 + 标签 + 一行摘要,半秒内决定是否值得点开。
迭代二:AI 中文摘要
问题
v1 的每条情报包含完整的 DeepSeek 分析:200-300 字翻译 + 地缘政治洞察。但我在 Obsidian Daily Note 中浏览时,根本不想读 300 字——我只想知道”这条说了什么,值不值得我点进去看全文”。
换句话说,我需要的是诱饵,不是大餐。
方案
用 DeepSeek 为所有情报批量生成一句话中文摘要(20-30 字),同时给出 0-100 的信号分。
关键设计:9 条情报一次 API 调用。
def _build_prompt(data):
lines = []
idx = 0
for domain, label in [("ai_tech", "AI技术"),
("politics", "国际政治"),
("economics", "国际经济")]:
items = data.get(domain, [])
start = idx
for item in items:
idx += 1
lines.append(f"{idx}. [{label}] {item['title']}")
if item.get("description"):
lines.append(f" 描述: {item['description'][:300]}")
domain_map[domain] = (start, idx)
prompt = """你是一个情报分析师。为以下每条新闻生成一句中文摘要
(20-30字,说清核心信息)。同时给出信号分(0-100),
100 = 对该用户(AI开发者+国际政经学生)极有价值。
## 输出格式
严格返回 JSON 数组,每个元素匹配输入顺序:
[
{"summary": "中文摘要", "signal": 85},
...
]
只返回 JSON,不要其他文字。
## 新闻列表
{news}"""
return prompt, domain_map
注意到 prompt 里明确定义了读者画像:AI 开发者 + 国际政经学生。这样 DeepSeek 的摘要会主动突出这两个视角下的关键信息,而不是泛泛概括。
实测效果
原始标题: "Anthropic Announces Claude Code with MCP Support"
原文描述: "Claude Code adds Model Context Protocol support..."
AI 摘要: "Anthropic 推出 Claude Code,支持 MCP 协议,提升 AI 编程效率。"
信号分: 92
原始标题: "US-China Trade Talks Resume"
原文描述: "High-level negotiations continue..."
AI 摘要: "中美高层贸易谈判重启,关注全球经济走向。"
信号分: 78
摘要控制在 20-30 字,刚好是一眼扫完的长度。感兴趣就点链接看全文,不感兴趣就跳过。整个扫读过程不超过 30 秒。
为什么是摘要而不是翻译
v1 做的是”翻译 + 深度分析”——把英文变成中文,再补充背景洞察。这在处理 10 条精选时可行,但每天读 10 篇 300 字分析,认知负担很重。
v2 的假设是:如果我能快速扫完所有条目,自然会点开真正重要的那两三篇看原文。 摘要的任务不是替代阅读,而是帮助决定”读哪篇”。
这个假设成立的前提是摘要质量够高,而 DeepSeek 在这方面表现足够好。
迭代三:从定时触发到开机触发
问题
v1 运行在 n8n 上,v2 最初部署在 Windmill(一个开源任务调度平台)上,设置每天早上 8:00 定时执行。但很快就发现一个尴尬的事实——
如果 8 点电脑还没开机,系统就不会执行。Windmill 跑在 localhost 上,电脑关机它就停了。
定时的逻辑是”每天 8 点你大概率已经开机了”,但这隐含了依赖——我必须每天都在 8 点前开机。
方案
放弃云调度,回到本地触发。用 Windows Task Scheduler 设置开机启动,加上去重机制防止一天内多次重启导致重复追加。
# main.py 中的去重逻辑
def _should_run():
today = datetime.now().strftime("%Y-%m-%d")
try:
with open("state.json") as f:
state = json.load(f)
if state.get("last_run_date") == today:
return False # 今天已跑过,跳过
except FileNotFoundError:
pass
return True
def _mark_run():
with open("state.json", "w") as f:
json.dump({"last_run_date": datetime.now().strftime("%Y-%m-%d")}, f)
开机触发脚本也非常简单——就是一个 PowerShell 脚本,Task Scheduler 调用它:
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location $scriptDir
python main.py 2>&1 | Out-File -Append -FilePath "../boot_run.log"
为什么这是正确的选择
这个决策背后有一个更本质的思考转变:不要把自动化系统设计成”服务器思维”。
我之前一直默认——自动化 = 定时触发 = 需要一台 7x24 运行的服务器。但这是我的个人电脑,它不是服务器。强行让个人电脑模拟服务器的行为模式,只会带来运维负担。
开机触发的逻辑是:你开机了 = 你要开始工作了 = 这时候给你情报刚好。它不要求电脑 24 小时在线,不要求设置复杂的时间调度,甚至不需要 Docker。而且实际上,我每天早上进系统的第一件事就是看 Obsidian Daily Note——情报已经在那里等我了。
去重机制保证了一天内多次重启不会重复,日志文件让排查问题变得简单。
技术债务清理
v1 → v2 不只是加功能,也砍了很多东西:
- 砍掉 Docker:之前 n8n 和 Windmill 都跑在 Docker 里,每个都要维护。现在纯 Python 脚本,一个
pip install requests就够了 - 砍掉 n8n:n8n 是优秀的低代码工具,但对我这个场景来说太重了。Python 脚本 + 命令行直接调用,简单到没有任何可坏的环节
- 砍掉复杂分析:v1 每条情报配多段分析,v2 只保留一行摘要。分析是作者视角(“我分析给你看”),摘要是编辑视角(“我帮你决定看什么”)
保留的只有 Obsidian Local REST API——这是整个系统的”最后一公里”,也是最稳定的一环。
结语:从能用走向好用的路标
回顾这三次迭代,我看到了一个清晰的模式:每次改进都在回答一个问题。
| 问题 | 答案 | 实现 |
|---|---|---|
| 我怎么知道哪条值得看? | 价值评级 | ★★★/★★☆/★☆☆ + 关键词匹配 |
| 我怎么快速决定点不点? | AI 摘要 | DeepSeek 批量生成 20 字摘要 |
| 我为什么要记得手动跑? | 开机触发 | Task Scheduler + 去重 |
“能用”和”好用”的区别不在于功能多少,而在于使用阻力的大小。
v1 每次看情报需要 3-5 分钟扫读、思考”这条和我有关吗”、决定是否点开——这是阻力。v2 把时间压缩到 30 秒以内,因为评分和摘要已经替我做了预筛选。
同样地,v1 需要我维护 Docker 容器、检查 n8n 工作流是否正常、关注 Windmill 是否还在跑——这也是阻力。v2 的代码量更少,依赖更少,出问题的可能自然也更少。
好的自动化系统最终应该让你忘记它的存在。它默默地出现在你每天打开的第一个页面上,然后你不需要去想它。
项目信息:
- 架构:Python 脚本 + AnySearch API + DeepSeek API + Obsidian Local REST API
- 触发方式:Windows Task Scheduler 开机启动
- 数据源:AnySearch(聚合搜索引擎)
- 情报量:每天 9 条(AI 技术 3 + 国际政治 3 + 国际经济 3)
- 代码行数:~350 行 Python
- 外部依赖:仅
requests
从 2.5 分钟的 n8n 工作流到 5 秒完成的 Python 脚本——有时候”少即是多”。