diff --git a/T-276.-.md b/T-276.-.md new file mode 100644 index 0000000..1c9a3c7 --- /dev/null +++ b/T-276.-.md @@ -0,0 +1,86 @@ + +> 同步来源:[`docs/tasks/T-276.md`](/chengma/mroubao/src/commit/afc651f75a3abc2676bb13aa8a80f6aa6a25a72e/docs/tasks/T-276.md) · commit `afc651f75a3a` + +--- +id: T-276 +title: 将候选图片搜索收敛为两轮 +phase: 2 +deps: + - T-248 + - T-250 + - T-272 + - T-275 +status: DONE +created: 2026-08-01 +context_ref: 374bc6b +work_branch: null +write_paths: + - docs/tasks/T-276.md + - docs/current-state.md + - docs/04-architecture.md + - docs/05-coding-rules.md + - docs/api.md + - android-buyer/app/src/main/** + - android-buyer/app/src/test/** + - backend-api/internal/** +--- + +## 问题 / 背景 + +现有候选采集执行三轮图片搜索:前两轮执行相同的严格 SKU 匹配,第三轮再回传两个 +默认排序结果。第二轮没有提供新的召回策略,却重复导入参考图、等待结果页和浏览商品, +增加任务耗时与拼多多页面漂移概率。 + +目标是在不降低身份、安全和审计要求的前提下改为两轮:第一轮扩大检查样本,第二轮 +直接承担保底职责。 + +## 行为契约 + +1. 每个 execution 最多执行两轮图片搜索;第一轮最多打开并检查 6 个不同候选,第二轮 + 最多打开并检查 2 个不同候选。 +2. 第一轮继续执行颜色/尺码严格匹配并增量回传,最多保存 5 个可确认候选;达到目标后 + 不执行第二轮。 +3. 第一轮结束仍不足目标时执行第二轮。第二轮优先保留已验证匹配结果;最终不足目标时, + 可将默认排序前 2 个身份已解析商品作为 `FALLBACK` 回传。 +4. `FALLBACK` 只能来自第二轮,必须保留 `search_round=2`、`result_rank=1..2`,不得绕过 + 商品身份解析、证据、支付边界、登录、验证码或风控检查。 +5. 后端拒绝 `search_round>2`、第二轮以外的 `FALLBACK` 和超过两个保底候选;Admin、 + 事件和诊断统一显示两轮口径。 +6. 升级前已被后台接受的三轮候选仍可查看;新 App 不得继续执行第三轮,也不得改写既有 + 审计记录。尚未上传的旧第三轮 outbox 不按新契约伪装,须由任务重试入口创建新 execution。 + +## 方案 + +1. 将 Android 搜索计划从三个 attempt 改为两个明确阶段,并把每轮候选浏览上限固化为 + `6 / 2`;复用既有进度快照和幂等增量回传。 +2. 第二轮沿用当前第三轮保底实现,但将合法轮次、耗尽判定、恢复逻辑和诊断字段统一改为 2。 +3. 后端数据库保留历史 `search_round=3` 数据的读取能力,新提交接口只接受两轮规则; + 不依赖客户端自报字段放宽校验。 +4. 更新架构、API 和编码约束,增加 Android 与 Go 回归测试。 + +## 验收要点 + +- [x] 新 execution 最多两轮,第一轮最多检查 6 个、第二轮最多检查 2 个。 +- [x] 第一轮最多保存 5 个严格候选,达到目标后不启动第二轮。 +- [x] 第二轮可回传最多 2 个 `FALLBACK`,轮次和排序字段正确。 +- [x] 新请求的第三轮或非法保底候选被后端拒绝,历史三轮记录仍可读取。 +- [x] 重启恢复、增量回传、终态耗尽和诊断事件均使用两轮口径。 +- [x] Android 单测、Go 全量测试、lint 和 Debug/Release 构建通过。 + +## 边界 + +- 本任务不增加节点 JSON/LLM 解析,不改变规格选择算法或价格判断。 +- 不放宽 `goods_id`、证据、候选唯一性、人工确认、授权、下单和支付边界。 +- 不清理或迁移历史三轮候选审计数据。 + +## 执行记录 + +- 2026-08-01:根据两轮收敛方案创建任务,状态 `TODO`。 +- 2026-08-01:Android 搜索门禁改为两轮,第一轮预算为 6 次候选打开、4 次滚动和 + 100 秒浏览,最多保存 5 个严格候选;第二轮预算为 2 次候选打开、0 次滚动和 45 秒 + 浏览,最多保存 2 个保底候选。节奏设置同步收敛为两轮,并从旧第三轮保底超时设置 + 一次性读取兼容值;新设置保存两轮版本标记。 +- 2026-08-01:Android 证据、outbox 与 Go API 统一只接受新请求轮次 `1..2`;严格候选 + 固定第 1 轮、保底候选固定第 2 轮,累计最多 5 个且保底最多 2 个。历史数据库记录不做 + 迁移。Go 全量测试、Android Debug/Release 单测、`lintDebug`、`assembleDebug` 和 + `assembleRelease` 全部通过,状态改为 `DONE`。