Aeria
GitHub
改 · 3.18

主动联系的流水线

最后核对 2026-10-08对应提交 4dc8009依据 impulse_sense.py · impulse.py · opportunity.py · topic_candidates.py · semantic_deliberation.py · outreach.py · outreach_service.py · bot.py · config.py

从「想起一个人」到一条主动消息发出去、再到「他没回」变成情绪,中间每一步在哪个文件、存在哪张表、为什么这么分。整条路上只有最后「把话说自然」那一步调用模型。

本页 6 节
  1. 一条路,七步
  2. 发出去以后
  3. 影子模式
  4. 改它的时候
  5. 对应的代码
  6. 没做到的

行为层面的讲法见 2.19、2.20。

一条路,七步

  1. 感知(cognition/impulse_sense.py):维护循环的「冲动」那一步(默认五分钟一次)给每个候选的人拍一张快照(关系、上次聊天、没聊完的话题、到期的承诺、最近的里程碑……),每个 sense_* 函数只看一种真实状态,判断它构不构成「想起这个人」,并把那个状态的编号原样写进 source_event_ids。十种由头见 ImpulseTrigger。
  2. 念头入库(SocialImpulse,表 social_impulses):状态 LATENT → CONSIDERING → WAITING,最后落到 SENT、KEPT_TO_SELF(想说但没说)、EXPIRED(过时了)、SUPPRESSED(被睡觉、勿扰、配额压下去)、CANCELLED(前提没了,比如对方先开口了)、FAILED(发失败了,不算对方无视)之一。
  3. 权衡(cognition/impulse.py 的 weigh):想找的劲(approach)和顾虑(avoidance)各算一串,得出 SEND、WAIT、KEEP_TO_SELF、WITHDRAW(被晾怕了)、EXPIRE。
  4. 配额:同一个人两次之间的最短间隔、一个人一天几次、所有人一天几次、一天最多生成几次(ProactiveConfig)。没额度就 WAITING,并在日志里说清是配额拦的。
  5. 时机(cognition/opportunity.py 的 judge_opportunity):不好的时候分「等得回来」(留着,过一会儿再看)和「等不回来」(直接过期)。
  6. 话题(cognition/topic_candidates.py):从八种真实来源拼候选(bot._pick_topic_for),本地打分,没有证据编号的丢掉,第一名过门槛才用;挑不出来就 KEPT_TO_SELF。打开了语义复核的,这里再问一次模型,只能往保守改(semantic_deliberation.apply_verdict)。
  7. 交给跟进去发(bot._schedule_impulse_contact):生成一个 SocialFollowUpIntent(最早两分钟后),由维护循环的「跟进」那一步认领,照常过回复的几道关、照常生成、照常发。

发出去以后

影子模式

[proactive].shadow_mode 打开时,前六步照常走、理由照常记,第七步不发,念头记成 SUPPRESSED(理由「影子模式:决定发,但不真的发」);跟进那一条在影子模式下记 follow_up_shadow_would_send。放开频率之前先开它读日志。

改它的时候

对应的代码

没做到的