Files
Neo-ZQYY/docs/prd/Neo_Specs/NS3-mcp-server-ai-extension.md

306 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NS3MCP Server 扩展 — mcp-server-ai-extension
> 优先级:中(可与 NS1/NS2 并行,批次 A 无前置依赖)
> 预估工作量:中等
> 前置条件:批次 A 无依赖;批次 B 依赖 P5-Abiz 表已建);批次 C 依赖批次 B
> 参考基准:`docs/prd/specs/P5.1-mcp-server-ai-extension.md`
---
## 一、背景与目标
当前 MCP Server`apps/mcp-server/server.py`)仅连接 `etl_feiqiu` 数据仓库,提供 4 个工具list_tables、describe_table、describe_schemas、query_sqlschema 白名单为 ods/dwd/dws/core/meta/app。SQL 安全通过正则禁词检测实现只读保护。
查库手册(`docs/mcp/AI-DATABASE-QUERY-MANUAL.md`内容陈旧DWS 层 34 张表缺少完整字段说明业务库zqyy_app完全未覆盖。
本 SPEC 目标:
1. MCP Server 新增 `zqyy_app` 业务库连接,支持多数据库路由
2. 实现业务库敏感字段脱敏策略
3. 重写查库手册ETL 全字段 + 业务库全字段 + 常用查询模式)
4. 手册上传百炼平台验证 AI 引用效果
### 当前 MCP Server 能力
| 工具 | 功能 | 限制 |
|------|------|------|
| `list_tables` | 列出指定 schema 下的表 | 仅 etl_feiqiu |
| `describe_table` | 查看表结构(列名、类型、注释) | 仅 etl_feiqiu |
| `describe_schemas` | 列出可用 schema 及表数量 | 仅 ods/dwd/dws/core/meta/app |
| `query_sql` | 执行只读 SQL 查询 | 正则禁词检测,单 schema 限制 |
---
## 二、技术架构
### 2.1 多数据库连接
```
apps/mcp-server/
├── server.py 🔧 扩展:多连接池 + schema 路由
├── db_pool.py 🆕 新建连接池管理etl_feiqiu + zqyy_app
├── security.py 🆕 新建:敏感字段脱敏策略
└── config.py 🆕 新建数据库配置DSN、schema 白名单)
```
### 2.2 连接池设计
```python
# db_pool.py
class DatabasePool:
"""管理两个数据库的连接池。"""
pools = {
"etl": {
"dsn_env": "PG_DSN", # etl_feiqiu / test_etl_feiqiu
"schemas": ["ods", "dwd", "dws", "core", "meta", "app"],
"readonly": True,
},
"biz": {
"dsn_env": "APP_DB_DSN", # zqyy_app / test_zqyy_app
"schemas": ["auth", "biz", "public"],
"readonly": True, # MCP 只读,写操作走后端 API
},
}
```
### 2.3 Schema 自动路由
工具参数中不再需要显式指定 `database`,而是根据 schema 名称自动路由:
| Schema | 路由目标 | 说明 |
|--------|---------|------|
| `ods` / `dwd` / `dws` / `core` / `meta` / `app` | etl_feiqiu | ETL 数据仓库 |
| `auth` / `biz` / `public` | zqyy_app | 业务库 |
路由逻辑:
```python
def resolve_database(schema: str) -> str:
ETL_SCHEMAS = {"ods", "dwd", "dws", "core", "meta", "app"}
BIZ_SCHEMAS = {"auth", "biz", "public"}
if schema in ETL_SCHEMAS:
return "etl"
elif schema in BIZ_SCHEMAS:
return "biz"
else:
raise ValueError(f"未知 schema: {schema}")
```
### 2.4 工具扩展
4 个现有工具的参数不变,内部根据 schema 参数自动选择连接池:
| 工具 | 变更 |
|------|------|
| `list_tables(schema)` | schema 参数扩展接受 auth/biz/public |
| `describe_table(table, schema)` | 同上 |
| `describe_schemas()` | 返回结果增加 auth/biz/public 三个 schema |
| `query_sql(schema, sql)` | 根据 schema 路由到对应连接池 |
### 2.5 跨库查询限制
- 单次 `query_sql` 调用只能查询单个数据库(由 schema 参数决定)
- 禁止在 SQL 中引用其他数据库的 schema现有 `_reject_cross_schema` 逻辑扩展)
- 如需跨库关联AI 应分两次查询后在应用层组合
---
## 三、敏感字段脱敏策略
### 3.1 脱敏规则
| Schema | 表 | 敏感字段 | 脱敏方式 |
|--------|-----|---------|---------|
| `auth` | `users` | `wx_openid` | 前 4 后 4 保留,中间 `***` |
| `auth` | `users` | `phone` | 前 3 后 4 保留,中间 `****` |
| `auth` | `users` | `wx_session_key` | 完全隐藏,返回 `[REDACTED]` |
| `biz` | `ai_messages` | `content`role=user | 不脱敏AI 需要理解对话内容) |
| `biz` | `ai_conversations` | — | 无敏感字段 |
| `public` | `member_retention_clue` | `recorded_by_assistant_id` | 不脱敏(非 PII |
### 3.2 实现方式
`query_sql` 返回结果时,对命中脱敏规则的列进行后处理:
```python
# security.py
MASKING_RULES = {
"auth.users": {
"wx_openid": lambda v: f"{v[:4]}***{v[-4:]}" if v and len(v) > 8 else "[REDACTED]",
"phone": lambda v: f"{v[:3]}****{v[-4:]}" if v and len(v) >= 11 else "[REDACTED]",
"wx_session_key": lambda v: "[REDACTED]",
},
}
def mask_row(schema: str, table: str, columns: list[str], row: tuple) -> tuple:
"""对查询结果行应用脱敏规则。"""
```
### 3.3 脱敏绕过防护
- `SELECT *` 查询 auth.users 时自动应用脱敏
- 禁止通过 `CAST``CONCAT`、子查询等方式绕过脱敏(在 SQL 解析阶段检测)
- 对 auth.users 的查询结果始终应用列级脱敏,无论 SQL 写法
---
## 四、查库手册重写
### 4.1 手册结构
重写后的手册分为两个文件,便于维护和上传:
```
docs/mcp/
├── AI-DATABASE-QUERY-MANUAL.md 🔧 重写(总览 + ETL 库)
└── AI-DATABASE-QUERY-MANUAL-BIZ.md 🆕 新建(业务库)
```
### 4.2 ETL 库手册内容(重写)
保留现有架构流程和工具说明,重点补充:
1. **DWS 层完整表清单**34 张表按业务域分组)
- 每张表列出全部字段(字段名、类型、中文说明)
- 标注关键字段的业务含义和使用注意事项
- 按业务域分组:会员域、助教域、财务域、配置域
2. **金额口径专章**
- `consume_money` 三种历史口径说明A/B/C明确标注"禁止直接使用"
- `items_sum` 定义和计算公式
- settle_type 枚举映射表1=台桌结账 78.6%、3=商城订单 21.4%、5=充值、7=充值退款、6=结算退款)
- 助教费用拆分规则assistant_pd_money 陪打 / assistant_cx_money 超休)
- 支付渠道恒等式balance_amount = recharge_card_amount + gift_card_amount
3. **会员字段断档说明**
- DQ-6member_phone/member_name 自 2025-12 起 NULL需 JOIN dim_member
- DQ-7member_card_type_name 自 2025-07-21 起 NULL需 JOIN dim_member_card_account
4. **常用查询模式**ETL 侧)
- 客户消费汇总查询
- 助教绩效查询
- 财务日报查询
- 指数排名查询
5. **数据量统计与性能建议**
- 各表的大致数据量级
- 推荐的 WHERE 条件时间范围、site_id
- 避免全表扫描的建议
### 4.3 业务库手册内容(新建)
1. **Schema 概览**
- `auth`用户认证users、user_applications、site_code_mapping、user_assistant_binding
- `biz`业务数据coach_tasks、notes、ai_conversations、ai_messages、ai_cache、trigger_jobs、salary_adjustments、excel_upload_log
- `public`共享数据member_retention_clue
2. **每张表完整字段说明**
- 字段名、类型、是否可空、默认值、中文说明
- 关键枚举值说明(如 coach_tasks.task_type、notes.type、ai_cache.cache_type
- 外键关系和关联查询建议
3. **常用查询模式**(业务侧)
- 维客线索查询(按客户、按来源、按标签)
- 任务系统查询(按助教、按状态、按类型)
- 备注查询(按客户、按助教、含星星评分)
- AI 缓存查询(按应用类型、按 target_id
- Excel 上传记录查询
4. **跨库关联指南**
- 业务库 member_id → ETL 库 dim_member 的关联方式
- 业务库 assistant_id → ETL 库 dim_assistant 的关联方式
- 注意MCP 不支持单次跨库 JOIN需分两次查询
### 4.4 数据字段权威参考
手册中涉及的 DWD/DWS 层字段来源、金额口径、业务逻辑,以 `docs/reports/DWD-DOC/` 校准文档为准(数据快照 2026-03-06
---
## 五、百炼平台上传与验证
### 5.1 上传方式
- 将重写后的手册作为知识库文档上传至百炼平台
- 关联到应用 1通用对话使 AI 在回答数据查询问题时可引用手册
### 5.2 验证场景
| 测试场景 | 预期行为 |
|---------|---------|
| "查询本月营业额" | AI 引用手册中的 dws_finance_daily_summary 表,使用 items_sum 口径 |
| "查看客户王先生的消费记录" | AI 引用 dim_member + dwd_settlement_head通过 member_id 关联 |
| "助教张三的本月绩效" | AI 引用 dws_assistant_salary_calc正确使用 assistant_pd_money 拆分 |
| "查看维客线索" | AI 引用业务库 member_retention_clue 表 |
| "查看用户申请列表" | AI 引用 auth.user_applications对 phone 字段脱敏 |
### 5.3 验证标准
- AI 不再频繁调用 `describe_table`(手册已提供完整字段信息)
- AI 生成的 SQL 使用正确的金额口径items_sum 而非 consume_money
- AI 查询 auth.users 时返回结果中敏感字段已脱敏
- AI 能正确区分 ETL 库和业务库的查询路由
---
## 六、参考文档
| 文档 | 路径 | 用途 |
|------|------|------|
| P5.1 原始 spec | `docs/prd/specs/P5.1-mcp-server-ai-extension.md` | 需求定义基准 |
| 现有 MCP Server | `apps/mcp-server/server.py` | 当前实现参考 |
| 现有查库手册 | `docs/mcp/AI-DATABASE-QUERY-MANUAL.md` | 重写基础 |
| DWD-DOC 标杆 | `docs/reports/DWD-DOC/` | 字段语义、金额口径权威参考 |
| BD 手册-业务表 | `docs/database/BD_Manual_biz_tables.md` | biz schema 表结构 |
| BD 手册-认证表 | `docs/database/BD_Manual_auth_tables.md` | auth schema 表结构 |
| ETL BD 手册 | `apps/etl/connectors/feiqiu/docs/database/` | DWD/DWS 表结构 |
---
## 七、预审查清单SPEC 启动前确认)
### 7.1 多数据库连接
1. **连接池大小**zqyy_app 连接池的 min/max 连接数?与 etl_feiqiu 共享还是独立MCP Server 的并发查询量预估?
2. **DSN 环境变量**MCP Server 运行环境中 `APP_DB_DSN` 是否已配置?测试环境使用 `test_zqyy_app` 还是 `zqyy_app`
3. **RLS 隔离**MCP 查询 zqyy_app 时是否需要 `SET LOCAL app.current_site_id`如果需要site_id 从哪里获取MCP 调用方传入?固定值?)?
4. **连接超时**FDW 查询和业务库查询的超时时间是否需要不同设置?
### 7.2 安全与脱敏
5. **脱敏范围确认**:除 auth.users 外,还有哪些表/字段需要脱敏biz.notes 的备注内容是否需要脱敏?
6. **脱敏粒度**:是否需要根据 MCP 调用方身份区分脱敏级别如管理员可看完整数据AI 应用只看脱敏数据)
7. **SQL 注入防护**:现有正则禁词检测是否足够?是否需要升级为 SQL 解析器(如 sqlparse
8. **审计日志**MCP 查询是否需要记录审计日志(谁查了什么表、什么时间)?
### 7.3 查库手册
9. **手册格式**百炼平台对知识库文档的格式要求Markdown 是否直接支持?是否需要转换为 PDF/TXT
10. **手册拆分**ETL 库和业务库是否拆分为两个知识库文档?还是合并为一个?
11. **手册更新机制**:表结构变更后,手册如何同步更新?是否需要自动化脚本从数据库 DDL 生成手册?
12. **DWD 层覆盖**:手册是否需要覆盖 DWD 层全部表的完整字段?还是只覆盖 DWS + 常用 DWD 表?
### 7.4 部署与运维
13. **MCP Server 重启**新增连接池后MCP Server 是否需要重启?是否支持热加载配置?
14. **监控指标**:是否需要监控 MCP 查询的响应时间、错误率、查询频次?
15. **降级策略**zqyy_app 连接失败时,是否影响 etl_feiqiu 的查询?两个连接池是否需要独立故障隔离?
---
## 八、任务清单草案SPEC 细化后调整)
### 批次 A查库手册 — ETL 库(无前置依赖)
- [ ] T1重写 `AI-DATABASE-QUERY-MANUAL.md` — DWS 层 34 张表全字段说明(按业务域分组)
- [ ] T2补充金额口径专章consume_money 禁用说明 + items_sum 定义 + settle_type 映射)
- [ ] T3补充会员字段断档说明DQ-6/DQ-7+ 常用 ETL 查询模式
### 批次 BMCP Server 扩展 + 业务库手册(依赖 P5-A
- [ ] T4创建 `db_pool.py` — 双连接池管理etl_feiqiu + zqyy_app
- [ ] T5扩展 `server.py` — 4 个工具支持 schema 自动路由
- [ ] T6创建 `security.py` — 敏感字段脱敏策略实现
- [ ] T7创建 `AI-DATABASE-QUERY-MANUAL-BIZ.md` — 业务库全字段说明 + 常用查询模式
### 批次 C百炼平台验证
- [ ] T8手册上传百炼平台并关联 AI 应用
- [ ] T9执行验证场景测试5 个场景),确认 AI 引用效果