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)