所属 MVP:#275 | 来源:用户 2026-09-14 需求讨论(原话摘要见 #275)
Agent 收到图搜类采集任务后,用 PDD App 的拍照搜索找到商品并打开,然后接入现有的分享链接识别与采集链路完成任务。
#276(相册权限)。契约依赖 #278。
实施前必须在真机确认参考项目记录的选择器仍然有效,尤其 contentDescription == "拍照搜索"。失效则本工单方案需重写并重新确认。
contentDescription == "拍照搜索"
PinduoduoImageSearchAssetStore
IS_PENDING
拍照搜索
搜图片同款
PddShareLinkResolution
service/AgentStateStore.kt
TaskDispatchPolicy.decide()
else -> CHECK_COLLECTION
AgentForegroundService
Agent 端无新页面。失败文案属于显示文案,执行最小界面检查。
Android 单元测试(含调度回归、图片准备策略)+ .\scriptserify.ps1 -Component android + 真机执行。真机结论只在同一设备、同一 App 版本、同一规则快照下复用。
.\scriptserify.ps1 -Component android
cards=0
Agent 执行行为与错误码变化,需更新对应 Wiki 页面与 docs/08-agent-api-contract.md 中的错误码表。
docs/08-agent-api-contract.md
release/283
c80d0c9
main
c14f5f5
go build ./...
go test ./...
npm run build:prod
git log --oneline main..release/283 | grep "(#277)" -> 0 条
release/283 上 Android 侧改动合计 12 行,且全部属于 #276:
android/app/src/main/AndroidManifest.xml | 2 ++ android/app/src/main/java/.../MainActivity.kt | 10 ++++++++++
本工单方案中的七项没有任何一项存在:相册写图与清理、图搜入口点击、选图、结果页判据、打开第一个候选、TaskDispatchPolicy 调度垫底、失败文案。
TaskDispatchPolicy
这是本 MVP 的执行端。服务端已能创建任务、下发参考图元数据、在结果回传后自动建立关联(#278 #279 均已实现),但没有任何组件会去执行图搜,因此整条链路不可用,#275 无法进行集成验收。
#275 记录的前置门禁(在图搜页与结果页各 dump 一次无障碍树,核对 拍照搜索 等常量)至今未执行。本工单方案依赖这批常量,门禁未过之前不应开始实施。
状态维持待实施。
1d01186
be03972..1d01186
/home/goauto/releases/20260915-1d01186
65e404c4721d592a
systemctl is-active goauto.service
active
127.0.0.1:8010
collection_task
shopee_product
外部入口验证:
GET /
GET /api/admin/v1/collection-tasks
{"code":401,"msg":"cookie token is empty"}
POST /api/admin/v1/collection-tasks/image-search/batch
{"code":401,...}
最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。
回退方式:把 current 软链切回 20260914-be03972-r2 后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。
current
20260914-be03972-r2
提交:9e0dcc2、a487409、def0a86、a16e692、5126568、c30b8c4、95be6e7、c42e32d。
9e0dcc2
a487409
def0a86
a16e692
5126568
c30b8c4
95be6e7
c42e32d
automation/PinduoduoImageSearchAsset.kt
automation/PinduoduoImageSearchCriteria.kt
automation/PinduoduoImageSearchAutomation.kt
service/AgentForegroundService.kt
image_search
CurrentPageIdentityRunner
PddProductDetailCollector
finally
IMAGE_SEARCH_PERMISSION_REQUIRED
ASSET_INVALID
ASSET_NOT_LATEST
ENTRY_NOT_FOUND
NO_CANDIDATES
ui/TaskHistoryFragment.kt
原实现给 TaskDispatchPolicy.decide() 加了 hasImageSearchWaiting 参数与 CHECK_IMAGE_SEARCH 分支,但调用点始终只传两个参数,该分支不可达,且注释声称的优先级与代码顺序相反。
hasImageSearchWaiting
CHECK_IMAGE_SEARCH
[必须] 该排序在客户端无法实现:图搜任务是 source='image_search' 的普通采集任务,由同一个 /tasks/next 端点下发,Agent 调用时服务端已经选好了行。已移除死代码,改在 task.Service.Next 的两处 ORDER BY 实现,并保证来源降级排在 device_id 之后——指派设备是人的显式选择,必须继续优先。新增 image_search_priority_test.go 三个用例覆盖。
[必须]
source='image_search'
/tasks/next
task.Service.Next
ORDER BY
device_id
image_search_priority_test.go
2026-09-15 在真机(1080×2354)dump 无障碍树,三处判据全部命中,详见 #275 的核对记录与 docs/08-agent-api-contract.md。
发现并已修复一处会点错的缺陷:个人中心 tab 的根节点同样带 content-desc='拍照搜索',覆盖全屏且不可点,而 visibleTexts() 会把 contentDescription 当文本收集。原实现只按文案判 HOME,导致个人中心被判成首页,几何兜底随后点到该页顶部最靠右的可点节点——实测那是「设置」按钮。已收紧为:HOME 必须由可点入口证明;几何兜底必须先看到顶部搜索栏证据。
content-desc='拍照搜索'
visibleTexts()
contentDescription
Android testDebugUnitTest 与 assembleDebug 通过;新增调度回归、图片准备策略、页面判据、候选挑选、媒体最新判定的单测。
testDebugUnitTest
assembleDebug
SnapshotNode.path
MediaStore.Files
代码已上线,端到端真机执行未做,保持待验收。下一步是安装 debug APK 到真机跑一次完整图搜任务。
No dependencies set.
The note is not visible to the blocked user.
目标
Agent 收到图搜类采集任务后,用 PDD App 的拍照搜索找到商品并打开,然后接入现有的分享链接识别与采集链路完成任务。
前置依赖
#276(相册权限)。契约依赖 #278。
前置门禁
实施前必须在真机确认参考项目记录的选择器仍然有效,尤其
contentDescription == "拍照搜索"。失效则本工单方案需重写并重新确认。方案
PinduoduoImageSearchAssetStore的做法——写入 MediaStore(IS_PENDING先置 1 再置 0)、等待媒体库索引、校验 JPEG 头尾标记与 sha256、最小边不足 960 时放大、写入前清理自己的历史图片。拍照搜索入口;支持从商品详情、规格弹层、订单确认页、图搜结果页、"再试一次"弹窗归位(参考项目状态机,上限 50 次恢复动作)。搜图片同款+ 排序控件 ≥ 3;打开首个候选后接回现有PddShareLinkResolution/ 剪贴板路径取 goods_id,调用现有身份回填接口,之后完全走现有采集流程。service/AgentStateStore.kt的TaskDispatchPolicy.decide()在else -> CHECK_COLLECTION之前插入图搜分支,使优先级为 采购 > 采集 > 图搜。现有四条路径行为不得改变(需回归测试证明)。AgentForegroundService现有错误码到人话的映射表补充:图搜入口打不开、没有搜到相似商品、价格差异过大已跳过、需要相册权限。明确不做
设计证据
Agent 端无新页面。失败文案属于显示文案,执行最小界面检查。
验收
验证
Android 单元测试(含调度回归、图片准备策略)+
.\scriptserify.ps1 -Component android+ 真机执行。真机结论只在同一设备、同一 App 版本、同一规则快照下复用。风险
cards=0)。若本工单在同一处受阻,可能需要拆单。文档影响
Agent 执行行为与错误码变化,需更新对应 Wiki 页面与
docs/08-agent-api-contract.md中的错误码表。核对范围与方法(2026-09-15)
release/283@c80d0c9;基线main@c14f5f5。go build ./...、go test ./...(server)、npm run build:prod(web)、逐条对照工单验收项读取 diff。结论:未开始
release/283上 Android 侧改动合计 12 行,且全部属于 #276:本工单方案中的七项没有任何一项存在:相册写图与清理、图搜入口点击、选图、结果页判据、打开第一个候选、
TaskDispatchPolicy调度垫底、失败文案。影响
这是本 MVP 的执行端。服务端已能创建任务、下发参考图元数据、在结果回传后自动建立关联(#278 #279 均已实现),但没有任何组件会去执行图搜,因此整条链路不可用,#275 无法进行集成验收。
仍未完成的前置
#275 记录的前置门禁(在图搜页与结果页各 dump 一次无障碍树,核对
拍照搜索等常量)至今未执行。本工单方案依赖这批常量,门禁未过之前不应开始实施。状态维持待实施。
上线信息(共用)
1d01186,已推送be03972..1d01186到main。/home/goauto/releases/20260915-1d01186,二进制 SHA-256 前缀65e404c4721d592a(本地与服务器一致)。systemctl is-active goauto.service=active,监听127.0.0.1:8010。collection_task222 行、shopee_product26901 行,逐一相符。外部入口验证:
GET /GET /api/admin/v1/collection-tasks{"code":401,"msg":"cookie token is empty"}POST /api/admin/v1/collection-tasks/image-search/batch{"code":401,...}最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。
回退方式:把
current软链切回20260914-be03972-r2后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。实施
提交:
9e0dcc2、a487409、def0a86、a16e692、5126568、c30b8c4、95be6e7、c42e32d。已完成
automation/PinduoduoImageSearchAsset.kt:MediaStore 写图(IS_PENDING1→0)、750ms 索引等待、JPEG 头尾标记与 sha256 校验、最小边不足 960 放大、写入前清理历史图片、最新一项判定跨图片与视频比较。automation/PinduoduoImageSearchCriteria.kt:页面与网格判据纯函数,常量集中。automation/PinduoduoImageSearchAutomation.kt:归位状态机、候选挑选(跳过广告)、媒体最新判定。service/AgentForegroundService.kt:image_search分支接入完整链路,复用既有CurrentPageIdentityRunner与PddProductDetailCollector,finally中删除本次写入的图片。IMAGE_SEARCH_PERMISSION_REQUIRED/ASSET_INVALID/ASSET_NOT_LATEST/ENTRY_NOT_FOUND/NO_CANDIDATES。ui/TaskHistoryFragment.kt:采集列表行显示图搜来源标记(#279 附带项),未重构既有布尔分叉。调度垫底改由服务端实现
原实现给
TaskDispatchPolicy.decide()加了hasImageSearchWaiting参数与CHECK_IMAGE_SEARCH分支,但调用点始终只传两个参数,该分支不可达,且注释声称的优先级与代码顺序相反。[必须]该排序在客户端无法实现:图搜任务是source='image_search'的普通采集任务,由同一个/tasks/next端点下发,Agent 调用时服务端已经选好了行。已移除死代码,改在task.Service.Next的两处ORDER BY实现,并保证来源降级排在device_id之后——指派设备是人的显式选择,必须继续优先。新增image_search_priority_test.go三个用例覆盖。前置门禁:已完成
2026-09-15 在真机(1080×2354)dump 无障碍树,三处判据全部命中,详见 #275 的核对记录与
docs/08-agent-api-contract.md。发现并已修复一处会点错的缺陷:个人中心 tab 的根节点同样带
content-desc='拍照搜索',覆盖全屏且不可点,而visibleTexts()会把contentDescription当文本收集。原实现只按文案判 HOME,导致个人中心被判成首页,几何兜底随后点到该页顶部最靠右的可点节点——实测那是「设置」按钮。已收紧为:HOME 必须由可点入口证明;几何兜底必须先看到顶部搜索栏证据。验证
Android
testDebugUnitTest与assembleDebug通过;新增调度回归、图片准备策略、页面判据、候选挑选、媒体最新判定的单测。未验证(重要)
SnapshotNode.path语义推断)。MediaStore.Files改动后的跨 ROM 真实查询行为。状态
代码已上线,端到端真机执行未做,保持待验收。下一步是安装 debug APK 到真机跑一次完整图搜任务。