让 AI 助手安全读写业务数据
一句话:把「让 AI 帮忙查数、改数」从「敢不敢」变成「怎么管」——读走只读工具、写走工作流草稿加两道人工确认,而权限全程按提问的那个人算。读完约 20 分钟。
演示环境里已经有成品,先看效果再动手
智能体「文档演示-数据查询助手」(编码 doc_demo_data)已发布,只绑 form_data_page / form_data_get 两把只读工具;四段真跑出来的对话(真调模型、真调工具)挂在三个账号下。用 docadmin / docsales / salesman01(密码均 admin123)登录 AI → AI 助手 → 智能助手,左侧会话列表里以「文档演示-AI读数据-」开头的四条就是本篇素材,点开即第 3 步与第 5 步的对照现场。
两条路,各走各的闸
| 想让 AI 做的事 | 走哪条路 | 拦它的闸 |
|---|---|---|
| 读业务数据 | 对话里选中「绑了只读工具的智能体」,模型自己决定调哪把工具、调几次 | 安全网关六步(身份 / 租户 / 开关 / 工具存在 / 权限串)+ 数据工具自带的表单数据权限校验 |
| 写业务数据 | 助手不直接写:把意图翻成一张工作流草稿卡,你点「确认并运行」才执行;执行到人工闸口再停一次弹确认卡 | 发布期只读校验 + 变更预演 + 「确认并运行」+ 「同意并继续」两道人工确认 |
最关键的一句口径:AI 没有自己的权限。每一次工具调用都以「发起这段对话的人」的身份过权限网关——你在界面上看不到的行,AI 也查不到;你没被授的动作,AI 也做不了。本篇第 3 步的三张截图就是这句话的现场证明。
功能在哪
| 页面 | 路由 | 本教程用它干什么 |
|---|---|---|
| 智能助手 | /ai/agent/assistant | 对话现场:选智能体、看答案、确认工作流草稿 |
| 智能体管理 | /ai/agent/def | 建并发布「绑了只读工具」的智能体 |
| 工具管理 | /ai/agent/tooldef | 看每把工具的风险等级与「需确认」标记 |
| 助手配置 | /ai/agent/config | 总开关、用量配额、已注册工具只读清单 |
| 流程编排 | /ai/agent/workflow | 工作流草稿的执行历史与版本 |
常用操作
第 1 步:建一个「只读」的数据查询智能体
默认平台助手只答平台手册问题,不碰业务数据。要让 AI 读库里的表,得先有一个绑了只读工具的已发布智能体:
- 打开 AI → AI 助手 → 智能体管理,点「新增」;
- 编码
doc_demo_data、名称「文档演示-数据查询助手」; - 人设(系统提示词)里写清纪律:不猜数据(条数与字段值必须来自工具返回)、工具报权限错就原样回传权限串、回答先结论后依据;
- 右列「工具(只读)」里勾
form_data_page(分页查多行)与form_data_get(按主键查单行); - 「保存并发布」。
发布时后端会校验所绑工具全部是只读——想在这里把 form_data_update 这类写工具绑进对话循环是绑不进去的;写只能走工作流 tool 节点或 Plan 确认(第 4 步)。

截图为什么走「查看」而不是「编辑」
已发布的智能体是不可变快照:列表点「编辑」会先弹「派生新草稿版本」确认,改动落在 v2 草稿上、原版本继续服务线上对话(否则同一段对话前后会对不上配置)。只想看配置,用行内「查看」——任意状态可看、纯只读,就是上图这个形态。
工具的风险等级在工具管理与助手配置的只读清单里都能看到,与「要不要人工确认」一一对应:
| 风险 | 需确认 | 本教程涉及的例子 |
|---|---|---|
| 只读 | 可直接跑 | form_data_page / form_data_get / form_list |
| 低风险 | 要确认 | form_data_create(新增表单数据) |
| 中风险 | 要确认 | form_data_update(修改表单数据) |
| 高风险 | 要确认 | form_data_delete(删除表单数据)、form_publish(一键发布表单) |
| 不可逆 | 要确认 | 创建数据表、修改数据表结构 等 |

第 2 步:让业务角色的 Agent 选择器能看到它
智能助手页的 Agent 选择器要拉智能体分页(权限串 agent:def:query)。业务角色默认没有这条授权,选择器里就只剩「默认平台助手」,进页还会闪一条「没有该操作权限」。
补法:在角色资源授权里给角色搜 agent:def:query,加一条「查看 / 允许」。代价要认下来:智能体管理菜单也会对该角色出现(只有查看权限,改不了任何东西)。演示环境给 doc_sales 与 salesman 两个角色都补了这条,所以下面几张截图里这两个角色的侧边栏都带着「智能体管理」——不是截图穿帮,是这条授权的可见副作用。
第 3 步:同一段提问,三个账号三种答案
前三段对话问的是同一句:
文档演示:查一下表单编码 test_demo_verify_supplier(校验示例4-唯一性长度与脱敏)现在一共有几条数据?请先用工具查询,然后只回答两件事:1)总条数;2)第一行的供应商名称。
| 账号 | 拿到的答案 | 为什么 |
|---|---|---|
租户管理员 docadmin | 8 条;第一行「华东电子元件有限公司」 | 无数据权限限制,作为基线 |
行级权限用户 docsales | 2 条;第一行「杭州启凌办公用品有限公司」 | 「仅自己的数据」行级权限对 AI 这条路一样生效 |
普通员工 salesman01 | 拒答,并原样给出权限串 infra:form-design-run:test_demo_verify_supplier:query | 这张表单是老形态资源族,:query 动作行默认效果 = 拒绝 |
基线:8 条,与配置行级数据权限第 5 步的管理员视角一致。

