评估
评估你的智能体系统输出
本指南涵盖了评估智能体的方法。有效的评估对于衡量智能体性能、跟踪改进以及确保你的智能体系统满足质量标准至关重要。
在构建 AI 应用时,评估其输出的一致性至关重要,这不仅有助于维护智能体,也有助于在初始设计阶段评估不同的架构或提示方式。
需要考虑各种定性和定量因素,包括响应语法、任务完成情况、成功率,以及不准确或幻觉。在评估中,也应比较不同配置,以针对特定期望结果进行优化。鉴于 LLM 的动态且非确定性特性,进行严格且频繁的评估也很重要,以确保有一个一致的基线来跟踪改进或回退。
配置你的应用
像单元测试一样,最好将 AI 系统的评估器收集到一个专门的目录中。这样,你可以把下面的配置添加到你的应用中 composer.json 文件,以便告诉 Composer 如何将你的评估器包含到应用命名空间中:
"autoload-dev": {
"psr-4": {
...,
"App\\Evaluators\\": "evaluators/"
}
},接下来创建 evaluators 在项目根目录中创建该目录。将评估代码与生产代码分离,可以清楚地区分哪些内容会部署到生产环境,哪些内容只是用于开发和质量保证。
创建评估器
使用下面的命令在 AgentEvaluator 类到 evaluators 文件夹中:
vendor/bin/neuron make:evaluator App\\Neuron\\Evaluators\\AgentEvaluator.\vendor\bin\neuron make:evaluators App\Neuron\Evaluators\AgentEvaluator创建的类将具有以下结构:
namespace App\Neuron\Evaluators;
use NeuronAI\Evaluation\Assertions\StringContains;
use NeuronAI\Evaluation\BaseEvaluator;
use NeuronAI\Evaluation\Contracts\DatasetInterface;
use NeuronAI\Evaluation\Dataset\JsonDataset;
class AgentEvaluator extends BaseEvaluator
{
/**
* 1. 获取要评估的数据集
*/
public function getDataset(): DatasetInterface
{
return new JsonDataset(__DIR__ . '/datasets/dataset.json');
}
/**
* 2. 运行被测试的智能体逻辑
*/
public function run(array $datasetItem): mixed
{
$response = MyAgent::make()->chat(
new UserMessage($datasetItem['input'])
)->getMessage();
return $response->getContent();
}
/**
* 3. 使用断言将输出与预期结果进行评估
*/
public function evaluate(mixed $output, array $datasetItem): void
{
$this->assert(
new StringContains($datasetItem['reference']),
$output,
);
}
} 逻辑非常直接。评估器首先加载数据集,然后针对数据集中的每个条目运行评估。
在 run 方法中,你可以使用示例输入执行你的智能体实体,并返回输出。然后输出会传递给 evaluate 方法,在那里你可以执行断言,将输出与参考值或你想要的任何其他逻辑进行比较。
数据集加载器
你可以使用任何你想要的内容作为数据集。没有预定义格式。评估器类只是让你能够加载一组测试用例,并针对它们运行评估器。你有两个数据集加载器。
ArrayDataset
JsonDataset
最终,你还可以实现 NeuronAI\Evaluation\Contracts\DatasetInterface.
运行评估
如果你已正确配置 composer 文件,可以使用 Neuron CLI 启动评估器:
断言
我们为最常见的用例提供了一组内置断言。你也可以实现自己的断言来设计自定义评分系统。请查看下一节。
StringContains
StringContainsAll
检查输出是否包含所有关键字:
StringContainsAny
检查输出是否包含任意一个关键字:
StringStartsWith
检查输出是否以前缀开头:
StringEndsWith
检查输出是否以后缀结尾:
StringLengthBetween
检查字符串长度是否在范围内:
StringDistance
使用 Levenshtein 距离检查字符串相似度:
StringSimilarity
使用嵌入检查字符串相似度:
MatchesRegex
匹配正则表达式:
IsValidJson
检查输出是否为有效的 JSON:
作为裁判的 AI
使用 AI 智能体通过自定义标准评估输出。Neuron 为你提供了原始类 AgentJudge 来定义自定义标准,否则你也可以使用内置的裁判断言之一。
忠实度裁判
检查输出是否基于上下文(没有幻觉):
正确性裁判
与预期答案比较:
相关性裁判
检查输出是否回答了问题:
有用性裁判
评估实用性和可操作性:
创建自定义断言
输出
评估模块使用一个 PHP 配置文件来控制评估结果的显示方式。配置系统支持多个输出驱动,从而使结果能够同时发送到控制台、文件、数据库或外部 API。
配置文件
创建 evaluation.php 文件到你的项目根目录:
你可以为每个输出类声明一个选项数组。这些配置将作为参数传递给输出类实现的构造函数。
如果不存在配置文件,系统默认使用 ConsoleOutputDriver 并输出到标准输出。
创建自定义输出
实现 EvaluationOutputInterface 来创建自定义输出驱动:
一旦你创建了输出类,就可以将其注册到配置文件中,以便在下次运行评估时使用。
并行执行
默认情况下,评估命令一次处理一个数据集条目。由于大多数评估器的时间都花在等待 AI 提供方响应上,通过使用 --concurrency 选项并行处理多个数据集条目,可以大幅缩短总运行时间:
使用 --concurrency=3时,最多可以同时评估 3 个数据集条目,每个条目都在各自的 PHP 子进程中运行。对于一个包含 100 个条目的数据集,如果每个条目都需要一次 2 秒的 LLM 调用,评估时间会从约 200 秒降至约 66 秒。
要求
并行执行依赖于进程 fork,这需要:
该 pcntl PHP 扩展(Linux 和 macOS 可用,Windows 不可用)
该 spatie/fork 包:
如果缺少其中任何一个,命令会打印提示并自动回退到顺序执行,因此同一个命令可在任何环境中运行。
如何选择并发级别
正在执行中的每个条目都是向你的 AI 提供方发出的一个活动请求。先从一个中等值(3–5)开始,只要没有碰到提供方的速率限制,就逐步提高。如果你看到速率限制错误以测试失败的形式出现,就降低这个值。
其工作原理,以及需要注意什么
每个数据集条目都在你的评估器的一个 fork 副本中运行,其结果会发送回父进程。这带来一些实际影响:
结果不受影响。 条目彼此独立地评估,结果保持其数据集顺序,最终报告与顺序运行完全一致。
状态不会在条目之间共享。 每个条目看到的评估器状态,都是在
setUp()之后的状态。处理某个条目时产生的副作用(增加属性、向文件追加内容)对其他条目不可见。如果你的评估器依赖于在多个条目之间累积状态,请继续顺序运行。输出必须可序列化。 由
run()返回的值会通过serialize()跨越进程边界。如果它无法被序列化(例如其中包含闭包或打开的连接),断言结果会保留,但报告中显示的输出会被替换为占位字符串。
执行时间报告
报告的总时间是真实的墙钟运行时长,而每个测试的平均时间反映的是每个单独条目的实际时长——因此在并行执行下,单个测试的平均时间可能大于总时间除以测试数量。
自定义 bootstrap 文件
默认情况下, neuron CLI 只会加载你项目的 Composer 自动加载器(vendor/autoload.php)。当你的类只是由 Composer 可解析的普通 PHP 类时,这就足够了,但通常并非如此:评估器可能需要通过框架辅助函数读取配置,需要从 .env加载环境变量,依赖常量,或需要初始化服务容器。在这些情况下,命令会因“找不到类”或缺少配置而失败,因为通常用于准备该环境的代码——也就是你的框架 bootstrap——从未运行。
该 --autoload-file 选项通过让你指定一个 PHP 文件来解决这个问题,这个文件会在 之前 命令启动时执行,并且会在默认 Composer 自动加载器之外额外加载:
这个文件可以像普通 bootstrap 一样做任何事情——注册额外的自动加载器、加载环境变量、定义常量,或启动你的框架。例如,要运行依赖 Laravel 应用的评估器:
最后更新于