d58dc2a251
Introduce Draft → Confirm → Commit flow for WeChat schedule intents behind feature flags, plus h5_tasks dual-write/read aggregation and rollout scripts so reminders and automations get explicit user confirmation before persisting. Co-authored-by: Cursor <cursoragent@cursor.com>
297 lines
11 KiB
Markdown
297 lines
11 KiB
Markdown
# Intent Transaction Layer — 意图事务层设计
|
||
|
||
> **状态:** 架构草案(2026-08-24)
|
||
> **受众:** Memind / TKMind 智趣 — 面向普通用户的 Agent 平台
|
||
> **与现有文档关系:** 本文件是 [schedule-reminder-design.md](./schedule-reminder-design.md) 的演进方向;不替代当前已上线的 `h5_schedule_*` / `h5_scheduled_tasks` 实现,而是定义下一阶段的统一模型与 Commit Gate。
|
||
|
||
## 1. 核心判断
|
||
|
||
三层/四层 **路由准确率**(规则 + Preflight)可达 **99%+**,但这只解决:
|
||
|
||
```text
|
||
用户一句话 → 分类 → 写入
|
||
```
|
||
|
||
生产级 Agent 平台必须覆盖完整 **意图生命周期**:
|
||
|
||
```text
|
||
用户输入 → 理解 → Draft → 确认 → Commit → Worker 执行 → 查询 / 修改 / 删除 → Event Log
|
||
```
|
||
|
||
**任何具有副作用的 Agent 行为,都不应直接 Commit**,包括但不限于:
|
||
|
||
- 创建提醒 / 定时任务
|
||
- 发送消息 / 邮件
|
||
- 调用外部接口
|
||
- 创建或发布页面
|
||
|
||
因此第 4 层不应称为「互动确认」,而应升级为 **Intent Transaction Layer(意图事务层)**。
|
||
|
||
---
|
||
|
||
## 2. 内部分层命名(用户语义 vs 技术实现)
|
||
|
||
| 内部 Layer | 用户感知 | 到点后系统行为 | 当前 Memind 落点 |
|
||
|------------|----------|----------------|------------------|
|
||
| **Layer 0: Query Guard** | 「只是问问」 | 只回答,零副作用 | `parseScheduleIntent` → `query_schedule`;需扩展 query _guard |
|
||
| **Layer 1: Personal Memory** | 「帮我记着 / 到点叫我」 | **通知用户** | `h5_schedule_items` + `h5_schedule_reminders`;Preflight `create_timed_reminder` |
|
||
| **Layer 2: Scheduled Action** | 「到点替我做」 | **系统执行动作并交付** | `h5_scheduled_tasks` + `scheduled-task-worker` |
|
||
| **Layer 3: Agent Workflow** | 「多步骤复杂任务」 | Agent 编排 + 工具链 | Goose session + MCP tools;Finish 后可能有页面/消息 |
|
||
|
||
**本质区别不是「有没有时间」,而是到点以后:**
|
||
|
||
- Personal Memory → 微信/站内 **通知**
|
||
- Scheduled Action → **调用能力链**(搜索 → 生成 → 发送)
|
||
|
||
示例:
|
||
|
||
| 用户说法 | Layer | 08:00 发生什么 |
|
||
|----------|-------|------------------|
|
||
| 每天 8 点提醒我跑步 | L1 Personal Memory | 推送通知 |
|
||
| 每天 8 点帮我生成跑步报告 | L2 Scheduled Action | 拉数据 → 分析 → 生成页 → 推送链接 |
|
||
|
||
---
|
||
|
||
## 3. 意图事务层(ITL)流程
|
||
|
||
```text
|
||
User Message
|
||
│
|
||
▼
|
||
Intent Classifier
|
||
│
|
||
┌──────────────┴──────────────┐
|
||
▼ ▼
|
||
Query Guard Action Router
|
||
(Layer 0) (L1 / L2 / L3)
|
||
│ │
|
||
▼ ▼
|
||
Answer Only Draft Object
|
||
(no DB write) │
|
||
▼
|
||
Confirmation Layer
|
||
(Agent Action Card)
|
||
│
|
||
┌────────────┼────────────┐
|
||
▼ ▼ ▼
|
||
Confirm Modify Cancel
|
||
│ │ │
|
||
▼ └→ 新 Draft ─┘
|
||
Commit
|
||
│
|
||
▼
|
||
Worker / Agent
|
||
│
|
||
▼
|
||
Event Log
|
||
```
|
||
|
||
### Draft 状态
|
||
|
||
- 所有 Layer 1–3 的创建请求,**默认先写 Draft**(或内存 + `source_message_id` 关联,MVP 可用 `status=draft` 行)。
|
||
- 微信侧:Passive Reply / 客服消息展示 **Agent Action Card**;用户回复「确认」或点按钮后再 Commit。
|
||
- 现有 `guardScheduleConfirmationReply` 是 **反伪确认**;ITL 是 **正向前置 Gate**,二者互补。
|
||
|
||
### Event Log
|
||
|
||
建议字段:`intent_id`, `user_id`, `action`, `from_status`, `to_status`, `source_message_id`, `committed_at`, `worker_run_id`, `error`。
|
||
|
||
可与现有 `h5_schedule_delivery_log`、scheduled task `last_result_json` 逐步合并。
|
||
|
||
---
|
||
|
||
## 4. Action Level(风险分级)
|
||
|
||
每个 Draft 附带 metadata:
|
||
|
||
```json
|
||
{
|
||
"intent": "schedule",
|
||
"layer": 1,
|
||
"action_level": 1,
|
||
"risk": "low",
|
||
"side_effects": ["notify_wechat"]
|
||
}
|
||
```
|
||
|
||
| Level | 含义 | 示例 | Confirm 策略 |
|
||
|-------|------|------|----------------|
|
||
| **0** | 纯查询 | 「有没有我的新闻任务?」 | 禁止创建;只读 |
|
||
| **1** | 低风险 | 「提醒我下午买咖啡」 | 简卡片,单次 Confirm |
|
||
| **2** | 中风险 | 「每天 7 点发日报」 | 完整 Action Card + 周期说明 |
|
||
| **3** | 高风险 | 「每天自动给客户发报价」 | Confirm + 权限 / 白名单 / 人工开关 |
|
||
|
||
Layer 2 周期性 Scheduled Action 默认 **Level 2**;涉及外发第三方默认 **Level 3**。
|
||
|
||
---
|
||
|
||
## 5. 统一 Agent Action Card(所有 Layer 复用)
|
||
|
||
```text
|
||
🤖 我准备执行:
|
||
|
||
任务:每天 08:00 生成 AI 新闻日报
|
||
|
||
动作:
|
||
1. 搜索最新 AI 新闻
|
||
2. 总结 10 条重点
|
||
3. 生成页面并发送给你
|
||
|
||
开始时间:明天 08:00(Asia/Shanghai)
|
||
频率:每天自动执行
|
||
风险:中(重复执行)
|
||
|
||
[确认执行] [修改] [取消]
|
||
```
|
||
|
||
Layer 1 简版:
|
||
|
||
```text
|
||
🤖 我准备设置提醒:
|
||
|
||
📌 项目计划例会
|
||
🕐 今天 14:30(Asia/Shanghai)
|
||
|
||
[确认] [改时间] [取消]
|
||
```
|
||
|
||
**实现锚点:** `wechat-mp.mjs` 在 Preflight 返回前不 `finishWechatMpMessage`;Draft 存 DB 后推卡片;下一条消息走 `confirm_intent` 解析器 Commit。
|
||
|
||
---
|
||
|
||
## 6. 统一 Task Schema(P0.5 — 停止模型分裂)
|
||
|
||
当前三套存储:
|
||
|
||
| 用途 | 表 |
|
||
|------|-----|
|
||
| 待办/日程/提醒 | `h5_schedule_items`, `h5_schedule_reminders` |
|
||
| 定时自动化 | `h5_scheduled_tasks` |
|
||
| Agent 多步 | 无一等公民(落在 session + 偶发 scheduled_task) |
|
||
|
||
**目标:** 单一 `h5_tasks`(名称可调整),类型区分行为,而非分表。
|
||
|
||
```sql
|
||
-- 演进目标(草案,非 MVP 迁移脚本)
|
||
CREATE TABLE h5_tasks (
|
||
id CHAR(36) PRIMARY KEY,
|
||
user_id CHAR(36) NOT NULL,
|
||
type ENUM('reminder','todo','digest','automation','workflow') NOT NULL,
|
||
title VARCHAR(255) NOT NULL,
|
||
spec JSON NOT NULL, -- 执行说明 / taskSpec / 步骤摘要
|
||
trigger JSON NOT NULL, -- { kind, time, repeat, timezone, condition? }
|
||
action JSON NOT NULL, -- { kind: notify|agent_run|webhook, payload }
|
||
action_level TINYINT NOT NULL DEFAULT 1,
|
||
notify_channel ENUM('wechat','web','both','none') DEFAULT 'both',
|
||
status ENUM('draft','confirmed','active','locked','paused','completed','failed','cancelled') NOT NULL,
|
||
next_run_at BIGINT NULL,
|
||
last_run_at BIGINT NULL,
|
||
source_channel VARCHAR(32),
|
||
source_message_id VARCHAR(128),
|
||
source_text TEXT,
|
||
event_log_tail JSON,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
```
|
||
|
||
**映射:**
|
||
|
||
- 提醒 → `type=reminder`, `action.kind=notify`
|
||
- 待办 → `type=todo`, `action.kind=none`(可无 trigger)
|
||
- Digest → `type=digest`, `trigger.repeat=daily`
|
||
- 唐用户 8:00 天气 / 5:30 新闻 → `type=automation`, `action.kind=agent_run`
|
||
- 复杂 Agent → `type=workflow`
|
||
|
||
**迁移策略(渐进,不要求 Big Bang):**
|
||
|
||
1. **Phase A:** 新建 `h5_intent_drafts` + Confirm Gate;现有表不变,Commit 时仍写旧表。
|
||
2. **Phase B:** 读路径聚合 `listTasks(userId)` 统一展示;写路径双写。
|
||
3. **Phase C:** 迁移脚本 + 废弃 `h5_scheduled_tasks` 直连创建。
|
||
|
||
---
|
||
|
||
## 7. 对抗测试(Adversarial Routing)
|
||
|
||
分类器必须覆盖 **故意模糊** 话术。纳入 `scripts/simulate-schedule-capability-routing.mjs`:
|
||
|
||
| 输入 | 期望 Layer | 说明 |
|
||
|------|------------|------|
|
||
| 明天提醒我自动生成日报 | L2 或 Clarify | 「提醒」+「生成」歧义 → 必须 Clarify,禁止静默 |
|
||
| 帮我每天看看有没有新的招聘信息 | L2 | 「看看」但含每天 → Scheduled Action(监控+推送) |
|
||
| 设置任务,余额低于 100 提醒我 | L1 + Condition | 非 cron;未来 Event Trigger |
|
||
| 查一下是否有执行的新闻任务 | L0 | Query Guard,禁止 create_todo |
|
||
| 每天 8 点提醒我跑步 | L1 recurrence | 循环提醒,非 L2 |
|
||
| 每天 8 点帮我生成跑步报告 | L2 | 明确执行链 |
|
||
|
||
**规则:** 对抗样本命中 **Clarify** 视为通过,命中错误 Layer Commit 视为失败。
|
||
|
||
---
|
||
|
||
## 8. 未来:Event Trigger(超出 Schedule)
|
||
|
||
```text
|
||
Event Trigger → Condition → Action
|
||
```
|
||
|
||
示例:余额 < 100 → 微信提醒;股价跌破 → 通知;新邮件 → 摘要。
|
||
|
||
**不要塞进 cron schedule 表**;在统一 Task Schema 的 `trigger.kind` 扩展:
|
||
|
||
```json
|
||
{ "kind": "condition", "watch": "balance", "op": "lt", "value": 10000 }
|
||
```
|
||
|
||
MVP 已有雏形:`create_balance_low_alert` + digest subscription。应归入 Layer 1/2 的 **Condition Task** 子类,而非新的第四套表。
|
||
|
||
---
|
||
|
||
## 9. 与 Goose + Memind 的插入点
|
||
|
||
| 组件 | 插入方式 |
|
||
|------|----------|
|
||
| **Intent Router** | 已有:`wechat-mp.mjs` → scheduled-task / schedule handlers → Agent prompt |
|
||
| **Draft** | 新增:`intent-draft-service.mjs`;微信 preflight 改 `createDraft` 而非 `createItem` |
|
||
| **Confirm Gate** | 微信下一条消息优先匹配 `confirm|取消|改` + `draft_id` |
|
||
| **Commit** | 现有 `schedule-service` / `scheduled-task-service` 作为 Commit 后端 |
|
||
| **Worker** | 不变:`schedule-reminder-worker`, `scheduled-task-worker` |
|
||
| **Agent** | Layer 3 仍走 Goose SSE;ITL 约束:**工具成功 + 用户 Confirm 后才可宣称「已设置」** |
|
||
|
||
**不需要改 SSE 主链路**;ITL 在微信 inbound 与 MCP write 工具之间加一层。
|
||
|
||
---
|
||
|
||
## 10. 修订后的优先级
|
||
|
||
| 优先级 | 项 | 说明 |
|
||
|--------|-----|------|
|
||
| **P0** | Intent Transaction Layer(Draft + Confirm + Commit) | 所有副作用走 Gate |
|
||
| **P0** | Agent Action Card 统一组件 | L1 简版 + L2/L3 完整版 |
|
||
| **P0** | Query Guard(Layer 0) | 「查一下/有没有/是否」禁止 create |
|
||
| **P0.5** | 统一 Task Schema 草案 + 双写计划 | 停止 reminder/schedule/automation 三分裂 |
|
||
| **P1** | 相对时间 / 循环提醒 / 偏移提醒 | 规则或 Agent 填槽 |
|
||
| **P1** | Action Level 2/3 策略 | 周期任务默认 L2;外发 L3 |
|
||
| **P2** | Event Trigger 模型 | condition task |
|
||
| **P2** | 对抗测试 CI 门禁 | `simulate-schedule-capability-routing.mjs --adversarial` |
|
||
|
||
---
|
||
|
||
## 11. 与当前工程状态的对齐(2026-08-24)
|
||
|
||
**已有:**
|
||
|
||
- Layer 1 Preflight:`create_timed_reminder`(待发版)
|
||
- Layer 2:`h5_scheduled_tasks` + worker + 去重修复(含 `locked`)
|
||
- 反伪确认:`schedule-guard.mjs`
|
||
- 压测:`scripts/simulate-schedule-capability-routing.mjs`
|
||
|
||
**缺口(与你指出的完全一致):**
|
||
|
||
- 无 Draft / Confirm 状态机
|
||
- 无统一 Task 模型
|
||
- Query 与 Create 未 hard 分离
|
||
- 无 Action Level
|
||
- 对抗样本未进 CI
|
||
|
||
**结论:** 路由工程可用;体验与可靠性由 **ITL + 统一 Task + Confirm Gate** 决定。下一迭代应少堆规则、多建事务层。
|