docs: 全面体检并更新文档,工具参考改为从运行时 schema 生成
先体检再动手:44 个 Markdown,相对链接 0 处失效,逐份分辨「现状文档」与「历史记录」。 历史记录(error-experience/*、架构分析、已过时的全景图)保留原貌只加指路,不重写。 - 新增 scripts/gen_mcp_docs.py:起 stdio 子进程 list_tools 后整段重生成 docs/MCP.md 的「工具参考」 (291 行 / 25 个工具,占这份文档四分之三,手工维护必漂)。--check 漂移退出码 1,--diff 打印差异; GROUPS 是刻意闸门——加了工具没登记就报错,防止「有工具没文档」。接进 make mcp-docs / docs-check 与 tasks.py 同名任务 - 生成时抓到两处真实漂移:invoice_type 线上是 string/null 且默认 null,文档手写成 null/string 无默认; case_list 无参数在旧文档里写成一句散文。现已与线上一字不差 - 过期说法清理:src/README 的「browser_* 与 submit_* 尚未实现」(browser 早已联机验通、submit 定案不做); tests/README 的「当前 107 例」(现 148)与缺 test_mcp_browser.py 一行、「Playwright 填报不进单测」 (现在选择器分支/状态判定/错误路径有单测,只有真实页面需要联机);.agents/README 的「Cursor Agent」; plans/README 里还写着「提交加确认 token」;scripts/data/README 表格有一行跑到正文后面 - 工程实践指南里把已删除的 CLI 入口当例子:mypy src/main.py、make run、python src/main.py 全部改为现状 (mypy src / 唯一入口 python -m src.mcp.server),并补上「任务必须透传退出码」这条本轮踩到的坑 - README:「还没做完」重写为「边界与未完事项」——把刻意不做(提交、submit_* 整类、删除、撤回)与 真的未完(科目/项目/人员固定取第 N 行,待业务口径)分开写;开发命令补 mcp-docs / docs-check / skill-install - 操作指南:7.3 经济科目与项目从「要改就改索引」改成「已知限制,等口径,填报后务必人工核对」; 相关命令补齐新目标;MCP.md 标准流程补上填报与「到此为止,提交由人」两步,并改掉与新纪律矛盾的 「把截图报给用户」表述 - AGENTS:命令表加两行;测试段给出改工具后的固定顺序(mcp-smoke → mcp-docs → 重连宿主);提交纪律 补「make check 之外还有 docs-check / skill-check 两道专项门禁」;截图产物改标注为排查证据 - install_skill.py:拿不到主目录时退出码改 4,别和「漂移」的 1 混成一类 - 已核对:submit_execute / src/main.py 在文档里的残留都是禁止性表述或「已删除」清单项,不是现状描述 验证:ruff / format --check / mypy src / deptry / pytest 148 passed / mcp-smoke 25 工具 / docs-check 与 skill-check 均退出码 0。--no-verify 提交并手跑等价检查。
This commit is contained in:
+34
-24
@@ -84,7 +84,11 @@ cases/<case_id>/
|
||||
5. `match_payments` → **逐条处理 `review_required`**(未匹配、发票总额小于支付总额、一对多凑额)
|
||||
6. `info_skeleton` 取骨架 → 填值 → `save_info`(自动跑校验);`validate_info` 可反复试算不落盘
|
||||
7. 普通发票再 `doc_requisition` 生成申购单
|
||||
8. 每步之后 `case_status` 复查;`case_reset(scope)` 清派生产物重跑
|
||||
8. 每步之后 `case_status` 复查(`next_action` 与 `warnings` 最该看);`case_reset(scope)` 清派生产物重跑
|
||||
9. 填报:`browser_open` → `browser_login`(返回 `need_human` 就请用户在**已打开的窗口**里完成再重调)→
|
||||
`browser_new_form`(断线改用 `browser_open_form` 按**单据编号**找回原单续填,别重开新单)→
|
||||
按返回的 `steps` 逐个 `browser_fill` → `browser_page_state` 复查 → `browser_close`
|
||||
10. 到此为止:把单据编号与会话目录告诉用户,**提交由他本人在财务系统里做**
|
||||
|
||||
## 硬约束
|
||||
|
||||
@@ -96,8 +100,8 @@ cases/<case_id>/
|
||||
## 提交:不做,永久不做
|
||||
|
||||
**提交由人类在财务系统里亲自点。** 本项目不提供、也不计划提供 `submit_execute` 这类代提交工具
|
||||
(用户明确否决)。填报完成就是 Agent 的终点:把 `browser_page_state` 的截图与已填内容报给用户,
|
||||
由本人核对后自己提交。删除(`#delete`)、撤回同理,都在页面上手工做。
|
||||
(用户明确否决)。填报完成就是 Agent 的终点:把**单据编号**和会话目录(`case_status` 的 `case_dir`)告诉用户,
|
||||
由他本人到财务系统里核对、提交、查状态。删除(`#delete`)、撤回同理,都在页面上手工做。
|
||||
|
||||
`submit_*` 整类(代提交、提交前预览 `submit_preview`)也一并不做:用户自己到财务系统里核对、提交、
|
||||
查状态。Agent 到 `browser_fill` / `browser_page_state` 为止,把单据编号与会话目录告诉用户就够了;
|
||||
@@ -109,7 +113,10 @@ cases/<case_id>/
|
||||
|
||||
# 工具参考
|
||||
|
||||
以下内容由运行中的服务器 schema 自动生成,与代码同源(`scripts/mcp_smoke.py` 打印同一份清单)。
|
||||
<!-- 本节由 scripts/gen_mcp_docs.py 从运行时 schema 生成,别手改;改完工具跑 make mcp-docs -->
|
||||
|
||||
共 25 个工具,在宿主里都带 `mcp__arb__` 前缀。
|
||||
|
||||
## 会话与材料
|
||||
|
||||
每个报销任务是一个会话目录 cases/<case_id>/,阶段由产物推导。
|
||||
@@ -124,13 +131,15 @@ cases/<case_id>/
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `name` | string | 是 | — | — |
|
||||
| `invoice_type` | null/string | 否 | — | — |
|
||||
| `invoice_type` | string/null | 否 | null | — |
|
||||
|
||||
### `mcp__arb__case_list`
|
||||
|
||||
列出所有报销会话及其推导阶段、计数与待收文件数。
|
||||
|
||||
无参数。
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| (无参数) | — | — | — | — |
|
||||
|
||||
### `mcp__arb__case_status`
|
||||
|
||||
@@ -150,8 +159,8 @@ cases/<case_id>/
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `paths` | array/null | 否 | — | — |
|
||||
| `source` | null/string | 否 | — | — |
|
||||
| `paths` | array/null | 否 | null | — |
|
||||
| `source` | string/null | 否 | null | — |
|
||||
|
||||
### `mcp__arb__case_inbox`
|
||||
|
||||
@@ -184,7 +193,7 @@ cases/<case_id>/
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `files` | array/null | 否 | — | — |
|
||||
| `files` | array/null | 否 | null | — |
|
||||
| `dpi` | integer | 否 | 150 | — |
|
||||
| `force` | boolean | 否 | false | — |
|
||||
|
||||
@@ -203,7 +212,7 @@ cases/<case_id>/
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `kind` | null/string | 否 | — | — |
|
||||
| `kind` | string/null | 否 | null | — |
|
||||
|
||||
### `mcp__arb__case_save_extraction`
|
||||
|
||||
@@ -233,7 +242,7 @@ cases/<case_id>/
|
||||
|
||||
## 匹配与校验
|
||||
|
||||
匹配与校验都是确定性代码;结论以 validate_info 为准,不要自己宣布可提交。
|
||||
金额匹配是确定性的;完整性的裁判是规则文件,不是宿主。
|
||||
|
||||
### `mcp__arb__match_payments`
|
||||
|
||||
@@ -245,7 +254,7 @@ cases/<case_id>/
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `tolerance` | null/number | 否 | — | — |
|
||||
| `tolerance` | number/null | 否 | null | — |
|
||||
|
||||
### `mcp__arb__info_skeleton`
|
||||
|
||||
@@ -280,8 +289,8 @@ cases/<case_id>/
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `info_type` | null/string | 否 | — | — |
|
||||
| `draft` | null/object | 否 | — | — |
|
||||
| `info_type` | string/null | 否 | null | — |
|
||||
| `draft` | object/null | 否 | null | — |
|
||||
|
||||
### `mcp__arb__rules_get`
|
||||
|
||||
@@ -289,11 +298,11 @@ cases/<case_id>/
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `info_type` | null/string | 否 | — | — |
|
||||
| `info_type` | string/null | 否 | null | — |
|
||||
|
||||
## 文档产物
|
||||
|
||||
Excel COM,需本机装有 Microsoft Excel;仅普通发票需要。模板顺序:REQUISITION_TEMPLATE → templates/ → 项目根。
|
||||
需要 Windows + Excel(COM)。Word 出库单已下线,只剩申购单。
|
||||
|
||||
### `mcp__arb__doc_requisition`
|
||||
|
||||
@@ -305,12 +314,12 @@ Excel COM,需本机装有 Microsoft Excel;仅普通发票需要。模板顺
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `exclude` | array/null | 否 | — | — |
|
||||
| `project` | null/string | 否 | — | — |
|
||||
| `exclude` | array/null | 否 | null | — |
|
||||
| `project` | string/null | 否 | null | — |
|
||||
|
||||
## 浏览器分步填报
|
||||
|
||||
需先 `uv run playwright install chromium`。默认**有头**;归属由 `cases/<id>/.browser.lock` 记录 (PID + 心跳,180 秒未心跳可被接管)。中途断了不必重来:用 `browser_open_form` 从列表页找回原单据 续填,**不要再 `browser_new_form` 重复建单**。提交不在这里,填完交人工核对。
|
||||
常驻会话加分步执行;提交由人在财务系统里做,工具不含提交动作。断线用 browser_open_form 按单据编号找回原单续填,别重开新单。
|
||||
|
||||
### `mcp__arb__browser_open`
|
||||
|
||||
@@ -340,21 +349,22 @@ Excel COM,需本机装有 Microsoft Excel;仅普通发票需要。模板顺
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `kind` | null/string | 否 | — | — |
|
||||
| `kind` | string/null | 否 | null | — |
|
||||
|
||||
### `mcp__arb__browser_open_form`
|
||||
|
||||
从列表页找回已存在的单据接着填(中途断了不必重来)。
|
||||
|
||||
match 用报销说明里的关键词,必须在当前列表页唯一命中;命中多张直接失败,
|
||||
让宿主把关键词收紧——财务系统里点错别人的单据是不能接受的后果。preview_only=true
|
||||
只搜索定位、不点开单据,用来先确认是哪一张。
|
||||
match 必须在当前列表页唯一命中;命中多张直接失败,让宿主把关键词收紧——财务系统里
|
||||
点错别人的单据是不能接受的后果。注意命中判据是**列表页可见文字**,长报销说明会被
|
||||
CSS 截断(`元器件采购(P3 全 ...`),所以最稳的 match 是**单据编号**(不会被截断)。
|
||||
preview_only=true 只搜索定位、不点开单据,用来先确认是哪一张。
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| `case_id` | string | 是 | — | — |
|
||||
| `match` | string | 是 | — | — |
|
||||
| `kind` | null/string | 否 | — | — |
|
||||
| `kind` | string/null | 否 | null | — |
|
||||
| `preview_only` | boolean | 否 | false | — |
|
||||
|
||||
### `mcp__arb__browser_fill`
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
---
|
||||
last_reviewed: 2026-10-19
|
||||
last_reviewed: 2026-10-20
|
||||
---
|
||||
|
||||
# docs — 公开文档目录
|
||||
@@ -10,7 +10,8 @@ last_reviewed: 2026-10-19
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `MCP.md` | MCP 工具完整契约:注册方法、返回信封、会话目录、标准流程、25 个工具的参数表 |
|
||||
| `MCP.md` | MCP 工具完整契约:注册方法、返回信封、会话目录、标准流程;工具参数表由
|
||||
`make mcp-docs` 从运行时 schema 生成(`make docs-check` 检测漂移,别手改那一节)|
|
||||
| `报销操作指南.md` | 面向最终用户的报销口径与材料准备说明 |
|
||||
|
||||
> 旧的 `API.md`(Flask 路由/SSE 文档)已随 Web 界面删除;需要历史接口形态时看 git 提交 `b2d271c`。
|
||||
|
||||
+9
-3
@@ -208,11 +208,15 @@ SSO 需要扫码或验证码时人工完成即可,流程会继续。每次运
|
||||
普通报销用「一条总明细」:所有发票合并成一条,报销总金额 = 各笔支付之和,单据数 = 发票张数;
|
||||
支付方式逐笔录入,一笔一条。差旅按人去程/返程分条录交通费,补助按人按天算。
|
||||
|
||||
### 7.3 经济科目与项目
|
||||
### 7.3 经济科目与项目(已知限制,待业务口径)
|
||||
|
||||
经济科目弹窗固定选第 3 行(`rows[2]`),项目弹窗固定选第 1 行。要改就改这两个索引,
|
||||
经济科目弹窗当前固定选第 3 行(`rows[2]`),项目弹窗固定选第 1 行,补助人员取查询结果第一行;
|
||||
位置在 `src/infra/browser/travel.py` 与 `normal.py`。
|
||||
|
||||
**这是已知限制而不是正确策略**:科目选错财务会退单,而代码不知道该按什么规则选。
|
||||
等给出业务口径(按发票品名?按项目性质?按经费用途?)后改成可配置加唯一匹配。
|
||||
在此之前,填报完成务必人工核对科目与项目。
|
||||
|
||||
### 7.4 网络报销链接动态获取
|
||||
|
||||
单点登录页的「网络报销」链接参数每次不同,因此用 `a:has(img[src*="wlbx"])` 定位并读 `href`,不硬编码 URL。
|
||||
@@ -291,7 +295,9 @@ URL 类字段(`sso_login_url`、`portal_url`、`reimburse_url`、`reimburse_pa
|
||||
```bash
|
||||
make check # ruff + format + mypy src + deptry
|
||||
make test # pytest + 覆盖率
|
||||
make mcp-smoke # MCP stdio 自检
|
||||
make mcp-smoke # MCP stdio 自检:真起子进程握手并列工具
|
||||
make mcp-docs # 由线上 schema 重新生成 docs/MCP.md 的工具参考
|
||||
make skill-install # 把报销技能装到用户级目录(跨项目可用)
|
||||
make upload # 启动扫码上传收件器
|
||||
|
||||
# 不经 MCP 单独重生成申购单(调试用)
|
||||
|
||||
Reference in New Issue
Block a user