🎯 Learning objectives
Triage with labels
Create a Gmail label/filter so Hermes only reads high-value mail.
สร้าง label/filter ของ Gmail ให้ Hermes อ่านเฉพาะอีเมลสำคัญ
建一个 Gmail 标签/筛选器,让 Hermes 只读重要邮件。
Draft-then-confirm
Add draft_gmail_reply — saves to Drafts, never sends.
เพิ่ม draft_gmail_reply — บันทึกลง Drafts ไม่ส่ง
添加 draft_gmail_reply — 只存草稿,从不发送。
Schedule with the OS
Wire launchd (Mac) / Task Scheduler (Win) to run daily_brief.py at 8 AM — same pattern as the extras' daily_word.py.
ตั้ง launchd (Mac) / Task Scheduler (Win) รัน daily_brief.py 8 โมง — pattern เดียวกับ daily_word.py ใน extras
用 launchd(Mac)/ 任务计划程序(Win)每天 8 点跑 daily_brief.py — 与 extras 里的 daily_word.py 同样模式。
📬 Interactive: triage in action
Click Run daily_brief.py. Watch the agent process only the labelled rows — newsletters and spam never touch Hermes' context window.
คลิก Run daily_brief.py ดู agent ประมวลผลเฉพาะแถวที่ติด label — จดหมายข่าวกับสแปมไม่เข้าถึง context ของ Hermes เลย
点击 Run daily_brief.py,看代理只处理带标签的行 — 邮件订阅和垃圾邮件根本不会进入 Hermes 的上下文。
📚 Key concepts
🇬🇧 English
Auto-triage — Gmail's filter rules are doing the cheap work. Hermes only burns tokens on emails the filter labelled @AI_Handle.
Draft-then-confirm — the FunctionTool calls drafts().create() only. It cannot send. The capability isn't there to abuse.
OS-scheduled agent run — launchd / Task Scheduler runs python daily_brief.py at 8 AM. The agent never schedules itself.
🇹🇭 ไทย
Auto-triage — ตัวกรองของ Gmail ทำงานหนัก Hermes เผา token เฉพาะอีเมลที่ติด @AI_Handle
Draft-then-confirm — FunctionTool เรียก drafts().create() เท่านั้น ส่งไม่ได้ ไม่มีความสามารถให้ใช้ผิด
OS-scheduled agent run — launchd / Task Scheduler รัน python daily_brief.py 8 โมง agent ไม่เคยตั้งเวลาตัวเอง
🇨🇳 中文
自动分流 — Gmail 的过滤规则承担粗活,Hermes 只在带 @AI_Handle 的邮件上消耗 token。
先起草再确认 — FunctionTool 只调 drafts().create()。它没有发送能力,自然无法滥用。
由操作系统调度 — launchd / 任务计划程序每天 8 点跑 python daily_brief.py,代理永远不会自己排定时任务。
🧪 Hands-on lab
Create the Gmail label + filter
In Gmail → Settings → Filters → Create. Match subject/body containing booking | price | tour | availability | ราคา | 价格 → apply label @AI_Handle.
Gmail → Settings → Filters → Create กรองคำว่า booking | price | tour | availability | ราคา | 价格 → ใส่ label @AI_Handle
Gmail → 设置 → 过滤器 → 新建:匹配 booking | price | tour | availability | ราคา | 价格 → 套用标签 @AI_Handle。
Upgrade the OAuth scope
In gmail_auth.py add the compose scope. Delete the cached token so the consent screen runs again.
ใน gmail_auth.py เพิ่ม scope compose ลบ token cache เพื่อให้หน้า consent มาใหม่
在 gmail_auth.py 加上 compose 权限。删除缓存的 token,让同意页面再跑一次。
Add the draft tool
The entry point + launchd plist
Install & smoke-test:
ติดตั้ง + ทดสอบ:
安装并冒烟测试:
Windows equivalent — Task Scheduler → Create Basic Task → Daily 08:00 → start python C:\path\to\daily_brief.py.
บน Windows — Task Scheduler → Create Basic Task → Daily 08:00 → รัน python C:\path\to\daily_brief.py
Windows 等价做法 — 任务计划程序 → 创建基本任务 → 每日 08:00 → 启动 python C:\path\to\daily_brief.py。
⚠️ Top gotchas
1. The "send" hallucination
If you ever add a send_gmail tool, the agent will use it even when you said "draft only." Don't add the tool.
ถ้าเพิ่ม send_gmail เมื่อไหร่ agent จะใช้แม้สั่ง "ร่างเท่านั้น" — อย่าเพิ่มเครื่องมือนี้
一旦加了 send_gmail 工具,即使你说"只起草",代理也会用它 — 干脆别加。
2. Sleeping laptop misses 8 AM
launchd can't wake a powered-off Mac. Use pmset repeat wakeorpoweron MTWRF 07:55:00.
launchd ปลุก Mac ที่ปิดเครื่องไม่ได้ ใช้ pmset repeat wakeorpoweron MTWRF 07:55:00
launchd 没法唤醒关机的 Mac,用 pmset repeat wakeorpoweron MTWRF 07:55:00。
3. Context drain from raw inbox
Hermes reading every email burns context. The label filter is what makes this affordable.
Hermes อ่านทุกอีเมล = เผา context ตัวกรอง label คือสิ่งที่ทำให้ทำได้
让 Hermes 读所有邮件会烧光上下文。标签过滤是这个方案能跑下去的关键。
📝 Assessment & homework
✅ Assessment
Practical: Drafts folder contains agent-written replies to dummy emails. Conceptual: why we filter before the agent reads, not after.
ภาคปฏิบัติ: โฟลเดอร์ Drafts มีร่างจาก agent ภาคทฤษฎี: ทำไมต้องกรอง ก่อน agent อ่าน ไม่ใช่หลัง
实操:草稿箱里有代理写的回复。概念:为什么要在代理读邮件之前过滤,而不是之后。
🏠 Homework
Let the 8 AM brief run 3 mornings. Bring the one email the agent answered worst — probably a meeting request, which is exactly Week 3.
ปล่อยให้รัน 3 เช้า เอาอีเมลที่ตอบแย่ที่สุดมาด้วย — น่าจะเป็นการนัดประชุม ซึ่งคือ Week 3 พอดี
让 8 点的简报跑三个早晨,挑出代理答得最差的一封 — 很可能是约会请求,正好是 Week 3 的内容。