Files
social-app/docs/plans/2026-03-17-automation-memory-design.md
T

317 lines
9.5 KiB
Markdown
Raw Normal View History

# 自动化记忆任务设计方案(v2
## 1. 背景与目标
本方案用于重构自动化记忆能力,目标是:
- 保持单一运行时框架,不并行维护第二套执行系统;
- 在运行时中新增一层抽象,使 `router``executor` 的启用策略可配置;
- 将记忆处理职责从通用 worker 中剥离为独立 `memory agent` 角色;
- 保留审计能力与用户可见性隔离(自动输入可审计、默认对用户隐藏);
- 维持与现有 `/api/v1/agent`、SSE、history 协议的兼容演进路径。
该版本是架构重构设计文档,重点解决职责边界与扩展性问题。
## 2. 设计原则
1. **单框架,多角色**
- 仍复用同一套 runtime、队列、持久化、SSE 通道;
- 不再让 worker 承担所有领域职责。
2. **配置驱动执行拓扑**
- 运行路径由配置决定:是否经过 router、最终由哪个 executor 执行;
- 执行拓扑可被审计并可回放。
3. **记忆职责显式化**
- 记忆提取、写入、遗忘由 `memory agent` 执行;
- worker 继续承担通用对话/工具编排场景。
4. **默认安全最小权限**
- 工具集必须是 `declared_tools ∩ allowlist`
- memory executor 默认仅开放记忆域工具。
5. **协议先行**
- 任何对运行协议和数据结构的变更,先更新 `docs/protocols/` 再落地代码。
## 3. 范围与非目标
### 3.1 范围
- `automation_jobs` 引入执行拓扑配置,支持是否启用 router 与 executor 选择;
- 运行时新增抽象层:`Execution Profile`
- 支持 executor 类型:`worker``memory`
- 自动任务默认使用 memory executor
- 消息可见性和审计策略保持增强。
### 3.2 非目标
- 不引入复杂 DSL 编排语言;
- 不开放无限制策略字段;
- 不新增独立部署形态的第二运行时;
- 不在本阶段改造前端交互形态(仅保证协议兼容)。
## 4. 核心决策
1. **新增抽象层:Execution Profile(关键)**
- 在 scheduler/orchestrator 与具体 agent 之间新增执行配置层;
- 该层决定是否调用 router、调用哪个 executor、可用工具策略。
2. **executor 职责分离**
- `worker executor`:通用任务、复杂工具编排、常规聊天;
- `memory executor`:记忆提取、记忆写入、记忆遗忘、记忆总结。
3. **router 可配置启用**
- 自动记忆任务默认 `enable_router=false`,减少不必要决策成本;
- 普通 chat 默认 `enable_router=true`
4. **拓扑合法性约束**
- 必须保证至少有一个 executor;
- 禁止出现 `enable_router=false``executor` 为空;
- executor 仅允许枚举值:`worker | memory`
5. **保持事件/审计统一出口**
- 无论 executor 类型,SSE 与消息持久化走同一通道;
- 仅扩展阶段字段枚举,不拆协议体系。
## 5. 目标架构
## 5.1 运行链路(重构后)
```text
scheduler/api trigger
-> execution profile resolver
-> (optional) router step
-> executor step (worker | memory)
-> persistence + redis stream
-> history/sse consumers
```
与旧链路相比,变化点是新增 `execution profile resolver``memory executor`
## 5.2 Execution Profile 抽象
建议抽象(运行时内部模型):
```json
{
"name": "automation_memory_default",
"enable_router": false,
"executor": "memory",
"tool_policy": {
"mode": "intersection",
"allowlist": ["memory_write", "memory_forget"]
},
"history_policy": {
"window": "today_yesterday"
}
}
```
说明:
- `enable_router`:是否执行 router 决策步骤;
- `executor`:最终执行角色;
- `tool_policy`:工具授权策略,默认交集模式;
- `history_policy`:上下文窗口策略(保持最小化,不扩展过多字段)。
## 5.3 默认 Profile 建议
- `chat_default`
- `enable_router=true`
- `executor=worker`
- `automation_memory_default`
- `enable_router=false`
- `executor=memory`
## 6. 数据模型设计
## 6.1 `automation_jobs` 调整
保留现有调度相关字段:
- `id`, `owner_id`, `title`, `schedule_type`, `run_at`, `next_run_at`, `timezone`, `last_run_at`, `status`
新增/调整字段:
- `config JSONB NOT NULL`:任务输入与工具声明;
- `execution_profile JSONB NOT NULL`:运行拓扑配置(MVP 可先内联,后续可抽到 profile registry)。
建议结构:
```json
{
"config": {
"prompt": "提取最近对话中的稳定记忆并写入",
"tools": ["memory_write", "memory_forget"]
},
"execution_profile": {
"enable_router": false,
"executor": "memory"
}
}
```
## 6.2 Schema 约束
- `config.prompt`:必填非空,建议长度 `<= 2000`
- `config.tools`:必填数组,元素为已注册工具名;
- `execution_profile.enable_router`:必填布尔;
- `execution_profile.executor`:必填枚举 `worker|memory`
- `extra=forbid`,拒绝未知字段;
- 执行前二次校验:`declared_tools ∩ runtime_allowlist`
## 6.3 `messages.metadata` 扩展
建议标准化字段:
- `hidden_from_user: bool`
- `origin: "chat" | "automation"`
- `executor: "worker" | "memory"`
- `execution_profile_name: string`
用途:
- 用户视图过滤自动输入;
- 审计可按 executor/profile 追踪行为;
- 支持后续灰度比较(同任务不同 profile)。
## 7. 运行时行为约束
## 7.1 自动任务
- 会话类型:`session_type=automation`
- 自动输入消息:`role=user` + `hidden_from_user=true`
- 默认 profile`automation_memory_default`
- executor`memory`
## 7.2 普通对话
- 会话类型:`session_type=chat`
- 默认 profile`chat_default`
- executor`worker`
## 7.3 工具授权
- 输入工具集合来自 `config.tools`
- 实际可调用集合来自 `config.tools ∩ profile_allowlist ∩ system_allowlist`
- 对被拒绝工具记录审计日志与拒绝原因。
## 8. 调度器设计
## 8.1 扫描与触发
- 扫描条件:
- `status='active'`
- `next_run_at <= now_utc`
- 命中后投递执行命令,命令中携带 `execution_profile` 快照。
## 8.2 幂等与并发
- 幂等键:`job_id + scheduled_slot`
- 通过原子更新或行级锁抢占,防止重复执行;
- 失败重试并保留错误上下文。
## 8.3 时区策略
- 调度语义按用户本地时区(例如每日 10:00);
- 存储执行点统一使用 UTC `next_run_at`
- 调度器仅按 UTC 扫描,避免多时区计算分散。
## 9. 协议影响与兼容策略
本阶段是设计重构,协议建议如下:
1. `docs/protocols/agent/sse-events.md`
- `STEP_STARTED/STEP_FINISHED.stepName``router|worker` 扩展为 `router|worker|memory`
-`enable_router=false` 时,不产出 router step 事件。
2. `docs/protocols/agent/run-agent-input.md`
- 增补运行上下文说明:内部执行可由 profile 决定 executor
- 对外 API 入参保持兼容,不强制前端传 executor。
3. `docs/protocols/agent/api-endpoints.md`
- 增补说明:`/runs` 的运行阶段由后端 profile 决定,历史与 SSE 保持统一消费方式。
兼容要求:
- 老客户端仍可消费现有事件;
- 仅新增枚举值,不删除既有字段;
- 如客户端未识别 `memory`,按未知阶段容错处理。
## 10. 默认任务创建
用户创建后自动创建 daily 记忆任务:
- `schedule_type='daily'`
- 本地时区目标时间 `10:00`
- `timezone` 优先用户设置,缺省 `Asia/Shanghai`
- `config.prompt` 使用内置记忆提取模板
- `config.tools=["memory_write","memory_forget"]`
- `execution_profile={"enable_router":false,"executor":"memory"}`
## 11. 安全与审计
安全约束:
- 禁止越权工具调用;
- memory 读写必须强制 owner 作用域;
- 日志不输出敏感内容与完整私密上下文。
审计能力:
- 自动输入、工具调用、输出全链路可追踪;
- 可按 `origin/executor/execution_profile_name` 回放。
## 12. 迁移与发布步骤
1. 更新 `docs/protocols`(先协议);
2. 新增 `execution_profile` schema 与运行时模型;
3. 数据迁移:历史任务写入默认 profile;
4. 运行时接入 profile resolver
5. 引入 `memory executor` 并接管自动记忆任务;
6. 灰度:先新建任务使用 memory executor,再迁移存量任务;
7. 稳定后收敛旧逻辑分支。
## 13. 测试与验收
## 13.1 单元测试
- profile schema 校验(非法枚举、空 executor、未知字段);
- 工具授权交集逻辑;
- `next_run_at` 跨时区计算;
- 隐藏消息过滤与审计字段落库。
## 13.2 集成测试
- 自动任务触发后进入 memory executor
- `enable_router=false` 时无 router step 事件;
- SSE `stepName=memory` 可被稳定消费;
- 自动输入审计可见、用户历史不可见。
## 13.3 验收标准
- 每日 10:00(用户本地时区)稳定执行;
- memory 任务不经过 router 亦可稳定完成;
- 工具权限边界有效;
- 审计链路完整;
- 对现有 chat 流程零回归。
## 14. 实施顺序建议
1. 协议文档更新(`docs/protocols/agent/*`);
2. `automation_jobs` 数据结构改造与迁移;
3. profile resolver 与 executor 抽象接入;
4. memory executor 接入与工具边界验证;
5. 调度器联调与默认任务创建;
6. 端到端压测与灰度发布。
---
本版(v2)将“抽象 Agent 运行”落到可执行的配置模型,核心是:
- 新增一层 `Execution Profile`
-`router``executor` 拓扑配置化;
- 使用独立 `memory executor` 承载记忆职责;
- 在不引入第二运行时的前提下完成大规模重构演进。