行级权限生效:同一句提问,docsales 只拿到自己名下的 2 条。注意输入区 Agent 选择器锁在「文档演示-数据查询助手」上(会话绑定后不可中途换)——锁图标旁边那个名字,就是这段对话真正在用的智能体。

显式拒绝:salesman01 没被授这张表单的任何资源,工具调用被数据权限校验拦下;助手不重试、不换工具绕,而是把需要的权限串原样告诉你,照着去授权即可。

AI 不会告诉你「其实还有 6 行」
行过滤是把条件拼进 SQL 的静默过滤:docsales 这一问拿到的 2 条就是他的全部真相,助手无从知道另外 6 行存在,答案里也不会留任何痕迹。想改变某人通过 AI 看到的范围,改的是角色资源授权,不是提示词。
第 4 步:写操作——助手不写,它起草工作流让你确认
在对话里提写意图(「给某表加一行」「把这条改成那条」),对话循环里的写工具一律拒绝;助手改走另一条路:产出一张工作流草稿卡,上面有节点预览、执行顺序和变更预演(「点了确认并运行之后,平台上会多出/改掉什么」),页脚是「取消 / 确认并运行」。


点「确认并运行」后才真正执行;执行到 hitl.confirm 人工闸口再停一次,聊天里弹确认卡,列出变更清单(动哪张表、哪几行、前后值),「同意并继续」才落库,「拒绝」则整单收尾不写。变更清单里每一项都带预演标签:预演通过 / 预演不通过 / 本次没校验。

「本次没校验」不等于「预演通过」
黄色标签 NOT_PROBED 的含义是这一项本次没跑试探(比如它依赖上一步的运行时产物,干跑时还不存在),不是「校验过了」。看到它别当成绿灯:确认卡里逐行核对前后值,才是落库前最后一道闸。含「预演不通过」或不可逆动作的清单会自动展开,就是提醒你逐条看。
第 5 步:没菜单的人,AI 也读得到?——塌缩族的默认放行
第四段对话换了个表单:salesman01 问 doc_device_ledger(文档演示-设备台账,从零搭建一个应用新建的那张)「一共几条」——3 条,全读到了。他没被授这张表单的任何资源,侧边栏里也没有这个入口。

原因不在 AI,在资源族的形状:
| 资源族形状 | 例子 | 链上没授权时的兜底 | salesman01 的结果 |
|---|---|---|---|
| 老形态:数据集 + 各动作子资源 | test_demo_verify_supplier | :query 动作行默认效果 = 拒绝 | 显式拒绝(第 3 步第三张图) |
| 新形态(权限塌缩):只有一行 DATASET 身份资源 | doc_device_ledger | 身份行默认效果 = 允许 | 放行,3 条全读到 |
这不是 AI 越权,是数据接口本身的兜底口径
把同一段话换成浏览器里直接调这张表单的数据分页接口,结果一样是 200 + 3 行——AI 只是把这条本来敞开的路走了一遍,而且诚实地把结果告诉你了。上线任何新发布表单后,把「没授权的人能不能读到数据」当成验收项:要收紧,就给该数据集补一条 :query 的显式「拒绝」,或按配置行级数据权限配行级过滤。
直达路由给的是 404 页,不是 403
salesman01 在地址栏直接敲这张表单的运行时路由,前端落在「抱歉,您访问的页面不存在」——路由守卫按菜单可见性拦,不给 403 页。所以「页面打不开」和「数据读不到」是两件事,要分开验:前者看菜单授权,后者看数据集的默认效果与授权行。
视角对照
| 视角 | 在智能助手里的表现 |
|---|---|
租户管理员 docadmin | 同一问拿到全部 8 条;能建 / 发布智能体;能看用量看板与助手配置 |
行级权限用户 docsales | 同一问只拿到自己名下的 2 条;列级 / 字段级限制同口径生效 |
普通员工 salesman01 | 老形态表单被显式拒(答案带权限串);新形态表单读得到(第 5 步的坑);写意图一律转工作流草稿 + 两道确认 |
进阶
- 配额与总开关:助手配置——「没有配置配额 = 不限制(但仍然全量计量)」,达到上限只拒绝新提问、不中断进行中的对话;
- 工具的风险等级是代码声明:在工具管理里改展示名不影响风险判定,把写工具降险成只读属于「放松安全约束」,要二次确认并留审计;
- 工作流草稿的节点、体检与沙箱:流程编排与工作流编辑器;
- 谁在什么时候用 AI 花了多少:用量看板(按用户 / 智能体 / 工作流维度出账)。
常见问题
Q:AI 会绕过行级权限吗? A:不会。工具调用以发起人身份过安全网关,行 / 列 / 字段限制与界面同口径——第 3 步的 8 条 vs 2 条就是现场对照。
Q:为什么我们角色在 Agent 选择器里看不到自建智能体? A:缺 agent:def:query(第 2 步)。补上后选择器就有了,代价是智能体管理菜单对该角色可见(只读)。
Q:对话里让 AI 删数据,它真删了吗? A:没有。写意图转工作流草稿,「确认并运行」与确认卡「同意并继续」两道都点了才落库;任一步点取消 / 拒绝都不写。
Q:助手答「没有权限」之后,会自己想办法绕吗? A:不会重试、不会换工具绕。答案里原样给出需要的权限串(如 infra:form-design-run:test_demo_verify_supplier:query),拿这串去角色资源授权里勾即可。
Q:关了助手总开关,进行中的对话会断吗? A:不会中断,只拒绝新提问(助手配置信息条原话)。
Q:怎么复核「AI 到底以谁的身份在跑」? A:权限诊断:选那个提问的用户、填工具需要的权限串诊断一次,命中明细与 AI 拿到的结果应当一致。
