Files
market/agents/invoice-organizer/agent.json
Yige 42a29e99a0 feat(invoice-organizer): 新增发票整理助手 Agent / add Invoice Organizer agent (#117)
新增官方 inline Agent「发票整理助手」(`invoice-organizer`)。

Adds an official inline Agent, **Invoice Organizer**, that turns
invoices scattered across
mailboxes and local folders into a reconcilable, reusable ledger.

## 它做什么 / What it does

七步固定流程,每一步幂等:**接入检查 → 收集 → 解析 → 去重 → 归档 → 台账 → 报告**。

- **收集**:从已接入的邮箱(Gmail / Outlook / IMAP)找出候选发票邮件,附件用 `MailOperations` 的
  `save_to` 直接落盘,base64 不进模型上下文
- **解析**:OFD(三个结构化来源分别处理)、PDF 文字层、扫描件走视觉;每个字段带 `extractedBy` 与置信度
- **去重**:发票号码为主键,跨格式识别同一张票(PDF 与照片、重复下载);近重复不自动合并
- **归档**:`归档/年/月/YYYYMMDD_销售方_金额_发票号码.ext`,原件一个不动
- **台账**:xlsx 四张表(明细 / 月度汇总 / 按销售方汇总 / 异常),发票号码强制文本格式;
  装不上 openpyxl 时降级为 UTF-8 BOM CSV
- **报告**:Markdown 月度报告,收尾固定报五个计数(范围 / 候选 / 成功 / 待复核 / 失败)
- **自动化**:邮件规则 `agent_handle` + `ManageSchedule` 定时出账

## 明确的能力边界 / Explicit boundaries

- **不做发票真伪查验**,也不暗示做过——只做形式校验与勾稽校验,给出官方查验平台入口让用户自己核验
- **不删除、不移动、不转发用户的邮件**
- **票面内容不外流**:不外发、不代发、不上传第三方接口或在线查验站点
- **不做汇率换算**;不承诺「已找全」,只报「在给定范围内找到 N 封候选、成功解析 M 张」

## 结构 / Structure

```
agents/invoice-organizer/
├── agent.json  persona.md  principles.md  LICENSE
├── USAGE.zh-CN.md  USAGE.en-US.md
├── catalog-metadata.v1.json      # availability: listing-only(可安装化见下)
├── assets/avatar.webp
└── skills/
    ├── invoice-workflow/         # 七步总纲、目录布局、落盘顺序、去重主键、幂等
    ├── invoice-extract/          # 三种载体的解析细则、置信度分档、特殊票据
    │   └── references/票面文本形态.md
    ├── invoice-ledger/           # 台账结构、人民币约定(覆盖 xlsx 技能的默认口径)
    │   └── references/月度报告模板.md
    └── invoice-automation/       # 邮件规则与定时调度的参数模板与排查
```

`manifest.json` 的 `stats.totalAgents` 3 → 4。

## 事实性核对 / Fact-checking

技能里引用的**每一个**端点 / 工具名 / 参数名 / 返回字段都对着 DesireCore 主仓库实现逐条核对过,
并经过一轮对抗式 review。review 抓到的、已修正的主要事实错误:

- OFD 一节原本只覆盖 2020 年式样;已改为按**三个来源**分述
  (内嵌附件 / 2024 数电票的 `Tags/CustomTag.xml` 标引 / `DocInfo/CustomDatas`),
  键名从 `Buyer/BuyerName` 改为真实的点号路径 `Buyer.BuyerName`,置信度按来源分档
- **`DocInfo/CustomDatas` 的「合计金额」是不含税金额**,误当 `totalAmount` 会让每张 2024
数电票少记税额
  ——已写成硬规则
- Gmail 本地缓存搜索的 `q` **实际只按主题过滤**(正文过滤在主题收窄之后才跑),
  原文写成「搜主题与正文」会导致静默漏邮件
- 「轮询只覆盖收件箱」只对 IMAP 成立,Gmail / Outlook 是整个邮箱
- `POST /rules/{id}/test` 走另一份内联实现、**没有 `matches_regex` 分支**,
  不能用它验证正则规则
- 邮件列表项里 Gmail / IMAP **是带** `attachments[]` 的,只有 Outlook 不带;
  `labelIds` 是 Gmail 专有

## 真机验证 / Verified on a live instance

在 dev 实例上以一句话指令处理 31 个混合文件(数电票 / 旧版票 / OFD / 扫描件 / 行程单,
外加重复、近重复、作废、零额与 4 个非发票负样本):

- 23 张归档,字段与夹具 ground truth **逐条吻合**
- 4 个非发票**全部正确拒绝**并写明理由(施工许可证 / 对账单 / 技术服务合同 / 邮件通知)
- 4 个跨格式重复(3 张扫描件 + 1 次重复下载)**全部靠发票号码主键识破**,隔离而非删除
- 近重复正确未合并;作废票归档但不计入合计;低置信度定额发票标为待复核
- 台账 xlsx 四张表、报告含五个计数、`SendUserMessage` 带附件交付
- `待整理/` 31 个原件一个未动

## 校验 / Validation

```
validate_catalog_metadata.py --require-complete   0 error, agents=4, sidecars=74   exit=0
validate-i18n.py                                  0 error                          exit=0
translate.py --check                                                               exit=0
gen-collection-children.py --check                                                 exit=0
```
129 条 warning 全部来自 `skills/*` 的存量条目,改前改后一字不差,`invoice-organizer` 零命中。
另核实:`agent.json` 过 `marketAgentSchema`(详情页)与收窄后过
`agentConfigSchema`(安装),
persona / principles 的 6 个 canonical key 用平台真实解析器全部解得出,全树敏感信息扫描通过
(所有公司名 / 税号 / 银行账号均为 `示例`/`示范`/`虚构`/`样例` 前缀的合成值)。

## 后续 / Follow-up

本 PR 为 `availability: listing-only`。可安装化需要把 `agent.json#contentSource` 与
sidecar 的 `provenance.content` **逐字一致地** pin 到本 PR 的合并 commit,
并补 `governance.compliance` 与 `timestamps.reviewedAt`——那是紧接着的第二个 PR。
2026-09-04 07:28:03 -04:00

145 lines
13 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"id": "invoice-organizer",
"name": "发票整理助手",
"description": "把散落在邮箱和本地的发票收拢成一本可对账、可复用的台账,并对每一条记录的来源负责",
"avatar": {
"t": "票",
"bg": "linear-gradient(135deg, #34C759, #007AFF)",
"image": {
"path": "assets/avatar.webp"
}
},
"category": "business",
"tags": [
"invoice",
"expense",
"ledger",
"finance",
"email"
],
"version": "1.0.0",
"updatedAt": "2026-09-04",
"maintainer": {
"name": "DesireCore Official",
"verified": true
},
"installPolicy": "market",
"updatePolicy": "market",
"llm": {
"routingMode": "smart",
"smart": {
"profile": {
"tier": "flagship"
}
},
"maxRetryDelayMs": 32000
},
"heartbeat": {
"enabled": false
},
"webhooks": {
"enabled": false
},
"session_mode": {
"manual": false
},
"env": {
"enabled": true,
"includeWeekday": true,
"includeLocalTime": true,
"includeSessionStart": true,
"includeOs": true,
"includeRuntime": true,
"includeManagedRuntimes": true
},
"mcp_servers": {},
"capabilities": [
"invoice-organizing",
"expense-reconciliation",
"document-extraction"
],
"trigger_patterns": [
"发票",
"报销",
"台账",
"invoice",
"receipt"
],
"accepts_handoff": true,
"accepts_messages": true,
"max_concurrent_sessions": 3,
"i18n": {
"default_locale": "en-US",
"source_locale": "zh-CN",
"locales": [
"zh-CN",
"en-US"
],
"zh-CN": {
"name": "发票整理助手",
"shortDesc": "把邮箱里的发票收拢成一本可对账的台账:按范围收集附件、解析 PDF / OFD / 扫描件、去重归档、生成表格台账与月度报告。需先在 DesireCore 中完成一次邮箱授权;只做形式校验,不做发票真伪查验。",
"fullDesc": "把散落在邮箱和本地的发票收拢成一本可对账、可复用的台账,并对每一条记录的来源负责。\n\n七步工作流顺序固定每一步都幂等接入检查 → 收集 → 解析 → 去重 → 归档 → 台账 → 报告。状态只写工作目录里的索引文件,且落盘顺序固定(记录先入账,再删原件),所以中途中断重跑不会重复入账;万一仍有漏记,每次整理都会反查归档目录把它补回台账。\n\n覆盖的载体\n- PDF数电票2023 年后的全国统一电子发票)、旧版增值税电子普通发票、铁路电子客票报销凭证、航空运输电子客票行程单、出租车与网约车票\n- OFD读取包内的结构化发票数据。2020 年式样的内嵌附件字段最全、值由开票系统直接写出置信度给满分2024 数电票式样只有发票标引,拿不到发票代码与逐行明细,这些会回到版面文本补齐并相应下调置信度;都没有时回落到版面文本\n- 扫描件与图片:交给视觉模型识别,并按来源下调置信度\n\n产出\n- 归档目录:按年/月归档文件名统一为「开票日期_销售方_价税合计_发票号码」\n- 台账:明细、月度汇总、按销售方汇总、异常四张表;金额按人民币口径(¥#,##0.00、负号式负数、零值显示为 ¥0.00),发票号码与税号按文本存放以免被识别成科学计数法。生成 xlsx 的依赖不可用时自动降级为带 UTF-8 BOM 的 CSV 并明确告知\n- 月度报告:一句话结论 + 汇总 + 支出构成 + 「需要你处理的」清单,每条都带具体动作\n\n自动化可选需你同意后才配置\n- 邮件规则:带附件且主题或正文含发票关键词的新邮件,自动交给本 Agent 增量入账\n- 定时任务:每月固定时间重建上月台账与报告,并把文件发回给你\n\n前置条件\n1. 在 DesireCore 的邮箱界面完成一次授权Gmail / Outlook / IMAP 均可)。这是唯一需要你介入的一步\n2. 建议用 ManageWorkDirs 登记一个你在文件管理器里找得到的目录(如 ~/Documents/发票)并设为首选,产物会落在那里并出现在文件工作台中\n3. 解析 PDF / OFD / 图片不需要额外安装任何东西;只有生成 xlsx 台账才可能需要 Python 的 openpyxl 与 pandas装不上会自动降级为 CSV\n4. 默认的执行审批模式下,写文件与邮件调用会逐条弹审批卡。要让定时任务与邮件规则真正无人值守,需要你自己把本 Agent 的执行审批模式改成允许全部\n\n边界不会做的事\n- 不做发票真伪查验。没有官方查验通道,只做形式校验与勾稽校验,并给出国家税务总局全国增值税发票查验平台入口让你自行核验\n- 不做记账凭证、不做纳税申报、不做进项抵扣判断,不是财务软件的替代品\n- 不删除、不移动、不转发你的邮件;邮箱清理请你自己在邮箱里做\n- 不做汇率换算。外币结算的票面本身仍以人民币计价,原币金额与折算汇率原样记录在备注里,不换算、也不并成第二套合计\n- 不自动合并疑似重复(号码只差一位、其余字段全同),标出来交你确认\n- 不编造票面字段。抽不到就留空、隔离原件并说明卡在哪一步,绝不用常见格式补全\n- 不承诺「已全部找到」,只报「在给定范围内找到 N 封候选、成功解析 M 张」\n\n隐私\n发票含公司抬头、纳税人识别号、开户行账号、行程信息。这些只在本机的工作目录与台账里流转本 Agent 没有对外发送的通道,也不会替你回复或转发邮件。",
"tags": [
"发票",
"报销",
"台账",
"财务",
"邮箱"
],
"persona": {
"role": "发票收拢、结构化与台账维护",
"traits": [
"按范围收集而非全量翻邮箱",
"字段带来源与置信度",
"同一张票处理多少次结果都一样",
"抽不到就隔离,不编造"
]
}
},
"en-US": {
"name": "Invoice Organizer",
"shortDesc": "Turns the invoices buried in a mailbox into a reconcilable ledger: collects attachments over a stated range, extracts fields from PDF, OFD and scanned images, deduplicates, archives, and produces a spreadsheet ledger plus a monthly report. Requires a one-time mailbox authorization inside DesireCore; it performs format and arithmetic checks only, never tax-authority invoice verification.",
"fullDesc": "Collects the invoices scattered across a mailbox and the local disk into one reconcilable, reusable ledger, and stays accountable for where every record came from.\n\nA seven-step pipeline in fixed order, each step idempotent: preflight, intake, extraction, dedupe, archive, ledger, report. All state lives in index files inside the work directory and is written in a fixed order — the record is posted before the original is removed — so re-running after an interruption never posts anything twice; and should a record still go missing, every run sweeps the archive directory to put it back in the ledger.\n\nFormats covered\n- PDF: fully digital VAT e-invoices (the nationwide platform format used since 2023), legacy VAT electronic ordinary invoices, railway e-ticket reimbursement vouchers, air transport e-ticket itineraries, taxi and ride-hailing receipts\n- OFD: reads the structured invoice data carried inside the package. The 2020-style embedded attachment is the most complete — its values are written by the issuing system itself, so confidence is full; the 2024 fully-digital style carries only invoice tags, which cannot supply the invoice code or the per-line item breakdown, so those are recovered from the layout text with confidence lowered to match; when neither is present it falls back to layout text entirely\n- Scans and images: handed to the vision model, with confidence lowered to match the source\n\nOutputs\n- Archive: filed by year and month, named uniformly as issue date, seller, tax-inclusive total, invoice number\n- Ledger: four sheets — line items, monthly summary, per-seller summary, exceptions. Amounts follow RMB conventions (¥#,##0.00, minus-sign negatives, zeros shown as ¥0.00), and invoice numbers and tax IDs are stored as text so spreadsheets cannot turn them into scientific notation. When the xlsx dependencies are unavailable it degrades to a UTF-8 BOM CSV and says so\n- Monthly report: a one-line conclusion, the totals, the spending breakdown, and a \"needs your attention\" list where every entry carries a concrete action\n\nAutomation (optional, configured only after you agree)\n- Mail rule: a new message with attachments whose subject or body mentions invoices is handed to this Agent for incremental posting\n- Scheduled job: rebuilds the previous month's ledger and report at a fixed time each month and sends the files back to you\n\nPrerequisites\n1. Complete a one-time mailbox authorization in the DesireCore mail interface (Gmail, Outlook or IMAP). This is the only step that requires you\n2. Register a directory you can actually find in your file manager (for example ~/Documents/invoices) with ManageWorkDirs and make it primary; deliverables land there and show up in the file workbench\n3. Parsing PDF, OFD and images needs nothing installed. Only the xlsx ledger may need Python's openpyxl and pandas, and it degrades to CSV when they are missing\n4. Under the default execution-approval mode, file writes and mail calls raise an approval card each time. Making the scheduled job and the mail rule genuinely unattended requires you to switch this Agent's execution-approval mode to allow-all yourself\n\nBoundaries (what it will not do)\n- No authenticity verification. There is no official verification channel available to it, so it performs format and arithmetic checks only and points you to the State Taxation Administration's national VAT invoice verification platform to check for yourself\n- No accounting entries, no tax filing, no input-tax-credit judgements. This is not a replacement for accounting software\n- It never deletes, moves or forwards your mail; mailbox cleanup stays with you\n- No currency conversion. A foreign-currency settlement is still priced in RMB on the face of the invoice; the original amount and the rate used are copied verbatim into the notes, never converted and never totalled as a second set of figures\n- It never merges suspected duplicates on its own (numbers differing by one digit with every other field identical); they are listed for you to decide\n- It never invents invoice fields. Whatever cannot be extracted is left empty, the original is quarantined, and the reason is stated; no field is ever completed from a \"usual format\"\n- It never claims to have found everything, only that within the stated range it found N candidate messages and successfully parsed M invoices\n\nPrivacy\nInvoices carry company names, taxpayer IDs, bank accounts and travel details. All of it stays in the local work directory and ledger; this Agent has no outbound channel and never replies to or forwards mail on your behalf.",
"tags": [
"invoice",
"expense",
"ledger",
"finance",
"email"
],
"persona": {
"role": "Invoice intake, structuring and ledger maintenance",
"traits": [
"collects over a stated range instead of trawling the whole mailbox",
"every field carries its source and a confidence score",
"idempotent: the same invoice yields the same result however often it is processed",
"quarantines what it cannot extract instead of inventing it"
]
},
"translated_by": "ai:claude-opus-5",
"translated_at": "2026-09-04"
}
},
"persona": {
"tools": []
},
"changelog": [
{
"version": "1.0.0",
"date": "2026-09-04",
"changes": {
"zh-CN": [
"首次登记发票整理助手覆盖收集、解析PDF / OFD / 扫描件)、去重、归档、台账与月度报告",
"内置四个私有技能invoice-workflow总纲、invoice-extract解析、invoice-ledger台账与报告、invoice-automation邮件规则与定时任务",
"声明前置条件:需自行在 DesireCore 中完成一次邮箱授权;不做发票真伪查验"
],
"en-US": [
"Initial listing: an invoice organizer covering intake, extraction (PDF, OFD, scans), dedupe, archiving, ledger and monthly reporting",
"Ships four private skills: invoice-workflow (pipeline), invoice-extract (parsing), invoice-ledger (ledger and report), invoice-automation (mail rules and scheduled jobs)",
"Prerequisites disclosed: users complete a one-time mailbox authorization inside DesireCore themselves; no tax-authority invoice verification is performed"
]
}
}
]
}