ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов Stage 3.7 ХВОСТЫ Убрана часть чат-дрифта и зафиксировал роутинг в deep \ Ослаблена шаблонность коротких блоков ответа (детерминированные вариативные формулировки вместо одной и той же фразы)
This commit is contained in:
+37
-4
@@ -912,6 +912,28 @@ function buildLimitedScopeLine(filters) {
|
||||
}
|
||||
return `Контекст запроса: ${scopeParts.join(", ")}.`;
|
||||
}
|
||||
function buildLimitedVariantSeedFingerprint(filters) {
|
||||
const seedParts = [];
|
||||
const keys = [
|
||||
"organization",
|
||||
"counterparty",
|
||||
"contract",
|
||||
"account",
|
||||
"document_ref",
|
||||
"as_of_date",
|
||||
"period_from",
|
||||
"period_to"
|
||||
];
|
||||
for (const key of keys) {
|
||||
const raw = filters[key];
|
||||
const value = typeof raw === "string" ? raw.trim() : "";
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
seedParts.push(`${key}:${value.toLowerCase()}`);
|
||||
}
|
||||
return seedParts.length > 0 ? seedParts.join("|") : "no_filter_seed";
|
||||
}
|
||||
function buildLimitedOffers(input) {
|
||||
const counterpartyRaw = toNonEmptyFilterValue(input.filters.counterparty);
|
||||
const contractRaw = toNonEmptyFilterValue(input.filters.contract);
|
||||
@@ -1001,12 +1023,21 @@ function hasAggregateLimitedSignal(input) {
|
||||
}
|
||||
function composeLimitedReply(input) {
|
||||
const reason = normalizeLimitedReason(input.reason);
|
||||
const headingSeed = `${input.category}|${input.shape.shape}|${reason}`;
|
||||
const filterSeed = buildLimitedVariantSeedFingerprint(input.filters);
|
||||
const missingSeed = Array.from(new Set(input.missingRequiredFilters.map((item) => String(item ?? "").trim())))
|
||||
.filter((item) => item.length > 0)
|
||||
.sort()
|
||||
.join(",");
|
||||
const headingSeed = `${input.category}|${input.shape.shape}|${input.intent}|${reason}|${filterSeed}|${missingSeed}`;
|
||||
const aggregateLimitedSignal = hasAggregateLimitedSignal({
|
||||
shape: input.shape,
|
||||
intent: input.intent,
|
||||
reason: input.reason
|
||||
});
|
||||
const missingAnchorLabels = Array.from(new Set((Array.isArray(input.missingRequiredFilters) ? input.missingRequiredFilters : [])
|
||||
.map((item) => normalizeMissingAnchorLabel(String(item ?? "").trim()))
|
||||
.filter((item) => item.length > 0)));
|
||||
const missingAnchorPhrase = missingAnchorLabels.length > 0 ? missingAnchorLabels.join(", ") : "контрагент, договор, счет или период";
|
||||
const heading = input.category === "empty_match"
|
||||
? pickDeterministicVariant(headingSeed, [
|
||||
"По текущим условиям в доступном срезе данных совпадений не нашлось.",
|
||||
@@ -1042,12 +1073,14 @@ function composeLimitedReply(input) {
|
||||
])
|
||||
: pickDeterministicVariant(reasonSeed, [
|
||||
"Сценарий пока не закрыт текущими адресными маршрутами без потери точности.",
|
||||
"Для этого запроса пока нет надежного ответа внутри текущего address-контура."
|
||||
"Для этого запроса пока нет надежного ответа в текущем адресном режиме.",
|
||||
"Надежный ответ здесь требует более широкого анализа, чем текущий адресный контур."
|
||||
])
|
||||
: input.category === "missing_anchor"
|
||||
? pickDeterministicVariant(reasonSeed, [
|
||||
"Нужно чуть точнее заякорить запрос: не хватает конкретного ориентира (контрагент, договор, счет или период).",
|
||||
"Для точного ответа нужен хотя бы один явный якорь: контрагент, договор, счет или период."
|
||||
`Нужно чуть точнее заякорить запрос: не хватает конкретного ориентира (${missingAnchorPhrase}).`,
|
||||
`Для точного ответа нужен хотя бы один явный ориентир: ${missingAnchorPhrase}.`,
|
||||
`Смысл запроса понятен, но без уточнения (${missingAnchorPhrase}) риск ошибки слишком высокий.`
|
||||
])
|
||||
: input.category === "recipe_visibility_gap"
|
||||
? "Для уверенного ответа нужен более специализированный сценарий выборки."
|
||||
|
||||
+54
-7
@@ -2667,27 +2667,74 @@ function buildShortSectionLine(structure) {
|
||||
const broken = sanitizeUserText(structure.direct_answer) ?? "";
|
||||
const domain = inferNarrativeDomainFromText(broken);
|
||||
const incomplete = isIncompleteEvidence(structure);
|
||||
const shortSeed = `${domain}|${incomplete ? "partial" : "grounded"}|${broken}`;
|
||||
if (/вне доступного учетного контура/i.test(broken)) {
|
||||
return "Запрос вне доступного учетного контура.";
|
||||
}
|
||||
if (/не совпал с предметом вопроса|более точный фокус/i.test(broken)) {
|
||||
return "Требуется уточнение фокуса, чтобы ответить по нужному участку учета.";
|
||||
return pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Требуется уточнить фокус, чтобы ответить по нужному участку учета.",
|
||||
"Сейчас не хватает точного фокуса вопроса для надежного вывода.",
|
||||
"Нужна чуть более точная формулировка фокуса запроса."
|
||||
]);
|
||||
}
|
||||
if (/ненадежен|уточнен/i.test(broken)) {
|
||||
return "Проблема подтверждается частично; для уверенного вывода нужны уточнения.";
|
||||
return pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Сигналы есть, но для уверенного вывода нужны уточнения.",
|
||||
"Картина пока частичная: подтверждения есть, но не хватает уточнений.",
|
||||
"Промежуточный вывод собран, однако без уточнений он остается ограниченным."
|
||||
]);
|
||||
}
|
||||
if (domain === "settlements_60_62") {
|
||||
return incomplete
|
||||
? "Проблема с закрытием расчета подтверждается частично."
|
||||
: "Проблема с закрытием расчета подтверждена.";
|
||||
? pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"По взаиморасчетам видны признаки неполного закрытия, но картина пока частичная.",
|
||||
"Есть подтвержденные сигналы разрыва закрытия расчетов, часть вывода остается ограниченной.",
|
||||
"Риск незакрытых взаиморасчетов подтвержден частично и требует уточнения."
|
||||
])
|
||||
: pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Проблема с закрытием расчетов подтверждена на текущей опоре.",
|
||||
"Разрыв в закрытии взаиморасчетов подтвержден.",
|
||||
"По текущей опоре несходимость в закрытии расчетов подтверждена."
|
||||
]);
|
||||
}
|
||||
if (domain === "vat_document_register_book") {
|
||||
return incomplete ? "Проблема в цепочке НДС подтверждается частично." : "Проблема в цепочке НДС подтверждена.";
|
||||
return incomplete
|
||||
? pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"В цепочке НДС есть подтвержденные отклонения, но пока не по всем звеньям.",
|
||||
"Сигналы по НДС подтверждены частично; для полного вывода нужна дополнительная проверка.",
|
||||
"Есть частичное подтверждение разрыва в НДС-контуре."
|
||||
])
|
||||
: pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Проблема в цепочке НДС подтверждена.",
|
||||
"Разрыв в НДС-контуре подтвержден на текущей опоре.",
|
||||
"По НДС выявлен и подтвержден проблемный переход в цепочке."
|
||||
]);
|
||||
}
|
||||
if (domain === "month_close_costs_20_44") {
|
||||
return incomplete ? "Проблема в контуре закрытия месяца подтверждается частично." : "Проблема в контуре закрытия месяца подтверждена.";
|
||||
return incomplete
|
||||
? pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"По закрытию месяца есть проблемные сигналы, но они подтверждены частично.",
|
||||
"Контур 20/44 показывает частично подтвержденные отклонения закрытия.",
|
||||
"Есть признаки сбоя в закрытии месяца, однако опора пока неполная."
|
||||
])
|
||||
: pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Проблема в контуре закрытия месяца подтверждена.",
|
||||
"Сбой в закрытии месяца подтвержден на текущей выборке.",
|
||||
"Разрыв в контуре 20/44 подтвержден."
|
||||
]);
|
||||
}
|
||||
return incomplete ? "Проблема подтверждается частично на текущей опоре." : "Проблема подтверждена на текущей опоре.";
|
||||
return incomplete
|
||||
? pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Есть подтвержденные сигналы, но вывод пока частичный.",
|
||||
"Промежуточная проверка выявила проблему, однако опора еще неполная.",
|
||||
"Часть признаков подтверждена, для полного вывода нужна допроверка."
|
||||
])
|
||||
: pickDeterministicBoundaryVariant(shortSeed, [
|
||||
"Проблема подтверждена на текущей опоре.",
|
||||
"Текущая опора подтверждает наличие проблемы.",
|
||||
"Подтверждение проблемы по текущей выборке получено."
|
||||
]);
|
||||
}
|
||||
function humanizeCompositeDirectAnswer(value) {
|
||||
const raw = String(value ?? "").trim();
|
||||
|
||||
@@ -3932,7 +3932,7 @@ function hasLivingChatSignal(text) {
|
||||
if (!lower) {
|
||||
return false;
|
||||
}
|
||||
if (/^(ага|угу|ок|окей|ясно|понял|поняла|принято|спасибо|благодарю|супер|класс|норм|го|давай|погнали|привет|хай|йо|hello|hi|thanks?)$/i.test(lower)) {
|
||||
if (/^(ага|угу|ок|окей|ясно|понял|поняла|принято|спасибо|благодарю|супер|класс|норм|го|давай|погнали|привет|хай|йо|yo|че\s+там|ч[её]\s+как|че\s+как|hello|hi|thanks?)$/i.test(lower)) {
|
||||
return true;
|
||||
}
|
||||
if (/(как дела|как ты|что нового|расскажи о себе|чем можешь помочь|давай поговорим|поговорим|обсудим|посоветуй|что думаешь)/i.test(lower)) {
|
||||
@@ -4802,6 +4802,12 @@ function resolveLivingAssistantModeDecision(input) {
|
||||
reason: "assistant_capability_query_detected"
|
||||
};
|
||||
}
|
||||
if (hasOrganizationFactLookupSignal(userMessage) || hasOrganizationFactFollowupSignal(userMessage)) {
|
||||
return {
|
||||
mode: "chat",
|
||||
reason: "organization_fact_lookup_signal_detected"
|
||||
};
|
||||
}
|
||||
if (hasStrongDataIntentSignal(userMessage)) {
|
||||
return {
|
||||
mode: "deep_analysis",
|
||||
@@ -4818,8 +4824,8 @@ function resolveLivingAssistantModeDecision(input) {
|
||||
const predecomposeConfidence = toNonEmptyString(input?.predecomposeModeConfidence);
|
||||
if (predecomposeMode === "unsupported" && (predecomposeConfidence === "low" || predecomposeConfidence === "medium")) {
|
||||
return {
|
||||
mode: "chat",
|
||||
reason: "predecompose_unsupported_mode"
|
||||
mode: "deep_analysis",
|
||||
reason: "predecompose_unsupported_mode_fallback_to_deep"
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user