Archived
M5 收官:六个活动包 + 统一报价全图 + 任务推进器
活动包(按 MVP示例工作流 归一化): - quote-intake A1 受理归一(flow):LLM 抽取 → 条件跳步补全 → 查历史价 → DMN 打标 → 验收 - quote-pricing A4 成本定价(flow):DMN 利润模型 P-01 + 底价门禁 P-02;超限条目调人决策 - quote-negotiate A6 报价议价(flow):写类动作登记意向、放行即落地;建 D+3 跟进监听; 议价结果建模为选择组三口(成交/有异议/拒绝)—— 业务分支走输出口,不用异常终态编码 - quote-archive A7 情报归档(flow):写共享域(历史价格情报/客户资料库/落地率统计) - quote-sourcing A3 渠道寻源(loop):CMMN 四阶段 + 里程碑 + 裁量项 + 两个时间监听; DMN 采用策略判定;案例说明书与 XML 同版本 - quote-alternative A2 替代选型(loop):CMMN 三阶段 + userEventListener(客户改需求); DMN 替代等级判定;禁区「差异没核清的不放行」有机检形态 流程包全图:7 节点 + 3 网关 + 1 审批点 - 已裁定①:A5 = 审批点,G3 并入驳回走向(驳回 → 回 A4 重开新实例) - 已裁定②:G2 = 并行网关,A3/A2 失败走向 = 容忍 - 已裁定④:议价回环 = 流程层回边(reopen) 闭合校验在此拦下一个真实建模错误(A4 有两条并发入边映射同名字段), 按规范改拓扑:TYPE-A 直通也走汇合;同时把「回边不是并发汇合」写进判定 —— reopen 边不参与隐式合并检查。 app:task-advancer worker —— 过程在后端,运行中的任务一拍一拍推,不依赖浏览器在线; 进入等待或终结即停手,不空转。第一方工具补齐 P-01/P-02/画像/落地率/出站发送。 已验证(真机): - 六个活动包经安装通道装入,静态审各 0 条提示 - 流程包闭合校验通过并发布 - 台账自生长:11 张表由活动声明物化(含 shared 三张共享域表) - 邮件入站 → 触发器 → 工作流 → A1 落到冯兵工位 → 推进器推 2 拍: 装载 5 步声明 → 执行 LLM 步 → 按声明重试 2 次 → 转人兜底 → awaiting-event (LLM 端点是占位 key,失败路径因此走通了 —— 正是声明给定的兜底) 358 个测试通过,门禁五道全绿 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
co-authored by
Claude Opus 5
parent
78dc03bb58
commit
2f01eda3fb
@@ -46,7 +46,72 @@ const classify: ToolHandler = async ({ input }) => {
|
||||
return { ok: false, error: { code: 'no-match', retryable: false, message: '三分类规则无命中行' } };
|
||||
};
|
||||
|
||||
/** 利润模型 P-01:品牌 × 类型 × 客户等级 × 数量档 → 目标毛利区间 */
|
||||
const P01_RULES = [
|
||||
{ id: 'p01-1', when: ['"战略客户"', '"A"', '"大批量"'], then: { marginLow: 0.08, marginHigh: 0.1 } },
|
||||
{ id: 'p01-2', when: ['"普通客户"', '"A"', '-'], then: { marginLow: 0.12, marginHigh: 0.15 } },
|
||||
{ id: 'p01-3', when: ['-', '"B"', '-'], then: { marginLow: 0.15, marginHigh: 0.2 } },
|
||||
{ id: 'p01-4', when: ['-', '"C"', '-'], then: { marginLow: 0.2, marginHigh: 0.5 } },
|
||||
{ id: 'p01-default', when: ['-', '-', '-'], then: { marginLow: 0.12, marginHigh: 0.15 } },
|
||||
] as const;
|
||||
|
||||
const margin: ToolHandler = async ({ input }) => {
|
||||
const values = [input['customerGrade'], input['materialType'], input['volumeTier']];
|
||||
for (const rule of P01_RULES) {
|
||||
if (rule.when.every((cell, i) => evaluateUnaryTest(cell, values[i], {}))) {
|
||||
const base = Number(input['basePrice'] ?? 0);
|
||||
return {
|
||||
ok: true,
|
||||
output: { ...rule.then, rule: rule.id, quotedPrice: Number((base * (1 + rule.then.marginLow)).toFixed(4)) },
|
||||
};
|
||||
}
|
||||
}
|
||||
return { ok: false, error: { code: 'no-match', retryable: false, message: '利润模型无命中行' } };
|
||||
};
|
||||
|
||||
/** 底价门禁 P-02:偏离底价 ±20% 即止 —— 结论是约束性输入,不可静默覆写 */
|
||||
const floorGate: ToolHandler = async ({ input }) => {
|
||||
const deviation = Number(input['deviation'] ?? 0);
|
||||
if (deviation >= 0) return { ok: true, output: { disposition: '直接放行', passable: true, rule: 'p02-1' } };
|
||||
if (deviation >= -0.2) return { ok: true, output: { disposition: 'PM 附理由放行', passable: true, rule: 'p02-2' } };
|
||||
return { ok: true, output: { disposition: '拦截 · BOSS 拍板', passable: false, rule: 'p02-3' } };
|
||||
};
|
||||
|
||||
/** 客户画像更新:把行为写成标签,供 P-01 的客户等级因子取用 */
|
||||
const profile: ToolHandler = async ({ input }) => {
|
||||
const reason = String(input['reason'] ?? '');
|
||||
const tags: string[] = [];
|
||||
if (/价|贵|低/.test(reason)) tags.push('价格敏感型');
|
||||
if (/快|急/.test(reason)) tags.push('快速决策型');
|
||||
if (tags.length === 0) tags.push('待观察');
|
||||
return { ok: true, output: { tags: tags.join('/') } };
|
||||
};
|
||||
|
||||
/** 落地率统计:放行通过的报价 ÷ 发出的报价 */
|
||||
const landingRate: ToolHandler = async ({ input }) => {
|
||||
const won = Number(input['won'] ?? 0);
|
||||
const total = Number(input['total'] ?? 0);
|
||||
return {
|
||||
ok: true,
|
||||
output: { landingRate: total === 0 ? 0 : Number((won / total).toFixed(4)), period: String(input['period'] ?? '') },
|
||||
};
|
||||
};
|
||||
|
||||
/** 出站发送 —— 写类:过程中登记为动作意向,放行后由系统执行落地(OS 7.3) */
|
||||
const mailSend: ToolHandler = async ({ input, connection }) => {
|
||||
// 运行时只拿得到申报过的连接目标;真发信由 channel 的出站面承担
|
||||
return {
|
||||
ok: true,
|
||||
output: { queued: true, to: String(input['to'] ?? ''), via: connection['endpoint'] ?? 'simulated' },
|
||||
};
|
||||
};
|
||||
|
||||
export const FIRST_PARTY_TOOLS: ReadonlyArray<readonly [string, ToolHandler]> = [
|
||||
['crm.history-price-read', historyPriceRead],
|
||||
['quote-intake.classify', classify],
|
||||
['quote-pricing.margin', margin],
|
||||
['quote-pricing.floor-gate', floorGate],
|
||||
['quote-archive.profile', profile],
|
||||
['quote-archive.landing-rate', landingRate],
|
||||
['mail.send', mailSend],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user