跳转至

运行与安全

适用对象

本文档面向 运维工程师安全审计员Backend Developer, 涵盖安全架构、可观测性、运行时稳定性及故障排查指南。


1. 安全架构 (Security Architecture)

TTD 采用 三层纵深防御 架构,确保从用户输入到数据返回的全链路安全。

1.1 安全分层总览

graph TB
    subgraph API 层
        A1[Better Auth JWKS Authentication]
        A2[Rate Limiting]
        A3[CORS Policy]
        A4[Input Validation]
    end
    subgraph 生成层
        B1[Content Safety Guard]
        B2[SQL Validation]
        B3[EXPLAIN Cost Check]
        B4[Forbidden Keywords]
    end
    subgraph 数据层
        C1[PII Exposure Policy]
        C2[Domain Boundaries]
        C3[Row-Level Security]
        C4[Statement Timeout]
    end
    A1 --> B1
    B1 --> C1

1.2 各层安全机制

层级 机制 实现位置 说明
API 层 JWT 认证 backend/app/security/auth.py Better Auth JWKS (RS256) 验签,Token 有效期内免重认证
API 层 Rate Limiting backend/app/api/ 60 次/分钟/用户,突发上限 100
API 层 CORS backend/app/main.py 可配置允许来源
API 层 Input Validation backend/app/api/ 最大问题长度 2000 字符
生成层 Content Safety Guard backend/app/security/guard.py DML 检测、Prompt Injection 检测
生成层 SQL Validation backend/app/security/policy.py Forbidden keywords、语法校验
生成层 EXPLAIN Cost Check backend/app/agents/ 预估行数/成本超限则拦截
数据层 PII Policy semantic-plane/ YAML llm_exposure_policy: visible/masked/hidden
数据层 Domain Boundaries Semantic Plane 仅允许查询已注册的表和列
数据层 Statement Timeout PostgreSQL / Redshift 30s 硬超时

2. 认证与授权 (Authentication & Authorization)

2.1 整体架构

TTD 采用 Better Auth 作为统一身份与会话权威,托管在 Next.js 侧。FastAPI 后端通过 JWKS 本地验签 信任 Better Auth 签发的 JWT,不维护第二套认证逻辑。

sequenceDiagram
    participant U as Browser
    participant W as Next.js (Better Auth)
    participant API as FastAPI Backend

    U->>W: POST /api/auth/sign-in/email
    W->>W: 验证凭据,创建 session
    W-->>U: Set-Cookie (session token)

    U->>W: GET /api/auth/token (JWT plugin)
    W-->>U: signed JWT (RS256)

    U->>API: GET /api/v1/chats (Authorization: Bearer <JWT>)
    API->>API: 从 JWKS 获取公钥,验证 JWT 签名
    API->>API: 校验 iss, aud, exp
    API-->>U: 200 OK (chats list)

2.2 身份提供者 (Identity Provider)

组件 技术 说明
IdP 框架 Better Auth 托管在 Next.js,提供注册/登录/会话/JWT/JWKS 端点
Session 管理 Better Auth native cookies 浏览器主会话,7 天有效期
JWT 签发 Better Auth JWT plugin RS256 签名,1 小时有效,用于 API 访问
JWKS 端点 /api/auth/jwks 公钥发布,FastAPI 据此验签
数据存储 PostgreSQL (共用实例) user / session / account / verification / jwks 五表

支持的登录方式:

方式 状态 说明
Email/Password ✅ 已启用 最小密码长度 8 字符
GitHub OAuth ⚡ 条件启用 需配置 GITHUB_CLIENT_ID + GITHUB_CLIENT_SECRET

2.3 JWT 验证 (FastAPI 侧)

FastAPI 使用 PyJWKClient 从 Better Auth JWKS 端点获取公钥,本地验签 JWT。

