{"id":51763522,"url":"https://github.com/wubx/databend-semantic-query-lab","last_synced_at":"2026-07-19T16:33:37.002Z","repository":{"id":371652568,"uuid":"1301387239","full_name":"wubx/databend-semantic-query-lab","owner":"wubx","description":"AI-powered, governed, and observable semantic query lab for Databend","archived":false,"fork":false,"pushed_at":"2026-07-17T03:26:05.000Z","size":429,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-17T05:24:03.806Z","etag":null,"topics":["databend","llm","query-observability","semantic-layer","semantic-query","text-to-sql"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wubx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-15T08:34:42.000Z","updated_at":"2026-07-17T03:26:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wubx/databend-semantic-query-lab","commit_stats":null,"previous_names":["wubx/databend-semantic-sql-demo","wubx/databend-semantic-query-lab"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/wubx/databend-semantic-query-lab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wubx%2Fdatabend-semantic-query-lab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wubx%2Fdatabend-semantic-query-lab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wubx%2Fdatabend-semantic-query-lab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wubx%2Fdatabend-semantic-query-lab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wubx","download_url":"https://codeload.github.com/wubx/databend-semantic-query-lab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wubx%2Fdatabend-semantic-query-lab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35659409,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-19T02:00:06.923Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["databend","llm","query-observability","semantic-layer","semantic-query","text-to-sql"],"created_at":"2026-07-19T16:33:35.328Z","updated_at":"2026-07-19T16:33:36.986Z","avatar_url":"https://github.com/wubx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Databend Semantic Query Lab\n\n一个面向 **Databend** 的 AI 驱动、可治理、可观测语义查询实验平台。语义 Query 到 Databend SQL 的编译使用 Cube Open Source Compiler；自然语言规划、认证资产、治理、安全和可观测由本项目实现。\n\n它将业务问题转换为受治理的单阶段 Cube Query、多阶段 Semantic Workflow 或认证 TPC-H SQL，在执行前完成成员、阶段依赖、参数和 SQL 安全校验，然后查询 Databend 并展示真实结果。同时提供可视化语义层、模块化 YAML 维护以及从 Databend 表生成模型草稿的能力。\n\n## 为什么使用 Databend 执行 AI / Semantic Query\n\n自然语言和语义层降低了查询门槛，也会让更多用户提出临时、长尾和跨实体问题。由语义模型编译出的 SQL 可能包含多表 `JOIN`、大范围扫描、`GROUP BY`、聚合、排序、时间计算和复杂过滤；它未必能依赖 OLTP 数据库中常见的逐行 B-tree 索引命中，所需的 CPU、内存、I/O 和并行计算资源也可能明显高于固定报表或点查询。\n\n这类工作负载更适合交给 Databend 这样的云原生分析引擎：\n\n- 面向列式扫描与分析型 SQL，可通过列裁剪和数据裁剪减少无关数据读取；\n- 支持分布式并行执行，适合大表扫描、多表关联和高基数聚合；\n- 存储与计算解耦，可针对 AI 问数带来的波动和突发负载独立扩展计算资源；\n- 让语义层和 LLM 专注于“理解并生成受治理的查询”，由 Databend 承担实际的重计算。\n\n这并不意味着生成的 SQL 可以不做优化。生产环境仍应结合 `EXPLAIN`、查询日志和真实负载，持续优化表设计、数据聚簇、过滤条件、查询并发和计算资源；高频且稳定的问题应优先沉淀为 `Certified Query`、认证 SQL，或在 Cube Server 模式中使用缓存和 Pre-aggregations。\n\n因此，本项目的核心分工是：\n\n```text\nLLM 负责理解自然语言\nDemo 负责语义约束、治理、安全与可观测\nCube Compiler 负责将 Semantic Query 编译为 Databend SQL\nDatabend 负责承载复杂 SQL 的分析计算与真实执行\n```\n\n## 平台结构\n\n```text\n用户 / BI / AI Agent\n         │\n         ▼\n┌──────────────────────────────────────────────┐\n│ Databend Semantic Query Lab                  │\n│                                              │\n│ Natural Language → LLM Semantic Planner      │\n│                      │                       │\n│              Query Strategy Router           │\n└──────────────────────┼───────────────────────┘\n                       │\n       ┌───────────────┼────────────────┬─────────────────┐\n       │               │                │                 │\n       ▼               ▼                ▼                 ▼\n Certified Query   Dynamic Cube   Semantic Workflow   Governed SQL\n 已验证计划         单一最终粒度     多阶段语义编排       Policy 控制\n       │               │                │                 │\n       │               │        ┌───────┴────────┐        │\n       │               │        │ Stage 1        │        │\n       │               │        │ Parent Top N   │        │\n       │               │        └───────┬────────┘        │\n       │               │                │ Export Keys      │\n       │               │        ┌───────▼────────┐        │\n       │               │        │ Stage 2        │        │\n       │               │        │ Child Details  │        │\n       │               │        └───────┬────────┘        │\n       │               │                │                 │\n       └───────────────┴────────────────┘                 │\n                       │                                  │\n                       ▼                                  │\n            Cube Compiler / Cube Server                   │\n                       │                                  │\n                       ▼                                  │\n               Databend SQL + Bindings                    │\n                       │                                  │\n                       ├───────────────◀──────────────────┘\n                       ▼\n             SQL Safety / Query Budget\n                       ▼\n                    Databend\n                       ▼\n        Result + Workflow Completeness + Logs\n```\n\n其中：\n\n- `Certified Query` 为高频、已验证问题提供稳定查询计划；\n- `Dynamic Cube` 由 LLM 从公开语义成员构造受约束的单阶段 Cube Query，包括聚合和 `ungrouped` 明细查询；\n- `Semantic Workflow` 在单个 Cube Query 不足时编排两个受治理阶段，例如先选择父实体 Top N，再将导出的 Keys 注入第二个 Cube Query 展开子明细；\n- `Governed SQL Policy` 控制用户提交的自由 SQL 是否允许进入执行链路；\n- `Cube Compiler / Cube Server` 将每个语义 Query 阶段编译为 Databend SQL；\n- `SQL Safety / Query Budget` 对最终 SQL执行确定性的只读、单语句和 Schema 边界校验，并约束阶段数、中间 Keys 和结果规模；\n- `Databend` 负责真实数据存储与 SQL 执行。\n\n```text\n业务问题\n   │\n   ▼\n精确认证查询匹配\n   │\n   ├─ 命中 → Certified Query / Certified SQL\n   │\n   └─ 未命中 → LLM Semantic Planner\n                    │\n                    ├─ 单一最终粒度\n                    │    └─ Dynamic Cube Query\n                    │\n                    ├─ 父实体 Top N → 子明细展开\n                    │    └─ Semantic Workflow\n                    │         ├─ Stage 1：查询父实体并导出 Keys\n                    │         └─ Stage 2：注入 Keys 并查询完整子明细\n                    │\n                    └─ 无安全语义计划 → Reject / 确定性回退\n\n每个 Semantic Stage\n   └─ Cube Compiler / Cube Server\n        → Databend SQL\n        → SQL Safety\n        → Databend\n        → 阶段行数、耗时、完整性和可观测日志\n```\n\n## 主要功能\n\n### AI 语义查询工作台\n\n- 使用自然语言查询订单、销售额、发货、供应商和区域等 TPC-H 业务数据\n- 优先匹配认证查询，也可以动态组合受校验的单阶段 Cube Query\n- 支持多阶段 Semantic Workflow：先查询父实体 Top N，再将导出的 Keys 注入下一阶段并展开子明细\n- 展示查询理解、Cube Query、Workflow Stage、生成的 Databend SQL、参数、阶段耗时、完整性和执行结果\n- 支持 SQL 校验、`EXPLAIN` 和真实查询执行\n- LLM 不可用时自动回退到确定性路由\n- 默认记录规划和执行阶段的 JSONL 可观测日志\n\n### 可视化语义层\n\n- 浏览实体、度量、维度、时间维度、分组和实体关系\n- 查看业务名称、描述、同义词、枚举、隐私属性和认证查询引用\n- 搜索和筛选已发布的语义成员\n- 查看实时组装的完整 Runtime Manifest\n\n### Semantic Model 管理\n\n语义模型采用模块化 YAML 维护：\n\n```text\nsemantic/model.yaml                 # 模型入口和 includes\nsemantic/entities/*.yaml            # 实体、度量、维度和分组\nsemantic/relationships.yaml         # 实体关系\nsemantic/verified-queries.yaml      # 认证查询\nsemantic/policy.yaml                # AI 与查询治理声明\n```\n\n页面支持：\n\n- 在线查看、编辑、校验和发布模块化 YAML\n- 发布前组装完整 Manifest 并执行引用校验和 Cube 编译\n- 发布时自动备份旧文件并热重载 Embedded Compiler，无需重启服务\n- 安全删除实体；存在 Relationship 或认证查询引用时拒绝删除\n- 从 Databend Catalog 选择数据库和表，自动生成可审阅的实体草稿\n- 可选使用 LLM 补充业务名称、描述、定义和同义词\n- LLM 只能增强业务元数据，不能修改表来源、SQL 表达式、类型、聚合方式、主键和访问权限\n\n### 已包含的认证查询\n\n- `S1`：订单总数\n- `S2`：按订单状态统计订单金额\n- `S3`：每月订单金额趋势\n- `S4`：按年统计发货商品数量\n- `S5`：延迟收货明细数量\n- `S6`：运输方式与效率分析\n- `S7`：按区域统计订单金额\n- `Q1`：TPC-H Pricing Summary Report\n- `Q6`：TPC-H Forecasting Revenue Change\n- `Q21`：TPC-H Suppliers Who Kept Orders Waiting\n\n## 运行架构\n\n项目支持两种 Semantic Gateway。\n\n### Embedded 模式（推荐用于本地 Demo）\n\n```text\nBrowser\n   │\n   ▼\nDemo Server :4100\n   │\n   ├─ Single Semantic Query ───────────────┐\n   │                                       │\n   └─ Semantic Workflow                   │\n        ├─ Stage 1：Parent Top N           │\n        └─ Stage 2：Bound Child Details    │\n                                            ▼\n                              Embedded Cube Compiler\n                                            ▼\n                                         Databend\n```\n\nCube Schema Compiler 和 `DatabendQuery` SQL Dialect 直接运行在 Demo 的 Node.js 进程中，不需要另外启动 Cube Server。\n\n保留的能力：\n\n- Cube YAML 编译\n- Measures、Dimensions、Facts、Segments、Filters、Joins、Order、Limit 和 `ungrouped` 明细查询\n- 两阶段 Semantic Workflow，由 Demo Server 顺序执行多个经 Cube 编译的查询并传递受限 Key 集合\n- Databend SQL 生成及参数绑定\n- Cube 成员别名映射\n\n不包含 Cube Server 的以下运行时能力：\n\n- Cube Query Orchestrator 和缓存（Semantic Workflow 由本项目的应用层 Orchestrator 实现，不是 Cube Query Orchestrator）\n- Pre-aggregations\n- Cube Security Context 和 Access Policy Enforcement\n- Cube `/meta`、`/sql`、`/load`、SQL API 和 Playground\n\n生产环境如需缓存、预聚合和运行时访问策略，建议使用 `cube-server` 模式。\n\n### Cube Server 模式\n\n```text\nBrowser\n   │\n   ▼\nDemo Server :4100 / Semantic Workflow Orchestrator\n   │\n   ├─ Stage 1 Cube Query\n   └─ Stage 2 Cube Query with bound Keys\n             │\n             ▼\n      Cube Server :4000\n             │\n             ▼\n          Databend\n```\n\n通过 Cube HTTP API 完成每个语义查询阶段，适合需要完整 Cube Runtime 能力的环境。多阶段 Workflow 仍由 Demo Server / Agent 层编排，Cube Server 负责执行各个受治理的 Cube Query Stage。\n\n## 环境要求\n\n- Node.js 20 或更高版本\n- npm\n- 可访问的 Databend\n- 已加载 TPC-H SF100 数据的 `tpch_100` 数据库\n- 一个只读 Databend 用户\n- Embedded 模式当前需要一份兼容且已经构建完成的 Cube 源码；推荐使用 [`wubx/cube`](https://github.com/wubx/cube) 的 `feat/databend-driver` 分支\n- LLM 是可选项；未配置 LLM 时认证查询和确定性路由仍可运行\n\n## 快速开始：Embedded 模式\n\n### 1. 准备已构建的 Cube（Embedded 模式当前必需）\n\n当前 Embedded Gateway 直接加载 Cube Schema Compiler 和尚未发布到 npm 的 Databend SQL Dialect，因此需要一份包含 Databend Driver 且已经构建完成的 Cube 仓库。推荐使用：\n\n```text\nRepository: https://github.com/wubx/cube\nBranch:     feat/databend-driver\n```\n\n如果本机已经有这份仓库，并且以下目录存在，可以跳过 clone、依赖安装和构建，直接在下一步配置 `CUBE_REPOSITORY_PATH`：\n\n```text\npackages/cubejs-schema-compiler/dist\npackages/cubejs-databend-driver/dist\n```\n\n首次准备时执行：\n\n```bash\ngit clone --branch feat/databend-driver https://github.com/wubx/cube.git\ncd cube\nyarn install\nyarn build\n```\n\n`CUBE_REPOSITORY_PATH` 必须设置为该 Cube 仓库的绝对路径，而不是某个 `packages/` 子目录。\n\n\u003e 这不是每次启动都要执行的步骤。只有首次准备、切换 Cube 版本、清理构建产物或修改 Schema Compiler / Databend Driver 后才需要重新构建。当前 Embedded 模式使用 Cube 内部编译器 API，因此 Demo 与 Cube 分支需要保持兼容。后续将 Schema Compiler 和 Databend Dialect 改为项目依赖后，可以移除此要求。\n\n### 2. 安装 Demo 依赖\n\n```bash\ngit clone https://github.com/wubx/databend-semantic-query-lab.git\ncd databend-semantic-query-lab\nnpm install\n```\n\n### 3. 创建配置\n\n```bash\ncp .env.example .env\n```\n\n编辑 `.env`，最小配置如下：\n\n```env\nSEMANTIC_GATEWAY=embedded\nCUBE_REPOSITORY_PATH=/absolute/path/to/cube\nDATABEND_DSN=databend://readonly_user:password@databend-host:8000/tpch_100?sslmode=disable\n\nPORT=4100\nAI_ENABLED=false\nMODELER_PUBLISH_ENABLED=false\n```\n\n注意：\n\n- 使用只读 Databend 账户\n- 如果用户名或密码中含有 `@`、`:`、`/`、`#` 等字符，需要进行 URL 编码\n- Databend Cloud 请根据实际连接信息配置主机、端口和 TLS 参数\n- `.env` 已被 Git 忽略，不要把真实密码或 API Key 写入 `.env.example`\n\n### 4. 启动服务\n\n```bash\nnpm start\n```\n\n开发时可以使用自动重启模式：\n\n```bash\nnpm run dev\n```\n\n打开：\n\n```text\nhttp://localhost:4100\n```\n\n### 5. 检查运行状态\n\n```bash\ncurl http://localhost:4100/api/health\n```\n\n正常响应应满足：\n\n```json\n{\n  \"ok\": true,\n  \"checks\": {\n    \"api\": { \"ok\": true },\n    \"cube\": { \"ok\": true },\n    \"databend\": { \"ok\": true }\n  },\n  \"semanticGateway\": \"embedded\"\n}\n```\n\n如果 `cube.ok` 为 `false`，优先检查 `CUBE_REPOSITORY_PATH` 是否指向 [`wubx/cube`](https://github.com/wubx/cube) 的 `feat/databend-driver` 分支，以及该仓库是否存在所需的 `dist` 构建产物；如果 `databend.ok` 为 `false`，检查 DSN、网络、TLS、用户权限和 `tpch_100` 数据库。\n\n## 使用 Cube Server 模式\n\n是的，当前 Cube Server 也应使用 [`wubx/cube`](https://github.com/wubx/cube) 的 `feat/databend-driver` 分支。该分支包含：\n\n- `@cubejs-backend/databend-driver`；\n- `dbType: databend` 的 Server Core 注册；\n- Databend SQL Dialect；\n- Cube Server 连接 Databend 所需的 Driver 依赖配置。\n\n上游 Cube 或普通已发布版本在尚未包含这些改动时，不能直接作为本 Demo 的 Databend Cube Server。\n\n准备 Cube Server 源码：\n\n```bash\ngit clone --branch feat/databend-driver https://github.com/wubx/cube.git\ncd cube\nyarn install\nyarn build\n```\n\n然后按照该分支的 Cube Server 配置启动一个能够连接 Databend 且已加载对应 Cube Model 的服务。Demo 侧修改 `.env`：\n\n```env\nSEMANTIC_GATEWAY=cube-server\nCUBE_API_URL=http://localhost:4000/cubejs-api/v1\nCUBE_API_SECRET=replace-with-a-local-secret\n\nDATABEND_DSN=databend://readonly_user:password@databend-host:8000/tpch_100?sslmode=disable\n```\n\n再启动 Demo：\n\n```bash\nnpm start\n```\n\nCube Server 模式下，`CUBE_REPOSITORY_PATH` 不由 Demo 进程使用，但运行在 `:4000` 的独立 Cube Server 当前仍应从上述 `feat/databend-driver` 分支构建和启动。详细能力边界见 [`docs/embedded-cube-compiler.md`](./docs/embedded-cube-compiler.md)。\n\n## 启用 LLM\n\n项目支持 OpenAI-compatible Chat Completions API。LLM 仅用于：\n\n- 在认证查询之后进行受约束的动态 Cube Query 规划\n- 根据真实查询结果生成简短摘要\n- 为生成的 Semantic Model 草稿补充业务元数据\n\n配置：\n\n```env\nAI_ENABLED=true\nAI_BASE_URL=https://api.openai.com/v1\nAI_API_KEY=replace-with-your-api-key\nAI_MODEL=gpt-4.1-mini\nAI_REQUEST_TIMEOUT_MS=30000\n\nMODELER_AI_TIMEOUT_MS=90000\nMODELER_AI_MAX_TOKENS=1800\n```\n\n如果访问外部模型需要代理：\n\n```env\nHTTPS_PROXY=http://127.0.0.1:7890\nHTTP_PROXY=http://127.0.0.1:7890\nNO_PROXY=127.0.0.1,localhost,databend-host\n```\n\nLLM 返回结果仍需经过本地成员、成员类型、Filter Operator、枚举值、时间粒度和 Limit 校验。LLM 不直接生成或执行 SQL。\n\n## 启用模型发布\n\n默认只允许生成和校验草稿，不允许写入语义源文件：\n\n```env\nMODELER_PUBLISH_ENABLED=false\n```\n\n需要在本地维护模型时，显式开启：\n\n```env\nMODELER_PUBLISH_ENABLED=true\n```\n\n开启后，可以在“语义层”页面中：\n\n1. 从 Databend 表生成模型草稿；\n2. 人工检查并直接修改 YAML；\n3. 校验完整 Manifest 和 Cube 编译结果；\n4. 发布到 `semantic/entities/`；\n5. 编辑现有模块化 YAML；\n6. 删除无引用的实体。\n\n发布或删除前，旧文件会保存到：\n\n```text\nsemantic/backups/\n```\n\n模块化 YAML 发布成功后会热重载 Embedded Compiler，通常不需要重启服务。以下情况仍需重启：\n\n- 修改 `.env` 或其他进程级环境变量；\n- 修改服务端 JavaScript 代码且未使用 `npm run dev`；\n- 切换 `SEMANTIC_GATEWAY`；\n- 更换或重新构建 `CUBE_REPOSITORY_PATH` 指向的 Cube 编译器代码。\n\n需要维护认证 SQL 时，单独开启：\n\n```env\nCERTIFIED_SQL_PUBLISH_ENABLED=true\n```\n\n开启后，“语义层 → 认证 SQL”支持新建、修改、参数 Schema 校验、SQL Safety、`EXPLAIN`、发布和删除。Q1、Q6、Q21 的元数据与 SQL Template 位于：\n\n```text\nsemantic/certified-sql/queries.yaml\nsemantic/certified-sql/templates/*.sql\n```\n\n发布和删除会自动备份到 `semantic/certified-sql/backups/`，Catalog 按请求实时读取，发布后无需重启。共享演示环境建议保持该开关为 `false`。\n\n## 构建和校验语义模型\n\n将模块化语义源确定性组装为运行时产物：\n\n```bash\nnpm run build:semantic\n```\n\n产物写入未纳入 Git 的 `generated/`：\n\n```text\ngenerated/semantic-manifest.yaml\n# 以及 Cube Model、LLM Member Catalog 和认证查询 Catalog\n```\n\n运行单元测试：\n\n```bash\nnpm test\n```\n\n连接真实 Databend，编译并执行 `S1`–`S7`：\n\n```bash\nnpm run verify:runtime\n```\n\n验证运行时 Cube Metadata：\n\n```bash\nnpm run validate:meta\n```\n\n输出认证查询报告：\n\n```bash\nnpm run report:queries\n```\n\n## 局域网访问\n\n服务默认监听：\n\n```env\nHOST=0.0.0.0\nPORT=4100\n```\n\n因此同一局域网中的其他设备可以通过运行 Demo 的机器 IP 访问。例如服务器地址为 `192.168.1.5`：\n\n```text\nhttp://192.168.1.5:4100\n```\n\n在 macOS 上可查询当前 Wi-Fi 地址：\n\n```bash\nipconfig getifaddr en0\n```\n\nLinux 常用命令：\n\n```bash\nhostname -I\n```\n\n如果局域网设备无法连接，请检查：\n\n- 两台设备是否位于同一局域网或可路由网段；\n- 系统防火墙是否允许 Node.js 或 TCP `4100` 端口；\n- 路由器是否启用了 AP / Client Isolation；\n- 公司网络或 VPN 是否阻断设备间访问；\n- 页面应使用服务端机器的局域网 IP，不能在其他设备上访问 `localhost:4100`。\n\n只允许本机访问时设置：\n\n```env\nHOST=127.0.0.1\n```\n\n修改 `HOST` 或 `PORT` 后需要重启服务。\n\n\u003e **安全警告：** 当前 Demo 没有登录、用户隔离、TLS、CSRF 防护和接口级授权。开放到局域网后，局域网用户可以调用查询、`EXPLAIN` 和执行接口；如果 `MODELER_PUBLISH_ENABLED=true`，还可以修改或删除语义模型。建议使用只读 Databend 账户，并在共享演示时保持 `MODELER_PUBLISH_ENABLED=false`、限制主机防火墙来源。不要直接暴露到公网。需要多人长期使用时，应在前面增加带认证和 HTTPS 的反向代理，并使用 Cube Server 承担运行时访问治理。\n\n## 页面使用\n\n启动后可在本机访问 `http://localhost:4100`；启用默认局域网监听时，也可通过 `http://\u003c服务器局域网IP\u003e:4100` 访问。\n\n### 查询页面\n\n1. 输入业务问题或选择示例；\n2. 选择 `Auto`、`Semantic` 或 `TPC-H` 模式；\n3. 生成查询计划；\n4. 查看 Cube Query 和 Databend SQL；\n5. 执行校验、`EXPLAIN` 或真实查询；\n6. 查看结果、耗时和请求信息。\n\n### 语义层页面\n\n- **语义模型**：按实体和成员浏览业务语义层\n- **关系图**：查看实体间 Join 关系\n- **认证查询**：查看已验证的问题和 Cube Query\n- **认证 SQL**：管理 Q1、Q6、Q21 等受控 SQL Template，支持参数 Schema、校验、`EXPLAIN` 和发布\n- **原始 YAML**：查看、编辑、校验和发布模块化语义源\n- **生成模型**：选择 Databend 数据库和表，生成规则草稿或 LLM 增强草稿\n\n## 常用配置\n\n| 环境变量                        | 默认值                             | 说明                                      |\n| ------------------------------- | ---------------------------------- | ----------------------------------------- |\n| `HOST`                          | `0.0.0.0`                          | 监听地址；默认允许局域网访问              |\n| `PORT`                          | `4100`                             | Demo HTTP 端口                            |\n| `SEMANTIC_GATEWAY`              | `embedded`                         | `embedded` 或 `cube-server`               |\n| `CUBE_REPOSITORY_PATH`          | 无                                 | Embedded 模式下已构建 Cube 仓库的绝对路径 |\n| `CUBE_API_URL`                  | 无                                 | Cube Server API 地址                      |\n| `CUBE_API_SECRET`               | 无                                 | Cube Server API Secret                    |\n| `DATABEND_DSN`                  | 无                                 | Databend 连接字符串，建议使用只读用户     |\n| `RESULT_ROW_LIMIT`              | `500`                              | 单次返回的最大行数                        |\n| `AI_ENABLED`                    | `false`                            | 是否启用 LLM 规划、摘要和模型增强         |\n| `AI_BASE_URL`                   | OpenAI API                         | OpenAI-compatible API 地址                |\n| `AI_MODEL`                      | `gpt-4.1-mini`                     | 模型名称                                  |\n| `MODELER_PUBLISH_ENABLED`       | `false`                            | 是否允许写入、替换和删除语义源文件        |\n| `CERTIFIED_SQL_PUBLISH_ENABLED` | `false`                            | 是否允许新增、修改和删除认证 SQL          |\n| `MODEL_GENERATOR_MAX_TABLES`    | `20`                               | 单次最多生成的表数量                      |\n| `QUERY_LOG_ENABLED`             | `true`                             | 是否记录查询可观测日志                    |\n| `QUERY_LOG_PATH`                | `logs/query-observability.jsonl`   | 查询日志文件                              |\n| `LLM_LOG_ENABLED`               | `true`                             | 是否记录 LLM 请求和 RAW 响应              |\n| `LLM_LOG_PATH`                  | `logs/llm-observability.jsonl`     | LLM 交互日志文件                          |\n| `MODELER_LOG_PATH`              | `logs/modeler-observability.jsonl` | 模型生成日志文件                          |\n\n完整示例见 [`.env.example`](./.env.example)。\n\n## 项目结构\n\n```text\n.\n├── public/                         # 无框架 Web UI\n├── semantic/\n│   ├── model.yaml                 # 模型入口\n│   ├── entities/                  # 模块化实体模型\n│   ├── certified-sql/            # 认证 SQL Catalog、模板和备份\n│   ├── relationships.yaml         # 关系定义\n│   ├── verified-queries.yaml      # 认证查询\n│   ├── policy.yaml                # AI / 查询 Policy 声明\n│   └── backups/                   # 发布和删除前的自动备份\n├── src/\n│   ├── server.js                  # Express API 和静态站点\n│   ├── planner.js                 # 查询规划与路由\n│   ├── semantic-gateway/          # Embedded / Cube Server Gateway\n│   ├── semantic-assembler.js      # 模块化 Manifest 组装\n│   ├── semantic-source-editor.js  # YAML 校验、发布和删除\n│   ├── model-generator.js         # Databend Catalog → 实体草稿\n│   ├── model-enricher.js          # 受约束的 LLM 元数据增强\n│   ├── compiler.js                # Cube Model 与 Catalog 编译\n│   └── sql-safety.js              # 只读 SQL 安全校验\n├── test/                           # Node.js 单元和回归测试\n├── docs/                           # 设计和运行文档\n└── generated/                      # 构建产物，不提交 Git\n```\n\n## 安全边界\n\n这是一个 Demo，但仍建议遵守以下规则：\n\n- 始终使用只读 Databend 账户；\n- 不要在 Git 中提交 `.env`、DSN、Token 或 API Key；\n- SQL Safety 只允许单条只读查询，并限制访问 `tpch_100`；\n- LLM 不直接生成 SQL，只能选择认证查询或构造受校验的 Cube Query；\n- 所有模型发布必须显式设置 `MODELER_PUBLISH_ENABLED=true`；\n- 模型发布前会执行完整 Manifest 校验和 Cube 编译；\n- Embedded 模式不包含 Cube Server 的 Security Context 和访问策略；生产治理场景应使用 Cube Server。\n\n\u003e `semantic/policy.yaml` 当前会进入 Manifest 和 LLM 上下文，但其中部分字段仍属于声明性治理元数据，不等同于完整的运行时 Policy Engine。最终安全边界以服务端成员校验、SQL Safety、只读数据库账号和 Cube Runtime 配置为准。\n\n## 可观测性\n\n默认日志：\n\n```text\nlogs/query-observability.jsonl\nlogs/llm-observability.jsonl\nlogs/modeler-observability.jsonl\n```\n\n查询日志记录问题、路由结果、Cube Query、最终 SQL、阶段耗时、降级原因、Policy 决策和执行结果；LLM 日志记录发送给模型的完整请求、Provider RAW 响应、解析结果、Token Usage、耗时和超时错误（不记录 API Key 或 Authorization Header）；模型日志记录 Catalog 读取、规则生成、LLM 增强、回退原因和总耗时。\n\n详细格式见：\n\n- [`docs/query-observability-log.md`](./docs/query-observability-log.md)\n- [`docs/validation-and-regression.md`](./docs/validation-and-regression.md)\n\n## 进一步阅读\n\n- [自然语言查询验证手册](./docs/natural-language-query-examples.md)\n- [Embedded Cube Compiler 模式](./docs/embedded-cube-compiler.md)\n- [Semantic Manifest 维护设计](./docs/semantic-manifest-maintenance.md)\n- [验证和回归测试](./docs/validation-and-regression.md)\n- [查询可观测日志](./docs/query-observability-log.md)\n- [Snowflake Semantic View 字段参考](./docs/snowflake-semantic-view-reference.md)\n- [Snowflake 与 Cube 语义层设计对比](./docs/snowflake-vs-cube-combined-semantic-layer.md)\n- [项目计划与验收条件](./PLAN.md)\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwubx%2Fdatabend-semantic-query-lab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwubx%2Fdatabend-semantic-query-lab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwubx%2Fdatabend-semantic-query-lab/lists"}