全部项目

ChatBI

P002Conversational intelligence

用自然语言探索股票数据,把查询、分析与可视化连接在一次对话里。

查看源码
ChatBI 股票查询助手主界面

项目概述

ChatBI 股票查询助手是一个 AI-Native 对话式商业智能(ChatBI)股票分析系统。用户可以通过自然语言对话的方式查询 A 股行情数据,系统利用大语言模型(LLM)自动完成意图识别、SQL 生成、数据查询、图表渲染和 ARIMA 趋势预测等全流程操作。同时配备了一套完整的管理后台,支持用户管理、操作审计、会话管理、AI 模型配置和 Prompt 模板管理。

核心能力:

  • 自然语言查询:用户输入自然语言问题(如"贵州茅台最近 30 天涨跌幅"),系统自动转换为 SQL 查询并返回结果
  • 智能数据分析:LLM 对查询结果进行趋势分析、对比分析、极值查询、统计分析等多维度专业解读
  • ARIMA 趋势预测:基于时间序列模型预测股票未来走势,附带 95% 置信区间
  • 数据可视化:自动渲染折线图、柱状图和预测图表
  • 向量语义检索:通过 Chroma 向量数据库实现 Schema 和 SQL 示例的语义相似度检索,提升 SQL 生成准确率
  • 查询缓存:基于问题文本哈希的查询结果缓存机制,避免重复计算
  • 多轮上下文对话:支持带上下文的连续对话,最多保留 10 轮历史
  • 管理后台:用户管理、会话管理、操作审计、查询审计、登录日志、AI 模型配置、Prompt 模板管理

数据范围:当前覆盖贵州茅台(600519.SH)、五粮液(000858.SZ)、中芯国际(688981.SH)、广发证券(000776.SZ)四支股票的日线行情数据。

技术选型

后端

技术 版本 用途
Python 3.12+ 主要编程语言
FastAPI 0.110+ Web 框架,提供 REST API + SSE 流式接口
Pydantic Settings 2.0+ 配置管理(.env 环境变量)
SQLite - 本地数据存储(股票数据 + 业务表 + 向量库)
JWT + bcrypt - 认证鉴权与密码加密
OpenAI SDK 1.0+ LLM 调用客户端(兼容 DashScope 接口)
LangChain 0.2+ LLM 缓存、Chroma 向量检索
LangGraph 0.2+ 工作流编排(PipelineState 状态图)
ChromaDB 0.5+ 向量数据库(Schema 字段 + SQL 示例的 Embedding 存储)
pandas 2.0+ 数据处理与 Excel 导出
matplotlib 3.8+ 图表渲染(折线图/柱状图/ARIMA 预测图)
statsmodels 0.14+ ARIMA 时间序列预测
Tushare 1.4+ A 股日线行情数据源

前端

技术 版本 用途
React 19 前端框架
TypeScript 6.0 类型安全
Vite 8.0 构建工具与开发服务器
Ant Design 6.3 UI 组件库
Zustand 5.0 轻量级状态管理
Axios 1.15 HTTP 请求
React Router 7 前端路由
ECharts 6.0 前端图表渲染
react-markdown 10.1 Markdown 内容渲染
highlight.js + KaTeX - 代码高亮与数学公式渲染
streamdown 2.5 流式 Markdown 渲染

外部服务

服务 用途
DashScope(阿里云灵积) LLM 调用(deepseek-v4-pro 模型)+ Embedding(text-embedding-v3)
Tushare A 股日线行情数据获取

实现过程

1. 系统架构

┌─────────────────────────────────────────────────────┐
│                    前端 (React)                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
│  │  聊天页面  │  │ 管理后台  │  │  Zustand 状态管理 │  │
│  └─────┬─────┘  └────┬─────┘  └──────────────────┘  │
│        │              │                              │
│        │  SSE 流式    │  REST API                   │
└────────┼──────────────┼─────────────────────────────┘
         │              │
         v              v
┌─────────────────────────────────────────────────────┐
│                  后端 (FastAPI)                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
│  │ 认证路由  │  │ 管理路由  │  │ 聊天路由/SSE 路由 │  │
│  └────┬─────┘  └────┬─────┘  └────────┬─────────┘  │
│       │              │                 │             │
│  ┌────┴─────┐  ┌─────┴──────┐  ┌──────┴──────────┐ │
│  │ 认证服务  │  │ 管理服务    │  │  聊天编排服务     │ │
│  │         │  │ (886行)    │  │  (1277行)        │ │
│  └─────────┘  └────────────┘  └──────┬──────────┘ │
│                                       │              │
│                          ┌────────────┼────────────┐ │
│                          v            v            v │
│                    ┌──────────┐ ┌────────┐ ┌──────────┐
│                    │语义层    │ │SQL引擎 │ │ARIMA预测 │
│                    │(749行)   │ │        │ │          │
│                    └──────────┘ └────────┘ └──────────┘
└─────────────────────────────────────────────────────┘
         │              │                 │
         v              v                 v
