推错一本刊,赔的是三周的沟通成本:用Jev给期刊销售做前置判断
期刊销售这个岗位有个反直觉的地方:推荐错一本刊的代价,不是浪费一次沟通。
稿子一旦投出去,作者按期刊要求改完稿、等到审稿、等到录用通知,最后发现这本刊根本不收这个方向。而这时候销售已经收完钱、结了单,进入下一轮了。所有成本都留在后面:转刊、退款、差评,还有销售自己多花的那三周。
问题是,推错的原因往往不是销售不上心。销售手里只有论文标题、一段摘要,以及作者在微信上东一句西一句的聊天记录。让一个人(或者一个模型)从这些碎片里推断出"这篇该投哪一档收稿方向的刊",然后在几十本刊里挑出最合适的那本。
这件事的答案空间是封闭的,输入却完全自由。这个组合决定了后面所有的设计选择。
从杂乱输入到推刊的四步链路
四步链路:LLM只做字段抽取,Jev只做判断,检索和兜底交给确定性代码
01 问题的真实形状:输入根本没有结构
先把输入摊开看。销售每天面对的东西,形态至少有四种:
- 论文标题,十几个英文单词,含术语
- 摘要,两三百字,术语密度高,但里面不会写任何投稿要求
- 微信聊天记录,口语、跳跃、夹杂"我们这个方向偏应用"
- 销售的口头转述,作者说过的话经销售复述,信息已经走了二手
这四种输入本身不带结构,要判断的事情混着好几个维度,性质完全不同:
| 输入里的工作 | 性质 | 归谁做 |
|---|---|---|
| 读懂研究方向 | 开放式语义理解 | 生成模型 |
| 匹配刊库收稿范围 | 闭集选择 | 决策模型 |
| 判断能否过硬性门槛 | 布尔判定 | 决策模型 |
| 查版面费与截稿时间 | 确定性查询 | 数据库 |
多数人上手第一件事,就是把整段摘要丢给一个生成模型,说"帮我推荐三本合适的期刊"。这在demo里看着挺像那么回事,到了真实场景就出问题——它把表里后三件事也一并做了,可闭集选择、布尔判定、查数据库这三样,本来就不该由生成模型插手。
问题不在于生成模型能力不够。问题在于这个任务的答案空间本来就有界,你却让一个逐token生成、每次都可能不一样的组件去承担了它。
02 为什么不能一步到位
有三个具体代价,不是空泛的"不够准"。
第一,推荐理由不可复现。同一个摘要,今天问一次和明天问一次,模型可能给出不同的三本刊。销售没法把这个结果拿给作者解释,出了问题也没法归因——你不知道是模型判断错了,还是客户信息本身就模糊。
第二,阈值不可调。生成模型返回的是一段自然语言描述:"这篇比较适合投那本综述类期刊,但可能需要补充实验。"这句话你没法拿来做业务决策。你需要的是"方向置信度0.62,低于0.7,转人工"。
第三,候选空间封闭,模型却在逐token重新发明答案。你的刊库里就那几十个方向档位,答案是有界的。让一个自回归模型在输出token的过程中"重新发现"这个有界空间,本身就是把确定性问题变成分布性问题。
03 第一步:LLM做什么,不做什么
边界先划清楚:LLM只做抽取和归一化,不做推荐。
它的唯一输出是一份结构化的"投稿画像",字段要能直接喂给下游程序,不是给人看的结论。
| 字段 | 抽取方式 | 为什么必须用生成模型 |
|---|---|---|
| 研究领域归一 | 从标题摘要判定研究方向 | 术语映射开放 |
| 收稿方向候选 | 映射到刊库方向档 | 一方向对多分类 |
| 文章类型 | 论文/综述/短讯/案例 | 依赖体裁语义 |
| 篇幅偏好 | 从方法数据规模推断 | 作者不会明说 |
| 开放获取需求 | 从聊天记录识别OA | 藏在口语里 |
| 特殊要求 | 彩图/审稿人/急刊 | 长尾条件会漏 |
| 预算档位 | 从措辞推断敏感度 | 委婉需理解 |
关键是最后一列。这些字段的共同点是:抽取规则不可能穷举,但抽取结果必须能被程序校验。所以字段名要固定、类型要固定、漏掉的字段必须能被拦住。
两个工程约束:
- schema必须能被程序校验。LLM漏输出一个字段,就在进Jev之前拦下来,不要指望下游能容忍缺失。
- 抽取结果要保留原文指针(哪句话支持这个判断)。后面推刊推错了,你要能回溯到"我当时是从这句话判断的方向"。
看一个具体例子。 销售实际收到的东西长这样:
论文标题:
柔性钙钛矿器件的界面钝化研究
摘要(节选):
针对钙钛矿光伏器件界面复合严重导致效率衰减的问题,我们采用分子内自组装策略制备了氟代胺基功能化的二维钙钛矿薄膜,器件开路电压损失显著下降……
微信聊天(节选):
我这个方向偏实验,理论这块不算强
预算有限,有没有开放获取的?费用能走报销
最好年底前能出录用通知,下个月要交材料
销售自己的转述:高校课题组,首次投稿。
LLM抽出来的paper_profile大致长这样:
{
"title": "柔性钙钛矿器件的界面钝化研究",
"type": "experimental_research",
"discipline": "材料科学",
"directions": [
"energy_storage", "material_science"],
"method": "实验制备 + 器件表征",
"open_access": true,
"budget_sensitive": "high",
"deadline_urgent": "high",
"missing": ["投稿字数要求", "是否已选定目标刊"]
}
direction_candidates给了两个而不是一个,因为光靠标题和摘要,"材料科学"和"能源与储能"都判得通。这种时候不该替LLM做决定,可能性都留着,交给下一步的choice去比概率。
evidence是原文指针,每条抽取结论后面都挂着它所依据的那句话。上面为了篇幅省掉了,它长这样:
"evidence": [
{"field": "deadline_urgent",
"quote": "最好年底前能出录用通知"}
]
推错刊的时候,能一路回溯到"我当时是从哪句话判断的"。
missing是显式的缺失声明。抽不到的字段不要填默认值,直接写进missing。这个例子里"投稿字数要求"缺失,意味着04节那个over_length根本问不出结果——这个信息缺口是明摆着的,而不是等推错刊才发现。
04 第二步:三种原语在这里怎么分工
先补一段背景。Jev是TypeSafe AI的System One决策模型,输入一段待判断材料(官方叫state)和一组预定义问题,输出可直接进程序分支的结构化概率判断,不生成自由文本。它只有三种原语——choice(闭集选一)、score(有序分档打分)、noul(这个命题是否为真)。同一份state上可以一次挂多个问题,它们彼此独立、并行评估,响应时间几乎不变。

