系统架构¶
文档定位
本文档是 TTD 系统的核心架构参考,涵盖全局架构、逻辑分层、在线 / 离线链路、 三引擎协作模型、多模型策略以及架构原则。适用于后端开发者、Data Steward 及 Platform Engineer。
1. 全局架构图¶
flowchart TB
%% ── 用户与前端 ──────────────────────────────────────
U([用户 / 业务分析师])
W[Web Frontend<br/>Next.js 16 · SSE Streaming · Admin Panel]
AUTH[Better Auth<br/>Identity Provider · JWT · JWKS<br/>托管于 Next.js]
U --> W
W --> AUTH
%% ── 负载均衡 ────────────────────────────────────────
LB[HAProxy<br/>Consistent Hash Router<br/>ketama on X-Chat-ID]
W -->|"HTTP/SSE + JWT"| LB
%% ── 后端服务 (Agent Runtime Pool) ────────────────────
subgraph RuntimePool["Agent Runtime Pool (Docker Swarm)"]
direction TB
R1["Runtime #1<br/>FastAPI + LangGraph<br/>1 worker"]
R2["Runtime #2<br/>FastAPI + LangGraph<br/>1 worker"]
RN["Runtime #N<br/>FastAPI + LangGraph<br/>1 worker"]
end
LB -->|"hash(chat_id)"| R1
LB -->|"hash(chat_id)"| R2
LB -->|"hash(chat_id)"| RN
%% ── Aurora PG Supernode ─────────────────────────────
subgraph PGSupernode["Aurora PostgreSQL — PG Supernode"]
direction LR
R[(Engine R<br/>Relational<br/>semlayer.*)]
V[(Engine V<br/>pgvector<br/>Embedding)]
G[(Engine G<br/>Apache AGE<br/>ttd_governance)]
end
RuntimePool -->|"RAG 检索 · 会话 · 检查点 · Advisory Lock"| PGSupernode
AUTH -->|"auth tables (user, session, jwks)"| PGSupernode
RuntimePool -.->|"JWKS 公钥验证"| AUTH
%% ── Data Plane ──────────────────────────────────────
DP[(Data Plane<br/>Redshift Serverless / pg_mooncake)]
RuntimePool -->|"SQL 执行"| DP
%% ── LLM Provider ────────────────────────────────────
DASH([DashScope API<br/>LLM + Embedding])
RuntimePool -->|"模型调用"| DASH
%% ── 离线发布管道 ────────────────────────────────────
subgraph Publishing["离线发布管道 (Offline Pipeline)"]
direction TB
YAML["semantic-plane/<br/>YAML 元数据资产"]
CI["CI 校验脚本<br/>schema · SQL · cross-ref · version"]
PUB["ttd-publish-sp<br/>发布到 S3"]
SYNC["Admin Backend<br/>semantic_plane agent<br/>(R + V + G)"]
YAML --> CI --> PUB --> SYNC
end
SYNC -->|"Upsert 关系表 + AGE Graph + pgvector"| PGSupernode
SYNC -.->|"text-embedding-v4"| DASH
图例说明
- 实线箭头 = 数据 / 请求流方向
- 虚线箭头 = 异步或可选调用
- 圆角矩形 = 外部服务或用户
- 方框 = 内部模块或容器
Agent Runtime Pool
后端从单体多 worker 模式演进为多实例池化部署(Docker Swarm)。每个实例运行 1 uvicorn worker, 通过 HAProxy consistent hashing 实现 session affinity。实例本身无状态,所有共享状态通过 PG Supernode (Checkpointer + Advisory Lock + Memory Store)持久化。一致性哈希是性能优化(缓存 warmth),非正确性依赖。
2. 五层逻辑模型¶
TTD 采用五层逻辑架构,每一层职责单一、边界清晰:
| 层级 | 名称 | 核心组件 | 关键目录 |
|---|---|---|---|
| L1 | 交互层 Interaction | Web Frontend (Next.js 16, SSE streaming, Admin Panel, shadcn/ui), Better Auth (Identity Provider) | web/ |
| L2 | 编排层 Orchestration | LangGraph Supervisor, Query Understanding, Router, 7 种路由决策 | backend/app/agents/ |
| L3 | 智能层 Intelligence | Sub-agents (SQL Gen, Guardrails, Insights, Viz, Analytics, Graph RAG, Knowledge QA) | backend/app/agents/sub_agents/ |
| L4 | 数据层 Data | Data Plane (Redshift / pg_mooncake), Semantic Layer (pgvector + AGE + Relational) | data-plane/, backend/app/skills/ |
| L5 | 治理层 Governance | Semantic Plane (YAML), Admin Backend Publishing Pipeline (R+V+G), CI Validation Scripts | semantic-plane/, backend/app/agents/semantic_plane/, scripts/ |
flowchart LR
subgraph L1["L1 交互层"]
WEB["Next.js 16<br/>SSE · Admin"]
end
subgraph L2["L2 编排层"]
SUP2["Supervisor"]
QU2["Query Understanding"]
RTR2["Router (7 routes)"]
end
subgraph L3["L3 智能层"]
AG["SQL Gen · Guardrails<br/>Insights · Viz · Analytics<br/>Graph RAG · Knowledge QA"]
end
subgraph L4["L4 数据层"]
DP2["Data Plane"]
SEM["Semantic Layer<br/>R + V + G"]
end
subgraph L5["L5 治理层"]
YML["YAML Assets"]
PUB["S3 Publish + Backend Import"]
SCRIPTS["CI Scripts"]
end
L1 --> L2 --> L3 --> L4
L5 -->|"发布"| L4
各层交互规则¶
层间调用约束
- 只能向下调用:L1 → L2 → L3 → L4,不允许跳层(L1 不可直接调 L4)
- 治理层独立发布:L5 通过离线管道写入 L4,不参与在线请求路径
- 编排层是唯一控制面:所有 Sub-agent 的调度、重试、降级决策均在 L2 完成
3. 认证与令牌链路¶
TTD 采用 Better Auth 作为统一身份源,托管在 Next.js (L1) 内,FastAPI (L2/L3) 通过 JWKS 本地验签信任其签发的 JWT。
sequenceDiagram
autonumber
participant U as Browser
participant W as Next.js (Better Auth)
participant DB as PostgreSQL (auth tables)
participant LB as HAProxy
participant API as FastAPI Runtime
Note over U,W: 1. 用户登录
U->>W: POST /api/auth/sign-in/email {email, password}
W->>DB: 验证凭据,创建 session
DB-->>W: session record
W-->>U: Set-Cookie: better-auth.session_token
Note over U,API: 2. 获取 API Token
U->>W: GET /api/auth/token (JWT plugin)
W->>DB: 从 jwks 表取私钥
W-->>U: signed JWT (RS256, 1h TTL)
Note over U,API: 3. 访问后端 API
U->>LB: GET /api/v1/chats (Authorization: Bearer <JWT>)
LB->>API: hash(chat_id) → runtime
API->>API: PyJWKClient → JWKS 公钥验签
API->>API: 校验 iss, aud, exp → UserContext
API-->>U: 200 OK
Note over U,W: 4. Token 过期处理
U->>LB: API 请求 (expired JWT)
LB->>API: 转发
API-->>U: 401 Unauthorized
U->>U: client interceptor → redirect /login
关键设计原则¶
| 原则 | 说明 |
|---|---|
| 单一身份源 | Better Auth 是唯一的用户/会话权威,Backend 不维护第二套认证逻辑 |
| JWT 仅用于 API 访问 | 浏览器主会话由 Better Auth cookie 管理,JWT 仅作为发往后端的短期令牌 |
| 本地验签 | FastAPI 通过 JWKS 公钥本地验证 JWT,不做逐请求 introspection |
| Identity Continuity | Better Auth user.id 直接作为后端 user_id,不引入映射表 |
| 全局角色 | Phase 1 仅 admin/user 两级,不引入 Organization/Team/Dynamic RBAC |
4. 在线查询链路¶
以下序列图展示了一个典型的 NL2SQL 查询从用户提问到结果返回的完整链路:
sequenceDiagram
autonumber
participant U as 用户 (Browser)
participant W as Web (Next.js)
participant API as Backend API
participant SUP as Supervisor
participant QU as Query Understanding
participant RTR as Router
participant DR as Data Retrieval
participant RR as Reranker
participant SE as Schema Explorer
participant SG as SQL Generator
participant GR as Guardrails
participant CR as Corrective Retrieval
participant EX as SQL Executor
participant RP as Result Processor
participant XP as SQL Explainer
participant VZ as Visualization
participant IN as Insights
participant FU as Suggest Follow-up
participant DP as Data Plane
participant PG as PG Supernode (R+V+G)
participant LLM as DashScope API
U->>W: 输入自然语言问题
W->>API: POST /api/v1/chats/{id}/messages/stream (SSE)
API->>SUP: 初始化 AgenticBIState
Note over SUP: Step 1: Embedding + 治理
SUP->>PG: compute embedding (text-embedding-v4)
PG-->>SUP: question_embedding
SUP->>PG: resolve_governance_context()
PG-->>SUP: governance_overlays
SUP->>SUP: 加载 short_term_memory
Note over QU: Step 2: 意图解析
SUP->>QU: 委派
QU->>LLM: intent parsing + entity extraction + question rewriting
LLM-->>QU: query_understanding JSON
QU-->>RTR: intent + rewritten_question
Note over RTR: Step 3: 路由决策
RTR->>RTR: intent → route mapping
RTR->>RTR: check SQL Cache (embedding similarity ≥ 0.92)
RTR-->>DR: Command(goto="data_retrieval_agent")
Note over DR,RR: Step 4: 检索增强
DR->>DR: 从 QU 提取 search_terms (LLM 已解析)
DR->>PG: R/V/G/D 四引擎检索(Engine 1+1b+2+D 并行,Engine 3 串行)
PG-->>DR: tables + columns + metrics + terms + few_shots(含动态 few-shot)+ term_bindings
DR-->>RR: retrieval_results + graph_context + _term_bindings
RR->>RR: 术语绑定加分/降权 + 评分 + 截断 + 排序
RR-->>SE: 精排后的 retrieval_results
Note over SE: Step 5: Schema 探索
SE->>SE: 验证 schema 充分性
SE-->>SG: confirmed retrieval_results
Note over SG,GR: Step 6: SQL 生成 + 校验
SG->>LLM: prompt (retrieval + governance + few_shots)
LLM-->>SG: generated_sql
SG-->>GR: SQL 语句
GR->>GR: Layer 1 语法检查 (forbidden keywords)
GR->>GR: Layer 2a 安全策略 (PII / permission)
GR->>GR: Layer 2c AST 列引用校验 (sql_column_validator)
GR->>GR: Layer 2d 术语绑定语义校验 (term binding validation)
GR->>DP: Layer 3 EXPLAIN (估算行数 + cost)
DP-->>GR: execution plan
alt 校验通过
GR-->>EX: execute
else 校验失败 (可修复)
GR-->>CR: corrective_retrieval
CR->>PG: 补充检索
PG-->>CR: additional context
CR-->>SG: 重新生成
else 不可修复
GR-->>API: reject + error message
end
Note over EX,XP: Step 7: 执行 + 后处理
EX->>DP: 执行 SQL (LIMIT injected)
DP-->>EX: result rows
EX-->>RP: execution_result
RP->>RP: 格式化 + 截断
RP-->>XP: cleaned result
XP->>LLM: SQL 业务解释
LLM-->>XP: sql_business_context
Note over VZ,FU: Step 8: 可视化 + 洞察
XP-->>VZ: 触发可视化
VZ->>VZ: 推荐决策(DataShapeAnalyzer → ChartMatcher.recommend(top_k) → EChartsAdapter)
Note right of VZ: 95%+ 无需 LLM,rule-based top-k 推荐 + 置信度评估
alt 低置信度 (needs_review)
VZ-->>W: SSE checkpoint event → 前端 HITL 候选确认
W-->>VZ: 用户选择(accept/select_alternative/fallback_table)
end
alt 模板匹配失败 (score < 0.3)
VZ->>LLM: 图表修复建议 (repair fallback)
LLM-->>VZ: visualization config
end
VZ-->>IN: 触发洞察
IN->>LLM: 数据洞察生成
LLM-->>IN: insights text
IN-->>FU: 触发追问建议
FU->>LLM: 生成 follow-up questions
LLM-->>FU: suggestions
Note over API,U: Step 9: 流式返回
API-->>W: SSE events (status → sql → result → viz → insights → followup)
W-->>U: 渐进式渲染结果
路由决策矩阵¶
Router 根据 Query Understanding 的输出决定执行路径:
| Route | 触发意图 | 执行路径 | 特点 |
|---|---|---|---|
kpi_lookup |
简单 KPI 查询 | retrieval → reranker → sql_gen → guardrails → executor → explainer | 最短路径,跳过 viz/insights |
nl2sql_query |
趋势、对比、排名、明细 | retrieval → reranker → schema_explorer → sql_gen → guardrails → executor → processor → explainer → viz → insights → followup | 完整管道 |
deep_analysis_workflow |
根因分析、报告生成 | planner → retrieval → ... → retrieval_eval → sql_eval → ... → answer_eval | 含三级评估器 |
analytical |
复杂分析(自动升级) | 同 deep_analysis,由 analytical_depth == "complex" 触发 |
nl2sql 的升级版 |
graph_reasoning |
关系探索、图谱推理 | graph_rag_agent | Cypher 查询 AGE |
business_knowledge_qa |
策略 / SOP 问答 | retrieval → knowledge_qa_agent | 不生成 SQL |
clarification_required |
模糊意图 | retrieval → follow_up_agent | 返回澄清选项 |
SQL Cache 快速路径
当 Router 检测到 question_embedding 与缓存 SQL 的 embedding 相似度 ≥ 0.92 时,
直接跳转 guardrails_agent,跳过检索和生成,大幅降低延迟。
5. 离线发布链路¶
语义资产从 YAML 编辑到线上生效的完整管道:
flowchart TB
subgraph DevPhase["开发阶段"]
EDIT["Data Steward 编辑 YAML<br/>semantic-plane/"]
VAL1["validate_all_yaml.py<br/>JSON Schema 校验"]
VAL2["validate_sql_definitions.py<br/>SQL 语法验证"]
VAL3["validate_cross_layer_refs.py<br/>跨层引用完整性"]
VAL4["check_version_bump.py<br/>版本号递增检查"]
end
subgraph CIPhase["CI / PR 阶段"]
PR["Pull Request"]
DIFF["analyze_metadata_diff.py<br/>变更影响分析"]
REVIEW["Governance Lead 审批<br/>(MAJOR 变更)"]
end
subgraph BuildPhase["构建阶段"]
CS["build_changeset.py<br/>增量 changeset (git diff)"]
FULL["build_full_changeset.py<br/>全量 changeset (首次)"]
end
subgraph DeployPhase["部署阶段 (Backend Auto-Sync)"]
PUB2["ttd-publish-sp<br/>发布 YAML 到 S3"]
BACKEND["Admin Backend semantic_plane agent<br/>━━━━━━━━━━━━━━━<br/>• Upsert → semlayer.* (Engine R)<br/>• MERGE → AGE graph (Engine G)<br/>• DashScope embedding → pgvector (Engine V)<br/>• 软删除缺失资产"]
end
EDIT --> VAL1 --> VAL2 --> VAL3 --> VAL4
VAL4 --> PR
PR --> DIFF --> REVIEW
REVIEW --> PUB2
PUB2 --> BACKEND
style DevPhase fill:#e8f4fd,stroke:#2980b9,color:#1a1a2e
style CIPhase fill:#e8f8f5,stroke:#27ae60,color:#1a1a2e
style BuildPhase fill:#fef9e7,stroke:#f39c12,color:#1a1a2e
style DeployPhase fill:#fdecea,stroke:#e74c3c,color:#1a1a2e
发布管道详细步骤¶
| 步骤 | 工具 | 输入 | 输出 | 失败处理 |
|---|---|---|---|---|
| 1 | validate_all_yaml.py |
YAML 文件 | Pass / Fail | CI 阻断 PR merge |
| 2 | validate_sql_definitions.py |
metric SQL | Pass / Fail | CI 阻断 |
| 3 | validate_cross_layer_refs.py |
全部资产 | 引用报告 | CI 阻断 |
| 4 | check_version_bump.py |
git diff | 版本对比 | 强制 bump |
| 5 | build_changeset.py |
git diff | JSON changeset | — |
| 6 | ttd-publish-sp |
YAML assets | S3 manifest | 重试 |
| 7 | Backend semantic_plane agent |
S3 manifest | Aurora R + V + G | 事务回滚 + 重试 |
change_log 状态机
metadata_ingest 写入 change_log 时状态为 pending(needs_vectorize = true),
embedding_generator 消费后更新为 completed。
6. R/V/G/D 四引擎协作¶
TTD 的 PG Supernode 将三种数据引擎统一部署在 Aurora PostgreSQL 实例中,
并通过 semlayer.dynamic_few_shot_cache 表引入Engine D(动态 Few-Shot),
实现「一个连接池、四种检索范式」:
flowchart LR
subgraph PGSupernode["Aurora PostgreSQL — PG Supernode"]
direction TB
subgraph EngineR["Engine R — Relational"]
R1["semlayer.table_asset"]
R2["semlayer.column_asset"]
R3["semlayer.metric_asset"]
R4["semlayer.business_term"]
R5["semlayer.join_rule"]
R6["semlayer.few_shot_example"]
R7["semlayer.business_rule"]
R8["semlayer.business_context"]
end
subgraph EngineV["Engine V — Vector (pgvector)"]
V1["table_embedding"]
V2["column_embedding"]
V3["metric_embedding"]
V4["term_embedding"]
V5["rule_embedding"]
end
subgraph EngineG["Engine G — Graph (Apache AGE)"]
G1["ttd_governance graph"]
G2["Nodes: Table, Column, Metric, Term, Rule, Context"]
G3["Edges: HAS_COLUMN, USES_TERM, BOUND_TO, RELATES_TO"]
end
subgraph EngineD["Engine D — Dynamic Few-Shot"]
D1["semlayer.dynamic_few_shot_cache"]
D2["review_status: approved"]
D3["similarity ≥ 0.95 gate"]
end
end
Q["查询请求"] --> EngineR
Q --> EngineV
Q --> EngineG
Q --> EngineD
四引擎对比¶
| 维度 | Engine R (Relational) | Engine V (Vector) | Engine G (Graph) | Engine D (Dynamic Few-Shot) |
|---|---|---|---|---|
| 存储 | Aurora PostgreSQL semlayer.* 表 |
pgvector *_embedding 表 |
Apache AGE ttd_governance 图 |
semlayer.dynamic_few_shot_cache (pgvector) |
| 目的 | Source of Truth,结构化精确查询 | 语义搜索,模糊匹配 | 关系遍历,治理边界执行 | 在线学习 few-shot,补充手工策划示例 |
| 访问模式 | FK lookup, 精确匹配, 约束检查 | Top-K cosine similarity, threshold 过滤 | Cypher 查询, 路径探索, 边界约束 | Top-K cosine similarity + review_status 过滤 |
| 写入时机 | Backend semantic_plane agent (实时) | Backend semantic_plane agent (实时) | Backend semantic_plane agent (实时) | SQL 修复成功时自动写入(pending_review) |
| 注入条件 | — | — | — | Admin approve + sim ≥ 0.95 + confidence ≥ 0.9 |
| 典型查询 | SELECT * FROM semlayer.table_asset WHERE table_id = ? |
ORDER BY embedding <=> $vec LIMIT K |
MATCH (t:Table)-[:HAS_COLUMN]->(c) RETURN c |
WHERE review_status='approved' AND sim >= 0.95 |
| 延迟 | < 5ms | 10-50ms (取决于 K 值) | 10-100ms (取决于遍历深度) | 10-30ms(并行执行,不在关键路径) |
检索编排策略¶
Data Retrieval 节点的四引擎协调
# 简化伪代码
async def data_retrieval(state):
embedding = state["question_embedding"]
# 从 Query Understanding 获取 LLM 提取的搜索关键词
# QU 已经用 LLM 解析出 entities.terms / metric_candidates 等
qu = state["query_understanding"]
search_terms = from_query_understanding(qu) # ["价格", "商品", ...]
# Engine 1+1b+2+D 并行:术语精确匹配 + 列别名匹配 + 向量召回 + 动态 few-shot
term_hits, keyword_hits, vector_results, dynamic_few_shots = await asyncio.gather(
exact_term_match(query, search_terms=search_terms), # Engine 1 (R): LLM 提取的关键词精确匹配
keyword_column_search(query), # Engine 1b (R+): 列别名字典匹配
pgvector_search(embedding, top_k=20), # Engine 2 (V): 向量语义召回
dynamic_few_shot_cache.search_similar(embedding), # Engine D: 已审批动态 few-shot
)
# Engine R+ 无条件合并:术语绑定的列始终注入,不受 vector 命中数量约束
merge_keyword_hits(vector_results, keyword_hits)
# Engine D merge:只注入 approved + similarity ≥ 0.95 的条目
if dynamic_few_shots:
vector_results["few_shots"].extend(dynamic_few_shots)
# 构建术语绑定视图:term → mapped_asset_id → parent table
term_bindings = build_term_bindings(term_hits, vector_results["terms"])
# Engine 3 (G): Graph 遍历:治理约束和关联路径(串行,依赖上游 asset_ids)
graph_context = await graph_traversal(all_asset_ids)
return {
"retrieval_results": {**vector_results, "_term_bindings": term_bindings},
"graph_context": graph_context,
}
术语绑定强路由
Term Binding 是从 Semantic Plane 业务术语到物理列/指标的映射关系。
当 Engine 1 命中了具有 mapped_asset_id 的术语时,该绑定会作为强路由信号贯穿整个管道:
- Reranker:绑定列得到优先加分,其父表得到提升,不含绑定列的表被降权
- Prompt Assembler:注入
## 术语绑定约束段落,明确告知 LLM 必须从哪张表取该列 - Guardrails:Layer 2d 语义校验,拦截将绑定列引用到错误表的 SQL
- Corrective Retrieval:检测到绑定违规时,优先按绑定关系拉取正确的表和列
7. 多模型协作¶
系统采用多模型分工协作策略,根据任务特性分配最优模型,通过 ModelRegistry 统一管理:
模型分配表¶
| 任务 (Task) | 默认模型 | Fallback Chain | 选型理由 |
|---|---|---|---|
| Supervisor / Intent | deepseek-v3.2 |
qwen3-max → qwen3-coder-plus | 推理能力强,指令遵循度高 |
| Query Understanding | deepseek-v3.2 |
qwen3-max → qwen3-coder-plus | 需要精准结构化分析 |
| SQL Generation | qwen3-coder-plus |
qwen3-max → deepseek-v3.2 | 代码生成专精,SQL 准确率最高 |
| SQL Repair | qwen3-coder-plus |
qwen3-max → deepseek-v3.2 | 需要理解错误并修复代码 |
| Insights / Viz | qwen3-max |
deepseek-v3.2 → qwen3-coder-plus | 自然语言生成质量最佳 |
| SQL Explanation | qwen3-max |
deepseek-v3.2 → qwen3-coder-plus | 需将 SQL 翻译为业务语言 |
| Knowledge QA | qwen3-max |
deepseek-v3.2 → qwen3-coder-plus | 复杂知识问答 |
| Follow-up | deepseek-v3.2 |
qwen3-max → qwen3-coder-plus | 轻量推理 + 快速响应 |
| Planner | deepseek-v3.2 |
qwen3-max → qwen3-coder-plus | 需要全局规划能力 |
| Embedding | text-embedding-v4 (DashScope) |
— | 1024 维向量,中英双语优化 |
模型调用架构¶
flowchart LR
subgraph Registry["ModelRegistry"]
MAP["Task → Model 映射"]
FB["Fallback Chain"]
ADMIN["Admin DB Override"]
end
subgraph Provider["DashScope (OpenAI-compatible)"]
DS["deepseek-v3.2"]
QM["qwen3-max"]
QC["qwen3-coder-plus"]
EMB["text-embedding-v4"]
end
SUP3["Supervisor Node"] -->|"get_model('supervisor')"| Registry
Registry -->|"primary"| DS
Registry -->|"fallback[0]"| QM
Registry -->|"fallback[1]"| QC
SG3["SQL Gen Node"] -->|"get_model('sql_generation')"| Registry
Registry -->|"primary"| QC
Fallback 机制¶
模型降级策略
当主模型不可用(HTTP 429/503/timeout)时,ModelRegistry 自动尝试 fallback chain:
- 捕获
ModelUnavailableError - 按 fallback chain 顺序尝试备选模型
- 全部失败则抛出
ModelUnavailableError终止管道 - Circuit Breaker:连续 3 次失败后暂停该模型 60s
配置方式¶
# app/config.py — 环境变量覆盖默认模型
TTD_SUPERVISOR_MODEL=deepseek-v3.2
TTD_SQL_GENERATION_MODEL=qwen3-coder-plus
TTD_INSIGHTS_MODEL=qwen3-max
TTD_FOLLOWUP_MODEL=deepseek-v3.2
TTD_EMBEDDING_MODEL=text-embedding-v4
管理员也可通过 Admin Panel (/admin/models/*) 在线修改任务 → 模型映射,
DB 配置优先级高于代码默认值。
8. 数据面切换¶
TTD 支持双数据面后端,通过环境变量一键切换:
双后端对比¶
| 维度 | 生产环境 (Redshift) | 开发环境 (pg_mooncake) |
|---|---|---|
| 引擎 | AWS Redshift Serverless | pg_mooncake (PostgreSQL + columnstore) |
| 连接方式 | redshift-connector |
psycopg (标准 PG 协议) |
| 存储格式 | Redshift 列式存储 | columnstore mirror (mooncake) |
| SQL 方言 | Redshift SQL | PostgreSQL (标准 SQL) |
| 性能 | 生产级,支持 PB 级数据 | 开发级,单机轻量 |
| 成本 | 按用量计费 | 本地免费 |
| 部署 | AWS 托管 | Docker Compose 一键启动 |
切换配置¶
# .env 配置切换数据面
TTD_DATA_PLANE_BACKEND=redshift # 生产环境
TTD_DATA_PLANE_BACKEND=pg_mooncake # 开发环境
# Redshift 配置 (TTD_DATA_PLANE_BACKEND=redshift)
TTD_REDSHIFT_HOST=workgroup.123456.us-east-1.redshift-serverless.amazonaws.com
TTD_REDSHIFT_PORT=5439
TTD_REDSHIFT_DATABASE=ttd_gold
TTD_REDSHIFT_USER=ttd_service
TTD_REDSHIFT_PASSWORD=***
TTD_REDSHIFT_TIMEOUT_MS=30000
# pg_mooncake 配置 (TTD_DATA_PLANE_BACKEND=pg_mooncake)
TTD_PG_MOONCAKE_DSN=postgresql://postgres:postgres@localhost:5436/ttd_lake
pg_mooncake 本地架构¶
flowchart LR
subgraph DockerCompose["docker-compose.yml (data-plane/)"]
PGL["pg_mooncake<br/>PostgreSQL + columnstore<br/>:5436"]
MINIO["MinIO<br/>S3-compatible<br/>:9000 / :9001"]
end
PGL -->|"S3 发布"| MINIO
BE["Backend"] -->|"PostgreSQL 协议"| PGL
本地开发快速启动
SQL 方言适配¶
settings.sql_dialect 属性根据 data_plane_backend 自动返回对应方言:
redshift→ Redshift SQL(支持DISTKEY,SORTKEY,APPROXIMATE COUNT等)pg_mooncake→ PostgreSQL SQL(标准 SQL)
SQL Generator 在 prompt 中注入当前方言,确保生成的 SQL 兼容目标引擎。
9. 架构原则¶
TTD 的架构设计遵循以下 8 项核心原则:
原则总览¶
| # | 原则 | 英文 | 核心要点 |
|---|---|---|---|
| 1 | 治理优先 | Governance First | 任何 SQL 生成必须经过术语、规则、上下文约束 |
| 2 | 异步优先 | Async First | 所有 I/O 使用 async/await,最大化并发吞吐 |
| 3 | 纵深防御 | Defense in Depth | 安全检查在意图→检索→生成→执行多层重复 |
| 4 | 可观测 | Observable | 全链路结构化日志 + Prometheus metrics |
| 5 | 可演进 | Evolvable | 语义资产、模型、数据源支持热切换与增量升级 |
| 6 | 本地可复现 | Locally Reproducible | data-plane + backend + web 跑通完整闭环 |
| 7 | Fail-Safe | Fail-Safe | 无法确认安全性时拒绝执行,而非尝试 |
| 8 | 配置集中 | Centralized Config | 所有配置通过 Settings + 环境变量统一管理 |
原则 1:治理优先 (Governance First)¶
理念
语义治理不是事后补充,而是内嵌于查询管道的核心约束。
- SQL Generator 的 prompt 中必须包含治理上下文(术语规范、业务规则、上下文假设)
- Guardrails Agent 检查 SQL 是否违反 Layer 3 业务规则
- Graph Engine (AGE) 在检索阶段执行边界约束(例:某些表只对特定域可见)
governance_overlays在 Supervisor 阶段一次性解析,下游所有节点共享
原则 2:异步优先 (Async First)¶
理念
高并发场景下,阻塞 I/O 是性能瓶颈。系统全链路异步化。
- FastAPI ASGI + uvicorn 单 worker per instance,水平扩展通过 Docker Swarm replicas
- 数据库:
psycopgAsyncConnectionPool(pg_pool_min=5, pg_pool_max=20 per instance) - LLM 调用:
model.ainvoke()异步调用 - Sub-agent 节点函数签名:
async def node(state) -> dict - SSE 流式响应:
StreamingResponse+async generator - 分布式并发控制:PG Advisory Lock(
pg_advisory_xact_lock(hashtext(chat_id))),跨实例安全
原则 3:纵深防御 (Defense in Depth)¶
理念
安全检查不依赖单点,每一层独立执行各自的安全职责。
[意图层] QU 识别高风险意图 → 标记 requires_elevated_check
↓
[检索层] Data Retrieval 过滤 sensitivity_level=pii 的列
↓
[生成层] SQL Generator 遵循 llm_exposure_policy 约束
↓
[校验层] Guardrails 检测 forbidden_keywords + EXPLAIN cost
↓
[执行层] SQL Executor 注入 LIMIT + statement_timeout
原则 4:可观测 (Observable)¶
理念
生产系统必须具备全链路可观测能力,问题发生时能快速定位。
- 结构化日志:
structlogJSON 格式,每个管道步骤记录输入/输出摘要 - 审计追踪:
app/audit/模块记录所有 SQL 生成/执行/拒绝事件 - Metrics:Prometheus endpoint (
/metrics),暴露延迟、错误率、模型调用统计 - Trace ID:每次请求生成唯一 trace_id,贯穿所有日志
原则 5:可演进 (Evolvable)¶
理念
业务需求持续变化,架构必须支持低成本增量演进。
- 语义资产:YAML 编辑 + CI 校验 + S3 发布 + Backend 自动导入,无需重启后端
- 模型配置:Admin Panel 在线切换 task → model 映射,支持 A/B 测试
- 路由扩展:新增 route 只需在 Router 的
_ROUTE_PLANS字典添加条目 - Sub-agent 插件化:新 Agent = 工厂函数 + state 字段 + 图注册,三步完成
原则 6:本地可复现 (Locally Reproducible)¶
理念
开发者在本地笔记本上能跑通完整系统,无需 AWS 账号。
| 云端组件 | 本地替代 | 启动方式 |
|---|---|---|
| Aurora PostgreSQL | Docker: age-pgvector:local | data-plane/docker-compose.yml |
| Redshift Serverless | pg_mooncake + MinIO | data-plane/docker-compose.yml |
| Step Functions + Lambda | ttd-publish-sp → Backend auto-sync |
task dp:publish-sp |
| DashScope API | 需真实 API Key (无 mock) | .env 配置 |
原则 7:Fail-Safe¶
理念
安全性优先于功能可用性。不确定的情况下拒绝,而不是尝试。
- Guardrails 遇到无法判定的 SQL → 拒绝执行并返回明确原因
- 模型输出解析失败 → 返回 safe fallback 而非传播错误
- EXPLAIN 估算行数超过
max_estimated_rows(10M) → 拒绝执行 - PII 列标记为
hidden→ 完全从 LLM 上下文中移除
原则 8:配置集中 (Centralized Config)¶
理念
配置散落在代码各处是运维噩梦。统一入口、统一前缀、类型安全。
# app/config.py — 唯一配置入口
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="TTD_", ...)
# 所有配置项类型安全、有默认值、可通过环境变量覆盖
data_plane_backend: DataPlaneBackend = "redshift"
supervisor_model: str = "deepseek-v3.2"
sql_cache_similarity: float = 0.92
...
# 使用方式
from app.config import settings
settings.data_plane_backend # 类型提示 + IDE 自动补全
附录 A:关键目录速查¶
| 目录 | 职责 | 关键文件 |
|---|---|---|
web/ |
Next.js 16 前端 | app/, components/, hooks/ |
backend/app/agents/ |
LangGraph 编排层 | supervisor.py, builder.py, state.py |
backend/app/agents/sub_agents/ |
所有 Sub-agent | router.py, sql_generation.py, guardrails.py |
backend/app/agents/evaluators/ |
质量评估器 | Retrieval / SQL / Answer Evaluator |
backend/app/runtime/ |
Agent Runtime Pool 管理 | registry.py, lifecycle.py |
backend/app/skills/ |
MCP 工具技能 | rag.py, reranker.py, sql_executor.py, governance.py |
backend/app/skills/chart_templates/ |
推荐决策引擎 + ECharts Adapter | top-k recommendation, 35 templates, adapter layer, theme system |
backend/app/api/ |
FastAPI 端点 | chats.py, sessions.py, admin/ |
backend/app/memory/ |
四层记忆 | Working / Profile / Episodic / Correction + SQL Cache |
backend/app/models/ |
多模型注册表 | registry.py |
backend/app/security/ |
安全模块 | JWT / Content Safety / Permission |
deploy/swarm/ |
Docker Swarm 生产部署 | docker-compose.swarm.yml, haproxy.cfg |
semantic-plane/ |
三层元数据资产 | domains/, terms/, business_rules/ |
data-plane/ |
本地数据面 | docker-compose.yml, sql/, scripts/ |
scripts/ |
CI 校验工具 | validate_*.py, build_changeset.py |
附录 B:技术栈总览¶
| 层 | 技术 | 版本 | 用途 |
|---|---|---|---|
| Frontend | Next.js | 16.2 | SSR + 流式 UI |
| Frontend | shadcn/ui + Radix | — | 组件库 |
| Backend | Python | 3.12+ | 运行时 |
| Backend | FastAPI + uvicorn | — | ASGI 服务器 |
| Backend | LangGraph | ≥ 0.4.0 | Agent 编排 |
| Backend | LangChain | — | 多模型集成 |
| Backend | Pydantic v2 | — | 数据校验 + Settings |
| Backend | psycopg 3 | — | 异步 PG 驱动 |
| Backend | structlog | — | 结构化日志 |
| Routing | HAProxy | 2.9+ | Consistent hash 路由 (session affinity) |
| Orchestration | Docker Swarm | — | Agent Runtime Pool 部署、滚动更新、自动扩缩 |
| Database | Aurora PostgreSQL | — | PG Supernode (R+V+G) + Advisory Lock |
| Database | pgvector | — | 向量检索 |
| Database | Apache AGE | — | 属性图 |
| Data Plane | Redshift Serverless | — | 生产数据面 |
| Data Plane | pg_mooncake | — | 开发数据面 |
| Storage | MinIO | — | 本地 S3 (发布 + 图片) |
| LLM | DashScope | — | DeepSeek / Qwen3 / Embedding |
| CI/CD | GitHub Actions | — | 自动化管道 |
附录 C:环境变量前缀规范¶
所有 TTD 环境变量使用 TTD_ 前缀,通过 app/config.py 的 Settings 单例读取:
| 分类 | 变量示例 | 说明 |
|---|---|---|
| 数据面 | TTD_DATA_PLANE_BACKEND |
redshift 或 pg_mooncake |
| 数据库 | TTD_AURORA_DSN |
PG Supernode 连接串 |
| 模型 | TTD_SUPERVISOR_MODEL |
Supervisor 使用的模型 |
| 安全 | TTD_JWT_SECRET |
JWT 签名密钥 |
| 检索 | TTD_TOP_K_TABLES |
向量检索 Top-K |
| 执行 | TTD_STATEMENT_TIMEOUT_MS |
SQL 超时限制 |
| 记忆 | TTD_SQL_CACHE_SIMILARITY |
SQL Cache 相似度阈值 |
完整变量列表参见根目录 .env.example。