本节摘要:判断质量的一半在喂给 Jev 什么。状态设计四规则:优先用对象(字段可被 instructions 用反引号路径引用,比揉成一段话稳且可维护);字段名自解释;只放相关状态——独立实测把"塞满无关内容的臃肿 state"列为 Jev 主要失效模式,无关信息稀释判断;守容量红线(state + 最长问题 ≤ ~32K token / 约 15 万字符,整请求 ≤ ~64K)。请求纪律三条:问题 ID 当变量名管(稳定、有意义);instructions 写判别标准;相同 (state, questions) 直接缓存——Jev 是无状态纯函数,缓存语义干净,高频场景能再砍一半成本。
阅读完本节,你应当能够:
{ "state": { "ticket": { "subject": "Stripe 连接失败", "body": "试了三天,客户付不了款", "tier": "paid" }, "account": { "churn_risk": 0.82 } }, "questions": { "vip_escalate": { "type": "noul", "instructions": "`customer_tier` 为付费用户且 `body` 表达了强烈不满" } } }
反引号路径引用(如 `ticket.body`)让每个问题精确锚定它要看的字段——比"在这段文字里判断"少了定位歧义,也让 state 的演进(加字段、改结构)不破坏既有问题。
churn_risk 一眼可读;c_r 或 f3 迫使模型猜语义。字段名是写给 Jev 看的 prompt 的一部分。
独立深度评测的失败模式清单(完整版见第 10.1 节)里,"臃肿/无关的 state"(整段数据库 dump、无关日志、超长上下文)直接导致判断质量下降——不是超限报错,而是悄悄变差。纪律:每个字段都应该至少被一个问题引用;没有任何问题看它的字段,删掉。
💡 相关性审计法:把 questions 里所有反引号路径收集起来,与 state 的字段集合做差集——差集里的字段就是"没人看"的候选删减项。
| 项 | 红线 |
|---|---|
| state + 最长问题 | ≤ ~32K token(约 15 万字符) |
| 整个请求(state + 所有问题) | ≤ ~64K token |
超线的处理:在代码里裁剪(截断旧日志、摘要长文、只带最近 N 轮对话)——宁可少而相关,不要多而稀释。超线不是"报错那么简单"与"没超就没事"的二值问题,接近红线时质量已在下滑。
is_urgent 而非 q1)。ID 不发给模型,改名只影响你的代码与历史数据的对齐成本——所以从第一天就起好。QUESTIONS),随代码走版本控制。import hashlib, json def jev_cached(state, questions, ttl=86400): key = "jev:" + hashlib.sha256( json.dumps({"s": state, "q": questions}, sort_keys=True, ensure_ascii=False).encode() ).hexdigest() if (hit := cache.get(key)) is not None: return hit result = _jev_call(state, questions) cache.set(key, result, ttl=ttl) return result
分类、审核这类输入高度重复的场景(同一商品描述被百万次审核),缓存命中率可观;排序场景(query×候选 组合爆炸)则慎用,TTL 取短。
# ❌ 前:揉成一段话 state = f"客户 {name},等级 {tier},流失风险 {risk},说:{message}" # ✅ 后:对象化 + 路径引用 + 裁掉无关字段 state = { "customer": {"tier": tier, "churn_risk": risk}, # 两个字段都有问题引用 "message": message, } questions = { "vip_escalate": {"type": "noul", "instructions": "`customer.tier` 为 paid 且 `message` 表达强烈不满或流失意向"}, }
差异不只是可读性:前者的"流失风险 0.82"混在文本里,问题的措辞被迫依赖模型 parsing;后者的判断锚点显式、可回归测试(第 9 章)。
输入设计好了,怎么安全地让真实流量用上它?下一节给出影子模式四步法——先当"旁听生",再当"值班员"。