操作指南

本节中的每个指南都针对您作为有经验的用户在使用 Ragas 时可能遇到的实际问题提供了专注的解决方案。这些指南设计得简洁直接,为您的问题提供快速解决方案。我们假设您对 Ragas 的概念有基本了解且能够熟练使用。如果不是,请先浏览 快速入门 (Get Started)部分。

如何评估 Text-to-SQL 智能体

在本指南中,您将学习如何使用 Ragas 系统地评估和改进文本转 SQL(text-to-SQL)系统。

您将完成的内容:

  • 设置用于评估的基线 text-to-SQL 系统
  • 学习如何创建评估指标
  • 为您的 SQL 智能体构建可重用的评估管道
  • 基于错误分析实现改进

设置您的环境

我们创建了一个简单的模块,您可以安装并运行,以便您可以专注于理解评估过程,而不是创建应用程序。

uv pip install "ragas-examples[text2sql]"

快速智能体测试

测试文本转 SQL(text-to-SQL)智能体,查看其如何将自然语言转换为 SQL:

import os
import asyncio
from openai import AsyncOpenAI
from ragas_examples.text2sql.text2sql_agent import Text2SQLAgent

# Set your OpenAI API key
os.environ["OPENAI_API_KEY"] = "your-api-key-here"

# Create agent
openai_client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"])
agent = Text2SQLAgent(client=openai_client, model_name="gpt-5-mini")

# Test with a sample query
test_query = "How much open credit does customer Andrew Bennett?"
result = asyncio.run(agent.query(test_query))

print(f"Natural Query: {result['query']}")
print(f"Generated SQL: {result['sql']}")

输出

Natural Query: How much open credit does customer Andrew Bennett?
Generated SQL: select sum(open_balance) from ( select distinct transaction_id, open_balance from master_txn_table where customers = "Andrew Bennett" )

这会根据自然语言查询生成 SQL。现在让我们构建一个系统化的评估流程。

下载 BookSQL

在运行智能体或数据库工具之前,从 Hugging Face 下载受限制的 BookSQL 数据集:

huggingface-cli login
uv run python -m ragas_examples.text2sql.data_utils --download-data

如果您看到认证错误,请先访问数据集页面并接受条款:BookSQL on Hugging Face

完整代码
您可以在此处查看智能体和评估管道的完整代码。

准备您的数据集

我们从 BookSQL 数据集中准备了一个包含 99 个示例的平衡样本数据集(简单、中等和困难查询各 33 个)。您可以立即开始评估,或按照下一节创建自己的数据集。

下载并检查示例数据集:

# Download the sample CSV from GitHub
curl -o booksql_sample.csv https://raw.githubusercontent.com/vibrantlabsai/ragas/main/examples/ragas_examples/text2sql/datasets/booksql_sample.csv
# View the first few rows to understand the structure
head -5 booksql_sample.csv
查询 SQL 难度级别 数据集划分
Richard Aguirre 的未付余额是多少? select sum(open_balance) from ( select distinct transaction_id, open_balance from master_txn_table where customers = “Richard Aguirre” ) medium train
Sarah Oconnor 的未付余额是多少? select sum(open_balance) from ( select distinct transaction_id, open_balance from master_txn_table where customers = “Sarah Oconnor” ) medium train
Jeffrey Moore 的平均发票金额是多少? select avg(amount) from (select distinct transaction_id, amount from master_txn_table where customers = “Jeffrey Moore” and transaction_type = ‘invoice’) hard train
客户 Andrew Bennett 的可用信用额度是多少? select sum(open_balance) from ( select distinct transaction_id, open_balance from master_txn_table where customers = “Andrew Bennett” ) easy train

📋 可选:我们如何准备样本数据集

BookSQL 以 CC BY-NC-SA(仅限非商业用途)协议发布。详情和引用信息如下。

📋 许可证 & 引用详情

有关如何创建自己的评估数据集的建议,请参考《数据集 - 核心概念》。

设置您的文本转 SQL 系统

创建提示词

提取数据库模式:

