返回资讯中心
外部精选
软件工程
#工程实践#架构

AI 改变的是数据接口,而不是查询引擎

AI 智能体如今可以生成分析代码、从对象存储读取文件,并将运维数据转为结构化报告。这是否意味着数据湖、湖仓一体和 SQL 引擎已经过时?我们在对一场大型容灾演练做自动化分析时遇到了这个问题。我们最初的可行方案是:将 30 秒粒度的服务指标以 Parquet 格式存入兼容 S3 的对象存储,使用 DuckDB 进行确定性聚合,再由 AI 智能体对故障转移结果进行分类并给出证据说明。这个原型在没有共享湖仓的情况下也能工作,但并不是因为查询…

InfoQ 中国作者:Peihao Yuan2026/11/3 · 今天16 分钟阅读中文

以下正文同步自 InfoQ 中国,版权归原站所有,已转换为易读排版。

AI 智能体如今可以生成分析代码、从对象存储读取文件,并将运维数据转为结构化报告。这是否意味着数据湖、湖仓一体和 SQL 引擎已经过时?我们在对一场大型容灾演练做自动化分析时遇到了这个问题。我们最初的可行方案是:将 30 秒粒度的服务指标以 Parquet 格式存入兼容 S3 的对象存储,使用 DuckDB 进行确定性聚合,再由 AI 智能体对故障转移结果进行分类并给出证据说明。这个原型在没有共享湖仓的情况下也能工作,但并不是因为查询引擎消失了。恰恰相反,引擎变成了嵌入在智能体工作流内部的组件。本文将讲解这个架构,介绍确定性计算与概率性推理之间的实用划分,并给出四个判断依据,用来决定什么时候用嵌入式引擎就足够,什么时候需要托管湖仓。

这个问题并不是头脑风暴空想出来的,而是在一个真实工作流成功产出第一份报告之后出现的。当时我们正在分析一次容灾隔离演练。演练中,一个区域被有意隔离,流量预期会转移到幸存区域。对每一个服务,我们都需要回答三个问题:

我们以 30 秒粒度导出服务指标,存为 Parquet 文件放到兼容 S3 的对象存储中,然后让 AI 智能体生成结构化分析报告。当这个工作流端到端跑通后,一个诱人的想法就出现了:

既然智能体能从对象存储读取文件并给出答案,那为什么我们还需要表、目录、湖仓或 SQL?

这个问题听起来合乎情理,因为面向用户的交互方式已经变了。工程师不再需要打开仪表盘或者手写查询,而是直接让智能体分析演练数据。智能体会识别相关数据,按需生成 DuckDB SQL 或者 Python 代码,通过确定性工具执行分析,再解释发生了什么。举个例子,为了验证流量是否在故障转移时从 A 区转移到了 B 区,智能体会针对预设的表集合与时间范围生成一条只读的 DuckDB 查询。执行前,这条查询会经过白名单校验,仅允许访问许可的数据集与操作,随后在沙箱分析运行时中执行。运行时返回结构化查询结果,再由确定性应用代码规整成事实数据包,里面包含分区域流量、时间戳、变化百分比等字段。一条简化的示例查询如下:

generated_sql = """SELECT region, SUM(request_count) AS requestsFROM traffic_metricsWHERE ts BETWEEN :start_time AND :end_timeGROUP BY region"""validate_sql( generated_sql, allowed_tables={"traffic_metrics"}, allowed_operations={"SELECT"},)rows = sandbox.execute( generated_sql, params={ "start_time": exercise_start, "end_time": exercise_end, },)fact_packet = { "metric": "request_count", "window": [exercise_start, exercise_end], "by_region": { row["region"]: row["requests"] for row in rows },}

复制代码

在这个简化示例里,智能体只负责生成分析查询。确定性校验层会在执行前拦截对白名单外的表或非只读操作的访问。查询在沙箱环境运行后,返回的数据行会由应用代码转换成结构化事实数据包。大模型拿到的是这个数据包(例如 A 区、B 区的请求量),而不是由模型自己编造或直接估算这些数值。

容灾分析的难点不在于检索时序数据,而在于判断这个时间序列意味着什么。假设 A 区被隔离,B 区保持正常,一次健康的故障转移应该产生一个可识别的序列:

每一个结论都需要上下文支撑。QPS 上升不等于故障转移成功,涨幅可能不足以承接隔离区域流失的流量。成功率下降也不代表容灾失败,指标里可能包含预期内的业务拒绝请求。切换瞬间的延迟尖峰也可能无害,只要系统能快速回到稳态。因此我们设置了两组基线和一个稳态窗口:

针对每个服务,确定性代码会计算出流量吸收率、SLO 违规情况、延迟变化、持续劣化时长等事实。智能体再结合服务、演练配置和已有证据对这些事实进行解读。这个区分至关重要:难点往往在于判断,但判断只有在底层事实是确定性的时候才可信。

