Ragas Ragas
stable · 中文译文
中文译文 · 原文:https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/sql/ · 许可证 Apache-2.0

SQL

基于执行的指标

在这些指标中,会将得到的 SQL 在数据库上执行后进行比较,然后将 response 与期望结果进行比较。

DataCompy Score

DataCompyScore 指标使用 DataCompy,这是一个比较两个 pandas DataFrame 的 Python 库。它提供了比较两个 DataFrame 的简单接口,并提供差异的详细报告。在该指标中,response 在数据库上执行,得到的数据与期望数据(即 reference)进行比较。为启用比较,response 和 reference 都应采用示例中所示的逗号分隔值形式。

DataFrame 可以按行或按列进行比较。这可以通过 mode 参数配置。

如果 mode 是 row,则按行进行比较。如果 mode 是 column,则按列进行比较。

[ \text{Precision } = {|\text{Number of matching rows in response and reference}| \over |\text{Total number of rows in response}|} ]

[ \text{Recall } = {|\text{Number of matching rows in response and reference}| \over |\text{Total number of rows in reference}|} ]

默认情况下,mode 设置为 row,指标为 F1 score,即 precision 和 recall 的调和平均。

from ragas.metrics.collections import DataCompyScore

data1 = """acct_id,dollar_amt,name,float_fld,date_fld
10000001234,123.45,George Maharis,14530.1555,2017-01-01
10000001235,0.45,Michael Bluth,1,2017-01-01
10000001236,1345,George Bluth,,2017-01-01
10000001237,123456,Bob Loblaw,345.12,2017-01-01
10000001238,1.05,Lucille Bluth,,2017-01-01
10000001238,1.05,Loose Seal Bluth,,2017-01-01
"""

data2 = """acct_id,dollar_amt,name,float_fld
10000001234,123.4,George Michael Bluth,14530.155
10000001235,0.45,Michael Bluth,
10000001236,1345,George Bluth,1
10000001237,123456,Robert Loblaw,345.12
10000001238,1.05,Loose Seal Bluth,111
"""

metric = DataCompyScore()
result = await metric.ascore(response=data1, reference=data2)
print(f"F1 Score: {result.value}")
print(f"Details: {result.reason}")

要将 mode 改为按列比较,将 mode 参数设置为 column。

metric = DataCompyScore(mode="columns", metric="recall")
result = await metric.ascore(response=data1, reference=data2)

DataCompyScore(旧版)

已弃用

来自 ragas.metrics 的 DataCompyScore 已弃用,将在未来版本中移除。请如上所示使用来自 ragas.metrics.collections 的 DataCompyScore。

旧版 DataCompyScore 使用 SingleTurnSample schema:

from ragas.metrics import DataCompyScore
from ragas.dataset_schema import SingleTurnSample

data1 = """acct_id,dollar_amt,name,float_fld,date_fld
10000001234,123.45,George Maharis,14530.1555,2017-01-01
10000001235,0.45,Michael Bluth,1,2017-01-01
10000001236,1345,George Bluth,,2017-01-01
10000001237,123456,Bob Loblaw,345.12,2017-01-01
10000001238,1.05,Lucille Bluth,,2017-01-01
10000001238,1.05,Loose Seal Bluth,,2017-01-01
"""

data2 = """acct_id,dollar_amt,name,float_fld
10000001234,123.4,George Michael Bluth,14530.155
10000001235,0.45,Michael Bluth,
10000001236,1345,George Bluth,1
10000001237,123456,Robert Loblaw,345.12
10000001238,1.05,Loose Seal Bluth,111
"""
sample = SingleTurnSample(response=data1, reference=data2)
scorer = DataCompyScore()
await scorer.single_turn_ascore(sample)

要将 mode 改为按列比较,将 mode 参数设置为 column。

scorer = DataCompyScore(mode="column", metric="recall")

非执行指标

在数据库上执行 SQL 查询可能很耗时,有时也不可行。在这种情况下,我们可以使用非执行指标来评估 SQL 查询。这些指标直接比较 SQL 查询,而不在数据库上执行它们。

SQL Semantic Equivalence(SQL 语义等价)

SQLSemanticEquivalence 是一种评估生成的 SQL 查询是否与 reference 查询语义等价的指标。该指标使用 LLM 在所提供的数据库 schema 上下文中分析两条查询,并确定它们是否会产生相同结果。

这是一个二元指标:

  • 1.0:SQL 查询语义等价
  • 0.0:SQL 查询不等价

该指标考虑数据库 schema 上下文以做出准确的等价判断,并计入不影响语义的句法差异(例如 active = 1 vs active = true)。

from openai import AsyncOpenAI
from ragas.llms.base import llm_factory
from ragas.metrics.collections import SQLSemanticEquivalence

# Initialize the LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)

# Create the metric
metric = SQLSemanticEquivalence(llm=llm)

# Evaluate SQL equivalence
result = await metric.ascore(
    response="""
        SELECT p.product_name, SUM(oi.quantity) AS total_quantity
        FROM order_items oi
        JOIN products p ON oi.product_id = p.product_id
        GROUP BY p.product_name;
    """,
    reference="""
        SELECT products.product_name, SUM(order_items.quantity) AS total_quantity
        FROM order_items
        INNER JOIN products ON order_items.product_id = products.product_id
        GROUP BY products.product_name;
    """,
    reference_contexts=[
        """
        Table order_items:
        - order_item_id: INT
        - order_id: INT
        - product_id: INT
        - quantity: INT
        """,
        """
        Table products:
        - product_id: INT
        - product_name: VARCHAR
        - price: DECIMAL
        """
    ]
)

print(f"Equivalent: {result.value == 1.0}")
print(f"Explanation: {result.reason}")

结果包含对两条查询的解释以及等价判定的推理。


LLMSQLEquivalence(旧版)

已弃用

LLMSQLEquivalence 已弃用,将在未来版本中移除。请如上所示使用来自 ragas.metrics.collections 的 SQLSemanticEquivalence。

LLMSQLEquivalence 是用于 SQL 语义等价评估的旧版指标。它使用 SingleTurnSample schema,并需要单独设置 LLM。

from ragas.metrics import LLMSQLEquivalence
from ragas.dataset_schema import SingleTurnSample

sample = SingleTurnSample(
    response="""
        SELECT p.product_name, SUM(oi.quantity) AS total_quantity
        FROM order_items oi
        JOIN products p ON oi.product_id = p.product_id
        GROUP BY p.product_name;
    """,
    reference="""
        SELECT p.product_name, COUNT(oi.quantity) AS total_quantity
        FROM order_items oi
        JOIN products p ON oi.product_id = p.product_id
        GROUP BY p.product_name;
    """,
    reference_contexts=[
        """
        Table order_items:
        - order_item_id: INT
        - order_id: INT
        - product_id: INT
        - quantity: INT
        """,
        """
        Table products:
        - product_id: INT
        - product_name: VARCHAR
        - price: DECIMAL
        """
    ]
)

scorer = LLMSQLEquivalence()
scorer.llm = openai_model
await scorer.single_turn_ascore(sample)