# 一期机器人入库规则与追问策略

更新时间：2026-06-03 21:25:53 CST  
适用阶段：公司财务报销与公司走账系统重构一期  
定位：给财务机器人 / MCP / 后端 API 使用的业务入库规则，不是前端录入页面设计。

---

## 0. 总原则

1. **机器人先读规则，再追问用户**：每次识别出 `intent` 后，先调用 `finance_get_intake_rules`。
2. **关键财务事实不能猜**：金额、主体、项目/基础经营归属、收付款方、发票状态、资金账户、真实发生日期等，缺失时必须追问。
3. **先草稿，后审批/确认，再入库**：机器人先生成 `intake_draft`，通过预览、用户确认或飞书审批边界后，才写正式事实表。
4. **真实资金流水只进 `fund_transaction`**：应收、应付、报销的已收/已付金额，全部由核销/分配表派生。
5. **个人账是派生结果，不是一层事实表**：无票报销、个人垫付、个人注资、公司还个人等来源进入派生计算。
6. **前端弱化，但后端契约要强**：前端不承担复杂录入；MCP/API 必须返回中文追问句、风险提示和可解释预览。
7. **写入接口必须幂等**：机器人写入类工具必须携带或生成 `idempotency_key`，避免重复消息/重试导致重复入库。

### 字段等级

| 等级 | 含义 | 处理方式 |
|---|---|---|
| `blocking` | 阻塞字段 | 缺失时不得提交审批/正式入库，机器人必须追问。 |
| `warning` | 风险字段 | 可生成草稿，但预览和审批摘要必须提示风险。 |
| `optional` | 可选字段 | 可空或标记 `待确认`，不阻塞草稿。 |

### 机器人处理顺序

```text
用户自然语言
  → 识别 intent
  → finance_get_intake_rules(intent)
  → 解析主体/项目/金额/发票/账户等字段
  → finance_validate_intake_draft
  → 如果 blocking 缺失：按 question 继续追问
  → 如果可形成草稿：finance_preview_intake
  → 用户确认 / 飞书审批边界
  → commit 写正式事实表
```

---

## 1. 一期 intent 总览

| intent | 中文 | 主要用途 | 写入边界 |
|---|---|---|---|
| `record_reimbursement` | 记录报销/个人垫付 | 用户说“我要报销/某人垫付了/无票先记一下” | 先 `intake_draft`，确认后写报销单和明细；付款另记资金流水。 |
| `record_receivable` | 记录应收/合同款 | 记录项目应收、尾款、合同款、收入计划 | 先草稿，确认后写 `receivable`；到账另记 `fund_transaction`。 |
| `record_fund_in` | 记录真实收款流水 | 记录客户打款、个人注资、退款到账等 | 写 `fund_transaction(direction=IN)`，业务归属后续核销。 |
| `allocate_receipt` | 核销收款 | 把一笔到账分配到应收/项目 | 写 `receivable_settlement`，不改应收原始金额。 |
| `record_payable` | 记录应付/费用义务 | 记录供应商款、采购款、待付费用 | 先草稿，确认后写 `payable`；付款另记资金流水。 |
| `record_fund_out` | 记录真实付款流水 | 记录付款给供应商、报销付款、公司还个人 | 写 `fund_transaction(direction=OUT)`，业务归属后续核销。 |
| `allocate_payment` | 核销付款 | 把付款分配到应付或报销单 | 写 `payable_settlement` 或 `reimbursement_payment`。 |
| `personal_injection` | 个人注资/借给公司 | 个人打钱进公司周转、借款、注资 | 写资金流入，并进入个人账派生来源。 |
| `company_repay_person` | 公司还个人 | 公司向个人还款、报销款已付 | 写资金流出，并核销个人相关来源。 |
| `query_project` | 查询项目 | 查项目收入、支出、应收应付、流水 | 只读。 |
| `query_personal_ledger` | 查询个人账 | 查个人派生余额和来源明细 | 只读。 |
| `query_subject_summary` | 查询主体汇总 | 查主体现金、待收、待付、待报销 | 只读。 |

---

# 2. 各 intent 入库规则

## 2.1 `record_reimbursement`｜记录报销/个人垫付