# 验证配置
Algorithm: RS256 / ES256
JWKS URL: ${BETTER_AUTH_URL}/api/auth/jwks
Issuer: ${BETTER_AUTH_URL}  (e.g. http://localhost:3000)
Audience: talk-to-data
JWKS Cache TTL: 3600s (1 hour)

实现位置: backend/app/security/auth.py

# 核心验证流程
jwks_client = PyJWKClient(f"{better_auth_url}/api/auth/jwks")
signing_key = jwks_client.get_signing_key_from_jwt(token)
payload = jwt.decode(token, signing_key.key, algorithms=["RS256", "ES256"],
                     audience="talk-to-data", issuer=better_auth_url)

2.4 Token Claims 结构

{
  "sub": "better_auth_user_id",
  "role": "admin",
  "aud": "talk-to-data",
  "iss": "http://localhost:3000",
  "exp": 1700000000,
  "iat": 1699913600
}
Claim 类型 说明
sub string Better Auth user.id — 全系统唯一主体标识
role string 全局角色(Better Auth Admin plugin 设置)
roles string[] 兼容扩展角色列表(可选)
allowed_domains string[] 可访问业务域(Phase 1 为空集合)
aud string 预期受众,必须匹配 talk-to-data
iss string 签发者,必须匹配 BETTER_AUTH_URL
exp int 过期时间 (Unix timestamp)
iat int 签发时间 (Unix timestamp)

2.5 授权模型

Phase 1 采用全局角色模型(不引入 Organization / Team / Dynamic RBAC):

角色 权限
admin 全部 API + Admin Panel
user (默认) Chat API + 自有资源访问

后端授权实现:

  • get_current_user — 解析 JWT,返回 UserContext(user_id, roles, allowed_domains)
  • require_admin — 依赖注入,要求 admin 角色,否则返回 403
  • 资源所有权 — Chat/Feedback 按 user_id 过滤,不依赖前端判断
# Admin API 路由级保护
admin_router = APIRouter(prefix="/admin", dependencies=[Depends(require_admin)])

2.6 开发模式旁路 (Dev Mode Bypass)

仅限开发环境

TTD_DEBUG=true 且请求无 Bearer Token 时,系统返回默认 admin 上下文。 生产环境必须设置 TTD_DEBUG=false

# 开发模式下的默认用户
dev_user = UserContext(user_id="dev-user", roles=["admin"], allowed_domains=[])

迁移期 HS256 回退

TTD_DEBUG=true 时,若 JWKS 验证失败,系统尝试以旧 HS256 secret 验证 Token。 此回退将在迁移完成后(Phase 7)移除。

2.7 环境变量清单

变量 位置 默认值 说明
BETTER_AUTH_URL Web + Backend http://localhost:3000 Better Auth 基础 URL
BETTER_AUTH_SECRET Web dev-secret-change-me 会话加密密钥(生产必须强随机值)
AUTH_DATABASE_URL Web Better Auth 专用数据库连接串
GITHUB_CLIENT_ID Web GitHub OAuth App ID(可选)
GITHUB_CLIENT_SECRET Web GitHub OAuth App Secret(可选)
NEXT_PUBLIC_GITHUB_AUTH_ENABLED Web 前端是否显示 GitHub 按钮
TTD_JWT_AUDIENCE Backend talk-to-data JWT audience 校验值
TTD_BETTER_AUTH_URL Backend http://localhost:3000 JWKS 获取地址
TTD_BETTER_AUTH_ISSUER Backend http://localhost:3000 JWT issuer 校验值
TTD_JWKS_CACHE_TTL_SECONDS Backend 3600 JWKS 缓存刷新间隔

2.8 API Key 支持

管理类操作(如强制刷新缓存、手动触发 ingest)仍支持通过 API Key 认证:

curl -H "X-API-Key: ${TTD_ADMIN_API_KEY}" \
     http://localhost:8000/api/v1/admin/refresh-cache

3. SQL 安全策略 (SQL Security Policies)

3.1 Forbidden Keywords

生成的 SQL 严禁包含以下关键字(大小写不敏感):

FORBIDDEN_KEYWORDS = [
    "INSERT", "UPDATE", "DELETE",
    "DROP", "ALTER", "CREATE",
    "TRUNCATE", "GRANT", "REVOKE",
    "EXECUTE"
]

违反后果

检测到 Forbidden Keyword 后,请求立即终止,返回 PolicyViolationError, 用户侧收到消息:"仅允许查询操作,不支持修改数据"。

3.2 EXPLAIN Cost Check

在执行 SQL 前,系统会先运行 EXPLAIN 分析查询计划:

检查项 阈值 配置变量
预估行数 (Estimated Rows) ≤ 10,000,000 TTD_MAX_ESTIMATED_ROWS
预估成本 (Estimated Cost) ≤ 100,000 TTD_MAX_ESTIMATED_COST

超过阈值时返回友好提示:

  • 行数超限:「查询结果集过大,请添加过滤条件缩小范围」
  • 成本超限:「查询复杂度过高,请简化查询条件」

3.3 执行约束

约束 配置变量
Statement Timeout 30 秒 TTD_STATEMENT_TIMEOUT_MS
最大返回行数 1,000 TTD_MAX_ROWS
最大扫描字节 1 GB TTD_MAX_SCANNED_BYTES
Stacked Queries 禁止 检测分号分隔的多语句

3.4 注入防护

# Content Safety Guard 检测模式
INJECTION_PATTERNS = [
    r";\s*(DROP|DELETE|INSERT|UPDATE)",   # Stacked DML
    r"UNION\s+SELECT",                    # UNION injection
    r"ignore\s+(previous|above)\s+instructions",  # Prompt injection
    r"system\s*prompt",                   # Prompt extraction
]

3.5 仅允许 SELECT

系统通过 AST 解析确认生成的 SQL 仅为 SELECT 语句。 任何非 SELECT 语句(包括 CTE 内嵌的 DML)均会被拦截。


4. 可观测性 (Observability)

系统采用统一可观测性架构,通过 ObservabilityFacade 将 Langfuse(追踪/评分)、AutoMQ(事件流)和 structlog(结构化日志)整合为一体。所有组件(Agent、Memory、Evaluator)共享同一 trace context。

graph LR
    A[API Request] --> B[ObservabilityFacade]
    B --> C[Langfuse Adapter<br/>trace / span / score]
    B --> D[AutoMQ Exporter<br/>event streaming]
    B --> E[structlog<br/>JSON logs]
    C --> F[Langfuse Cloud / Self-hosted]
    D --> G[Kafka-compatible Topic]
    E --> H[Log Collector]

4.1 统一可观测性门面 (ObservabilityFacade)

文件:backend/app/observability/facade.py

ObservabilityFacade 是所有可观测性操作的唯一入口,封装了 Langfuse、AutoMQ 与 structlog 三个后端。Agent 编排、记忆系统、评估器均通过此门面记录追踪数据,确保 trace_id 贯穿完整请求链路。

核心方法 (Key Methods)

方法 说明
start_trace(session_id, user_id, ...) 创建请求级 trace,返回 trace_id
finalize_trace(trace_id, status, ...) 关闭 trace,记录最终状态与 token 汇总
start_span(trace_id, name, ...) 在 trace 下创建子 span(Agent 步骤、LLM 调用等)
end_span(span_id, output, ...) 关闭 span,附带输出与耗时
record_score(trace_id, name, value, ...) 记录评分(评估器结果或用户反馈)
emit_event(event_type, payload, ...) 发送事件至 AutoMQ 流
get_langchain_handler(trace_id) 返回 LangChain callback handler(自动关联 trace)

使用示例

from app.observability.facade import observability

# 请求入口
trace_id = observability.start_trace(session_id=sid, user_id=uid)

# Agent 步骤
span_id = observability.start_span(trace_id, name="sql_generation")
# ... 执行逻辑 ...
observability.end_span(span_id, output={"sql": generated_sql})

# 记录评分
observability.record_score(trace_id, name="sql_quality", value=0.92)

# 发送事件
observability.emit_event(EventType.SESSION_TURN_PERSISTED, {"turn_id": turn_id})

# 请求结束
observability.finalize_trace(trace_id, status="success")

4.2 Langfuse 集成

文件:backend/app/observability/langfuse_adapter.py

每个用户请求对应一个 Langfuse Trace,所有后续操作(Agent 步骤、LLM 调用、记忆检索)作为 Span 挂载在该 trace 下。评估器结果和用户反馈通过 Score 关联到 trace。

graph TD
    T[Trace: user request] --> S1[Span: intent_recognition]
    T --> S2[Span: sql_generation]
    T --> S3[Span: memory.retrieve]
    S2 --> S2a[Span: llm_call]
    T --> SC1[Score: sql_quality = 0.92]
    T --> SC2[Score: user_feedback = like]

关联关系 (Correlation)

维度 说明
trace_id 请求唯一标识,贯穿所有 span 和 score
session_id 同一会话的多轮对话共享
user_id 用户级聚合分析
turn_id 单轮对话标识

observe_span 装饰器(backend/app/observability/spans.py)可自动为任意函数创建 span:

from app.observability.spans import observe_span

@observe_span(name="validate_sql")
async def validate_sql(sql: str) -> ValidationResult:
    ...

4.3 AutoMQ 事件流

文件:backend/app/observability/automq_exporter.py

系统通过 Kafka-compatible 的 AutoMQ 进行轻量级事件流转发。事件仅携带引用 ID(非完整 payload),下游消费者可据此构建仪表盘、告警规则和审计线索。

事件类型 (EventType)

定义于 backend/app/observability/events.py

事件 触发时机
session.created 新会话创建
session.turn.started 用户发送消息,开始处理
session.turn.persisted 处理完成,结果已持久化
turn.feedback.received 收到用户反馈(like/dislike)

事件消息结构

{
  "event_type": "session.turn.persisted",
  "trace_id": "abc-123-def",
  "session_id": "sess_456",
  "turn_id": "turn_012",
  "timestamp": "2024-01-15T10:30:01.500Z",
  "ref_ids": {
    "user_id": "user_789",
    "model": "qwen3-coder-plus"
  }
}

4.4 记忆生命周期事件 (Memory Lifecycle Events)

记忆系统(四层:working、profile、episodic、correction)的所有操作均为 trace-native,自动关联 trace_idsession_idturn_id。以下 7 个事件覆盖记忆的完整生命周期:

事件 说明
memory.retrieve.completed 记忆检索完成(含命中条数与延迟)
memory.rank.completed 记忆排序/重排完成
memory.write.candidate 产生候选写入记忆
memory.upsert.completed 记忆写入/更新完成
memory.suppress.completed 记忆被抑制(去重/冲突处理)
memory.expire.completed 记忆过期清理完成
memory.delete.completed 记忆显式删除完成

这些事件同时写入 Langfuse(作为 span 上的 event)和 AutoMQ(供下游审计/分析)。在 Langfuse UI 中可按 trace_id 查看某次请求涉及的所有记忆操作。

4.5 结构化日志 (structlog)

所有日志以 JSON 格式输出,便于日志收集和分析。

{
  "timestamp": "2024-01-15T10:30:00.123Z",
  "level": "info",
  "event": "sql_generated",
  "trace_id": "abc-123-def",
  "session_id": "sess_456",
  "user_id": "user_789",
  "model": "qwen3-coder-plus",
  "tokens_in": 2500,
  "tokens_out": 180,
  "latency_ms": 1200,
  "agent": "sql_generation"
}

标准日志字段

字段 类型 说明
trace_id string 请求级追踪 ID(贯穿整个 Agent 编排)
session_id string 会话 ID
user_id string 用户 ID
agent string 当前执行的 Agent 名称
model string 使用的 LLM 模型
tokens_in int 输入 Token 数
tokens_out int 输出 Token 数
latency_ms int 处理耗时 (ms)
event string 事件名称

4.6 Prometheus Metrics

TTD_PROMETHEUS_ENABLED=true 时,暴露 /metrics 端点:

# 请求与 LLM 指标
ttd_requests_total{endpoint, method, status}
ttd_request_duration_seconds{endpoint}
ttd_llm_calls_total{model, agent}
ttd_llm_tokens_total{model, direction}
ttd_sql_cache_hits_total
ttd_sql_cache_misses_total
ttd_active_sessions_gauge
ttd_sql_execution_duration_seconds

# 记忆系统指标
ttd_memory_retrieve_duration_seconds{layer}
ttd_memory_write_total{layer, operation}
ttd_memory_suppress_total{layer, reason}
ttd_memory_active_count{layer}

4.7 Health Check

GET /api/v1/health

返回示例:

{
  "status": "healthy",
  "version": "0.3.0",
  "uptime_seconds": 86400,
  "db_pool": {
    "size": 10,
    "available": 8,
    "in_use": 2
  },
  "data_plane": "pg_mooncake",
  "metadata_cache_age_seconds": 3600
}

4.8 审计日志

关键操作会写入审计表,包括:

  • 用户查询请求(脱敏后)
  • SQL 生成结果
  • 安全策略触发事件
  • 管理员操作
  • 记忆生命周期变更(通过 ObservabilityFacade 事件采集)

配置:

TTD_AUDIT_LOG_LEVEL: INFO          # 审计日志级别
TTD_AUDIT_ARCHIVE_BUCKET: ttd-audit-archive  # S3 归档桶
TTD_AUDIT_ARCHIVE_AFTER_DAYS: 90   # 90 天后归档至 S3

5. 运行时稳定性 (Runtime Stability)

5.1 SQL Cache (快路径)

graph LR
    A[用户提问] --> B{语义相似度 > 0.92?}
    B -->|是| C[返回缓存 SQL]
    C --> D[Guardrails 校验]
    D --> E[执行并返回]
    B -->|否| F[完整 Agent 编排]
配置 默认值 说明
TTD_SQL_CACHE_SIMILARITY 0.92 相似度阈值,越高越精确
TTD_SQL_CACHE_TTL_MINUTES 15 缓存条目有效期

Note

即使命中缓存,SQL 仍需经过 Guardrails 安全校验后才会执行。

5.2 Repair 机制 (SQL 修复)

SQL 执行失败时,系统会尝试自动修复:

graph TD
    A[SQL 执行失败] --> B{重试次数 < 1?}
    B -->|是| C[提取错误信息]
    C --> D[构造修复 Prompt]
    D --> E[重新生成 SQL]
    E --> F[执行修复后的 SQL]
    B -->|否| G[返回友好错误]
  • 最大重试次数: 1 (TTD_MAX_REPAIR_RETRIES)
  • 修复 Prompt 包含:原始 SQL、错误信息、可用表/列白名单

5.3 Circuit Breaker (熔断)

连续失败达到阈值时触发熔断:

参数 默认值 说明
TTD_CIRCUIT_BREAKER_THRESHOLD 3 连续失败次数阈值

熔断触发后:

  • 暂停向对应模型发送请求
  • 返回 fallback 响应:"AI 模型服务暂时不可用,请稍后重试"
  • 定时探活,恢复后自动解除熔断

5.4 Session 清理

过期会话定时回收,避免内存泄漏:

参数 默认值 说明
TTD_SESSION_TTL_HOURS 24 会话最大存活时间
TTD_SESSION_MAX_TURNS 20 单会话最大对话轮次
TTD_CLEANUP_INTERVAL_MINUTES 60 清理任务执行间隔

5.5 Metadata Cache

语义层元数据在内存中缓存,减少数据库查询:

参数 默认值 说明
TTD_METADATA_CACHE_TTL_SECONDS 86400 (24h) 缓存有效期

缓存失效策略:

  • TTL 过期后自动刷新
  • 管理员可通过 API 手动刷新
  • Ingest 流程完成后自动 invalidate

6. 错误处理 (Error Handling)

6.1 异常层次结构

classDiagram
    TTDError <|-- ClarificationNeededError
    TTDError <|-- PolicyViolationError
    TTDError <|-- SQLValidationError
    TTDError <|-- RetrievalMissError
    TTDError <|-- ModelUnavailableError

    class TTDError {
        +str message
    }
    class ClarificationNeededError {
        +list ambiguities
        +to_dict()
    }
    class PolicyViolationError {
        +list[str] errors
    }
    class SQLValidationError {
        +str layer
        +list[str] details
    }
    class RetrievalMissError {
    }
    class ModelUnavailableError {
        +str model_id
        +str cause
    }

6.2 错误类型说明

异常类 触发条件 用户侧行为
ClarificationNeededError 用户提问存在歧义 返回澄清选项供用户选择
PolicyViolationError 触发安全策略 (DML/注入) 拒绝并提示安全原因
SQLValidationError SQL 语法错误/成本超限 提示缩小范围或简化查询
RetrievalMissError 检索引擎未命中任何资产 提示换一种方式提问
ModelUnavailableError LLM API 不可用 提示稍后重试

6.3 错误消息脱敏映射

技术错误自动转换为用户友好的中文消息:

技术错误 用户消息
statement timeout 查询执行超时,请尝试缩小查询范围
syntax error at or near 生成的 SQL 语法有误,系统将尝试修复,请重试
relation .+ does not exist 查询引用了不存在的表,请换一种方式提问
column .+ does not exist 查询引用了不存在的字段,请换一种方式提问
permission denied 没有权限访问该数据,请联系管理员
connection refused 数据库连接失败,请稍后重试
Forbidden keyword detected SQL 包含禁止使用的操作
Estimated rows exceeds limit 查询结果集过大,请添加过滤条件缩小范围
Estimated cost exceeds limit 查询复杂度过高,请简化查询条件
Model .+ unavailable AI 模型服务暂时不可用,请稍后重试
(未匹配的错误) 系统处理出现异常,请稍后重试

7. 维护检查清单 (Maintenance Checklists)

7.1 每日巡检

  • 检查 Backend 健康状态:curl /api/v1/health
  • 检查错误率趋势(日志 level=error 频率)
  • 检查关键 API 响应延迟 (P95 < 5s)
  • 检查 DB 连接池使用率 (in_use / total < 80%)
  • 确认无异常的安全告警(PolicyViolation 突增)

7.2 每周巡检

  • 抽样检查高频查询的 SQL 质量(是否语义正确)
  • 复核 Semantic Plane 新增/修改的规则是否产生副作用
  • 复核模型路由配置(是否需要切换模型版本)
  • 检查 SQL Cache 命中率(正常范围 30%~60%)
  • 审查审计日志中的异常模式(频繁 PolicyViolation 用户)

7.3 每月巡检

  • 盘点敏感字段 PII 暴露策略(新增字段是否漏标)
  • 回顾失败路径分布:clarification / rejected / error 比例
  • 更新 Handbook 中过期的文档内容
  • 检查依赖库安全漏洞 (uv auditbun audit)
  • 验证备份恢复流程可行性
  • 评估是否需要调整 Rate Limit 或 Cost Threshold

8. 备份与恢复 (Backup & Recovery)

8.1 备份策略

数据源 备份方式 RPO RTO
Aurora PostgreSQL 自动快照 (每日) + 连续归档 5 分钟 < 1 小时
Semantic Plane Git 历史 (完整 YAML) 0(每次 commit) < 10 分钟
审计日志 S3 归档 (90 天后) 1 天 < 4 小时
SQL Cache 无(临时数据,可重建) N/A 自动恢复

8.2 Semantic Plane 恢复

Semantic Plane 的所有元数据以 YAML 形式存储在 Git 中, 任何版本都可通过以下步骤完整恢复:

# 1. 切换到目标版本
git checkout <commit-sha> -- semantic-plane/

# 2. 全量发布到 S3(重建 R+V+G)
task dp:publish-sp

# Backend 检测 S3 变更后自动执行全量 R+V+G 导入

8.3 数据库恢复

# 从快照恢复
aws rds restore-db-cluster-from-snapshot \
  --db-cluster-identifier ttd-restored \
  --snapshot-identifier ttd-daily-<date>

# 恢复后重新执行 migrations
cd backend && uv run alembic upgrade head
# 重建本地环境
task dp:down
docker volume rm data-plane_pg_data  # 清除旧数据
task dp:up
task dp:publish-sp
task dp:load-hm

8.4 全量重同步

当数据不一致或需要灾难恢复时:

# 构建全量 changeset(包含所有资产)
task sp:changeset:full

# 发布到 S3 触发全量导入
task dp:publish-sp
# Backend 自动检测 S3 变更并执行 R+V+G pipeline

9. 性能调优 (Performance Tuning)

9.1 关键调优参数

graph TB
    subgraph 检索精度
        A[TTD_TOP_K_TABLES]
        B[TTD_TOP_K_COLUMNS]
        C[TTD_TOP_K_METRICS]
        D[TTD_TOP_K_TERMS]
        E[TTD_TOP_K_FEW_SHOTS]
    end
    subgraph 质量阈值
        F[TTD_SIMILARITY_THRESHOLD]
        G[TTD_SQL_CACHE_SIMILARITY]
    end
    subgraph 执行限制
        H[TTD_STATEMENT_TIMEOUT_MS]
        I[TTD_MAX_ROWS]
        J[TTD_MAX_ESTIMATED_ROWS]
    end

9.2 检索范围参数

参数 默认值 调优建议
TTD_TOP_K_TABLES 5 表较多时增加到 8~10,但会增加 Token 消耗
TTD_TOP_K_COLUMNS 20 宽表场景可增加到 30
TTD_TOP_K_METRICS 5 指标丰富的域可增加
TTD_TOP_K_TERMS 10 同义词/歧义多时增加
TTD_TOP_K_FEW_SHOTS 3 增加可提升 SQL 质量,但增加 latency

9.3 精度/召回权衡

参数 默认值 调高效果 调低效果
TTD_SIMILARITY_THRESHOLD 0.65 精确但可能漏召回 召回高但可能引入噪音
TTD_SQL_CACHE_SIMILARITY 0.92 缓存更精确,命中率低 命中率高,但可能返回不匹配的缓存

9.4 延迟优化

优化手段 效果 配置
SQL Cache 命中时跳过 LLM 调用,延迟 < 200ms TTD_SQL_CACHE_SIMILARITY
Metadata Cache 减少 DB 查询,检索阶段提速 30%+ TTD_METADATA_CACHE_TTL_SECONDS
模型选择 使用更快的模型降低延迟 TTD_*_MODEL 系列参数
Graph Traversal Depth 减少深度加速 Join 推理 TTD_GRAPH_TRAVERSAL_DEPTH
Statement Timeout 防止慢查询阻塞连接池 TTD_STATEMENT_TIMEOUT_MS

9.5 模型选择建议

场景 推荐模型 原因
SQL 生成 qwen3-coder-plus 代码能力强,SQL 准确率高
洞察分析 qwen3-max 推理能力强,文本质量高
Supervisor 路由 deepseek-v3.2 速度快,路由判断准确
Follow-up 生成 deepseek-v3.2 轻量级任务,低延迟

10. 故障排查 (Troubleshooting)

10.1 常见问题速查表

症状 可能原因 排查命令 解决方案
API 返回 401 JWT 过期/无效 检查 Token exp claim 重新获取 Token
API 返回 429 触发 Rate Limit 查看 X-RateLimit-* 响应头 等待窗口重置或联系管理员提限
查询超时 SQL 复杂度过高 task dp:psql + EXPLAIN ANALYZE 优化查询或提升 timeout
"查询引用了不存在的表" 元数据未导入 SELECT * FROM semlayer.table_asset 执行 task dp:publish-sp
"AI 模型服务暂时不可用" DashScope API 异常 检查 API Key + 网络 验证 TTD_DASHSCOPE_API_KEY
Backend 启动崩溃 DB 连接失败 task dp:ps 查看容器状态 重启 Data Plane: task dp:down && task dp:up
检索不到相关资产 Embedding 缺失 查询 semlayer.embedding 执行 task dp:publish-sp(Backend 自动生成 Embedding)
Cache 命中率异常低 相似度阈值过高 查看 Prometheus sql_cache_* 调低 TTD_SQL_CACHE_SIMILARITY
前端无法连接后端 CORS 或端口问题 curl localhost:8000/api/v1/health 检查 TTD_CORS_ORIGINS 配置
pg_mooncake 查询报错 表未加载 task dp:psql:mooncake 查表 执行 task dp:load-hm

10.2 排查工具命令

# 后端测试(快速验证代码正确性)
task be:test

# 代码静态检查(发现潜在问题)
task be:lint
task be:typecheck

# 元数据校验(检查 YAML 一致性)
task sp:validate

# 数据面日志(查看容器运行状态)
task dp:logs

# 数据库连接测试
task dp:psql       # Aurora 替代
task dp:psql:mooncake  # pg_mooncake

# 健康检查
curl -s http://localhost:8000/api/v1/health | python -m json.tool

10.3 日志分析技巧

# 查看最近的错误日志
docker logs ttd-backend 2>&1 | grep '"level":"error"' | tail -20

# 按 trace_id 追踪完整请求链路
docker logs ttd-backend 2>&1 | grep "trace_id.*abc-123-def"

# 统计各 Agent 的调用延迟
docker logs ttd-backend 2>&1 | grep "latency_ms" | \
  python -c "import sys,json; [print(json.loads(l).get('agent','?'), json.loads(l).get('latency_ms',0)) for l in sys.stdin]"

10.4 紧急恢复步骤

生产环境紧急恢复

场景:元数据损坏导致全部查询失败

# 1. 确认问题
curl http://localhost:8000/api/v1/health

# 2. 从 Git 恢复到已知良好版本
git checkout <last-known-good-commit> -- semantic-plane/

# 3. 全量重建
task dp:publish-sp
# Backend 自动检测 S3 变更并执行全量 R+V+G 导入

# 4. 验证恢复
curl http://localhost:8000/api/v1/health
# 通过 Web 界面测试关键查询

场景:数据库连接池耗尽

# 1. 检查连接池状态
curl -s http://localhost:8000/api/v1/health | jq '.db_pool'

# 2. 重启应用服务(释放连接)
task down && task up

# 3. 如果问题持续,检查是否有慢查询占用连接
task dp:psql
SELECT * FROM pg_stat_activity WHERE state = 'active';

11. 环境变量完整参考

所有 TTD_ 配置变量
变量 默认值 说明
TTD_HOST 0.0.0.0 服务监听地址
TTD_PORT 8000 服务监听端口
TTD_WORKERS 4 Worker 进程数
TTD_DEBUG true 调试模式(生产必须为 false)
TTD_AURORA_DSN postgresql://... PostgreSQL 连接串
TTD_PG_POOL_MIN 2 连接池最小连接数
TTD_PG_POOL_MAX 10 连接池最大连接数
TTD_DATA_PLANE_BACKEND redshift 数据面后端 (redshift/pg_mooncake)
TTD_PG_MOONCAKE_DSN postgresql://... pg_mooncake 连接串
TTD_DASHSCOPE_API_KEY - DashScope API Key
TTD_ANTHROPIC_API_KEY - Anthropic API Key
TTD_SUPERVISOR_MODEL deepseek-v3.2 Supervisor 模型
TTD_SQL_GENERATION_MODEL qwen3-coder-plus SQL 生成模型
TTD_INSIGHTS_MODEL qwen3-max 洞察分析模型
TTD_VISUALIZATION_MODEL qwen3-max 可视化模型
TTD_FOLLOWUP_MODEL deepseek-v3.2 Follow-up 模型
TTD_JWT_SECRET change-me... JWT 签名密钥(迁移期 HS256 回退用,将移除)
TTD_JWT_ALGORITHM HS256 JWT 算法(迁移期回退用,将移除)
TTD_JWT_AUDIENCE talk-to-data JWT 受众校验值
TTD_BETTER_AUTH_URL http://localhost:3000 Better Auth 基础 URL (JWKS 端点来源)
TTD_BETTER_AUTH_ISSUER http://localhost:3000 JWT issuer 校验值
TTD_JWKS_CACHE_TTL_SECONDS 3600 JWKS 公钥缓存时间
TTD_RATE_LIMIT_PER_USER 60 每用户每分钟请求限制
TTD_BURST_LIMIT 100 突发请求上限
TTD_MAX_QUESTION_LENGTH 2000 最大问题长度 (字符)
TTD_SESSION_TTL_HOURS 24 会话 TTL
TTD_SESSION_MAX_TURNS 20 最大对话轮次
TTD_TOP_K_TABLES 5 检索表数量
TTD_TOP_K_COLUMNS 20 检索列数量
TTD_TOP_K_METRICS 5 检索指标数量
TTD_TOP_K_TERMS 10 检索术语数量
TTD_TOP_K_FEW_SHOTS 3 检索 Few-shot 数量
TTD_SIMILARITY_THRESHOLD 0.65 检索相似度阈值
TTD_GRAPH_TRAVERSAL_DEPTH 3 Graph 遍历深度
TTD_STATEMENT_TIMEOUT_MS 30000 SQL 超时 (ms)
TTD_MAX_ROWS 1000 最大返回行数
TTD_SQL_CACHE_SIMILARITY 0.92 SQL Cache 相似度
TTD_SQL_CACHE_TTL_MINUTES 15 SQL Cache TTL
TTD_METADATA_CACHE_TTL_SECONDS 86400 元数据缓存 TTL
TTD_MAX_REPAIR_RETRIES 1 SQL 修复最大重试
TTD_CIRCUIT_BREAKER_THRESHOLD 3 熔断连续失败阈值
TTD_MAX_ESTIMATED_ROWS 10000000 EXPLAIN 行数上限
TTD_MAX_ESTIMATED_COST 100000 EXPLAIN 成本上限
TTD_PROMETHEUS_ENABLED true 是否启用 Prometheus
TTD_METRICS_PATH /metrics Metrics 端点路径