仓库:github.com/aks-666888/... | SkillHub:邮件摘要待办助手 v2.0.0(安全审核中)
一、痛点
周一早上 200+ 封未读,老板的消息混在订阅推送里。我不想把邮件交给任何云端 AI(隐私焦虑 + 数据出境),又受不了逐封翻------所以手搓了一个本地的邮件摘要工具:
- 邮件只在本机处理,零依赖(仅 Python 标准库)
- 把一堆邮件变成「高优/中/低」+「待办清单」+「截止日」
- 可选本地 LLM(Ollama/Hermes)增强语义,失败自动降级规则
- 一键推送到手机(企业微信/飞书机器人)
二、为什么选本地处理
| 方案 | 隐私 | 成本 | 离线可用 |
|---|---|---|---|
| 通用云端 AI 摘要(Superhuman AI、Shortwave AI 等) | ❌ 邮件出本机 | 月费 | ❌ |
| 本地自托管(本文) | ✅ 邮件不出电脑 | 免费 | ✅ |
| Apple Intelligence(iOS 端) | ✅ | 设备绑定 | ✅ |
2026 年的明确趋势是 on-device/local-first。隐私焦虑最尖锐------企业怕客户邮件/商业计划上云。
三、实现要点
3.1 核心数据结构
邮件统一成一份 list,每封是个 dict:
python
{
"from": "老板王总",
"subject": "【紧急】客户方案请今天下班前确认",
"date": "2026-08-24",
"body": "小李,客户对方案提了两点修改意见......",
}
3.2 优先级打分(关键设计:未读≠重要)
python
HIGH = ["紧急", "尽快", "请今天", "截止", "请确认", "请处理", "请回复", "asap", "urgent"]
MID = ["会议", "周报", "复盘", "进度", "提醒", "改期", "报名", "订阅", "通知"]
def score(em):
s = 0
text = (em["subject"] + " " + em["body"]).lower()
has_high = False
for k in HIGH:
if k.lower() in text:
s += 3
has_high = True
for k in MID:
if k.lower() in text:
s += 1
em["_has_high"] = has_high # 高优用「信号词」标记,不用累加分数
return s
设计取舍:高优不是「分数最高」,而是「含紧急/截止/需行动类信号词」。避免「未读 = 重要」的误判。
3.3 待办与截止日抽取
python
TODO_PAT = re.compile(r"请[^\n。]{2,30}(?:一下|一下我|处理|确认|回复|补交|修改|报名|查看)")
DDL_PAT = re.compile(r"((?:\d{1,2}\s*月\s*\d{1,2}\s*日)|(?:周[一二三四五六日])|(?:今天|明天|后天|本周|下周))")
def todos(em): return [t.strip() for t in TODO_PAT.findall(em["body"])][:3]
def ddls(em):
text = em["body"] + " " + em["subject"]
out = []
for m in DDL_PAT.finditer(text):
d = m.group(2) or m.group(3)
if d: out.append(d.strip())
return list(dict.fromkeys(out))[:2]
3.4 项目分组
优先取方括号标签([项目A] 周报),否则按关键词匹配:
python
def project(em, projects):
m = re.search(r"\[([^\]]+)\]", em.get("subject", ""))
if m: return m.group(1)
body = em.get("body", "").lower()
for kw in projects:
if kw.lower() in body or kw.lower() in em.get("subject", "").lower():
return kw
return "其他"
3.5 三入口设计(不绑架用户)
- 宿主连接器(零配置,主推):WorkBuddy/Codex/Claude/Hermes 拉邮件 → 转 JSON → 本技能消费
- IMAP 直连(自托管):配一次授权码,数据完全自控
- 文本粘贴(兜底):复制邮件正文存 txt
3.6 输出(JSON 契约)
json
{
"total": 6, "high": 3, "mid": 3, "low": 0,
"emails": [
{"from":"老板王总","subject":"...","priority":"high",
"project":"客户","todos":["请在今天下班前确认并回复我"],"ddl":[]}
]
}
HTML/Markdown 输出供人看,JSON 给 Agent 框架消费。
四、踩坑
- 未读 ≠ 重要:第一版用「未读+时间衰减」打分,结果营销订阅被误判高优。改用信号词后准确率大幅提升。
- 正则贪婪匹配 :截止日正则要排除邮件签名/转发链里的日期串,常见做法是先剥
发件人:/签名块再匹配。 - 编码 :IMAP 抓
.eml要强制utf-8,国内邮箱(QQ/网易)经常返回 GBK。 - 降级:LLM 增强失败时(端点挂了/超时)必须降级到规则------不能因为 LLM 不可用就让整个工具瘫痪。
五、成果
- 已上架 SkillHub「邮件摘要待办助手」v2.0.0(TRACE 评测安全审核中)
- 计划:v2.1 加 RAG 召回历史邮件(同一项目上下文)
六、关键代码
完整实现 22KB,单文件 digest.py:仓库链接,欢迎 Star / Issue。
标签:#Python #效率工具 #邮件处理 #AI #本地化