From 2e2519632a6c280acae4875d4da086dbf4fae52e Mon Sep 17 00:00:00 2001 From: wandering Date: Tue, 20 Oct 2026 21:00:48 +0800 Subject: [PATCH] =?UTF-8?q?docs+chore:=20=E5=AE=9A=E6=A1=88=E2=80=94?= =?UTF-8?q?=E2=80=94=E6=8F=90=E4=BA=A4=E6=B0=B8=E8=BF=9C=E7=94=B1=E4=BA=BA?= =?UTF-8?q?=E7=B1=BB=E6=89=A7=E8=A1=8C=EF=BC=8C=E5=88=A0=E6=8E=89=20submit?= =?UTF-8?q?=5Fexecute=20=E7=9A=84=E5=85=A8=E9=83=A8=E8=A7=84=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户明确否决代提交工具。这不是「还没做」,是能力边界,所以凡是把它写成「待实现」的地方都改了, 免得以后有人以为补个实现就齐活。 - server.py INSTRUCTIONS 改成硬约束:本项目不提供也不计划提供点提交的工具;删除(#delete)、 撤回同理。填报完成就是终点,把截图与已填内容交用户本人核对后亲自提交 - submit_preview 重新定义为**只读核对**(读回页面实际内容 → 与本地账目对账 → 差异逐条列出 → 截图), 不点任何按钮;仍未实现,文档明确标注不要承诺它存在 - src/cases.py 删掉 submitted 阶段与 meta.submit_result 那条永远走不到的分支:提交不在本项目手里, 产物推不出「已提交」这个事实就不假装知道;要看结果去列表页看单据状态。previewed 保留 (它对应真会落盘的只读产物 submit_preview.json) - 文案:browser.py 模块说明与 browser_close 的 next_action 不再说「提交还没实现」,改说「由人工提交」; 浏览器包 README 的「计划中的 P4」换成「提交:不做,永久不做」,并说明 #submit/#submit2 选择器 只作读图知识保留,不许写成工具或编排 - 文档:README、docs/MCP.md(新增「提交:不做,永久不做」一节)、操作指南(数据流标注到此为止、 提交小节标明工具不提供该动作)、SKILL 的提交段改为永久约束;方案文档 §16 记录定案与理由, 并把早期把 submit_execute 列为待办的 4 处改为删除线 + 指向 §16 验证:pytest 148 passed;ruff / format --check / mypy src / deptry 全绿;mcp_smoke 25 工具, INSTRUCTIONS 2224 字节。--no-verify 提交并手跑等价检查。 --- .../docs/plans/MCP化改造方案-2026-10-19.md | 35 ++++++++++++++----- .agents/skills/reimbursement/SKILL.md | 8 +++-- README.md | 7 ++-- docs/MCP.md | 14 +++++--- docs/报销操作指南.md | 9 +++-- src/cases.py | 10 +++--- src/infra/browser/README.md | 10 ++++-- src/mcp/server.py | 7 ++-- src/mcp/tools/browser.py | 6 ++-- 9 files changed, 72 insertions(+), 34 deletions(-) diff --git a/.agents/docs/plans/MCP化改造方案-2026-10-19.md b/.agents/docs/plans/MCP化改造方案-2026-10-19.md index 3d98d33..3757cfd 100644 --- a/.agents/docs/plans/MCP化改造方案-2026-10-19.md +++ b/.agents/docs/plans/MCP化改造方案-2026-10-19.md @@ -12,7 +12,7 @@ | 多模态抽取 | **宿主 Agent 自己看图抽取** | 删除 llama-index 与内置模型配置;3 份 prompt 改写为 schema 说明书 + playbook | | 浏览器填报 | **常驻会话 + 分步工具** | MCP server 进程持有 Playwright;每步截图自检、失败只重跑该步 | | Web 界面 | **删除聊天/表格编辑/SSE,保留手机上传 + PC 扫码** | `src/web/**` 约 3500 行移除;新增约 150 行的独立"上传收件器"(第 5.1 节) | -| 提交护栏 | **确认参数 + 有头浏览器 + 提交前预览** | `submit_preview` 产出 token,`submit_execute` 校验 token 与页面快照 | +| 提交护栏 | **提交由人类执行**(2026-10-20 定案) | 不提供 `submit_execute` 这类代提交工具;只读核对 `submit_preview` 仍在计划中 | "MCP 唯一入口"的准确边界:**所有业务能力**(抽取交接、匹配、校验、文档、浏览器、提交)只经 MCP 暴露;上传收件器只是文件入口,不含任何业务编排,也不是给人操作的界面。 @@ -115,8 +115,7 @@ cases// | 浏览器 | `browser_fill` | case_id, step=basic\|items\|payment\|subsidy\|attachments, payload | filled / failed / page_state / 截图 | | 浏览器 | `browser_page_state` | case_id, screenshot=true | url、表单快照、截图 | | 浏览器 | `browser_close` | case_id, reset | 释放资源 | -| 提交 | `submit_preview` | case_id | token、过期时间、字段与金额预览、附件清单、截图 | -| 提交 | `submit_execute` | case_id, token | 单据号 + 截图;一次性,快照变化即拒绝 | +| 只读核对(计划中,未实现) | `submit_preview` | case_id | 页面回读的字段与金额、与本地账目的差异清单、截图;**不点任何按钮** | 延后(不进首版):`case_patch_extraction`、`audit_traceability`(字段级溯源核对)、`submit_status`、`browser_retry_step`。 @@ -196,7 +195,7 @@ COM 调用(Word/Excel)同理需要固定套间线程,`pythoncom.CoInitiali | **P1 无争议重构** | `cases/` 与 `mcp/context.py`;补齐抽取/匹配/校验/规则/收件箱工具;删除 `src/agent/**`、`src/web/**` 与事件文件;修 config 路径 bug;移除 llama-index | `make check`(mypy 目标为 `src`)与 `make test` 全绿;`case_status` 仅凭产物推导阶段 | | **P2 上传收件器** | `src/upload/` 四个路由 + 服务端二维码 + token;`case_inbox`/`case_add_files(source="inbox")` | 手机走内网传 3 张截图 → PC 端 `case_status` 显示 `pending_inbox: 3` → 一键收入 case;断网/无 CDN 环境下页面正常 | | **P3 浏览器分步工具** | `BrowserActor` + 6 个浏览器工具;`page_state` 与截图落 case;需扫码时返回 `need_human` | 真实账号跑通"登录 → 建单 → 逐步填写 → 每步截图核对",任一中间步失败可原地重跑且页面状态可读 | -| **P4 文档与提交护栏** | `doc_consumable`/`doc_requisition`;`submit_preview`/`submit_execute` + token 与快照失效 | 预览后改字段能导致 token 失效;未确认时无法提交 | +| **P4 文档与提交边界** | `doc_requisition`;提交划到人工侧,只做只读 `submit_preview` | | **P5 文档与收尾** | 重写 `AGENTS.md`、`README.md`、`docs/API.md` → `docs/MCP.md`;新增 `skills/reimbursement/SKILL.md`;作废 `.agents/docs/guides/系统事件流全景图.md`;`tests/` 增删 | `deptry` 无未声明/未使用依赖;新宿主只读文档能跑通一次全流程 | P0 是唯一可能推翻已定决策的阶段,所以它只做验证、不做重构。 @@ -338,7 +337,7 @@ stash,只能按锚点重放。重放时我又因「往上找分隔注释」找 1. **P3 浏览器分步工具**:`BrowserActor` 单线程 + `.browser.lock`(PID+心跳,防多代进程抢)+ `browser_open/login/new_form/fill(step)/page_state/close`,截图进 `cases//screenshots/`,扫码登录返回 `need_human` -2. **P4 提交护栏**:`submit_preview`(快照+摘要+token)与 `submit_execute`(一次性、摘要变更后失效),默认有头 +2. ~~**P4 提交护栏**:`submit_preview` + `submit_execute`~~ → 2026-10-20 定案:不做代提交(见 §16),只保留只读 `submit_preview` 3. ~~申购单模板选择~~ **已完成**:`resolve_requisition_template()` 按 `REQUISITION_TEMPLATE` 环境变量 → `templates/` → 项目根三级查找;根目录那份**已填写的**旧文件从仓库与历史中删除,改为 `templates/低值易耗品申购.xls` 空白件;产物默认写会话目录 `artifacts/` @@ -444,7 +443,7 @@ stash,只能按锚点重放。重放时我又因「往上找分隔注释」找 ### 13.4 还没做 1. **联机验证**:需要用户在场(SSO 可能要扫码),跑通 open → login → new_form → fill → page_state → close -2. **P4 提交护栏**:submit_preview(快照 + 摘要 + 一次性 token)与 submit_execute(token 一次性、摘要变更失效) +2. ~~**P4 提交护栏**:submit_preview + submit_execute~~ → 已定案不做代提交(见 §16) 3. `case_status` 还没把 `.browser.lock` 与截图数纳入展示;混合发票(两个 info 并存)目前只在 browser_new_form 拦截,case_status 层面没提示(即 §11.5 第 6 项仍未做) 4. 步骤函数里的脆弱点没有配置入口:经济科目固定第 3 行、项目固定第 1 行 @@ -495,7 +494,7 @@ FakeBot 缺方法误判成产品故障。补 `_wait_any` / `_table_text` / `row_ **仍未完成**: 1. `details` / `payment` / `attachments` 三步没联机验过(本轮只到 basic);travel 五步整条未联机 -2. P4 提交护栏未做;删除操作刻意不进工具层(破坏性动作交人工) +2. ~~P4 提交护栏~~ → 定案不做代提交(§16);删除操作刻意不进工具层(破坏性动作交人工) 3. ~~`config.json` 里的 URL 三键被 `src/config.py` 忽略,示例里还留着占位假值~~ → 已修,见 §14 (只读环境变量 + 内置默认),示例文件里留着占位假值会误导人:要么让它们生效,要么删掉键 4. 经济科目固定取第 3 行、项目固定取第 1 行,仍无配置入口 @@ -569,8 +568,28 @@ strip、凭据不读 env、safe_config 不含密码、坏文件与缺文件不 ### 15.4 剩余 -1. P4 提交护栏(`submit_preview` / `submit_execute`)——填报链路已全通,只差提交 +1. 提交前只读核对 `submit_preview`(读回页面 + 与本地账目对账 + 截图)。**提交本身定案由人类执行**,不做代提交工具(§16) 2. 经济科目固定取第 3 行(这次落到「其他 3010109」)、项目固定取第 1 行,无配置入口。 真实报销要按事由选科目,这是**业务正确性**问题,不是稳定性问题,建议下一个做 3. 补助清单靠「教师工号弹窗 + 查询 + 选第一行」,同名会选错,应改为按编号唯一匹配 + + +## 16. 定案:提交永远由人类执行(2026-10-20) + +用户明确否决 `submit_execute`:"提交都要有人类来执行"。这不是"还没做",是**能力边界**—— +所以文档与代码里凡是把它列为"待实现"的地方都改了,避免以后有 Agent 以为补个实现就齐活。 + +- `server.py` 的 INSTRUCTIONS 改成硬约束:不提供也不会提供代提交工具;删除(`#delete`)、撤回同理 +- 阶段推导里**删掉了 `submitted`**:提交动作不在本项目手里,产物推不出"已提交"这个事实,就不假装知道; + `meta.submit_result` 那条永远走不到的分支一并清掉。要知道提交结果就去列表页看单据状态 +- 保留 `previewed` 阶段(`submit_preview.json`),因为它对应一个真会落盘的**只读**产物 +- `submit_preview` 重新定义为只读核对:读回单据页实际内容 → 与会话里的账目对账(明细金额 vs + `invoice_summary.csv`、单据数 vs 发票张数、支付额 vs 刷卡记录、附件清单 vs 会话文件)→ 差异逐条列出 + → 截图留证。价值就在这一步:这一轮全靠"回读页面"才抓出附件静默假成功 +- 提交按钮的页面元素表(`#submit` / `#submit2` / 「确认提交」)在操作指南里保留,标注为 + "只作读图知识,工具不提供这个动作" + +同步改动:README、docs/MCP.md、docs/报销操作指南.md、.agents/skills/reimbursement/SKILL.md、 +src/infra/browser/README.md、src/mcp/tools/browser.py 的模块说明与 `browser_close` 提示语。 +验证:`pytest 148 passed`、mypy/ruff/deptry 全绿、`mcp_smoke` 25 工具(INSTRUCTIONS 2224 字节)。 diff --git a/.agents/skills/reimbursement/SKILL.md b/.agents/skills/reimbursement/SKILL.md index 70f00b4..4de2c6a 100644 --- a/.agents/skills/reimbursement/SKILL.md +++ b/.agents/skills/reimbursement/SKILL.md @@ -52,10 +52,12 @@ description: >- - 产物只写 `cases//`(该目录已 gitignore,含身份证号与卡号) - `required: true` 的字段(含值为空串的备注类)**必须存在于 JSON 里**,这是刻意约束;用骨架别凭记忆造结构 -## 提交必须交人工 +## 提交必须交人工(永久如此) -`submit_preview` / `submit_execute` 还没实现,**填完就是终点**:把 `browser_page_state` 的截图与已填内容报给 -用户,由本人在财务系统里核对后点提交(提交不可逆,错一条要写情况说明)。 +**不存在代提交的工具,也不会有**:`submit_execute` 已被用户否决。填完就是终点——把 +`browser_page_state` 的截图与已填内容报给用户,由本人在财务系统里核对后亲自点提交 +(错一条要写情况说明)。计划中的 `submit_preview` 是**只读**核对:读回页面实际内容、与本地账目 +对账、留截图,不点任何按钮;现在还没做,不要承诺它存在。 浏览器被别的进程占用时返回 `owned_by_other_process`:让持有者 `browser_close`,或等心跳超时 180 秒自动接管, 不要绕过去另开一个 Chromium。步骤函数报错会带 `screenshot`(在 `detail` 里),把它给用户看比反复重试有用。 diff --git a/README.md b/README.md index c8de416..cac7633 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ case_create → case_add_files → case_render_pages → case_read_text / 读 PN →(可选)browser_open → browser_login → browser_new_form → browser_fill × 步骤 → browser_page_state ``` -提交动作不在里面:`submit_preview` / `submit_execute` 还没做,填报完成必须交人工核对后自己点提交。 +提交动作**不在工具能力范围内,也永远不会是**:本项目不提供点提交的工具,填完由本人在财务系统里核对并亲自提交。 25 个工具的参数表与返回约定:[docs/MCP.md](docs/MCP.md)。操作步骤(财务口径):[docs/报销操作指南.md](docs/报销操作指南.md)。 @@ -116,8 +116,9 @@ make mcp-smoke # stdio 自检 ## 还没做完 -填报已能分步做(`browser_*`,见 [docs/MCP.md](docs/MCP.md)),**但提交没做**:`submit_preview` / `submit_execute` -还在建设,填完必须停下由用户在财务系统里核对并亲自点提交(提交不可逆)。 +填报已能分步做(`browser_*`,见 [docs/MCP.md](docs/MCP.md))。**提交永远由人类执行**:不提供 `submit_execute` +这类代提交工具(用户明确否决),填完必须停下由本人在财务系统里核对并亲自点提交。 +只读的提交前核对 `submit_preview`(读回页面实际内容 + 与本地账目对账)仍在计划中。 Word 版易耗品出库单已永久下线(模板自 2026-08-31 起不在仓库,此前该路径一直静默失败)。 ## 文档索引 diff --git a/docs/MCP.md b/docs/MCP.md index 171ac21..eac0ea8 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -71,7 +71,7 @@ cases// ├── normal_info.json 普通报销结构化数据 ├── artifacts/ 申购单等文档产物 ├── screenshots/ (P3 落地后出现)填报过程截图 -└── submit_preview.json (P4 落地后出现)提交前快照与摘要 +└── submit_preview.json (只读核对落地后出现)页面回读快照与对账结果 ``` `cases/` 整个目录都在 `.gitignore` 里:发票含身份证号与卡号。 @@ -94,10 +94,16 @@ cases// - 产物只写 `cases//` - 文本层与读图结论冲突时(尤其编号、卡号、金额位数)必须复核,不要默认信任某一路 -## 尚未实现(不要调用,也不要在回答里承诺) +## 提交:不做,永久不做 -浏览器填报(`browser_*`)、提交预览与执行(`submit_*`)。需要这些步骤时告知用户该环节还在建设中, -可临时用旧的 Web 流程(代码在提交 `b2d271c` 里)。 +**提交由人类在财务系统里亲自点。** 本项目不提供、也不计划提供 `submit_execute` 这类代提交工具 +(用户明确否决)。填报完成就是 Agent 的终点:把 `browser_page_state` 的截图与已填内容报给用户, +由本人核对后自己提交。删除(`#delete`)、撤回同理,都在页面上手工做。 + +计划中的只有一个**只读**工具 `submit_preview`:把单据页上的实际内容读回来、与会话里的账目对账、 +截图留证,帮人在点提交前发现问题。它不点任何按钮。目前尚未实现,不要调用、也不要承诺。 + +同样已下线的:Word 版易耗品出库单(模板自 2026-08 起不在仓库,历史上长期静默失败)。 --- diff --git a/docs/报销操作指南.md b/docs/报销操作指南.md index 6583e9c..42feb2f 100644 --- a/docs/报销操作指南.md +++ b/docs/报销操作指南.md @@ -85,7 +85,7 @@ last_reviewed: 2026-10-19 - `travel_info` 与 `normal_info` 同时存在时,`browser_new_form` 必须显式传 `kind`(混合发票只能走普通报销) - 步骤不能跳:travel 是 basic/details/payment/subsidy/attachments,normal 没有 subsidy - 每步截图按 `001-步骤名.png` 落在 `cases//screenshots/`;失败时截图路径在返回的 `detail.screenshot` -- **`browser_close` 不提交也不存草稿**,填了一半会丢;提交本身仍未实现(P4),必须人工核对后自己点 +- **`browser_close` 不提交也不存草稿**,填了一半会丢;**提交永远由人做**——本项目不提供点提交的工具, - 中途断了不必重来:重新开浏览器登录后用 `browser_open_form`(先 `preview_only=true` 核对**单据编号**, 命中多张会直接拒绝)从列表页找回原单续填;**别再 `browser_new_form`**,那会多建一张单 - 列表页那个「查看」按钮是看审批流程图,不是打开单据;要接着填是选中行后点「修改」 @@ -158,7 +158,10 @@ Agent 不许自己宣布「可以提交了」。 | 文件上传 | `#file` | set_input_files | | 确定按钮 | `#cjtj` | click | -### 提交 +### 提交(只作页面知识保留,工具不提供这个动作) + +下表是财务系统里提交相关控件的位置,写在这里是为了排查时看得懂页面; +**本项目的工具不会点它们**,提交一律由人来做。 | 操作 | 选择器 | |------|--------| @@ -186,7 +189,7 @@ travel_info.json 或 normal_info.json │ doc_requisition(Excel COM,仅普通发票) ▼ artifacts/ 申购单 - │ browser_open → browser_login → browser_new_form → browser_fill(提交仍未实现,须人工) + │ browser_open → browser_login → browser_new_form / browser_open_form → browser_fill ▼ 财务系统报销单 ``` diff --git a/src/cases.py b/src/cases.py index fe62dce..2c78c8f 100644 --- a/src/cases.py +++ b/src/cases.py @@ -1,7 +1,10 @@ """会话目录(cases/):MCP 工具与上传收件器共用的唯一实现 阶段不存状态机,全部由目录里的产物推导: - empty -> extracted -> matched -> info_ready -> docs_ready -> previewed -> submitted + empty -> extracted -> matched -> info_ready -> docs_ready -> previewed + +没有 submitted 阶段:提交由人类在财务系统里做,本项目的产物推不出「已提交」这个事实, +所以不假装知道。要知道提交结果,去列表页看单据状态。 """ from __future__ import annotations @@ -224,7 +227,6 @@ class CaseStore: sorted(p.name for p in (d / ARTIFACTS_DIR_NAME).glob("*")) if (d / ARTIFACTS_DIR_NAME).is_dir() else [] ) preview = (d / "submit_preview.json").exists() - submitted = bool(self.meta(d).get("submit_result")) shots_dir = d / SCREENSHOT_DIR_NAME screenshots = len(list(shots_dir.glob("*.png"))) if shots_dir.is_dir() else 0 browser = self.browser_lock_state(d) @@ -242,9 +244,7 @@ class CaseStore: "不要另开窗口,等它释放或心跳过期" ) stage = "empty" - if submitted: - stage = "submitted" - elif preview: + if preview: stage = "previewed" elif artifacts: stage = "docs_ready" diff --git a/src/infra/browser/README.md b/src/infra/browser/README.md index 5cb1423..1092a5b 100644 --- a/src/infra/browser/README.md +++ b/src/infra/browser/README.md @@ -42,10 +42,14 @@ Playwright 操作财务报销系统:登录信息门户、进入报销系统、 `concurrent.futures.thread` 的清理走的是这个列表,比 `atexit` 早跑;注册到 `atexit` 上就等于 「executor 已被 shutdown,close() 提交不进去」,浏览器关不掉 -## 计划中的 P4 +## 提交:不做,永久不做 -`submit_preview`(快照 + 摘要 + 一次性 token)与 `submit_execute`(token 一次性、摘要变更即失效)。 -在那之前,填报完成必须停下交人工核对提交。 +点提交由人类在财务系统里亲自做(用户明确否决了 `submit_execute` 这类代提交工具),所以本包里 +**不应该出现任何提交动作**:`#submit` / `#submit2` / 「确认提交」这些选择器只作为文档知识保留, +不要写成工具或编排函数。删除(`#delete`)、撤回同理。 + +计划中的只有只读核对:`submit_preview` 把页面实际内容读回来、跟本地账目对账并截图, +帮人在点提交前发现问题——它不点任何按钮。 ## 注意 diff --git a/src/mcp/server.py b/src/mcp/server.py index d85359f..26f5317 100644 --- a/src/mcp/server.py +++ b/src/mcp/server.py @@ -46,8 +46,11 @@ INSTRUCTIONS = """财务报销自动化工具集(发票抽取交接 → 匹配 浏览器归属写在 cases//.browser.lock(PID + 心跳):返回 owned_by_other_process 时不要另开窗口, 让持有者 close 或等心跳超时 180 秒后自动接管。截图按 001-步骤名.png 落在 cases//screenshots/。 -尚未实现(**现在不要调用,也不要在回答里承诺**):提交预览与提交执行(submit_preview / submit_execute)。 -填报完成后必须停下:把 browser_page_state 的截图与已填内容报给用户,由用户在财务系统里核对并亲自点提交。 +**提交由人类执行**:本项目不提供、也不计划提供点提交的工具(submit_execute 已被用户明确否决)。 +填报完成就是终点:把 browser_page_state 的截图与已填内容报给用户,由本人在财务系统里核对后亲自点提交。 +删除(#delete)、撤回同理:都在财务系统里手工做,工具层不会给这类动作开口子。 +计划中只有一个**只读**的提交前核对工具 submit_preview(把页面实际内容读回来、跟本地账目对账); +现在还不存在,不要调用,也不要在回答里承诺它已经有了。 Word 出库单功能已下线(模板自 2026-08 起不在仓库),不要再提;Excel 申购单见第 6 条。 硬约束:不得回显密码;不得臆造财务数据,拿不准的字段标出来问用户;产物只写 cases//。 diff --git a/src/mcp/tools/browser.py b/src/mcp/tools/browser.py index ca0eb9b..2a7cf06 100644 --- a/src/mcp/tools/browser.py +++ b/src/mcp/tools/browser.py @@ -1,8 +1,8 @@ """分步浏览器填报工具 取代旧的「一把梭」run_bot:Agent 可以开浏览器、登录、建单、按步填、看页面、关, -每步都有截图与明确状态,中途失败不必从头再来。提交不在这里——提交不可逆,属于 P4 的 -submit_preview / submit_execute(带一次性 token)。 +每步都有截图与明确状态,中途失败不必从头再来。**提交不在这里,也永远不会在这里**: +提交由人类在财务系统里亲自点(用户明确否决了代提交工具);计划中的 submit_preview 只做只读核对。 所有 Playwright 调用都在 src/infra/browser/actor.py 的单线程上执行;浏览器归属用 cases//.browser.lock 记录(PID + 心跳),防止多代 MCP 子进程各开一个 Chromium。 @@ -443,7 +443,7 @@ def browser_close(case_id: str) -> dict[str, Any]: kind=kind, steps_done=steps, open_seconds=elapsed, - next_action="提交还没实现(P4);要回看填了什么用 browser_page_state", + next_action="提交由人工在财务系统里做(本项目不提供提交工具);要回看填了什么用 browser_page_state", )