该工作流分为三个逻辑层:数据准备、确定性计算和智能体驱动的解释,并将可复现性视为硬性需求。数据准备层使用可复用的 DuckDB 构建逻辑——生成一次即可复用——把原始指标转换为对象存储中的自描述资产。对于每个分析请求,智能体选择相关输入,生成受约束的 SQL 或 Python 代码,并编排执行确定性计算。智能体解释由此产生的结构化事实包,并生成最终报告。在整个工作流中,输入数据、配置、可复用构建逻辑、确定性事实和智能体执行元数据都被保留下来,以便后续能够重建、重放和评估该分析。

图 1. AI 智能体发起并调度分析流程,确定性工具计算事实,智能体解读事实数据包。来源:作者自制示意图,由 ChatGPT 辅助绘制。

s3://<bucket>/<root-prefix>/ index.json <exercise-id>/ manifest.json exercise_config.json metrics-*.parquet service_dimension.parquet

复制代码

service_dimension.parquet 存放服务元数据,如归属团队和服务等级。

清单文件(manifest)很重要,一堆零散文件不等于可信的数据资产。使用者需要知道里面有什么、使用的是什么 Schema、写入是否完成、后续能不能校验文件完整性。

存储边界的两侧都使用了 DuckDB。在摄入阶段,它读取原始指标记录、排序、写入压缩 Parquet 文件,并为 manifest 生成校验统计信息。在分析阶段,它直接读取 Parquet 文件,过滤目标时间窗口,关联服务元数据,并计算供智能体使用的事实包。该架构受益于 DuckDB 的若干特性:

这并不是说 DuckDB 在所有场景下都优于 Spark、Trino 或者托管湖仓。核心原因只是:当前负载还不需要一套分布式共享查询引擎。

智能体并不会收到数十万条原始指标,然后自己去统计错误或计算延迟均值。相反,它收到的是每个服务精简的、确定性的证据数据包。一个简化的证据包如下例所示:

{"service_id": "service-a","exercise_window": "post-cutover-steady-state","expected_failover_qps": 1200,"observed_qps_increase": 910,"traffic_absorption_ratio": 0.758,"success_rate_baseline": 0.9992,"success_rate_during_exercise": 0.9941,"service_slo": 0.9990,"p99_latency_baseline_ms": 84,"p99_latency_during_exercise_ms": 191,"sustained_degradation_minutes": 18,"data_quality_flags": []}

复制代码

智能体使用这个证据包来对结果进行分类、解释支持性证据,并提出下一步排查方向。相应的输出可能是:

{"classification": "partial_failover","confidence": "high","evidence": ["The surviving region absorbed approximately 76% of the expected traffic.","Availability remained below the service SLO during the steady-state window.","The p99 latency increase was sustained for 18 minutes."],"recommended_action": "Review routing capacity and downstream dependency limits."}

复制代码

简单的基于阈值的规则并不总是够用。例如,在故障转移后,某个服务的 p99 延迟阈值可能暂时超标,但流量已经正常转移、可用性仍在服务目标之内。一个把任何阈值违规都视为失败的规则会把该服务判定为已劣化。而智能体可以比较过渡期窗口与稳态窗口,识别出延迟在几分钟内回到了基线,判定这是一次伴随短暂抖动的成功切换,而不是持续性容灾故障。

更重要的是,有些情况包含相互冲突的证据,无法通过单一阈值或时间规则来解决。一个服务可能吸收了预期流量并恢复了自身延迟,但由于下游依赖已接近饱和,依然存在风险。反过来,一个 Tier-2 异步服务可能出现临时积压增加,但未违反可用性目标;同样的模式若出现在 Tier-0 同步依赖中,就必须升级处理。在这些情况下,确定性层仍然产生底层事实(即流量转移、延迟、成功率、积压、依赖饱和度、服务等级和 SLO 状态),智能体将这些事实与服务上下文结合,判断哪些证据优先级更高、事件该如何归类。

因此,智能体的价值不在于取代确定性计算,而在于解决依赖上下文、相互冲突的证据——否则我们就要维护越来越多、每个服务单独定制的规则。

这种划分可以避免一种常见反模式——把 LLM 当作查询引擎。语言模型不应该读取数十万行数据并统计错误数、百分位数或平均值。这种做法速度慢、Token 消耗高,且难以复现。更重要的是,它把确定性工作交给了概率性系统。更安全的模式是:

要求大模型基于数据包内字段给出结论,同时保留输入、生成代码、执行元数据、输出,用于重放和审计。

智能体可以决定要调查哪个问题、动态生成受约束的 DuckDB SQL 或 Python,并调度执行。代码的生成过程可以带有概率性,但最终数值事实必须来自确定性执行,而不是大模型凭空算出。

