Skip to content

Jev ​

Jev 是 TypeSafe 的“System One”决策模型:不生成文字,只对结构化问题返回校准过的概率。远程决策接口也可以换成 OpenAI Decisions API(jev.provider: "openai",模型 gpt-6-luna):问题完全相同,是非题以 predicate 发送、选择题以 choice 发送,是非题的判断标准并入说明文字,拒答按调用失败处理。精魅用同一个决策客户端做接话判断、最终文字审查、表情、记忆排序,以及可选的话题归属与参与度判断。

接话判断(replyDecision,默认 true)。明确 @、回复、名字/别名命中时直接路由,不请求接话判断。其他人类消息在启用且有客户端时各发一次请求:带上发言者,从当前空间的全部角色与 none 中判断是否在对某个角色说话。没有点名时只有明显在回应角色刚说的话才算(角色刚发过言不算),拿不准选 none;选中角色的概率 ≥ 0.5 时直接路由,不受抽样与门控限制,秒回表情也视它为被点名。

  • 普通接话候选仍按累积 routingP 的 HMAC 抽样产生。角色当前平台账号最近 30 秒发过任何消息则冷却;最近 10 分钟最多 30 条消息中,该账号至少 3 条、其他不同作者多于 1 人且该账号占比 ≥ 25% 时也不主动接话。
  • 只有抽样且未被门控的候选才在同一次请求中附带 chat_in 的 noul 评分问题,评分 ≥ replyThreshold(默认 0.7)才接话。即使没有候选或被门控,仍判断内容指向;调用失败记 participation_failed 和错误类别,不让任何角色接话。关闭或没有客户端时,只用 HMAC 抽样与门控。

