分段和打字
它回你,通常不是一大段,而是几条短消息,一条一条打出来。这一页讲这几条怎么来的、每条打多久。
变成几条消息
模型写回复时就按聊天的样子分好段。发出去之前,还要整理一遍:
- 去掉「回复:」这类前缀,和单独一行、括号里的动作描写;
- 空一行的地方分成两条;太长的一段在标点处切开,每条最多 520 个字,一次最多 4 条;
- 和自己最近说过的话几乎一样的长句不再发;
- 每条末尾的句号、悬空的逗号去掉,4 个字以内的短句留着句号。
写的刚到家 / 今天地铁好挤,站了一路。 / 你吃饭了没发的刚到家 / 今天地铁好挤,站了一路 / 你吃饭了没
每条打多久
按字数算:中文一个字算 1,英文字母算 0.55,除以打字速度。默认每秒 3.5 个字,每条最少 0.35 秒、最多 40 秒,都可以在人格配置里改。
速度跟着此刻的状态变:兴奋时最多快 65%,害羞时慢一点;疲惫、情绪低落、刚睡醒时,速度只剩七成。每条消息的时长还会在上下 14% 里浮动(同一条算几次结果一样),所以不会每条都卡在同一个节奏上。
同一段话,两种状态
0 秒24681012
精神好 4.2 秒
很累 10.9 秒
精神好4.2 秒发完
刚到家
今天地铁好挤,站了一路
你吃饭了没
很累10.9 秒发完
刚到家
今天地铁好挤,站了一路
你吃饭了没
两条之间
发完一条,停一下再打下一条。停多久看状态:兴奋时 0.22–0.7 秒,平常 0.45–1.35 秒,犹豫时 0.75–1.8 秒,没精神时 1–2.4 秒。
开始打字之前
看到你的消息以后,先按字数读完(默认每秒 20 个字),再想一下。模型判断、生成用掉的时间算在这里面,不另外叠加:模型慢了,「想」就短了。
醒着、手上没事的时候,从消息到达到第一条回复发出,最长 120 秒;超了先压缩「想」,再压缩第一条的打字。
打错一个字
它偶尔会选错一个同音字,发出去才发现,再补一条「*正字」或者撤回重发。怎么错、多常错、什么时候更容易错,见 2.9。
要不要引用原消息
第一条回复要不要挂上「回复某条消息」的引用,和真人一样看需要:
- 私聊里接着刚说的那句回、群里马上回:直接发,不引用;
- 那条消息之后别人又说过话,或者群里隔了两分钟以上才回:引用,免得对不上是在回哪句;
- 那条消息已经不在最近十二条里、或者读不到最近的消息:照旧引用。
只回表情
拿主意的时候选了「只回表情」(2.7),就真的点一个,不说话。点哪个由模型按那条消息,从设置里列的几个表情里挑(默认八个);挑不出合适的就不点。同一个频道里两次只点表情至少隔十分钟,没到就安静不出声。
过一会儿补一句
真人发完一段话,偶尔过一会儿会自己再补一句。写回复的模型可以另写一句「补一句」,它和正文一样要过发送前的检查;按比例真的发出去(默认八次里大约一次):
- 先停一会儿,默认 8 到 25 秒,再打字发出去,作为最后一条;
- 停着、打着的时候有人说了话,就不补了;
- 和正文一样整理:句末不带句号,免得一眼看出是另一个人写的。
对应的代码
- 整理成几条:
splitting.py的normalize_segments、remove_repetitive_segments、soften_terminal_punctuation,发送前由bot.py的_outgoing_segments依次调用。 - 每条打多久、两条之间停多久:
cognition/conversation_behavior.py的build_human_send_plan。 - 开始打字之前:
bot.py的_send_timing。 - 引用:
bot.py的_should_quote_target(QUOTE_LATE_SECONDS= 120,看最近 12 条);只点表情:[conversation].reaction_emojis、reaction_min_gap_seconds(600);补一句:cognition/afterthought.py的afterthought_pause和bot.py的_send_afterthought,afterthought_probability(0.12)、afterthought_min_seconds(8)、afterthought_max_seconds(25)。 - 人格配置的
[conversation]一段:typing_characters_per_second(默认 3.5)、typing_min_seconds(0.35)、typing_max_seconds(40)、max_segments(4)、max_segment_characters(520)。 - 测试:
tests/test_splitting.py;tests/test_reply_manner.py(「引用_真的发出去时_私聊和群里马上回不引用_群里回晚了引用」「只回表情_模型挑不出合适的就不点」「补一句_停的时候有人说话就不补」);test_phrasing_habits.py的「结尾句号去掉,短句的句号留着」;test_3_5_1_human_behavior_pass.py的「发送计划跟着状态变,不是固定等待」;test_global_invariants.py的「很累时节奏、篇幅、主动性一起变」。
没做到的
- 打字时长只看字数,不看这句话难不难打、要不要翻记录。
- 你停下来想的那一会儿(没在打字),它分不出你话说完了没有:只有你正在输入的时候,它才会等你打完再发。