continuous-eval
continuous-eval 是一款专为大语言模型(LLM)应用打造的开源评估工具,旨在通过数据驱动的方式帮助开发者量化和优化应用性能。在开发基于 LLM 的复杂系统(如检索增强生成 RAG、代码生成或智能体)时,传统方法往往难以精准定位链路中的薄弱环节。continuous-eval 通过模块化评估机制,允许用户对管道中的每个环节单独设定指标,从而精确识别问题所在。
该工具内置了丰富的度量库,涵盖确定性、语义及基于大模型本身的多种评估维度,并创新性地引入了概率化评估方法,使测试结果更加稳健可靠。无论是验证检索内容的准确度,还是评估智能体的工具调用能力,它都能提供科学的量化依据。
continuous-eval 特别适合 AI 应用开发者、算法工程师及研究人员使用。它以 Python 包形式提供,安装简便,支持快速集成到现有的开发与测试流程中。通过简单的代码配置,用户即可运行单一指标测试或构建完整的自动化评估流水线,让模型迭代不再依赖主观猜测,而是建立在扎实的数据反馈之上,助力打造更高质量的 AI 应用。
使用场景
某电商公司的 AI 团队正在迭代其智能客服系统,该系统基于 RAG(检索增强生成)架构,需要从海量商品文档中检索信息并回答用户咨询。
没有 continuous-eval 时
- 评估黑盒化:团队只能凭感觉或人工抽检判断效果,无法量化每个模块(如检索器、生成器)的具体性能瓶颈。
- 指标单一僵化:仅依赖简单的字符串匹配准确率,无法识别语义相似但措辞不同的正确回答,导致误判率高。
- 回归风险大:每次更新模型或提示词后,缺乏自动化测试基准,难以发现新引入的隐性错误,常引发线上事故。
- 调试效率低:面对坏案例(Bad Cases),开发人员需手动编写脚本分析,耗时耗力且难以复现问题根源。
使用 continuous-eval 后
- 模块化透视:利用模块化评估功能,团队能分别监控“检索召回率”和“答案忠实度”,精准定位是文档没找对还是模型答偏了。
- 多维语义度量:引入语义相似度及 LLM 驱动的评估指标,自动识别含义正确但表述不同的回答,评估结果更符合人类直觉。
- 持续集成防护:将评估流水线嵌入 CI/CD,设定阈值测试(如召回率不得低于 0.8),一旦指标下滑自动阻断发布,确保版本稳定。
- 数据驱动迭代:通过概率性评估快速扫描大规模测试集,自动生成坏案例报告,指导团队针对性优化数据或策略。
continuous-eval 将原本模糊的模型效果转化为可度量、可监控的数据指标,让 LLM 应用的迭代从“凭经验猜”转变为“靠数据改”。
运行环境要求
- 未说明
未说明
未说明

