---
title: AI 话术生成
description: 客服召回话术的三档(稳健/标准/深度)生成 —— 投入档联动输入/输出/步数,安全接地地板恒定,脊柱固定策略可插。
icon: MessageSquare
---

> **产物**:`plan_scripts`(per-plan 一份 Markdown 话术)。**按需懒生成**:客服打开详情页或点"重新生成"时触发,经 `AiCallRunner` 调 LLM,落 `agent_invocations`。
>
> **真理源**:`apps/pac-service/src/modules/ai/orchestrators/plan-script.orchestrator.ts`(编排)、`calls/draft-plan-script/`(三档 call + shared 构件)。上游消费 `plan_reasons` / `fact.content` / persona,**不读治疗链**。

---

## 目标与硬约束

一通召回电话的脚本给客服四件事:**开场 → 切入(把"该治没治"自然带出)→ 异议(患者推脱怎么接)→ close(约下一步)**。

硬约束(所有档恒定):
- **接地**:只用真事实,不编(医生没说的不说);只喂 canonical 切片,**严禁拼 raw EMR 全文 dump**。
- **不承诺**:不保证疗效、不报价、不写死时间(诊所无排班接口,时间只能给"示例")。
- **贴这个患者**:病种 / 牙位 / 年龄(儿童对家长)/ 新老客 / 语气。
- **失败兜底**:任何环节挂 → 退回安全模板(`source='template_fallback'`),客服永远有东西可用。

## 三档(投入档)

一个"投入档"旋钮联动**输入 / 输出 / 步数**三样;**安全 / 接地地板对所有档恒定**。tier 由调用方传(默认 `stable`),`?model=` 可覆盖模型。

| 档 | 输入 context | 输出 | 步数 | 调用 |
|---|---|---|---|---|
| **stable 稳健**(默认) | base | **固定 4 段**(模板填空)`opening / informMissed / reviewAdvice / closing` + `tone` | 1 | `DraftPlanScriptCall`(单次 AiCall) |
| **standard 标准** | base | **自由 4 段** `sections[{title, markdown}]`(LLM 自定标题,去模板名) | 1 | `StandardScriptCall`(单次 AiCall) |
| **deep 深度** | base + 扩展(画像 rubric + 联系历史) | **多段**(段数模型自定) | 3–4 | `DeepScriptStrategy`(pipeline) |

> **自洽**:深度档拿更多料,正好配它多一步的**自检** —— 料越多越易跑题/编,自检兜底。富输入 ↔ 强校验成对出现。

## 脊柱(固定)+ 策略(可插)

三档共用一根脊柱,只换中间一段策略;加一档 = 加一个 call/strategy,脊柱不动:

```
buildContext(plan_reasons + facts + persona, tier)
  → 策略(stable | standard | deep)
    → 安全机器闸(machineSafetyScan,输出后扫)
      → 失败/不过 → stable 模板兜底(source='template_fallback')
        → 落 plan_scripts(status=ready)+ agent_invocations(tier/model/token/cost/source)
```

**stable**:单次 AiCall 产固定 4 段 —— `opening`(开场)/ `informMissed`(告知应治未治,单项)/ `reviewAdvice`(复查建议,含`【时间段】`占位)/ `closing`(结束语,成功/失败两分支)+ `tone`。失败 → `stableTemplateFallback`(不调 LLM,从 `disease-knowledge` 拼 4 段)。

**standard**:单次 AiCall,输出 `sections[{title, markdown}]`(固定 4 段但 LLM 自定标题/结构)。失败 → stable 模板转 sections。

**deep**:pipeline —— ① **规划**(`DeepPlanCall` → 3–6 段意图 + 关键点)② **撰写**(`DeepWriteCall`,流式逐字)③ **自检**(`DeepVerifyCall` LLM 评 + 独立机器闸 `machineSafetyScan`)④ **修订**(≤1 轮,按 issues 原地改);最终再过机器闸,仍不过 → stable 兜底。

