配套③:人類与 Agent 共用同一條 DuckDB 查詢管线。Run / Source Run / validate / @@PROTECT0@@ 的语意契約見 Prompt 与 Context 工程 §七。快取与 Source Run 操作見 使用者指南 §7–8。
系列位置
完整导读見 系列导读与产品定位。
| 順序 | 文章 | 本題 |
|---|---|---|
| 0 | 系列导读与产品定位 | 系列导读与产品定位 |
| 1–2 | Agent 时代的数据分析工作流、可治理的 Agent Memory | 工作流、記憶 |
| 3–4 | Prompt 与 Context 工程、AI Agent 架構 | Context、Agent |
| 5 | 本文 | 查詢层 |
一、背景:为什麼需要統一查詢层
使用者与 Agent 在 SQL 里引用的是逻辑表名(檔名、快取分页名、MCP 物化表、ATTACH 后的 @@PROTECT1@@),執行时由后端改写为 DuckDB 可读路徑或 TEMP TABLE。統一查詢层的目标很单純:人類与 Agent 写同一種 SQL、走同一條管线、受同一套唯读与物化规则約束。具体而言:
- 编辑器与对話里的 SQL 语法一致;
- 权限与唯读规则一處实施;
- Agent 建立的快取与使用者手動 Run 的快取同一套血緣。
SQL-first 的方法論(为何口徑与取数以可審閱 SQL 为主契約)見 Agent 时代的数据分析工作流 §三。本篇說明上述原则如何以統一查詢层承載(逻辑表名、物化、血緣、Source Run)。
二、逻辑表名 vs 实际來源
@@PROTECT2@@@@PROTECT3@@@@PROTECT4@@
表名必須双引号引用(檔名含 @@PROTECT5@@ 等)。Excel 为 @@PROTECT6@@。外部庫为 @@PROTECT7@@ 或 @@PROTECT8@@。
三、查詢管线总览
典型路徑:
- 解析 SQL(sqlglot AST)。
- 替換表名为路徑或保留快取/ATTACH 名称。
- 唯读守衛(拒絕 DDL/DML)。
- DuckDB 執行。
- 可选:物化为 TEMP TABLE 并註冊 @@PROTECT9@@;或写入 @@PROTECT10@@ 供结果面板分页。
§七展开分析就緒层;§八展开快取与 Source Run;§十一展开 ResultManager 生命周期。
四、sqlglot 改写
字串替換无法安全處理引号、子查詢与多表 JOIN。AST 遍历可:
- 辨识表名是否为已註冊快取 → 跳过路徑改写;
- 辨识 ATTACH @@PROTECT11@@ / @@PROTECT12@@ 前綴 → 交給 DuckDB;
- 将本機檔映射为 @@PROTECT13@@ / @@PROTECT14@@ 等。
五、唯读安全
使用者 SQL 与 Agent SQL 皆不得透过查詢管线修改原始檔或外部庫内容。@@PROTECT15@@ 等仅能出现在「物化快取」的受控路徑,而非使用者自由撰写的 DDL。
六、本機檔案映射
工作区 @@PROTECT16@@ 登記的檔案与 Excel 工作表,在解析階段改写为 DuckDB 可读表达式。側邊欄 schema 与 @@PROTECT17@@ 输出与此登記一致。
七、分析就緒层(工程定義)
在 系列导读 §一「分析師的一天」 的 Medallion 隱喻中,Lantide 的 Silver 对应工作区内的分析就緒/中间结果——本篇定義其工程实作,非企业級 ETL。
| 能力 | 实作 |
|---|---|
| 可引用的中间表 | 逻辑表名 + @@PROTECT18@@ |
| 可重跑 | Source Run DAG、拓撲排序 |
| 可審閱 SQL | @@PROTECT19@@、@@PROTECT20@@、@@PROTECT21@@ |
| 人類与 Agent 一致 | 同一條 DuckDB 管线(§十二) |
与 Julius 類「会話内 transform」的差异在于:中间结果是具名、可查、可 Source Run 的 artifact,而非沙箱内隱式变数(对照見 系列导读 §一 与 工作流 §三)。
但分析就緒层不是每次分析的必经路徑。一次性、口徑清楚的多表 JOIN 可以直接執行;只有当中间结果需要重用、審閱或重跑时,persist tab / Source Run 才是更好的选擇。
八、快取表与 Source Run
8.1 单次 Run
持久分页執行查詢(@@PROTECT22@@ 或工具 @@PROTECT23@@)时,结果物化为 DuckDB TEMP TABLE,并在 @@PROTECT24@@ 註冊,名称通常与分页标題一致。其他 SQL 可直接:
@@PROTECT25@@@@PROTECT26@@@@PROTECT27@@
快取存在目前工作区的 DuckDB 連线記憶体中;切換工作区或重启应用会清除 — 符合「分析中间结果」定位,非长期倉儲。
Agent 快取(@@PROTECT28@@ 條件物化)亦註冊为可查表,但语意上为代理分析用,不参与 Source Run DAG(見 Prompt 与 Context 工程(Query Execution Model))。
條件物化策略(@@PROTECT29@@)
| 條件 | 物化 | reason_code |
|---|---|---|
| 显式 @@PROTECT30@@ | 是 | @@PROTECT31@@ |
| 单表探索(单依賴、@@PROTECT32@@、无 JOIN/GROUP)且显式 @@PROTECT33@@ | 否 | @@PROTECT34@@ |
| 对話 ledger 已有 ≥1 成功步 | 強制 | @@PROTECT35@@ |
| SQL 引用既有快取表名 | 強制 | @@PROTECT36@@ |
| JOIN 表 ≥2 或 CTE ≥3 | 強制(含首步) | @@PROTECT37@@ |
| 预设 | 否 | @@PROTECT38@@ |
推断与 LLM 传入 @@PROTECT39@@ 衝突时採 auto_warn:仍物化、@@PROTECT40@@,并附 @@PROTECT41@@。
这里的「條件物化」是 @@PROTECT42@@ 的资料重用策略,不等同于阻擋查詢。前景 @@PROTECT43@@ 的阻擋型 complexity gate 目前只保留給过度复杂、難以審閱的形态(例如 3+ CTE);純多实体表 JOIN 允許執行,最多回传非阻擋的 @@PROTECT44@@,提醒可视情况改用 persist tab。
@@PROTECT45@@ 与查看 API
@@PROTECT46@@ 的 @@PROTECT47@@ 可存 @@PROTECT48@@、@@PROTECT49@@、@@PROTECT50@@(@@PROTECT51@@ | @@PROTECT52@@)。agent 物化时写入 SQL;persist 可由分页内容懶載入。
@@PROTECT53@@@@PROTECT54@@@@PROTECT55@@
解析順序:registry → persist 分页 content → ResultManager → workspace ledger 掃描。回传 @@PROTECT56@@(@@PROTECT57@@ | @@PROTECT58@@ | @@PROTECT59@@ | @@PROTECT60@@ | @@PROTECT61@@)。UI 右鍵 查看 SQL 不依賴 @@PROTECT62@@。
8.2 依賴解析与 DAG
当 SQL 引用其他持久分页的快取名,系統解析依賴邊,组成 DAG,并做循環偵测与拓撲排序。实作集中于 tab cache 的 dependency 模组:从 sqlglot 擷取 @@PROTECT63@@ 中引号包裹的持久表名,与已註冊快取比对。
规则摘要:
- 依賴邊 = 被引用的持久快取表名;
- 禁止自引用自己的快取名;
- 臨时分页不进 Source Run。
8.3 Source Run 与 SSE
Source Run 对目标持久分页:先依 DAG 依序重算所有上游,再執行目标 SQL。透过 @@PROTECT64@@ 以 SSE 推送 @@PROTECT65@@、@@PROTECT66@@、@@PROTECT67@@、@@PROTECT68@@ 等事件;前端显示流程图进度。失敗时清理相关快取狀态。
Agent 对应工具 @@PROTECT69@@(UICommand + 后端适配),与人類按工具列 Source Run 同源。操作見 §8。
8.4 Deep lineage
Check Lineage 可不執行查詢,仅建深度血緣图:Physical(檔案)、Cached(上游分页快取)、Target(目前分页)、Unknown。用于理解资料从哪來,再決定是否 Source Run。
8.5 run_id 与 abort
进行中的互動查詢与 Source Run 可帶 @@PROTECT70@@ 登录;使用者 Abort 时对 DuckDB 連线 @@PROTECT71@@,并以統一方式辨识取消錯誤,使 Tab/结果狀态收斂。互動查詢与 Source Run 中止语意对齊。
九、外部资料庫 ATTACH
PostgreSQL / MySQL / SQLite 透过 DuckDB @@PROTECT72@@ 掛載,跨源 JOIN 与本機檔在同一 SQL 中完成。解析器对已 ATTACH 的 alias 不做「拉回本機路徑」改写。連线生命周期由 Connection Manager 管理(试連、持久化、schema 列举)。
十、MCP 物化 Parquet
MCP 工具回传结果物化为工作区内 Parquet,以 @@PROTECT73@@ 形式註冊进查詢层。Stale 时由 MCP 工具刷新,而非在 SQL 内隱式連外網。这是把 Bronze(远端/API 原始源)拉入工作区 Silver(本機可查表)的典型路徑。
十一、ResultManager 生命周期
互動查詢的结果面板綁定 @@PROTECT74@@:支援分页瀏览、排序、匯出。与 TEMP 快取表分工不同 — 快取服务下游 SQL 引用;ResultManager 服务人類閱读与匯出。Agent @@PROTECT75@@ 可读持久分页对应的快取结果。Run 路徑可能物化进 Registry(供下游 @@PROTECT76@@)或写入 ResultManager(供结果面板),依執行入口而定;对照 §三管线图的物化分支。
十二、人類与 Agent 共用管线
| 動作 | 人類 | Agent(典型工具) |
|---|---|---|
| 单分页執行 | Run | @@PROTECT77@@ |
| 上游链重算 | Source Run | @@PROTECT78@@ |
| 试錯语法 | 编辑器執行前 | @@PROTECT79@@ |
| 预览列 | 结果面板 | @@PROTECT80@@(≤200 行) |
| 读快取 | SQL @@PROTECT81@@ | 同上 + @@PROTECT82@@ |
| 查看 SQL | 右鍵 查看 SQL / @@PROTECT83@@ | @@PROTECT84@@(与 API 同源,見 AI Agent 架構 §6.2) |
Prompt 层的 Query Execution Model(Prompt 与 Context 工程 §七)与工具矩陣(AI Agent 架構)必須与本层语意一致,否则模型会写出无法 Source Run 的 SQL 或混淆 agent 快取。
十三、錯誤设計
錯誤讯息指向可修正項(表名未加引号、依賴分页未執行、循環依賴、唯读違规)。查詢失敗时,Context 可把錯誤 + 觸发 SQL 一併送給 Agent(見 §12.11)。
十四、工程決策总览
| 決策 | 取捨 |
|---|---|
| DuckDB in-process | 低延遲;快取隨程序 |
| sqlglot | 安全改写 vs 正则 |
| TEMP TABLE 快取 | 速度 vs 持久化 |
| Source Run DAG | 正確順序 vs 单次 Run 簡单 |
| SSE 进度 | 可观测长链執行 |
| 多表 JOIN 不硬擋 | 实务分析可完成;cache 以 hint 引导 |
十五、结语
統一查詢层让「分析師写的 SQL」与「Agent 写的 SQL」落在同一套物化与血緣规则上——是 SQL-first 与 分析就緒层 的工程落点。
方法論見 工作流 §三;Execute 与持久分页的产品故事見同篇 §四、§七;模型何时可呼叫 @@PROTECT85@@,見 AI Agent 架構。