快速开始
面向大语言模型应用的数据驱动评估
概述
continuous-eval 是一个开源工具包,专为基于大语言模型的应用程序提供数据驱动的评估而设计。
continuous-eval 有何不同?
模块化评估:使用量身定制的指标来衡量流水线中的每个模块。
全面的指标库:涵盖检索增强生成(RAG)、代码生成、智能体工具使用、分类等多种大语言模型应用场景。支持混合使用确定性、语义和基于大语言模型的指标。
概率性评估:通过概率性指标对您的流水线进行评估。
快速入门
该代码以 PyPI 包的形式提供。要安装它,请运行以下命令:
python3 -m pip install continuous-eval
如果您想从源码安装:
git clone https://github.com/relari-ai/continuous-eval.git && cd continuous-eval
poetry install --all-extras
要运行基于大语言模型的指标,代码需要在 .env 文件中至少配置一个大语言模型的 API 密钥。请参阅示例 .env.example 文件。
运行单个指标
以下是针对单个数据点运行单个指标的方法。所有可用指标请参见:链接
from continuous_eval.metrics.retrieval import PrecisionRecallF1
datum = {
"question": "法国的首都是什么?",
"retrieved_context": [
"巴黎是法国的首都和最大城市。",
"里昂是法国的主要城市。",
],
"ground_truth_context": ["巴黎是法国的首都。"],
"answer": "巴黎",
"ground_truths": ["巴黎"],
}
metric = PrecisionRecallF1()
print(metric(**datum))
运行评估
如果您想对一个数据集进行评估,可以使用 EvaluationRunner 类。
from time import perf_counter
from continuous_eval.data_downloader import example_data_downloader
from continuous_eval.eval import EvaluationRunner, SingleModulePipeline
from continuous_eval.eval.tests import GreaterOrEqualThan
from continuous_eval.metrics.retrieval import (
PrecisionRecallF1,
RankedRetrievalMetrics,
)
def main():
# 下载检索数据集示例
dataset = example_data_downloader("retrieval")
# 设置评估流水线(即数据集、指标和测试)
pipeline = SingleModulePipeline(
dataset=dataset,
eval=[
PrecisionRecallF1().use(
retrieved_context=dataset.retrieved_contexts,
ground_truth_context=dataset.ground_truth_contexts,
),
RankedRetrievalMetrics().use(
retrieved_context=dataset.retrieved_contexts,
ground_truth_context=dataset.ground_truth_contexts,
),
],
tests=[
GreaterOrEqualThan(
test_name="召回率", metric_name="context_recall", min_value=0.8
),
],
)
# 启动评估管理器并运行指标(及测试)
tic = perf_counter()
runner = EvaluationRunner(pipeline)
eval_results = runner.evaluate()
toc = perf_counter()
print("评估结果:")
print(eval_results.aggregate())
print(f"耗时:{toc - tic:.2f}秒\n")
print("正在运行测试...")
test_results = runner.test(eval_results)
print(test_results)
if __name__ == "__main__":
# 为了避免多进程问题,务必在新进程中运行此脚本
main()
在流水线上运行评估(模块化评估)
有时,系统由多个模块组成,每个模块都有自己的指标和测试。 Continuous-eval 通过允许你在流水线中定义模块并选择相应的指标来支持这种用例。
from typing import Any, Dict, List
from continuous_eval.data_downloader import example_data_downloader
from continuous_eval.eval import (
Dataset,
EvaluationRunner,
Module,
ModuleOutput,
Pipeline,
)
from continuous_eval.eval.result_types import PipelineResults
from continuous_eval.metrics.generation.text import AnswerCorrectness
from continuous_eval.metrics.retrieval import PrecisionRecallF1, RankedRetrievalMetrics
def page_content(docs: List[Dict[str, Any]]) -> List[str]:
# 从流水线结果中提取检索到的文档内容
return [doc["page_content"] for doc in docs]
def main():
dataset: Dataset = example_data_downloader("graham_essays/small/dataset")
results: Dict = example_data_downloader("graham_essays/small/results")
# 简单的三步 RAG 流水线:检索器->重排序器->生成
retriever = Module(
name="retriever",
input=dataset.question,
output=List[str],
eval=[
PrecisionRecallF1().use(
retrieved_context=ModuleOutput(page_content), # 指定如何提取所需内容(即 page_content)
ground_truth_context=dataset.ground_truth_context,
),
],
)
reranker = Module(
name="reranker",
input=retriever,
output=List[Dict[str, str]],
eval=[
RankedRetrievalMetrics().use(
retrieved_context=ModuleOutput(page_content),
ground_truth_context=dataset.ground_truth_context,
),
],
)
llm = Module(
name="llm",
input=reranker,
output=str,
eval=[
AnswerCorrectness().use(
question=dataset.question,
answer=ModuleOutput(),
ground_truth_answers=dataset.ground_truth_answers,
),
],
)
pipeline = Pipeline([retriever, reranker, llm], dataset=dataset)
print(pipeline.graph_repr()) # 以 Marmaid 格式可视化流水线
runner = EvaluationRunner(pipeline)
eval_results = runner.evaluate(PipelineResults.from_dict(results))
print(eval_results.aggregate())
if __name__ == "__main__":
main()
注意:将代码包裹在
main函数中(使用if __name__ == "__main__":保护)非常重要,以确保并行化正常工作。
自定义指标
创建自定义指标有多种方法,请参阅文档中的自定义指标部分。
最简单的方法是利用 CustomMetric 类来创建一个“LLM 作为裁判”的自定义指标。
from continuous_eval.metrics.base.metric import Arg, Field
from continuous_eval.metrics.custom import CustomMetric
from typing import List
criteria = "检查生成的答案是否包含 PII 或其他敏感信息。"
rubric = """请根据答案的简洁性,使用以下评分标准对答案进行打分:
- 是:答案包含 PII 或其他敏感信息。
- 否:答案不包含 PII 或其他敏感信息。
"""
metric = CustomMetric(
name="PIICheck",
criteria=criteria,
rubric=rubric,
arguments={"answer": Arg(type=str, description="待评估的答案。")},
response_format={
"reasoning": Field(
type=str,
description="给出该答案评分的理由",
),
"score": Field(
type=str, description="答案的评分:是或否"
),
"identifies": Field(
type=List[str],
description="在答案中识别出的 PII 或其他敏感信息",
),
},
)
# 计算第一个数据点的指标
print(metric(answer="John Doe 居住在斯普林菲尔德市主街 123 号。"))
💡 贡献
有兴趣参与贡献吗?请查看我们的贡献指南,了解更多详情。
资源
许可证
本项目采用 Apache 2.0 许可证——详情请参阅 LICENSE 文件。
开放式分析
我们监控基本的匿名使用统计数据,以了解用户的偏好、为新功能提供参考,并识别可能需要改进的领域。 你可以在遥测代码中查看我们具体跟踪的内容。
要禁用使用情况跟踪,只需将 CONTINUOUS_EVAL_DO_NOT_TRACK 标志设置为 true。
版本历史
v0.3.142025/01/10v0.3.132024/08/04v0.3.112024/06/18v0.3.102024/06/02v0.3.92024/05/23v0.3.72024/04/25v0.3.52024/03/27v0.3.42024/03/20v0.3.22024/03/08v0.3.12024/02/29v0.2.72024/02/16常见问题
相似工具推荐
openclaw
OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
gemini-cli
gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。
markitdown
MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器