## 输入:聚焦切片 + 薄画像(`ScriptContext`)

**原则:聚焦切片 + 薄画像 > 全历史**。召回只为一件事(`plan_reasons`),喂全历史会跑题/编造/token 爆。

- **召回主体(说什么)**:scenario / sub_key、诊断码 + 病名、牙位(口语化"上门牙/智齿")、拖了多久、目标治疗、触发医生 + 日期、医生医嘱原话(仅引用本次相关)。
- **薄画像(怎么说,只定语气不进内容)**:称呼、年龄→人群、新老客、价值档、流失风险、距上次就诊;深度档另加画像 rubric + 近 5 次回访(避免重复)。
- **去标识(`pii.ts`)**:真实姓名不进 prompt —— 医生只留姓,患者用"年龄+性别+监护人"感知称呼(≤12 岁对家长)。
- **不进**:**治疗链(chain-composer)**(已废弃,"做过什么"用 `treatment_record` 近期治疗代替)、raw EMR 全文 dump、身份证/地址等(召回不需要 + 合规)。

确定性前置(`script-facts.ts`,不调 LLM):日期口语化(X 月 X 号/去年/XXXX 年)、FDI 牙位→患者友好词。

## 安全 / 接地(`safety-rules.ts` 单一源,两道闸)

禁词与规则集中在 `safety-rules.ts`,**机器闸与 prompt 注入同引一份**:

- **禁词**:承诺类(保证 / 绝对 / 100% / 一定能)、淘宝腔(亲爱的)、价格类(便宜 / 促销 / 折扣 / 免费 / 赠送)
- **承诺词**:已为您约好 / 已成功预约(无排班接口,不许预先承诺)
- **正则**:`BOLD_TIME`(禁加粗写死时间 → 用`【时间段】`占位)、`CLINICAL_CODE`(禁 K 码 / 枚举名漏给患者)

两道闸:① **prompt 级** —— `forbiddenWordsBlock()` 注入 system;② **机器闸** —— `machineSafetyScan()` 在输出后扫,命中即 block → 走兜底(深度档自检步骤额外跑一次)。

## 提示词组装(`skill-composer`)

system prompt = `base common`(`shared/skills/_base/common.md`,三档共用:角色定位/语调/接地铁律)+ tier format(`tiers/{tier}/_base/format.md`,各档输出格式不同)+ 禁词块 + 匹配的 skill(人群 adult/child)。按 `applies` 匹配 + `tiers` 过滤 + `priority` 排序拼接;`composeHash` 落账归因。user prompt 由 `fact-block.buildRichFactBlock()` 拼厚事实块。

> **知识 vs 模板分离**:病种/人群的**规则知识**(风险/趁早理由/沟通规则)tier-agnostic 共用;**口语模板**(4 段脚手架 + 口语文案 `phrasing.ts`)仅 stable 独占。标准/深度只吃知识,LLM 自己组织。

## provider 与落账

- **模型**:三档默认 `deepseek-v4-flash`(`?model=` 可覆盖)。
- **落账**:每次经 `AiCallRunner` → `invocation-recorder` 两段式落 `agent_invocations`(tier 嵌在 `promptVersion`、`modelProvider`/`modelName`、token、`costYuan`、source);深度档额外 `attachJudge` 落自检质量分。
- **写库**:`plan_scripts` upsert(`content` Markdown、`status='ready'`、`source`、`agentInvocationId`)。

## 触发

详情页打开按需拉 `GET /pac/v1/plans/:id/script:stream`(SSE 流式),或点"重新生成"走 `POST /pac/v1/plans/:id/script:regenerate`(同步)。两个旋钮:**投入档**(tier)+ **模型**。自动批量生成走 `plan-asset-generate` 队列,当前为 no-AI stub(省 token),见 [三层模型](/docs/architecture/three-layer-model)。
