Jev 问题设计与状态管理实战
判断模型会放大你喂给它的东西:一道边界清晰的 Jev 问题能让你拿到稳定、带 confidence 的答案用几个月;一道含糊的问题则让答案随输入的细微变化而漂移。所以在 Jev 集成里,问题设计是杠杆最高的一环。这篇讲怎么把判断题、选择题、打分题写稳,怎么定义模型真正能执行的边界,以及调用之间怎么传递上下文状态。
TL;DR: 显式说清答案空间,用具体规则或示例定义边界,给棘手情况配 2–5 个 few-shot 示例,上下文以明确文本随问题传入。如果一个问题两次回答结果不一致,先改问题,再怀疑模型。
稳定问题的解剖
一道稳定的问题有四个部分,按这个顺序:
- 题型。 “Judgment question:”、“Choice question:” 或 “Scoring question (1-10):“——先报题型,答案空间才无歧义。
- 判定标准。 一句话说清什么算 yes、哪个选项胜出、高分意味着什么。
- 边界。 边缘情况算什么,写成规则或示例。
- 输入。 待判对象,明确分隔。
对比弱版本和强版本:
弱:"Is this review bad?"
强:"Judgment question: should this product review be hidden for
violating the no-promotional-links policy? The policy prohibits
links to sellers, coupon codes, and contact info. Mentions of the
product's own brand do not count. Review: \"...\""
弱版本在邀请漂移:“bad” 没有答案空间。强版本报了题型、给了标准、点了边界、隔开了输入。它的响应——示例数据(example fixture),正式字段名以官方文档为准——长这样:
{
"answer": "no",
"confidence": 0.93,
"rationale": "The review mentions the product's own brand only, which the policy explicitly excludes from violations."
}
选择题的选项枚举
选择题成也选项列表,败也选项列表。三条规则:
- 列表要么穷尽,要么加逃生选项。 如果”其他”是合法结局,就把它枚举出来;否则模型被迫选一个错误的桶。
- 每个选项一句话定义,保证互斥。 “billing——关于扣款、退款、发票的争议”比光秃秃的 “billing” 强得多。
- 选项数量控制住。 大约超过一打选项,准确度就下滑;考虑拆成两段式选择题。
import json, os, requests
prompt = (
"Choice question: which queue does this ticket belong to? "
"Definitions: billing - charges, refunds, invoices; "
"technical - product errors and bugs; "
"account - login, permissions, profile. "
"Ticket: \"...\""
)
resp = requests.post(
"https://openrouter.ai/api/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
json={
# Confirm the exact model slug on the OpenRouter model page
"model": "typesafe/jev-1.13",
"messages": [{"role": "user", "content": prompt}],
},
timeout=30,
)
route = json.loads(resp.json()["choices"][0]["message"]["content"])
一句话定义把光秃秃的标签变成了边界;上线前去 OpenRouter 模型页确认确切的 model slug。解析出的 route 是示例数据(example fixture)——响应形态为示例,正式字段名以官方文档为准,形如 {"answer":"technical","confidence":0.9,"rationale":"..."}。
few-shot 示例在边界处最值钱
抽象规则覆盖分布的中间,示例覆盖边缘。针对你被坑过的场景,在问题里放 2–5 个示例:
Examples:
- "Buy now at deals.example, 50% off!" -> hide (promotional link)
- "This product broke after two weeks, very disappointed." -> keep (genuine complaint)
- "Great product, contact me at me@example.com for bulk orders." -> hide (contact info)
Now judge: Review: \"...\"
每个示例都是被具体化的边界。答案开始漂移时,为漂移的那一类补一个示例,而不是无限扩写规则。
调用之间怎么传状态
Jev 调用是单轮的,上下文必须随问题一起走。实用模式:
| 需要的状态 | 传递方式 |
|---|---|
| 前几轮对话 | 附紧凑记录:“Previous turns: user asked X, agent answered Y.” |
| 用户或账户属性 | “Account context: enterprise plan, customer since 2023.” |
| 管线阶段 | “Context: this is the second review, the first was rejected for policy P.” |
| 此前的 Jev 决策 | 嵌入上一次的 answer 和 rationale:“Earlier judgment: yes (0.97) because …” |
状态块保持简短、只陈述事实——状态是判断的上下文,不是第二个问题。决策依赖上一次 Jev 答案时,复制 answer 和一行 rationale 即可,不必整个 fixture 都搬。
多语言评论审核的 case 展示了这些技巧的合体——枚举的政策边界加 few-shot——横跨多种语言;你的边界定义偶尔会产出 unclear 答案,怎么处理见《Jev 置信度与兜底策略》。
本文适用版本 Jev 1.13。