feat(android): extract structured purchase requirements

This commit is contained in:
QiuSW
2026-07-25 21:05:51 +08:00
parent c25d63c730
commit 32d5310000
22 changed files with 2014 additions and 32 deletions
+3 -3
View File
@@ -51,9 +51,9 @@
## 当前阶段与优先路径
当前已完成 Phase 0、T-101 和 T-102:Android 可运行、设备就绪、workflow、私有样本
导入、固定词搜索以及最多 5 个候选截图采集均已在真机验证。下一步是 T-103,使用
私有 ProbeTask 验证结构化需求提取,继续禁止订单提交和支付。
当前已完成 Phase 0、T-101 至 T-103:Android 可运行、设备就绪、workflow、私有样本
导入、固定词搜索、最多 5 个候选截图采集和结构化需求提取链路均已验证。下一步是
T-104,用同一需求 schema 评估候选并停在人工确认点,继续禁止订单提交和支付。
严格按以下顺序推进:
+4 -2
View File
@@ -102,7 +102,8 @@ T-004 已固定首版规则:推荐私有目录为被 Git 忽略的 `private-fi
- F-003/US-003/IX-004:App 点击“获取任务”后原子领取一条任务;重复点击或多请求
不得领取第二条或把同一任务分配两次。
- F-004/US-004/IX-006:解析结果包含搜索词、识别属性、预算、数量、置信度和警告;
原始输入保留,硬约束与输入一致。
原始输入保留,硬约束与输入一致。T-103 已实现版本化 schema、0.75 置信阈值、
冲突转人工以及 SKU/数量的本地确定性回填;当前样本未提供预算,因此预算保持空。
- F-005/US-004/IX-006:在已验证的拼多多版本上,App 能从任务进入搜索结果并检查
最多 5 个候选;无合理候选时明确结束而不是随意选择。
- F-006/US-005/IX-007:流程到达人工确认点后停止;MVP 任意路径都不能触发最终
@@ -142,7 +143,8 @@ T-004 已固定首版规则:推荐私有目录为被 Git 忽略的 `private-fi
样例和独立任务。
- OnePlus PKG110、Android 16/API 36、拼多多 8.17.0 的首页、搜索输入、结果页、
候选卡和详情返回已形成可复现基线;不同账号、类目和页面实验的差异仍是风险。
- VLM 厂商、模型、成本上限、数据留存地区和图片隐私规则待确认。
- VLM 需求提取的 provider-neutral 合约和 OpenAI 兼容适配器已实现;真实供应商、
模型、测试凭证、成本上限、数据留存地区和图片隐私规则仍待确认。
- 拼多多平台条款、自动化允许范围和账号风控需要业务方确认;项目不实现绕过措施。
- 后续若允许提交订单,必须先明确 SKU、收货地址、运费、优惠、发票、金额审批、
幂等和人工确认规则,并单独更新需求。
+4 -2
View File
@@ -25,10 +25,10 @@
| 图片/截图 | 后端受控本地文件目录,数据库存元数据 | MVP 已定 | 禁止把二进制直接塞入日志;生产再评估对象存储。 |
| 管理鉴权 | 单个种子管理账号 + 服务端会话 Cookie | MVP 已定 | 密码只保存哈希;完整 RBAC 为 V2。 |
| App 鉴权 | 采购员登录态 + 设备绑定令牌 | 目标已定,细节待实现 | 人员身份与设备身份分离;令牌只保存哈希。 |
| VLM 接入 | 应用内统一适配器,优先兼容 OpenAI 风格多模态接口 | 接口已定,供应商待定 | 模型输出必须符合本项目 JSON Schema。 |
| VLM 接入 | 应用内统一适配器,优先兼容 OpenAI 风格多模态接口 | 需求提取已实现,供应商待定 | T-103 使用严格 JSON Schema、单次调用预算和 2048 px 图片上限;GUI-Owl/MAI-UI 动作模型不具备需求提取能力。 |
| 通知 | MVP 不使用推送 | 已定 | 点击“获取任务”调用原子 claim API;V2 再评估厂商推送/WebSocket。 |
| 后端测试 | 标准库 `testing` + `httptest` | MVP 已定 | 覆盖状态机、权限、幂等、SQLite 事务和输入校验。 |
| Android 测试 | Gradle `test` + `kotlinx-coroutines-test` 1.7.3 + 真实设备 smoke | 候选探针已验证 | runner、页面分类、搜索和有界候选 Fake driver 已覆盖;OnePlus PKG110 + 拼多多 8.17.0 的 5 个截图及返回 smoke 成功。 |
| Android 测试 | Gradle `test` + `kotlinx-coroutines-test` 1.7.3 + 真实设备 smoke | 需求提取探针已验证 | 122 次测试覆盖 runner、页面分类、候选、VLM schema、端点策略与隐私;OnePlus PKG110 上完成私有 fixture + 本机 mock 的单次多模态请求 smoke。 |
| 部署 | 单机局域网 Go 服务;容器化后置 | MVP 已定 | Android 测试机必须能通过 HTTPS 或受控测试网络访问。 |
## Roubao 上游版本基线
@@ -68,6 +68,8 @@ Windows Debug 构建。上游无障碍分支落后于 `main` 的修复和 1.4.2
`04-architecture.md` 的领域边界重组。
- SQLite 只服务单实例验证;出现多服务实例、并发写或正式备份要求时迁移 PostgreSQL。
- VLM 厂商可替换,领域层只接收结构化请求和结果,不传播供应商 SDK 类型。
- 需求提取与通用 MobileAgent 分离;只有声明 `supportsRequirementExtraction` 的
OpenAI 兼容 provider 可以进入 T-103 链路。
- 拼多多自动化是独立工作流模块,不能耦合后端数据库实现或管理页面。
## 骨架选择记录
+28 -3
View File
@@ -94,16 +94,34 @@ evidence/ # 截图、步骤日志、脱敏和上传
只负责两类能力:
1. **需求提取**:图片 + 标题 + 描述 -> 搜索词、属性、置信度、警告。
1. **需求提取**:参考图 + 标题 + SKU -> 搜索词、类目、属性、置信度、警告。
2. **候选评估**:候选截图/文本 + 原始约束 -> 匹配项、缺失项、拒绝原因、建议分。
模型输出是不可信建议,必须通过 schema 和确定性校验:
- `quantity` 和 `max_budget` 使用原始任务值。
- `sku`、`quantity` 和 `max_budget` 使用原始任务值;数量和预算不进入模型 prompt。
- 价格未知、超预算或关键属性无法确认时不能判为可接受。
- 置信度低于配置阈值时进入人工处理,不自动扩大浏览范围。
- T-103 探针阈值为 `0.75`;低于阈值或标题/图片冲突时进入人工处理,不自动扩大
浏览范围。
- 模型不能返回点击坐标、状态迁移或“允许提交订单”等执行授权。
T-103 的模型响应只允许
`schema_version/search_query/category/attributes/confidence/warnings`。属性来源限定为
`TITLE/IMAGE/BOTH`;额外字段、无效 JSON、重复或越界属性、坐标/动作语义均视为无效
输出并转人工。最终领域结果再由确定性代码补回原 SKU、数量、空预算、人工复核原因和
`provider/model/prompt_version/reference_image_sha256`。
技术探针每次点击最多发出一次 VLM 请求,不沿用通用 Agent 的重试循环。该结构化
HTTP 客户端关闭连接自动重试、HTTP/HTTPS 重定向,整体调用超时为 75 秒;协程取消
会取消底层 HTTP call,成功响应正文上限为 64 KiB,非成功响应不读取正文。
远程 provider 只允许 HTTPS;HTTP 仅允许无 API Key 的 `localhost`、`127.0.0.1`
或 `::1` 本机 mock。端点不得包含 userinfo、query 或 fragment。标题和 SKU 在进入
prompt 前分别限制为 2048 和 512 个 UTF-8 字节。JPEG 在调用前复核媒体类型、20 MiB
上限、魔数和 SHA-256,按声明长度一次分配并精确读取,Android 解码后最长边限制为
2048 px。请求和响应正文、Base64、API Key 不写普通日志;加密密钥存储不可用且存在
密钥时拒绝调用。
## 三、核心数据流
### 3.1 技术探针
@@ -140,6 +158,8 @@ Debug 构建或测试装载。导入必须:
- 对缺失、重复、编码无法识别和字段格式未知返回结构化错误。
- 不把完整订单号、店铺名、原图路径写入普通日志。
- 仅在用户明确配置 VLM 后发送必要的标题、SKU 和参考图;不发送订单号或店铺名。
- `RequirementProbeSource` 只从固定 asset 根读取已导入任务和引用图片;随后立即进入
大小、JPEG 魔数和 SHA-256 复核,不接受任意 cache 或绝对路径。
实现边界:
@@ -186,6 +206,11 @@ T-102 在搜索结果后追加一个有界候选步骤:
受控 evidence 边界读取,不能让 VLM adapter 自行遍历 cache。Android 10/API 29 及
以下不能运行当前截图探针,应在预检时明确不支持,不使用媒体投影或 shell 绕过。
需求提取是独立探针,不启动拼多多,也不接入 `MobileAgent`。GUI-Owl 和 MAI-UI 输出
动作/坐标,明确不具备 `supportsRequirementExtraction` 能力。真实供应商未确认前,
普通测试只使用 Fake gateway;本机 OpenAI 兼容 mock 仅验证 Android 请求链路和隐私
边界,不作为真实模型效果证据。
### 3.2 MVP 业务闭环
```text
+13 -1
View File
@@ -51,10 +51,20 @@
- 输入明确区分原始事实、用户硬约束、页面观察和待推断字段。
- 输出只接受结构化 schema;解析失败不能回退到自由文本猜测。
- 数量、预算、允许平台和停止边界由确定性代码覆盖模型输出。
- SKU、数量、预算、允许平台和停止边界由确定性代码覆盖模型输出;数量和预算不进入
需求提取 prompt。
- 提示词、schema、模型名和阈值版本化并记录到 execution。
- 不向模型发送密码、token、支付信息或与候选判断无关的个人信息。
- 模型低置信度或前后结果冲突时转人工,不自动增加动作权限。
- 需求提取一次用户操作最多发出一次付费调用;重试必须由上层人员显式触发并另计预算。
- GUI-Owl、MAI-UI 等动作模型不能复用为需求提取 provider。
- 需求提取 provider 的远程端点必须使用 HTTPS;HTTP 只允许不携带 API Key 的本机
回环地址,且禁止 userinfo、query、fragment 和重定向。
- 结构化 VLM 调用必须禁用底层自动重试,协程取消必须取消 HTTP call;非成功响应
不读取正文,成功响应最多读取 64 KiB。
- 需求提取标题和 SKU 分别限制为 2048、512 个 UTF-8 字节,超过上限不得截断后发送。
- 图片进入 VLM 前必须校验媒体类型、字节上限、JPEG 魔数、SHA-256 和可解码尺寸,并
按声明长度一次分配精确读取、有界缩放;prompt、Base64 和原始响应不得写普通日志。
## 6. 后端与 API 规则
@@ -85,6 +95,8 @@
- 领域状态机、硬约束、错误码:单元测试。
- API 权限、事务、幂等、文件校验:集成测试。
- VLM adapter:固定 fixture/契约测试,不让普通测试依赖真实付费 API。
- VLM 隐私测试必须用 sentinel 断言订单号、店铺名、路径和数量不进入 provider
prompt,并断言一次 extractor 调用只调用 gateway 一次。
- 蝦皮文件导入:覆盖同名配对、缺图、重复图片、未知格式、非法数量和敏感日志检查。
- 私有 ProbeTask 只允许通过 `-PprobeFixturesDir` 注入 Debug APK;验证后必须再做
一次不带属性的普通构建,并确认 APK 不含 `assets/probe-fixtures/`。
+17 -1
View File
@@ -292,13 +292,29 @@ App 空闲或运行时上报设备状态;运行时任务续租使用任务专
{"name": "color", "value": "black", "source": "text"},
{"name": "capacity", "value": "about 20L", "source": "text"}
],
"sku": "BLACK-20L",
"quantity": 2,
"max_budget": "200.00",
"confidence": 0.86,
"warnings": []
"warnings": [],
"manual_review": {
"required": false,
"reasons": []
},
"provenance": {
"provider_id": "configured-provider",
"model": "configured-model",
"prompt_version": "requirement-extraction-v1",
"reference_image_sha256": "64-char-lowercase-hex"
}
}
```
`sku`、`quantity` 和 `max_budget` 必须来自原始任务,不能采用模型返回值。第一层
`ProbeTask` 尚无预算字段,因此 T-103 输出 `max_budget: null` 并追加
`MAX_BUDGET_NOT_PROVIDED` 警告。属性 `source` 的 API 表示使用小写
`title/image/both`;供应商响应在 adapter 内规范化后才进入此合约。
### `POST /api/v1/tasks/{task_id}/ai/evaluate-candidate`
```json
+16 -7
View File
@@ -5,8 +5,8 @@
## 当前快照
- 日期:2026-07-25
- 阶段:T-102 已完成;准备 T-103 VLM 需求提取
- Git:当前分支为 `main`;T-001 至 T-004、T-101 和 T-102 均已纳入 Git 历史
- 阶段:T-103 已完成;准备 T-104 候选评估与人工确认点
- Git:当前分支为 `main`;T-001 至 T-004、T-101 至 T-103 均已纳入 Git 历史
- 生产代码:`android-buyer/` 已接入 Roubao Android 源码
- Android:固定 `main@c8a6d7f03422eb01744b01f3ee77bf7757741f7e`;MIT 许可证已保留
- 后端:已决定使用 Go 1.23.0 + Gin 1.11.0;Go Blueprint v0.10.11 骨架尚未接入
@@ -14,10 +14,12 @@
Build Tools 34.0.0、Platform Tools/ADB 37.0.0;用户级 SDK 环境变量已设置
- Android Studio:未安装;`winget` 静默安装卡住后已终止,不阻塞命令行构建
- 测试:`lintDebug test assembleDebug` 成功;App 两个变体、task contract 和导入器
共执行 78 次测试,0 failure、0 error、0 skipped
共 20 份报告、122 次测试,0 failure、0 error、0 skipped
- Workflow:纯 Kotlin runner 已支持步骤 timeout、最多 3 次 retry、安全阻塞、
用户停止和单 runner 并发拒绝;T-102 已接入搜索加有界候选采集五步
- TaskSource:严格 CLI 已生成并验证真实私有 ProbeTask;默认 APK 不含私有 fixture
- VLM:需求提取 schema、0.75 阈值、冲突转人工、单次 OpenAI 兼容调用、安全端点
策略、字段/响应上限和 JPEG 校验/缩放已实现;SKU/数量由本地原值回填,预算保持空
- 测试设备:OnePlus PKG110,Android 16/API 36;肉包 `1.4.2 (7)`;拼多多
`8.17.0 (81700)`
- 设备就绪:肉包采购无障碍已启用并连接;拼多多首页、搜索输入、固定词结果页、
@@ -27,8 +29,8 @@
已用 CLI 真实导入并逐字段/图片哈希验证,生成物位于被忽略的 `.local/`
- 标准启动路径:`$env:RUN_START_COMMAND="1"; .\init.ps1`
- 标准验证路径:`.\init.ps1`
- 当前 blocker:VLM 供应商、模型、测试凭证、成本上限和数据留存尚未确认;当前只
支持单 SKU/JPEG;候选探针截图要求 Android 11/API 30+
- 当前 blocker:真实 VLM 供应商、模型、测试凭证、成本上限和数据留存尚未确认;
当前只支持单 SKU/JPEG;候选探针截图要求 Android 11/API 30+
## 当前目录
@@ -42,6 +44,7 @@
| `docs/tasks/T-004.md` | DONE | 私有蝦皮文本/JPEG 严格导入和 Debug TaskSource |
| `docs/tasks/T-101.md` | DONE | 固定脱敏词拼多多搜索和结果页真机验证 |
| `docs/tasks/T-102.md` | DONE | 最多 5 个候选详情截图、证据 manifest 和结果页返回 |
| `docs/tasks/T-103.md` | DONE | 私有任务需求 schema、硬约束、隐私边界和 VLM 适配器 |
| `deepseek总结.txt` | 已有 | 历史讨论摘要,不是正式需求权威 |
| `android-buyer/` | 已有 | Roubao `main` 固定 commit 的 Android 基线 |
| `android-buyer/task-contract/` | 已有 | Android/CLI 共享 ProbeTask 与 TaskSource |
@@ -51,9 +54,9 @@
## 任务摘要
- 已完成:T-001 至 T-004,以及 T-101、T-102。
- 已完成:T-001 至 T-004,以及 T-101 至 T-103。
- 正在进行:无。
- 下一个可领取任务:T-103 接入 VLM 需求提取。
- 下一个可领取任务:T-104 接入候选评估并停在人工确认点。
## 当前可运行内容
@@ -68,6 +71,12 @@ $env:RUN_START_COMMAND = "1"
固定词搜索和 5 个候选采集。默认首屏为候选探针,用户点击后五步全部完成,5 张
匿名 PNG 与 manifest 哈希一致并返回结果页;logcat 无崩溃或 ANR。
同日用显式私有 fixture 和一次性本机 OpenAI 兼容 mock 完成 T-103 Android smoke:
只发出 1 次 POST 和 1 张 JPEG data URL,请求不含订单/店铺字段或数量键;严格响应
进入 READY,UI 保留原 SKU/数量、空预算和警告。恢复无密钥 provider 后失败状态会
清空旧结果;设备原 API provider 设置已恢复。该 smoke 只证明集成与隐私边界,不
代表真实 VLM 提取质量;真实凭证调用未执行。
## 维护规则
发生以下变化时覆盖更新本文:
+147
View File
@@ -0,0 +1,147 @@
---
id: T-103
title: 接入 VLM 需求提取
phase: 1
deps:
- T-004
- T-101
status: DONE
created: 2026-07-25
context_ref: c25d63c
work_branch: main
write_paths:
- android-buyer/app/src/main/java/com/roubao/autopilot/MainActivity.kt
- android-buyer/app/src/main/java/com/roubao/autopilot/data/SettingsManager.kt
- android-buyer/app/src/main/java/com/roubao/autopilot/task/**
- 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/vlm/**
- docs/00-ai-start-here.md
- docs/02-requirements.md
- docs/03-tech-stack.md
- docs/04-architecture.md
- docs/05-coding-rules.md
- docs/api.md
- docs/current-state.md
- docs/tasks/T-103.md
- progress.md
---
## 问题 / 背景
T-004 已把本机私有蝦皮文本和 JPEG 严格导入为 `ProbeTask`,T-101 已证明固定搜索词
可以进入拼多多结果页,但业务工作流尚不能从标题、SKU、数量和参考图得到受约束的
搜索需求。T-103 只验证结构化需求提取,不让模型控制页面、不评估候选,也不提交订单。
## 关联需求与交互
- 功能:F-004 结构化需求提取、F-007 安全失败。
- 用户故事:US-004、US-006。
- 交互:Android“探针”页提供独立的需求提取入口,展示脱敏状态、SKU、数量、置信度、
警告和是否需要人工复核。
- 架构:`ProbeTask` -> 隐私映射 -> `RequirementExtractor` -> provider-neutral gateway
-> 严格 schema -> 确定性硬约束复核。
## 方案
1. 建立与供应商无关的需求提取输入、输出、错误码和 JSON schema。
2. VLM 请求只保留标题、SKU 和参考图;数量留在本地,订单号、店铺名及本机路径不
进入 prompt。
3. SKU、数量和预算只从原始任务产生;模型响应无权覆盖。当前 `ProbeTask` 没有预算,
输出固定为未知并产生警告。
4. 严格校验图片大小、媒体类型和 SHA-256;严格解析模型 JSON,拒绝额外字段、坐标、
动作授权和格式不明输出。
5. 置信度低于固定探针阈值或输出无效时进入人工复核,不扩大搜索或触发拼多多动作。
6. 普通测试使用 Fake gateway;真实调用只通过用户已配置且声明支持需求提取的
OpenAI 兼容供应商进行,每次用户操作最多发出一次模型调用。
## 验收要点
- [x] 私有样本标题、SKU、数量和 JPEG 可形成不含订单号、店铺名的 VLM 请求。
- [x] 有效模型响应可解析为版本化 schema。
- [x] SKU 和数量与原始 `ProbeTask` 完全一致,模型不能改写。
- [x] 未提供预算时不会由模型猜测,并产生结构化警告。
- [x] 低置信度、冲突、无效 JSON、额外动作字段和图片校验失败均安全转人工或明确失败。
- [x] API Key、原图 Base64、订单号、店铺名和模型原始响应不进入普通日志。
- [x] Fake gateway 测试覆盖成功、隐私、硬约束、低置信度和错误路径。
- [x] `lintDebug test assembleDebug` 通过,默认 APK 不含私有 fixture。
- [x] 设备无真实测试凭证;已记录外部 blocker,并用一次性本机 mock 验证真实 Android
请求链路,不把 mock 结果当成模型效果证据。
## 边界
- 不让 VLM 输出或执行坐标、点击、状态迁移、下单或支付动作。
- 不把候选截图交给模型;候选评估属于 T-104。
- 不引入新的供应商 SDK;沿用现有 OpenAI 兼容客户端。
- 不提交私有订单、图片、生成 fixture、API Key 或模型原始响应。
- 不把技术探针的端上密钥路径当作正式架构;正式密钥仍由后端保管。
## 执行记录
### 2026-07-25:任务开始
- 基于 T-102 提交 `c25d63c` 开始。
- 已确认现有 `VLMClient` 可复用 OpenAI 兼容多模态调用,但业务层缺少 schema、隐私
映射、确定性复核和低置信度处理。
- 当前外部 blocker 仍是供应商、模型、测试凭证、成本上限和数据留存未确认;先完成
provider-neutral 契约、Fake 测试和可配置真实探针,不使用默认付费调用。
### 2026-07-25:实现
- 新增 `RequirementExtractionInput/Result`、版本化最终 JSON、严格模型响应 parser 和
`RequirementExtractor`。模型只能返回搜索词、类目、带来源属性、置信度和警告;
额外字段、动作/坐标语义、格式或边界错误统一转人工。
- 隐私映射只把标题、SKU 和参考图交给 gateway。订单号、店铺名、相对路径和数量不
进入 prompt;SKU、数量、空预算和图片 SHA-256 由确定性代码组装。
- 固定探针阈值为 `0.75`;低于阈值以及图片歧义、标题/图片冲突或 SKU 不清晰均进入
人工复核,不触发拼多多动作。
- 新增 `predictStructuredOnce`,每次按钮操作最多调用 provider 一次;禁用连接自动
重试和 HTTP/HTTPS 重定向,协程取消会取消底层 call,调用上限 75 秒。HTTP 错误不
读取响应正文,成功响应上限 64 KiB。
- 远程端点只允许 HTTPS;无 API Key 的本机回环 HTTP 可用于受控 mock。标题和 SKU
分别限制为 2048、512 个 UTF-8 字节。JPEG 在调用前复核媒体类型、20 MiB 上限、
魔数、大小和 SHA-256,按声明长度精确读取,解码后最长边限制为 2048 px。
- `ApiProvider` 增加 `supportsRequirementExtraction`;GUI-Owl 和 MAI-UI 明确禁用。
加密凭证存储不可用时需求探针 fail closed。
- “采购验证探针”增加独立 VLM 入口和 IDLE/RUNNING/READY/MANUAL_REVIEW/FAILED/
STOPPED 状态;展示 schema 摘要,但不展示订单号、店铺名或图片路径。
### 2026-07-25:自动化验证
- `$env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk";`
`$env:ANDROID_SDK_ROOT=$env:ANDROID_HOME;`
`.\gradlew.bat lintDebug test assembleDebug --no-daemon` 成功。
- App Debug/Release、task contract 和导入器共 20 份报告、122 次测试,0 failure、
0 error、0 skipped;默认 Debug APK 中 `assets/probe-fixtures/` 条目数为 0。
- Fake gateway 覆盖有效 schema、订单/店铺/路径/数量不进入 prompt、单次调用、
原始 SKU/数量保持、空预算、0.75 阈值边界、冲突转人工、无效/动作字段、JPEG
魔数/哈希失败、输入长度、provider 失败、调用取消和安全端点策略。
- 静态检查确认需求链路没有记录 prompt、图片字节或原始响应,也没有可执行动作输出。
### 2026-07-25:真机集成 smoke
- OnePlus PKG110、Android 16/API 36、肉包 `1.4.2 (7)` 上显式注入 T-004 私有
fixture;设备未配置真实 API Key,直接点击时稳定显示“未配置模型”且不发网络请求。
- 为验证网络链路,临时选择自定义 provider,通过 `adb reverse` 连接一次性本机
OpenAI 兼容 mock。App 只发出 1 次 `/v1/chat/completions` POST,包含 1 张 JPEG
data URL;布尔审计确认 prompt 不含订单/店铺字段和数量键。
- mock 返回的严格 schema 以 `0.82` 置信度进入 READY;UI 显示类目、属性、原始
SKU/数量、空预算和 `MAX_BUDGET_NOT_PROVIDED`。截图/XML 和 mock 布尔审计位于
被忽略的 `.local/`,请求正文和图片未落盘。
- 最新 APK 再次 smoke 后,将 provider 恢复为无密钥的阿里云配置并重新触发;UI
显示“未配置模型”,此前 READY 的搜索词和类目不再存在,证明失败路径会清空旧结果。
- smoke 后已移除 `adb reverse`、停止本机 listener 并恢复设备原 API provider。
logcat 未写入订单号、店铺名、标题、SKU、prompt、Base64 或原始响应。
### 未验证范围
- 没有可用的真实 VLM 测试凭证,因此未验证任何供应商的真实提取质量、时延和费用。
- 真实供应商、模型、成本上限、数据留存地区和图片隐私规则仍是外部 blocker;启用
前必须由用户显式配置并确认,不得把本机 mock 结果计入 20 条业务试验。
## 后续
- T-104 读取 T-102 的受控候选证据和本任务的 `RequirementExtraction`,输出匹配项、
缺失项和拒绝原因,并停在人工确认点。
- T-104 继续使用 Fake gateway 和本机 mock 验证集成;没有真实凭证时不能宣称候选
匹配质量已验证。