Files
cmroubao/docs/tasks/T-104.md
T

5.9 KiB
Raw Blame History

id, title, phase, deps, status, created, context_ref, work_branch, write_paths
id title phase deps status created context_ref work_branch write_paths
T-104 接入候选评估并停在人工确认点 1
T-102
T-103
DONE 2026-07-25 32d5310 main
android-buyer/app/src/main/java/com/roubao/autopilot/MainActivity.kt
android-buyer/app/src/main/java/com/roubao/autopilot/accessibility/**
android-buyer/app/src/main/java/com/roubao/autopilot/pinduoduo/**
android-buyer/app/src/main/java/com/roubao/autopilot/ui/screens/SearchProbeScreen.kt
android-buyer/app/src/main/java/com/roubao/autopilot/vlm/**
android-buyer/app/src/test/java/com/roubao/autopilot/pinduoduo/**
android-buyer/app/src/test/java/com/roubao/autopilot/vlm/**
docs/**
progress.md

问题 / 背景

T-102 已能有界采集最多 5 份匿名候选截图证据,T-103 已能从私有任务得到严格的结构化 需求,但两者尚未使用同一搜索词连接,候选也没有匹配项、缺失项和拒绝原因。T-104 只完成候选建议和人员确认闭环,不提交订单、不进入支付。

方案

  1. 需求提取成功后,候选探针使用该提取结果的搜索词;固定脱敏词仍保留给 T-101/T-102 独立回归。
  2. 只有搜索词与当前需求一致且 workflow 成功的候选证据可以评估。
  3. 受控 evidence source 按内存中的候选元数据读取匿名 PNG,复核数量、文件名、路径、 字节数、PNG 尺寸和 SHA-256;VLM adapter 不自行遍历 cache。
  4. 每次用户操作按 ordinal 串行评估,单个候选最多调用一次、全批最多 5 次;任一网络 失败或无效输出都会停止后续付费调用。
  5. 本地代码从有效评估中稳定产生建议项;预算缺失、低分、不确定或模型输出无效时保持 人工处理。无论模型输出如何,都不能产生页面动作或订单授权。
  6. UI 展示匹配项、缺失项、拒绝原因和建议项,并停在人工确认点;人员只能标记候选 可用或拒绝本次候选,结果始终记录 order_submitted=false。

验收要点

  • 候选搜索使用当前结构化需求的搜索词,旧搜索结果不能冒充当前任务证据。
  • 最多 5 份候选 PNG 经受控边界验证后才进入评估 gateway。
  • 模型请求不含订单号、店铺名、本机路径、数量或支付信息。
  • 严格 schema 输出每个候选的判断、分数、匹配项、缺失项和拒绝原因。
  • 缺候选、ordinal 不一致、额外字段、动作语义和证据篡改均安全失败或转人工。
  • UI 明确停在人工确认,不包含提交订单或支付动作。
  • Fake gateway、证据读取、动态搜索和人工确认状态均有自动化测试。
  • lintDebug test assembleDebug 通过,默认 APK 不含私有 fixture。
  • 无真实模型凭证时只用本机 mock 验证集成,不宣称真实匹配质量。

执行记录

2026-07-25:任务开始

  • 基于 T-103 提交 32d5310 开始。
  • 当前外部 blocker 仍是真实 VLM 供应商、凭证、费用、数据留存和模型效果;先完成 provider-neutral 契约、Fake 测试和本机 mock 集成。

2026-07-25:实现

  • 动态搜索使用当前 RequirementExtraction.searchQuery,同时绑定完整需求快照、 搜索词、成功 workflow 和本次候选 metadata;任一不一致都拒绝评估。
  • CandidateEvidenceSource 只按内存 allowlist 读取 candidate-01.png 等固定匿名 文件,复核规范路径、8 MiB 单图/32 MiB 总量、PNG/IHDR、尺寸和 SHA-256。
  • CandidateEvaluator 按 ordinal 串行调用,单候选一次、全批最多 5 次;无效输出、 provider 失败或取消立即停止后续调用,无效批次不保留先前自动建议。
  • 严格解析候选 ordinal、判断、分数、匹配项、缺失项、拒绝原因和置信度;拒绝额外 字段、数字字符串、坐标/动作/提交/支付语义,以及无预算时的价格匹配声明。
  • 推荐候选由本地按分数、置信度和 ordinal 稳定产生;人工接受必须对应实际存在的 REVIEW 建议项,批次和 UI 均固定 order_submitted=false。
  • UI 展示每个候选的评估理由、警告和人工操作,只提供“标记建议候选可用”和 “拒绝本次候选”,没有提交订单或支付控件。

2026-07-25:自动化验证

  • 执行 .\gradlew.bat :app:lintDebug test assembleDebug --no-daemon,构建与 lint 通过。
  • App Debug/Release、task contract 和导入器共 26 份报告、166 次测试,0 failure、 0 error、0 skipped。
  • 覆盖动态搜索、其他关键词结果页、受控证据路径/大小/PNG/尺寸/哈希、每候选调用 次数与停止规则、严格 schema、隐私字段、确定性推荐、人工确认和订单未提交状态。
  • 不带 probeFixturesDir 重建默认 Debug APK,assets/probe-fixtures/ 条目为 0。

2026-07-25:真机 smoke

  • 在 OnePlus PKG110、Android 16/API 36、拼多多 8.17.0 上,用私有 fixture 完成 动态搜索和 5/5 候选证据采集。
  • 一次性本机 OpenAI 兼容 mock 精确收到 5 次 POST,ordinal 为 1 至 5,每次只有 一张 JPEG data URL;订单、店铺、本机路径和数量字段命中均为 false。
  • 严格响应进入“等待人工确认”,5 个候选均可见;点击“标记建议候选可用”后显示 候选已由人员标记可用且订单未提交,页面没有提交或支付按钮。
  • 候选流程后的 logcat 中私有 sentinel、Base64、原始 mock 响应及 schema/prompt 命中均为 0;设备 provider 已恢复,ADB reverse 已移除。

未验证项

  • 未使用真实远程 VLM 凭证,不宣称真实商品匹配质量、成本或供应商可用性。
  • 当前证据是整页截图,尚无确定性商品标题和价格采集;第一层预算为空,因此任何 价格或预算匹配都转人工。

后续

  • T-201 建立 Go-Gin、SQLite 和迁移骨架。
  • T-202 生成并确认 P0 Web/App 低保真原型。