┌─────────────────────────────────────────────────────┐
│                    数据层                             │
│  ┌────────────┐  ┌────────────┐  ┌───────────────┐ │
│  │stock_prices│  │schema_     │  │ Chroma        │ │
│  │.db (行情)  │  │vector.db   │  │ 向量数据库     │ │
│  │            │  │(语义元数据) │  │ (Embedding)   │ │
│  └────────────┘  └────────────┘  └───────────────┘ │
└─────────────────────────────────────────────────────┘

2. 自然语言查询流程

这是系统的核心业务流程,从用户输入自然语言到返回分析结果,经历以下阶段:

用户输入自然语言问题
        │
        v
┌───────────────────┐
│  ① 意图归一化      │  整合会话上下文,判断问题类型
│                   │  - forecast: 预测请求
│                   │  - query: 数据查询
│                   │  - chat: 闲聊
└───────┬───────────┘
        │
        ├── forecast ──> [ARIMA 预测流程] ──> 图表 + 文字总结
        ├── chat ──────> [LLM 闲聊回复]
        │
        └── query ────> 数据查询主流程
                        │
                        v
              ┌───────────────────┐
              │ ② 语义层扩展       │  同义词映射(如"茅台"→"贵州茅台")
              │                    │  "收盘价"→"close"、"涨跌幅"→"pct_chg"
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ③ 向量语义检索     │  检索相关 Schema 字段和 SQL 示例
              │                    │  - Chroma 向量数据库 (LangChain 集成)
              │                    │  - SQLite 内建向量 (余弦相似度计算)
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ④ 查询缓存检查     │  SHA256(问题文本) 作为缓存键
              │                    │  命中 → 直接返回历史结果
              │                    │  未命中 → 继续流程
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ⑤ LLM 生成 SQL    │  Prompt 包含:
              │                    │  - 表 DDL(CREATE TABLE 语句)
              │                    │  - 股票代码映射表
              │                    │  - 语义层扩展后的用户问题
              │                    │  - 向量检索到的相关 Schema 字段
              │                    │  - 向量检索到的相似 SQL 示例
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ⑥ SQL 安全校验    │  禁止 INSERT/UPDATE/DELETE/DROP
              │                    │  限制返回行数 (MAX_RESULT_ROWS)
              │                    │  查询超时控制 (QUERY_TIMEOUT_SECONDS)
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ⑦ SQL 执行        │  SQLite 引擎执行
              │  (失败则LLM纠错)   │  失败 → LLM 纠错重试(最多3次)
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ⑧ 图表渲染        │  matplotlib 生成 PNG 图表
              │                    │  自动选择折线图或柱状图
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ⑨ LLM 数据分析    │  5 种分析模式:
              │                    │  - trend: 趋势分析
              │                    │  - compare: 对比分析
              │                    │  - extreme: 极值查询
              │                    │  - statistics: 统计分析
              │                    │  - evaluate: 综合评价
              └───────┬───────────┘
                      │
                      v
              ┌───────────────────┐
              │ ⑩ 结果缓存 + 返回  │  缓存结果 (TTL 默认 600 秒)
              │                    │  通过 SSE 流式输出或同步返回
              └───────────────────┘

2.1 语义层设计

语义层是整个系统 SQL 生成准确率的核心保障,位于 semantic_layer.py(约 749 行),包含以下模块:

  • Schema 元数据表(schema_metadata):存储 12 个字段的详细业务语义描述,包括字段名、类型、业务含义、是否为关键字段等
  • 语义同义词表(semantic_layer):存储股票名称、指标、维度的同义词映射。例如用户说"茅台",系统会自动扩展为"贵州茅台";用户说"涨跌幅",系统映射到数据库字段 pct_chg
  • SQL 示例库(sql_examples):9 个预置的 question-SQL 配对,包括查询、排序、聚合、分组等典型场景,用于 Few-shot 提示
  • 向量表(schema_vectors):将 Schema 字段语义描述和 SQL 示例通过 Embedding API 转换为向量,存储在 SQLite 和 Chroma 中,支持语义相似度检索

2.2 向量检索方案

系统实现了 双重向量检索 机制:

  1. Chroma 向量数据库(通过 LangChain 集成):在应用启动时自动从 SQLite 种子数据初始化 Chroma 集合,创建 schema_fields 和 sql_examples 两个集合
  2. SQLite 内建向量(自定义余弦相似度):作为 Chroma 不可用时的回退方案,或作为补充检索

