最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Dify Custom Tool 配置化实践:用一行提示词接入新报表
时间:2026-09-15 12:50:01 编辑:袖梨 来源:一聚教程网
报表系统真正难以控制的往往不是单次查询,而是报表种类不断增长后产生的大量重复代码。取数、聚合、表头和格式化流程高度相似,却常被拆成多套实现。要让 Dify Custom Tool 稳定承接新报表,需要先把易变的报表定义从执行逻辑中抽离,再为动态公式和查询性能划定清晰边界。
Dify Custom Tool 设计模式:一行提示词接入一张新报表
系列第 4 篇。第 1 篇解决了"查得快"(2700 次 SQL → 4 次),第 2 篇解决了"答得真"(防幻觉四铁律),这一篇解决更现实的问题:报表数量爆炸时,工具层怎么不跟着爆炸。 全部代码可运行:
tools/report_tool/,一张报表就是一个 YAML。
速览(60 秒版)
| 你将看到 | 一句话结论 |
|---|---|
| 事故现场 | 20+ 张报表 = 20+ 套取数代码,每张都要开发、联调、维护 |
| 病根 | 把"报表"当程序写(每张一套 SQL + 拼装 + 格式化),而不是当数据描述 |
| 解法 | 配置驱动:一张报表 = 一个 YAML;计算列用 formula 声明 |
| 兜底 | 新报表上线,AI 侧只改一行提示词,工具侧只加一个 YAML |
一、事故现场:报表数量爆炸
真实系统里,报表工具链的核心痛点不是"写 SQL",而是报表永远在增加:日报、周报、月报、值际报、指标统计分析……20+ 张报表,每张的流程都一样——写一段取数 SQL、拼装表头、格式化小数、返回二维数组。每张都要开发、联调、维护。
更糟的是需求永远在变:今天加一个"峰谷差率",明天加一个"条件筛选均值"。每张报表都是硬编码,每次改动都是一次回归风险。开发速度永远追不上报表增加的速度。
二、病根:把报表当程序写
每张报表的 90% 代码其实是相同的:批量取数、聚合计算、格式化输出。真正不同的只有三样——查哪些测点、算哪些指标、表头叫什么。
这三样是数据,不是程序。所以正确的设计是把它们从代码里抽出来,变成配置:
把"怎么查"写进代码,把"查什么"写进配置。
三、设计模式拆解
3.1 一张报表 = 一个 YAML
report:
id: monthly_report
title: 月度生产报表
columns:
- { key: point, type: point_name, label: "测点" }
- { key: avg, type: agg, agg: avg, label: "月均负荷", unit: "MW" }
- { key: max, type: agg, agg: max, label: "月最高", unit: "MW" }
- { key: load_factor, type: calc, formula: "avg / capacity * 100", label: "负荷率", unit: "%" }
rows:
- { point: point_001, name: 1号机组, capacity: 1000 }
- { point: point_003, name: 3号机组, capacity: 660 }
列只有三种类型,覆盖了报表的全部形态:
| 列类型 | 说明 |
|---|---|
point_name | 维度列(测点名) |
agg | 聚合列(avg / max / min / sum / count,白名单) |
calc | 计算列:formula 引用聚合列或行属性,声明即用 |
新增一张报表 = 复制一个 YAML 改几行,执行器一行代码不用动。测试里专门有一条用例验证"两张不同报表共用同一执行器"。
3.2 计算列:formula 声明 + 白名单校验
派生指标(负荷率、峰谷差率、单位容量发电量)是报表需求变化最频繁的地方。把它们做成 formula 声明后,运营侧加指标不再需要发版。
但 formula 是动态执行的表达式——安全边界必须有。这里的实现走白名单校验:只放行数字、四则运算符、括号、已知变量名;__import__、os.system、函数调用一律拒绝(有专门的注入测试用例盯着)。
取舍记录:白名单意味着公式能力有上限(没有 if/嵌套函数)。这十年报表里 95% 的派生指标就是四则运算——为 5% 的复杂需求引入图灵完备的表达式引擎,才是真正的风险。真遇到复杂逻辑,那不是配置的事,是代码的事。
3.3 批量取数打底
配置驱动解决"报表多",批量取数解决"报表慢"——这个在第 1 篇讲透了:无论报表多少列多少测点,取数恒为 1 次查询 + 内存索引。执行器的 [统计] 行每次都输出实际查询次数,性能不是靠感觉,是每次运行都可见。
3.4 统一输出契约
所有报表返回同一种结构:二维数组 + 中文表头 + 两位小数。这个契约带来两个红利:
- 前端零适配——新报表上线,前端一行不改
- AI 侧零改造——Dify Custom Tool 的返回格式永远一致,模型不需要学新的解析规则
四、"一行提示词接入"是怎么发生的
这是本文标题的答案。配置驱动完成之后,接入一张新报表只剩两个动作:
- 工具侧:加一个 YAML(声明列、行、公式)
- AI 侧:在 Custom Tool 的提示词规则里加一句"报表清单里新增 XX 报表,参数范围 Y"
第二点正是第 2 篇防幻觉铁律的落地——写规则不写死数据:提示词里不写死任何测点、指标、表头(它们都在 YAML 和 DB 里动态加载),只写路由规则:"用户要报表 → 调本工具 → 报表 id 从清单匹配"。于是新报表对 AI 的全部影响,就是清单里多一行字。
五、实测输出
=== 月度生产报表 === (时间范围: 2026-07-01 ~ 2026-07-31)
测点 月均负荷(MW) 月最高(MW) 月最低(MW) 负荷率(%)
1号机组 75.60MW 81.36MW 69.88MW 7.56%
...
[统计] 数据库查询次数: 1 次 | 耗时: 9.2 ms
7 个测试用例覆盖:配置加载、二维数组结构、计算列正确性、多报表共用执行器、注入防护。
六、写在最后
这套模式的本质是一条分工原则:变化频繁的放配置,相对稳定的放代码,安全边界用白名单钉死。
- 完整实现(执行器 + 2 个示例配置 + 测试):github.com/yang-shenxu… →
tools/report_tool/ - 配套阅读:第 1 篇(性能)、第 2 篇(防幻觉)、第 3 篇(AI 协作治理)
下一篇计划讲演示环境的搭建思路:怎么让招聘方 clone 下来 30 秒跑出和你简历一致的数字。
说明:数据为模拟生成,脱敏处理,仅用于技术演示。
相关文章
- 实现css文字垂直居中的8种方法 09-15
- AI Agent 的 AG-UI 协议与流式组件渲染实践 09-15
- AI Coding Harness 流程跑全、CI 全绿,为何联调仍会漏场景? 09-15
- 企业 AI 全链路审计落地:从单次请求到完整会话追踪 09-15
- 学习小实例滚动条的简单实现 09-15
- WorkBuddy 从入门到实战:桌面 AI 工作台完整上手指南 09-15