ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

pxpipe 成本 A/B 演示的定价引擎规格(SPEC.md)深度解读:orderTotalCents 四步计价流水线与银行家舍入规则

pxpipe 成本 A/B 演示的定价引擎规格(SPEC.md)深度解读:orderTotalCents 四步计价流水线与银行家舍入规则 【免费下载链接】pxpipecut Claude Code token usage by rendering text context as images项目地址https://gitcode.com/gh_mirrors/px/pxpipe点击查看免费下载orderTotalCents(items, tier)是 pxpipe 仓库demo/cost-ab/template/模板工程中一份故意埋错的定价函数规格它用一张四步计价流水线小计 → 阶梯量折扣 → 会员折扣 → 销售税和一条每一步都必须使用银行家舍入的硬性规则把金额精度约束到整数分。本指南完整解读 SPEC.md 的每一条规则结合 src/pricing.js、src/money.js 与 test/pricing.test.mjs 逐例验算并说明该规格在 pxpipe 成本 A/B 演示中承担精确任务回归测试的定位。读完你既能独立写出通过全部 5 个测试的正确实现也能理解为什么折扣键、计算顺序和舍入方式三者缺一不可。规格文档在项目中的定位一份可被精确复现的任务载体这份 SPEC.md 并不描述 pxpipe 的压缩管线而是demo/cost-ab/成本 A/B 演示使用的真实小项目template/的定价引擎规格。演示的目的在于让两个 Claude 会话在隔离工作副本里修复同一个失败的测试套件——一个走普通直通代理一个走 pxpipe 压缩代理——从而回答pxpipe 把文本上下文渲染成图片后是否仍然不破坏精确任务。正如 demo/cost-ab/README.md 所写这个任务同时充当一次召回recall测试修复的关键恰恰在于 SPEC 中容易被视觉化渲染丢失的细节——按总数量划分的量折扣、折扣之后才施加的会员折扣、以及银行家舍入。规格中不存在任何可以被模糊理解的口径五个测试断言的是精确到整数分的期望值如8316、9975、45181。这意味着 pxpipe 压缩后模型看到的规格图片必须被逐字符读准任何一位数字的偏差都会导致测试失败。函数契约与输入模型规格为orderTotalCents(items, tier)定义了如下契约返回值整数分integer cents的最终订单总额items行项目数组每个元素为{ cents, qty }——cents是整数分的单价qty是整数数量tier三选一的字符串NONE | SILVER | GOLD。所有货币都用整数分处理是 src/money.js 的基础约定其中formatCents(cents)将整数分格式化为美元字符串如2468 → $24.68。在真实应用里行项目来自 src/catalog.js 的 SKU 目录解析toLineItems(order)把[{ sku, qty }]解析为{ cents, qty }列表价格以整数分存储如SKU-COFFEE-250为 1299 分未知 SKU 直接抛错。四步计价流水线顺序是规格的第一等公民规格明确要求严格按照此顺序执行以下四步SPEC.md原文强调in exactly this order第 1 步小计Subtotal对所有行项目求和Subtotal Σ (cents × qty)。注意是逐行乘加不是先汇总数量再乘单价。第 2 步量折扣Volume discount折扣档位键控于所有行项目的总数量之和Σ qty而不是行项目条数也不是单行数量总数量折扣≥ 10020%≥ 5012%≥ 105% 100%从当前金额中减去roundHalfEven(subtotal × pct)。这是一个取最高命中档位的分段折扣档位不叠加——总数量 120 只享受 20%而不是 20%12%5% 累加。第 3 步会员折扣Loyalty discount会员折扣施加在量折扣之后的金额上而不是原始小计这一点与直觉相反且极易写错会员等级折扣GOLD3%SILVER1%NONE0%减去roundHalfEven(amount × pct)。第 4 步销售税Tax税率 8.25%在全部折扣之后的金额上计算tax roundHalfEven(amount × 0.0825)然后加回金额。返回的即税后总额整数分。整个流水线可以表达为import { roundHalfEven } from ./money.js; export function orderTotalCents(items, tier) { const subtotal items.reduce((sum, i) sum i.cents * i.qty, 0); // 第 2 步按总数量取最高档 const totalQty items.reduce((sum, i) sum i.qty, 0); const volumePct totalQty 100 ? 0.20 : totalQty 50 ? 0.12 : totalQty 10 ? 0.05 : 0; let amount subtotal - roundHalfEven(subtotal * volumePct); // 第 3 步会员折扣作用于折扣后金额 const loyaltyPct { GOLD: 0.03, SILVER: 0.01, NONE: 0 }[tier] ?? 0; amount - roundHalfEven(amount * loyaltyPct); // 第 4 步税作用于全部折扣之后 amount roundHalfEven(amount * 0.0825); return amount; }以上实现完全由 SPEC.md 推导即任务要求的目标形态。注意每一步都调用了roundHalfEven且后两步的基数都是上一步完成后的金额。舍入规则为什么Math.round会算错一分钱规格将舍入规则单列为 Rounding rule (important) 一节每一步货币舍入都必须使用 round-half-to-even银行家舍入从src/money.js导入roundHalfEven禁止使用Math.round。原因是Math.round是半进位half-up舍入遇到恰好.5的平局时向正无穷方向进一。而银行家舍入把平局舍入到最近的偶数整数。规格给出了关键反例税额16.5分必须舍入为16而不是 17。src/money.js 中roundHalfEven的真实实现印证了这一规则export function roundHalfEven(value) { const floor Math.floor(value); const frac value - floor; if (Math.abs(frac - 0.5) 1e-9) { return floor % 2 0 ? floor : floor 1; } return Math.round(value); }实现细节先取floor与小数部分当小数部分与0.5的差的绝对值小于1e-9时判定为恰好平局用 epsilon 容差规避浮点表示误差如0.1 0.4类运算的二进制误差此时若floor为偶数则取floor否则取floor 1非平局时退化为普通Math.round。注释中的断言给出了完整的行为矩阵roundHalfEven(16.5) 16、roundHalfEven(17.5) 18、roundHalfEven(16.4) 16、roundHalfEven(16.6) 17。与故意埋错的实现对照三个典型 bug 逐一拆解src/pricing.js 当前是错误的实现文件头注释明确声明这个实现有 bug不遵循 SPEC.md你的任务是修复它。它浓缩了三个最典型的规格误读export function orderTotalCents(items, tier) { const subtotal items.reduce((sum, i) sum i.cents * i.qty, 0); // BUG: discounts by number of line items, not total quantity; half-up rounding. const volume items.length 1 ? Math.round(subtotal * 0.05) : 0; // BUG: ignores the loyalty tier entirely, and taxes before discounts are final. const tax Math.round(subtotal * 0.0825); return subtotal - volume tax; }对照规格可以指出三处确凿的错误折扣键错误用items.length 1行项目条数判断是否打折而规格要求按所有行 qty 的总和分档且折扣率被硬编码为 5%丢失了 12%/20% 档位舍入错误两处都用了Math.roundhalf-up在.5平局时如测试用例 3 的税16.5分会多算 1 分结构错误完全忽略tier会员折扣从未施加且税直接算在原始小计上而不是全部折扣之后的金额上——量折扣与会员折扣的顺序关系也一并丢失。修复要点因此是三管齐下折扣键改按总数量、每步改用roundHalfEven、重建小计 → 量折扣 → 会员折扣 → 税的完整顺序。测试套件 test/pricing.test.mjs 的注释也点明了期望值的推导依据volume tier by total qty, loyalty on the post-volume amount, 8.25% tax last, bankers rounding at each money step。测试套件逐例验算5 个断言的完整演算测试运行零依赖package.json声明type: module与脚本test: node --test使用 Node 内置测试运行器node:testnode:assert/strict无需安装任何依赖即可执行node --test。五个用例的完整演算如下每一分钱都可复算用例 1no discount, plain[{cents:200, qty:12}],NONE小计 200×12 2400总数量 12 ≥ 10 → 5% 折扣roundHalfEven(2400×0.05)120折扣后 2280NONE 无会员折扣税roundHalfEven(2280×0.0825)188合计 2468✓用例 2volume 12% gold 3%[{cents:150, qty:60}],GOLD小计 150×60 9000总数量 60 ≥ 50 → 12% 折扣roundHalfEven(9000×0.12)1080折扣后 7920GOLD 3%roundHalfEven(7920×0.03)238→ 7682税roundHalfEven(7682×0.0825)634合计 8316✓用例 3banker rounding tie (tax 16.5 - 16)[{cents:200, qty:1}],NONE小计 200总数量 1 10 无折扣无会员折扣税roundHalfEven(200×0.0825)roundHalfEven(16.5)16平局取偶数合计 216✓ —— 若用Math.round会得到 217这正是规格强调的 tie 场景用例 4volume 5% then gold 3% (order matters)[{cents:1000, qty:10}],GOLD小计 10000总数量 10 ≥ 10 → 5% 折扣roundHalfEven(500)500→ 9500GOLD 3%roundHalfEven(9500×0.03)285→ 9215税roundHalfEven(9215×0.0825)760合计 9975✓ —— 注意若会员折扣误算在原始小计上结果会不同这就是顺序很重要用例 5multi-line, silver[{cents:999, qty:50}, {cents:50, qty:55}],SILVER小计 999×50 50×55 49950 2750 52700总数量 5055 105 ≥ 100 → 20%此处若误用items.length会得到 5%折扣roundHalfEven(52700×0.20)10540→ 42160SILVER 1%roundHalfEven(42160×0.01)422→ 41738税roundHalfEven(41738×0.0825)3443合计 45181✓五个期望值全部与实现对照一致任何一个环节折扣键、顺序、舍入出错都会使assert.equal失败。关联工程目录解析与完整文件清单模板工程结构清晰是理解规格落地的完整样例src/pricing.js —— 待修复的定价引擎当前有 bugsrc/money.js —— 货币工具roundHalfEven、formatCentssrc/catalog.js —— 产品目录与 SKU → 行项目解析15 个 SKU全部整数分定价SPEC.md —— 实现必须遵循的精确计价规则test/pricing.test.mjs —— 测试套件5 个用例node --test运行package.json —— 零依赖 ESM 工程npm test即node --test。验证命令只有一条template/README.md 中的任务说明node --test输出pass 5 / fail 0即修复完成。在 pxpipe 成本 A/B 演示中的角色用精确任务验证压缩不损精度template/被 setup.mjs 复制为/tmp/pp-demo-left与/tmp/pp-demo-right两个隔离工作副本每个副本写入独立的.claude/settings.json仅含模型、无 MCP并通过--setting-sources project --strict-mcp-config只读取项目配置从而排除全局配置的混杂变量。演示运行方式详见 demo/cost-ab/README.md# Terminal 1 —— 一次性准备构建、启动双代理、播种副本 bash demo/cost-ab/setup.sh # 默认模型Fable 5 bash demo/cost-ab/setup.sh opus # 或指定其他模型只在这里定一次 # Terminal 2 —— LEFT 普通 Claude经直通代理:47823同样被记录日志 bash demo/cost-ab/a.sh # Terminal 3 —— RIGHT pxpipe Claude经压缩代理:47824 bash demo/cost-ab/b.sh两臂的提示词都是同一句Read SPEC.md and the source, then fix src/pricing.js so it follows SPEC.md exactly and the test suite (node --test) passes见 a.sh 与 b.sh。两臂都经过代理因此两侧都被记录日志~/.pxpipe/ab-on.jsonl与~/.pxpipe/ab-off.jsonlpxpipe 臂还会把每次渲染的 PNG 转储到/tmp/ab-png供人工检查setup.sh 中PXPIPE_DUMP_DIR。值得注意的两个工程细节模型单一来源demo/models.sh 不硬编码任何模型名而是从产品自身的 src/core/applicability.tsDEFAULT_MODEL_BASES运行时导出为getConfiguredModelBases()读取模型列表再按唯一子串匹配解析——避免版本迭代后opus仍指向旧模型这类静默失效b.sh 的拒绝门demo_require_scope会在模型不在压缩作用域内时拒绝启动——因为此时 pxpipe 会原样透传而不压缩该臂看起来像 pxpipe 结果实际什么都没测。这保证了规格确实以图片形态而非文本被送入模型。结果以两个实时仪表盘呈现无需命令http://127.0.0.1:47824/显示 pxpipe 臂本次会话 N% 更少 tokenhttp://127.0.0.1:47823/显示直通对照臂约 0%证明方法本身不会凭空捏造节省也可用node eval/ab/savings.mjs在终端读取同样的数据。关于该任务的最终结论demo/README.md 记录了两列都通过了全部 5 个测试且拿到精确的期望整数——pxpipe 通过图片化的规格 源码完成了这一精度任务即压缩没有破坏精确任务。这正是把 SPEC.md 设计成整数分 银行家舍入 严格顺序这种不容含混的规格的意义所在。赞分享【免费下载链接】pxpipecut Claude Code token usage by rendering text context as images项目地址https://gitcode.com/gh_mirrors/px/pxpipe点击查看免费下载相关推荐SQLFluff 架构深度解析从模板引擎到规则修复的四阶段流水线SQLFluff 架构深度解析从模板引擎到规则修复的四阶段流水线 SQLFluff 是一款模块化的 SQL 静态检查器linter与自动格式化工具支持多代码质量Lint格式化静态分析开发工具终极指南在Windows上无缝运行Linux图形应用的完整解决方案终极指南在Windows上无缝运行Linux图形应用的完整解决方案 GWSLGraphical Windows Subsystem for Linux是一3步定制Terminal演示风格slides引擎渲染规则全解析3步定制Terminal演示风格slides引擎渲染规则全解析 你是否曾为终端演示缺乏个性而困扰slides作为Terminal based presentCLI开发工具上一篇NocoDB终极指南5分钟搭建你的可视化数据库平台下一篇DeepSeek Harness 命令行接缝精简parseCmdline 把应用校验与发布交还 commander 的 action 席位创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表