7.5 KiB
| trio | trio-initialized |
|---|---|
| standard-v2 | 2026-06-08 |
铁路系统发票 · Agent 操作守则
上来先读这份,再看
INDEX.md找模块和导航。通用三件套协议见
../docs/trio-protocol.md(文档维护节奏 / Handoff 写入 / 子项目嵌套 / 记忆三条线边界 / 语言规则 / 跨项目反例)。本文件只列本项目专属守则。
trio: standard-v2= 本项目按当前标准维护三件套。
这是什么项目
铁路系统发票专项工作区,用于沉淀铁路系统相关发票资料、处理脚本、核对记录和衍生产出。
核心愿景(Core Vision)
最终目标:用户在 Web UI 上操作,脚本全自动完成开票、状态记录、结果文档输出。
技术路线:
- 截屏驱动:ADB 截屏 → 视觉 LLM(Qwen3-VL via SiliconFlow)识别页面元素、脱敏姓名、按钮位置
- 脚本编排:视觉 LLM 返回归一化 bbox(0-1000 坐标系)→ 脚本判断当前页面状态 → 决定下一步动作(tap / scroll / back)
- UI 配合:Web UI 负责触发、监控进度、展示结果;脚本在子进程中运行,通过 CSV 文件与 UI 交换状态
- 对话调试:James 和 Claude Code 通过实际运行观察手机行为,持续修正脚本的判断逻辑和边界条件
当前阶段:H5 扫码开票单页面自动化。页面结构:单个开票单下挂 N 个乘客(脱敏姓名 + 身份证类型 + 脱敏身份证号 + 「开具」按钮),需要逐人点击「开具」走完子流程,记录每个乘客的开票结果。
已完成的路径(保留不动):
- 原生列表页视觉驱动批量(
android-vision-page-run):截图 → list-rows 识行 → anchor 去重 → 点击 → 核验/发票管理子流程 - 原生列表页 XML 驱动(
android-page-run):uiautomator dump → 解析 XML → 匹配 text/bounds
上手三步
- 读
INDEX.md,看项目结构和子模块导航。 - 找到目标模块目录,先读它的本地文档(如
<module>/README.md或<module>/AGENTS.md若存在)。 - 看根目录或模块里有没有脚本入口、配置文件、环境变量样例。
项目专属硬规则
- 不要随手改
.env/ 凭证 /settings.json:敏感配置由项目所有者维护。 - 不要主动删除文件:废弃 / 旧版本 / 半成品请移动到
archive/或不加载/这类约定目录,不要rm。 - 不要重命名公共接口、路由、对外 API 字段:除非明确授权,这些是契约。
- 涉及发票、金额、税号、单位名称等字段时先保留原始值:规范化和清洗产物另存,不覆盖来源资料。
- 改动前确认是否有依赖你正在改的代码的其他模块:先
grep引用再下手。
目录命名约定
| 子目录 | 用途 |
|---|---|
data/ |
本项目自有数据与导入材料 |
scripts/ |
可执行脚本 |
src/ 或 lib/ |
主代码 |
tests/ |
测试 |
docs/ |
详细文档 |
assets/ |
静态素材 |
templates/ |
模板文件 |
archive/ 或 不加载/ |
归档区,不参与构建 |
项目专属"不要做的事"
- ❌ 删除文件(应该
mv到归档目录) - ❌ 自动提交 secrets / 凭证
- ❌ 覆盖原始发票资料或人工核对记录
- ❌ 未经确认修改发票字段含义、金额口径、税率口径
架构与关键依赖
本节是给 Claude Code 看的"big picture"。具体命令清单在
INDEX.md的"常用操作"段;详细用法在docs/usage.md。这里只写读多个文件才能拼出来的事。
四个脚本的分工
scripts/ 下没有 src/lib,所有逻辑都在四个独立 Python 文件里,彼此通过文件(CSV / 配置 / 截图)耦合,而不是 import:
| 脚本 | 角色 | 入口形式 |
|---|---|---|
invoice_tool.py |
主 CLI,~1700 行,argparse 多子命令。覆盖:台账 / 名单 / 邮件归集 / 网页辅助页 / Android ADB 自动化 / 视觉驱动批量。所有路径常量、run_adb、Config 都在这里 |
python3 scripts/invoice_tool.py <subcmd> |
web_ui.py |
本地 HTTP 服务(端口 8765),import invoice_tool 复用其常量和 run_adb,把批处理包成子进程跑;日常启动优先用稳定重启脚本 |
./scripts/restart_web_ui.sh(推荐)/ python3 scripts/web_ui.py(前台调试) |
vision_fallback.py |
视觉调用层:adb 截屏 → base64 → 调 SiliconFlow Qwen3-VL grounding API → 解析归一化 bbox | python3 scripts/vision_fallback.py {ping,detect-page,ask,list-rows} |
record_step.py |
录制工具:adb uiautomator dump + screencap 落盘到 work/replay/<session>/<NN_label>/,用于"人工演示 → 反推脚本" |
python3 scripts/record_step.py "label" [--new] [--list] |
web_ui.py 当前调用的是旧路径 android-page-run(XML/文字匹配),没有接 android-vision-page-run。如果改 Web UI 的"开始运行"按钮,注意切换的是 invoice_tool.py 的子命令名。
两条 Android 自动化路径并存
12306 App 是脱敏姓名(张*岩)+ 输入身份证后 8 位的开票流程。代码里有两套实现,都保留:
- 旧:
android-page-run/android-page-step— 走uiautomator dump读 XML,按 text / bounds 匹配。问题是 12306 列表页很多控件没有 text,全靠坐标。 - 新:
android-vision-page-run— 截屏交给 Qwen3-VL,模型返回归一化 bbox(0-1000 坐标系,不是像素),脚本再 denormalize 到屏幕像素后 tap。流程:截图 →vision_fallback.list-rows识所有可见行 → anchor 去重防滑动后重复 tap → 子流程(核验 / 发票管理 / 成功页)走旧的状态机。
配置与外部依赖
- ADB 路径硬编码:
invoice_tool.py:39写死/opt/homebrew/share/android-commandlinetools/platform-tools/adb(Apple Silicon Homebrew)。换机器或换 Intel Mac 要改这里。 config.local.json:除company_title / tax_id / receiver_email(config.example.json已示范)外,视觉路径还需要一个vision段:base_url/api_key/model(当前用 SiliconFlow +Qwen/Qwen3-VL-8B-Instruct,详见 memoryreference_siliconflow_qwen_vl.md)。vision_fallback.load_vision_config缺任一键直接抛错。config.local.json、work/、data/input|mail|attachments/、output/全在.gitignore里。
关键工作文件(都在 work/,CSV,UTF-8-BOM)
| 文件 | 内容 | 写入者 |
|---|---|---|
passenger_roster.csv |
名单:姓名 / 身份证号 / 后 8 位 / 来源 | import-roster |
invoice_tasks.csv |
开票码主台账 | import-codes |
android_invoice_progress.csv |
逐人处理结果(masked_name / real_name / id_last8 / status) | Android 子命令 + Web UI 读 |
android_page_queue.csv |
当前可见页的待点击队列 | android-build-page-queue |
replay/<session>/ |
record_step.py 的演示快照(ui.xml + screen.png + texts.txt + meta.json) | record_step.py |
CSV header 常量都集中在 invoice_tool.py 顶部(TASK_HEADERS / ROSTER_HEADERS / PROGRESS_HEADERS / PAGE_QUEUE_HEADERS)。改字段要同步改这里 + 所有读它的子命令。
测试
tests/ 当前是空目录。没有单测 / 集成测试框架;验证靠 --dry-run 子命令 + 真机跑 + work/replay/ 录制比对。新增功能不强求加测试,但如果改了 CSV schema 或 ADB 命令组合,至少跑一次 --dry-run --max-actions 1。