智能体主动模式(Agent Proactive Mode)
主动不是“多发通知”,而是知道什么时候该找你、什么时候该闭嘴。 它从你的真实决策里推断容忍度、预算与冷却,只在真正影响客户的事情上打扰你。
为什么需要主动模式
一个只会“等客上门”的门面,会把三类事情拖到出事:
| 事情 | 不主动的后果 |
|---|---|
| 一条法规知识 7 天后到期 | 到期后客户查不到答案,agent 只能说“不知道” |
| 连续三天有客户追问同一个能力缺口 | 需求在流失,但没人看到模式 |
| 复盘已经给出改进建议 | 建议躺在报告里,永远不会被处理 |
但“什么都推”是另一种失败:提醒一多,人就会全部忽略。
主动模式要同时做到两件事:该说的不漏,能等的不吵。
它主动推什么
| 候选类型 | 优先级 | 来源 | 当前状态 |
|---|---|---|---|
| 知识即将到期 | 4 | 有效期在 7 天内的已批准条目 | 已实现 |
结果未回读(stale_result) | 3 | 需要“结果已读”埋点 | 刻意不做:没有已读标记就不猜“你没看”,避免误报 |
| 行业订阅有新内容 | 2 | Observe 环产出的新闻摘要(/agents/{id}/sources/{date}/digest) | 已实现:collectSourceDigest 在复盘当天从 digest 生成候选 |
| 复盘建议待决策 | 1 | 当天复盘报告的 proposedActions | 已实现 |
候选只描述事实(“3 天后到期”),不替主人下结论(“你该更新了”)。
主人模型:它怎么学会“别烦我”
系统只记录所有者的决策行为(知识 / 变更的批准与拒绝),不记录对话内容, 按近 30 天窗口聚合成四个参数:
| 参数 | 含义 | 怎么推断 |
|---|---|---|
interruptionTolerance | 对主动打扰的容忍度 | 拒绝率 + L3 拒绝次数 |
dailyProactiveBudget | 每天最多推几条 | 低容忍 1 条 / 中等 2 条 / 高容忍 4 条 |
cooldownDays | 同一主题冷却几天 | 低容忍 7 天 / 中等 3 天 / 高容忍 1 天 |
handsOnLevel | 哪些等级需要亲自拍板 | L3 被拒 2 次即升级为“L3 必须我批” |
具体阈值:
| 近 30 天信号 | 容忍度 | 每日预算 | 冷却 |
|---|---|---|---|
| 少于 3 条 | 中等(保守默认) | 2 条 | 3 天 |
| 拒绝率高于 50%,或 L3 被拒 2 次 | 低 | 1 条 | 7 天 |
| 拒绝率 20%–50% | 中等 | 2 条 | 3 天 |
| 拒绝率低于 20% | 高 | 4 条 | 1 天 |
纪律:
- 每个推断都带
evidence(批准数、拒绝数、窗口天数),你能问“为什么今天没提醒我”; - 信号不足时保守默认,不假设你不怕打扰;
- 谁批的记在谁头上:多 owner 时,A 的拒绝不会压低 B 的预算。
决策顺序:不能换
候选 → 冷却过滤 → 容忍度过滤 → 按优先级抢预算 → 站内通知 + 邮件顺序是刻意的:
- 先冷却:同一个话题在冷却期内不再提;
- 再容忍度:低容忍时只保留优先级 3 及以上的类型(到期、卡单这类会直接影响客户的事);
- 最后抢预算:按优先级排序,超出的条目留到下次,而不是叠加推送。
反过来的话,高优先级条目会先把预算占满,老话题被反复提起。
固定顺序也是“可解释”的前提:每一条被跳过或接受,都能说出原因 (
cooldown/tolerance/budget)。
送达:两个通道,一条底线
| 通道 | 行为 |
|---|---|
| 站内收件箱 | 按所有者隔离;未读数就是角标;点开深链回到所有者面对话 |
| 邮件 | 复用登录邮箱;没有可用邮箱就静默跳过,站内通知不受影响 |
三条实现纪律:
- 幂等:同一条候选重复推送落到同一个通知 key,不会刷屏;
- 已读不重复写:前端重试标记已读,不会刷出一堆无意义事件;
- 失败只降级:邮件服务挂了只记录告警,不会让“今天该提醒的事”消失。
多所有者:共享能力,分开打扰
| 数据 | 粒度 | 原因 |
|---|---|---|
| 知识、能力、复盘 | agent 级共享 | 多个所有者共同维护同一个门面 |
| 信号、偏好、通知、主动计划 | per-owner | 描述的是“这个人”的习惯与收件箱 |
两个所有者各自拥有独立的预算、冷却与已读状态——一个人同意了 10 条变更, 不会让另一个人突然被每日 4 条提醒轰炸。
你怎么“训练”它
不需要配置表,正常做决策就是在训练它:
| 你的行为 | 它学到什么 |
|---|---|
| 连续批准知识 / 变更 | 你愿意被打扰,预算可放宽 |
| 连续拒绝 L3 能力变更 | “能力变更必须我亲自看”,同时降低打扰频率 |
| 拒绝某类复盘建议 | 该主题进入冷却,短期内不再提 |
| 一直不处理收件箱 | 未读持续累积(当前不会被自动判为“你不想看”,这是刻意的) |
当前接入状态(重要边界)
主动模式目前是能力就绪、调度未内置:
- 候选采集、决策、站内通知、邮件发送都已实现并有单测;
- 没有内置的“每天自动推送”cron:
decideForToday(agentId, ownerId, candidates)需要由前端(一天一次拉取)或某条业务事件调用; - 通知读端已就绪:
GET /api/agent-rsi/:agentId/notifications、POST /api/agent-rsi/:agentId/notifications/:notificationId/read。
这样设计是为了避免“先造一个每天准点轰炸的调度器”:主动与否要能被多个入口复用, 而不是只存在于 cron 里。接线时仍需遵守上面的预算、冷却与容忍度约束。
创新点
1. 偏好从行为推断,不从设置表读取
你不用填“每天最多几条”,系统从批准 / 拒绝里推断; 每个推断都带证据,可以解释、可以推翻。
2. 主动之前先学会克制
冷却 → 容忍度 → 预算的固定顺序,让“高优先级”不能挤掉“老话题的尊严”, 也让低容忍用户只收到真正影响客户的事。
3. 事实级候选,不下结论
候选只陈述“7 天后到期”,不替你做判断;决策权始终在你手里。
4. 双通道送达且可降级
站内一定有,邮件是增强;邮件不可用时不会让提醒消失。
5. 多所有者互不打扰
每个人的预算、冷却、已读都是自己的,能力却仍然共享。
边界:如实列出
| 项 | 现状 |
|---|---|
| 内置每日主动推送 cron | 未接线(见上) |
stale_result(结果未回读) | 刻意不做:缺少已读埋点,硬猜会误报 |
| 行业摘要 → 主动候选 | 摘要已能产出,转候选未接线 |
| 前端“为什么今天没提醒我”解释页 | 证据已在 owner-model.evidence,页面未做 |
| 每 agent 的邮件开关 / 全局静音 | 未做;当前只能通过决策行为间接降低打扰 |
| 周报 / 趋势型主动摘要 | 未做,只有日粒度 |
怎么判断它有用
| 指标 | 含义 | 健康线 |
|---|---|---|
| 每日推送数 | 单个 owner 当天收到的条数 | 不超过其推断预算 |
| 接受率 | 被处理的提醒 / 总提醒 | 高于 20%(过低说明推得没价值) |
| 冷却命中 | 因冷却被跳过的候选数 | 有命中说明去重在工作 |
| 未读积压 | 长期未读的通知数 | 持续上升说明打扰过多或内容无价值 |
| 邮件失败率 | 发送失败 / 尝试发送 | 失败只降级,但应被观测 |
相关阅读
- Agent RSI:智能体自进化——主动模式消费的复盘与信号从哪里来
- 知识库——到期提醒指向的那些条目
- 状态层——信号、通知、主动计划的存储底座
- 门面 Agent——它为什么不能替客户做承诺
源码位置(开发者)
| 能力 | 文件 |
|---|---|
| 主人信号与偏好模型 | libs/modules/src/agent-runtime/rsi/{owner-signal,owner-model.service}.ts |
| 主动决策(冷却 / 容忍度 / 预算) | libs/modules/src/agent-runtime/rsi/proactive.ts |
| 候选采集 | libs/modules/src/agent-runtime/rsi/proactive-candidates.ts |
| 站内通知 | libs/modules/src/agent-runtime/rsi/notification.ts、agent-rsi.controller.ts |
| 邮件端口与 apps 实现 | libs/modules/src/agent-runtime/rsi/owner-contact.port.ts、apps/hushwork/src/user/owner-contact.service.ts |