AI Agent结合知识库解释指标口径——经营问答中的知识结构、KFS MCP Server与效果评估
文章目录
- 每日一句正能量
- 前言
- 1. 背景与问题
- 2. 环境与数据
- 3. 复现过程
- 4. 方案实施
- 4.1 指标知识库必须结构化
- 4.2 稳定标识使用 metric_code
- 4.3 指标别名
- 4.4 知识检索工具
- 4.5 版本必须由时间选择
- 4.6 指标定义与 SQL 模板关联
- 4.7 KFS MCP Server 不暴露任意 SQL
- 4.8 服务端二次校验指标版本
- 4.9 MyBatis 参数化实现
- 4.10 动态维度白名单
- 4.11 知识库权限和数据权限是两回事
- 4.12 多租户隔离
- 4.13 数据库最小权限
- 4.14 结果脱敏
- 4.15 数据时效必须进入答案
- 4.16 工具调用流程
- 4.17 独立查询可以并行
- 4.18 缓存指标知识
- 4.19 数据结果缓存
- 4.20 缓存 Key 必须包含口径版本
- 4.21 回答模板
- 4.22 为什么要在回答里显示口径
- 4.23 知识库变更流程
- 4.24 版本不可覆盖
- 4.25 异常结构化
- 4.26 事务边界
- 4.27 如果需要修改指标口径
- 4.28 效果评估
- 4.29 构造评测集
- 4.30 一个示例对比实验
- 5. 结果对比
- 6. 风险与复盘
- 结语

每日一句正能量
🔵 格局:从“是非”到“风景”的跃迁
“提升自己的格局,很多琐碎的烦恼自然会烟烟云散。”
当你的认知从“街头巷尾”升至“高空俯瞰”,那些曾令你纠结的人情往来、微小得失,便如地图上的褶皱,在更大的版图中自然舒展、不再刺眼。
前言
经营问答里最危险的问题,往往不是 SQL 写错,而是“指标说对了名字,却说错了口径”。
例如用户问:
“这个月 GMV 为什么下降?”
听起来只是一个经营分析问题,但系统真正需要先回答:
这里的 GMV 到底指什么?
是否含退款订单?
是否含取消订单?
按下单时间还是支付时间统计?
是否包含税费、运费?
跨境订单是否折算成人民币?
历史月份是否使用当时口径,还是当前口径回算?
如果这些定义没有统一,Agent 即使查出一个数字,也可能只是“算对了一个错误指标”。
因此,AI Agent 做经营问答时,不能只连接数据库,还需要一层结构化知识库保存指标口径;同时,真实数据查询仍要通过受控工具层执行。本文沿用前文的架构约定:KFS MCP Server 指面向 KFS/数据库能力的 MCP 工具服务层,用于向 Agent 暴露受控查询工具。公开资料中,KFS 官方产品是 Kingbase FlySync;MCP 官方规范则允许 Server 暴露带输入 Schema 的工具供模型调用。
核心思路可以概括成一句话:
知识库负责解释“指标是什么”,
MCP 工具负责查询“数据是多少”。
两者必须在同一个口径版本、时间范围和权限上下文中工作。
1. 背景与问题
企业里一个“销售额”可能有五种定义:
下单金额
支付金额
确认收货金额
扣除退款后的净额
财务入账金额
业务部门都可能简称:
销售额
这类语义冲突是经营问答最典型的问题。
假设用户问:
“华东区 7 月销售额同比增长多少?”
Agent 如果直接根据字段名猜:
SUM(order_amount)
很可能错误。
真正流程应该先确认:
当前用户所在业务域默认的“销售额”定义
例如:
metric_code = PAID_GMV
definition = 支付成功订单实付金额总和
time_basis = pay_time
refund_rule = 不扣除后续退款
currency_rule = 按支付时币种折算人民币
然后再去查数据库。

