257cb0f5d5
- 重构 automation-memory-design.md 为 v2 版本,新增 Execution Profile 抽象层 - 删除 auth-global-rewrite-design.md 和 auth-global-rewrite-plan.md - 更新 agent/api-endpoints.md 协议文档 - 更新 ASR 与 worker token latency 优化 TODO 文档
317 lines
9.5 KiB
Markdown
317 lines
9.5 KiB
Markdown
# 自动化记忆任务设计方案(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` 承载记忆职责;
|
||
- 在不引入第二运行时的前提下完成大规模重构演进。
|