Commit 4ae1aa8a by luoqi

refactor(ai): user prompt 去掉冗余的 skills 名字索引

skills 正文已直接注入 system,user prompt 末尾再列名字纯冗余(还易困惑);删之。
promptVersion bump 到 skills-base-v2 便于 eval 区分。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent 2a43e5a7
...@@ -180,7 +180,7 @@ function isSkillsEnabled(): boolean { ...@@ -180,7 +180,7 @@ function isSkillsEnabled(): boolean {
* composeHash 可以在 agent_invocations.input_snapshot.skills_used 看到具体装配)。 * composeHash 可以在 agent_invocations.input_snapshot.skills_used 看到具体装配)。
*/ */
const DRAFT_PLAN_SCRIPT_PROMPT_VERSION_SKILLS = const DRAFT_PLAN_SCRIPT_PROMPT_VERSION_SKILLS =
'draft_plan_script@2026-05-27-skills-base-v1'; 'draft_plan_script@2026-05-31-skills-base-v2'; // v2: user prompt 去掉冗余的 skills 名字索引
@Injectable() @Injectable()
export class DraftPlanScriptCall export class DraftPlanScriptCall
...@@ -202,14 +202,14 @@ export class DraftPlanScriptCall ...@@ -202,14 +202,14 @@ export class DraftPlanScriptCall
buildPrompt(input: DraftPlanScriptInput) { buildPrompt(input: DraftPlanScriptInput) {
if (!isSkillsEnabled()) { if (!isSkillsEnabled()) {
// legacy 路径 — 老 prompt 单系统词,user prompt 不传 matchedSkills // legacy 路径 — 老 prompt 单系统词
return { return {
system: DRAFT_PLAN_SCRIPT_SYSTEM_LEGACY, system: DRAFT_PLAN_SCRIPT_SYSTEM_LEGACY,
prompt: buildDraftPlanScriptPrompt(input, []), prompt: buildDraftPlanScriptPrompt(input),
}; };
} }
// skills 路径 — composer 装配 system + user prompt 末尾追加 skills 清单 // skills 路径 — composer 装配 system(含 skill 正文);user prompt 不再重列 skills 名字
const composed = composeSystem(input, this.skillRegistry.getAllSkills()); const composed = composeSystem(input, this.skillRegistry.getAllSkills());
if (composed.matchedSkills.length === 0) { if (composed.matchedSkills.length === 0) {
this.logger.warn( this.logger.warn(
...@@ -226,7 +226,7 @@ export class DraftPlanScriptCall ...@@ -226,7 +226,7 @@ export class DraftPlanScriptCall
} }
return { return {
system: composed.systemPrompt, system: composed.systemPrompt,
prompt: buildDraftPlanScriptPrompt(input, composed.matchedSkills), prompt: buildDraftPlanScriptPrompt(input),
}; };
} }
......
import type { DraftPlanScriptInput } from './input.types'; import type { DraftPlanScriptInput } from './input.types';
import type { Skill } from './skill.types';
/** /**
* Prompt 版本管理约定: * Prompt 版本管理约定:
...@@ -171,15 +170,11 @@ followup / objection 段是邀约 / 应对异议,可以给多个时间选项供 ...@@ -171,15 +170,11 @@ followup / objection 段是邀约 / 应对异议,可以给多个时间选项供
* *
* 设计: * 设计:
* - 把患者信息以"病历摘要"风格组织,LLM 对自然语言上下文比对 JSON 上下文更稳 * - 把患者信息以"病历摘要"风格组织,LLM 对自然语言上下文比对 JSON 上下文更稳
* - 末尾追加"本次激活的 skills"清单(由 composer 传入) — 让 LLM 跨 skill 自检 + 落账归因 * - skills 正文已直接注入 system(composeSystem),user prompt 不再重列名字清单(冗余,已删)
* - matchedSkills 空时(legacy 路径)不输出 skills 段
* *
* inline hint(原 §临床上下文"老客可家常 / 新客需详细")已删除,改由 relationship skill 承担。 * inline hint(原 §临床上下文"老客可家常 / 新客需详细")已删除,改由 relationship skill 承担。
*/ */
export function buildDraftPlanScriptPrompt( export function buildDraftPlanScriptPrompt(input: DraftPlanScriptInput): string {
input: DraftPlanScriptInput,
matchedSkills: readonly Skill[],
): string {
const { patient, clinicName, plan, personaHighlights, clinicalContext } = input; const { patient, clinicName, plan, personaHighlights, clinicalContext } = input;
const personaLines = personaHighlights.length > 0 const personaLines = personaHighlights.length > 0
...@@ -236,21 +231,6 @@ ${pendingLines} ...@@ -236,21 +231,6 @@ ${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') : ' - (无正在进行的治疗链)'}
${renderActiveSkillsBlock(matchedSkills)}# 任务 # 任务
schema 5 字段输出 1 JSON。所有事实必须来自上面字段,system prompt "反向约束"严格遵守。`; schema 5 字段输出 1 JSON。所有事实必须来自上面字段,system prompt "反向约束"严格遵守。`;
} }
/**
* "本次激活的 skills" 清单(末尾追加)— 让 LLM 跨 skill 自检 + 便于审计归因。
* legacy 路径(空数组)直接返回空串,user prompt 末尾无变化。
*/
function renderActiveSkillsBlock(matchedSkills: readonly Skill[]): string {
if (matchedSkills.length === 0) return '';
const lines = matchedSkills
.map((s) => `- ${s.frontmatter.name} (v${s.frontmatter.version})`)
.join('\n');
return `## 本次激活的 skills(已注入 system,这里只列清单供你跨 skill 自检)
${lines}
`;
}
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