uv run python -m ragas_examples.text2sql.db_utils --schema

📋 预期的模式输出

=== Database Schema ===
             name  type                                     sql
chart_of_accounts table CREATE TABLE chart_of_accounts(
                         id INTEGER ,
                         businessID INTEGER NOT NULL,
                         Account_name TEXT NOT NULL,
                         Account_type TEXT NOT NULL,
                         PRIMARY KEY(id,businessID,Account_name)
                         )
        customers table CREATE TABLE customers(
                         id INTEGER ,
                         businessID INTEGER NOT NULL,
                         customer_name TEXT NOT NULL,
                         customer_full_name TEXT ,
                         ... (continues for all columns)
                         PRIMARY KEY(id,businessID,Customer_name)
                         )
... (continues for all 7 tables with complete DDL)

编写提示词内容:

我们的提示词遵循以下模板结构:

You are a SQL query generator for a business accounting database. Convert natural language queries to SQL queries.

DATABASE CONTEXT:
This is an accounting database (accounting.sqlite) containing business transaction and entity data.

TABLES AND THEIR PURPOSE:

- master_txn_table: Main transaction records for all business transactions
- chart_of_accounts: Account names and their types for all businesses  
- products_service: Products/services and their types used by businesses
- customers: Customer records with billing/shipping details
- vendors: Vendor records with billing address details
- payment_method: Payment methods used by businesses
- employees: Employee details including name, ID, hire date

DATABASE SCHEMA (DDL):

[Complete DDL statements for all tables]

INSTRUCTIONS:
Convert the user's natural language query into a valid SQL SELECT query. Return only the SQL query, no explanations or formatting.

定义评估指标

对于文本转 SQL(text-to-SQL)系统,我们需要评估结果准确性的指标。我们将使用执行准确度作为主要指标,以验证生成的 SQL 返回正确的数据。

执行准确度指标(Execution Accuracy Metric) :使用 datacompy 比较预期 SQL 查询和预测 SQL 查询之间的实际结果。这验证了两个查询是否返回相同的数据,这是正确性的最终测试。

评估系统将结果分类为:

  • “correct”(正确) :查询成功执行并匹配预期结果
  • “incorrect”(错误) :查询执行失败,或执行成功但返回错误结果
设置指标函数

使用 Ragas 离散指标创建您的评估指标。

# File: examples/ragas_examples/text2sql/evals.py
from ragas.metrics.discrete import discrete_metric
from ragas.metrics.result import MetricResult
from ragas_examples.text2sql.db_utils import execute_sql

@discrete_metric(name="execution_accuracy", allowed_values=["correct", "incorrect"])
def execution_accuracy(expected_sql: str, predicted_success: bool, predicted_result):
    """Compare execution results of predicted vs expected SQL using datacompy."""
    try:
        # Execute expected SQL
        expected_success, expected_result = execute_sql(expected_sql)
        if not expected_success:
            return MetricResult(
                value="incorrect",
                reason=f"Expected SQL failed to execute: {expected_result}"
            )

        # If predicted SQL fails, it's incorrect
        if not predicted_success:
            return MetricResult(
                value="incorrect",
                reason=f"Predicted SQL failed to execute: {predicted_result}"
            )

        # Both queries succeeded - compare DataFrames using datacompy
        if isinstance(expected_result, pd.DataFrame) and isinstance(predicted_result, pd.DataFrame):
            # Handle empty DataFrames
            if expected_result.empty and predicted_result.empty:
                return MetricResult(value="correct", reason="Both queries returned empty results")

            if expected_result.empty != predicted_result.empty:
                return MetricResult(
                    value="incorrect",
                    reason=f"Expected returned {len(expected_result)} rows, predicted returned {len(predicted_result)} rows"
                )

            # Use datacompy to compare DataFrames with index-based comparison
            comparison = datacompy.Compare(
                expected_result.reset_index(drop=True), 
                predicted_result.reset_index(drop=True),
                on_index=True,  # Compare row-by-row by index position
                abs_tol=1e-10,  # Very small tolerance for floating point comparison
                rel_tol=1e-10,
                df1_name='expected',
                df2_name='predicted'
            )

            if comparison.matches():
                return MetricResult(
                    value="correct",
                    reason=f"DataFrames match exactly ({len(expected_result)} rows, {len(expected_result.columns)} columns)"
                )
            else:
                return MetricResult(
                    value="incorrect",
                    reason="DataFrames do not match - different data returned"
                )

    except Exception as e:
        return MetricResult(
            value="incorrect",
            reason=f"Execution accuracy evaluation failed: {str(e)}"
        )
