
1. 为什么数据分析平台里的“数据治理”会卡住整条链路1.1 从“有数可用”到“数据可信”的真实距离今年我一直在折腾一个内部的数据分析平台框架上用了 LLM Data Multi-Agents前端接 BI 看板后端接数仓。刚开始跑演示时所有人都很兴奋你跟 Agent 说一句“帮我看看华东区 6 月销售额环比”它自己会选表、写 SQL、做图、给结论体验确实像有个数据分析师坐在旁边。可一上真实业务数据问题就全冒出来了。华东区 6 月销售额算出来是 2 亿可业务口同事说他们系统里看是 1.85 亿。两边都用了同一个数仓为什么结果不一致查了半天发现销售订单表里“金额”字段被上游 CRM 同步任务改过口径原来含税现在不含税更隐蔽的是有部分门店数据在 5 月底做过一次迁移老数据里的维度编码根本没有同步到新编码体系Agent 用旧编码去匹配区域结果丢了一大批订单。这一下让我彻底意识到LLM 再聪明Multi-Agents 再多它也只是在你的数据上面跑。数据本身不可信任何智能化的分析都是空中楼阁。所以这个系列的第二篇我没有马上去聊怎么做更炫酷的 Agent 能力而是扎进数据治理——这件事做不好后面所有环节都会被放大拖累。数据治理这个词在企业里已经提了很多年但在传统 CDH/DW 语境里它更多是偏管理侧的词语元数据管理系统、质量稽核、血缘追踪、权限审批往往是 IT 部门被动响应业务部门感知不到价值。而当 LLM 把数据分析从一个“工具”变成“数字员工”之后数据治理的颗粒度、时效性、执行方式全都变了。Agent 每次答题前都得判断“哪个表是对的”“哪个字段是可信的”“我能不能看这部分数据”这就是把治理能力从后台管理直接推到了分析入口。1.2 LLM 时代治理问题会被放大而不是消失有人问过我既然 Agent 都能理解自然语言了是不是治理规则也可以用自然语言直接告诉它就不用建复杂的治理系统了这是一个非常危险的误区。LLM 确实能“理解”很多规则描述但理解不等于执行。你告诉 Agent “取数时注意过滤掉测试环境的数据”它下一步还是会全表扫描因为它不知道哪个库是测试环境也不知道“环境”这个语义在表结构里该如何表达。更麻烦的是Agent 会一本正经地编造一个它认为合理的条件。这恰恰是数据治理要解决的问题把组织里的数据约定、业务口径、权限边界变成 Agent 可识别、可推理、可校验的机器知识而不是让 Agent 靠“猜”来碰运气。我们平台当时踩过一个典型的坑让 Agent 直接去做跨部门报表分析结果它把不同系统中“用户数”的定义混用了。有的系统统计的是注册用户有的统计的是去重后的登录用户有的统计的是有购买行为的活跃用户。单看每个系统都没错但 Agent 取数时如果只看字段名三个“用户数”会被当作同一个指标最终得出一份完全错误的留存结论。这已经不是 LLM 幻觉问题而是企业数据语义治理不到位的问题。大模型只是忠实地把混乱的语义关系“翻译”成了更严谨的 SQL把原来隐性的脏乱差变成了显性的错误结论罢了。所以在这一篇里我想把数据治理拆开讲清楚在 LLM Multi-Agents 架构下治理到底要治理什么哪些技术点值得优先投入哪些环节最容易翻车。题目里写“数据治理之一”是因为治理本身包罗甚多一篇写不完这篇先聚焦元数据、质量、血缘、访问控制这四个最直接影响 Agent 分析结果的方向。2. Data Multi-Agents 下的治理架构我为什么这么拆2.1 多智能体不是堆角色而是“数据流分工”很多团队一听说 Multi-Agents就常规性地拆一堆 Agent数据接入 Agent、指标问答 Agent、报表生成 Agent、异常预测 Agent……每个名字听着都合理但跑起来就会陷入互相掣肘。比如指标问答 Agent 需要调用数据接入 Agent 拿数但数据接入 Agent 只管连通性不管质量拿到一半脏数据就丢给上层 Agent上层 Agent 又没感知自然出错。我现在的做法是把多智能体理解成一条数据流水线每个环节都有明确的责任和输出标准。所有 Agent 并行不悖但数据流是严格串起来的——先治理、后分析、再呈现。治理类的 Agent 不是挂在边上的临时工而是所有分析 Agent 前方的质检站。基于这个思路我的治理链路里定义了四个基础角色元数据 Agent负责回答“这个表/字段是什么、准不准、怎么理解”。质量 Agent负责回答“这批数据现在能不能用、有什么异常”。血缘 Agent负责回答“这个字段是从哪来的、中间经过哪些加工”。安全 Agent负责回答“当前用户能看哪些数据、字段要怎么脱敏”。这四个角色在平台上并不一定都是独立服务更多时候是共享同一个治理底座对外提供 API。上层 Planner Agent 收到用户问题后会先并行调用这四个治理 Agent 做一次“数据健康度体检”体检通过之后才进入取数和分析阶段。2.2 “治理 Agent 四件套”的内部关系与协作机制一开始我也以为这四个 Agent 各干各的就行。后来发现它们之间的关系必须靠一套共享知识库来打通否则每个 Agent 只掌握局部信息做出的判断经常自相矛盾。举个真实例子。某报表里的“销售额”字段在元数据 Agent 里定义是“不含税、已回款”在质量 Agent 里发现近三天空值率上升到 30%在血缘 Agent 里追溯到是因为上游接口改了字段映射。这几个信息如果分散在三个系统里Planner Agent 无法形成整体判断。所以我在设计上增加了一个事件总线由每个 Agent 在发现异常时向总线推事件其他 Agent 订阅事件更新自己的状态。元数据 Agent 发现字段口径变更马上会通知质量 Agent 重新启用“口径变更期间数据不可信”的标记质量 Agent 发现异常会触发血缘 Agent 去定位根因链路。这样一来四件套就不是四个孤岛而是一张动态更新的知识网。上层分析 Agent 在写 SQL 之前只要问一次“这个字段当前状态是什么”就能拿到一个综合结论而不是只看单一 Agent 的结果。下面是我简化过的类型定义示例伪代码dataclass class FieldHealth: field_name: str semantic_type: str # 例如: monetary_value / user_id / date quality_score: float # 0-1 completeness: float consistency: bool lineage_verified: bool access_level: str # 例如: public / restricted / pii last_verified_at: datetime def health_check(field: str, user_context: dict) - FieldHealth: md metadata_agent.get_field_semantics(field) qa quality_agent.evaluate(field, window7d) lin lineage_agent.trace(field) sa security_agent.check(field, user_context) return FieldHealth(...)这段伪代码代表了数据流水线中“治理前置”的最小单元。实际系统里我会再包一层缓存避免 Agent 每回答一个问题都把全链路跑一遍。2.3 为什么不用单一“超级 Agent”一把梭也见过有人用一个大模型 Agent 把元数据、质量、权限判断全部写在 prompt 里让模型自己推理。短期 demo 确实够用长期维护是噩梦。上下文窗口有限企业级数据治理动辄涉及上千张表、几万个字段prompt 根本塞不下。知识更新困难治理规则是经常变的每次变更都改 prompt不可控而且模型容易被旧知识误导。责任边界模糊出了问题后你很难确认是模型忘了质量规则还是压根没调用质量检测工具。分开成不同 Agent每次决策和行为都有日志排查时能精确到某一条链路。成本控制更优只有需要深度分析时才让轻量模型做路由重任务再交给大模型避免所有问题都打大模型接口。从团队协作角度看拆成独立 Agent 也更贴近组织分工。元数据治理这件事往往由一个数据平台组负责质量稽核由另一个数据质量组负责权限安全由基础架构组负责。系统模块和团队职责对齐后续沟通成本低很多。3. 核心环节落地实录元数据、质量、血缘、权限3.1 元数据 Agent让 Agent 真正“看懂”字段而不是猜字段做数据分析的人都有个直觉看到“sales_amt”就能猜出是销售额看到“crt_time”就能猜出是创建时间。但这种直觉对 LLM 来说既可靠又不可靠。可靠的是它确实能根据命名做出高概率推断不可靠的是一旦字段命名不规范或者同一个缩写在不同表里含义不同猜错一次就是全盘错。我设计元数据 Agent 时思路不是让它去猜而是让它把“猜”的过程变成“查证”的过程。具体分三步字段语义注册每个表在接入平台时通过自动化脚本解析 DDL、数据字典、历史 SQL 脚本生成字段级别的描述并同步人工维护的业务术语表。比如amt字段在字典里登记为“订单实付金额含运费不含退款”user_id登记为“用户体系主键仅包含注册用户”。语义冲突检测元数据 Agent 会定期扫描所有表把所有字段名相似但语义描述不一致的字段找出来形成“疑似同义不同义”清单。这个工作靠规则能完成一半另一半要借助 LLM 做语义聚类。例如user_cnt、uv_cnt、user_num本质都可能是“用户数/访客数”Agent 让模型给出相似度评分再结合字段备注和样例数据自动打标。语义注入模板当上层分析 Agent 准备针对某个字段写 SQL 时元数据 Agent 会把该字段的完整语义描述、取值示例、单位/口径、有效期这些信息拼装成一小段“字段说明书”动态注入到分析 Agent 的 prompt 里。这个机制解决了一个很实际的问题LLM 的统计能力很强但业务口径不是统计出来的是业务定义出来的。比如“GMV”在不同公司有完全不同的算法你无法靠模型悟出来只能依赖元数据去约束。3.2 质量 Agent用自然语言配置校验规则而不是写死脚本数据质量规则如果全部交给工程师写 Python/SQL那治理这件事就会变成永远排不上期的需求桶。所以我给质量 Agent 加了一层自然语言规则翻译器。业务人员或数据分析师可以直接提交这样一句话“订单表里的 order_date 不能为空如果最近一天缺失率超过 5%请在报告里标记告警。”质量 Agent 会把这句话解析成一个可执行的质检任务扫描目标表计算 order_date 的空值率跑批频率设置为天级产出结构化报告。这套能力依赖一个小模型做意图解析再加上模板映射并不需要太复杂的模型。我在实际平台里落地的质检项大概有这几类质检类型自然语言示例底层实现逻辑完整性“订单金额字段不能为空”计算空值率超过阈值告警唯一性“订单号不允许重复”查重复记录数输出重复明细有效性“省份字段必须在标准字典内”枚举匹配检查非法值占比及时性“昨天的数据今天早上8点前必须到位”比较分区表最新可用分区时间与当前时间波动性“销售额环比波动超过30%要提示”对比当日值与历史均值计算 Z-Score口径一致性“本月销售额与上月统计口径必须一致”比对元数据版本号发现变更则触发复核值得注意的是质量 Agent 的告警结果不是只给运维人员看它必须反向影响分析 Agent。在我们的流水线里如果质量 Agent 给某张表打上“质量分低于 0.6”的标签上层 Agent 取数时就会自动被拦截并生成一个解释说明“由于该表数据近 3 日缺失率达到 15%本次分析结果置信度较低建议先检查上游同步任务。”这样的提示比直接在报告里给出错误数字要有价值得多。3.3 血缘 Agent可追溯才不会让错误“背锅”数据分析里最尴尬的场景是报告做出来业务方问“这个数哪来的”。如果回答“从宽表里查的”就是没治理。血缘 Agent 的目标是让每一个产出指标都可以沿着加工链路回溯到源头表同时让每次加工变化都被记录。血缘追踪在实现上分两个层面静态血缘由 SQL 解析器自动解析数仓的 ETL 作业识别每张表 SELECT 了哪些上游表、JOIN 了哪些键、做了哪些转换。这类血缘图比较稳定适合做资产地图。动态血缘在查询分析阶段实时记录 Agent 提交的 SQL 访问了哪些表、哪些字段以及命中了什么质量标签。这一步能让平台知道“用户刚刚的查询依赖了已经被质量胶囊标记的字段”从而在返回结果时主动附加可信度提示。动态血缘我还用来做性能治理。某次 Agent 写了一个带笛卡尔积的查询跑了一个多小时。血缘追踪显示它错误 JOIN 了两张没有关联键的大表。定位后我在查询日志里加了一条识别规则如果 Agent 生成的 SQL 出现 1:N 关联且关联字段不是血缘图中的外键关系就会被安全拦截并退回重写。血缘不仅仅是事后审计更应该作为 Agent 选表时的重要参考。当系统里存在两张表都含有“销售额”字段时血缘 Agent 会告诉上层 Agent一张是 ODS 层原始表一张是经过统一定义的 DWS 层指标表分析场景应该优先选后者。这个“推荐优先取数路径”的能力极大减少了 Agent 在不合适的表上乱取数的频率。3.4 安全 Agent数据脱敏与权限校验是最后一道闸权限问题在 LLM 场景里比传统 BI 更敏感。传统 BI 里每个用户有固定菜单他不会也不容易写出跨权限的 SQL。但 LLM 生成 SQL 时压根不知道你是谁你有多大权限。如果不在 Agent 层加一道强校验很容易出现普通用户查询数据时把用户的手机号、身份证号等敏感字段带出来。我实现的安全 Agent 分两级第一级在取数前做字段级权限判断。用户发起查询后安全 Agent 根据用户的角色列表判断该用户能不能访问这张表能不能访问这些敏感字段如果不能直接把字段从 Agent 可见的 schema 中去掉甚至替换成脱敏后的仿真数据。对 LLM 来说看不到的字段和值就不会平白无故出现在 SQL 里。第二级在 SQL 执行后做结果集守卫。即使前面的过滤已经生效用户也有可能利用 Agent 漏洞构造恶意查询或者说模型误生成把敏感字段带出来。这一级我会在查询结果返回前扫描每一列如果结果集中出现手机号、邮箱、身份证等格式数据而当前用户没有相应权限则自动对该列做掩码处理并在报告里标注“敏感字段已脱敏”。这里有个容易忽略的细节LLM 在生成 SQL 时如果你只是简单给它一个 schema它很容易在 JOIN 时把不相关的表也带进来从而意外访问到无权限字段。我在实际开发中会根据用户权限表提前过滤掉用户不可见的表名和字段名从物理上缩小 Agent 的决策空间。权限表本身也放在治理平台上定期与统一身份认证系统同步。以下是一段简化的权限过滤逻辑def filter_schema_for_user(user_id: str, raw_schema: list[Table]) - list[Table]: allowed_tables access_control.get_user_tables(user_id) visible_schema [] for table in raw_schema: if table.name not in allowed_tables: continue allowed_cols access_control.get_user_columns(user_id, table.name) visible_columns [col for col in table.columns if col.name in allowed_cols] visible_schema.append(Table(table.name, visible_columns)) return visible_schema在跑了一段时间后我发现安全 Agent 的价值不仅在于防泄露它还能反哺质量。安全 Agent 的访问日志记录了每个用户高频查询哪些字段这些“真实需求热度”可以反馈给元数据 Agent帮助确定哪些字段应该优先补全语义描述。治理能力之间不再是割裂的而是互相生长。4. 实际运行中经常翻车的 6 个坑4.1 脏数据把 Agent “带偏”但报告依旧很漂亮最典型的翻车现象是Agent 基于一份质量很差的表生成了汇报图表、摘要、结论什么都有业务方差点拿去开周会。原因不是 Agent 不聪明而是质量 Agent 当时没有配置那张表的完整性校验。等业务方发现问题时已经晚了。后来我规定所有进入分析广度的表如果没有质量评分一律视为“未知质量”不允许直接用于正式报告只能用于探索。同时增加“快照对比”功能Agent 生成结果时会同时展示“如果使用昨日数据会怎样”通过两个版本对比提醒用户数据时效性问题。4.2 元数据语义过时Agent 越用越“自信”还有一次业务方把“销售额”的口径从“含税”调整为“不含税”但元数据 Agent 里的描述还是旧口径。Agent 写 SQL 时完全没意识到口径变化出来的数据全错了。这个问题的根源在于业务变更没有同步到治理平台。解决方法是每次数据加工任务更新后自动下发变更事件给元数据 Agent并触发一个“流通预警”流程。如果某张表存在口径变更所有相关字段的健康状态降级分析 Agent 必须重新确认。这个机制跑起来以后错误结论少了很多。4.3 血缘断裂导致链路无法追溯有一次某张核心表的字段源头被替换了但血缘系统里没有记录新旧字段的数据格式不一致Agent 用旧字段去关联新表导致最终结果多出大量 NULL。后来我在血缘解析上增加了“反向溯源校验”每次查询执行完反向检查结果集中每一列是否与血缘图中的字段路径一致不一致就报警。还有一个小经验SQL 解析不要只解析标准语法还要能处理各种方言比如一些数据库的 limit 语法、开窗函数写法、replace into 等。血缘 Agent 的解析引擎一开始漏掉了很多非标准语法导致图谱不完整。后来我换了一个具备方言扩展能力的解析库并补充了一批历史任务日志进行验证血缘覆盖率才提到 95% 以上。4.4 权限校验和 Agent 推理之间的“递归打架”安全 Agent 要在 SQL 执行前拦截但它拦截条件越复杂Agent 就越容易写出绕过的 SQL。比如我们限制只能查询最近 3 个月数据Agent 可能通过拼时间函数绕过分区过滤把历史数据全查出来。这不是安全 Agent 不够强而是它没有把约束条件直接传递给 SQL 生成层。正确的做法分两层第一层在 schema 注入阶段就把时间分区裁剪条件写死在表定义中Agent 只能看到“分区表近90天”而不是完整表第二层在执行层再校验一次查询的扫描分区数量。如果 Agent 试图扫描全分区立刻熔断。这样既保留了 Agent 的灵活性又卡住了底线。4.5 治理 Agent 自身变成性能瓶颈起初我让治理 Agent 在每次查询前都做一次全量往返结果 SQL 还没写元数据、质量、血缘三个 Agent 的 API 调用已经花了 4 秒多。加上大模型推理时间整个回答过程逼近 20 秒体验很差。后来我加了治理指标缓存把每个表的元数据版本、质量评分、血缘路径按小时粒度缓存到 Redis 里。只有表发生变更或者质量告警时才会强制刷新。实测下来缓存命中时治理检查整体耗时压到了 100ms 级别对上层 Agent 几乎无感知。4.6 LLM 生成列名和治理字典不匹配最让我头疼的是 Agent 从列名里猜不出语义比如一个字段叫a_0001元数据字典里明明有解释但 Agent 没有主动去查直接用这个字段名拼 SQL导致结果出来全是看不懂的内容。这个问题靠 prompt 调优无法根治后来我在 Agent 的输出解析里加了一步“列语义校验”当 SQL 涉及的字段不在可见 schema 列表中时强制要求 Agent 重新生成并将字段语义信息反馈回去。相当于给 Agent 装了一个“查字典”的强制动作。5. 一些个人收尾建议给正在做同类事情的朋友数据治理和 LLM 分析平台的结合说到底还是一个工程问题不是某一个模型能单独解决的。我自己做下来最深的体会是先别急着把概念铺得太大拆出三四个核心治理能力让它们真正在每个查询链路里起作用比建一个“完整数据治理中台”更实际。刚开始我只实现了元数据和质量这两个 Agent血缘和安全都是后面才补的。事实证明先跑通这两个已经能拦下 70% 的错误。再加上血缘追溯和权限校验后整体正确率才有了质的提升。所以如果你也在做一个 LLM Multi-Agents 的数据分析项目建议遵循这个优先级元数据 - 质量 - 血缘 - 权限每一步都要跟真实业务场景绑定验证不要光做内部 Demo。再分享一个小技巧所有治理 Agent 的决策记录都必须落库包含时间、输入 schema、规则命中、输出结论。这不是为了出报告而是为了将来排查问题时有据可依。我踩过好几次坑都是因为没有日志出了问题只能靠人肉猜。有了记录复盘的效率翻倍。下一篇我打算继续写数据治理之二重点放到监控告警、数据分级分类以及如何通过用户反馈闭环持续提升治理规则的质量。也欢迎在评论区聊聊你项目里遇到的数据治理难题尤其是 Agent 被脏数据坑过哪些奇奇怪怪的方式咱们一起攒点经验。