一条消息在代码里怎么走
一条 Discord 消息从进来到回出去,在代码里依次经过哪些函数。QQ 的消息先在平台层变成同样的形状,后面走的是同一条路。
进来:on_message
AeriaBot.on_message(src/aeria/bot.py)是入口。它先做几件不管回不回都要做的事:等插件就绪、记下对方「正在输入」结束了没有、从这条消息里学(_learn_from_ordinary_message)、看它是不是在回应之前主动发的话(_resolve_outreach_answer)。
然后进 _on_message_guarded:
- 是不是在叫它、归哪个人格:
_resolve_message_addressing、_assigned_persona_for_message。 - 在不在范围里:
_in_scope(白名单、忽略的频道)、_response_policy_allowed(不理 webhook、不理别的机器人,除非是信任的人格)。不在范围里的只做旁听(_observe_ambient_message)或者直接不存。 - 变成一行聊天记录:
_to_chat_line;访问控制:_interaction_allowed。 - 是不是在请它做事:装了「对话指令」插件时,
_instruction_judge_eligible→_start_instruction_judgment(后台问模型,和下面并行)。 - 它在不在:睡着、出门时
_sleep_blocks_message、_note_missed_while_unavailable(回来再看)。 - 交给认知内核:
_submit_nhcx_message把它变成一个认知事件。 - 开一个频道工作器:
_spawn_channel_worker。同一个频道同一时间只有一个工作器在处理,连发的消息合在一起看。
一轮对话:_conversation_turn
频道工作器(_channel_worker)先等对方打完字(_wait_while_typing),再跑一轮 _conversation_turn:
- 取最近的上下文:
_recent_context_messages。 - 什么时候看到:
_notice_gate(没到看到的时候,推迟这一轮)。 - 回不回:认知内核出决定(专家、护栏、打分,3.13);本地打分和门槛只在内核出故障时接手。只点表情的:
_react_instead_of_reply。每一次都记_record_decision_trace。 - 写回复:
_plan_and_generate→deepseek.py(要规划的先plan_reply,再用写回复的模型生成;草稿过reply_quality.assess_reply_draft,不合格重写一次)。 - 分条、定时:
_outgoing_segments(splitting.py)、_send_timing、发送计划build_human_send_plan(cognition/conversation_behavior.py)。 - 打错字:
_typo_plan;一条一条发,发前再看对方是不是又在打字;发完_own_up_to_typo(撤回重发或补「*正字」)、_send_afterthought(补一句)。 - 收尾:
_note_reply_sent、_record_memory_mentions(最近提过的记忆往后放)。
在旁边跑的
- 学习:
_start_learning_task(事实、说话方式、黑话,按批)、_start_mid_term_task(中期记忆)、_start_profile_refresh_task(对人的印象)。 - 主动联系:定时扫描「谁把我晾着了」、念头到期,走的是同一个认知内核和同一套发送路径。
- 作息和生活:生活引擎按时钟推进,睡着、醒来、出门、发呆。
想看一条消息实际走了哪几步
网页后台「认知观测台」「事件流」按事件实时显示每一站和耗时;「回放实验室」能拿一条历史事件重新跑一遍(不发、不写记忆)。
没做到的
- 整条流水线在
bot.py一个类里,函数之间靠实例属性传状态;要拆成独立的阶段,还没做。 - 写回复那一段在观测台里只有总耗时,看不到模型内部卡在哪。