企业数据助手开发文档

Enterprise Data Assistant — 说人话,查数据

一、项目概述

项目名称

企业数据助手

项目定位

一款面向企业管理者的数据查询助手。通过手机微信样式对话窗口,以自然语言("说人话")的方式,直接查询企业ERP数据库中的业务数据。无需登录后台、无需写SQL、无需找IT人员协助,管理者拿起手机就能获取经营数据。

核心组成:手机微信样式对话窗 + n8n工作流引擎 + SQL Server数据库直连 + AI理解层。

部署位置

部署服务器:小广(腾讯云,公网IP 114.132.93.176,WireGuard内网 10.0.0.20)

访问地址

整体架构

手机对话窗(微信样式网页)
↓ 人话请求
AI理解层(深度求索 · 转SQL)
↓ SQL语句
n8n引擎(调度中枢 · 安全校验)
↓ SQL查询
SQL Server数据库
↑ 数据结果
结果格式化返回手机

二、系统架构

系统采用四层架构,自上而下分别为对话窗层、AI理解层、调度中枢层、数据层。

2.1 对话窗层

2.2 AI理解层

2.3 调度中枢

2.4 数据层

三、核心业务表

以下为AI可查询的业务表白名单。AI的system prompt中仅包含这些表的结构信息,确保查询范围限定在白名单内。

表名 含义 关键列
RS_CustomerInfo 客户信息表 Code(客户编码), Name(客户名称), Phone(联系电话)
Rent_ZLContract 租赁合同表 Code(合同号), CustomerId(客户ID), RentMoney(租金), DepositMoney(押金), State(状态)
FM_ReceivableFee 应收费用表 ReceiveAmount(应收金额), ReceivedAmount(已收金额), State(状态), BeginDate(开始日期), EndDate(结束日期), CustomerId(客户ID)
FM_ReceiptBill 收款单表 Code(单据号), Date(收款日期), ReceivedMoney(实收金额), ReceivableMoney(应收金额)
WM_WarehouseProduct 库存表 ProductId(商品ID), Num(数量), UnitPrice(单价)
WM_ProductInfo 商品信息表 Id(商品ID), Code(编码), Name(品名)
说明:库存查询库存数据时,需通过 WM_WarehouseProduct 与 WM_ProductInfo 通过 ProductId 关联,获取商品名称。

四、AI理解层设计

4.1 工作流节点链

对话查询工作流共10个节点,完整链路如下:

  1. 对话入口(Webhook节点):接收前端POST请求,参数含sessionId和用户消息
  2. 构造AI请求(Code节点):读取会话记忆文件,拼接system prompt和历史消息
  3. 是否需要AI(IF节点):判断是否命中快捷按钮等无需AI的场景
  4. 调用深度求索AI(Code节点):使用内置https模块直调api.deepseek.com,90秒超时,异常容错
  5. 解析+安全检查(Code节点):解析AI返回内容,执行三层安全检查
  6. 判断是否查询(IF节点):判断是SQL查询还是分析类回复
  7. 执行SQL查询(MSSQL节点):执行SELECT语句查询数据库
  8. 非查询结果处理(Code节点):分析类回复直接格式化输出
  9. 格式化+写记忆(Code节点):结果格式化,写入会话记忆文件
  10. 返回结果(Webhook响应节点):JSON格式返回前端

4.2 System Prompt 规则

AI系统提示词包含以下核心规则:

4.3 会话记忆

4.4 安全检查(三层防护)

AI返回的SQL在执行前,必须经过三层安全检查:

  1. 开头校验:必须以SELECT开头(去除前后空白后)
  2. 多语句检测:检测分号、GO等多语句分隔符,禁止多语句执行
  3. 危险关键字黑名单:单词边界匹配检测 DELETE、UPDATE、DROP、ALTER、EXEC、INSERT、TRUNCATE、CREATE 等危险关键字
安全原则:任何一层检查不通过,直接返回"臣不能执行写操作",绝不放行SQL执行。

五、部署过程

以下为项目从0到1的完整部署实战记录。

5.1 数据库部署

  1. 解压 lyz.7z 备份压缩包(密码保护)
  2. Docker 启动 SQL Server 2022 容器
  3. 将备份文件拷贝至容器内
  4. 通过 SQLCMD或SSMS方式还原 13GB 备份文件
  5. 验证:还原完成后共 2586 张业务表

5.2 n8n 部署

  1. Docker 部署 n8n 最新版
  2. 首次启动完成 owner 账号注册
  3. 生成 API Key 用于后续API调用
  4. 创建数据查询工作流(10节点)
  5. 配置 MSSQL 数据库凭据(lyz-mssql)
  6. 配置 Webhook 节点并激活工作流

5.3 对话窗页面部署

  1. 编写单文件 HTML 对话页面(微信气泡样式)
  2. 部署至 box 站点 nginx 目录
  3. 配置 nginx 反向代理 n8n webhook
  4. 配置 proxy_read_timeout 120秒

