Уточнить честность широкого бизнес-обзора ассистента
This commit is contained in:
parent
baa8aa31e7
commit
92473c894f
|
|
@ -0,0 +1,96 @@
|
||||||
|
{
|
||||||
|
"schema_version": "domain_truth_harness_spec_v1",
|
||||||
|
"scenario_id": "hm_business_profile_evaluation_limits_20260525",
|
||||||
|
"domain": "assistant_stage1_business_overview",
|
||||||
|
"title": "Hm business profile evaluation coverage honesty",
|
||||||
|
"description": "Focused live replay for broad company evaluation: the assistant must give a useful business reading while clearly presenting cashflow probes as a limited checked 1C slice, not a full audit, clean profit, or complete accounting turnover.",
|
||||||
|
"bindings": {},
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"step_id": "s01_top_year_establish_company",
|
||||||
|
"title": "Establish company context through top-year question",
|
||||||
|
"question": "какой у ООО \"Альтернатива Плюс\" самый доходный год",
|
||||||
|
"allowed_reply_types": [
|
||||||
|
"factual",
|
||||||
|
"factual_with_explanation",
|
||||||
|
"partial_coverage"
|
||||||
|
],
|
||||||
|
"required_direct_answer_patterns_any": [
|
||||||
|
"2015",
|
||||||
|
"входящ"
|
||||||
|
],
|
||||||
|
"forbidden_answer_patterns": [
|
||||||
|
"Коротко:",
|
||||||
|
"capability_id",
|
||||||
|
"mcp_discovery"
|
||||||
|
],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": [
|
||||||
|
"business_overview",
|
||||||
|
"company_context",
|
||||||
|
"yearly_ranking"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step_id": "s02_broad_company_evaluation",
|
||||||
|
"title": "Broad company evaluation must lead with limited-evidence framing",
|
||||||
|
"question": "Как ты оценишь деятельность компании?",
|
||||||
|
"allowed_reply_types": [
|
||||||
|
"factual_with_explanation",
|
||||||
|
"partial_coverage"
|
||||||
|
],
|
||||||
|
"required_answer_patterns_all": [
|
||||||
|
"ограниченн",
|
||||||
|
"денежн",
|
||||||
|
"не аудиторское",
|
||||||
|
"не подтвержден",
|
||||||
|
"чист",
|
||||||
|
"прибыл",
|
||||||
|
"Комитет государственных услуг",
|
||||||
|
"зависим"
|
||||||
|
],
|
||||||
|
"forbidden_answer_patterns": [
|
||||||
|
"Коротко:",
|
||||||
|
"capability_id",
|
||||||
|
"mcp_discovery",
|
||||||
|
"query_movements",
|
||||||
|
"business_overview_route_template_v1"
|
||||||
|
],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": [
|
||||||
|
"business_overview",
|
||||||
|
"broad_business_evaluation",
|
||||||
|
"coverage_honesty",
|
||||||
|
"profit_boundary"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step_id": "s03_profitability_boundary",
|
||||||
|
"title": "Profitability follow-up must not convert net cashflow into profit",
|
||||||
|
"question": "то есть бизнес прибыльный или это только обороты?",
|
||||||
|
"allowed_reply_types": [
|
||||||
|
"factual_with_explanation",
|
||||||
|
"partial_coverage"
|
||||||
|
],
|
||||||
|
"required_answer_patterns_all": [
|
||||||
|
"не подтверждаю",
|
||||||
|
"прибыл",
|
||||||
|
"денежн",
|
||||||
|
"нетто",
|
||||||
|
"не полн"
|
||||||
|
],
|
||||||
|
"forbidden_answer_patterns": [
|
||||||
|
"Коротко:",
|
||||||
|
"capability_id",
|
||||||
|
"mcp_discovery",
|
||||||
|
"это прибыль"
|
||||||
|
],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": [
|
||||||
|
"business_overview",
|
||||||
|
"profitability_boundary",
|
||||||
|
"cashflow_not_profit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -959,11 +959,7 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
|
||||||
: "Это учетный финрезультат по найденным строкам закрытия периода в 1С, а не внешний аудит и не юридически подтвержденная отчетность.");
|
: "Это учетный финрезультат по найденным строкам закрытия периода в 1С, а не внешний аудит и не юридически подтвержденная отчетность.");
|
||||||
return joinBusinessReplyLines(lines);
|
return joinBusinessReplyLines(lines);
|
||||||
}
|
}
|
||||||
const headline = toNonEmptyString(draft.headline);
|
lines.push("Коротко: чистую прибыль и маржу не подтверждаю по текущему срезу 1С; видны только ограниченные денежные обороты и расчетное нетто/операционный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат.");
|
||||||
const cleanHeadline = headline?.replace(/^Коротко:\s*/iu, "").trim();
|
|
||||||
lines.push(cleanHeadline
|
|
||||||
? `Коротко: ${localizeLine(cleanHeadline)}`
|
|
||||||
: "Коротко: нельзя точно подтвердить чистую прибыль и маржу по текущему срезу 1С; есть только ограниченный операционный денежный/товарный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат.");
|
|
||||||
const boundaryLines = userFacingLines([
|
const boundaryLines = userFacingLines([
|
||||||
...toStringList(draft.confirmed_lines),
|
...toStringList(draft.confirmed_lines),
|
||||||
...toStringList(draft.inference_lines),
|
...toStringList(draft.inference_lines),
|
||||||
|
|
@ -1113,8 +1109,8 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
|
||||||
(actionFamily === "broad_evaluation" || unsupportedFamily === "broad_business_evaluation")) {
|
(actionFamily === "broad_evaluation" || unsupportedFamily === "broad_business_evaluation")) {
|
||||||
const subject = organizationScope ?? "компания";
|
const subject = organizationScope ?? "компания";
|
||||||
const periodWithoutPrefix = period.replace(/^за\s+/iu, "");
|
const periodWithoutPrefix = period.replace(/^за\s+/iu, "");
|
||||||
lines.push(`Коротко: по доступным данным ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж.`);
|
lines.push(`Коротко: по ограниченному проверенному 1С-срезу ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж; это не аудиторское заключение и не подтвержденная чистая прибыль.`);
|
||||||
lines.push("Что видно:");
|
lines.push("Что видно в ограниченном денежном срезе:");
|
||||||
if (incomingAmount) {
|
if (incomingAmount) {
|
||||||
lines.push(`- входящие деньги за ${periodWithoutPrefix}: ${incomingAmount};`);
|
lines.push(`- входящие деньги за ${periodWithoutPrefix}: ${incomingAmount};`);
|
||||||
}
|
}
|
||||||
|
|
@ -1146,7 +1142,9 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
|
||||||
if (debtLine) {
|
if (debtLine) {
|
||||||
lines.push(`- ${localizeLine(debtLine)}`);
|
lines.push(`- ${localizeLine(debtLine)}`);
|
||||||
}
|
}
|
||||||
|
if (!limitLine) {
|
||||||
lines.push("Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль.");
|
lines.push("Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль.");
|
||||||
|
}
|
||||||
const missingOverviewFamilies = [];
|
const missingOverviewFamilies = [];
|
||||||
if (!taxLine) {
|
if (!taxLine) {
|
||||||
missingOverviewFamilies.push("НДС/налоговая позиция без отдельного точного расчета");
|
missingOverviewFamilies.push("НДС/налоговая позиция без отдельного точного расчета");
|
||||||
|
|
|
||||||
|
|
@ -1167,12 +1167,8 @@ function buildCompactBusinessOverviewReply(
|
||||||
);
|
);
|
||||||
return joinBusinessReplyLines(lines);
|
return joinBusinessReplyLines(lines);
|
||||||
}
|
}
|
||||||
const headline = toNonEmptyString(draft.headline);
|
|
||||||
const cleanHeadline = headline?.replace(/^Коротко:\s*/iu, "").trim();
|
|
||||||
lines.push(
|
lines.push(
|
||||||
cleanHeadline
|
"Коротко: чистую прибыль и маржу не подтверждаю по текущему срезу 1С; видны только ограниченные денежные обороты и расчетное нетто/операционный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат."
|
||||||
? `Коротко: ${localizeLine(cleanHeadline)}`
|
|
||||||
: "Коротко: нельзя точно подтвердить чистую прибыль и маржу по текущему срезу 1С; есть только ограниченный операционный денежный/товарный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат."
|
|
||||||
);
|
);
|
||||||
const boundaryLines = userFacingLines([
|
const boundaryLines = userFacingLines([
|
||||||
...toStringList(draft.confirmed_lines),
|
...toStringList(draft.confirmed_lines),
|
||||||
|
|
@ -1366,9 +1362,9 @@ function buildCompactBusinessOverviewReply(
|
||||||
const subject = organizationScope ?? "компания";
|
const subject = organizationScope ?? "компания";
|
||||||
const periodWithoutPrefix = period.replace(/^за\s+/iu, "");
|
const periodWithoutPrefix = period.replace(/^за\s+/iu, "");
|
||||||
lines.push(
|
lines.push(
|
||||||
`Коротко: по доступным данным ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж.`
|
`Коротко: по ограниченному проверенному 1С-срезу ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж; это не аудиторское заключение и не подтвержденная чистая прибыль.`
|
||||||
);
|
);
|
||||||
lines.push("Что видно:");
|
lines.push("Что видно в ограниченном денежном срезе:");
|
||||||
if (incomingAmount) {
|
if (incomingAmount) {
|
||||||
lines.push(`- входящие деньги за ${periodWithoutPrefix}: ${incomingAmount};`);
|
lines.push(`- входящие деньги за ${periodWithoutPrefix}: ${incomingAmount};`);
|
||||||
}
|
}
|
||||||
|
|
@ -1404,9 +1400,11 @@ function buildCompactBusinessOverviewReply(
|
||||||
if (debtLine) {
|
if (debtLine) {
|
||||||
lines.push(`- ${localizeLine(debtLine)}`);
|
lines.push(`- ${localizeLine(debtLine)}`);
|
||||||
}
|
}
|
||||||
|
if (!limitLine) {
|
||||||
lines.push(
|
lines.push(
|
||||||
"Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль."
|
"Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль."
|
||||||
);
|
);
|
||||||
|
}
|
||||||
const missingOverviewFamilies: string[] = [];
|
const missingOverviewFamilies: string[] = [];
|
||||||
if (!taxLine) {
|
if (!taxLine) {
|
||||||
missingOverviewFamilies.push("НДС/налоговая позиция без отдельного точного расчета");
|
missingOverviewFamilies.push("НДС/налоговая позиция без отдельного точного расчета");
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,8 @@ describe("assistant MCP discovery response candidate", () => {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(candidate.reply_text).toContain("нельзя точно подтвердить чистую прибыль");
|
expect(candidate.reply_text).toContain("чистую прибыль и маржу не подтверждаю");
|
||||||
|
expect(candidate.reply_text).toContain("расчетное нетто");
|
||||||
expect(candidate.reply_text).toContain("полный отчет о прибылях и убытках");
|
expect(candidate.reply_text).toContain("полный отчет о прибылях и убытках");
|
||||||
expect(candidate.reply_text).toContain("себестоимости");
|
expect(candidate.reply_text).toContain("себестоимости");
|
||||||
expect(candidate.reply_text).not.toContain("47 628 853");
|
expect(candidate.reply_text).not.toContain("47 628 853");
|
||||||
|
|
@ -1003,7 +1004,7 @@ describe("assistant MCP discovery response candidate", () => {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(candidate.reply_text).toContain("Что видно:");
|
expect(candidate.reply_text).toContain("Что видно в ограниченном денежном срезе:");
|
||||||
expect(candidate.reply_text).toContain("НДС:");
|
expect(candidate.reply_text).toContain("НДС:");
|
||||||
expect(candidate.reply_text).toContain("Долги:");
|
expect(candidate.reply_text).toContain("Долги:");
|
||||||
expect(candidate.reply_text).toContain("Склад:");
|
expect(candidate.reply_text).toContain("Склад:");
|
||||||
|
|
@ -1425,6 +1426,11 @@ describe("assistant MCP discovery response candidate", () => {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const firstLine = candidate.reply_text?.split("\n")[0] ?? "";
|
||||||
|
expect(firstLine).toContain("по ограниченному проверенному 1С-срезу");
|
||||||
|
expect(firstLine).toContain("не аудиторское заключение");
|
||||||
|
expect(firstLine).toContain("не подтвержденная чистая прибыль");
|
||||||
|
expect(candidate.reply_text).toContain("Что видно в ограниченном денежном срезе");
|
||||||
expect(candidate.reply_text).toContain("Что не подтверждено в этом срезе");
|
expect(candidate.reply_text).toContain("Что не подтверждено в этом срезе");
|
||||||
expect(candidate.reply_text).toContain("НДС");
|
expect(candidate.reply_text).toContain("НДС");
|
||||||
expect(candidate.reply_text).toContain("долги");
|
expect(candidate.reply_text).toContain("долги");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue