基于 Hiclaw/CoPaw 本地 AgentTeams 技术栈实现的企业财务风险调查系统:对发票台账里的票面异常信号做深度调查(连号发票、税率异常、同税号多档案等),区分"供应商虚开"、"ERP 录入错误"、"合法业务变更未同步主数据"三类完全不同的成因,产出带完整证据链的风险结论(HIGH/MEDIUM/LOW/INSUFFICIENT_EVIDENCE)与处置建议。
系统由 4 类职能 Agent 组成(Vendor Investigation / Evidence Review / Disposition / Knowledge-Postmortem),既可以用一套纯 Node 脚本在本地离线跑(回归测试 harness),也可以部署进 Hiclaw Docker 容器、通过 Element 聊天界面以自然语言发起调查。本仓库不依赖任何真实 ERP —— 所有数据来自仓库自带的 mock server。
本仓库支持两条独立的运行路径,二者共用同一套 app/src/m5-*.ts 业务逻辑:
cd app
npm install
npm run mock:serve & # 启动离线 mock ERP,端口 8091(Ctrl+C 或 kill 结束)
QIHENG_BASE_URL=http://localhost:8091 npm run vendor-audit -- --eval --out-dir ./run-evidence跑完会在终端打印风险分布、跨供应商风险信号、总花费,并在 ./run-evidence/ 下写入 vendor-risk-report.json(结构化报告)和 vendor-risk-summary.md(中文摘要)。本仓库已经提交了一份真实跑出来的结果,见第 6 节「运行证据」。
npm run vendor-audit(不带--eval)需要读取m3-result.json(上游 M2/M3 发票稽核流水线产出的物料),本仓库未包含该文件,请始终使用--eval模式——它会对 mock server 里的发票台账做实时扫描,不依赖任何外部产物。
前提:本机已经用 hiclaw create team 装好 Hiclaw/CoPaw 平台并建好了 2 个 Team、6 个 Agent 容器(这一步是平台安装,超出本仓库范围)。在此基础上:
- 把本仓库
app/agents/、app/workers/下各 Agent 的SOUL.md/AGENTS.md/skills/*/SKILL.md部署进对应容器; - 在 host 机器上常驻启动
npm run mock:serve+npm run skills-bridge(Worker 调查时通过curl回调 host 的 Skills Bridge 才能查到数据); - 浏览器打开
http://127.0.0.1:18088登录 Element,找risk-case-leader说"帮我调查一下供应商 VEN-0052 有没有风险"即可触发一次完整的调查 → 证据审核 → 处置 → 知识沉淀流程。
完整部署步骤、容器改动生效方式、状态重置方法见 app/HICLAW-README.md 和 app/HICLAW-TROUBLESHOOTING.md,本文档不重复。
- Node.js:建议 v20+(
type: module+tsx直跑 TypeScript,无需单独编译步骤)。 - 需要分别在两个目录执行
npm install:sdk/typescript/:app/src/m5-connectors.ts通过相对路径../../sdk/typescript/src/index.ts引用 SDK,用于对接真实或 mock ERP 的 REST 接口。app/:主业务代码。核心第三方依赖:包 用途 openai以 OpenAI 兼容协议调用 DeepSeek(对话)和 SiliconFlow(向量/重排序) @modelcontextprotocol/sdkapp/mcp-server/暴露的 MCP 工具通道(可选,非调查主路径必需)expressmock server + Skills Bridge 的 HTTP 服务 tsx/typescript直接运行 .ts源码,无编译步骤
- 外部 LLM API(需要自备 key,见第 3 节):
- DeepSeek:Vendor Investigation Agent 的 ReAct 对话模型。
- SiliconFlow:Policy RAG Skill 检索制度文档时用的嵌入 + 重排序模型。
- 两者都是调用逻辑推理/证据审核时的必需依赖,没有配置有效 key 时
--eval会在调用时报错——这两个 key 与"是否需要真实 qiheng ERP"无关,是完全独立的两件事。
复制 app/.env.example 为 app/.env 并填写:
cd app && cp .env.example .env| 变量 | 说明 |
|---|---|
QIHENG_API_KEY |
mock server 只校验该值非空字符串,不校验具体内容;填任意非空值即可(如 .env.example 里的占位值) |
QIHENG_BASE_URL |
默认值 http://localhost:8091 指向本仓库自带的 mock server,完全离线;若有真实 ERP 环境,改成 http://localhost:8081 即可无缝切换,业务代码不用改一行 |
DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL / DEEPSEEK_MODEL |
Vendor Investigation Agent 的对话模型,必填有效 key |
SILICONFLOW_API_KEY / SILICONFLOW_EMBEDDING_MODEL / SILICONFLOW_RERANK_MODEL |
Policy RAG Skill 的嵌入 + 重排序模型,必填有效 key;模型名有默认值可不改 |
SKILLS_BRIDGE_PORT / MCP_SERVER_PORT |
host 侧常驻服务端口,可选,留空用默认值(8093 / 8092) |
其余配置文件:
app/tsconfig.json/sdk/typescript/tsconfig.json:标准 TS 配置,无需改动。app/mock-server/data/*.json:mock ERP 的静态数据(供应商主数据、发票台账、审批记录),已预生成好,npm run mock:serve直接读取,不需要(也没有提供)重新生成脚本。app/mock-server/data/docs/*.txt:供 Policy RAG Skill 检索的制度文档,含现行版《供应商管理办法》V2.0 和已废止 V1.0(两版条款故意存在差异,用于验证 Agent 是否引用了正确版本)。
app/m5-eval-vendors.json 是人工核对 ERP 原始数据得出的评测集,覆盖全部四档风险等级 + 两类"陷阱"设计:
| vendorId | 供应商 | 期望风险等级 | 设计意图 |
|---|---|---|---|
| VEN-0056 | 北京正泰金属材料股份有限公司 | HIGH | 连号发票 + 税率异常两条独立信号同时命中 |
| VEN-0043 | 常州腾跃人力资源服务有限公司 | MEDIUM | 单一维度税率异常,方向不一致,证据不足以直接定论 |
| VEN-0104 | 常州广盛金属材料股份有限公司 | LOW | 孤立票面异常,金额占比仅 0.02%,业务风险极低 |
| VEN-0052 / VEN-0121 | 腾跃铜业(同税号双档案) | INSUFFICIENT_EVIDENCE | 两类不同性质的信号(主数据治理问题 + 孤立票面异常)无法互相印证收敛,如实标注证据不足而非强行定级 |
| VEN-S001 | 宁波恒远物流有限公司(合成,仅存在于 mock server) | LOW | 防误报陷阱:税率持续变化 + 涉及金额占比 34%,表面特征极易触发 HIGH,但有合法审批记录(APR-V001/APR-V002)覆盖,真正问题只是主数据 category 字段未同步更新 |
样例输出(vendor-risk-report.json 单条记录的结构,字段节选自本仓库实测产出):
{
"vendorId": "913205GTDY9AK5KCK9",
"vendorName": "北京正泰金属材料股份有限公司",
"taxNo": "913205GTDY9AK5KCK9",
"riskLevel": "HIGH",
"conclusion": "两条同一性质的票面异常信号(税率异常 + 连号发票)均具制度依据、涉及可观金额,合并升级判定为 HIGH。",
"evidence": ["INV-003948", "INV-006880", "INV-006881", "INV-006882"],
"policyRefs": ["发票合规指引 二 税率适用表", "供应商管理办法(V2.0-现行)第六条"],
"suggestedActions": ["核查 INV-003948 为何适用 6% 税率并追偿进项税差异", "核查三张连号发票对应采购订单及业务真实性", "..."],
"auditTrail": [ "...完整 ReAct 调查步骤序列,用于回放调查过程,此处省略..." ],
"reviewRounds": 1,
"investigationIncomplete": false,
"costUsd": 0.0138,
"disposition": { "action": "冻结供应商合作、暂停在途付款,转人工审批", "status": "PENDING_APPROVAL" }
}完整的 5 家供应商结论、逐条证据引用和 ReAct 调查轨迹见 app/run-evidence/vendor-risk-report.json,中文管理层摘要见 app/run-evidence/vendor-risk-summary.md。
以下是本仓库当前状态下、按第 1.1 节命令实测跑出来的结果(详见 app/run-evidence/eval-run-transcript.txt 完整终端输出):
评测模式:仅调查 6 家评测集供应商:北京正泰金属材料股份有限公司、常州腾跃人力资源服务有限公司、常州广盛金属材料股份有限公司、烟台腾跃铜业有限责任公司、腾跃铜业、宁波恒远物流有限公司
实时扫描发票台账并关联供应商...
候选供应商 27 家,本次调查 5 家
开始调查:宁波恒远物流有限公司(7 张异常发票)
开始调查:腾跃铜业(1 张异常发票)
开始调查:常州腾跃人力资源服务有限公司(2 张异常发票)
开始调查:常州广盛金属材料股份有限公司(1 张异常发票)
完成:常州广盛金属材料股份有限公司 → LOW
开始调查:北京正泰金属材料股份有限公司(1 张异常发票)
完成:宁波恒远物流有限公司 → LOW
完成:常州腾跃人力资源服务有限公司 → MEDIUM
完成:腾跃铜业 → INSUFFICIENT_EVIDENCE
完成:北京正泰金属材料股份有限公司 → HIGH
=== 风险分布 === { HIGH: 1, MEDIUM: 1, LOW: 2, INSUFFICIENT_EVIDENCE: 1 }
=== 跨供应商风险 === [
'不同税号供应商(南通润泽设备维护有限责任公司/91320591JG1M99RA6F、润泽设备维护/9132057NDECQ6NL0MD)共用联系电话 17090604194,疑似关联方/马甲公司'
]
=== 总花费 === $0.0624
5/5 全部命中 m5-eval-vendors.json 的预期风险等级(VEN-0056→HIGH、VEN-0043→MEDIUM、VEN-0104→LOW、VEN-0052/VEN-0121→INSUFFICIENT_EVIDENCE、VEN-S001→LOW),且 VEN-S001(防误报陷阱)没有被表面的税率异常误导成 HIGH,判定依据里正确引用了 APR-V001/APR-V002 审批记录——说明 Agent 是查完审批依据再下结论,而不是看到异常就跳 HIGH。全程未连接任何真实 ERP,QIHENG_BASE_URL 全程指向本机 mock server(:8091)。
产出文件:
app/run-evidence/vendor-risk-report.json—— 完整结构化报告(含每家供应商的 ReAct 调查轨迹)app/run-evidence/vendor-risk-summary.md—— 中文管理层摘要(逐供应商完整结论与建议措施)app/run-evidence/eval-run-transcript.txt—— 完整终端输出app/vendor-disposition-log.json—— 处置留痕日志(disposition-execution-worker对每家供应商生成的处置动作,MEDIUM及以上要求人工审批)
在聊天界面发送调查指令给 risk-case-leader:
帮我调查一下供应商VEN-0052有没有风险
risk-case-leader 创建了 room,开始调查:
- 给 risk-investigation-worker 发布任务,risk-investigation-worker 进行 react 调查:
- leader 收到回复与 disposition-execution-worker 交互,disposition-execution-worker 完成任务:
- leader 给 admin 返回任务执行结果:
- investigation-result.md:investigation-result.md
- risk-assessment-report.md(风险评估报告):risk-assessment-report.md
- audit-trail.md(完整 ReAct 审计轨迹):audit-trail.md
- disposition-result.md:disposition-result.md
- disposition-opinion.md(风险处置意见):disposition-opinion.md
- plan.md(任务规划):plan.md
FinProbe/
sdk/typescript/ # 开放平台官方 TS SDK,app/ 通过相对路径引用
app/
src/
m5-*.ts # 4 类职能 Agent 的业务逻辑本体(Vendor/Evidence/Disposition/Knowledge)
m5-orchestrator.ts # 本地回归 harness 用的编排逻辑(--eval 模式)
m3.ts / rules.ts / policy.ts # --eval 模式实时扫描发票台账依赖的规则引擎(非 M2/M3 全量功能)
skills/ # 5 个底层数据 Skill:供应商/发票/审批查询、财务分析、制度文档 RAG
cli-vendor-audit.ts # npm run vendor-audit 的命令行入口
mock-server/ # 离线 mock ERP:server.ts 只读预生成好的 data/*.json,零 ERP 依赖
skills-bridge/ # host 侧常驻 HTTP Bridge,供 Docker 容器里的 Worker 用 curl 调用
mcp-server/ # 可选的原始数据查询 MCP 通道
agents/ # 2 个 Team Leader(risk-case-leader / risk-audit-leader)的 SOUL.md/AGENTS.md
workers/ # 4 个 Worker 的 SOUL.md/AGENTS.md/Skill 定义
run-evidence/ # 第 5 节的实测运行证据
各文件更详细的职责说明见 app/HICLAW-README.md §2。
- 风险等级判定依赖 LLM 推理,同一输入在不同运行之间存在一定非确定性;已用多轮独立评测验证过评测集的稳定性,但不构成生产级统计意义上的准确率保证。
- Evidence Review Agent 是规则化检查(有没有调用某个 Skill、有没有引用证据 ID),不校验"引用的证据是否真的支撑结论"这类语义正确性。
disposition-execution-worker产出的PENDING_APPROVAL只是留痕,不代表真的有人审批通过——系统内没有真实的人工审批 UI。- Hiclaw/Element 路径依赖用户本机已安装的 Hiclaw/CoPaw 平台(
hiclaw create team建的 Docker 容器),这部分平台安装超出本仓库范围;本仓库负责的是"平台装好之后,把 Agent 定义部署进容器 + 起 host 侧服务,调查请求能在 Element 里查到 mock 数据"。 npm run vendor-audit(不带--eval)依赖上游 M2/M3 发票稽核流水线产出的m3-result.json,本仓库未包含该文件,因此该模式在本仓库里不可用,请使用--eval模式。