5.4 AI接入

  1. 初期方案:火山方舟(字节跳动)模型接入测试
  2. 最终方案:切换为官方深度求索接口(api.deepseek.com)
  3. 切换原因:官方深度求索稳定性更好、响应速度更快、SQL生成质量更高
  4. 调用方式:n8n Code节点内置https模块直调(绕过凭据问题

六、踩坑记录

以下为部署过程中遇到的典型问题及解决方案,供后续维护参考。

6.1 SQL Server 镜像拉取

问题:mcr.microsoft.com 微软镜像国内无法直接拉取。

解决:在 Mac 上安装 skopeo,通过小家 SOCKS5 代理下载镜像为 tar 文件,传输到小广后 docker load 导入。

6.2 n8n 凭据引用格式

问题:新版 n8n 中通过 API 创建工作流时,凭据引用写字符串 ID 会报 "Credential not configured"。

解决:凭据必须使用对象格式 {"microsoftSql":{"id":"xxx","name":"xxx"}}。

6.3 MSSQL 凭据字段名

问题:MSSQL 凭据的 TLS 配置字段是 tls 不是 ssl,字段名写错会导致连接失败。

6.4 n8n REST API 激活工作流

问题:PATCH 修改 active 字段不生效,工作流无法通过 API 激活。

解决:必须使用 POST /rest/workflows/{id}/activate 接口,并带上 versionId 参数。

6.5 nginx 容器配置更新

问题:在容器内 sed -i 修改配置文件后不生效(inode 变化容器不认。

解决:修改配置后必须 docker restart xiaoguang-nginx 重启容器。

6.6 n8n 容器重建

问题:n8n 容器重建后配置丢失。

解决:容器重建三连:数据卷保留映射、重新 docker network connect 接入网络、重新登录账号。

6.7 n8n 容器内调外部 API

问题:HTTP Request 节点无凭据时报 "Credentials not found"。

解决:使用 Code 节点内置 https 模块直调 API,配置环境变量 NODE_FUNCTION_ALLOW_BUILTIN=fs,path,https。

6.8 JSON Body 表达式转义

问题:shell 中传递 jsonBody 经 shell 转义后引号丢失,导致 JSON 格式错误。

解决:使用 Python heredoc 方式写入 JSON,避免 shell 转义问题。

6.9 nginx 超时配置

问题:AI 生成 SQL 较慢时,nginx 默认 60s 超时返回 504。

解决:nginx 配置 proxy_read_timeout 改为 120s。

6.10 AI 节点容错

问题:AI 调用失败时 reject,导致 webhook 空响应,前端卡死。

解决:AI 节点失败时 resolve 返回友好提示,绝不 reject,保证 webhook 始终有响应。

6.11 前端渲染兼容

问题:n8n webhook 返回单行数据时返回对象而非数组,前端表格渲染报错。

解决:前端兼容处理:判断返回是对象时自动转数组。

七、验证方法

上线前检查清单,按顺序逐项验证。

7.1 页面访问

7.2 人话查询(明细类)

发送:我要应收款明细

预期:返回应收费用表明细数据表格,包含客户、金额、日期等字段。

7.3 人话汇总(统计类)

发送:我4月份赚了多少钱

预期:返回 4 月份实收合计金额(约 14,562,751.8 元)。

7.4 连续对话(记忆测试)

第一步发送:我要应收款明细

第二步发送:为什么差距这么大

预期:AI 能理解上下文,给出分析类回复(type: analysis),解释应收与实收的差异原因。

7.5 危险操作拦截

发送:DELETE FROM RS_CustomerInfo

预期:返回"臣不能执行写操作",SQL 不执行。

7.6 健康检查

  • n8n:http://localhost:5678/healthz 返回 ok
  • 数据库容器:docker ps 显示 sqlserver 容器状态为 Up
  • n8n 容器:docker ps 显示 n8n 容器状态为 Up

八、运维信息

以下为内部运维参考信息,敏感信息不公开。

8.1 服务地址

  • n8n 工作台:http://114.132.93.176:5678
  • 管理员账号:admin(密码见记忆中心 / 管理员保管)

8.2 Docker 容器

容器名用途说明
sqlserverSQL Server 数据库SA 账号,LYz 库
n8nn8n 工作流引擎端口 5678
xiaoguang-nginxNginx 反向代理站点入口

8.3 数据目录

  • 会话记忆目录:/tmp/n8n_memory/
  • 站点根目录:/var/www/box/n8n-chat/

8.4 n8n 凭据

  • 凭据名称:lyz-mssql
  • 数据库服务器:172.17.0.3(Docker 内网)
  • TLS:关闭
  • 数据库:LYz

8.5 常用运维命令

# 查看容器状态
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 查看 n8n 日志
docker logs n8n --tail 50

# 重启 nginx
docker restart xiaoguang-nginx

# 查看会话记忆
ls /tmp/n8n_memory/

# n8n 健康检查
curl -s http://localhost:5678/healthz
注意:所有密码、密钥等敏感信息均存储于记忆中心,本文档不包含任何明文密码。