实验函数

实验函数编排完整的评估管道——运行文本转 SQL(text-to-SQL)智能体并为每个查询计算指标:

# File: examples/ragas_examples/text2sql/evals.py
from typing import Optional
from openai import AsyncOpenAI
from ragas import experiment
from ragas_examples.text2sql.text2sql_agent import Text2SQLAgent
from ragas_examples.text2sql.db_utils import execute_sql

@experiment()
async def text2sql_experiment(
    row,
    model: str,
    prompt_file: Optional[str],
):
    """Experiment function for text-to-SQL evaluation."""
    # Create text-to-SQL agent
    openai_client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"])
    agent = Text2SQLAgent(
        client=openai_client,
        model_name=model,
        prompt_file=prompt_file
    )

    # Generate SQL from natural language query
    result = await agent.query(row["Query"])

    # Execute predicted SQL
    try:
        predicted_success, predicted_result = execute_sql(result["sql"])
    except Exception as e:
        predicted_success, predicted_result = False, f"SQL execution failed: {str(e)}"

    # Score the response using execution accuracy
    accuracy_score = await execution_accuracy.ascore(
        expected_sql=row["SQL"],
        predicted_success=predicted_success,
        predicted_result=predicted_result,
    )

    return {
        "query": row["Query"],
        "expected_sql": row["SQL"],
        "predicted_sql": result["sql"],
        "level": row["Levels"],
        "execution_accuracy": accuracy_score.value,
        "accuracy_reason": accuracy_score.reason,
    }
数据集加载器

将您的评估数据集加载到 Ragas Dataset 对象中以执行实验:

# File: examples/ragas_examples/text2sql/evals.py
import pandas as pd
from pathlib import Path
from typing import Optional
from ragas import Dataset

def load_dataset(limit: Optional[int] = None):
    """Load the text-to-SQL dataset from CSV file."""
    dataset_path = Path(__file__).parent / "datasets" / "booksql_sample.csv"

    # Read CSV
    df = pd.read_csv(dataset_path)

    # Limit dataset size if requested
    if limit is not None and limit > 0:
        df = df.head(limit)

    # Create Ragas Dataset
    dataset = Dataset(name="text2sql_booksql", backend="local/csv", root_dir=".")

    for _, row in df.iterrows():
        dataset.append({
            "Query": row["Query"],
            "SQL": row["SQL"], 
            "Levels": row["Levels"],
            "split": row["split"],
        })

    return dataset

数据集加载器包含一个 limit 参数,用于开发工作流——先从少量样本开始快速捕捉基本错误,然后扩展到完整评估。

运行基线评估

执行评估管道并收集结果
import asyncio
from ragas_examples.text2sql.evals import text2sql_experiment, load_dataset

async def run_evaluation():
    """Run text-to-SQL evaluation with direct code approach."""
    # Load dataset
    dataset = load_dataset()
    print(f"Dataset loaded with {len(dataset)} samples")

    # Run the experiment
    results = await text2sql_experiment.arun(
        dataset, 
        name="gpt-5-mini-prompt-v1",
        model="gpt-5-mini",
        prompt_file=None,
    )

    # Report results
    print(f"✅ gpt-5-mini-prompt-v1: {len(results)} cases evaluated")

    # Calculate and display accuracy
    accuracy_rate = sum(1 for r in results if r["execution_accuracy"] == "correct") / max(1, len(results))
    print(f"gpt-5-mini-prompt-v1 Execution Accuracy: {accuracy_rate:.2%}")

# Run the evaluation
await run_evaluation()

