Commit d09f4339 by luoqi

fix(ai-script): 单一聚焦 — user prompt 只喂主漏诊项,其他不展示

对齐业务提示词"只处理最高优先级漏诊项,其他完全忽略":
- 之前 user prompt 仍把全部 reason + 全部待做治疗塞进去 → LLM 看得到就可能提其他项
- 改:只喂 priorityScore 最高那条 reason 的触发详情;其他 reason **不展示**(渐进式披露,
  LLM 看不到自然不会提)+ 显式标注"另有 N 项,本次一律不提,下次召回单独处理"
- 删 pendingTreatments 多项列表(主漏诊项已覆盖);ongoingChains 保留(语义不同:已在管别再约)

typecheck 0 + build 通过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent d3d093c4
...@@ -190,22 +190,19 @@ export function buildDraftPlanScriptPrompt(input: DraftPlanScriptInput): string ...@@ -190,22 +190,19 @@ export function buildDraftPlanScriptPrompt(input: DraftPlanScriptInput): string
? personaHighlights.map((p) => `- ${p.label}:${p.description}`).join('\n') ? personaHighlights.map((p) => `- ${p.label}:${p.description}`).join('\n')
: '- (暂无关键画像特征)'; : '- (暂无关键画像特征)';
const reasonsLines = plan.reasons.length > 0 // ⭐ 单一聚焦(对齐业务提示词"只处理最高优先级漏诊项,其他完全忽略"):
? plan.reasons // 只把 priorityScore 最高的那条 reason 喂进去;其他 reason **不展示**(LLM 看不到 → 不会提)。
.map((r, i) => { const sortedReasons = [...plan.reasons].sort((a, b) => b.priorityScore - a.priorityScore);
// 触发医生 + 日期 cluster — followup 必须引这条 const top = sortedReasons[0];
const trigBits: string[] = []; const otherCount = Math.max(0, sortedReasons.length - 1);
if (r.triggerDoctor) trigBits.push(`触发医生:${r.triggerDoctor}`); const topReasonLine = top
if (r.triggerDate) trigBits.push(`日期:${r.triggerDate}`); ? `${top.reason}${
const trigStr = trigBits.length > 0 ? ` (${trigBits.join(' · ')})` : ''; [top.triggerDoctor ? `触发医生:${top.triggerDoctor}` : '', top.triggerDate ? `日期:${top.triggerDate}` : '']
return `${i + 1}. [${r.scenarioLabel}, 优先级 ${r.priorityScore}] ${r.reason}${trigStr}`; .filter(Boolean)
}) .join(' · ')
.join('\n') .replace(/^(.+)$/, ' ($1)')
: '- (无具体触发原因)'; }`
: '(无具体触发原因)';
const pendingLines = clinicalContext.pendingTreatments.length > 0
? clinicalContext.pendingTreatments.map((t) => `- ${t}`).join('\n')
: '- (暂无明确待做治疗)';
// ⭐ 程序算好的确定性事实(渐进式组合:LLM 不做年龄分支/日期格式/优先级/查表/称呼) // ⭐ 程序算好的确定性事实(渐进式组合:LLM 不做年龄分支/日期格式/优先级/查表/称呼)
const now = new Date(); const now = new Date();
...@@ -254,8 +251,8 @@ ${kp ? kp.advantages.map((a) => ` - ${a}`).join('\n') : ' - 趁现在早点处 ...@@ -254,8 +251,8 @@ ${kp ? kp.advantages.map((a) => ` - ${a}`).join('\n') : ' - 趁现在早点处
## ⭐ 本次召回目的(必须对齐 — followup 段务必体现这个目标,不要自行脑补别的目的) ## ⭐ 本次召回目的(必须对齐 — followup 段务必体现这个目标,不要自行脑补别的目的)
${plan.goal ?? '(未指定 — 自行从 reasons 推断)'} ${plan.goal ?? '(未指定 — 自行从 reasons 推断)'}
## 触发原因 ## 本次聚焦的漏诊项触发详情(就讲这一个)
${reasonsLines} ${topReasonLine}${otherCount > 0 ? `\n> ⚠️ 该患者另有 ${otherCount} 项应治未治,**本次话术一律不提**(本次只聚焦上面这一个;其他项下次召回单独处理)。` : ''}
## 患者画像关键特征 ## 患者画像关键特征
${personaLines} ${personaLines}
...@@ -266,12 +263,10 @@ ${personaLines} ...@@ -266,12 +263,10 @@ ${personaLines}
- 上次就诊主诉(患者原话,可作开场寒暄/关怀的上下文,别照念医学词):${clinicalContext.lastChiefComplaint ?? '无记录'} - 上次就诊主诉(患者原话,可作开场寒暄/关怀的上下文,别照念医学词):${clinicalContext.lastChiefComplaint ?? '无记录'}
- 该患者长期主诊医生:${clinicalContext.primaryDoctorName ?? '(未知)'} - 该患者长期主诊医生:${clinicalContext.primaryDoctorName ?? '(未知)'}
- 历史已做治疗:${clinicalContext.completedTreatmentCount} - 历史已做治疗:${clinicalContext.completedTreatmentCount}
- 待做治疗(牙位已转俗称,本次召回想推进的就是这些):
${pendingLines}
- 正在进行的治疗链(已在管,**不要再次邀约**这些类目;可作为"诊所记得 ta"的引用素材): - 正在进行的治疗链(已在管,**不要再次邀约**这些类目;可作为"诊所记得 ta"的引用素材):
${clinicalContext.ongoingChains.length > 0 ? clinicalContext.ongoingChains.map((l) => ` - ${l}`).join('\n') : ' - (无正在进行的治疗链)'} ${clinicalContext.ongoingChains.length > 0 ? clinicalContext.ongoingChains.map((l) => ` - ${l}`).join('\n') : ' - (无正在进行的治疗链)'}
# 任务 # 任务
schema 4 (opening 开场白 / informMissed 告知漏诊项目 / reviewAdvice 复查建议 / closing 结束回访语)+ tone 输出 1 JSON schema 4 (opening 开场白 / informMissed 告知漏诊项目 / reviewAdvice 复查建议 / closing 结束回访语)+ tone 输出 1 JSON
**只讲上面"主漏诊项"那一个**,严禁提其他漏诊项。称呼/日期/复查时长直接用"程序已算好的事实",不要自己改。所有事实必须来自上面字段。`; **全程只讲"程序已算好的事实·主漏诊项"那一个**,严禁提及任何其他漏诊项目。称呼/日期/复查时长直接用"程序已算好的事实",不要自己改。所有事实必须来自上面字段。`;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment