735 lines
30 KiB
Markdown
735 lines
30 KiB
Markdown
# Text2SQL 多智能体系统
|
||
|
||
基于 **CAMEL AI 框架**、**DeepSeek 大模型** 和 **经验数据集 Few-Shot 增强** 的专业 Text-to-SQL 生成系统,专为证券经纪业务领域优化。
|
||
|
||
## 🚀 核心特性
|
||
|
||
- **🤖 多Agent协作流水线**:Schema Linker → SQL Generator → Validator 三阶段协作
|
||
- **🎯 高精度表检索**:向量检索(OpenAI 兼容 / ModelScope 等远程 Embedding)+ LLM精筛,从 250+ 张表中精准定位相关表
|
||
- **💡 经验数据集 Few-Shot**:基于 50 条高质量样例的语义检索,动态注入相似示例提升准确率
|
||
- **🔒 双重验证机制**:程序语法验证 + LLM语义验证,确保 SQL 正确性
|
||
- **🏦 金融领域深度优化**:针对证券经纪业务(账户、持仓、现金、结算)定制 Prompt 和推断规则
|
||
- **✍️ 确定性模式**:Temperature=0 + 单次重试,保证相同输入产生稳定输出
|
||
- **🌐 多方言支持**:T-SQL(SQL Server)/ MySQL / PostgreSQL / SQLite
|
||
- **🔄 自修正循环**:验证失败自动重试(最多 2 次),智能修正 SQL
|
||
|
||
## 📊 系统架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 用户自然语言问题 │
|
||
└────────────────────────────┬────────────────────────────────────┘
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 阶段1: Schema Linker Agent │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 1.1 向量检索粗筛(ChromaDB + Embedding 向量) │ │
|
||
│ │ - 检索 Top 20 候选表(相似度阈值 0.1) │ │
|
||
│ │ └─ 支持对手方/经纪商问题特殊处理(强制纳入 Broker 表) │ │
|
||
│ │ │ │
|
||
│ │ 1.2 LLM 精筛 │ │
|
||
│ │ - 基于表注释选择最多 5 张相关表 │ │
|
||
│ │ └─ 输出:relevant_tables + reasoning(JSON格式) │ │
|
||
│ │ │ │
|
||
│ │ 1.3 外键扩展 │ │
|
||
│ │ - 自动添加被引用表(FK → ref_table) │ │
|
||
│ │ - 自动添加引用表(反向外键,确保 LEFT JOIN 完整性) │ │
|
||
│ └───────────────────────────────────────────────────────────┘ │
|
||
│ ↓ 精简 Schema 子集 │
|
||
└────────────────────────────┬────────────────────────────────────┘
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 阶段2: SQL Generator Agent(集成 Few-Shot 增强) │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 2.1 语义检索相似示例 │ │
|
||
│ │ - 从 50 条经验数据集中检索 Top-K 高评分示例 │ │
|
||
│ │ - 支持语义匹配(SentenceTransformer)或关键词回退 │ │
|
||
│ │ │ │
|
||
│ │ 2.2 注入 Prompt │ │
|
||
│ │ "参考以下相似示例的SQL编写风格:<examples>" │ │
|
||
│ │ │ │
|
||
│ │ 2.3 生成 T-SQL │ │
|
||
│ │ - 遵循标准版式(SELECT 每列一行、4 空格缩进) │ │
|
||
│ │ - 正确使用方括号 [TableName]、[ColumnName] │ │
|
||
│ │ - 日期函数:CAST(GETDATE() AS DATE)、DATEADD │ │
|
||
│ │ - 字符串连接:+ 运算符 │ │
|
||
│ └───────────────────────────────────────────────────────────┘ │
|
||
│ ↓ SQL 语句 │
|
||
└────────────────────────────┬────────────────────────────────────┘
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 阶段3: Validator Agent │
|
||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||
│ │ 3.1 程序验证(确定性规则) │ │
|
||
│ │ ✓ SQL 语法正确(sqlglot 解析) │ │
|
||
│ │ ✓ Schema 一致性(表/字段存在性) │ │
|
||
│ │ ✓ 别名解析正确(JOIN 别名匹配) │ │
|
||
│ │ ✓ 无危险操作(DROP/DELETE/UPDATE 等拦截) │ │
|
||
│ │ │ │
|
||
│ │ 3.2 LLM 语义验证 │ │
|
||
│ │ ✓ 业务逻辑合理性 │ │
|
||
│ │ ✓ 聚合函数使用正确(COUNT/SUM/AVG 等) │ │
|
||
│ │ ✓ WHERE 条件无矛盾 │ │
|
||
│ │ │ │
|
||
│ │ 3.3 结果判断 │ │
|
||
│ │ ✅ 通过 → 返回最终 SQL │ │
|
||
│ │ ❌ 失败 → 重试(最多 MAX_RETRY 次) │ │
|
||
│ └───────────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 🛠️ 技术栈
|
||
|
||
| 组件 | 技术选型 | 版本/说明 |
|
||
|------|---------|-----------|
|
||
| Agent 框架 | **CAMEL AI** | >= 0.2.0,角色扮演、消息通信 |
|
||
| LLM 模型 | **DeepSeek-chat** | 国产大模型,代码生成能力强 |
|
||
| Embedding | **远程 API** | OpenAI 兼容 / ModelScope / DashScope 等 |
|
||
| 向量数据库 | **ChromaDB** | 本地轻量,持久化 Schema 索引 |
|
||
| SQL 解析 | **sqlglot** | >= 20.0.0,多方言 AST 转换与验证 |
|
||
| 配置管理 | **Pydantic Settings** | 类型安全的环境变量管理 |
|
||
| 数据处理 | **pandas / numpy** | 结构化数据操作 |
|
||
|
||
## 📁 项目结构
|
||
|
||
```
|
||
text2sql_agent_camel/
|
||
├── api_server.py # FastAPI NL 网关(根目录入口;启动前将 backend 加入 sys.path)
|
||
├── backend/ # Python 后端(除 api_server 外的编排与工具)
|
||
│ ├── main.py # CLI 入口(交互模式:python backend/main.py)
|
||
│ ├── nl_lite_store.py # 轻量会话/收藏内存存储(API 演示用)
|
||
│ ├── agents/ # Agent 层
|
||
│ │ ├── orchestrator.py # 主编排器(协调 Schema Linker → Generator → Validator)
|
||
│ │ ├── schema_linker.py # 表筛选 Agent(粗筛 + LLM 精筛 + 外键扩展)
|
||
│ │ ├── sql_generator.py # SQL 生成 Agent(集成 Few-Shot 注入)
|
||
│ │ └── validator.py # SQL 验证 Agent(程序 + LLM 双重验证)
|
||
│ ├── config/
|
||
│ │ ├── prompts.py # 系统与用户 Prompt 模板
|
||
│ │ └── settings.py # 配置类(基于 Pydantic)
|
||
│ ├── schema/ # Schema 管理层
|
||
│ │ ├── models.py # 数据模型(Table, Column, ForeignKey, DatabaseSchema)
|
||
│ │ ├── loader.py # Schema 加载器(JSON / G3SB 格式解析)
|
||
│ │ ├── manager.py # Schema 管理器(查询、过滤、转字符串)
|
||
│ │ └── indexer.py # 向量索引构建器(ChromaDB 封装)
|
||
│ ├── llm/
|
||
│ │ └── deepseek_client.py # DeepSeek API 客户端(chat / validate_sql / select_tables)
|
||
│ └── utils/
|
||
│ ├── embedding.py # Embedding(远程 OpenAI 兼容 /v1/embeddings)
|
||
│ ├── sql_parser.py # sqlglot 工具(语法验证、方言转换、规范化)
|
||
│ ├── validators.py # 验证逻辑(危险操作检测、完整验证流水线)
|
||
│ └── fewshot_selector.py # Few-Shot 示例选择器(语义/关键词检索)
|
||
├── data/
|
||
│ ├── schemas/ # Schema JSON 文件
|
||
│ │ ├── G3SB_MCDataDictionary_table_structure.json # 表结构
|
||
│ │ └── G3SB_MCDataDictionary_table_meta.json # 表注释元数据
|
||
│ ├── experiences/ # 经验数据集(Few-Shot 数据源)
|
||
│ │ ├── all_samples.jsonl # 50 条样本(全部)
|
||
│ │ ├── high_rating_samples.jsonl # 30 条高质量样本(rating ≥ 8)
|
||
│ │ ├── difficulty_easy.jsonl / medium.jsonl / hard.jsonl
|
||
│ │ ├── fewshot_examples.md # Markdown 格式示例
|
||
│ │ └── by_tag/ # 按标签分类(20 类)
|
||
│ ├── embeddings/ # ChromaDB 向量索引持久化目录
|
||
│ └── models/ # (可选)其他本地模型资源
|
||
├── scripts/
|
||
│ ├── parse_examples.py # 解析 Example_text2sql.md → 结构化数据集
|
||
│ ├── integrate_fewshot.py # Few-Shot 集成指南与测试
|
||
│ └── patch_fewshot.py # 自动化修改 orchestrator.py(已内置)
|
||
├── logs/
|
||
│ └── text2sql.log # 运行日志(默认)
|
||
├── .env # 环境变量配置(API Key、路径、参数)
|
||
├── pyproject.toml # 项目元数据与依赖
|
||
├── README.md # 本文档
|
||
└── SQL_GENERATION_LOGIC.md # SQL 生成逻辑详解(流程图、示例)
|
||
```
|
||
|
||
## ⚡ 快速开始
|
||
|
||
### 前置要求
|
||
|
||
- Python **3.10+**
|
||
- DeepSeek API Key(申请地址:https://platform.deepseek.com/api_keys)
|
||
- 配置远程 Embedding API(OPENAI_* / MODELSCOPE_* / DASHSCOPE_*)
|
||
|
||
### 1. 安装依赖
|
||
|
||
```bash
|
||
# 使用 uv(推荐,速度快)
|
||
uv pip install -e .
|
||
|
||
# 或使用 pip
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
依赖清单(pyproject.toml):
|
||
```toml
|
||
dependencies = [
|
||
"camel-ai>=0.2.0",
|
||
"openai>=1.0.0",
|
||
"chromadb>=0.4.0",
|
||
"transformers>=4.36.0",
|
||
"torch>=2.0.0",
|
||
"sqlglot>=20.0.0",
|
||
"pydantic>=2.0.0",
|
||
"sentence-transformers>=2.2.0", # Few-Shot 语义检索
|
||
"python-dotenv>=1.0.0",
|
||
]
|
||
```
|
||
|
||
### 2. 配置环境变量
|
||
|
||
```bash
|
||
# 复制模板并编辑
|
||
cp .env .env.local # 或直接编辑 .env
|
||
|
||
# 必填项
|
||
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
|
||
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
||
|
||
# 远程 Embedding(OpenAI 兼容网关或 ModelScope 等)
|
||
OPENAI_BASE_URL=https://api.openai.com/v1
|
||
OPENAI_API_KEY=sk-xxxxxxxx
|
||
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
|
||
|
||
# 或使用 ModelScope
|
||
# MODELSCOPE_API_KEY=ms-xxxxxxxx
|
||
# MODELSCOPE_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8B
|
||
```
|
||
|
||
### 3. 准备 Schema 文件
|
||
|
||
将 G3SB 系统的 Schema 导出为 JSON 格式,并放置到 `data/schemas/` 目录:
|
||
|
||
```bash
|
||
# 目录结构
|
||
data/schemas/
|
||
├── G3SB_MCDataDictionary_table_structure.json # 必需:表结构定义
|
||
└── G3SB_MCDataDictionary_table_meta.json # 可选:表注释(用于 LLM 理解)
|
||
```
|
||
|
||
Schema JSON 格式示例:
|
||
```json
|
||
{
|
||
"database": "G3SB_MC",
|
||
"tables": [
|
||
{
|
||
"name": "MCAccount",
|
||
"comment": "账户主表",
|
||
"columns": [
|
||
{"name": "AccountID", "type": "NCHAR(16)", "comment": "账户唯一标识", "nullable": false, "primary_key": true},
|
||
{"name": "AccountName", "type": "NVARCHAR(100)", "comment": "账户名称"},
|
||
{"name": "State", "type": "CHAR(1)", "comment": "状态: A=Active, D=Deleted, X=SameDayDeleted"},
|
||
{"name": "OpenDate", "type": "DATE", "comment": "开户日期"}
|
||
],
|
||
"foreign_keys": [
|
||
{"columns": ["AEID"], "ref_table": "MCUser", "ref_columns": ["UserID"]}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 4. 构建向量索引(首次运行)
|
||
|
||
```bash
|
||
# 自动构建:首次在交互模式里提问时会自动创建
|
||
python backend/main.py
|
||
|
||
# 或手动预构建(推荐,加速首次查询;请在仓库根目录执行)
|
||
python -c "
|
||
import sys
|
||
from pathlib import Path
|
||
sys.path.insert(0, str(Path.cwd() / 'backend'))
|
||
from agents.orchestrator import Text2SQLOrchestrator
|
||
from schema.manager import SchemaManager
|
||
|
||
schema = SchemaManager.load_from_json('./data/schemas/G3SB_MCDataDictionary_table_structure.json')
|
||
orch = Text2SQLOrchestrator(schema_mgr=schema, deepseek_api_key='sk-xxx')
|
||
orch.build_vector_index(force_rebuild=True)
|
||
"
|
||
```
|
||
|
||
### 5. 运行演示
|
||
|
||
```bash
|
||
# 启动后进入交互式问答(默认 T-SQL / SQL Server)
|
||
python backend/main.py
|
||
|
||
# 可选:启动时附带参数(均在进入交互前生效),例如指定 Schema、方言、Few-Shot、日志等
|
||
python backend/main.py --schema ./data/schemas/custom_schema.json --dialect postgresql --verbose
|
||
python backend/main.py --no-fewshot
|
||
python backend/main.py --fewshot-top-k 5 --fewshot-min-rating 8
|
||
```
|
||
|
||
## 🎯 使用示例
|
||
|
||
### Python API
|
||
|
||
```python
|
||
import os
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# 在仓库根目录运行时,将 backend 加入模块搜索路径(请先 cd 到项目根)
|
||
sys.path.insert(0, str(Path.cwd() / "backend"))
|
||
|
||
from agents.orchestrator import Text2SQLOrchestrator
|
||
from schema.manager import SchemaManager
|
||
from llm.deepseek_client import DeepSeekConfig
|
||
|
||
# 1. 加载 Schema
|
||
schema_mgr = SchemaManager.load_from_json(
|
||
"./data/schemas/G3SB_MCDataDictionary_table_structure.json",
|
||
g3sb_meta_path="./data/schemas/G3SB_MCDataDictionary_table_meta.json"
|
||
)
|
||
|
||
# 2. 配置 DeepSeek
|
||
config = DeepSeekConfig(
|
||
api_key=os.getenv("DEEPSEEK_API_KEY"),
|
||
base_url=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||
model_name="deepseek-chat",
|
||
temperature=0, # 确定性模式
|
||
max_tokens=4096,
|
||
)
|
||
|
||
# 3. 初始化编排器
|
||
orchestrator = Text2SQLOrchestrator(
|
||
schema_manager=schema_mgr,
|
||
deepseek_config=config,
|
||
max_retry=1, # 单次尝试(确定性)
|
||
use_vector_search=True, # 启用向量检索
|
||
fewshot_enabled=True, # 启用 Few-Shot
|
||
fewshot_top_k=3, # 每次使用 3 个示例
|
||
fewshot_min_rating=7, # 最低评分过滤
|
||
)
|
||
|
||
# 4. 生成 SQL
|
||
result = orchestrator.generate(
|
||
question="查询2024年1月的销售额最高的前10个产品",
|
||
dialect="tsql",
|
||
top_k_candidates=20
|
||
)
|
||
|
||
# 5. 查看结果
|
||
print(f"SQL: {result.sql}")
|
||
print(f"有效: {result.valid}")
|
||
print(f"使用表: {result.tables_used}")
|
||
print(f"尝试次数: {result.attempts}")
|
||
print(f"推理过程: {result.reasoning}")
|
||
if result.warnings:
|
||
print(f"警告: {result.warnings}")
|
||
```
|
||
|
||
### 典型查询与期望输出
|
||
|
||
| 用户问题 | 生成 SQL(T-SQL) | 关键特性 |
|
||
|---------|------------------|---------|
|
||
| "查询2024年1月的销售额" | `WHERE TradeDate >= '2024-01-01' AND TradeDate < '2024-02-01'` | 日期范围推断 |
|
||
| "统计所有活跃账户数" | `WHERE State = 'A'` | 状态值推断 |
|
||
| "查询每个对手方的未结算交易总额" | `LEFT JOIN MCBroker ... GROUP BY ... ORDER BY SUM(...) DESC` | 多表 JOIN + 聚合 + 排序 |
|
||
| "列出今天的所有 Margin Call" | `WHERE TradeDate >= CAST(GETDATE() AS DATE)` | 相对日期处理 |
|
||
| "查询账户 ACC001 的持仓" | `WHERE AccountID = 'ACC001'` | 精确匹配 |
|
||
|
||
## 🔧 核心配置
|
||
|
||
### 环境变量(`.env`)
|
||
|
||
```ini
|
||
# ========== DeepSeek API ==========
|
||
DEEPSEEK_API_KEY=sk-xxxxxxxx
|
||
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
||
|
||
# ========== 模型参数 ==========
|
||
TEMPERATURE=0 # 0=确定性,0.3=推荐平衡值
|
||
MAX_TOKENS=4096
|
||
TEXT2SQL_DIALECT=tsql # tsql / mysql / postgresql / sqlite
|
||
|
||
# ========== 检索配置 ==========
|
||
MAX_RETRY=1 # 重试次数(1=仅首次,2=允许一次修正)
|
||
FEWSHOT_ENABLED=true # 是否启用 Few-Shot
|
||
FEWSHOT_TOP_K=3 # 每次注入的示例数量
|
||
FEWSHOT_MIN_RATING=7 # 示例最低评分(1-10)
|
||
# 推荐:Few-shot 走 Chroma(运行时可不配 FEWSHOT_DATA_PATH;灌库见 scripts/build_fewshot_chroma_index.py)
|
||
FEWSHOT_USE_CHROMA=true
|
||
FEWSHOT_CHROMA_PATH=./data/embeddings/chroma_fewshot
|
||
# FEWSHOT_DATA_PATH=./data/experiences/all_samples.jsonl # 仅构建索引时需要
|
||
|
||
# ========== Embedding(远程 /v1/embeddings)==========
|
||
# OPENAI_* 或 MODELSCOPE_* / DASHSCOPE_*(与代码内优先级一致)
|
||
OPENAI_BASE_URL=https://api.openai.com/v1
|
||
OPENAI_API_KEY=sk-xxxx
|
||
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
|
||
|
||
# ========== Schema ==========
|
||
SCHEMA_DIR=./data/schemas
|
||
SCHEMA_FILE=${SCHEMA_DIR}/G3SB_MCDataDictionary_table_structure.json
|
||
|
||
# ========== 向量数据库 ==========
|
||
VECTOR_DB_PATH=./data/embeddings/chroma
|
||
```
|
||
|
||
### CLI 参数速查
|
||
|
||
```bash
|
||
python backend/main.py [选项]
|
||
|
||
# 核心选项
|
||
--schema PATH Schema 文件路径
|
||
--dialect {mysql,postgresql,sqlite,tsql} 目标 SQL 方言
|
||
--api-key KEY DeepSeek API Key(优先于环境变量)
|
||
|
||
# 生成控制
|
||
--temperature FLOAT 采样温度(0-1,默认 0.3)
|
||
--max-tokens INT LLM 最大输出 token(默认 4096)
|
||
--max-retry INT 最大重试次数(默认 2)
|
||
|
||
# Few-Shot
|
||
--no-fewshot 禁用经验数据集增强
|
||
--fewshot-top-k N 每次使用的示例数量(默认 3)
|
||
--fewshot-min-rating N 示例最低评分(默认 7)
|
||
|
||
# 向量检索
|
||
--no-vector-search 禁用向量检索(使用全部表)
|
||
|
||
# 其他
|
||
--verbose, -v 详细日志
|
||
```
|
||
|
||
## 📈 性能与调优
|
||
|
||
### 影响因素与优化策略
|
||
|
||
| 维度 | 影响因素 | 优化建议 |
|
||
|------|---------|---------|
|
||
| **召回率** | 向量阈值 `score_threshold=0.1` | 降低至 0.05 可提高召回,但可能引入噪声 |
|
||
| **准确率** | Few-Shot 示例质量 | 补充更多高评分(≥8)样本,按业务域分类 |
|
||
| **响应速度** | 候选表数 `top_k_candidates=20` | 减少至 10-15,牺牲召回保速度 |
|
||
| **成本** | 重试次数 `max_retry` | 确定性模式下设为 1,避免重复调用 |
|
||
| **稳定性** | `TEMPERATURE` | 生产环境设为 0,确保结果可重现 |
|
||
|
||
### 典型性能数据(实测参考)
|
||
|
||
| 查询类型 | 表数 | 响应时间 | 准确率 |
|
||
|---------|------|---------|-------|
|
||
| 单表简单查询 | 1-2 | 8-12s | >90% |
|
||
| 2-3 表 JOIN | 2-3 | 12-18s | >85% |
|
||
| 聚合 + GROUP BY | 1-2 | 15-22s | >80% |
|
||
| 复杂多表(4+) | 4-6 | 25-35s | >70% |
|
||
|
||
*注:时间包含向量检索(~2s)+ LLM 生成(~5-10s)+ 验证(~1-3s),网络条件不同可能有差异。*
|
||
|
||
## 🧪 测试
|
||
|
||
```bash
|
||
# 安装测试依赖
|
||
pip install pytest pytest-cov
|
||
|
||
# 运行单元测试
|
||
pytest tests/unit/ -v
|
||
|
||
# 运行集成测试
|
||
pytest tests/integration/ -v --tb=short
|
||
|
||
# 覆盖率报告
|
||
pytest --cov=agents --cov=utils --cov-report=html
|
||
```
|
||
|
||
测试数据集:`data/Example/Example_text2sql.md` 中的 50 个标注样本。
|
||
|
||
## 📚 经验数据集(Few-Shot 数据源)
|
||
|
||
### 数据来源
|
||
`data/Example/Example_text2sql.md` — 领域专家标注的 50 个 Q&A 对,包含:
|
||
- 中英双语问题
|
||
- 专家级 T-SQL 实现
|
||
- SQL 编写理由(explanation)
|
||
- 人工评分(1-10 分,平均 7.6 分)
|
||
- 业务标签(filter, join, aggregation, broker, account...)
|
||
- 难度等级(easy / medium / hard)
|
||
|
||
### 生成数据集
|
||
|
||
```bash
|
||
# 解析 MD 文件,生成结构化数据
|
||
python scripts/parse_examples.py
|
||
|
||
# 输出文件
|
||
data/experiences/
|
||
├── all_samples.jsonl # 50 条完整样本
|
||
├── high_rating_samples.jsonl # 30 条高质量样本(rating ≥ 8)
|
||
├── difficulty_easy.jsonl # 27 条简单问题
|
||
├── difficulty_medium.jsonl # 6 条中等问题
|
||
├── difficulty_hard.jsonl # 17 条复杂问题
|
||
├── fewshot_examples.md # Markdown 格式,便于阅读
|
||
└── by_tag/ # 按标签分类(20 个目录)
|
||
├── filter.jsonl
|
||
├── join.jsonl
|
||
├── aggregation.jsonl
|
||
└── ...
|
||
```
|
||
|
||
### Few-Shot 检索逻辑
|
||
|
||
1. **语义匹配优先**:使用 SentenceTransformer 计算问题相似度(需下载模型)
|
||
2. **关键词回退**:无模型时使用中文 2-gram + 英文 token 匹配
|
||
3. **过滤条件**:
|
||
- `min_rating`:示例评分 ≥ 阈值
|
||
- `max_difficulty`:示例难度不超过指定等级
|
||
- `required_tags`:必须包含的标签(可选)
|
||
4. **排序**:相似度降序,返回 Top-K
|
||
|
||
## 🏦 领域知识:证券经纪业务(G3SB 系统)
|
||
|
||
### 数据库概览
|
||
|
||
| 模块 | 表前缀 | 说明 | 表数 |
|
||
|------|-------|------|------|
|
||
| Master Client | `MC*` | 客户、账户、产品主数据 | ~80 |
|
||
| Broker Cash | `BC*` | 资金余额、日终结算 | ~40 |
|
||
| History Cash | `HC*` | 资金历史流水(时序) | ~60 |
|
||
| Hong Kong Stock | `HXSB*` | 港股业务 | ~30 |
|
||
| Vietnam Market | `HCVSD*` | 越南市场 | ~15 |
|
||
| Reporting | `VSB*`, `VSBRpt*` | 报表视图(预计算) | ~120+ |
|
||
|
||
### 关键字段约定
|
||
|
||
| 字段名 | 类型 | 说明 | 示例值 |
|
||
|--------|------|------|--------|
|
||
| `AccountID` | NCHAR(16) | 账户唯一标识 | `'ACC0001234567'` |
|
||
| `MarketID` | NCHAR(4) | 市场代码 | `'HK'` / `'VN'` / `'CN'` |
|
||
| `InstrumentID` | NCHAR(16) | 证券代码 | `'00700.HK'` |
|
||
| `CurrencyID` | NCHAR(3) | 币种 | `'USD'` / `'HKD'` / `'CNY'` |
|
||
| `ValueDate` | DATE | 价值日期(结算日) | `'2024-01-15'` |
|
||
| `TradeDate` | DATE | 交易日期 | `'2024-01-14'` |
|
||
| `BusinessDate` | DATE | 业务日期(当前处理日) | `'2024-01-15'` |
|
||
| `Settled` | DECIMAL | 已结算余额 | `123456.78` |
|
||
| `State` | CHAR(1) | 记录状态 | `A`=活跃, `D`=已删除, `X`=当日删除 |
|
||
| `SettleStatus` | CHAR(1) | 结算状态 | `U`=未结算, `S`=已结算 |
|
||
|
||
### 常见业务查询模式
|
||
|
||
```sql
|
||
-- 1. 查询未结算交易(按对手方分组)
|
||
SELECT
|
||
b.BrokerID,
|
||
m.Name AS BrokerName,
|
||
COUNT(*) AS UnsettledTradeCount,
|
||
SUM(b.SettleAmount) AS TotalUnsettledAmount
|
||
FROM TSBBrokerContract b
|
||
LEFT JOIN MCBroker m ON b.BrokerID = m.BrokerID
|
||
WHERE b.SettleStatus = 'U' -- 未结算
|
||
AND b.CashSettleDate <= CAST(GETDATE() AS DATE) -- 截至今日
|
||
GROUP BY b.BrokerID, m.Name
|
||
ORDER BY TotalUnsettledAmount DESC;
|
||
|
||
-- 2. 查询账户资金(多币种)
|
||
SELECT
|
||
AccountID,
|
||
CurrencyID,
|
||
SUM(CASE WHEN Settled > 0 THEN Settled ELSE 0 END) AS CreditBalance,
|
||
SUM(CASE WHEN Settled < 0 THEN Settled ELSE 0 END) AS DebitBalance
|
||
FROM BCAccountCash
|
||
WHERE AccountID = 'ACC001'
|
||
GROUP BY AccountID, CurrencyID;
|
||
|
||
-- 3. 查询持仓(包含产品名称)
|
||
SELECT
|
||
i.InstrumentID,
|
||
p.InstrumentName,
|
||
i.Settled AS Quantity,
|
||
i.MarketPrice AS UnitPrice,
|
||
i.Settled * i.MarketPrice AS MarketValue
|
||
FROM MCAccountInstrument i
|
||
LEFT JOIN MCProduct p ON i.InstrumentID = p.InstrumentID
|
||
WHERE i.AccountID = 'ACC001'
|
||
AND i.Settled <> 0;
|
||
```
|
||
|
||
## 🔍 问题排查
|
||
|
||
### 1. 向量索引为空 / 检索不准
|
||
|
||
**现象**:`schema.indexer: 索引为空,正在构建...` 每次都重建,或返回表不相关。
|
||
|
||
**排查**:
|
||
```bash
|
||
# 检查索引文件
|
||
ls -la data/embeddings/chroma/
|
||
|
||
# 强制重建索引(在仓库根目录执行)
|
||
python -c "
|
||
import sys
|
||
from pathlib import Path
|
||
sys.path.insert(0, str(Path.cwd() / 'backend'))
|
||
from agents.orchestrator import Text2SQLOrchestrator
|
||
from schema.manager import SchemaManager
|
||
|
||
s = SchemaManager.load_from_json('./data/schemas/...json')
|
||
orch = Text2SQLOrchestrator(schema_mgr=s, deepseek_api_key='sk-xxx')
|
||
orch.build_vector_index(force_rebuild=True)
|
||
"
|
||
```
|
||
|
||
**原因**:Embedding 模型未加载成功,或 ChromaDB 文件损坏。
|
||
|
||
---
|
||
|
||
### 2. Few-Shot 未生效
|
||
|
||
**现象**:日志中未见 "已注入 X 个 few-shot 示例"。
|
||
|
||
**排查**:
|
||
```bash
|
||
# 检查数据文件
|
||
python -c "
|
||
import sys
|
||
from pathlib import Path
|
||
sys.path.insert(0, str(Path.cwd() / 'backend'))
|
||
from utils.fewshot_selector import FewShotSelector
|
||
s = FewShotSelector('./data/experiences/all_samples.jsonl')
|
||
print(f'样本数: {len(s.samples)}')
|
||
ex = s.select('查询账户余额', top_k=3, min_rating=7)
|
||
print(f'选中: {[e.qid for e in ex]}')
|
||
"
|
||
```
|
||
|
||
**常见原因**:
|
||
- 文件路径错误 → 检查 `FEWSHOT_DATA_PATH`
|
||
- 评分过滤过高 → 降低 `FEWSHOT_MIN_RATING`
|
||
- 语义匹配未加载模型 → 检查网络或使用本地模型
|
||
|
||
---
|
||
|
||
### 3. 生成 SQL 字段错误
|
||
|
||
**现象**:SQL 语法正确,但字段名与 Schema 不匹配。
|
||
|
||
**原因**:
|
||
- Schema 注释不完整 → LLM 无法理解字段语义
|
||
- 向量检索召回表错误 → 降低 `score_threshold`
|
||
- Temperature 过高 → 设为 0 或 0.1
|
||
|
||
**解决**:
|
||
1. 补充 Schema 字段注释
|
||
2. 重建向量索引
|
||
3. 启用 Few-Shot 并增加高评分样本
|
||
|
||
---
|
||
|
||
### 4. 日期函数错误(MySQL 风格)
|
||
|
||
**现象**:生成 `WHERE date >= CURDATE()` 而非 T-SQL 风格。
|
||
|
||
**解决**:系统已内置 `rewrite_mysql_builtins_for_tsql` 自动替换,但仍需确保 Prompt 约束。检查 `config/prompts.py` 中 T-SQL 约束是否完整。
|
||
|
||
---
|
||
|
||
### 5. 外键缺失导致 JOIN 失败
|
||
|
||
**现象**:SQL 使用 `JOIN` 但缺少 `ON` 条件,或关联表未纳入。
|
||
|
||
**解决**:
|
||
- 检查 Schema 中 `foreign_keys` 定义是否完整
|
||
- 向量检索可能遗漏关联表 → 启用外键扩展(默认开启)
|
||
- 手动在 Prompt 中强调 JOIN 完整性
|
||
|
||
---
|
||
|
||
## 🎓 Prompt 设计哲学
|
||
|
||
### 原则1:明确约束,禁止猜测
|
||
|
||
```python
|
||
"只提取明确信息,禁止猜测:仅实现用户问题里明确写出的筛选条件,"
|
||
"不可自行推断或补充未提及的筛选条件。"
|
||
```
|
||
|
||
**反面示例**:用户问"2024年1月的销售额",不应推断为"2024年1月1日至1月31日"(除非 Schema 有相应字段)。
|
||
|
||
---
|
||
|
||
### 原则2:提供推断指南
|
||
|
||
当无法避免推断时,提供**明确的推断规则**:
|
||
|
||
```python
|
||
**常见时间/状态推断指南**(需结合 Schema 字段注释):
|
||
- "2024年1月" → WHERE date_col >= '2024-01-01' AND date_col < '2024-02-01'
|
||
- "今天" / "当日" → WHERE date_col >= CAST(GETDATE() AS DATE)
|
||
AND date_col < DATEADD(DAY,1,CAST(GETDATE() AS DATE))
|
||
- "活跃" → 通常对应 State = 'A'(需确认 Schema 注释)
|
||
- "未结算" → 通常对应 SettleStatus = 'U' 或 Settled = 0
|
||
```
|
||
|
||
---
|
||
|
||
### 原则3:Few-Shot 示范优于文字描述
|
||
|
||
LLM 更擅长模仿示例而非理解抽象规则。提供 5-7 个高质量示例覆盖常见模式:
|
||
|
||
- 示例 3:日期范围推断
|
||
- 示例 4:状态值推断
|
||
- 示例 5:聚合 + 排序
|
||
- 示例 6:当日查询(GETDATE())
|
||
- 示例 7:LEFT JOIN 取维度名称
|
||
|
||
---
|
||
|
||
### 原则4:结构化输出要求
|
||
|
||
```python
|
||
输出格式:严格 JSON
|
||
{
|
||
"relevant_tables": ["TableA", "TableB"],
|
||
"reasoning": "选择理由(50-100字)"
|
||
}
|
||
```
|
||
|
||
避免自由文本,便于程序解析。
|
||
|
||
---
|
||
|
||
## 📝 开发日志
|
||
|
||
### v0.2.0(2026-04-10)—— Few-Shot 增强版
|
||
|
||
- ✅ 集成经验数据集(50 条标注样本)
|
||
- ✅ 实现 Few-Shot 选择器(语义/关键词双模式)
|
||
- ✅ 动态注入相似示例到 Prompt
|
||
- ✅ 优化 Prompt:允许合理推断,禁止随意猜测
|
||
- ✅ 添加 5 个新 Few-Shot 示例(日期、状态、聚合等)
|
||
- ✅ 降低向量检索阈值(0.2 → 0.1),提升召回率
|
||
- ✅ 确定性模式(TEMPERATURE=0, MAX_RETRY=1)
|
||
- ✅ 修复 Unicode 编码问题(Windows 控制台)
|
||
|
||
---
|
||
|
||
### v0.1.0(2026-04-08)—— 基础版本
|
||
|
||
- 🎉 初始发布
|
||
- 三 Agent 流水线(Schema Linker / SQL Generator / Validator)
|
||
- 向量检索 + LLM 精筛表选择
|
||
- ChromaDB + Embedding 向量索引(默认远程 API 编码)
|
||
- T-SQL / MySQL / PostgreSQL 多方言支持
|
||
- 双重验证机制(程序 + LLM)
|
||
- 自修正重试(最多 2 次)
|
||
|
||
---
|
||
|
||
## 📄 许可证
|
||
|
||
MIT License — 详见 [LICENSE](LICENSE) 文件。
|
||
|
||
## 🙏 致谢
|
||
|
||
- [CAMEL AI](https://www.camel-ai.org/) — 多 Agent 框架
|
||
- [DeepSeek](https://platform.deepseek.com/) — 大模型 API
|
||
- [Qwen](https://qwen.ai/) — Embedding 模型
|
||
- [ChromaDB](https://www.trychroma.com/) — 向量数据库
|
||
- [sqlglot](https://sqlglot.com/) — SQL 解析与转换
|
||
|
||
---
|
||
|
||
**维护者**:Text2SQL Team
|
||
**更新日期**:2026-04-10
|
||
**文档版本**:v0.2.0
|