2.3 查询缓存

为了提高响应速度并降低 LLM 调用成本,系统实现了查询缓存机制:

  • 缓存键:SHA256(归一化后的问题文本 + SQL)
  • 缓存存储:SQLite 的 query_cache 表
  • 默认 TTL:600 秒(可通过 QUERY_CACHE_TTL 环境变量配置)
  • 缓存命中时直接返回之前的结果、图表和分析总结,无需重新执行全流程

3. ARIMA 趋势预测

系统使用 statsmodels 库实现 ARIMA(5,1,5) 时间序列预测,位于 backend/services/arima_stock.py。

实现步骤:

  1. 数据准备:从 SQLite 提取目标股票的历史收盘价序列(按日期升序排列)
  2. 差分处理:对序列进行一阶差分(d=1),使数据平稳化
  3. 模型拟合:使用 ARIMA(5,1,5) 对历史数据建模(自回归阶数 p=5,差分阶数 d=1,移动平均阶数 q=5)
  4. 未来预测:预测未来 N 个交易日的收盘价,附带 95% 置信区间(上下界)
  5. 图表渲染:使用 matplotlib 生成包含历史数据、预测值、置信区间的可视化图表
  6. 自然语言触发:用户通过自然语言触发预测(如"预测贵州茅台未来 30 天走势"),意图归一化自动识别为 forecast 类型

4. 流式输出(SSE)

系统使用 Server-Sent Events(SSE)实现聊天过程中的实时流式输出,位于 backend/routers/chat_stream.py 和 frontend/src/hooks/useSSE.ts。

SSE 事件类型:

事件类型 说明
intent 意图识别结果(forecast/query/chat)
tokens LLM 生成的 token 流
sql_chunk SQL 语句片段(逐步展示)
data_info 数据查询完成通知(返回行数、耗时)
chart 图表生成完成(返回图片 URL)
analysis_tokens 数据分析 token 流
done 整个流程完成
error 错误信息

前端使用 streamdown 库实现流式 Markdown 渲染,使用 react-markdown + rehype-highlight + rehype-katex 实现代码高亮和数学公式渲染。

5. 管理后台

管理后台提供了完整的运维能力,后端 API 位于 backend/routers/admin.py(16 个接口),业务逻辑位于 backend/services/admin_service.py(约 886 行),前端页面位于 frontend/src/pages/Admin/。

管理功能模块:

模块 功能
面板总览 今日登录数、用户数、活跃用户数、会话数、失败登录数
用户管理 用户 CRUD、角色分配(superadmin/admin/user)、状态管理、密码重置
会话管理 查看/删除/置顶所有用户的聊天会话,查看完整消息历史
操作审计 管理员操作日志(创建用户、修改角色、删除会话等)
查询审计 所有用户的自然语言查询记录,包含 SQL、耗时、缓存命中、图表生成状态,支持导出 Excel
登录日志 所有用户的登录成功/失败记录,含 IP 和 User-Agent
AI 模型配置 动态修改模型名称、Base URL、超时、重试次数、上下文轮数
Prompt 模板管理 动态编辑 SQL 生成规则、分析师系统提示词、Few-shot 示例

6. 前端架构

前端采用 React 19 + TypeScript + Vite 构建,目录结构如下:

frontend/src/
├── components/     # UI 组件
│   ├── ChatMessageBox/   # 聊天消息气泡组件
│   ├── DataTable/        # 数据表格组件
│   ├── Sidebar/          # 侧边栏(会话列表)
│   ├── SqlBlock/         # SQL 代码块展示组件
│   └── ThemeToggle/      # 主题切换组件
├── hooks/          # 自定义 Hook
│   └── useSSE.ts         # SSE 流式消费 Hook
├── layouts/        # 布局组件
│   └── ChatLayout/       # 聊天页面布局
├── pages/          # 页面
│   ├── Chat/             # 聊天页面
│   ├── Admin/            # 管理后台页面
│   └── Login/            # 登录页面
├── services/       # Axios API 封装
│   ├── admin.ts
│   ├── auth.ts
│   ├── chat.ts
│   └── session.ts
├── stores/         # Zustand 状态管理
│   ├── auth.ts           # 认证状态
│   ├── chat.ts           # 聊天状态
│   └── ui.ts             # UI 状态(主题、侧边栏等)
└── types/          # TypeScript 类型定义

状态管理:使用 Zustand 实现轻量级全局状态管理,分为三个 Store:

  • authStore:用户认证信息、登录状态
  • chatStore:当前会话、消息列表、流式状态
  • uiStore:主题模式、侧边栏折叠状态