Jev的三种原语及各自用途
三种原语的选择依据只有一条:答案空间有界用choice,有序用score,是非用noul
映射到我们这个场景(字段名沿用上一节的paper_profile):
| 维度 | 原语 | 问什么 | 怎么用 |
|---|---|---|---|
| 收稿方向 | choice | 匹配哪档收稿范围 | 概率分布参与排序 |
| 契合度 | score | 契合度分几档 | 落档决定是否入选 |
| 硬性门槛 | noul | 超篇幅/伦理/已投/预算 | 命中降权或转人工 |
| 退稿风险 | noul | 明显偏离目标刊 | 命中要求人工复核 |
一次调用就能把三类问题全问一遍。注意state传的是上一节那个paper_profile对象——Jev能直接吃结构化数据,不用再拼成一段自然语言:
resp = client.system_one(
state=paper_profile,
questions={
"direction": Choice(
"学术方向最符合哪一档收稿范围",
criteria=[
"材料科学与工程",
"能源与储能",
"生物医学工程",
"环境工程",
]),
"fit": Score(criteria=[...4 档...]),
"over_length": Noul(
criteria={
"true": "超上限",
"false": "未超",
}),
},
)
三个问题的结构一样:第一个参数是instructions(问什么),criteria是闭集选项。这里只把direction这一支摊开,另外两个收成一行——手机上竖着滚三十行代码没人读得下去。
(criteria里的选项名用业务方看得懂的词,不要用materials_science这种内部枚举值。05节会看到,模型判的是"像不像",选项名本身就是提示。)
这里有一个坑值得单独说:question id不发给模型。direction、fit这些key只用在你自己的代码里做映射,模型完全看不到。所以问题必须完整地写在instructions里,写成direction_fit模型是不知道什么意思的。
另一个坑在score的criteria:档位要写情境,不写程度。官方文档明确建议前者,因为"属于某一种状态"是模型能判断的,"属于某种程度"不是。官方给的对比很直观:同一份bug报告,档位写成裸数字0/1/2时,模型给出0.57分、置信度只有0.35;改成"能凑合看 / 还得改 / 基本不用改"之后,置信度明显改善。
05 第三步:Jev说的话不能直接推刊
拿到结果之后最容易犯的错,就是直接推第一名。
choice是相对的,不是绝对的。 它回答的是"在给定选项里哪个最像",没回答"哪个最合适"。你的刊库里可能有三本刊方向相同,模型给它们的概率几乎一样。这时候选谁,取决于你的业务权重,不是模型的置信度。
正确做法是把概率分布拿出来,让业务权重参与排序:
final = (
probs["direction"] * W_dir
+ fit_score / 4 * W_fit
+ journal_weight[journal_id]
- penalty(over_length, over_budget)
)
四项依次是方向匹配度、契合度归一化、业务侧给的刊权重、硬红线的惩罚项。
journal_weight这个字段很关键——同一本刊在"这个方向是刚需"和"这个方向只是备选"两种定位下,业务价值完全不同。这个信息模型不知道,只有你有。
score返回的是概率加权分,落在档位之间是正常现象(比如1.7表示"大部分权重在第二档,少量在第三档")。别把它当精确刻度用,它的作用是让你划一条可调的阈值线。
置信度分三档处理:
- 高置信度 → 直接给出推荐列表
- 中置信度 → 给列表,但把每个候选的判断理由附上,让销售一眼能验证
- 低置信度 → 不给推荐,只给候选池,让销售自己看
阈值画在哪儿取决于你翻车的代价。推错一本刊要三周沟通和一次退款,那阈值就该比推错一个按钮高得多。

