1
T-281
ila edited this page 2026-08-07 16:37:17 +08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

同步来源:docs/tasks/T-281.md · commit afc651f75a3a


id: T-281 title: 修复首轮规格 AI 兜底并记录可诊断证据 phase: 2 deps:

  • T-276
  • T-277
  • T-278 status: DONE created: 2026-08-03 context_ref: 5a6a2b8 work_branch: null write_paths:
  • docs/tasks/T-281.md
  • docs/current-state.md
  • docs/04-architecture.md
  • docs/05-coding-rules.md
  • android-buyer/app/src/main/**
  • android-buyer/app/src/test/**

问题 / 背景

任务 55e61d13-63ef-4673-b8dd-959c1d220339 的第一轮浏览了 4 个候选,规格模型 调用 3 次但 accepted=0、verified=0;其中 2 次被合并记为拒绝,另 1 次在整轮 200 秒超时时没有留下终态。规则侧读取到 6 条价格文本,但全部被归为 pricePrefix, priceParsed=0。第一轮没有形成候选后,第二轮按 T-276 契约关闭规格目标和模型,最终 回传的两个保底候选自然都是空 sku_text、空 price_text。

当前实现还存在三个可复现缺口:规则点击返回成功但复读没有选中时仍强制结束该规格; 完整规格组判定目标缺失时不经过模型;无价格上限任务仍因价格为空消耗最终模型调用。 模型网关失败、合同不符、低置信度、节点无效、页面过期和点击失败又都折叠为一个拒绝 计数,现有“记录”模块无法说明具体失败原因。

行为契约

  1. 第一轮继续先走确定性规则。规则点击后复读未选中、目标语义缺失或歧义时,必须在 当前规格弹层和同一候选内调用本机规格模型兜底;AI 只能返回当前节点 ID,App 复核 可见、启用、可点击及快照仍有效后才能单步点击。
  2. 确定性规则确认目标规格不可用时保持不可购买,不允许 AI 改选另一个相似规格;登录、 验证码、风控、订单确认和支付边界保持原安全停止优先级。
  3. 每次模型调用使用独立有界超时,并在取消时保留 TIMEOUT/CANCELLED 诊断;整轮超时 仍必须停止当前候选,不得延长到离线执行授权之外。
  4. 任务未设置 max_budget_cents 时,候选仍尽力读取页面价格,但价格为空或歧义不得单独 触发模型调用或阻止 SKU 匹配;有价格上限时保持组合价验证要求。
  5. 价格解析器允许一组固定的拼多多价格标签与唯一人民币金额组合,例如“拼单价¥19.9” 和“券后价¥19.9”;价格区间、“起”、划线原价、多金额和未知标签继续拒绝。模型仍只能 指向原始价格节点,最终金额必须由本地解析器计算。
  6. App 私有 SQLite 按 execution 保存采购运行摘要、规则判定、模型阶段、稳定拒绝码、 节点快照摘要/hash、模型合同响应摘要、点击复核及候选接受/拒绝结果,并在“记录”模块 可查看。最多保留最近 50 个采购 execution,每个 execution 最多 200 个事件。
  7. 本地诊断不得保存截图/Base64、API Key、Bearer token、Cookie、收货信息、完整任务 描述或任意 HTTP header。无效模型原文只保存 SHA-256 和长度;合法响应仅保存 schema 白名单字段。后台继续只接收有界聚合计数和稳定拒绝码分布,不上传节点 JSON。

方案

  1. 为 PinduoduoCandidateAutomation 增加 priceRequired 和规格诊断观察器;修正规则点击 后复核失败及完整组误判缺失的 VLM 分支,同时保持 disabled fail-closed。
  2. 为规格 VLM 引入稳定拒绝原因、单次超时和结构化 trace;解析器逐项返回合同、置信度、 节点、证据、价格等拒绝原因,不再只返回无信息的 Rejected。
  3. 扩展人民币价格解析器,仅规范化固定标签,继续拒绝范围、后缀和多个金额。
  4. 新增采购运行 SQLite journal,并把 journal 记录映射为既有 ExecutionRecord,与普通 Agent 记录合并展示、分别删除;候选搜索开始、规则/VLM 判定和终态均追加事件。
  5. 增加规则点击未生效后 AI 恢复、完整组语义误判后 AI 恢复、disabled 不点击、空价格 不消耗模型、固定价格标签解析、模型拒绝原因和 journal 保留策略测试。

验收要点

  • 规则点击返回成功但页面未选中时,AI 定位并点击目标后可通过双规格复核。
  • 规则把完整规格组判断为目标缺失时允许 AI 语义映射;disabled 规格仍不会被点击。
  • 空价格任务不会只因价格缺失调用模型;有预算任务仍要求可验证组合价。
  • 固定标签单金额可解析,区间、“起”、未知前缀和多金额保持拒绝。
  • 每次 AI 调用都有稳定终态或取消记录,记录模块可按采购 execution 查看规则、AI 和 候选摘要;敏感数据和截图不入库、不上传后台。
  • Android Debug/Release 单测、lint 和 APK 构建通过。

边界

  • 不修改第二轮只回传两个保底候选且不调用规格模型的 T-276 契约。
  • 不降低商品身份、人工确认、订单授权、提交围栏或支付边界。
  • 不把本机模型配置迁移到 Admin,不新增后端 VLM 代理。
  • 不在本任务执行真实下单或支付真机 smoke。

执行记录

  • 2026-08-03:根据真机任务第一轮模型零接受、价格前缀零解析和本地证据不足问题创建 任务,状态 TODO。
  • 2026-08-03:修正规则点击复核、完整组别名误判和无预算价格分支;模型调用增加 20 秒 超时、稳定拒绝码及脱敏 trace,后台事件只增加聚合原因分布。
  • 2026-08-03:新增 App 私有 SQLite 采购 journal,并合并到“记录”页面;保留上限为 50 次 execution、每次 200 个事件。
  • 2026-08-03:通过 :app:testDebugUnitTest、:app:testReleaseUnitTest、 :app:compileDebugAndroidTestKotlin、:app:lintDebug、:app:assembleDebug 和 :app:assembleRelease。Android 仪器测试已编译,未在本任务中执行真实下单 smoke。