典型话术：我要报销；某人垫付了；这笔无票先记一下；这个费用走公司。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `applicant_subject` | 申请/经办人 | 这笔是谁申请或经办的？如果就是你，我先按你作为经办人记录。 |
| `payee_subject` | 收款/报销对象 | 这笔最终要报销给谁，或记到谁的个人账？ |
| `items[].amount` | 每条明细金额 | 每一笔分别是多少钱？ |
| `items[].project_or_owner_subject` | 费用归属项目或主体基础经营 | 这笔费用归哪个项目？如果不是具体项目，请告诉我是哪个主体的基础经营/公共支出。 |
| `items[].invoice_status` | 发票状态 | 这笔有没有发票？是有票、待补票，还是无票？ |
| `items[].description` | 费用说明 | 这笔费用具体是什么？ |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `occurred_at` | `待确认` | 发生日期是哪天？不知道可以先记待确认。 |
| `expense_category` | `待分类` | 费用大类是什么？例如采购、打样、物流、AI工具、办公、差旅等。 |
| `attachments` | 空 | 有没有发票、截图或付款凭证要附上？ |
| `advancer_subject` | 默认等于 `payee_subject` | 实际垫付人是不是收款/报销对象本人？ |

### 默认规则

- 如果有 `project_id`，费用归属主体由 `project.owner_subject` 推导。
- 如果无业务项目但明确主体，则挂该主体默认 `BASE_OPERATION` 项目。
- 无票报销默认进入个人账派生候选；有票报销默认不进入个人账，除非业务规则另设。

### 风险提示

- 无发票；
- 待补票；
- 归属基础经营项目；
- 金额较大但无附件；
- 项目归属不明确。

### 入库边界

审批或人工确认后才创建正式 `reimbursement_order` / `reimbursement_item`；实际付款发生后，再用 `fund_transaction` + `reimbursement_payment` 核销。

---

## 2.2 `record_receivable`｜记录应收/合同款/项目收入计划

典型话术：这个项目要收多少钱；合同款；尾款；对方还欠我们。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `project` | 归属项目 | 这笔应收归哪个项目？ |
| `owner_subject` | 收入归属主体 | 这笔收入归哪个主体？如果项目已配置主体，可由项目自动推导。 |
| `amount` | 应收金额 | 应收金额是多少？ |
| `counterparty_subject` | 客户/付款方 | 应该由谁付款？客户或对方主体是谁？ |
| `receivable_name` | 款项名称 | 这笔款叫什么？例如首款、尾款、设计费、货款等。 |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `expected_date` | `待确认` | 预计什么时候收？ |
| `contract_or_order` | 可空但风险提示 | 有没有对应合同、订单或报价单？ |
| `expected_receiver_subject` | 默认收入归属主体 | 预计打到哪个主体或账户？ |
| `invoice_requirement` | `待确认` | 是否需要开票？ |

### 默认规则

- 项目唯一命中时，`owner_subject` 自动由项目推导。
- 没有合同编号时仍可创建应收草稿，但标记“缺合同/订单依据”。

### 风险提示

- 缺合同依据；
- 付款方不明确；
- 收款主体与项目归属主体不一致；
- 预计收款账户未填。

### 入库边界

确认后创建 `receivable`；真实到账必须另记 `fund_transaction`，再用 `allocate_receipt` 核销。

---

## 2.3 `record_fund_in`｜记录真实收款流水

典型话术：钱进来了；客户打款了；收到一笔款；到账了。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `amount` | 到账金额 | 实际到账金额是多少？ |
| `occurred_at` | 到账日期 | 哪一天到账？ |
| `receiver_subject_or_account` | 收款主体/账户 | 钱进到哪个主体或账户？ |
| `payer_or_counterparty` | 付款方 | 付款方是谁？ |
| `source_category` | 资金来源分类 | 这笔是项目收款、个人注资、退款，还是其他来源？ |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `bank_transaction_no` | 可空 | 有没有银行/支付宝/微信流水号？ |
| `proof_attachment` | 可空 | 有没有到账截图或银行回单？ |
| `candidate_receivable` | `待核销` | 这笔对应哪个项目/应收？如果不确定，可先作为未分配到账。 |

### 默认规则

- 只有一个活跃收款账户时可作为候选，但预览必须提示。
- 若用户明确“个人打给公司周转”，`source_category=personal_injection`。

### 风险提示

- 未分配到账；
- 付款方不明确；
- 收款账户不明确；
- 到账金额与应收金额不一致。

### 入库边界

真实资金流水可先确认入账；业务归属通过 `allocate_receipt` 单独核销，可部分核销/多笔核销。

