mcpField
E
ERP Report Engine

ERP Report Engine

本地服务
gulmezeren2-byte.github.io数据与分析213 周前更新

关于 ERP Report Engine

ERP Report Engine 为需要从 ERP 数据库生成周报及供 AI Agent 查询数据的团队提供只读 SQL 数据层。它通过语义配置映射规范实体,并以四层防护和审计记录约束查询。

主要功能

  1. 01生成含 KPI、趋势和数据质量检查的 HTML 报告
  2. 02映射订单、订单明细和库存等规范实体
  3. 03四层只读 SQL 防护
  4. 04记录查询、参数、行数和耗时
  5. 05支持 MSSQL、PostgreSQL 和 SQLite

适用场景

  1. 01定期生成 ERP 经营周报
  2. 02让 AI Agent 安全查询 ERP 数据
  3. 03检查重复、负数等数据质量问题

MCP 相关

MCP 服务通过规范实体向 AI Agent 暴露 ERP 数据,并使用与报告引擎相同的只读防护。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"gulmezeren2-byte-erp-report-engine": {
"command": "uvx",
"args": [
"erp-report-engine"
]
}
}
}
启动命令uvx erp-report-engine

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypierp-report-engine0.7.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

erp-report-engine

周一会议要用的数据已经存放在 ERP 的数据库里了。那么,为什么还要有人手动写报告?

为 ERP 背后的 SQL 数据库提供只读、自验证的数据层——既能生成周报,也能为 AI Agent 提供带防护的 MCP 服务。每条查询都能证明只读:经 28 种攻击测试,而非仅凭文字承诺。

CI Python License: MIT

🇹🇷 土耳其语版:README.tr.md

一次定时执行 run,就会运行 9 条经过审计的 SELECT 语句,并生成一份独立完整的 HTML 报告:包含与 8 周基线对比的四项 KPI、注明具体驱动因素的发现、数据质量门控,以及与源数据核对一致的行数。不需要 BI 许可证,不需要在 ERP 服务器上安装 Agent,而且绝不写入——通过四层防护(词法、解析树、副作用函数防护和只读会话)强制执行,而非仅凭文字承诺。

引擎根据捆绑的演示数据库生成的周报

这份报告由一条命令根据捆绑的演示数据库生成,其中包括特意植入的三个数据质量问题,全部都被门控捕获。

同一个带防护的引擎也能与 AI Agent 通信。 erp-report-engine mcp 通过标准实体(orders,而非 LG_001_01_ORFICHE)向 Agent 暴露 ERP,并由同一只读防护层守护——MCP 生态系统一直在这方面做得不够。参考 PostgreSQL MCP 服务的只读模式曾被 COMMIT; DROP SCHEMA public CASCADE; 绕过,随后已被归档;Supabase 的 MCP 则成了经典的“致命三要素”案例。这里的防护会检查语句调用的函数,而不只是语句的结构——你也不必只听信形容词:

▶ 运行 28 种攻击信任基准测试 · 在浏览器中亲自尝试突破防护(通过 Pyodide 运行真实的 guard.py,不会向任何地方发送数据)。

浏览器演练场中的只读防护:拒绝读取服务器文件和著名的 COMMIT; DROP Postgres 绕过攻击,允许真实分析——通过 Pyodide 运行真实的 guard.py

测试运行的正是这份 guard.py,并在浏览器中执行——拒绝文件读取和逃逸只读事务,允许真实聚合查询。粘贴你自己的攻击 →

60 秒演示(无需 ERP)

# install (pipx or uv keep it isolated; plain pip works too)
pipx install erp-report-engine          # or: uv tool install erp-report-engine
# from source instead:  pip install .

erp-report-engine init-demo             # builds demo.db + config.demo.yaml here
erp-report-engine run -c config.demo.yaml

每条命令也可以通过 python -m erp_report_engine … 运行。通过 extras 添加数据库驱动:pipx install "erp-report-engine[mssql]"(Logo Tiger / Netsis / Mikro — SQL Server)或 [postgres]。

