Skip to main content

评估LLM文本到SQL的性能

Promptfoo是一个命令行工具,允许你测试和验证文本到SQL的转换。

本指南将引导你设置一个评估工具,帮助你提高文本到SQL提示的质量。

最终结果是一个类似如下的视图:

文本到SQL评估

配置

首先创建一个空的promptfooconfig.yaml文件(可选地,使用npx promptfoo@latest init生成占位符)。

第一步:定义提示

指定用于生成SQL查询的文本提示。使用{{placeholders}}作为在测试期间将被实际值替换的变量。

prompts:
- |
Output a SQL query that returns the number of {{product}} sold in the last month.

Database schema:
{{database}}

Only output SQL code.

如果愿意,你可以引用外部文件中的提示:

prompts:
- file://path/to/my_prompt.txt
- file://path/to/another_prompt.json

第二步:指定提供者

定义一个或多个语言模型提供者以使用。例如,这里我们比较GPT 3.5和GPT 4的性能:

providers:
- openai:gpt-4o-mini
- openai:gpt-4o

支持多种LLM API,包括本地模型。更多信息请参见提供者

第三步:定义测试

创建测试用例以验证生成的SQL查询。每个测试用例包括:

  • vars: 用于提示模板的变量。
  • assert: 用于验证输出的断言。

基本SQL验证

此测试生成一个针对bananas的查询(记住我们上面的提示),并确认生成的输出是有效的SQL。

- vars:
product: bananas
database: file://database.sql
assert:
- type: is-sql
tip

使用contains-sql而不是is-sql以允许包含SQL代码块的文本响应。

特定表的SQL验证

此测试确保SQL查询仅使用指定的表(ProductsShipments)。

- vars:
product: apples
database: file://database.sql
assert:
- type: is-sql
value:
databaseType: 'MySQL'
allowedTables:
- select::null::Products
- select::null::Shipments

允许的表示格式为{type}::{tableName}::{columnName}null可用于允许任何内容。

特定列的SQL验证

此测试预期会失败,因为DoesntExist列不存在于数据库中:

- vars:
product: oranges
database: file://database.sql
assert:
- type: is-sql
value:
databaseType: 'MySQL'
allowedColumns:
- select::null::DoesntExist

第四步:定义数据库模式

在单独的SQL文件(database.sql)中定义数据库的结构。

CREATE DATABASE IF NOT EXISTS ShipmentSystem;

USE ShipmentSystem;

CREATE TABLE IF NOT EXISTS Products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS Shipments (
shipment_id INT AUTO_INCREMENT PRIMARY KEY,
product_id INT NOT NULL,
quantity INT NOT NULL,
shipment_date DATE NOT NULL,
status VARCHAR(50) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);

CREATE TABLE IF NOT EXISTS ShipmentDetails (
detail_id INT AUTO_INCREMENT PRIMARY KEY,
shipment_id INT NOT NULL,
location VARCHAR(255) NOT NULL,
status VARCHAR(50) NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (shipment_id) REFERENCES Shipments(shipment_id)
);

最终配置

将所有步骤合并到最终配置文件(promptfooconfig.yaml)中:

description: 'Is-SQL示例'

prompts:
- |
Output a SQL query that returns the number of {{product}} sold in the last month.

Database schema:
{{database}}

Only output SQL code.

providers:
- openai:gpt-4o-mini

tests:
- vars:
product: bananas
database: file://database.sql
assert:
- type: is-sql

- vars:
product: apples
database: file://database.sql
assert:
- type: is-sql
value:
databaseType: 'MySQL'
allowedTables:
- select::null::Products
- select::null::Shipments

- vars:
product: oranges
database: file://database.sql
assert:
- type: is-sql
value:
databaseType: 'MySQL'
allowedColumns:
- select::null::DoesntExist

运行测试

运行你的测试:

npx promptfoo@latest eval

这将在终端中生成输出的摘要。

审查结果

使用网页查看器:

npx promptfoo@latest view

这将打开您的测试结果,并允许您优化提示词并比较模型性能。

文本到SQL评估