---

## 2.4 `allocate_receipt`｜核销收款到应收/项目

典型话术：这笔到账对应某项目；把这笔收款核到尾款；这笔钱是哪个项目的。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `fund_transaction` | 待核销资金流水 | 要核销哪一笔到账？ |
| `receivable_or_project` | 对应应收/项目 | 这笔到账对应哪个应收或项目？ |
| `amount` | 核销金额 | 核销金额是多少？如果全额核销，我按到账剩余未分配金额处理。 |

### 默认规则

- 如果资金流水未分配余额等于应收未收余额，可默认全额核销。
- 支持一笔到账拆到多个应收；支持一个应收被多笔到账核销。

### 风险提示

- 核销金额超过未分配余额；
- 核销金额超过应收未收余额；
- 项目/付款方不匹配。

### 入库边界

只创建 `receivable_settlement`，不改写 `receivable.received_amount` 原始字段；已收金额由核销表汇总派生。

---

## 2.5 `record_payable`｜记录应付/费用义务

典型话术：供应商款待付；采购款；合同已签待付；有一笔费用要付。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `project_or_owner_subject` | 费用归属项目或主体基础经营 | 这笔应付归哪个项目？如果不是项目，归哪个主体的基础经营？ |
| `counterparty_subject` | 收款方/供应商 | 应付给谁？供应商或收款对象是谁？ |
| `amount` | 应付金额 | 应付金额是多少？ |
| `paying_subject` | 预计付款主体 | 预计由哪个主体付款？ |
| `name_or_description` | 应付事项 | 这笔应付是什么事项？ |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `due_date` | `待确认` | 预计什么时候付？ |
| `invoice_status` | `待确认` | 对方是否会开发票？现在有票吗？ |
| `expense_category` | `待分类` | 费用大类是什么？ |
| `contract_or_order` | 可空 | 有没有采购合同或订单？ |

### 默认规则

- 项目唯一命中时，费用归属主体自动推导；无项目但主体明确时挂基础经营项目。
- `paying_subject` 可默认项目归属主体，但若实际付款主体不同必须显式记录。

### 风险提示

- 付款主体与费用归属主体不一致；
- 缺发票信息；
- 缺供应商；
- 归属基础经营项目。

### 入库边界

确认后创建 `payable`；实际付款必须另记 `fund_transaction`，再用 `allocate_payment` 核销。

---

## 2.6 `record_fund_out`｜记录真实付款流水

典型话术：已经付款了；打款给供应商；公司还给个人；钱出去了。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `amount` | 付款金额 | 实际付款金额是多少？ |
| `occurred_at` | 付款日期 | 哪一天付出的？ |
| `payer_subject_or_account` | 付款主体/账户 | 从哪个主体或账户付出？ |
| `receiver_or_counterparty` | 收款方 | 付给谁？ |
| `source_category` | 付款分类 | 这笔是供应商付款、报销付款、公司还个人、退款，还是其他？ |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `proof_attachment` | 可空 | 有没有付款凭证？ |
| `candidate_payable_or_reimbursement` | `待核销` | 这笔对应哪个应付或报销单？不确定可以先记未分配付款。 |

### 默认规则

- 若 `source_category=company_repay_person`，后续优先核销个人相关报销/借款。
- 真实付款不等同于费用归属，必须通过核销/分配表挂业务对象。

### 风险提示

- 未分配付款；
- 付款账户不明确；
- 收款方不明确；
- 付款金额与应付/报销不一致。

### 入库边界

真实付款可先入 `fund_transaction`；业务归属通过 `allocate_payment` 绑定 `payable` 或 `reimbursement_order`。

---

## 2.7 `allocate_payment`｜核销付款到应付/报销

典型话术：这笔付款对应供应商款；这笔打款是报销；把付款核掉。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `fund_transaction` | 待核销付款流水 | 要核销哪一笔付款？ |
| `target_type` | 核销对象类型 | 这笔付款是核销应付，还是核销报销单？ |
| `target_id` | 核销对象 | 对应哪一张应付/报销单？ |
| `amount` | 核销金额 | 核销金额是多少？如果全额核销，我按未分配余额处理。 |

### 默认规则

- 若付款收款方与报销 `payee` 或应付 `counterparty` 唯一匹配，可作为候选但需预览。
- 支持部分付款和一笔付款分摊多个对象。

### 风险提示