更喜欢 Docker? 先运行 docker build -t erp-report-engine .,然后运行 docker run --rm -v "$PWD:/work" erp-report-engine run -c config.demo.yaml。SQLite 和 PostgreSQL 开箱即用;MSSQL 需添加 Microsoft 的 ODBC 驱动(参见 Dockerfile)。只需发布一个 GitHub Release 即可上传到 PyPI——publish.yml 会通过 Trusted Publishing 构建并上传(OIDC,无需存储令牌),CI 也已配置为构建 wheel 并确认每个内置配置文件都随包发布。

打开 reports/erp_report_<week>.html。你会看到引擎捕捉到收入激增并将其归因于某个区域,标记准时率下降 2 个百分点,列出库存覆盖不足两周的商品——还会坦承运行过程中发现的所有重复行和负值行。

▶ 查看实时示例报告:gulmezeren2-byte.github.io/erp-report-engine(也已提交至 docs/sample-report.html)。

或者运行 run --dashboard,查看高级版 Command Center——一个深色、现代、独立运行的仪表板,带有动画 KPI 和发光的 SPC 控制带图表(实时演示):

Command Center 仪表板——深色玻璃拟态便当盒网格,配有 SPC 控制带图表

单次运行会生成什么

部分解答的问题
KPI 卡片收入、订单、准时率、低库存数量——分别与上周以及8 周基线对比
发现“收入环比增长 6.5%——主要驱动因素:区域 ‘Ege’(占本周变动的 54%,部分被 Marmara 抵消(−14,697))”——指出驱动因素,也指出走势相反的细分项,并给出建议措施
信号(SPC)“收入信号:148,291 高于控制限(UCL 143,078 = 均值 93,168 ± 2.66 × 平均移动极差 18,763,基线 n=25 周)”——识别真实变化,并将其与逐周噪声区分开,同时显示计算过程和样本量
趋势13 个完整周的收入和准时率,使用内嵌 SVG(无外部资源)
库存关注清单低于库存覆盖阈值的商品,按情况最严重者排在前面
数据质量关卡重复 ID、无法解析的日期、负总额、先发货后下单的行
来源核对获取的行数与对同一查询独立执行的 COUNT(*) 结果对比——✓ 或不匹配
SQL 审计记录执行的每条语句及其参数、行数和耗时
运行状态记忆“收入已连续 3 周下降”——提供超出回溯窗口的上下文

工作原理

flowchart LR
    DB[("ERP database<br/>MSSQL · PostgreSQL · SQLite")]
    PROF["Semantic profile<br/>(YAML contract)"]
    GUARD["safe_read<br/>read-only guard + audit"]
    GATE["Data-quality gate<br/>+ source reconciliation"]
    KPI["KPI engine<br/>ISO weeks, 8-wk baseline"]
    INS["Insight rules<br/>driver attribution"]
    HTML["Self-contained<br/>HTML report"]
    STATE[("state.db<br/>run memory")]

    PROF --> GUARD
    DB --> GUARD --> GATE --> KPI --> INS --> HTML
    STATE --- HTML
    GATE --> PBI["Power BI Command Center<br/>(TMDL + PBIR, code-authored)"]

让这一方案具备可移植性的层是语义配置文件:一个带版本的 YAML 契约,用于将某个 ERP 的晦涩架构映射到三个标准实体——orders、order_lines、inventory——以及一个可选的 receivables 实体(未结应收账款,用于账龄分析)。如果能够访问账本,配置文件就会映射该实体;如果不能,下游所有环节都会优雅地跳过它。引擎始终只接触标准列。更换配置文件,保留报告。

安全模型

将软件连接到生产 ERP 数据库是一项信任决策。此引擎对此严肃对待——这些保障由代码强制执行,并通过测试覆盖:

只读模式通过四层机制强制执行,因此任何单一失误都不会让引擎具备写入能力:

