Files
memind/docs/intent-transaction-layer-design.md
T
john d58dc2a251 feat(wechat): add Intent Transaction Layer with unified task schema
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>
2026-08-24 15:59:17 +08:00

297 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 toolsFinish 后可能有页面/消息 |
**本质区别不是「有没有时间」,而是到点以后:**
- 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:00Asia/Shanghai
频率:每天自动执行
风险:中(重复执行)
[确认执行] [修改] [取消]
```
Layer 1 简版:
```text
🤖 我准备设置提醒:
📌 项目计划例会
🕐 今天 14:30Asia/Shanghai
[确认] [改时间] [取消]
```
**实现锚点:** `wechat-mp.mjs` 在 Preflight 返回前不 `finishWechatMpMessage`;Draft 存 DB 后推卡片;下一条消息走 `confirm_intent` 解析器 Commit。
---
## 6. 统一 Task SchemaP0.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 SSEITL 约束:**工具成功 + 用户 Confirm 后才可宣称「已设置」** |
**不需要改 SSE 主链路**ITL 在微信 inbound 与 MCP write 工具之间加一层。
---
## 10. 修订后的优先级
| 优先级 | 项 | 说明 |
|--------|-----|------|
| **P0** | Intent Transaction LayerDraft + Confirm + Commit | 所有副作用走 Gate |
| **P0** | Agent Action Card 统一组件 | L1 简版 + L2/L3 完整版 |
| **P0** | Query GuardLayer 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** 决定。下一迭代应少堆规则、多建事务层。