Commit a0afbd7e by luoqi

fix(ai-script): 深度档 repair 严格按自检逐条改(喂上一稿 + 强约束)

问题:verify 后的修订阶段,模型没严格按自检 issue 改 —— 根因是 repair 只给了大纲+问题提示、
没给上一稿,模型是'凭大纲重写'而非'在原稿上逐条改'。

- DeepWriteInput 加 prevDraft;strategy 的 repair(run + runStream)把上一稿传进去。
- buildWritePrompt repair 分支重写:① 附【上一稿(待修订)】②【必须修正的问题,逐条缺一不可,每条带'必须改成'】
  ③【修订铁律:只动被点名处/其余原样/不得引入新违规/缺一不可】。
- writeCall promptVersion → v11。
验证(本地深度生成触发 repair):repair invocation prompt 含上一稿+逐条问题+铁律(4项校验全 t)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent 01508da3
......@@ -47,7 +47,7 @@ export class DeepPlanCall implements AiCall<ScriptContext, DeepPlanZ> {
export class DeepWriteCall implements AiCall<DeepWriteInput, DeepWriteZ> {
readonly kind = 'script' as const;
readonly callKey = 'draft_plan_script_write';
readonly promptVersion = 'draft_plan_script@2026-06-06-deep-write-v10'; // v6: 去 {} 替换占位 + common.md/deep format 去 brace + 预约句 X医生
readonly promptVersion = 'draft_plan_script@2026-06-08-deep-write-v11'; // v11: repair 喂上一稿 + 逐条强约束(严格按自检 fix 改)
readonly defaultModelId = 'deepseek-v4-flash';
readonly outputSchema = DeepWriteSchema;
constructor(private readonly skillRegistry: DraftPlanScriptSkillRegistry) {}
......
......@@ -119,7 +119,7 @@ export class DeepScriptStrategy {
if (issues.length > 0) {
ensureLive();
this.logger.debug(`deep repair: ${issues.length} 个 issue`);
const w2 = await this.runner.run(this.writeCall, { ctx, plan, repairIssues: issues }, runCtx);
const w2 = await this.runner.run(this.writeCall, { ctx, plan, repairIssues: issues, prevDraft: draft }, runCtx);
acc(w2);
draft = w2.output;
invocationId = w2.invocationId;
......@@ -227,7 +227,7 @@ export class DeepScriptStrategy {
if (issues.length > 0) {
ensureLive();
yield { kind: 'step', step: 'repair', status: 'running', detail: { issuesCount: issues.length } };
const w2 = yield* this.streamWrite({ ctx, plan, repairIssues: issues }, runCtx, acc);
const w2 = yield* this.streamWrite({ ctx, plan, repairIssues: issues, prevDraft: draft }, runCtx, acc);
draft = w2.output;
invocationId = w2.invocationId;
steps.push(w2.source === 'template_fallback' ? 'repair:fallback' : 'repair');
......@@ -255,7 +255,7 @@ export class DeepScriptStrategy {
/** 流式跑 write/repair:逐字 yield partial,返回 done(output/invocationId/source) */
private async *streamWrite(
wInput: { ctx: ScriptContext; plan: DeepPlan; repairIssues?: DeepVerifyIssue[] },
wInput: { ctx: ScriptContext; plan: DeepPlan; repairIssues?: DeepVerifyIssue[]; prevDraft?: DeepDraft },
runCtx: AiCallContext,
acc: (r: { costYuan: number; promptTokens: number; completionTokens: number }) => void,
): AsyncGenerator<DeepStepEvent, { output: DeepDraft; source: 'agent' | 'template_fallback'; invocationId: string; fallbackReason?: string }> {
......
......@@ -17,19 +17,42 @@ export function buildPlanPrompt(ctx: ScriptContext): string {
基于以上事实,规划这通回访电话拆成几段、每段讲什么。要点须来自上面事实,不编造。`;
}
/** 步骤2:写 user prompt —— 深度厚事实块 + 上一步大纲(+ repair 反馈) */
/** 步骤2:写 user prompt —— 深度厚事实块 + 上一步大纲(+ repair:上一稿 + 逐条修正约束) */
export function buildWritePrompt(input: DeepWriteInput): string {
const outline = renderPlanOutline(input.plan);
const repair = input.repairIssues?.length
? `\n\n# ⚠️ 上一稿校验未过,按以下逐条修正后重写\n${input.repairIssues
.map((i) => `- [${i.section}] 问题:${i.problem} → 修:${i.fix}`)
.join('\n')}`
: '';
// ── repair 轮:不是"凭大纲重写",而是"在上一稿上,严格按自检逐条改" ──
if (input.repairIssues?.length) {
const prev = input.prevDraft
? input.prevDraft.sections.map((s, i) => `### 第${i + 1}段:${s.title}\n${s.markdown}`).join('\n\n')
: '(上一稿缺失,按大纲重写并满足下列修正)';
const issues = input.repairIssues
.map((it, i) => `${i + 1}. 【${it.section}】问题:${it.problem}\n 必须改成:${it.fix}`)
.join('\n');
return `${deepFacts(input.ctx)}
---
# 本步任务:修订(不是重写)
上一稿没通过【接地 + 安全】自检。**在上一稿基础上,严格逐条改掉下面每一处问题**,改完输出完整修订稿。
## 上一稿(待修订)
${prev}
## 必须修正的问题(逐条,缺一不可)
${issues}
## 修订铁律
- 上面每一条都必须改到位,**一条都不能漏**;改法以"必须改成"为准。
- **只动被点名的地方**,其余句子保持原样,不要顺手重写或新增事实。
- 修正不得引入新的违规:不报价/不承诺疗效/不写死具体时间(用【时间段】占位)/≤18 岁不提拍片。
- 段落结构沿用上一稿(标题可不变),输出完整的多段话术。`;
}
return `${deepFacts(input.ctx)}
---
# 本步大纲(按它逐段写,可微调措辞,不要新增事实)
${outline}${repair}`;
${outline}`;
}
/** 步骤3:独立对抗校验 user prompt —— 事实 + 待验草稿(新开上下文,对抗) */
......
......@@ -61,6 +61,8 @@ export interface DeepWriteInput {
plan: DeepPlan;
/** repair 轮:把校验不过的点回喂 writer 修(≤1 轮) */
repairIssues?: DeepVerifyIssue[];
/** repair 轮:上一稿(让 writer 在原稿上逐条改,而非凭大纲重写 → 严格按自检 fix 修) */
prevDraft?: DeepDraft;
}
export interface DeepVerifyInput {
ctx: ScriptContext;
......
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