first commit

This commit is contained in:
陈辅元
2026-04-10 16:52:07 +08:00
commit 84fe545640
87 changed files with 20842 additions and 0 deletions
+736
View File
@@ -0,0 +1,736 @@
# Text2SQL 多智能体系统
基于 **CAMEL AI 框架**、**DeepSeek 大模型** 和 **经验数据集 Few-Shot 增强** 的专业 Text-to-SQL 生成系统,专为证券经纪业务领域优化。
## 🚀 核心特性
- **🤖 多Agent协作流水线**:Schema Linker → SQL Generator → Validator 三阶段协作
- **🎯 高精度表检索**:向量检索(Qwen3-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 + Qwen3-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 | **Qwen3-Embedding-0.6B** | 阿里云 6 亿参数,本地免费部署 |
| 向量数据库 | **ChromaDB** | 本地轻量,持久化 Schema 索引 |
| SQL 解析 | **sqlglot** | >= 20.0.0,多方言 AST 转换与验证 |
| 配置管理 | **Pydantic Settings** | 类型安全的环境变量管理 |
| 数据处理 | **pandas / numpy** | 结构化数据操作 |
## 📁 项目结构
```
text2sql_agent_camel/
├── 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 # Qwen3-Embedding 封装(本地 / 远程 API)
│ ├── 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/ # 本地 Embedding 模型权重
├── scripts/
│ ├── parse_examples.py # 解析 Example_text2sql.md → 结构化数据集
│ ├── integrate_fewshot.py # Few-Shot 集成指南与测试
│ └── patch_fewshot.py # 自动化修改 orchestrator.py(已内置)
├── logs/
│ └── text2sql.log # 运行日志(默认)
├── .env # 环境变量配置(API Key、路径、参数)
├── main.py # CLI 入口(单次查询 / 批量 / 交互模式)
├── pyproject.toml # 项目元数据与依赖
├── README.md # 本文档
└── SQL_GENERATION_LOGIC.md # SQL 生成逻辑详解(流程图、示例)
```
## ⚡ 快速开始
### 前置要求
- Python **3.10+**
- DeepSeek API Key(申请地址:https://platform.deepseek.com/api_keys)
- (可选)本地 Embedding 模型权重(或配置远程 Embedding API)
### 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(无需网络,但需下载模型)
USE_LOCAL_EMBEDDING=true
EMBEDDING_MODEL_PATH=./data/models/Qwen3-Embedding-0.6B
# 或使用远程 Embedding API(无需本地模型)
USE_LOCAL_EMBEDDING=false
MODELSCOPE_API_KEY=ms-xxxxxxxx
MODELSCOPE_BASE_URL=https://api-inference.modelscope.cn/v1
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 main.py "测试查询"
# 或手动预构建(推荐,加速首次查询)
python -c "
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 main.py "查询2024年1月的销售额"
# 交互模式
python main.py --interactive
# 批量查询(每行一个问题)
python main.py --batch queries.txt
# 指定 Schema 和方言
python main.py "统计每个市场的未结算交易量" \
--schema ./data/schemas/custom_schema.json \
--dialect postgresql
# 禁用 Few-Shot(对比实验)
python main.py "查询活跃账户数" --no-fewshot
# 调整 Few-Shot 参数
python main.py "查询2024年1月的销售额" \
--fewshot-top-k 5 \
--fewshot-min-rating 8
# 详细日志(调试用)
python main.py "查询持仓余额" --verbose
```
## 🎯 使用示例
### Python API
```python
import os
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)
# ========== Embedding ==========
USE_LOCAL_EMBEDDING=false # true=本地模型,false=远程API
# 本地模型路径
EMBEDDING_MODEL_PATH=./data/models/Qwen3-Embedding-0.6B
# 远程 API(ModelScope)
MODELSCOPE_API_KEY=ms-xxxx
MODELSCOPE_BASE_URL=https://api-inference.modelscope.cn/v1
MODELSCOPE_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8B
# ========== Schema ==========
SCHEMA_DIR=./data/schemas
SCHEMA_FILE=${SCHEMA_DIR}/G3SB_MCDataDictionary_table_structure.json
# ========== 向量数据库 ==========
VECTOR_DB_PATH=./data/embeddings/chroma
```
### CLI 参数速查
```bash
python 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 禁用向量检索(使用全部表)
--embedding-model PATH Embedding 模型路径
# 其他
--interactive, -i 交互模式
--batch FILE 批量文件路径
--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 "
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 "
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 + Qwen3-Embedding 本地索引
- 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