- 核销金额超过付款未分配余额；
- 核销金额超过对象未付余额；
- 收款方不匹配。

### 入库边界

只创建 `payable_settlement` 或 `reimbursement_payment` 关联；对象已付金额由关联汇总派生。

---

## 2.8 `personal_injection`｜个人注资/借给公司

典型话术：某人打钱进公司；我先借给公司；个人注资；公司周转款。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `person_subject` | 出资个人 | 是哪位个人打给公司的？ |
| `receiver_subject_or_account` | 收款主体/账户 | 钱进到哪个公司/主体或账户？ |
| `amount` | 金额 | 金额是多少？ |
| `occurred_at` | 发生日期 | 哪一天到账？ |
| `nature` | 性质 | 这笔是借款周转、投资注资，还是临时垫资？ |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `repayment_expectation` | `待确认` | 后续是否需要还给个人？预计什么时候还？ |
| `remark` | 空 | 有没有备注或凭证？ |

### 默认规则

- 默认 `source_category=personal_injection`，影响个人账派生。
- 若性质为投资/资本性投入，个人账派生方向需要单独标注，不自动等同应还款。

### 风险提示

- 借款/投资性质不明确；
- 收款账户不明确；
- 无凭证。

### 入库边界

先作为资金流入与个人账派生来源；是否形成应还款，取决于性质和规则。

---

## 2.9 `company_repay_person`｜公司还个人/报销付款

典型话术：公司还了某人的款；报销款已付；还给我了；公司转给个人。

### 必须拿到的阻塞字段

| 字段 | 含义 | 缺失时追问 |
|---|---|---|
| `payer_subject_or_account` | 付款主体/账户 | 从哪个公司/主体或账户付出？ |
| `person_subject` | 收款个人 | 还给哪位个人？ |
| `amount` | 金额 | 还款/报销金额是多少？ |
| `occurred_at` | 发生日期 | 哪一天付出的？ |
| `repayment_target` | 对应事项 | 这笔是还哪一类钱：报销、个人借款、个人垫资，还是历史调整？ |

### 可选/可待确认字段

| 字段 | 默认/处理 | 追问建议 |
|---|---|---|
| `target_reimbursement_order` | `待匹配` | 是否对应某张报销单？ |
| `proof_attachment` | 可空 | 有没有付款凭证？ |

### 默认规则

- 若 `repayment_target=报销` 且有唯一未付报销单，可提示候选。
- 不得直接减少个人账余额，必须通过资金流水与核销/派生规则实现。

### 风险提示

- 未匹配报销/借款来源；
- 付款账户不明确；
- 金额超过个人账待还余额。

### 入库边界

创建付款流水并按目标核销；个人账余额由来源与还款核销派生。

---

## 2.10 查询类 intent

### `query_project`

- 必填：`project_or_keyword`。
- 默认返回：项目摘要、应收未收、应付未付、报销待付、资金流水概览。
- 如果项目候选不唯一，先返回候选，不猜。

### `query_personal_ledger`

- 必填：`person_subject`。
- 默认返回：个人派生余额、来源分类、无票报销、个人注资、公司还款、待确认项。
- 必须说明：个人账是派生结果，不是手工维护余额。

### `query_subject_summary`

- 必填：`subject`。
- 默认返回：现金账户核对状态、应收未收、应付未付、报销未付、未分配资金流水。
- 若现金账户未核对，摘要必须提示。

---

# 3. 一期后端实现建议

1. `intake_rules_一期草案.json` 先作为规则配置雏形，后续可以迁移到数据库或版本化规则表。
2. `finance_get_intake_rules` 读取规则时，应返回 required/optional/default/risk/follow_up_questions。
3. `finance_validate_intake_draft` 不只返回字段错误，还要返回中文追问句。
4. `finance_preview_intake` 必须生成用户能看懂的摘要：会创建什么、不会创建什么、风险是什么、还缺什么。
5. `commit` 阶段必须检查 `idempotency_key`、草稿状态、审批/确认状态、月结锁定状态。
6. 禁止提供任意表写入工具；所有 MCP 都以业务动作封装。

---

# 4. 和现有文档的关系

- 本文承接 `API_MCP_机器人接口设计草案.md` 的机器人优先架构。
- 本文的正式事实对象对应 `一期业务事实模型与基础表结构草案.md` 和 `prisma_schema_一期草案.prisma`。
- 本文的结构化版本是 `intake_rules_一期草案.json`。
