docs: record round-1 audit and open round-2 brief
Verified both round-1 briefs against the code rather than the progress notes. Billing 0/1/2/3/6 and rectification 0/1/2/3/6 are in and clean, and neither the confirmation gate nor the sealed holdout was loosened. Two gaps remain. Prompt caching only emits its marker for Anthropic, so on a DeepSeek-class provider it buys observability and no cost reduction, and the membership fair-use numbers are untouched — correctly so, since no real unit cost has been measured yet. The round-2 brief gates those on a staging measurement pass and pulls the per-answer narrowing table forward, since it is the deliverable and depends on nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
This commit is contained in:
@@ -112,3 +112,31 @@
|
||||
### 全量测试补充
|
||||
|
||||
`./node_modules/.bin/tsx --test tests/*.test.ts`:2369 passed,1 failed。唯一失败为既有的 `tests/staging-backend-workflows.test.ts` YAML 语法检查,失败原因是运行环境的 Python 缺少 `yaml` 模块(`ModuleNotFoundError: No module named 'yaml'`);本轮未修改 `.gitea/workflows/**`,因此不是本轮回归。该环境缺口未通过新增依赖绕过。
|
||||
|
||||
---
|
||||
|
||||
## 外部核对(2026-08-31,按代码逐条验证,不依据本文件自述)
|
||||
|
||||
| 任务 | 状态 | 验证依据 |
|
||||
| --- | --- | --- |
|
||||
| 0 用量成本聚合 | 已完成 | `frontend/src/app/api/admin/usage/aggregate/route.ts` |
|
||||
| 1 报告接计费 | 已完成 | `api/reports/route.ts:203` authorize;`lib/personal-report-worker.ts:211,219` complete / release |
|
||||
| 2 校正按功能定价 | 已完成 | `api/rectification/agent/route.ts:573` → `creditCost: pricing.credit_cost`,已脱离 `model.creditCost` |
|
||||
| 3 feature_pricing 可配置 | 已完成 | `supabase/migrations/20260831010000_feature_pricing.sql` + `admin/feature-pricing` |
|
||||
| 4 上下文缓存 | **部分完成** | 见下 |
|
||||
| 5 会员参数 | **仅语义** | 见下 |
|
||||
| 6 定价测算页 | 已完成 | `admin/pricing-simulator` + `lib/pricing-simulation.ts` + 单测 |
|
||||
|
||||
### 任务 4 的缺口
|
||||
|
||||
`lib/agent-generation-settings.ts` 的 `cachedSystemMessage()` 对非 Anthropic provider 直接返回 `null`。用量解析(`readTokens` / `writeTokens` / `hit`)覆盖了全部 provider,但**真正产生降本的缓存标记只对 Anthropic 生效**。
|
||||
|
||||
同一文件顶部注释与 `api/daily-starlanguage/route.ts:105`(`deepseek-v4-flash`)都指向 DeepSeek 系。若生产 provider 非 Anthropic,本任务目前交付的是**可观测性,不是降本**。会员「随便聊」档的毛利模型依赖这项降本,因此这是阻塞项。**下一轮任务 1 处理。**
|
||||
|
||||
### 任务 5 的缺口与判断
|
||||
|
||||
`product_entitlements` 的公平使用参数一个未改,仍为种子值:月卡 `billingLimit 2000`、年卡 `24000`、Pro 月卡 `5000`、Pro 年卡 `60000`(`20260806020000_billing_products_subscriptions.sql:146-155`)。
|
||||
|
||||
**这一保留是正确的**,符合任务书红线「不得凭估算改价」。缺的是上游输入:聚合端点已就绪但 staging 尚无真实单位成本数据。**这是流程阻塞,不是实现缺陷。下一轮任务 0 处理。**
|
||||
|
||||
同时记录一个尚未解决的商业事实:在参数未调整前,月卡按 `billingLimit` 打满的成本高于售价,「随便聊」档在上线前必须先完成任务 0 与任务 1。
|
||||
|
||||
@@ -96,3 +96,25 @@
|
||||
- 任务 6 已完成实现与本地强制门禁,等待精确提交。
|
||||
- 提交前及 push 前均重新同步并核对 `origin/staging`;若远端前进,只安全合并,不 reset/stash/clean。
|
||||
- 任务 6 将单独快进推送到 `staging`;不手动部署,不提升 `main`。
|
||||
|
||||
---
|
||||
|
||||
## 外部核对(2026-08-31,按代码逐条验证,不依据本文件自述)
|
||||
|
||||
| 任务 | 状态 | 验证依据 |
|
||||
| --- | --- | --- |
|
||||
| 0 上游手册与阈值 | 已完成 | `references/upstream/` 五份归档 |
|
||||
| 1 轮次预算 | 已完成 | `core/rectification-decision.ts:250` `budgetExhausted()`,:263 走 `"exhausted"` |
|
||||
| 2 问题槽 + 删清洗正则 | 已完成 | `v9/spoken-answer.ts` 已整文件删除,101 条正则不再存在 |
|
||||
| 3 停止话术契约 | 已完成 | `scripts/rectification/api_service.py:6,200,214,240` 已恢复并接出 `next_step_codes` |
|
||||
| 6 证据型停止语义 | 已完成 | `core/rectification-decision.ts:114` `evidenceStopReason()`,:148 参与判定 |
|
||||
| 4 标定数据入口 | 未开始 | — |
|
||||
| 5 清理与同步机制 | 未开始 | P2,按任务书本就应等任务 1–3 稳定两周 |
|
||||
| **7 逐条回答归因表** | **未开始** | **P0,且不依赖任何外部数据,应优先于 8/9/10** |
|
||||
| 8 质疑通道 | 未开始 | — |
|
||||
| 9 改窗口重跑 | 未开始 | — |
|
||||
| 10 首轮批量出题 | 未开始 | `src/mastra/agentic-rectification.ts` 中「一次一问」仍在 |
|
||||
|
||||
任务 1、2、3、6 的实现与任务书要求一致,未发现踩红线:`convergence-evaluator.ts` 未被改动,`confirmation-gate.ts` 的 blocker 未放宽,sealed holdout 阈值未动,本仓仍未被 1993 案例答案污染(全仓 `pl9_1993` / `target_minute` 无相关命中)。
|
||||
|
||||
未完成项转入 `TASK-round2-cost-and-delivery-20260831.md`。
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
# 任务书 · 第二轮:真实成本与交付物(2026-08-31)
|
||||
|
||||
基线:`origin/staging` @ `3a4396a4`。
|
||||
|
||||
**下面所有行号只是线索,请按选择器/函数名定位。**
|
||||
|
||||
## 为什么要做
|
||||
|
||||
前两份任务书(`TASK-billing-pricing-20260830.md`、`TASK-rectification-convergence-20260830.md`)已完成大部分实现。按代码逐条核对后,剩余缺口集中在两类:
|
||||
|
||||
**A 类 · 卡在缺真实数据,不是实现问题。** 计费任务 0 的聚合端点已就绪,但 staging 没有跑出真实单位成本,于是会员参数不敢动、缓存降幅无法验证、定价测算页只能显示估算。上一轮拒绝凭估算改参数是对的,**本轮负责把这个输入补上**。
|
||||
|
||||
**B 类 · 交付物本身还是空的。** 校正任务 7(逐条回答 → 区间收窄归因表)是 P0,且不依赖任何外部数据,但排在 8/9/10 后面一起没做。用户为一次校正付的钱,买的就是这张表。
|
||||
|
||||
还有一个上一轮遗留的阻塞项:**上下文缓存目前只对 Anthropic 生效**,若生产 provider 不是 Anthropic,则「随便聊」会员档的毛利模型不成立。
|
||||
|
||||
### 已完成,不要重做
|
||||
|
||||
计费任务 0/1/2/3/6,校正任务 0/1/2/3/6。核对依据见两份 PROGRESS 末尾的「外部核对(2026-08-31)」。
|
||||
|
||||
---
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. **任务 0 是门控。** 会员参数、售价、公平使用上限的任何调整,必须在任务 0 产出真实单位成本之后。**不得凭估算改数**——上一轮正确地拒绝了这件事,本轮不得倒退。
|
||||
2. **不得用生产用户数据做压测。** 任务 0 的数据采集用真实调用,但必须是可控账号,且不得为了凑数据而批量刷接口造成成本与容量浪费。
|
||||
3. **归因表的收窄贡献必须来自服务端打分,不得由模型叙述生成。** 一张看起来专业、实则模型编的归因表比没有更糟。
|
||||
4. **零贡献证据必须显式标注**,不得静默丢弃。这是诚实性的一部分。
|
||||
5. **禁止答案回流**(沿用上一轮红线 3):任何以已知答案调出来的规则不得进入生产打分链路。
|
||||
6. **上游同步必须过污染审查**(沿用上一轮红线 4):不得同步带 `pl9_1993`、`observed_*_case_only`、`target_minute` 标记的打分逻辑。
|
||||
7. **诚实性不可让渡**:不得放宽 `confirmation-gate.ts` 的 blocker,不得降低 sealed holdout 门槛。
|
||||
8. **不得修改既有测试断言** —— 除非该断言锁的正是本轮要改的缺陷本身;那种情况必须在断言上方注明原值与原因,并在 PROGRESS 单列。
|
||||
9. 推 staging 前必须 `./node_modules/.bin/tsc --noEmit` 通过。**不要用 `npx tsc`**,本仓库环境下会装到空包 `tsc@2.0.4`。
|
||||
10. **数据库测试必须真跑。** `npm run test:db` 需要 Docker。没有 Docker 就不要推 —— 写进 `BLOCKED.md` 并停下。
|
||||
11. 不得改 `.gitea/workflows/**`。不得在有未提交改动的工作树上切分支。不得自行把 staging 提升到 main。
|
||||
|
||||
让步顺序:**诚实性不回退 > 数据不损坏 > 功能与测试不回归 > 可验证的改进 > 成本 > 代码整洁**。
|
||||
|
||||
## 开工前置
|
||||
|
||||
```bash
|
||||
git fetch origin --prune
|
||||
git worktree add -b codex/round2-cost-delivery-20260831 \
|
||||
../.worktrees/round2-cost-delivery-20260831 origin/staging
|
||||
```
|
||||
|
||||
读 `pre_work_error_ledger.md`,跑 `scripts/pre_work_check.py`,读 `frontend/AGENTS.md`。改前在 `docs/BUG_HISTORY.md` 检索同类记录。
|
||||
|
||||
**先读这些:**
|
||||
|
||||
- 两份 PROGRESS 末尾的「外部核对(2026-08-31)」——本轮范围的依据
|
||||
- `frontend/src/app/api/admin/usage/aggregate/route.ts` —— 任务 0 的现成入口
|
||||
- `frontend/src/lib/agent-generation-settings.ts` —— `cachedSystemMessage()` 的 provider 分支
|
||||
- `frontend/src/lib/rectification-agentic/v9/evidence-model.ts` 与 `core/rectification-decision.ts` —— 任务 2 要接归因的地方
|
||||
- `references/upstream/1993-session-correction-rerun.txt` —— 归因表的目标形态就在这份记录里
|
||||
|
||||
---
|
||||
|
||||
## 任务 0(P0,门控)· 在 staging 采到真实单位成本
|
||||
|
||||
### 事实
|
||||
|
||||
计费任务 0 已交付聚合端点,但 `report.full` 从未有过真实行(上一轮才接上计费),`chat.standard` 与 `rectification` 也缺分叉后的新数据。没有这批数据,任务 3(会员参数)与任务 1 的降幅验证都无法进行。
|
||||
|
||||
### 要做什么
|
||||
|
||||
1. 把当前 staging 部署起来,确认 `/api/health` 的 SHA 与 `origin/staging` 一致,并在 PROGRESS 记录。
|
||||
2. 用可控账号跑出每类功能的真实调用,**每类至少 5 次、覆盖典型与偏长两种形态**:
|
||||
- `chat.standard`:含多领域计算的完整咨询
|
||||
- `rectification`:至少一个跑到证据停止或预算耗尽的完整 case
|
||||
- `report.full`:至少一份分章节完整生成
|
||||
3. 用聚合端点导出 per-feature 的 `runs / p50 / p95 / max` 的 `cost_microusd`、`input_tokens`、`output_tokens`、`duration_ms`,以及 `metadata.cache` 的命中情况。
|
||||
4. 结果写进 PROGRESS,形成一张表:**功能 → p50 成本 → p95 成本 → 缓存命中率**。
|
||||
|
||||
### 验收
|
||||
|
||||
- 三类功能各有不少于 5 条真实 `usage_ledger` 记录。
|
||||
- PROGRESS 里有上述表格,数值可复核到 request_id(脱敏,只列聚合值)。
|
||||
- 明确记录当前生产/staging 实际使用的 provider 与 model_id —— **任务 1 依赖这个结论**。
|
||||
|
||||
### 停止条件
|
||||
|
||||
若 staging 无法部署或无法产生真实调用,写进 `BLOCKED.md` 并停下。**任务 2 不受影响,可并行开工**;任务 1、3 必须等本任务。
|
||||
|
||||
---
|
||||
|
||||
## 任务 1(P0,依赖任务 0 的 provider 结论)· 让上下文缓存对生产 provider 真正生效
|
||||
|
||||
### 事实
|
||||
|
||||
`frontend/src/lib/agent-generation-settings.ts`:
|
||||
|
||||
```ts
|
||||
/** Adds only Anthropic's message-level cache marker; other providers keep current behavior. */
|
||||
export function cachedSystemMessage(content: string, model?: unknown) {
|
||||
if (modelProviderId(model) !== "anthropic") return null;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
用量解析覆盖全 provider,但缓存标记只对 Anthropic 下发。同文件顶部注释与 `api/daily-starlanguage/route.ts:105`(`deepseek-v4-flash`)都指向 DeepSeek 系。
|
||||
|
||||
会员「随便聊」档的毛利模型完全依赖这项降本,因此这是上线阻塞项。
|
||||
|
||||
### 要做什么
|
||||
|
||||
1. 按任务 0 确认的生产 provider,查清其上下文缓存契约——**以 provider 官方文档为准,不要凭记忆写**。要弄清:怎么声明、命中如何计价、最小可缓存长度、前缀稳定性要求。
|
||||
2. 为该 provider 实现缓存声明,保证 system + skill 前缀落在缓存边界内。校正的 system message 内嵌绑定 Skill 全文(`v9/agent-run.ts` 的 `bootstrap`),是最值得缓存的稳定前缀。
|
||||
3. 不支持缓存的 provider 保持现有行为,返回 `null`,不报错、不改变请求形状。
|
||||
4. **降幅必须实测**:用任务 0 的同一批 case 形态再跑一轮,对比 p50 `cost_microusd`。没有前后对比就不许在 PROGRESS 声称降本。
|
||||
|
||||
### 验收
|
||||
|
||||
- 生产 provider 的请求能在账本 `metadata.cache` 看到非零命中。
|
||||
- 对话与校正的 p50 `cost_microusd` 相对任务 0 基线有可测量下降,降幅写进 PROGRESS。
|
||||
- 非目标 provider 行为不变,既有测试全绿。
|
||||
|
||||
---
|
||||
|
||||
## 任务 2(P0,无依赖,可立即开工)· 逐条回答 → 区间收窄归因表
|
||||
|
||||
> 这是 `TASK-rectification-convergence-20260830.md` 的任务 7,原文保留有效,本节为可独立执行的展开。
|
||||
|
||||
### 事实
|
||||
|
||||
`references/upstream/1993-session-correction-rerun.txt` 里,整场真实会话最有价值的产物是用户主动索要的那张表:
|
||||
|
||||
| 你的回答 | 压缩后的分钟区间 | 作用 |
|
||||
| --- | --- | --- |
|
||||
| 2017 入职,岗位内容不合 | 14:48–14:50 | 很强的收窄点 |
|
||||
| 2023 末起量,一改风格就稳 | 14:48–14:50 | 最接近最终分钟的一条 |
|
||||
|
||||
本仓没有这个概念:`v9/evidence-model.ts` 与 `core/*.ts` 中不存在 `narrow` / `contribution` / `attribution` 语义,只有「这条证据支持哪个候选」,没有「这条回答把区间从 X 压到了 Y」。
|
||||
|
||||
同一份记录也证明了产品价值的真实边界:用户的 8 条生平锚点把窗口从 30 分钟压到 3 分钟,**收窄是真的**。归因表就是把这件事变得可见。
|
||||
|
||||
### 要做什么
|
||||
|
||||
1. 每次证据写入后记录**区间快照**:写入前宽度、写入后宽度、该条证据的归属贡献。**持久化**,不靠事后重算(重算会因候选集变化而不可复现)。沿用既有 receipt / SQL 函数模式,状态留在 Postgres。
|
||||
2. 报告(校正任务 3 的产物)新增归因表:用户原话(走 `display_date_label` 口径)→ 收窄前后区间 → 一句作用说明。
|
||||
3. 收窄贡献由服务端打分产出,**模型只做措辞**(红线 3)。
|
||||
4. 无贡献的证据也要列出并标注「未产生收窄」(红线 4)。
|
||||
5. 归因表要能回答用户那句真实提问:**「这个结论有多少来自我的回答?」** ——若最终区间主要由声明窗口或先验决定,必须说出来。
|
||||
|
||||
### 验收
|
||||
|
||||
- 报告含归因表,条目数等于已确认证据数。
|
||||
- 每条的收窄前后宽度与该轮实际候选集一致,可复核。
|
||||
- 零贡献证据被显式标注,不被静默丢弃。
|
||||
- 归因数据来自持久化快照,重开页面结果一致。
|
||||
|
||||
---
|
||||
|
||||
## 任务 3(P1,依赖任务 0 与任务 1)· 会员参数与售价重设
|
||||
|
||||
> 这是 `TASK-billing-pricing-20260830.md` 的任务 5,上一轮正确地保留未改,本轮在有数据后执行。
|
||||
|
||||
### 事实
|
||||
|
||||
`product_entitlements` 的公平使用参数仍为种子值(`20260806020000_billing_products_subscriptions.sql:146-155`):月卡 `billingLimit 2000`、年卡 `24000`、Pro 月卡 `5000`、Pro 年卡 `60000`。上一轮已完成语义澄清与文案约束,只差参数本身。
|
||||
|
||||
### 要做什么
|
||||
|
||||
1. 用任务 0 / 任务 1 的实测 p50、p95 成本重设 `minuteLimit` / `dayLimit` / `billingLimit`。**按 p95 定,不按均值**——公平使用要挡的是尾部。
|
||||
2. `billingLimit` 的定位是**熔断**,不是对用户承诺的配额;「随便聊」靠 `minuteLimit` + `dayLimit` 保护真人容量。语义已在上一轮写入 admin 文案,本轮只改数。
|
||||
3. 按产品已定规则,移除 standard 月卡/年卡的 `rectification` 与 `report.full` 权益(改为单独计费)。**移除前必须核查存量订阅依赖**,有在期会员依赖这些配额时给出兼容处理,不得让权益凭空消失。
|
||||
4. 售价(`billing_products.price_cents`)改动需产品确认后再执行,本任务只准备迁移,不擅自调价。
|
||||
5. 全部走幂等迁移或既有 `admin_save_product_draft` 审计路径,**不得手改生产库**。
|
||||
|
||||
### 验收
|
||||
|
||||
- 迁移幂等,`npm run db:migrate:check` 在隔离 Docker PostgreSQL 里 apply / check / reapply 三次退出码均为 0。
|
||||
- 新参数下,按 p95 成本估算的会员毛利写进 PROGRESS。
|
||||
- 存量订阅的兼容路径有明确记录。
|
||||
- 定价测算页读到新参数后,输出表与 PROGRESS 的数字一致。
|
||||
|
||||
---
|
||||
|
||||
## 任务 4(P1)· 「为什么是这个结论」的质疑通道
|
||||
|
||||
> `TASK-rectification-convergence-20260830.md` 的任务 8,原文有效。
|
||||
|
||||
真实会话里用户问「你是信息记忆联想了吗?还是靠印度占星专业技术推理出来的?」——这一问是全部真相的来源。本仓没有任何「为什么」入口(`v9/choice-card.ts` 的 `why` 是每个选项的说明,不是结论来源)。
|
||||
|
||||
内容全部来自服务端已有的 `claimCards` / `evidenceRefs` / `confirmation-gate` blocker,**不得由模型即兴生成**。与任务 2 的归因表共用同一份服务端数据,不要建第二套。
|
||||
|
||||
---
|
||||
|
||||
## 任务 5(P1)· 中途改窗口与保留证据重跑
|
||||
|
||||
> `TASK-rectification-convergence-20260830.md` 的任务 9,原文有效。
|
||||
|
||||
要点重申:同一 case 内重跑**不重复扣费**(沿用 `rectification:case:<caseId>` 幂等键);重跑必须留痕;新窗口与既有证据冲突时如实呈现,不得静默丢弃。
|
||||
|
||||
---
|
||||
|
||||
## 任务 6(P1)· 首轮批量出题
|
||||
|
||||
> `TASK-rectification-convergence-20260830.md` 的任务 10,原文有效。
|
||||
|
||||
`src/mastra/agentic-rectification.ts` 中「一次一问」仍在。上游手册的节奏是第 1 轮 3–5 道 A/B/C/D 一起出。批量轮在轮次预算里**记为一轮**。
|
||||
|
||||
---
|
||||
|
||||
## 建议执行顺序
|
||||
|
||||
1. **任务 2** —— 无依赖,交付物核心,立即开工
|
||||
2. **任务 0** —— 与任务 2 并行,它是任务 1、3 的输入
|
||||
3. **任务 1** —— 拿到 provider 结论后立即做,它是「随便聊」上线的阻塞项
|
||||
4. **任务 3** —— 有成本数据后执行
|
||||
5. 任务 4 / 5 / 6 —— 依次
|
||||
|
||||
## 交付
|
||||
|
||||
- PROGRESS 写进 `PROGRESS-round2-cost-delivery-20260831.md`,任务 0 的成本表与任务 1 的降幅对比单列。
|
||||
- 每个任务一个提交。
|
||||
- 推 staging 前:`./node_modules/.bin/tsc --noEmit` 通过、`npm run lint` 无新增 error、`npm run test:db` 在 Docker 下 fail=0、`npm run build` 通过。
|
||||
- 全量 `./node_modules/.bin/tsx --test tests/*.test.ts` 的失败清单与基线逐条比对,确认无新增。
|
||||
Reference in New Issue
Block a user