ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов Stage 3.6 Усилина оркестрация и детект data-scope для живого сленга. Убрана шаблонность soft-refusal в limited-ответах. Подрезана словарнаю жирность в фильтр-экстракторе

This commit is contained in:
2026-04-11 19:45:20 +03:00
parent 88d5561fad
commit 351993430f
20 changed files with 2060 additions and 830 deletions
@@ -4306,6 +4306,74 @@ function renderPolicyReply(structure: AnswerStructureV11, context?: AnswerRender
);
}
function shouldUseSoftPolicyReply(input: {
mode: PolicyMode;
policySignals: PolicySignals;
limitationReasonCodes: EvidenceLimitationReasonCode[];
aggregateEvidenceConfidence: EvidenceConfidence;
coverageReport: RequirementCoverageReport;
hasCriticalEvidenceLimitation: boolean;
}): boolean {
if (input.mode === "focused_grounded" || input.mode === "route_mismatch" || input.mode === "backend_error" || input.mode === "out_of_scope") {
return false;
}
if (input.mode === "clarification_required" || input.mode === "no_grounded" || input.mode === "empty") {
return true;
}
if (input.mode !== "broad_partial") {
return false;
}
const hasCoverageGaps =
input.coverageReport.requirements_uncovered.length > 0 ||
input.coverageReport.requirements_partially_covered.length > 0 ||
input.coverageReport.clarification_needed_for.length > 0 ||
input.coverageReport.out_of_scope_requirements.length > 0;
const weakEvidenceSignals =
input.policySignals.broad_query_detected ||
input.policySignals.broad_result_flag ||
input.policySignals.minimum_evidence_failed ||
input.aggregateEvidenceConfidence === "low" ||
input.hasCriticalEvidenceLimitation ||
input.limitationReasonCodes.includes("weak_source_mapping") ||
input.limitationReasonCodes.includes("insufficient_detail") ||
input.limitationReasonCodes.includes("missing_mechanism");
return hasCoverageGaps || weakEvidenceSignals;
}
function renderSoftPolicyReply(input: {
structure: AnswerStructureV11;
context?: AnswerRenderContext;
mode: PolicyMode;
}): string {
const questionType = input.context?.questionType ?? "unknown";
const shortLine = ensureSentence(buildShortSectionLine(input.structure));
const evidenceLines = dedupeNarrativeLines(buildEvidenceSectionLines(input.structure, questionType, input.context), 3);
const limitationLines = dedupeNarrativeLines(buildLimitationsSectionLines(input.structure), 3);
const checkLines = dedupeNarrativeLines(buildChecksSectionLines(input.structure, input.context), 3);
const clarificationLines = dedupeNarrativeLines(input.structure.next_step_block.clarification_questions ?? [], 2);
const actionLines = dedupeNarrativeLines(
[...checkLines, ...(input.structure.next_step_block.recommended_actions ?? []), ...clarificationLines],
3
);
const modeLine =
input.mode === "clarification_required"
? "Чтобы дать точный ответ, нужно уточнить несколько ориентиров."
: input.mode === "no_grounded" || input.mode === "empty"
? "Сейчас подтвержденной опоры недостаточно для прямого вывода."
: "Есть рабочие сигналы, но часть вывода пока ограничена.";
return sanitizeUserFacingReply(
[
`Коротко: ${shortLine}`,
modeLine,
evidenceLines.length > 0 ? `Что уже проверено: ${evidenceLines.join("; ")}` : "",
limitationLines.length > 0 ? `Что пока не доказано: ${limitationLines.join("; ")}` : "",
actionLines.length > 0 ? `Что могу сделать сейчас: ${actionLines.join("; ")}` : ""
]
.filter(Boolean)
.join("\n\n")
);
}
function composeAssistantAnswerV11(input: ComposeAnswerInput): ComposeAnswerOutput {
const fallbackType = fallbackFromSummary(input.routeSummary);
const questionType: QuestionTypeClass = input.questionTypeHint ?? "unknown";
@@ -4596,12 +4664,30 @@ function composeAssistantAnswerV11(input: ComposeAnswerInput): ComposeAnswerOutp
missingAnchors,
coverageReport: input.coverageReport
})
: renderPolicyReply(answerStructure, {
questionType,
focusDomain: focusNarrativeDomain,
anchors: anchorUsage,
userMessage: input.userMessage
});
: shouldUseSoftPolicyReply({
mode: guardedDecision.mode,
policySignals,
limitationReasonCodes,
aggregateEvidenceConfidence,
coverageReport: input.coverageReport,
hasCriticalEvidenceLimitation
})
? renderSoftPolicyReply({
structure: answerStructure,
context: {
questionType,
focusDomain: focusNarrativeDomain,
anchors: anchorUsage,
userMessage: input.userMessage
},
mode: guardedDecision.mode
})
: renderPolicyReply(answerStructure, {
questionType,
focusDomain: focusNarrativeDomain,
anchors: anchorUsage,
userMessage: input.userMessage
});
return {
assistant_reply: finalAssistantReply,