📋 输出(提示词 v1)

Loading dataset...
Dataset loaded with 99 samples
Running text-to-SQL evaluation with model: gpt-5-mini
Using prompt file: prompt.txt
Running experiment: 100%|██████████████████████| 99/99 [01:06<00:00,  1.49it/s]
✅ gpt-5-mini-prompt-v1: 99 cases evaluated
gpt-5-mini-prompt-v1 Execution Accuracy: 2.02%

配置选项:

  • model :要使用的 OpenAI 模型(默认: “gpt-5-mini” )
  • prompt_file :自定义提示词文件(默认:内置提示词为 None )
  • limit :样本数量(默认: None 表示所有样本,指定数字可限制数量)
  • name :自定义实验名称,用于结果跟踪
初始性能分析

评估生成全面的 CSV 结果用于分析。每行包含:

  • query :自然语言输入
  • expected_sql :真实 SQL
  • predicted_sql :生成的 SQL
  • level :难度(easy/medium/hard)
  • execution_accuracy :correct/incorrect(结果比较)
  • accuracy_reason :详细比较结果

分析错误和失败模式

运行评估后,您可以分析失败模式,了解您的 Text2SQL 智能体在哪里出错。以下是我们基线评估结果中的一些示例行,让您全面了解评估数据的样子:

查询 预期SQL 预测SQL 难度 执行准确度
Richard Aguirre 的未付余额是多少? select sum(open_balance) from ( select distinct transaction_id, open_balance from master_txn_table where customers = “Richard Aguirre” ) SELECT customer_name, customer_full_name, Balance FROM customers WHERE customer_name = ‘Richard Aguirre’ OR customer_full_name = ‘Richard Aguirre’; medium incorrect
客户 Natalie Myers 的可用信用额度是多少? select sum(open_balance) from ( select distinct transaction_id, open_balance from master_txn_table where customers = “Natalie Myers” ) SELECT Balance FROM customers WHERE customer_name = ‘Natalie Myers’ OR customer_full_name = ‘Natalie Myers’; easy incorrect
Ashley Thompson 的平均发票金额是多少? select avg(amount) from (select distinct transaction_id, amount from master_txn_table where customers = “Ashley Thompson” and transaction_type = ‘invoice’) SELECT AVG(Amount) FROM master_txn_table WHERE Customers = ‘Ashley Thompson’ AND Transaction_TYPE = ‘Invoice’; hard incorrect
显示 Carol Smith 的交易数量 select count(distinct transaction_id) from master_txn_table where customers = ‘Carol Smith’ or vendor = ‘Carol Smith’ SELECT COUNT(*) AS num_transactions FROM master_txn_table WHERE Customers = ‘Carol Smith’; medium incorrect

从这些示例中得出的关键观察:

执行准确度:0% - 没有任何查询返回与预期相同的结果

常见失败模式:

  • 使用错误的表( customers vs master_txn_table )
  • 缺少去重( count(distinct transaction_id) vs COUNT(*) )
  • 过滤逻辑不完整(缺少 OR vendor = ‘Name’ 条件)
  • 列名错误( Balance vs open_balance )

这表明虽然智能体生成了有效的 SQL,但在理解业务逻辑和数据库模式关系方面需要显著改进。

错误分析

为了系统地分析失败,手动审查并标注结果 CSV 中的每一行,对观察到的错误类型进行分类。您可以使用 AI 通过以下提示词帮助分类:

📋 错误分析分类提示词

为方便起见,我们提供了一个脚本,您可以使用它通过 GPT-5 自动分类错误:
uv run python -m ragas_examples.text2sql.analyze_errors --input experiments/your_results.csv

审查流程
  1. 检查摘要中的高频错误代码
  2. 手动检查每种主要错误类型的 5-10 个示例
  3. 验证 AI 的分类是否与您的理解一致
  4. 检查"预期"SQL 是否对您的模式真正正确
  5. 寻找 AI 可能遗漏的模式
  6. 根据影响和频率确定修复优先级

