最近在做 RAG 相关的实验时,我发现自己在这套流程中耗费了比较多的时间:
- 找一份还算靠谱的中文问答数据集
- 把原始数据加工成评估样本,再切成 chunks 写进向量库
- 把向量库检索和生成模型串成一条 RAG 链路
- 再搭一条评估链路,用 RAGAS 这类指标看一看效果到底如何
每一步单独看都不算难,但接口、格式、路径和配置都不统一。
如果只是想“快速验证一个 RAG 方案”,从头搭一遍这条链路,性价比其实不高。
于是我干脆把这条链路抽出来,做成了一个可以直接复用的小脚手架:
qwen-rag-eval-scaffold。
它面向 Qwen 千问 API,做的事情可以概括为一条链路:
CMRC2018 → Chroma Vector Store → RAG Workflow → RAGAS Evaluation
只需要准备一个 DashScope API Key,一条命令就能从数据跑到评估结果。
一、项目定位:我想解决什么问题?
这个脚手架的目标不是“写一个最强的 RAG 系统”,而是提供一条可复现、可复用的中文 RAG 评测链路。
对我自己来说,更在意的是下面几件事:
- 数据从哪里来、格式怎么约定,能不能一劳永逸
- 向量库怎么建,后面改 workflow 的时候不用反复重来
- RAG 工作流可以随便折腾,但对外暴露的接口尽量简单、统一
- 评估这一层抽象出来,不因为换了 RAG 写法就重写一遍评测脚本
qwen-rag-eval-scaffold 在这个目标下做了一个取舍:
与其做一个“什么都能配”的大而全框架,不如先在 Qwen + 中文问答 这个场景里,把那条从数据集到评估的链路打通、固化下来,作为一个基线工程。
二、整体设计:从数据到评估的四层
整个脚手架可以拆成四层,每一层只负责一件事情。
1. 数据层:CMRC2018 标准化样本
默认使用 CMRC2018 作为中文阅读理解基准数据集,在此基础上约定了一种通用的样本格式:
{
"id": "...",
"question": "...",
"ground_truth": "...",
"ground_truth_context": "..."
}
只要你的数据满足这四个字段,就可以直接作为评估样本使用。
其中:
question是用户问题ground_truth是期望回答ground_truth_context是支持这个回答的原文片段(后面会被切成 chunks,写入向量库)
2. 向量库层:Chroma + DashScope Embedding
在向量库这一层,脚手架做了两件事:
- 使用 DashScope 的向量模型构建 embedding
- 使用 Chroma 作为本地向量库实现
从流程上看就是:
CMRC2018 samples → 只挑 ground_truth_context → 切分成多个 chunk → 写入 Chroma collection。
这一层的实现被封装在 qwen_rag_eval/vector 里,可以单独复用。
3. 执行层:Runner 抽象 + 默认 RAG 工作流
真正的 RAG 逻辑被抽象成一个 Runner,只约定一个极薄的接口:
def invoke(self, question: str) -> dict:
return {
"question": question,
"generation": "...", # 模型最终回答
"contexts": [...], # 检索到的上下文,可以是 str 或带 page_content 的对象
}
脚手架默认提供了一条基于 LangGraph 的 NormalRag 工作流,暴露成 DefaultRunner。
但你可以完全忽略它,直接把自己的 RAG workflow 包成一个 Runner 丢进来,只要遵守这个返回格式即可。
4. 评估层:RagBatchRunner + RagasEvaluator
评估层做了两件事情:
- 用
RagBatchRunner批量调用 Runner,把每条样本变成question + generation + contexts的记录 - 用
RagasEvaluator调用 RAGAS,对这些记录打分,输出整体指标和逐样本评分 CSV
对于使用者来说,评估接口大致是:
from qwen_rag_eval.evaluation import RagBatchRunner, RagasEvaluator
runner = MyRunner()
records = RagBatchRunner(runner, mode="my_runner").run_batch(eval_samples)
result = RagasEvaluator("config/application.yaml").evaluate(records)
其中 records 会被规整成内部的 RagEvalRecord 列表,然后交给 RAGAS 进行打分。
三、Quick Start:一条命令跑通
整个脚手架的使用门槛尽量控制在“安装依赖 + 配置一个环境变量”。
1. 环境准备
- Python 版本:建议 3.10+
- 安装依赖:
pip install -r requirements.txt
- 配置 DashScope API Key:
Windows 示例:
set API_KEY_Qwen=your-dashscope-api-key
python quick_start.py
Linux / macOS 示例:
export API_KEY_Qwen="your-dashscope-api-key"
python quick_start.py
2. 一条命令:python quick_start.py
在项目根目录执行:
python quick_start.py
会自动做四件事:
- 从原始 CMRC2018 构建评估样本(samples),写入
datasets/processed - 基于
ground_truth_context切分 chunks,构建 Chroma 向量库 - 使用
DefaultRunner批量跑 RAG,生成 question–answer–contexts 记录 - 调用 RAGAS 做自动评估,打印整体指标,并导出逐样本评分 CSV
只要环境变量和依赖安装正确,这一条命令就能完成从数据到评估结果的完整闭环。
四、如何接入自己的 RAG 工作流?
如果你已经有一条自己的 RAG 链路(不管是 LangChain、LangGraph 还是纯手写 pipeline),可以很轻量地接进这个脚手架进行评估。
核心就是:实现一个 Runner,满足前面提到的接口约定。
示例:
class MyRunner:
def __init__(self, retriever, llm):
self.retriever = retriever
self.llm = llm
def invoke(self, question: str) -> dict:
contexts = self.retriever.get_relevant_documents(question)
answer = self.llm.invoke({
"question": question,
"contexts": contexts,
})
return {
"question": question,
"generation": answer,
"contexts": contexts,
}
然后用统一评估接口:
from qwen_rag_eval.evaluation import RagBatchRunner, RagasEvaluator
from qwen_rag_eval.dataset_tools.loader import load_cmrc_samples
# 1. 加载评估样本
config_path = "config/application.yaml"
eval_samples = load_cmrc_samples(config_path)
# 2. 初始化你的 Runner
runner = MyRunner(retriever=..., llm=...)
# 3. 批量跑 RAG
records = RagBatchRunner(runner, mode="my_runner").run_batch(eval_samples)
# 4. 调用 RAGAS 评估
evaluator = RagasEvaluator(config_path)
result = evaluator.evaluate(records)
这样你只需要关心“怎么做检索 + 生成”,评估流程不需要每个项目重新写一份。
五、替换数据集与重建向量库
默认使用 CMRC2018 只是为了给出一条“开箱即用”的中文评测链路,但脚手架本身支持替换数据集。
只要你能把自己的数据整理成下面这种样本格式:
{
"id": "...",
"question": "...",
"ground_truth": "...",
"ground_truth_context": "..."
}
就可以直接:
- 把它保存成
samples.json - 使用
build_vector_store_from_samples直接基于样本构建向量库:
from qwen_rag_eval.vector import build_vector_store_from_samples
build_vector_store_from_samples(
"path/to/samples.json",
collection_name="my_collection",
overwrite=True,
)
后续评估逻辑保持不变。
这意味着你可以在不同任务、不同领域下重用同一套评估代码和 Runner,实现真正的“多场景复用”。
六、适用人群与应用场景
我自己在写这个脚手架时,心里对应的是几类典型使用者:
- 想入门 RAG,但不想被“找数据集 + 建库 + 写评测”拖住节奏的人
- 已经有 RAG 工作流,希望有一条统一评测链路做方案对比的人
- 在 Qwen / DashScope 生态里做应用,需要一个干净工程基线的人
对这些人来说,qwen-rag-eval-scaffold 更像是一个实验底座,而不是一个“什么都替你做好”的大框架。
它负责把那条“中文数据集 → 向量库 → RAG 工作流 → RAGAS 评估”的路径铺平,让你可以在这条路径上持续迭代自己的想法。
七、仓库地址与后续计划
仓库地址:
github.com/syy12335/qw…
目前版本是一个初始测试版,主要提供:
- CMRC2018 → Chroma → DefaultRunner → RAGAS 的完整评测链路
- Runner 接入协议和评估封装
- Streamlit 控制台作为调试与展示入口
后续计划包括:
- 补充更多 Runner 示例(不同检索策略、多跳链路等)
- 引入更多中文数据集与预设配置
- 在评估侧支持更灵活的指标组合与评估配置
如果你刚好在做中文 RAG,或者在 Qwen 生态下需要一条可复用的评测链路,希望这个脚手架能帮你少踩一点重复的坑。