1725244faf
填报从「一把梭」变成分步:Agent 可以开浏览器、登录、建单、按步填、看页面、关,每步有截图, 中途失败不必从头重来。提交不在本步——提交不可逆,留给 P4 的 submit_preview/submit_execute。 - src/infra/browser/actor.py(新):Playwright 单线程 actor(sync API 的 greenlet 线程亲和要求所有 调用回到创建线程)+ 会话注册表 + cases/<id>/.browser.lock(PID/started_at/heartbeat/url, 心跳 180 秒过期才允许接管;锁文件损坏按无锁处理;atexit 尽力关浏览器)。与 COM actor 分开。 - base.py:login_portal 拆成 submit_login + wait_for_portal(返回布尔不抛异常),新增 portal_reached/ human_required;_screenshot 支持 screenshot_dir 并按 001-步骤名.png 编号、返回路径、失败只告警 - src/mcp/tools/browser.py(新):browser_open/login/new_form/fill/steps/page_state/close,工具 17 → 24 · need_human 用 ok:true + logged_in:false 返回(扫码不是失败,避免宿主当错误重试或另开窗口) · 步骤顺序硬约束,跳步拒绝并用 next_action 指回该补的一步;步骤报错回传 detail.screenshot · browser_close 明确不提交不存草稿;travel 五步、normal 四步(无 subsidy) - tests/test_mcp_browser.py(新,17 例,FakeBot/FakePage 不起浏览器):锁四种情形、need_human 分支与 截图落点、重复登录幂等、未打开时各工具拒绝、类型推断与两 info 并存时拒猜、未登录拒建单、跳步拦截、 步骤推进与 remaining、未知步骤、报错截图、close 释放会话与锁、open 复用、steps 两种流程 - 文档:docs/MCP.md 工具段按 wire schema 重生成(24 工具);AGENTS/SKILL/操作指南/README/浏览器 README 同步分步流程、锁与心跳、有头默认、提交必须交人工;方案文档 §13 记录实现、取舍与未完成项 验证: - 联机跑通 open(3.1s 起有头 Chromium)→ 锁写入(pid/heartbeat)→ page_state(about:blank, 001-state.png 4721 字节)→ 重复 open 复用(already_open=true,不多开窗)→ close(锁释放、注册表清空) - 登录与填报的联机验证需要用户在场(SSO 可能扫码),本轮未做 - 门禁:ruff / format --check / mypy src / deptry / pytest 129 passed / mcp_smoke 24 工具 instructions 2109 字节。仍用 --no-verify 提交并手跑等价检查(原因见 AGENTS 提交纪律)。
4.1 KiB
4.1 KiB
name, description
| name | description |
|---|---|
| reimbursement | 财务报销自动化(阜阳师范大学):把发票、支付截图、出差申请单变成结构化报销数据, 生成低值易耗品申购单,并在财务系统填报。当用户提到报销、发票、差旅费、公务卡刷卡记录、 易耗品申购、财务系统填报时使用本技能。通过 mcp__arb__* 工具操作,禁止臆造财务数据。 |
财务报销(MCP 工具版)
接口细节与参数表见 docs/MCP.md。本文件只写"怎么做才对"的操作纪律。
流程
mcp__arb__case_create建会话,记下case_id与upload_page(手机扫码上传入口,告诉用户)- 材料入库:本地文件用
case_add_files(paths=[...])(路径必须正斜杠D:/Code/...); 手机上传先落inbox/,再case_add_files(case_id, source="inbox")收取 case_render_pages:text_chars > 0就case_read_text读文本层(比读图准且省 token), 否则读pages/<stem>/p01.png。PDF 自动转正已处理,但转正角度要看 meta.json- 逐张出 JSON →
case_save_extraction。字段定义用extraction_spec,判读细则见references/invoice-fields.md match_payments:必须逐条处理review_required(未匹配、发票总额小于支付总额、 一对多凑额)。贪心结果ok不等于"已核对"info_skeleton(info_type)取骨架 → 填值 →save_info(自动跑规则校验)。 拿不准的字段用validate_info(draft=...)不落盘反复试;规则原文rules_get- 普通发票:
doc_requisition生成 Excel 申购单(exclude剔除不参与申购的物品) case_status复查态势;要重跑用case_reset(scope)- 填报:
browser_open(默认有头)→browser_login→browser_new_form→ 按它返回的steps顺序逐个browser_fill(step=...)→browser_page_state复查 →browser_close(不提交也不存草稿)。browser_login返回need_human时,让用户在已打开的那个窗口里完成扫码/验证码,然后重调browser_login;browser_new_form在 travel_info 与 normal_info 同时存在时必须显式传kind。
必须遵守
- 完整性不由你宣布:以
validate_info/save_info返回的校验报告为准;不完整就向用户要材料, 禁止说"可以提交了" - 不得臆造财务数据:金额、日期、发票号、卡号读不清就标出来问用户,不要猜
- 双通道冲突要复核:PDF 文本层与读图结论不一致时(尤其编号、卡号、金额位数),两条都不许默认采信,
重新放大该区域确认。已知文本层会把"标签"和"值"分段存储,且康熙部首类字符(
⽇⻔)NFKC 后仍不变形 - 不回显密码,不把凭据写进任何产物或日志
- 产物只写
cases/<case_id>/(该目录已 gitignore,含身份证号与卡号) required: true的字段(含值为空串的备注类)必须存在于 JSON 里,这是刻意约束;用骨架别凭记忆造结构
提交必须交人工
submit_preview / submit_execute 还没实现,填完就是终点:把 browser_page_state 的截图与已填内容报给
用户,由本人在财务系统里核对后点提交(提交不可逆,错一条要写情况说明)。
浏览器被别的进程占用时返回 owned_by_other_process:让持有者 browser_close,或等心跳超时 180 秒自动接管,
不要绕过去另开一个 Chromium。步骤函数报错会带 screenshot(在 detail 里),把它给用户看比反复重试有用。
参考
references/invoice-fields.md— 七类票据的字段判读细则(火车票/支付截图/酒店/普通发票/事前申请单/出入库单/其他附件)references/travel-info-fields.md— 差旅报销数据:交通/住宿/会议费、支付方式、按人按天的补助清单references/normal-info-fields.md— 普通报销数据:明细与支付方式.agents/docs/plans/MCP化改造方案-2026-10-19.md— 架构决策与实测记录(含抽取质量闸门数据)