跨服务上游采集任务由并发 worker 执行,耗时大约一小时。由此产生的分析数据集足够紧凑,嵌入式引擎可以在靠近智能体的位置完成计算,不需要引入共享数据平台。这点很重要:架构决策要贴合真实负载,而不是看到“大数据”标签就上重型组件。一百多万行数据听起来很多,但仅凭行数并不能作为部署分布式湖仓的理由。列数、压缩方式、查询形态、并发量、访问模式、数据迁移成本都需要纳入考量。

对于某个服务,确定性执行层产出的事实包显示:幸存区域吸收了约 76% 的预期故障转移流量,可用性在稳态窗口内低于服务 SLO,p99 延迟持续偏高 18 分钟。与此同时,该服务仍然在处理请求,没有完全中断。

智能体将这些事实解释为部分故障转移,而非简单的成功或失败二元判定。它的解释引用了流量吸收率、持续的 SLO 违规和延迟劣化这几点证据,并建议检查路由容量和下游依赖限制。

随后需要结合底层确定性事实和演练时间线来验证该结论。评审者可以把智能体解释中的每一句话追溯到事实包中的字段,并使用保留的输入数据和配置重跑同样的 DuckDB/Python 分析。确认结论后,下一步动作就是排查:调查路由容量或下游瓶颈是否阻碍了幸存区域吸收全部的预期负载。

这一验证步骤很重要:智能体提出解释和下一步行动,但数值证据保持可复现、可独立验证。

只有把可复现性当成一等需求,原型才能成为正式的工程系统。每一次演练都会保存一个重放包,其中包含:

重放包可用于离线重跑分析、复核有争议的结论或者用同一套证据对比两个智能体版本的表现。我们还显式定义了数据语义。一个容易忽略的点是空值含义:某些场景下,QPS 或者错误计数为空可能代表没有流量;但成功率或延迟为空往往代表没有可供统计的流量,而不是成功率为零、延迟为零。

把所有缺失值填零会造成假失败和假恢复。Schema 和数据质量标志需要保留这种语义差异,保证引擎和智能体对数据集的解释保持一致。

智能体加 DuckDB 并不是所有分析系统的最终架构。当工作负载具有与之相匹配的形态时它是有效的。有四个信号表明轻量架构开始遇到压力,但即使出现这些信号也并不意味着要立刻采用完整的湖仓方案。每个信号都指向一种可以逐步引入的能力,包括用于共享发现与治理的目录、用于安全并发写入和演进的开放表格式,或当计算必须靠近大型共享数据集时引入的分布式查询引擎。

如果仪表盘、定时任务、笔记本或其他团队需要直接访问数据,就需要一个稳定的契约。这些消费者不应该去调用原始智能体,或者自己反向解析存储桶目录。共享目录让他们能够按表名查找、理解 Schema、配置权限,并用标准工具查询。

数据达到 TB 级别之后,把文件拉到本地或者开发环境进行分析,效率非常低。查询应该在数据存储侧执行(也就是近数据处理),利用分区裁剪、谓词下推、分布式计算,只把结果传回给智能体。

当两边数据都不大时,DuckDB 可以高效连接本地文件。当另一侧是组织级权威数据集、已注册在共享目录中、太大或更新太频繁而无法安全导出时,边界就出现了。这时更稳妥的做法是把新数据注册到同一环境中,用共享引擎完成连接查询。

单写入者约定简单有效,适合早期工作流。当多个生产者更新数据集、Schema 独立演进或读取方需要一致快照时,这种方式就会失效。Apache Iceberg 等开放表格式在 Parquet 文件之上增加了表元数据、快照、Schema 演进和事务性提交语义。托管湖仓随后可以结合三项能力:

这些能力很有价值,但会引入集成、治理、计算和运维成本。只有在真实存在数据共享、规模、事务需求时才引入,不要默认所有 AI 项目上线第一天就需要湖仓。

AI 智能体降低了数据分析的使用门槛。它们能够把业务问题转化为分析步骤,筛选相关依据、对行为进行归类,并输出工程师可直接落地的报告。但它们并不能取代精准执行的环节。

在我们的容灾分析工作流中,Parquet 和 DuckDB 完成了机械性工作:存储、过滤、聚合、校验和连接。智能体负责上下文判断:综合解释流量吸收、可用性和延迟,并输出结论。架构刻意保持轻量,因为真实负载暂时不需要共享湖仓。

跑通这套工作流之后,我们对分析交互入口的看法发生了变化。工程师不再每一次排查都直接和查询引擎交互,但引擎依然是产出可信事实的关键。智能体变成负责规划分析、生成 SQL / Python、解读证据的层。

因此,主要的架构权衡不是 AI 对 SQL,也不是文件对表,而是对于手头的工作负载,智能体到底需要多强的分析基础设施。对于聚焦的工作流,小型嵌入式引擎可能已经足够;只有当共享、规模、写入并发或治理产生具体需求时,才需要引入共享目录、开放表格式和分布式引擎。引擎一直都在,变的只是接口。

查看英文原文:https://www.infoq.com/articles/ai-changes-data-interface/

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →