19981964fb
- 移除 backend/scripts/build_litellm_proxy_config.py - 简化 LiteLLMService,移除 run_completion_with_cost 方法 - AgentScopeRunner 改为从 LlmFactory 获取 api_base 和 api_key - 部署配置移除 litellm/litellm-config-job 服务 - Flutter 新增 AuthBootScreen 引导页 - Android 添加通知权限 (POST_NOTIFICATIONS, RECEIVE_BOOT_COMPLETED, SCHEDULE_EXACT_ALARM) - 优化 LocalNotificationService 调度失败 fallback - 更新 manifest.json (version 3)
7.1 KiB
7.1 KiB
自动化记忆任务设计方案(v1)
1. 背景与目标
本方案用于落地后端自动化记忆任务:
- 提供每日/每周自动执行能力;
- 自动提取用户近期对话中的可沉淀记忆并写入
memories; - 支持“忘记”操作;
- 复用现有 Agent 运行链路,避免并行维护两套运行时;
- 保证可审计、可追溯,同时对用户界面隐藏自动输入提示词。
2. 范围与非目标
2.1 范围
automation_jobs增加config(JSONB,强约束);- 调度器执行
automation_jobs,按用户本地时区计算执行时间; - 自动任务复用现有
router -> agent运行策略; - 自动输入落库但对用户不可见;
- 工具集按任务配置分发,仅允许白名单工具;
- 正式启用
memory_prompt,将memories注入系统提示词。
2.2 非目标
- 不开放复杂 DSL 编排;
- 不开放细粒度策略配置(如
execution_profile/history_window_days/memory_policy); - 不引入第二套独立 Agent 运行框架。
3. 关键决策
-
调度与执行分离
run_at/next_run_at/timezone负责“何时执行”;config负责“如何执行”(提示词与工具集)。
-
配置最小化
automation_jobs.config仅保留:prompt: stringtools: string[]
-
自动输入可审计但用户不可见
- 自动任务提示词作为“用户消息”写入
messages; - 在 metadata 加可见性标记并在用户历史接口中默认过滤;
- 审计路径可查询完整消息链路。
- 自动任务提示词作为“用户消息”写入
-
时区策略
- 调度语义采用“用户本地时区 10:00”;
- 存储执行时间统一为 UTC 的
next_run_at; - 调度器仅按 UTC 扫描,降低运维复杂度。
4. 数据模型设计
4.1 automation_jobs 调整
- 保留字段:
id,owner_id,title,schedule_type,run_at,next_run_at,timezone,last_run_at,status等; - 新增字段:
config JSONB NOT NULL; - 迁移策略:
- 将历史
prompt迁移到config.prompt; - 切换业务代码后删除旧
prompt字段(可分两步灰度)。
- 将历史
4.2 config 强约束 schema
{
"prompt": "提取最近对话中的稳定记忆并写入",
"tools": ["memory_write", "memory_forget"]
}
约束要求:
prompt:必填、非空、长度受限(建议 <= 2000);tools:必填数组,元素为注册工具名;extra="forbid",拒绝未知字段;- 执行前二次校验:
tools必须与后端 allowlist 取交集,禁止越权。
4.3 messages.metadata 扩展
新增建议字段:
hidden_from_user: boolorigin: "chat" | "automation"
用途:
hidden_from_user=true的消息在用户历史默认不可见;- 审计查询可读取全量。
5. 运行时架构
5.1 复用现有 Agent 链路
自动任务不新建运行时,沿用现有 router -> orchestrator -> worker 流程:
- 输入:来自
automation_jobs.config.prompt的合成“用户输入”; - 上下文:默认加载“今天 + 昨天”历史;
- 工具:仅启用
config.tools且通过 allowlist 校验。
5.2 会话与消息策略
- 自动任务写入独立
session_type=automation会话,并关联job_id; - 普通对话维持
session_type=chat; - 自动输入消息:
role=user但hidden_from_user=true; - Assistant 输出消息:默认可见。
6. 调度器设计
6.1 扫描与触发
- 周期扫描条件:
status='active'next_run_at <= now_utc
- 命中后入队执行命令(复用现有任务队列)。
6.2 幂等与并发控制
- 使用任务槽位去重键:
job_id + scheduled_slot; - 使用行级抢占或原子更新防止并发重复执行;
- 失败可重试并记录错误上下文。
6.3 下次执行时间计算
- 每次执行完成后按
schedule_type + timezone计算下一次触发时间; - 保存到
next_run_at(UTC); last_run_at记录实际执行时间。
7. 默认任务创建
用户创建后自动创建一条默认 daily 记忆任务:
schedule_type = 'daily'- 本地时区目标时间:10:00
timezone:优先用户设置时区,缺省Asia/Shanghaiconfig.prompt:内置记忆提取提示词模板config.tools = ["memory_write", "memory_forget"]
8. 记忆工具设计
8.1 memory_write
- 用途:写入/更新用户记忆;
- 输入:受 schema 限制(标题、内容、来源等);
- 安全:owner 作用域强制绑定,不信任模型输入的 owner 信息。
8.2 memory_forget
- 用途:失效或删除用户记忆;
- 输入:
memory_id或受限条件; - 安全:仅允许当前 owner 范围内操作。
8.3 工具授权
- 任务声明工具集来自
config.tools; - 运行时执行
declared_tools ∩ allowlist; - 非白名单工具直接拒绝并记录审计日志。
9. memory_prompt 启用策略
- 从数据库读取当前用户可用
memories; - 组装为系统提示词 memory section;
- 设置条数与长度上限,避免 token 膨胀;
- 自动任务与普通对话统一使用该注入机制。
10. 前端展示策略
- 历史消息接口默认过滤
hidden_from_user=true; - 用户仅看到 assistant 输出(以及可选系统摘要,不包含原始自动 prompt);
- 前端无需大量工具分支 if/else,可统一按 metadata 标记处理。
11. 安全与审计
- 关键要求:
- 禁止越权工具调用;
- 禁止跨用户 memory 读写;
- 日志不输出敏感数据和完整私密上下文。
- 审计能力:
- 自动输入、工具调用、输出全链路可追踪;
- 用户界面只显示允许可见内容。
12. 迁移与发布步骤
- 新增
config字段与 schema 代码; - 数据迁移:旧
prompt -> config.prompt; - 运行时切换到
config.prompt/config.tools; - 灰度验证后移除旧
prompt; - 上线调度器与默认任务创建;
- 启用
memory_prompt并完成联调。
13. 测试与验收
13.1 单元测试
configschema 校验(非法字段、非法工具、空 prompt);next_run_at计算(跨时区、边界时间);- 隐藏消息过滤逻辑;
memory_write/memory_forgetowner 边界。
13.2 集成测试
- 用户创建触发默认 daily 任务创建;
- 调度触发 -> Agent 执行 -> memory 写入 ->
next_run_at更新; - 自动输入在审计可见、在用户历史不可见。
13.3 验收标准
- 每日 10:00(用户本地时区)稳定执行;
- 自动化链路有完整审计;
- 工具授权边界有效;
- 前端历史展示符合“隐藏自动输入、展示输出”的预期。
14. 实施顺序建议
- 先更新协议文档(
docs/protocols)明确契约; - 数据库与 schema 改造(
automation_jobs.config); - 工具集与授权边界实现;
- 调度器与默认任务创建;
memory_prompt注入与端到端验证;- 前端过滤逻辑收口。
本方案是最小可行版本(MVP)设计,重点保障:
- 复用现有架构;
- 低配置复杂度;
- 可审计与可维护并存;
- 为后续扩展保留演进空间。