流式聊天:useSSE Hook 封装了 SSE 连接的生命周期管理,包括连接建立、事件监听、重连机制和连接清理。

7. 安全设计

  • 认证鉴权:JWT Token + bcrypt 密码加密,支持角色权限(superadmin/admin/user)
  • SQL 安全:禁止 INSERT/UPDATE/DELETE/DROP/ALTER/CREATE 等写操作语句,仅允许 SELECT
  • 查询限制:结果行数上限(默认 5000 行)、查询超时(默认 60 秒)
  • SQL 纠错:执行失败时自动调用 LLM 进行纠错重试,最多 3 次,避免因 LLM 生成的不完美 SQL 导致查询失败

8. 配置管理

系统使用 Pydantic Settings 进行配置管理,所有配置项通过 .env 文件或环境变量注入,位于 backend/config.py。

核心配置项:

配置项 默认值 说明
MODEL_NAME deepseek-v4-pro LLM 模型名称
DASHSCOPE_BASE_URL https://dashscope.aliyuncs.com/compatible-mode/v1 LLM API 地址
TUSHARE_TOKEN - Tushare 数据源 Token
MAX_RETRY 3 SQL 纠错最大重试次数
MAX_CONTEXT_ROUNDS 5 上下文最大轮数
QUERY_CACHE_TTL 600 查询缓存过期时间(秒)
MAX_RESULT_ROWS 5000 查询结果最大行数
QUERY_TIMEOUT_SECONDS 60 查询超时时间(秒)

目录结构

ChatBI助手/
├── backend/                          # FastAPI 后端
│   ├── main.py                       # 应用入口,路由注册与初始化
│   ├── config.py                     # 配置中心 (Pydantic Settings)
│   ├── llm.py                        # LLM Embedding 配置
│   ├── memory.py                     # LangChain 记忆模块
│   ├── schemas.py                    # 公共 Pydantic 模型
│   ├── callbacks.py                  # LLM 回调处理
│   ├── vector_store.py               # Chroma 向量存储操作
│   ├── engine/                       # SQL 执行引擎
│   │   ├── base.py                   # 引擎抽象基类
│   │   └── sqlite_engine.py          # SQLite 引擎实现
│   ├── graph/                        # LangGraph 工作流
│   │   ├── nodes.py                  # 工作流节点定义
│   │   └── state.py                  # 状态定义
│   ├── models/                       # API 请求/响应模型
│   │   ├── admin.py
│   │   ├── auth.py
│   │   ├── chat.py
│   │   └── common.py
│   ├── prompts/                      # LLM 提示词模板
│   │   ├── analyst.py                # 数据分析师提示词
│   │   ├── classify.py               # 意图分类提示词
│   │   ├── common.py                 # 通用提示词常量
│   │   ├── correction.py             # SQL 纠错提示词
│   │   └── sql_generator.py          # SQL 生成提示词
│   ├── routers/                      # API 路由层
│   │   ├── admin.py                  # 管理后台接口 (16个)
│   │   ├── auth.py                   # 认证接口
│   │   ├── chat.py                   # 同步聊天接口
│   │   ├── chat_stream.py            # SSE 流式聊天接口
│   │   └── session.py                # 会话管理接口
│   └── services/                     # 业务逻辑层
│       ├── chat_service.py           # 核心:意图识别+SQL生成+执行+分析 (1277行)
│       ├── arima_stock.py            # ARIMA 时间序列预测
│       ├── admin_service.py          # 管理后台服务 (886行)
│       ├── auth_service.py           # 认证鉴权服务
│       ├── session_service.py        # 会话管理服务
│       └── security.py               # SQL 安全校验
├── frontend/                         # React + Vite 前端
│   └── src/
│       ├── App.tsx                    # 前端入口(路由、权限守卫、主题配置)
│       ├── main.tsx                   # React 渲染入口
│       ├── index.css                  # 全局样式
│       ├── components/                # UI 组件
│       ├── hooks/                     # 自定义 Hook (useSSE)
│       ├── layouts/                   # 布局组件
│       ├── pages/                     # 页面组件
│       ├── services/                  # Axios API 封装
│       ├── stores/                    # Zustand 状态管理
│       └── types/                     # TypeScript 类型定义
├── semantic_layer.py                 # 语义层元数据、向量检索、缓存 (749行)
├── logger_utils.py                   # 日志工具
├── prepare_stock_data.py             # 股票数据生成脚本
├── stock_prices.sql                  # 股票价格表结构定义
├── requirements.txt                  # Python 依赖清单
├── .env.example                      # 环境变量模板
├── LICENSE                           # MIT 许可证
└── README.md                         # 项目说明

ViBlog