只有在手动验证后,您才应使用这些见解来改进提示词、示例或智能体架构。

示例错误分析结果

以下是标注结果中的一些示例行,显示了第一轮改进后仍然存在的错误类型:

查询 预期 SQL 预测 SQL 错误分析 错误代码
我们从 Fuel 收到了多少? select sum(credit) from master_txn_table as T1 join chart_of_accounts as T2 on T1.account = T2.account_name where account_type in (‘Income’, ‘Other Income’) and instr(account,“Fuel”) SELECT SUM(Amount) FROM (SELECT DISTINCT Transaction_ID, Amount FROM master_txn_table WHERE Customers = ‘Fuel’); 预测结果对 master_txn_table 中的 Amount 求和,而不是 credit ,并且省略了与 chart_of_accounts 的连接,使用 Customers=‘Fuel’ 而不是筛选包含 ‘Fuel’ 的账户名并限制为收入/其他收入。 [“WRONG_SOURCE_TABLE_OR_COLUMN”, “WRONG_FILTER_COLUMN”, “NULL_OR_EMPTY_RESULT”]
Roberta Shaw 的最近一张发票是什么? select transaction_id from master_txn_table where transaction_type = ‘invoice’ and customers = “Roberta Shaw” order by transaction_date desc limit 1 SELECT Transaction_ID, Transaction_DATE, Amount, Open_balance, CreatedDATE, CreatedUSER, Account, Customers, Product_Service FROM master_txn_table WHERE Transaction_TYPE = ‘invoice’ AND Customers = ‘Roberta Shaw’ ORDER BY Transaction_DATE DESC LIMIT 1; 预测结果选择了9列而不是预期的仅 Transaction_ID ,导致列/模式不匹配,尽管返回了相同的行。 [“OUTPUT_COLUMN_ALIAS_MISMATCH”]
Jeremy Strong 的平均发票金额是多少? select avg(amount) from (select distinct transaction_id, amount from master_txn_table where customers = “Jeremy Strong” and transaction_type = ‘invoice’) SELECT AVG(Amount) FROM (SELECT DISTINCT Transaction_ID, Amount FROM master_txn_table WHERE Transaction_TYPE = ‘invoice’ AND Vendor = ‘Jeremy Strong’) AS t; 查询在 Vendor = ‘Jeremy Strong’ 上过滤,而不是正确的 customers 列,因此可能没有匹配到任何行。这导致 AVG(amount) 返回 NULL 。 [“WRONG_FILTER_COLUMN”, “NULL_OR_EMPTY_RESULT”]

从结果中得出的关键观察:

  • 错误模式:
  • 缺少 OR 条件:关于"与"某人交易的查询应检查 customers 和 vendor 两列
  • 列选择错误:财务查询使用 Amount 而不是 credit
  • 输出模式不匹配:选择了太多列或列名错误
  • 缺少连接:没有与 chart_of_accounts 连接以进行账户类型过滤

这些模式为下一轮提示词改进提供了信息,重点关注完整的过滤逻辑和正确的财务查询处理。

使用通用规则决定在提示词中更改什么,而不是逐行修复。避免添加特定案例的示例;优先使用基于模式的护栏,以避免过拟合数据。

迭代重复此循环:

  • 运行 → 标注 → 审查 → 决定通用护栏 → 更新 prompt_vX.txt → 重新运行 → 比较 → 重复。

  • 保持护栏简洁且基于模式,以便改进能够泛化而不过拟合。

  • 对提示词进行版本管理( prompt_v2.txt 、 prompt_v3.txt 、 prompt_v4.txt ),并为每个版本维护简要的变更日志。

  • 当连续两次迭代的执行准确度达到平稳状态或满足业务阈值时停止。

改进您的系统

创建并使用新版本提示词

我们保持基线提示词不变,并创建一个新版本进行迭代。

创建 prompt_v2.txt ,包含简洁、可重用的护栏。保持它们足够通用以广泛应用,同时基于提供的模式。以下是我们添加到 prompt_v1.txt 以创建 prompt_v2.txt 的部分示例:

