AI客服的评分机制及自动化测试

智能客服的评分机制及自动化测试

使用pytest来编写智能客服的测试框架:

  1. 准备一个CSV文件来存储测试用例和预期结果。
  2. 编写测试脚本,其中包含测试用例的读取、发送请求、评分逻辑和结果验证。
  3. 使用pytest断言来验证测试结果。

首先安装pytestrequests库:

pip install pytest requests

创建一个CSV文件test_cases.csv,它包含示例测试用例:

#问题,预期回复
"已付款,啥时候发货?","你好,系统在24小时内发顺丰快递的"
"麻烦尽快发货!","你好,已为您加急发货~"
"最晚几号发货?","你好,系统最晚在24小时内发顺丰快递的"
"用什么快递发货?","你好,默认是发顺丰快递"

...

然后编写测试脚本test_ai_responses.py

import csv
import requests
import pytest

# 假设的AI服务的URL
AI_SERVICE_URL = "http://192.168.1.100:8888/query"

# 函数用于发送查询到AI服务
def send_query_to_ai(query):
    response = requests.post(AI_SERVICE_URL, json={"query": query})
    if response.status_code == 200:
        return response.json().get('response', '')
    else:
        # 在真实测试中,这里应该处理错误情况
        return None

# 评分函数,这里使用简单的字符串相等进行评分
def score_response(ai_response, expected_response):
    return ai_response.strip().lower() == expected_response.strip().lower()