这意味着经营问答 Agent 的上下文至少由两类事实组成:
语义事实:
指标定义、公式、适用范围、版本。
数据事实:
某时间、某区域、某渠道的实际数值。
把两者混在 Prompt 里硬编码,很快会失控。
2. 环境与数据
示例环境:
JDK 21
Spring Boot 3.3+
KingbaseES / PostgreSQL 类数据库
KFS MCP Server
MyBatis / JDBC
Redis
Embedding / 全文检索
OpenTelemetry
支付订单表:
CREATE TABLE payment_order (
id BIGINT PRIMARY KEY,
order_no VARCHAR(64) NOT NULL,
region_code VARCHAR(16) NOT NULL,
channel_code VARCHAR(32) NOT NULL,
order_amount NUMERIC(18,2) NOT NULL,
pay_amount NUMERIC(18,2) NOT NULL,
refund_amount NUMERIC(18,2) NOT NULL DEFAULT 0,
pay_status VARCHAR(16) NOT NULL,
order_time TIMESTAMP NOT NULL,
pay_time TIMESTAMP NULL
);
指标定义表:
CREATE TABLE metric_definition (
metric_code VARCHAR(64) PRIMARY KEY,
metric_name VARCHAR(128) NOT NULL,
metric_aliases TEXT,
definition TEXT NOT NULL,
formula_text TEXT NOT NULL,
time_basis VARCHAR(32) NOT NULL,
freshness VARCHAR(32) NOT NULL,
owner_dept VARCHAR(128) NOT NULL,
security_level VARCHAR(32) NOT NULL,
enabled BOOLEAN NOT NULL
);
指标版本表:
CREATE TABLE metric_version (
id BIGINT PRIMARY KEY,
metric_code VARCHAR(64) NOT NULL,
version_no VARCHAR(32) NOT NULL,
effective_from TIMESTAMP NOT NULL,
effective_to TIMESTAMP NULL,
definition TEXT NOT NULL,
formula_text TEXT NOT NULL,
change_reason TEXT,
approved_by VARCHAR(64) NOT NULL,
UNIQUE(metric_code, version_no)
);
维度白名单:
CREATE TABLE metric_dimension (
metric_code VARCHAR(64) NOT NULL,
dimension_code VARCHAR(64) NOT NULL,
dimension_name VARCHAR(128) NOT NULL,
allowed BOOLEAN NOT NULL,
PRIMARY KEY(metric_code, dimension_code)
);
3. 复现过程
3.1 只靠模型记忆指标定义
最简单实现:
系统 Prompt:
GMV 就是成交总额。
这几乎没有工程价值。
因为:
口径会变
部门间定义不同
历史问答需要旧版本
Prompt 无法审计
一旦财务部门把 GMV 改为:
扣除全额退款
旧 Prompt 就过期了。
3.2 直接让模型查指标表也不够
可以暴露:
SELECT * FROM metric_definition
让 Agent 自己查。
问题是模型可能:
查错别名
忽略历史版本
忽略权限
一次拉回全部口径
指标解释需要一个专门的知识检索层,而不是“随便查数据库”。
3.3 同名指标跨部门冲突
例如:
运营 GMV:
支付成功金额
财务 GMV:
确认收入金额
用户只说:
GMV
Agent 必须结合:
用户部门
工作空间
默认业务域
问题上下文
选择正确口径。
否则数据查询即使准确,也是在回答另一个部门的问题。
3.4 历史口径问题
用户问:
“2025 年 12 月和 2026 年 1 月 GMV 为什么跳变?”
假设:
2026-01-01
开始 GMV 改口径。
如果系统永远读取当前定义,就会错误地把 2025 年数据按新口径解释。
所以知识库必须支持:
effective_from
effective_to
4. 方案实施
4.1 指标知识库必须结构化

