jevbooks

← 全部设计模式

问卷

平铺扇出 · Questionnaire

一题一事,一次问完

把一次判断拆成互不依赖的几道小题,一次请求全部问完。

statenoulchoicescorenoul

问题

你在做一个文风检查器:一段话发过去,附一道题 —— 这段读起来像不像机器写的?

一段话里有一处明显的破绽,另外四句写得还行,它返回 0.52。整体印象被摊平了 —— 五分之一不对,于是给你五分之一的分。可你要知道的是「这里有一处得改」,不是「这段打 5 分」。

于是你把它改写成五条具体的毛病,逐句判。有人量过这一步的效果:80 个植入的故障,抓出来的从 58 个变成 63 个,误报一个没多。接着下一个问题来了:五道题你写成五次调用,一次 300 毫秒,一段话要等一秒半 —— 十条规则就是三秒。

解决方案

问卷模式说:一道题只问一件事,而且所有题对着同一份材料、装进同一次请求一起问。

「一件事」的意思是问「有没有」。「这段里有没有出现『不是 X,而是 Y』这种句式」能答;「这段写得好不好」不能答。一句话就足够让它触发,旁边那些好句子不替它开脱。

每个答案有自己的线,各消费各的:辱骂过 0.8 就拦,紧急过 0.7 就叫人,剩下的按类别分流。唯独不能把同一件事换三种说法问三遍 —— 三道同义题不是三份证据,是同一个数乘三。

问 · 答 · 拍

  1. 问把用户的一条消息放进去,一次问三件事:要不要一小时内找人、是不是账单的事、有没有辱骂。
  2. 答辱骂 0.05,紧急 0.81,账单 0.63。
  3. 拍没有辱骂,紧急过线了,直接叫人;账单那道题这次用不上。

名字从哪来

问卷。医生不会只问一句「你身体好不好」,单子上是一项一项的:哪里疼、疼了几天、发不发烧。每一项都真的答得出来,合起来才是诊断。而且单子是一次给你的,不是问一句、等一句。

什么时候用

你要知道的事能拆成几件,每件都能单独答。

什么时候别用

第二道题该怎么问,取决于第一道的答案 —— 那要么合成一题,要么改用预问。或者你那几道题其实是同一句话换了件衣服。

做这件事的项目

  • foreman — 使用决策模型的智能体监督者与软件工厂工头。
  • jev-axi — 为 TypeSafe 的 Jev 提供的 CLI:从 shell 快速获得校准判断。
  • snifftest — 散文检查器,用可计数规则和一个判断模型找出 AI 写作痕迹。

用这种模式的全部项目 →

看谁的代码
想看代码
const { answers } = await jev(state, {
  urgent:  noul("要不要一小时内找人处理?"),
  billing: noul("这是关于扣费或退款的事吗?"),
  abusive: noul("这条消息里有威胁或辱骂吗?"),
});
// 三个概率,一次往返,约 300 毫秒;各有各的线
if (answers.abusive.p >= 0.8) return block();
if (answers.urgent.p >= 0.7)  return page();
return answers.billing.p >= 0.6 ? route("billing") : route("general");
jevbooks 怎么认出它

我们怎么知道一个项目用没用这一招?拿它的 README 问 Jev 一句话,Jev 给个百分比,数字越高说明越像。你要抄这道题,记住一点:别问「这个项目好不好」,要问「有没有讲到这一件具体的事」。

questions.json · 每份 README 都发这道题
{
  "flat-fanout": {
    "type": "noul",
    "instructions": {
      "what": "Does the text describe sending several independent questions about the same state in a single Jev request?",
      "not_for": "One question per request, or questions spread over separate calls."
    },
    "criteria": {
      "true": "The text explicitly describes this. One sentence is enough; other content does not cancel it.",
      "false": "The text does not describe this."
    }
  }
}

用 Jev 做一个 →