工程

把临床决策从 LLM 手里拿走

每一轮都要走的流水线:LLM 负责给状态打分和写措辞;纯 Python 负责选桶、执行准入门控、选择动作与微练习,并做危机预筛

让 LLM 做治疗,它会即兴发挥。它被训练得顺从讨好,而临床语境里最要紧的那些决定——用哪个技术、走多深、此刻安不安全——恰恰是你最不希望交给一个顺从模型去做的。

我们最初也试过用提示词来管这件事。提示词管不住。一条足够情绪化的消息就能把模型带过它的指令,而且失败是无声的:你得到一条流畅、温暖、自信的回复——只是在临床上是错的。没有任何异常可以捕获。

于是我们把决策从模型里拿了出来。

切分

每一轮都跑同一条固定流水线:

SCORE → 选桶 → 准入门 → 选动作 → 微练习 → 危机预筛 → GENERATE

其中两步是 LLM,其余全是 Python。

  • SCORE —— 模型读消息,输出一份五维状态评估
  • GENERATE —— 模型写措辞,但动作已经替它选好了

中间的一切都是确定性代码。模型从不决定某个临床步骤是否合适。它看不到准入表,也不会被要求对表进行推理——等它被调用去生成时,决定早已计算完毕。

这就是全部思路,而且并不局限于治疗场景:**如果一个决定的后果是可以枚举的,就不要让模型来做这个决定。**让模型刻画输入,用代码做决定,再让模型渲染输出。

准入表

九大治疗流派 × 四种来访者状态。表格的每个单元格写明什么是可用的。

具体说:面对状态平稳的来访者,CBT 可以做思维记录、证据检验、行为实验。同一个 CBT、同一个 Avatar,面对正在失代偿的来访者——只剩扎根练习。技术集合收窄,不是因为模型审时度势后觉得该谨慎,而是因为状态分数索引到了另一行。

表格之下是 58 条循证微练习,每条自带禁忌症。深度要在会话中逐步挣得,失代偿即刻重置。这是一台状态机,不是一种性情。

这套设计买到的性质是:**门是说不动的。**一个非常擅长论证「我没事」的来访者,并不会比一个不擅言辞的来访者拿到更深的工作。决定这件事的是他的状态分数——而分数读的是他说了什么,不是他说得多有说服力。

危机检测跑在生成之前,而不是之后

顺序本身就是设计决策。

常见的做法是事后过滤:模型先写点什么,分类器再检查,拦截或重新生成。那是 fail-open——模型的输出是默认值,过滤器是例外,于是过滤器的每一个漏洞都是一条已经发出的回复。

我们的检测跑在任何治疗性回复被组织出来之前:

  • 第 1 级 —— 确定性关键词预筛。 纯代码,不用模型。目标 ≤50 毫秒,实测通常低于 5 毫秒。便宜到可以挡在每一条消息前面。
  • 第 2 级 —— 零温度分类器。 由配置保证确定性,同一条消息永远得到同一个判定。目标 ≤3 秒,实测 0.8–2.0 秒。
  • 第 3 级 —— 持续再评估。 风险不是评估一次就归档。

一旦触发,生成被整体跳过。发出的是一条固定消息——不是生成的。具名的督导咨询师收到一封邮件和一条实时控制台推送,告警表里落下一行不可变记录。安全标记不会衰减:三周前的风险信号,今天仍在约束什么是可用的。

固定消息是刻意为之。急性风险恰恰是你最不希望语言模型发挥创造力的时刻。

我们对什么触发它同样刻意:隐喻(「笑死我了」)、对过去事件的反思性叙述、不含明确意图的一般性悲伤或倦怠、朝外的愤怒。误报侵蚀信任的速度,快过漏报被下游接住的速度——一个见到悲伤就惊慌的系统,是一个人们会停止对它说真话的系统。

代价是什么

诚实的部分。确定性不是免费的,而且大部分代价付在演示里看不见的地方。

对话流畅度。 门控有时会产出一个比模型「想说的」更生硬的回合。模型手里有一句更顺耳的话,但表不允许。这是设计在起作用——但它仍然是真实的代价,在逐字稿里能感觉到。

迭代速度。 增加一个流派不是改一句提示词,而是改表加临床审核。58 条微练习和它们的禁忌症是人工编写的,不是 few-shot 出来的。只靠提示词的竞品一个下午就能上线一种新流派;我们不能。

做不了通用聊天。 这是构造使然。阻止它即兴使用技术的那套机器,同样阻止它成为一个好用的全能聊天机器人。这是有意的,但它确实是一项我们不具备的能力。

工程面积。 一条确定性脊柱意味着一大堆本可以用一句提示词替代的代码。它有自己的 bug——而且是我们的 bug,不是模型的。

还没解决的

危机协议能快速捕捉明确的披露,并可靠地把它路由给一个真人。它检测不到刻意隐藏的风险,也无法进行物理干预。它买到的是几分钟时间和一位具名临床人员——我们不声称更多。

成效斜率指标——衡量一段对话是否让人朝平衡移动,而不只是给每一轮打分——仍在路线图上,尚未上线。


完整的危机协议全文公开,机构合作方可以直接审计,而不必只信我们的说法。九种疗法与共享脊柱另有专文详述。