每个指标至少应包含:
metric_code
metric_name
aliases
definition
formula
time_basis
dimensions
freshness
owner
security_level
effective period
不要只存一段 Markdown。
结构化后才能:
版本控制
权限过滤
自动校验
SQL 模板关联
4.2 稳定标识使用 metric_code
名称可以变:
成交额
支付成交额
实付GMV
但内部主键:
PAID_GMV
应该稳定。
Agent 最终工具调用也应传:
metricCode
而不是自然语言名称。
4.3 指标别名
例如:
{
"metricCode": "PAID_GMV",
"metricName": "支付GMV",
"aliases": [
"成交额",
"支付成交额",
"实付金额"
]
}
但别名并不意味着完全等价。
如果某别名在另一个业务域代表其他指标,应在检索阶段加入:
domain
department
tenant
约束。
4.4 知识检索工具
MCP Tool:
{
"name": "resolve_metric",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string"
},
"businessDomain": {
"type": "string"
},
"asOfTime": {
"type": "string"
}
},
"required": [
"query",
"businessDomain"
]
}
}
输出:
{
"metricCode": "PAID_GMV",
"metricName": "支付GMV",
"version": "v3",
"definition": "支付成功订单的实付金额总和",
"timeBasis": "pay_time",
"freshness": "near_realtime",
"allowedDimensions": [
"region",
"channel"
]
}
4.5 版本必须由时间选择
SQL:
SELECT
mv.metric_code,
mv.version_no,
mv.definition,
mv.formula_text
FROM metric_version mv
WHERE mv.metric_code = ?
AND mv.effective_from <= ?
AND (
mv.effective_to IS NULL
OR mv.effective_to > ?
)
ORDER BY mv.effective_from DESC
LIMIT 1;
这样问历史月份时能自动取当时口径。
4.6 指标定义与 SQL 模板关联
不要让模型根据自然语言定义临时猜 SQL。
可以增加:
CREATE TABLE metric_query_template (
metric_code VARCHAR(64) NOT NULL,
version_no VARCHAR(32) NOT NULL,
template_code VARCHAR(64) NOT NULL,
sql_template TEXT NOT NULL,
PRIMARY KEY(
metric_code,
version_no,
template_code
)
);
例如:
SELECT
SUM(pay_amount)
FROM payment_order
WHERE pay_status = 'SUCCESS'
AND pay_time >= ?
AND pay_time < ?;
当口径版本变化时:
定义
公式
SQL模板
一起版本化。
4.7 KFS MCP Server 不暴露任意 SQL
经营问答场景更适合:
query_metric
compare_metric
breakdown_metric
而不是:
execute_sql
工具:
{
"name": "query_metric",
"inputSchema": {
"type": "object",
"properties": {
"metricCode": {
"type": "string"
},
"metricVersion": {
"type": "string"
},
"startTime": {
"type": "string"
},
"endTime": {
"type": "string"
},
"dimensions": {
"type": "array"
},
"filters": {
"type": "object"
}
},
"required": [
"metricCode",
"metricVersion",
"startTime",
"endTime"
]
}
}
4.8 服务端二次校验指标版本
不能完全相信模型传入:
metricVersion
服务端应再次校验:
该版本是否存在
时间是否匹配
用户是否有权限
维度是否合法
模型只是调用方,不是信任边界。
4.9 MyBatis 参数化实现
<select id="queryPaidGmv"
resultType="MetricValue">
SELECT
SUM(pay_amount) AS metric_value
FROM payment_order
WHERE pay_status = 'SUCCESS'
AND pay_time >= #{startTime}
AND pay_time < #{endTime}
<if test="regionCode != null">
AND region_code = #{regionCode}
</if>
</select>
这里所有值参数都用:
#{}
维度字段本身如果需要动态选择,则必须经过服务端白名单。
4.10 动态维度白名单
错误:
GROUP BY ${dimension}
如果 dimension 直接来自 Agent,不安全。
服务端:
String column =
switch (dimension) {
case "region" -> "region_code";
case "channel" -> "channel_code";
default ->
throw new InvalidDimensionException();
};
只有固定映射后的列名才能进入 SQL。
4.11 知识库权限和数据权限是两回事
用户可能:
能知道“利润率”的定义
但不能查看利润率真实数值。
也可能:
只能知道本部门指标定义。
所以要分别维护:
knowledge ACL
data ACL
不能因为能检索指标解释,就自动获得数据库查询权限。
4.12 多租户隔离
所有知识库检索都带:
tenant_id
所有 MCP Tool 同样带租户上下文,但该上下文最好从鉴权会话注入,而不是让模型自由填写。
4.13 数据库最小权限
Agent 查询账号:
agent_metric_reader
只访问指标视图:
GRANT SELECT
ON v_metric_payment
TO agent_metric_reader;
不要直接开放所有原始明细表。
4.14 结果脱敏
经营指标一般是聚合数据,但下钻时可能出现:
客户名称
手机号
订单号
MCP Server 应根据:
role
securityLevel
决定是否返回。
4.15 数据时效必须进入答案
如果指标定义:
freshness = T+1
用户问:
“今天利润率是多少?”
Agent 不应该把昨天最后一次数据装成实时值。
回答应该明确:
当前该指标为 T+1,
最新可用数据截至昨日。
4.16 工具调用流程
一个标准问题:
“昨天华东 GMV 比上周同一天低多少?”
建议:
Tool 1:
resolve_metric(
query="GMV",
domain="operation",
asOfTime="yesterday"
)
Tool 2:
query_metric(
metricCode="PAID_GMV",
version="v3",
period="yesterday",
region="east"
)
Tool 3:
query_metric(
metricCode="PAID_GMV",
version="v3",
period="last_week_same_day",
region="east"
)
然后模型做比较。
不要先猜 SQL,再回头解释口径。
4.17 独立查询可以并行
两个时期的数据:
昨天
上周同日
如果口径版本相同,可以并行 Tool Call。
但如果跨越口径切换日,必须先分别解析:
asOfTime
对应版本。
4.18 缓存指标知识
指标定义变化频率低,可以缓存:
metricCode + version
TTL:
5~30 分钟
更重要的是:
审批发布新版本时主动失效。
4.19 数据结果缓存
例如昨天 GMV:
已经封账
可缓存较久。
今天实时 GMV:
TTL 很短
缓存策略应跟:
freshness
绑定,而不是所有指标固定 5 分钟。
4.20 缓存 Key 必须包含口径版本
错误:
gmv:east:2026-07-01
正确:
metric:PAID_GMV:v3:east:2026-07-01
否则口径升级后可能命中旧定义下的数据。
4.21 回答模板
一个可信回答至少包含:
1. 数值
2. 变化
3. 指标口径
4. 时间范围
5. 数据时效
例如:
昨日华东区支付GMV为 1.82 亿元,
较上周同日下降 7.4%。
这里“支付GMV”按支付成功订单的实付金额统计,
以 pay_time 作为归属时间,不扣除后续退款。
当前数据为近实时口径。
不要只回答:
下降 7.4%。
4.22 为什么要在回答里显示口径
经营指标本身具有歧义。
用户如果看到:
口径说明
更容易判断答案是否符合自己的业务语境。
而且这也减少:
“AI 编了一个数字”
的信任问题。
4.23 知识库变更流程
指标修改不应该让开发人员直接改数据库。
建议:
提出变更
-> 指标 Owner 审核
-> 数据团队验证公式
-> 生效时间确认
-> 发布新版本
-> 刷新缓存
-> Agent 测试集回归
4.24 版本不可覆盖
不要把:
v3
原地改掉。
应该:
v4
新增。
历史问答才能复现。
4.25 异常结构化
指标不存在:
{
"code": "METRIC_NOT_FOUND",
"retryable": false
}
口径歧义:
{
"code": "METRIC_AMBIGUOUS",
"candidates": [
"PAID_GMV",
"REVENUE_GMV"
]
}
权限不足:
{
"code": "METRIC_FORBIDDEN",
"retryable": false
}
数据库超时:
{
"code": "METRIC_QUERY_TIMEOUT",
"retryable": true
}
模型可以根据错误类型采取不同动作。
4.26 事务边界
指标解释:
只读
指标查询:
只读
可以使用:
@Transactional(readOnly = true)
public MetricResult query(...) {
...
}
Agent 不应该拥有:
BEGIN / COMMIT / ROLLBACK
工具。
4.27 如果需要修改指标口径
这是管理操作,不能让普通经营问答 Agent 直接完成。
应使用独立:
metric_admin
工具,并要求:
管理员角色
审批号
版本号
生效时间
审计
4.28 效果评估