层强制执行方式
词法防护单条语句,以 SELECT/WITH 开头,不含注释(--、/*、#),不含写入/DDL 关键字,也不含会升级写入权限的锁提示(TABLOCKX、UPDLOCK、XLOCK)。扫描时会将字符串字面量置空,因此 SELECT 'please delete this note' 是读取操作,而不是威胁
解析树防护sqlglot 会解析语句——而且必须解析成功,否则查询会被拒绝:无法读取查询的防护机制,就无法为它背书。查询必须是单条读取查询,其 AST 中不得包含 INSERT/UPDATE/DELETE/CREATE/DROP/ALTER/MERGE/EXEC/INTO 节点(可捕获隐藏在 CTE 中的写入操作)
函数防护许多看似纯粹的 SELECT 并非读取操作。 pg_read_file、lo_export(会写入文件)、dblink(会连接外部)、OPENROWSET、LOAD_FILE、load_extension(可执行任意代码)、query_to_xml(可执行任意 SQL)、set_config(会关闭会话级后备防护)、SLEEP/BENCHMARK(拒绝服务)——全部会被拒绝,既通过 AST 检查,也通过词法检查,因为 OPENROWSET 正是 sqlglot 无法解析的内容
只读会话PostgreSQL 的 default_transaction_read_only=on、SQLite 的 PRAGMA query_only、MySQL 的 SET SESSION TRANSACTION READ ONLY + max_execution_time,以及所有数据库上的单语句超时

临时 SQL——Agent 使用的路径——限制更严格。 query 和 guarded_query 在严格模式下运行,默认拒绝防护机制无法识别的所有函数:sqlglot 的函数注册表就是允许列表,因为它只了解可移植的分析函数,不包含任何读取文件或打开套接字的函数。所有四种内置配置都能通过检查——它们完全不调用无法识别的函数。

还有一层不由我们控制。 MSSQL 没有会话级只读开关,因此请使用权限最小化的只读登录账号运行引擎(MSSQL 上使用 db_datareader,PostgreSQL 上授予仅 SELECT 权限——最好使用只读副本)。防护机制提供纵深防御;如果防护机制存在漏洞,权限授予才是能够兜底的那一层。过去确实出现过漏洞:审计本仓库时发现了这些函数绕过方式,目前已按名称、按方言记录在 tests/test_guard.py 中。

别只听我说——亲自测量。 防护机制附带一套可复现的可信度基准测试:在四种方言上测试 28 个格式正确、仅凭语句形态检查的防护机制会放行的攻击,全部都会被拒绝;同时也测试必须通过的合法读取操作。测试得分来自实际运行防护机制的结果,而不是写在说明里的断言,并且 CI 会在每次提交时对其进行验证。

而且,“28/28”只有与较弱防护机制在相同的 28 个案例上的得分对照才有意义。因此,基准测试还会用实际工具常用的捷径来测试这组语料——检查语句是否以 SELECT 开头,以及屏蔽写入关键字——并展示差距:它们分别会拒绝 28 个案例中的 6 个和 9 个;关键字扫描甚至会拦截一条文本中含有 “delete” 一词的合法读取操作,而本防护机制会拒绝全部 28 个攻击,且不会拦截任何合法读取。测试会确保它严格优于所有这类捷径。

erp-report-engine trust-benchmark
#   this guard               28/28 attacks refused · 8/8 reads allowed
#   starts-with-SELECT        6/28                  · 8/8   (waves 22 through)
#   write-keyword blocklist   9/28                  · 7/8   (leaky AND breaks a real read)

▶ 查看结果:可信度基准测试——查看每个案例、其严重程度以及实际效果。或者**亲自试试能否绕过**:将 SQL 粘贴到浏览器中运行的真实防护机制里(无需安装,也不会向任何地方发送数据——这是测试实际运行的 guard.py,通过 Pyodide 执行)。

只想为你自己的 MCP 服务或数据库工具获取防护机制?它已提取为独立软件包:readonly-sql-guard(pip install readonly-sql-guard)——仅包含一个函数,只依赖 re + sqlglot。 再往上一层也是同样的思路:ossie-guard 会检查 Apache Ossie 语义模型,找出不同方言会悄然产生分歧的指标(一个数据仓库使用 SUM,另一个使用 AVG),以及并非纯粹、可复现读取的表达式,并以 SARIF 格式报告到 GitHub 代码扫描。

延伸阅读:为什么“文字上只读”并不代表只读(两个著名的 MCP 数据库故障案例,以及背后的攻击类型) · AI Agent 的只读数据库访问方式对比(事务与角色、语句守卫、语义层的对比——如实说明各自的优势所在)。

此外:配置文件变量符合标识符安全规则(^[A-Za-z0-9_]{1,16}$,因此 "001; DROP TABLE x" 会在建立任何连接前触发错误);密钥绝不会存放在配置文件中(加载器会拒绝任何形式的内嵌凭据——password、passwd、pwd、sslpassword、ODBC PWD=——请使用 url_env);每条执行过的语句都会写入报告的审计记录;行数上限(默认 500k)限制任何单条查询的结果。

测试套件会向守卫发起一系列注入尝试——多语句、三种语法的注释隐藏、事务控制拼接(ROLLBACK/COMMIT)、SELECT INTO、锁提示,以及隐藏在 CTE 中的 DELETE——并要求每一种都触发错误。请参阅 SECURITY.md。

接入你自己的 ERP

  1. 将连接 URL 放入环境变量(绝不要写入文件):
# Windows (System Properties → Environment Variables, or:)
setx ERP_DB_URL "mssql+pyodbc://readonly_user:***@SERVER/LOGODB?driver=ODBC+Driver+17+for+SQL+Server"
  1. 将 config.example.yaml 复制为 config.yaml:
connection:
  url_env: ERP_DB_URL          # the engine reads the URL from this env var
profile: logo_tiger            # a bundled profile name, or a path to your own YAML
profile_vars:
  firm_no: "001"               # identifier-safe values only, validated
  period_no: "01"
report:
  company_alias: "Company"     # display name — use an alias if you prefer
  lookback_weeks: 13
  low_cover_weeks: 2.0
limits:
  row_cap: 500000
  query_timeout_s: 60
  1. 先进行试运行——validate 会建立连接、检查配置文件契约并核对计数,除此之外不会触碰任何内容:
python -m erp_report_engine validate -c config.yaml
python -m erp_report_engine run -c config.yaml
内置配置文件

配置文件随软件包提供,并通过名称引用(generic、logo_tiger)——配置文件旁边无需存在 profiles/ 文件夹。

  • generic — 规范架构;也是编写自定义配置文件的模板。
  • logo_tiger — 适用于 MSSQL 上的 Logo Tiger / GO:通过 LG_{firm}_{period}_ORFICHE 订单头连接 CLCARD 客户、ORFLINE 明细行和 STINVTOT 库存总量;使用 TRCODE = 2 筛选销售;并可选择启用应收账款账龄分析,数据来自 PAYTRANS(分期付款 TOTAL − PAID,MODULENR = 4)。Logo 架构会因版本而异——配置文件中附有字段说明,指出在信任结果前需要针对你的版本核实哪些内容。
  • netsis — 适用于 MSSQL 上的 Logo Netsis 3(每家公司使用独立数据库):TBLSIPAMAS/TBLSIPATRA 销售订单(FTIRSIP = '6')、TBLCASABIT 客户、TBLSTOKPH 库存总量,并可选择启用应收账款账龄分析,数据来自 TBLCAHAR(其中关于未结项目与滚动余额的注意事项已在行内注明——这是需要如实指出的薄弱环节)。字段映射依据真实生产集成编写;薄弱环节(订单状态、交货日期、应收账款结账方式)已在行内标出,供你对照自己的安装版本核实。
  • mikro — 适用于 MSSQL 上的 Mikro ERP(Mikro Yazılım、Fly/Jump/V16–V17):使用 SIPARISLER(sip_ 前缀,行级)作为销售订单、CARI_HESAPLAR 作为客户、STOK_HAREKETLERI 作为现有库存(sth_tip 表示出入库),并可选择启用应收账款账龄分析,数据来自 CARI_HESAP_HAREKETLERI(cha_vade 为到期日)。需要如实说明的薄弱环节——sip_tip 销售筛选条件、总额是否含增值税、订单没有发货日期,以及纯滚动余额的应收账款分类账没有未结项目标记——均已在行内标出,供你对照自己的版本核实。

Logo Tiger、Netsis 和 Mikro 均使用 MSSQL,合计覆盖了土耳其中小企业 ERP 市场的大部分。要为其他 ERP(SAP B1、Odoo、自定义系统)编写配置文件,只需编写三个 SELECT 语句,输出规范列即可——可以单独编写一个 YAML 文件并通过 profile: 指定,也可以将文件放入 erp_report_engine/profiles/,随软件包一同发布。契约就这么简单——validate 会立即告诉你是否配置正确。

实现自动化运行

引擎是一条具备幂等性的命令,因此任何调度程序都能使用:

# Windows Task Scheduler — every Monday 07:00
schtasks /create /tn "erp-weekly-report" /sc weekly /d MON /st 07:00 ^
  /tr "cmd /c cd /d C:\erp-report-engine && python -m erp_report_engine run -c config.yaml"
# cron — every Monday 07:00
0 7 * * 1  cd /opt/erp-report-engine && python -m erp_report_engine run -c config.yaml

每次运行都会向 state.db 追加数据,因此报告可以说出“连续第三周下滑”——跨运行记忆,无需从 ERP 重新查询历史记录。

退出代码可让调度程序根据运行失败的原因采取不同操作:0 成功 · 2 配置错误 · 3 数据库/连接错误 · 4 契约错误(配置文件架构错误或源数据计数无法核对) · 5 --strict 下的数据质量失败 · 1 其他意外情况。机器可读的结果会输出到 stdout(… run -c config.yaml | jq);日志会输出到 stderr,也可通过 --log-file run.jsonl 同时写入 JSON 行文件。在 CI 中运行 validate --strict,即可在数字无法核对时让流水线失败。

可选的 AI 摘要,绝不说谎。 run --narrate 会添加一份 LLM 执行摘要,但它的诚实性由设计保证:模型只会收到经过审计的汇总数据(KPI、发现、账龄/集中度——绝不包含原始行),报告还会打印它看到的确切载荷,任何人都能核实模型获得了什么。如果未配置密钥,该标志不会执行任何操作,报告也不会改变。任何兼容 OpenAI 的端点都可使用,包括本地、无需密钥的模型(Ollama / LM Studio)。大多数工具会在生成后才加上幻觉检查;而在这里,模型根本看不到任何可能泄露信息或导致过度断言的内容。

内置交付功能。 run --send 会通过电子邮件(SMTP)发送报告、将摘要发布到 Slack 或 Teams(Power Automate Workflows),并在成功或失败时向 healthchecks.io 发送无人值守监测信号——这样就能发现静默运行的 cron。所有密钥都来自环境变量;某个渠道失败时会记录日志,但不会导致运行失败。在 delivery: 块中进行配置(参见 config.example.yaml)。如需完全自动化的流水线,power_automate 渠道会向 Teams 发布 Adaptive Card,并且将 HTML 报告存档到 SharePoint/OneDrive——可导入的流程和分步指南见 automation/POWER-AUTOMATE.md。报告会自动生成,并且自动交付——这是大多数 BI 工具收费提供的功能。

Power BI 指挥中心

引擎还为交互式 Power BI 层提供数据——本仓库中没有 .pbix 二进制文件。整个项目是一份以代码编写的 PBIP 项目:使用 TMDL 编写的语义模型(星型架构、28 个附带文档的 DAX 度量值——包括SVG 微型图表度量值,可直接通过 DAX 绘制每位客户的迷你趋势线和每个商品的覆盖条形图,以及一个应收账款账龄事实表和相关度量值——基于无间断周序号的 Time Shift 计算组,以及一个字段参数);使用 PBIR 编写的报告(5 个页面 / 30 个视觉对象,由脚本根据精简规格生成);以及一套通过 Microsoft 官方主题架构验证的暗色未来风格主题。

# a demo export already ships in powerbi/data — just open the project:
#   powerbi/ERP Command Center.pbip   (Power BI Desktop)
# to feed it your own ERP (writes to gitignored powerbi/data.local by default):
erp-report-engine export-powerbi -c config.yaml

其标志性页面是信任页面:将源数据核对、数据质量门禁和完整的 SQL 审计轨迹渲染为视觉对象——仪表板会展示其依据。警报阈值与 insights.py 中的阈值相同,并在 DAX 中重新推导:一套定义,两个呈现界面。在项目加载到 Desktop 之前,pbir-cli 会依据 TMDL 模型验证字段绑定。完整指南:powerbi/README.md。

通过 Agent 查询你的 ERP — 带防护的 MCP 服务

AI Agent 连接 ERP 是一个一直没有得到妥善解决的信任问题:现有的每个“ERP MCP”都是依赖 ERP 自身权限的 REST 封装,而每个数据库 MCP 都会把原始表交给 Agent。这个引擎提供了别处尚不存在的组合 — 一个 Model Context Protocol 服务,Agent 可通过规范实体(orders,而不是 LG_001_01_ORFICHE)进行交互,并使用与报表相同的只读防护和审计跟踪;在严格模式下,防护会默认拒绝所有无法识别的函数,并将每个数据结果标记为不可信输入。

pipx install "erp-report-engine[mcp]"
erp-report-engine mcp -c config.yaml          # stdio server

六种工具,全部经由受防护的路径:

工具Agent 可获取的内容
describe_model规范的语义层 — 每个实体的粒度,以及每列的类型和含义(例如,发货前 actual_ship_date 为 NULL,因此逾期但尚未发货的订单不会被计入准时率),还包括可运行的示例查询。提供含义,而不只是名称 — 这能确保 Agent 使用文本转 SQL 时结果准确。不包含原始 ERP 表名
weekly_report完整的 KPI 简报 — 发现、数据质量检查、对账、SQL 审计跟踪
reconcile获取的行数与每个实体独立执行的 COUNT(*) 结果对比,并给出信任判定
aging应收账款账龄 — 按逾期天数分组的未结余额、逾期百分比,以及欠下最多逾期款项的客户(仅汇总数据)
check_query检查 SQL 语句是否能通过防护 — 但不执行它
query执行只读 SELECT/WITH,并限制结果数量、记录审计;返回的行作为不可信数据

规范模型也以机器可读契约的形式发布 — model.json,或运行 erp-report-engine schema — 这样工具无需连接即可读取实体、列类型、含义和示例查询。CI 会根据代码重新生成它,并在出现偏差时失败,因此契约不会声称引擎不具备的内容。

第一方 Agent 技能包(erp-safe-query、explain-kpi-move、write-erp-profile)会教 Agent 如何遵循这种粒度开展工作 — 查询前先试运行,使用聚合而不是倾倒行数据,引用经过审计的数字,并且绝不把 ERP 文本当作命令。

一行即可试用,无需 ERP,也无需配置 — 通过内置演示数据库提供受防护的 MCP:

erp-report-engine mcp --demo        # or: docker run --rm -i erp-report-engine

然后让 Claude Desktop(或任何 MCP 客户端)连接它:

{ "mcpServers": { "erp": { "command": "erp-report-engine", "args": ["mcp", "-c", "C:\\path\\config.yaml"] } } }

或者将它安装为 Claude Code 插件 — 只需两行,即可使用受防护的 MCP 服务、安全查询技能,以及无需设置的 /trust-benchmark 和 /erp-schema 命令:

/plugin marketplace add gulmezeren2-byte/erp-report-engine
/plugin install erp-report-engine

服务通过 uvx 启动(无需手动安装),并从你的项目读取 erp-config.yaml。数据库连接配置完成前,技能和基准测试/架构命令也能立即使用。(详情:.claude-plugin/。)

Agent 无法写入数据:防护会拒绝除仅调用可识别函数的单条只读查询以外的所有内容,会话本身也是只读的;此外,依据 2025 年 MCP 数据外泄事件的教训,每个返回值都会附带说明,强调行数据是数据而非指令。据我们所知,这是第一个在 SQL 层实施防护的 ERP MCP 服务,也是第一个适用于 Logo Tiger 的此类服务。它已收录于 awesome-turkish-mcp,这是一个精选的土耳其数据与领域 MCP 服务索引。

不会做什么

坦诚胜于营销——在将它用于生产环境前,你应该了解它的边界:

  • 这里的准时是轻量版 OTIF。 它按订单评分,条件是 shipped ≤ promised。真正的 OTIF 需要行级收货数据,而大多数 ERP 订单表都不包含这类数据,因此报告称其为“准时发货”,而非“OTIF”,并在页脚说明原因。
  • 准时率只对已发货的订单评分——这种统计方向很危险。 延迟且仍未发货的订单没有 actual_ship_date,因此既不计入分子,也不计入分母,永远不会让指标失分。极端情况下,随着履约崩溃,准时率会不断上升:最糟糕的订单被排除在样本之外。引擎无法仅凭订单表中的数据解决这个问题,因此它会统计百分比无法体现的情况——“本周有 N 个订单承诺发货,但尚未发货”——并在卡片上显示为单独的发现。要么结合这两项一起看,要么就别看这个百分比。
  • 样本太少时,不会宣称准时率有所变动。 两次交付从 1/2 变为 2/2,确实是“+50 个百分点”,但若面不改色地这样报告,报告就会失去公信力。评分交付少于 5 次时,会显示变动,但明确说明不作判断。
  • 发现只是线索,不是结论。“驱动因素:Ege 地区,占变动的 111%”会告诉你先从哪里查起,但不会告诉你原因——那是分析师(也就是你)的工作。
  • Logo Tiger 配置是字段映射,不是经过认证的集成。 Logo 架构会因版本和本地化设置而异;配置文件中的字段说明列出了需要核实的内容。
  • 当前未完成的周永远不会绘制在图表中。 趋势图止于最近一个已完成的 ISO 周,因为把周一早上的“暴跌”误当成实际趋势,而它其实只是一个只有两天数据的周,这会让仪表板失去可信度。
  • 这是每周简报,不是 BI 平台。 没有下钻分析、实时数据或用户管理。它只做一件事:自动生成每周一的报告,并附上依据。

设计决策

为什么使用基于规则的发现,而不是大模型? 为了确定性。相同的数据库状态始终会生成相同的报告;它可以在与 ERP 相邻的隔离网络环境中运行;报告中的每个数字都能追溯到审计记录中的 SQL 语句。不会生成任何无法重新推导的内容。

为什么采用自包含 HTML 文件? 无需基础设施。图表使用内嵌 SVG,样式使用内嵌 CSS;没有 CDN,也没有跟踪功能。十年后,它仍可在 Outlook 的浏览器预览中、手机上或文件共享目录中正常呈现。

为什么核对行数? 因为“DataFrame 有 494 行”和“源查询返回 494 行”是两种不同的说法。无人值守的系统必须审计自己的输入——每个实体都会使用独立的 COUNT(*) 重新计数,并在任何人信任 KPI 之前,以红色标记所有不一致之处。

测试

pip install pytest && python -m pytest tests/ -v

测试套件涵盖只读保护(大量注入尝试)、配置文件契约、日历核心(单元测试和基于属性的测试)、渲染转义、诚实性修复、CLI 退出代码、MCP 工具、SPC 信号、交付路由,以及完整的端到端运行和 Power BI PBIP 完整性检查(导出器键、无间断的周序号、视觉元素重叠检测,以及模型中是否存在每个视觉元素字段)。CI 还会运行 ruff,并在 Python 3.10–3.13 上检测 PBIR 生成器漂移,出现漂移时即判定失败。

路线图

已交付:带防护机制的 MCP 服务 + 第一方 Agent 技能包、可选的 LLM 叙述层(仅聚合数据,设计上确保如实呈现)、SPC/XmR 异常检测层、原生交付(SMTP/Slack/Teams/healthchecks)+ Power Automate 流水线、声明式配置文件契约、三个真实的土耳其 ERP 配置文件(Logo Tiger、Netsis、Mikro)——每个都可选支持应收账款账龄,营收集中度分析(前三名占比 + HHI)、DAX SVG 迷你图表,以及通过架构验证的深色 Power BI 主题。接下来:

  • 在 PyPI 上运行 pip install erp-report-engine + 发布 Docker 镜像
  • 增加更多 ERP 配置文件(SAP Business One、Odoo、通用 ODBC 模板)
  • 为持续余额分类账(Netsis / Mikro)实现精确 FIFO 未结项目账龄,使应收账款账龄无需配置未结项目匹配即可保持精确

测量诚信系列的一部分

如实呈现运营情况的工具,作者:Eren Gülmez:

许可证

MIT © Eren Gülmez

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。