最终文字审查。发送最终文字(或把它转换成明确要求的语音)前,先检查 §E 后跟数字、[当前事件 等内部标记,命中直接判为不通过,不请求审查。有客户端时再用 noul 评分自然度:分数 < 0.5 不通过;用户明确要求总结、梳理或列时间线时,应要求做的复述算自然正文。

  • 重写一次:每轮第一次不通过不会直接沉默。自然度不过时再问一次决策模型原因(复述群聊、写作规划、列草稿、其他),按原因给角色一句具体的修改提示(标记泄漏则提示去掉标记),让它重写;记 reply_rewrite。最终文字通过隐藏的 jingmei_audit_gate_v1 消息告知并触发重写;send_reply 则在工具结果里告知,本轮不结束,角色可以再调一次或改发文字。重写照常审查。
  • 仍不通过:整条回复不发,改发固定的一句 (系统提示:说了不该说的东西被捂嘴了)(回复原消息、入库),记不含正文的 reply_withheld;最终文字还会持久保存隐藏的 jingmei_withheld_v1 标记。下轮 provider 投影去掉被拒的草稿、重写提示与被扣留的回复,避免把未发送内容当历史。
  • 审查调用失败:内容指向和概率接话不重写、静默扣留(audit_failed,没有判断就不说“说了不该说的”),明确 @、回复、名字路由则放行。没有客户端时只做标记检查。

send_reply 在准备任何部分前做同样的审查:所有文字部分与语音稿合在一起审查自然度,配文与长文图 Markdown 也做内部标记检查。只有图片、表情图的纯媒体回复不请求自然度审查。

秒回表情(quickReactions)。每条有文字的人类消息发一次 Jev 请求,同时问三件事:从表情表里选一个(或 none)、这条消息情绪是否强烈、是否好笑。

  • 点名的消息(@、回复、叫名字或内容判断选中 directed 角色):由对应角色点上选中的表情,Jev 选 none 时不点。
  • 普通消息:只有 max(情绪强烈, 好笑) ≥ threshold,并且该频道距上一次这样的表情已超过 minIntervalMs 才点;由该群配置顺序里第一个角色来点。处于限频期的消息连 Jev 都不调用。
  • 与主回复并行,失败只记日志,不影响回复。开启后,主模型不再注册 react_to_message 工具,表情完全交给 Jev。

记忆排序(memoryScoring)。角色按需调用 recall_member_memory 时,把候选事实和关系(每人最近 20 条事实、最强 16 条关系)一次性交给 Jev 与当前消息比对相关度,每人保留最相关的 5 条事实和 4 条关系。Jev 不可用时退回按时间和互动次数排序。

本地包装与回退。jev.apiKeyEnv 有值时先调用 jev.endpoint;配置了本地 LLM 时,远程调用任何失败都会回退一次到进程内 notjev 包装器。没有远程 key 时直接用包装器,不另起 HTTP 服务。“本地”指包装器在进程内运行,其 LLM 可以是远程 DeepSeek。省略 localJev、有 DEEPSEEK_API_KEY 且没有远程 key 时,默认连接 https://api.deepseek.com 的 deepseek-flash;配置了远程 key 时这个默认不生效,也就没有回退,要回退须显式写 localJev;显式 localJev 完全覆盖这个默认,省略其 apiKeyEnv 即不带鉴权。

包装器默认超时 30 秒,关闭 DeepSeek thinking(thinking.type=disabled);LLM 必须返回 logprobs,缺失会作为 invalid_response 调用失败处理。模型弃答时取概率最大的选项(argmax)。

秒回表情和记忆排序仍须显式配置 jev 段落;仅配置 events 或仅有 DeepSeek key 不会开启它们。接话判断默认开启,有共享决策客户端即可运行;最终文字审查也在有客户端时运行,不受 replyDecision 开关控制。jev 可省略 apiKeyEnv,这时使用本地包装器,但必须有可用的本地 LLM(localJev 段落或 DEEPSEEK_API_KEY),否则是配置错误。完全不写 jev 段落时退回确定性路由与标记检查。显式填写的 apiKeyEnv 若在 .env / 进程环境中缺失,仍是配置错误,不会悄悄回退。包装器调用按所选 LLM 的费用计费。

成本。远程 Jev 只按输入 token 计费,输出免费(撰写时 jev-1.13 为每百万 token $0.042,以官方价格为准)。一次表情请求只包含当前消息、最多 5 行近期聊天(每行截断到 200 字符)和三个问题,通常只有几百 token;远程请求超时 3 秒。它不消耗主模型的 token;本地包装器则消耗其配置的 LLM token。

接话判断启用且客户端可用时,每条未明确点名的人类消息额外 +1 次决策请求(内容指向与可选接话分数合并),每条最终文字回复额外 +1 次自然度审查(不通过时再 +1 次原因判断,重写后再 +1 次审查);明确点名省掉接话请求,内部标记命中省掉审查请求。这些调用不使用主回复模型,但本地包装器按其 LLM 计费;远程失败回退可能额外调用一次本地 LLM。

配置。在 .env 写 TYPESAFE_API_KEY: …,在 jingmei.config.json 加(用 OpenAI 时改为 "provider": "openai"、"apiKeyEnv": "OPENAI_API_KEY",并省略 endpoint 与 model 以使用其默认值):

json
"jev": {
	"endpoint": "https://api.typesafe.ai/v1/systemone",
	"apiKeyEnv": "TYPESAFE_API_KEY",
	"model": "jev-latest",
	"quickReactions": true,
	"memoryScoring": true,
	"replyDecision": true,
	"replyThreshold": 0.7,
	"threshold": 0.8,
	"minIntervalMs": 60000
}
字段默认说明
providertypesafe远程接口格式:typesafe 或 openai
endpointhttps://api.typesafe.ai/v1/systemone远程 Jev 的 http(s) URL;openai 默认 https://api.openai.com/v1/decisions
apiKeyEnv无远程 key 的环境变量名;省略则仅使用本地包装器
modeljev-latest也可固定版本,如 jev-1.13.0;openai 默认 gpt-6-luna
quickReactionstrue秒回表情
memoryScoringtrue记忆排序
replyDecisiontrue内容感知接话判断;关闭仍保留确定性抽样门控与最终文字审查
replyThreshold0.7取值 (0, 1],普通抽样候选接话所需的最低分
threshold0.8取值 (0, 1],普通消息点表情所需的最低分
minIntervalMs60000同一频道两次“普通消息表情”之间的最短间隔
emojis平台默认表按平台覆盖表情表:{ "discord": { "👍": "赞同" }, "telegram": { … } };不能使用保留键 none

默认表情表(表情 → 交给 Jev 的含义):

含义DiscordTelegram
赞同、收到👍👍
好笑😂🤣
难过、破防😭😭
暖心、感谢❤️❤
疑问、不确定🤔🤔

Telegram 自定义表情表中不在 Bot API 允许集合里的表情会被丢弃并记一条警告。

话题配置 ​

json
"events": {
	"summaryModel": "deepseek/deepseek-flash",
	"embeddingModel": "fast-bge-small-zh-v1.5"
}

回复某条已有话题的消息时,直接沿用该话题,不调用决策模型(bot 消息同理,未回复的 bot 消息无话题)。去掉 [贴纸 …]、[视频 N帧]、[文件] 等裸媒体占位后不足 2 个字母/数字的人类消息,并入 10 分钟内最近活跃的话题。其余人类消息在有候选话题时由决策客户端选择归属:短回复、追问和情绪反应倾向延续正在进行的话题;决策选“新话题”但其概率低于 0.6 时,改归概率最高的现有话题。最近 2 小时有消息的话题视为活跃,每次最多提供 5 个活跃话题、2 个同频道向量召回的旧话题,以及“新话题”选项。累计消息数达到 3、6、12、24……时,后台生成/刷新标题描述、参与度与向量;同一事件只同时刷新一次,不阻塞频道处理。摘要使用独立的 summaryModel;话题说明只在触发回复的那一轮附在消息后面,下一轮起不再留在历史里,也不写入 system prompt。

话题摘要要求中性地描述正在讨论或玩的内容:接梗仍是接梗,不评价成员行为,不给角色安排管理任务,也不保留与话题无关的成员隐私。

BSD 2-Clause 许可