- Use exact table and column names from the schema; do not invent fields
- Prefer transactional facts from `master_txn_table`; use entity tables for static attributes
- Map parties correctly in filters:
  - Customer-focused → filter on `Customers`
  - Vendor-focused → filter on `Vendor`
- Disambiguate events via `Transaction_TYPE` (e.g., invoices → `Transaction_TYPE = 'invoice'`)
- Avoid double-counting by deduplicating on `Transaction_ID` for counts and aggregates:
  - Counts: `count(distinct Transaction_ID)`
  - Aggregates: compute over a deduplicated subquery on `(Transaction_ID, metric_column)`
- For open credit/balance due per customer, aggregate `Open_balance` from `master_txn_table` filtered by `Customers` with deduplication
- Do not add extra transforms or filters (e.g., `abs()`, `< 0`) unless explicitly asked
- Keep a single `SELECT`; avoid aliases for final column names

我们将这个改进后的提示词保存为 prompt_v2.txt 。

使用新提示词重新运行评估
import asyncio
from ragas_examples.text2sql.evals import text2sql_experiment, load_dataset

async def run_v2_evaluation():
    """Run evaluation with prompt v2."""
    # Load dataset
    dataset = load_dataset()
    print(f"Dataset loaded with {len(dataset)} samples")

    # Run experiment
    results = await text2sql_experiment.arun(
        dataset, 
        name="gpt-5-mini-prompt-v2",
        model="gpt-5-mini",
        prompt_file="prompt_v2.txt",
    )

    # Report results
    print(f"✅ gpt-5-mini-prompt-v2: {len(results)} cases evaluated")

    # Calculate accuracy
    accuracy_rate = sum(1 for r in results if r["execution_accuracy"] == "correct") / max(1, len(results))
    print(f"gpt-5-mini-prompt-v2 Execution Accuracy: {accuracy_rate:.2%}")

await run_v2_evaluation()

📋 输出(提示词 v2)

Loading dataset...
Dataset loaded with 99 samples
Running text-to-SQL evaluation with model: gpt-5-mini
Using prompt file: prompt_v2.txt
Running experiment: 100%|██████████████████████| 99/99 [01:00<00:00,  1.63it/s]
✅ gpt-5-mini-prompt-v2: 99 cases evaluated
gpt-5-mini-prompt-v2 Execution Accuracy: 60.61%

我们看到使用 prompt_v2 后,执行准确度从 2.02% 提升到了 60.61%。

查看 experiments/ 目录中新的结果 CSV,并再次继续迭代循环。

继续迭代:创建提示词 v3

尽管 prompt_v2.txt 有了重大改进,但 60% 的准确度仍有提升空间。对失败的深入分析揭示了几个反复出现的模式:

  1. 对财务概念的误解 :模型始终默认对 Amount 列进行聚合,而不是正确的 Credit (收入)或 Debit (支出)列。它也经常无法与 chart_of_accounts 进行 JOIN 以按账户类型(例如 ‘Income’)过滤。
  2. 添加不必要的转换 :模型经常用未经请求的 DISTINCT 子句或额外过滤条件(如 Transaction_TYPE = ‘invoice’ )使查询复杂化,从而改变结果。
  3. 列选择错误 :对于"显示所有交易"的查询,它经常使用 SELECT * 而不是预期的 SELECT DISTINCT Transaction_ID ,导致模式不匹配。它还为聚合生成错误的列名(例如 max(transaction_date) 而不是 transaction_date )。
  4. 过滤不完整 :它经常遗漏 OR 条件(例如,检查与某人交易时的 Customers 和 Vendor ),或者完全在错误的列上进行过滤。

基于此深入分析,创建 prompt_v3.txt ,包含更具体、基于模式的指南来解决这些反复出现的问题:

prompt_v3.txt 的主要新增内容:

### CORE QUERY GENERATION GUIDELINES

1.  **Use Correct Schema**: Use exact table and column names...
2.  **Simplicity First**: Keep the query as simple as possible...
...

### ADVANCED QUERY PATTERNS

