Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1e38190
阶段3:.github/workflows/tests.yml
Smilewithoutfalling Oct 10, 2026
2765839
阶段3:app/eval/cases.py
Smilewithoutfalling Oct 10, 2026
06ee2ee
阶段3:app/eval/comparator.py
Smilewithoutfalling Oct 10, 2026
b803dd5
阶段3:app/eval/report.py
Smilewithoutfalling Oct 10, 2026
9d80f0c
阶段3:app/eval/rescore.py
Smilewithoutfalling Oct 10, 2026
46174b2
阶段3:app/eval/runner.py
Smilewithoutfalling Oct 10, 2026
358b656
阶段3:app/nodes/codegen.py
Smilewithoutfalling Oct 10, 2026
0a9f03c
阶段3:app/nodes/planner.py
Smilewithoutfalling Oct 10, 2026
dc13c05
阶段3:app/nodes/reviewer.py
Smilewithoutfalling Oct 10, 2026
62023c9
阶段3:app/react_agent.py
Smilewithoutfalling Oct 10, 2026
27bb95f
阶段3:docs/DEVLOG.md
Smilewithoutfalling Oct 10, 2026
e157b24
阶段3:run_eval.py
Smilewithoutfalling Oct 10, 2026
a475bef
阶段3:tests/test_comparator.py
Smilewithoutfalling Oct 10, 2026
bb03782
阶段3:tests/test_entrypoints.py
Smilewithoutfalling Oct 10, 2026
815e677
阶段3:tests/test_eval_cases.py
Smilewithoutfalling Oct 10, 2026
6005191
阶段3:app/eval/case_model.py
Smilewithoutfalling Oct 10, 2026
7faaa27
阶段3:app/eval/cases_extra.py
Smilewithoutfalling Oct 10, 2026
c9ef0e1
阶段3:data/eval/employees.csv
Smilewithoutfalling Oct 10, 2026
af2ecba
阶段3:data/eval/employees.dict.csv
Smilewithoutfalling Oct 10, 2026
1522648
阶段3:data/eval/inventory.csv
Smilewithoutfalling Oct 10, 2026
dd75e27
阶段3:data/eval/inventory.dict.csv
Smilewithoutfalling Oct 10, 2026
7f6345d
阶段3:data/eval/orders.csv
Smilewithoutfalling Oct 10, 2026
72754b7
阶段3:data/eval/orders.dict.csv
Smilewithoutfalling Oct 10, 2026
f5f1e34
阶段3:data/sample_eval.dict.csv
Smilewithoutfalling Oct 10, 2026
2d4c82f
阶段3:scripts/gen_eval_data.py
Smilewithoutfalling Oct 10, 2026
edc0e26
阶段3:Windows_CRLF_签出兼容
Smilewithoutfalling Oct 10, 2026
53b9caf
阶段3:Windows_CRLF_签出兼容
Smilewithoutfalling Oct 10, 2026
c43b969
阶段3:Windows_CRLF_签出兼容
Smilewithoutfalling Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 评测数据按 LF 存储(scripts/gen_eval_data.py --check 逐字节对比)
data/eval/*.csv text eol=lf
6 changes: 4 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ jobs:
env:
PYTHONUTF8: "1"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
cache: pip
cache-dependency-path: requirements*.txt
- name: 安装依赖
run: python -m pip install -r requirements-dev.txt
- name: 评测数据与生成脚本一致
run: python scripts/gen_eval_data.py --check
- name: pytest
run: python -m pytest -q -p no:cacheprovider --durations=10
22 changes: 22 additions & 0 deletions app/eval/case_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""评测用例的数据结构。"""
from dataclasses import dataclass, field


@dataclass
class EvalCase:
id: str
category: str # aggregation | filtering | correlation | timeseries | refusal | ambiguity
question: str # 中文自然语言问题
ground_truth: str # pandas代码,执行后 result = 期望结果
keywords: list = field(default_factory=list) # 生成代码应包含的关键词
has_chart: bool = False
# 结果顺序是否计分(B12):只有题目明确要求排序/排名时为 True,比较器据此决定是否比较顺序
ordered: bool = False
# 题目问"占比"时,比例(0.49)与百分数(49%)都算对(B24 规则 12);问"百分比"的不设
percent_equiv: bool = False
# 阶段 3:所用数据表(见 DATASETS)
dataset: str = "sales"
# 应拒答题:数据里没有回答所需的信息,期望 result = "无法回答:<原因>"
expect_refusal: bool = False
# 歧义题:其他合理理解的标准答案,命中 ground_truth 或其中任一即对
alt_ground_truths: list = field(default_factory=list)
45 changes: 24 additions & 21 deletions app/eval/cases.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
"""50条标注测试用例,覆盖聚合/过滤/关联/时序四类分析场景。
"""评测用例:自然语言问题 + 标准答案代码。

每个用例包含自然语言问题 + 标准答案代码。
- 原 50 题(data/sample_eval.csv,dataset="sales"),覆盖聚合/过滤/关联/时序;
- 阶段 3 新增 80 题(app/eval/cases_extra.py),3 张合成表,另含应拒答题与歧义题。
"""
import os

from dataclasses import dataclass, field


@dataclass
class EvalCase:
id: str
category: str # aggregation | filtering | correlation | timeseries
question: str # 中文自然语言问题
ground_truth: str # pandas代码,执行后 result = 期望结果
keywords: list = field(default_factory=list) # 生成代码应包含的关键词
has_chart: bool = False
# 结果顺序是否计分(B12):只有题目明确要求排序/排名时为 True,比较器据此决定是否比较顺序
ordered: bool = False
# 题目问"占比"时,比例(0.49)与百分数(49%)都算对(B24 规则 12);问"百分比"的不设
percent_equiv: bool = False
from app.eval.case_model import EvalCase # noqa: F401 (EvalCase 定义移到 case_model,供 cases_extra 共用)


# ============================================================
Expand Down Expand Up @@ -216,7 +204,7 @@ class EvalCase:
),
EvalCase(
id="corr_003", category="correlation",
question="每个产品在各地区的销售额占比",
question="每个产品的销售额在各地区的占比(每个产品内部各地区合计为 100%)",
ground_truth="result = df.assign(sales=df['units'] * df['price']).groupby(['product', 'region'])['sales'].sum().groupby(level=0, group_keys=False).apply(lambda x: (x / x.sum() * 100).round(2))",
keywords=["groupby", "sum"],
percent_equiv=True,
Expand All @@ -241,7 +229,7 @@ class EvalCase:
),
EvalCase(
id="corr_007", category="correlation",
question="分析各产品在不同地区的销量标准差,判断分布是否均匀。",
question="先按产品和地区汇总销量,再求每个产品在各地区之间销量的标准差,判断分布是否均匀。",
ground_truth="result = df.groupby(['product', 'region'])['units'].sum().groupby(level=0).std().round(2)",
keywords=["groupby", "std"],
),
Expand Down Expand Up @@ -334,7 +322,7 @@ class EvalCase:
),
EvalCase(
id="ts_011", category="timeseries",
question="每月平均单价的走势是怎样的?",
question="每月的平均单价(按记录简单平均)走势是怎样的?",
ground_truth="df['date'] = pd.to_datetime(df['date']); result = df.set_index('date')['price'].resample('ME').mean().round(2)",
keywords=["resample", "mean", "price"],
),
Expand All @@ -352,11 +340,26 @@ class EvalCase:
),
]

ALL_CASES = AGG_CASES + FILT_CASES + CORR_CASES + TS_CASES
SALES_CASES = AGG_CASES + FILT_CASES + CORR_CASES + TS_CASES

CATEGORY_MAP = {
"aggregation": "聚合",
"filtering": "过滤",
"correlation": "关联",
"timeseries": "时序",
"refusal": "应拒答",
"ambiguity": "歧义",
}

_DATA = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "data")
# 数据表名 -> CSV 路径(相对仓库根目录)。同目录下的同名 .dict.csv 是它的数据字典
DATASETS = {
"sales": os.path.join(_DATA, "sample_eval.csv"),
"orders": os.path.join(_DATA, "eval", "orders.csv"),
"employees": os.path.join(_DATA, "eval", "employees.csv"),
"inventory": os.path.join(_DATA, "eval", "inventory.csv"),
}

from app.eval.cases_extra import EXTRA_CASES # noqa: E402

ALL_CASES = SALES_CASES + EXTRA_CASES
Loading
Loading