JEV 的题型、候选排序与上下文预算
noul/choice/score 的协议、三候选排序、翻译与上下文预算,以及概率未校准的边界。
JEV 的客户端只发一种结构:{state, model, questions}。questions 只接受 noul、choice、score 三类(app/clients/jev_client.py:call_systemone)。choice 最多 255 个选项,score 2–10 个等级,noul 带 criteria.true/false;app/scenarios/builders.py 会加 BACKGROUND_NOTE。返回后 _present 把 noul >= 0.5 当 yes,score 四舍五入,choice 按概率排序。协议不匹配(缺 answers、非 JSON)直接 502,不猜。
翻译
app/clients/translation.py:annotate() 只在文本含非 ASCII 时触发,要求 LLM 返回 {"lines":[{id,text}]};任何一个 id 缺失,整个分析 502。decide_service 的桥更严格,只要 question/context/options,两次尝试,检查选项数和空值。超时 45s JEV / 60s LLM / 75s vision;重试 3 次,退避 0.4/0.8s,Retry-After 最多 8s。
候选和上下文
候选回复固定 3 条(reply_service._RANK_KEYS = reply_a/b/c),虽然 Scenario.rank_min=3、rank_max=5,但后者没被读取。排序问 JEV 一个 choice 问题,把 probabilities 换成百分比;并列保持原顺序。翻译或 JEV 失败时 ranked=False,所有百分比为 0,但草稿仍然返回。JEV 健康检查是 5 个固定 smoke case,阈值 80,低于阈值 UI 只允许 3 条排序。
上下文有独立预算:分析取最近 10 条消息(RECENT_MESSAGE_LIMIT);背景默认 JEV_STATE_BUDGET_CHARS=5000(硬上限 60000);persona 行 1000 字符、最多 6 个 trait;memory 行 240 字符;积压 20 条才总结,摘要最多 500 字符。记忆 reflection 最多 12 个变更、30 条消息;UPDATE/INVALIDATE 对 source="qa" 会跳过;confidence 固定 0.6;revert() 只能回退最新一个未回退的 reflection。
数据和图片
图片限 4MiB、每消息 9 张,不做 OCR,原始字节转 data URL 交给 supports_vision 的 LLM,描述最多 3 句;SQLite WAL,busy_timeout=5000,所有查询带 owner_user_id;provider key 是 hmj1 HKDF/AES-GCM envelope;保留 15 天,session 8 小时,call log body 64KiB。trace ID 用 ContextVar + before_flush 镜像到 ActivityLog。
这些概率是模型原样输出,不是校准过的偏好;noul 的 0.5 和 choice 的百分比都只是决策输入。要做可靠的概率,需要按用户/模型测可靠性,现在没有。