api_server.py to import environment setup and schema loading from bootstrap.py, enhancing modularity. Introduce a new function in Text2SQLOrchestrator to prioritize VCUserAccessibleFunction in table selection, improving SQL generation accuracy. Update validation logic to enforce restrictions on CJK characters in SQL string literals, ensuring compliance with business rules. Enhance prompts to clarify SQL generation constraints regarding date conditions and CJK usage.
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. 安装依赖
# 使用 uv(推荐,速度快)
uv pip install -e .
# 或使用 pip
pip install -r requirements.txt
依赖清单(pyproject.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. 配置环境变量
# 复制模板并编辑
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/ 目录:
# 目录结构
data/schemas/
├── G3SB_MCDataDictionary_table_structure.json # 必需:表结构定义
└── G3SB_MCDataDictionary_table_meta.json # 可选:表注释(用于 LLM 理解)
Schema 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. 构建向量索引(首次运行)
# 自动构建:首次在交互模式里提问时会自动创建
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. 运行演示
# 启动后进入交互式问答(默认 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
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)
# ========== 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 参数速查
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),网络条件不同可能有差异。
🧪 测试
# 安装测试依赖
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)
生成数据集
# 解析 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 检索逻辑
- 语义匹配优先:使用 SentenceTransformer 计算问题相似度(需下载模型)
- 关键词回退:无模型时使用中文 2-gram + 英文 token 匹配
- 过滤条件:
min_rating:示例评分 ≥ 阈值max_difficulty:示例难度不超过指定等级required_tags:必须包含的标签(可选)
- 排序:相似度降序,返回 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=已结算 |
常见业务查询模式
-- 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: 索引为空,正在构建... 每次都重建,或返回表不相关。
排查:
# 检查索引文件
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 示例"。
排查:
# 检查数据文件
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
解决:
- 补充 Schema 字段注释
- 重建向量索引
- 启用 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:明确约束,禁止猜测
"只提取明确信息,禁止猜测:仅实现用户问题里明确写出的筛选条件,"
"不可自行推断或补充未提及的筛选条件。"
反面示例:用户问"2024年1月的销售额",不应推断为"2024年1月1日至1月31日"(除非 Schema 有相应字段)。
原则2:提供推断指南
当无法避免推断时,提供明确的推断规则:
**常见时间/状态推断指南**(需结合 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:结构化输出要求
输出格式:严格 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 文件。
🙏 致谢
维护者:Text2SQL Team
更新日期:2026-04-10
文档版本:v0.2.0