14 KiB
| date | topic |
|---|---|
| 2026-06-23 | calendar-schedule |
Summary
在 AgentKit 客户端右侧面板嵌入行事历(可展开为大抽屉),通过混合模式(ReAct 工具调用 + 时间关键词触发的后处理提取)自动捕获对话中的日程,同时支持完整的手动管理——循环事件、自定义类型、标签、三种视图(日历/卡片/列表),UI 对标 Notion Calendar。日程双向同步 Apple Calendar (CalDAV)、Outlook (Graph API) 和 iCal/ICS,配套独立的多渠道提醒子系统(客户端 + 邮件 + Webhook),个人为主 + 共享邀请。
Problem Frame
Agent 对话中频繁产生可执行的时间安排——会议时间、截止日期、跟进任务——但这些信息当前无处记录。用户必须手动将这些内容转移到外部日历中,这个过程容易遗漏,尤其在长对话中多个时间点被讨论时。痛点不在"缺少一个日历应用",而在"Agent 产生的日程与日历之间没有桥梁":对话结束后,时间承诺就消失了。
Key Decisions
混合 Agent 识别模式。 ReAct 工具调用捕获实时意图(Agent 在对话中主动调用 create_event),后处理提取作为兜底——但仅在对话包含时间关键词时触发 LLM 提取,避免每轮对话都产生额外 LLM 调用。两层机制互补:工具调用覆盖 Agent 已识别的明确日程,后处理覆盖 Agent 未主动识别但对话中隐含的时间安排。
右侧面板 + 大抽屉而非独立页面。 日历紧贴对话上下文,用户不用切换页面就能看到即将到来的日程。需要全屏管理时展开为大抽屉。这牺牲了独立页面的全屏日历体验,但换来了日程与对话的紧密耦合——这是核心痛点的解法。
提醒系统作为独立子系统。 多渠道提醒(客户端推送 + 邮件 + Webhook)需要后台调度器、通知规则、渠道适配器、投递追踪——这不仅是日历的一个功能,而是 AgentKit 目前不存在的全新基础设施。作为独立子系统设计,未来可被其他功能复用。
个人日历 + 共享邀请,不做团队日历。 用户有自己的私人日历,可以邀请其他用户参加事件(类似 Google Calendar 的邀请),但不支持多用户共同编辑同一日历。团队日历是不同的产品形态,不在此次范围内。
Actors
- A1. 终端用户 — 管理个人日历,手动创建/查看/编辑/删除事件,管理事件类型和标签,配置提醒规则
- A2. Agent — 在 ReAct 循环中自主识别日程意图并调用日历工具创建事件;后处理提取层在时间关键词触发时分析对话内容
- A3. 外部日历服务 — Apple Calendar (CalDAV)、Outlook (Microsoft Graph API)、iCal/ICS 通用格式,作为双向同步目标
- A4. 提醒子系统 — 后台调度器定期扫描即将到期的事件,根据提醒规则通过配置的渠道分发通知
Requirements
事件数据模型
- R1. 事件包含标题、描述、开始时间、结束时间、全天标记、地点字段
- R2. 事件支持循环模式:每日、每周、每月、自定义 RRULE 规则(至少支持 INTERVAL、COUNT、UNTIL、BYDAY)
- R3. 事件支持自定义事件类型——用户可创建带名称和颜色的分类(如"会议"蓝色、"截止"红色),事件创建时选择类型
- R4. 事件支持多标签——用户可自定义标签,单个事件可挂多个标签,支持按标签筛选
- R5. 事件支持时间段——开始时间 + 结束时间,不限于时间点;全天事件和跨天事件均支持
视图模式
- R6. 日历视图——月/周/日网格布局,支持拖拽创建(拖选时间段直接建事件)、拖拽移动(拖动事件改变时间)
- R7. 卡片视图——看板风格,按日期或事件类型分组,卡片可拖拽调整分组
- R8. 列表视图——按时间排序的列表,支持行内编辑和批量操作
- R9. 三种视图在右侧面板和大抽屉中均可切换使用
Agent 自动识别
- R10. Agent 在 ReAct 循环中可调用日历工具集:
create_event、query_events、update_event、delete_event - R11. 后处理提取在对话轮次结束后运行,但仅当对话内容包含时间关键词时触发——关键词列表包括但不限于:明天、下周、今天下午、X点、X月X日、开会、截止、deadline、schedule、reminder、提醒、预约
- R12. 时间关键词检测使用正则/关键词匹配(零 LLM 调用),命中后才发起 LLM 提取请求
- R13. Agent 创建的事件标记
source="agent",并关联到 originating 对话 ID,可在日历中追溯来源 - R14. 后处理提取创建的事件标记
source="post_extract",同样关联对话 ID - R15. 用户可在 UI 中区分手动创建、Agent 创建、后处理提取的事件(通过来源标记或颜色区分)
手动管理
- R16. 用户可通过 UI 手动创建、编辑、删除事件——三种视图均支持创建入口
- R17. 日历视图支持拖拽改期——拖动事件到新时间位置即可调整开始/结束时间
- R18. 事件类型和标签可在事件编辑界面中设置和修改
- R19. 支持批量操作:多选事件后批量删除、批量修改类型/标签
外部日历同步
- R20. 与 Apple Calendar 通过 CalDAV 协议双向同步——在 AgentKit 创建/修改/删除的事件同步到 Apple Calendar,反之亦然
- R21. 与 Outlook Calendar 通过 Microsoft Graph API 双向同步——同上双向
- R22. 支持 iCal/ICS 格式的导入和导出——可从 .ics 文件导入事件,可将日历导出为 .ics
- R23. 同步冲突采用 last-write-wins 策略,冲突时保留最后修改的版本,并向用户发送冲突通知
- R24. 用户可在设置中配置每个外部日历的同步频率和同步范围(哪些事件类型参与同步)
提醒子系统
- R25. 事件支持提醒规则——可配置多个提醒(如"提前15分钟"、"提前1天"),每个提醒指定渠道
- R26. 提醒渠道支持:客户端内通知(WebSocket 推送 / Tauri 系统通知)、邮件、Webhook
- R27. 后台调度器定期扫描即将到期的事件,匹配提醒规则,通过配置的渠道分发通知
- R28. 用户可为每种事件类型配置默认提醒规则——新建事件时自动继承
- R29. 提醒投递状态可追踪(已发送/已读/失败),失败的提醒有重试机制
共享与邀请
- R30. 用户可邀请其他用户参加事件——通过用户名或邮箱搜索并邀请
- R31. 被邀请用户收到通知,可接受/拒绝/暂定
- R32. 事件创建者可查看邀请回复状态(谁接受、谁拒绝、谁未回复)
- R33. 被邀请用户的事件在其日历中以特殊样式标记(如半透明或边框区分)
UI/UX
- R34. 日历嵌入右侧面板作为标签页(与 Workflow/Monitor 并列),展示今日/近期日程摘要
- R35. 右侧面板日历可展开为大抽屉——覆盖大部分屏幕,提供完整的三视图管理体验
- R36. UI 遵循 Notion Calendar 设计语言——简洁排版、充足留白、流畅拖拽、柔和配色
- R37. Agent 创建事件时,右侧面板实时更新(无需手动刷新),并有视觉提示(如高亮动画)
Key Flows
-
F1. Agent 工具调用创建日程
- Trigger: Agent 在 ReAct 循环中识别到对话内容包含明确的时间安排
- Actors: A2 (Agent), A1 (用户)
- Steps: Agent 调用
create_event工具,传入标题/时间/类型等参数 → 工具执行写入 → 返回创建结果 → Agent 在回复中告知用户已创建日程 → 右侧面板实时更新显示新事件 - Outcome: 事件被创建并标记
source="agent",用户在对话中收到确认 - Covers: R10, R13, R37
-
F2. 后处理提取创建日程
- Trigger: 对话轮次结束,对话内容命中时间关键词正则
- Actors: A2 (Agent 后处理层), A1 (用户)
- Steps: 关键词检测命中 → 发起 LLM 提取请求,分析对话中的时间安排 → LLM 返回提取结果(0 或多个事件) → 写入日历,标记
source="post_extract"→ 在对话中插入轻量提示"检测到 N 条日程,已添加到日历" - Outcome: 隐含的日程被捕获,用户收到提示可查看/修改
- Covers: R11, R12, R14
-
F3. 外部日历双向同步
- Trigger: 定时同步任务触发,或用户手动触发同步
- Actors: A3 (外部日历服务), A1 (用户)
- Steps: 拉取外部日历变更 → 与本地事件比对 → 检测冲突 → last-write-wins 解决冲突 → 推送本地变更到外部日历 → 冲突时向用户发送通知
- Outcome: 本地与外部日历保持一致,冲突被记录和通知
- Covers: R20, R21, R23
-
F4. 提醒分发
- Trigger: 后台调度器扫描到事件即将到达提醒时间点
- Actors: A4 (提醒子系统), A1 (用户)
- Steps: 调度器匹配提醒规则 → 按规则配置的渠道分发通知(客户端推送 / 邮件 / Webhook) → 记录投递状态 → 失败时重试
- Outcome: 用户在事件前通过配置的渠道收到提醒
- Covers: R25, R26, R27, R29
-
F5. 手动创建事件
- Trigger: 用户在任意视图中触发创建操作(点击新建、拖选时间段、列表中添加)
- Actors: A1 (用户)
- Steps: 打开事件编辑表单 → 填写标题/时间/类型/标签/提醒/地点 → 保存 → 事件出现在日历中 → 如配置了外部同步,异步推送到外部日历
- Outcome: 事件被创建并可管理
- Covers: R16, R18
Acceptance Examples
-
AE1. Agent 在对话中识别日程
- Covers: R10, R13, R15
- Given: 用户与 Agent 对话,用户说"下周三下午3点开个产品评审会"
- When: Agent 在 ReAct 循环中处理该输入
- Then: Agent 调用
create_event创建事件(标题="产品评审会", 开始时间=下周三15:00, source="agent"),并在回复中告知"已为您创建下周三下午3点的产品评审会日程"
-
AE2. 后处理提取被关键词门控
- Covers: R11, R12, R14
- Given: 用户与 Agent 对话,对话内容为"这个方案不错,我们继续优化吧"
- When: 对话轮次结束,后处理层检查时间关键词
- Then: 关键词检测未命中(无时间相关词),不发起 LLM 提取请求,不创建任何事件
-
AE3. 后处理提取在关键词命中时运行
- Covers: R11, R12, R14
- Given: 用户与 Agent 对话,对话内容为"好的,那下周二之前把文档发给我"
- When: 对话轮次结束,后处理层检查时间关键词
- Then: 关键词"下周二"命中 → 发起 LLM 提取 → 创建事件(标题="发送文档", 截止时间=下周二, source="post_extract")→ 对话中插入提示"检测到 1 条日程,已添加到日历"
-
AE4. 同步冲突解决
- Covers: R23
- Given: 用户在 AgentKit 修改了事件 A(改到周三),同时在 Outlook 也修改了事件 A(改到周四),同步时检测到冲突
- When: 同步任务运行
- Then: 保留最后修改的版本(last-write-wins),向用户发送冲突通知"事件 A 存在同步冲突,已保留最新修改"
-
AE5. 提醒按渠道分发
- Covers: R25, R26, R27
- Given: 事件 B 配置了两个提醒:提前30分钟客户端通知 + 提前1天邮件通知
- When: 调度器扫描到事件 B 的提前1天提醒时间点到达
- Then: 通过邮件渠道发送提醒 → 记录投递状态为"已发送" → 继续等待提前30分钟的客户端通知时间点
Scope Boundaries
Deferred for later
- Google Calendar 集成——用户未选择,可在后续版本按需添加
- 团队共享日历——多用户共同编辑同一日历,当前仅支持个人 + 邀请
- 日历分析报表——事件统计、时间分布分析等
- 资源预订——会议室、设备等资源预约
- 移动端独立 App——当前仅 Web/Tauri 客户端
Outside this product's identity
- 替代专业日历应用——AgentKit 行事历的核心差异化是 Agent 自动识别,不是与 Google Calendar/Notion Calendar 全功能竞争
- 项目管理——行事历不承担任务跟踪、甘特图、依赖管理等项目管理职能
Dependencies / Assumptions
- 复用现有认证系统(
src/agentkit/server/auth/models.py的UserModel)作为用户身份基础 - 复用现有 WebSocket 基础设施实现客户端实时通知推送
- 新增依赖:后台调度器(如 APScheduler)用于提醒子系统
- 新增依赖:CalDAV 客户端库用于 Apple Calendar 同步
- 新增依赖:Microsoft Graph SDK 或直接 HTTP 客户端用于 Outlook 同步
- 新增依赖:邮件发送能力(SMTP 或第三方服务)用于邮件提醒渠道
- 假设:用户已拥有 Apple Calendar / Outlook 账号并可提供 OAuth/CalDAV 凭据
- 假设:AgentKit 服务端可持续运行后台调度器进程(提醒子系统依赖)
Sources / Research
- 现有架构落位参考:路由注册在
src/agentkit/server/app.py(第 928-954 行),前端布局在src/agentkit/server/frontend/src/components/layout/AgentLayout.vue(第 146-156 行定义象限标签) - 前端 Pinia stores 位于
src/agentkit/server/frontend/src/stores/,API 客户端位于src/agentkit/server/frontend/src/api/ - 后端路由模块位于
src/agentkit/server/routes/(27 个 .py 文件),工具注册在src/agentkit/tools/registry.py - 用户模型位于
src/agentkit/server/auth/models.py(SQLAlchemy 2 + SQLite),可复用Base创建日历模型 - 消息总线
src/agentkit/bus/message.py的AgentMessage可用于提醒子系统的内部通信 - DocumentTool(
src/agentkit/tools/document_tool.py)可作为 Agent 工具集成的参考模式——工具注册、ReAct 循环调用、结果返回