# 读取CSV文件并构建测试用例
def read_test_cases(csv_file):
    test_cases = []
    with open(csv_file, newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            test_cases.append((row['query'], row['expected_response']))
    return test_cases

# 参数化测试用例
test_data = read_test_cases('test_cases.csv')

@pytest.mark.parametrize("query,expected_response", test_data)
def test_ai_response(query, expected_response):
    # 发送查询并获取AI系统的响应
    ai_response = send_query_to_ai(query)
    
    # 断言AI的响应是否与预期相符
    assert score_response(ai_response, expected_response), f"Query: {query}, Expected: {expected_response}, Got: {ai_response}"

代码解析:

  • 上面定义了一个send_query_to_ai函数来发送查询到AI客服系统,并获取响应。
    我们还定义了一个score_response函数来评分响应。
    read_test_cases函数从CSV文件中读取测试用例,并以适合pytest参数化测试的格式返回它们。

  • 最后用pytest.mark.parametrize装饰器来参数化test_ai_response函数,这样pytest就会为CSV文件中的每个测试用例运行一个测试。

在命令行中执行pytest命令。
pytest test_ai_responses.py

总结:以上实现了一个简单的评分机制:检查字符串是否完全匹配。


下面,来点硬货,实现更复杂的、更科学有效的评分机制:

评估响应的语义相似度,一般有2个方法:

  • 使用词嵌入(如Word2Vec、GloVe或BERT)来将文本转换为向量,然后计算这些向量之间的余弦相似度
  • 使用专门的评估指标,如BLEU(双语评估底线),这个常用在机器翻译领域。其实还有一个方案(偷懒~)是直接调用语言模型(如GPT-3或BERT)来进行语义相似度评分。
  • 余弦相似度是一种计算两个非零向量夹角余弦值的度量,它可以用来评估文本向量的相似性。
  • BLEU(BiLingual Evaluation Understudy)分数则通过比较机器翻译的输出和一组参考翻译来评估质量,计算n-gram的重叠度。BLEU主要关注准确性,它计算了几个不同大小的n-gram(通常是1到4)的精确匹配,并通过考虑最长的匹配序列来惩罚过短的生成句子。
  • ROUGE(Recall-Oriented Understudy for Gisting Evaluation)分数和BLEU都是常用于评估自然语言生成系统的指标,尤其在机器翻译和文本摘要领域。ROUGE评估自动文本摘要时更关注召回率,即参考摘要中的n-gram有多少被生成摘要所覆盖。ROUGE有多个变体,如ROUGE-N(考虑n-gram重叠)、ROUGE-L(考虑最长公共子序列)等。

步骤 1: 安装所需的库

我们需要安装一些NLP库,如transformerssentence-transformers,以及scikit-learn来计算余弦相似度。

pip install transformers sentence-transformers scikit-learn

步骤 2: 编写评分逻辑

我们将使用Hugging Face的transformers库来获取预训练的BERT模型的句子嵌入,然后使用scikit-learn来计算余弦相似度。

from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

# 加载预训练的句子嵌入模型
model = SentenceTransformer('all-MiniLM-L6-v2')

def calculate_cosine_similarity(response1, response2):
    # 将文本转换为向量
    embeddings = model.encode([response1, response2])
    # 计算向量之间的余弦相似度
    cosine_sim = cosine_similarity([embeddings[0]], [embeddings[1]])[0][0]
    return cosine_sim

def score_response(ai_response, expected_response):
    # 计算余弦相似度
    similarity_score = calculate_cosine_similarity(ai_response, expected_response)
    # 可以设置阈值来确定是否接受响应
    return similarity_score
    

在测试框架中加入BLEU和ROUGE分数计算方法

安装nltk和rouge-score库:

pip install nltk rouge-score

然后,更新测试脚本以包括BLEU和ROUGE评分:

import nltk
from rouge_score import rouge_scorer
from nltk.translate.bleu_score import sentence_bleu

# nltk下载器需要的数据
nltk.download('punkt')

def calculate_bleu_score(candidate, reference):
    # 分词
    candidate_tokens = nltk.word_tokenize(candidate)
    reference_tokens = nltk.word_tokenize(reference)
    # 计算BLEU分数
    score = sentence_bleu([reference_tokens], candidate_tokens)
    return score

def calculate_rouge_score(candidate, reference):
    # 初始化ROUGE评分器
    scorer = rouge_scorer.RougeScorer(['rouge1', 'rougeL'], use_stemmer=True)
    # 计算ROUGE分数
    scores = scorer.score(reference, candidate)
    return scores

# ...其他测试代码保持不变...

@pytest.mark.parametrize("query,expected_response", test_data)
def test_ai_response(query, expected_response):
    # 发送查询并获取AI系统的响应
    ai_response = send_query_to_ai(query)
    
    # 计算BLEU分数
    bleu_score = calculate_bleu_score(ai_response, expected_response)
    # 计算ROUGE分数
    rouge_scores = calculate_rouge_score(ai_response, expected_response)
    
    # 断言BLEU分数和ROUGE分数是否满足预期
    assert bleu_score > 0.5, f"Query: {query}, Expected: {expected_response}, Got: {ai_response}, BLEU: {bleu_score}"
    assert rouge_scores['rouge1'].fmeasure > 0.5, f"Query: {query}, Expected: {expected_response}, Got: {ai_response}, ROUGE-1: {rouge_scores['rouge1'].fmeasure}"
    assert rouge_scores['rougeL'].fmeasure > 0.5, f"Query: {query}, Expected: {expected_response}, Got: {ai_response}, ROUGE-L: {rouge_scores['rougeL'].fmeasure}"

前面定义了两个函数calculate_bleu_score和calculate_rouge_score来计算BLEU和ROUGE分数。然后,在测试函数test_ai_response中,我们计算这些分数并使用assert语句来检查它们是否满足预设的阈值。请注意,BLEU和ROUGE分数的阈值(在这里假设为0.5)应该根据实际情况进行调整。这些阈值可以通过对历史数据的分析来确定,以确保它们反映出对系统性能的实际期望。此外,BLEU和ROUGE分数对于某些类型的响应可能不够灵敏,因此应该结合其他评估方法使用。

步骤 3: 更新测试脚本

更新上面的test_ai_responses.py脚本,修改为最新评分逻辑。

# ...其他代码保持不变...

@pytest.mark.parametrize("query,expected_response", test_data)
def test_ai_response(query, expected_response):
    # 发送查询并获取AI系统的响应
    ai_response = send_query_to_ai(query)
    
    # 计算余弦相似度
    similarity_score = calculate_cosine_similarity(ai_response, expected_response)
    
    # 断言相似度得分是否高于设定的阈值
    # 余弦相似度是一种常用的度量文本相似度的方法,但它可能不足以捕捉所有语义差异,因此我们设置了一个阈值来判断响应是否足够接近预期。
    assert similarity_score > 0.7, f"Query: {query}, Expected: {expected_response}, Got: {ai_response}, Similarity: {similarity_score}"

相似度阈值的设计

  • 实际应用中需要根据具体情况调整相似度阈值或考虑其他评分机制,比如结合BLEU分数或ROUGE分数。

重新运行测试

使用pytest运行测试,对比结果

pytest test_ai_responses.py

写在最后:自动化测试无法完全替代人工评审,特别是在处理复杂、开放式的用户查询时。但自动化测试结合人工评审可以大大提升效率,更好地保障AI智能客服的回答质量。

你可能感兴趣的:(人工智能,Python自动化测试,测试开发工程师,人工智能)