5.  **Financial Queries (Revenue, Sales, Expenses)**:
    -   **Metric Selection**:
        -   For revenue, income, sales, or money **received**: aggregate the `Credit` column.
        -   For expenses, bills, or money **spent**: aggregate the `Debit` column.
        -   Use the `Amount` column only when...
    -   **Categorical Financial Queries**: For questions involving financial categories... you **MUST** `JOIN` `master_txn_table` with `chart_of_accounts`...

6.  **Filtering Logic**:
    -   **Ambiguous Parties**: For questions about transactions "with" or "involving" a person or company, you **MUST** check both `Customers` and `Vendor` columns. E.g., `WHERE Customers = 'Name' OR Vendor = 'Name'`.
    -   **Avoid Extra Filters**: Do not add implicit filters...

7.  **Column Selection and Naming**:
    -   **Avoid `SELECT *`**: When asked to "show all transactions", return only `DISTINCT Transaction_ID`...
    -   **"Most Recent" / "Last" Queries**: To get the 'most recent' or 'last' record, use `ORDER BY Transaction_DATE DESC LIMIT 1`. This preserves the original column names... Avoid using `MAX()`...

这些新规则旨在保持通用性,但直接针对观察到的失败模式。
使用 prompt_v3.txt 重新运行评估:

import asyncio
from ragas_examples.text2sql.evals import text2sql_experiment, load_dataset

async def run_v3_evaluation():
    """Run evaluation with prompt v3."""
    # Load dataset
    dataset = load_dataset()
    print(f"Dataset loaded with {len(dataset)} samples")

    # Run experiment
    results = await text2sql_experiment.arun(
        dataset, 
        name="gpt-5-mini-prompt-v3",
        model="gpt-5-mini",
        prompt_file="prompt_v3.txt",
    )

    # Report results
    print(f"✅ gpt-5-mini-prompt-v3: {len(results)} cases evaluated")

    # Calculate accuracy
    accuracy_rate = sum(1 for r in results if r["execution_accuracy"] == "correct") / max(1, len(results))
    print(f"gpt-5-mini-prompt-v3 Execution Accuracy: {accuracy_rate:.2%}")

await run_v3_evaluation()

我们看到使用 prompt_v3 后,执行准确度从 60.61% 提升到了 70.71%。

持续迭代的关键原则

使用 prompt_v3.txt 达到的 70% 准确度证明了系统迭代的强大力量。您可以继续这个过程将准确度推向更高水平。

持续迭代的关键原则:

  • 每次迭代应针对最新结果中的 3-5 个高频错误模式
  • 保持新规则的通用性和基于模式,避免过拟合
  • 当连续 2-3 次迭代的准确度达到平稳状态时停止
  • 如果提示词改进遇到瓶颈,您可以尝试使用更好的模型,或将 SQL 错误返回给 LLM 进行修复,构建实际的智能体流程

比较结果

运行所有提示词版本后,我们可以比较最终结果。

提示词 执行准确度 结果CSV
v1 ( prompt.txt ) 2.02% experiments/…-prompt-v1.csv
v2 ( prompt_v2.txt ) 60.61% experiments/…-prompt-v2.csv
v3 ( prompt_v3.txt ) 70.71% experiments/…-prompt-v3.csv

进度分析:

  • v1 → v2:通过基本去重和业务逻辑指南,实现了从 2.02% 到 60.61% 的巨大提升(58 个百分点)
  • v2 → v3:通过增强的财务查询指南、更好的过滤逻辑和列选择规则,进一步提升了 10 个百分点(从 60.61% 到 70.71%)
  • 改进针对的是通过错误分析识别出的特定失败模式:财务概念、不必要的转换和不完整的过滤

结论

本指南向您展示了如何为文本转 SQL(text-to-SQL)系统构建系统化的评估流程。

主要收获:

  • 设置执行准确度指标来比较实际查询结果
  • 遵循迭代流程:评估 → 分析错误 → 改进 → 重复

评估框架为您提供了一种可靠的方式来衡量和改进系统,Ragas 自动处理编排和结果聚合。

更多推荐