至少评估:
Metric Match Accuracy
Numeric Accuracy
Tool Calls / Request
Unauthorized Access
Freshness Match
Definition Coverage
4.29 构造评测集
例如 200 条:
简单指标
同义词
跨部门同名指标
历史口径
实时/T+1冲突
权限不足
多维度下钻
不存在指标
每条都标注:
正确 metric_code
正确 version
正确 SQL 结果
期望安全行为
4.30 一个示例对比实验
基线:
只给模型指标名称 + 数据库工具
优化后:
结构化指标知识库
+
版本解析
+
受控 MCP Tool
示例结果:
| 指标 | 基线 | 优化后 |
|---|---|---|
| 指标匹配准确率 | 78% | 96% |
| 数值正确率 | 84% | 98% |
| 平均 Tool Call | 4.1 | 2.6 |
| 口径说明覆盖率 | 41% | 97% |
| 越权访问 | 2 次 | 0 次 |
以上数字是实验模板,正式参赛时应替换为实际测试结果。
5. 结果对比
改造前
流程:
用户问指标
-> 模型猜指标含义
-> 模型直接调用数据库
-> 返回数字
问题:
同名指标易混淆
历史口径无法复现
工具调用多
答案缺少口径
权限控制粗
改造后
流程:
问题
-> 知识库解析 metric_code
-> 解析时间对应版本
-> 校验维度和权限
-> KFS MCP Server 查询真实数据
-> 结果校验
-> 回答中附带口径与时效
这样“解释”与“取数”不再混为一谈。
最重要的变化是:
Agent 不再自己发明指标定义。
6. 风险与复盘
6.1 知识库错误比模型错误更隐蔽
如果指标库本身写错:
所有 Agent 都会稳定地答错。
所以知识库必须有 Owner 和审批流程。
6.2 指标版本管理不能省
经营指标会变化。
没有版本:
历史分析不可复现。
6.3 同名指标要允许歧义,而不是强猜
如果上下文不足:
GMV
同时匹配两个指标,系统应该返回候选,而不是擅自选择。
6.4 权限不只是数据库权限
知识定义本身也可能敏感。
例如:
风控命中率
客户流失风险
成本利润率
可能只允许部分角色查看。
6.5 缓存必须携带 metric version
否则口径升级后最容易出现:
解释是新口径,
数据却来自旧缓存。
6.6 数据时效必须显式
T+1 指标不能包装成实时指标。
Agent 必须把:
数据截止时间
告诉用户。
6.7 模型不能成为授权系统
无论模型是否“理解用户有权限”,真正权限判断都必须在:
知识检索
MCP Server
数据库
执行。
6.8 效果评估必须同时看数字与解释
一个数字正确但口径错误的答案,仍然是错误答案。
所以:
Numeric Accuracy
+
Definition Accuracy
必须一起评估。
结语
经营问答真正难的地方不是把 SQL 交给 AI,而是建立:
指标语言
和:
数据库事实
之间稳定、可审计的映射。
成熟架构应该是:
指标知识库
-> 解析 metric_code 和 version
-> Agent 规划
-> KFS MCP Server 受控工具
-> 数据库查询
-> 口径与数据联合校验
-> 生成经营回答
可以把全文总结为一句话:
经营问答先解释“怎么算”,
再查询“是多少”,
最后才讨论“为什么”。
当指标定义、公式、版本、权限和真实查询结果全部成为可治理的数据资产后,AI Agent 才不会只是一个会“猜指标”的聊天机器人,而能真正成为可信的经营分析入口。
转载自:https://blog.csdn.net/u014727709/article/details/165357427
欢迎 👍点赞✍评论⭐收藏,欢迎指正
更多推荐


所有评论(0)