置信度三档分流:只有低置信度需要人工确认
三档分流的差别只在最后一步:前两档直接推刊,第三档才交给人
有个必须提前说的坑:中文场景的校准效果,目前没有公开数据。 TypeSafe至今没发布过中文语料上的校准曲线,也没有任何独立第三方基准。别假定它在中文期刊标题上天然可靠,务必先用自己的历史工单跑一批小批量验证。这是最容易翻车的地方。
06 第四步:数据库才是最终裁判
Jev给出的是特征,不是指令。
拿到方向、契合度、风险项之后,检索条件是这样拼出来的:
| 判断结果 | 数据库侧的约束 |
|---|---|
| 收稿方向候选 | 该方向在架的刊及影响因子 |
| 契合度分档 | 是否开放投稿、在截稿窗口内 |
| 超出篇幅上限 | 该刊篇幅区间,命中不进列表 |
| 违反伦理声明要求 | 该刊是否要求声明,命中转人工 |
| 已投冲突 | 历史投稿记录,命中则标记 |
| 超出预算上限 | 该刊版面费区间,命中则降权 |
这里有一条不能让的原则:硬红线不能由Jev一票否决。
Jev的价值在于发现风险,但决定"推不推"的必须是确定性规则。原因有两个:一是中文校准效果没数(前面提过);二是价格上限、已投冲突这类判断,本质是查一条记录、比一个区间,让模型去干,等于用一个不可靠的组件做确定的事。
这个分工可以概括成一句话:模型说"像哪一类",规则决定"这一类怎么处理"。
把模型判断和业务执行分开之后,调阈值、调权重、改刊库都不用碰模型,也不用重跑一遍语义理解。
07 踩过的坑
六条,按踩到的先后顺序排,不一定全。
候选项里一定要留other: null。边缘case是被硬塞进某个标签,还是被老老实实承认"不属于任何一类",对后续逻辑影响很大。前者会污染你的加权排序,后者至少是可见的异常。
choice的选项顺序会影响概率分布。评测集和线上必须保持同一种排列,否则你调出来的阈值上线就失效。这条没什么文档会写,但踩过一次就记住了。
别把具体期刊名直接当choice的选项。你的刊库可能有几百本刊。choice单字段上限255,超过之后会走两阶段路径(先独立打分,再显式选择),延迟会明显上去。而且刊名之间语义高度重叠,选项越多分布越糊。正确做法是先按方向分档,让Jev在方向档之间选,然后在选中的档内用确定性代码检索具体刊。
score的criteria别写数字档。写"1-3分 / 4-6分"模型判不了,得写"能凑合投 / 勉强可以 / 比较契合"这种带情境的说法。
抽取层的schema要能被程序校验。LLM少给一个字段就拦下来。不要指望下游能容忍"有时候没有预算档位"。
别信英文语料上校准出来的阈值。 校准是分布特性,中英文分布不一样。这条和第05节那条是同一件事,但值得再说一次,因为它是最常见的省事做法。
08 怎么验证它真的更准
上手方式是影子流量(shadow mode):真实流量照常跑,Jev的判断只记录、不生效,同时和现有的人工推荐结果做对比。跑一段时间,看两件事:它的方向选择和销售的判断重合多少,以及在这些重合的case里,转刊率有没有差别。
评测集怎么造:从历史工单里抽一批,人工标注"这篇稿子实际该投哪本刊"。标注口径要先定清楚:"最合适"和"能投"是两个标准,前者下可能一本科刊都不算合适。
| 指标 | 怎么算 | 说明什么 |
|---|---|---|
| Top-1命中率 | Jev首选==标注首选 | 整体准不准 |
| Top-3覆盖率 | 标注刊落在Jev前三 | 候选池够不够用 |
| 转刊率 | 推刊后转刊比例 | 业务最终结果 |
| 人工介入率 | 低置信转人工占比 | 阈值是否太严 |
这里有个现实问题:这个场景没有公开基线可比。不像文本分类有GLUE那种现成榜单,期刊推荐是垂直业务,数字只能自己跑出来。也正因为如此,表里第三、第四个指标比前两个更值得盯——前两个是模型指标,后两个才是业务指标。
09 最后
回到开头那个问题:这套架构省的是什么?
先说结论:省的不是钱,也不是延迟。Jev单次成本本来就低,几十毫秒和一秒的差别放到人工销售场景里也无所谓。
真正省下来的是售后工时。推错一本刊的代价是三周沟通加一次退款,这笔账不在推理成本表上,但它才是这个场景里最大的一项。降低它的办法是把"判断"这一步从那个不可复现、不可调阈值的组件里挪出来,换成一个能被测试和调参的东西。
架构上的收益在另一头:判断层变成了一个可替换、可调参、可解释的独立层。今天用Jev,明天发现别的方案更合适,换掉就行,上面那两步不用动。
最后留个问题:
你现在做的业务里,还有哪个环节是"答案空间明明有限,却交给了一个每次输出都不一样的生成模型"的?
评论区聊聊,我很想看看大家踩过哪些坑。
觉得有用?点个点个「推荐」,我会持续更新这类决策层的实操拆解。
如果这篇文章对你有帮助,欢迎转发给正在纠结「该不该换模型」的朋友。

浙公网安备 33010602011771号