从零开始构建AI Agent评估体系:12种LangSmith评估方法详解

原文:https://zhuanlan.zhihu.com/p/1935065663346544823

AI Agent 的评估需要全面考虑其完整的生命周期,从开发阶段到生产部署。评估过程应当涵盖多个关键维度:最终输出的事实准确性和实用价值、推理过程中工具选择的合理性和路径效率、结构化响应生成能力(如 JSON 格式)、多轮对话的上下文维持能力,以及在真实用户流量下的持续性能表现和错误监控能力。

为了有效监控和评估 Agent 生命周期的各个组件,LangSmith 作为最具影响力和广泛应用的工具平台之一,提供了强大的评估框架。本文将深入探讨十二种不同的智能体评估技术,详细阐述每种技术的适用场景和实施方法。这些技术涵盖了从传统的预测答案与标准答案比较,到先进的实时反馈评估等多个层面,其中标准答案会随时间动态变化。

评估技术体系架构

基于标准答案的评估方法

这类方法包括环境配置、精确匹配评估、非结构化问答评估、结构化数据比较以及动态标准答案等技术。

程序性评估(过程分析)

此类别涵盖轨迹评估、工具选择精度分析、组件级 RAG 评估、基于 RAGAS 的 RAG 评估以及实时反馈机制。

观察性与自主评估

包括成对比较、基于仿真的评估、算法反馈以及技术总结等方法。

环境配置与初始化

评估工作的首要步骤是建立 LangSmith 环境。需要从官方仪表板获取 API 密钥,这是后续通过仪表板跟踪 Agent 进度的关键步骤。以下为 API 密钥的初始化配置:

import os   
from langchain_openai import ChatOpenAI   
import langsmith   
 
# 设置 LangSmith 端点(使用云版本时请勿修改)   
os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"   
 
# 配置 LangSmith API 密钥   
os.environ["LANGCHAIN_API_KEY"] = "YOUR_LANGSMITH_API_KEY"   
 
# 配置 OpenAI API 密钥   
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

虽然本文使用 OpenAI 模型作为示例,但 LangChain 支持广泛的开源和闭源大语言模型。开发者可以根据需求切换到其他模型 API 提供商或本地部署的 Hugging Face 模型。

LangSmith API 端点负责在 Web 仪表板中存储所有评估指标,这将在后续分析中发挥重要作用。接下来需要初始化 LangSmith 客户端,作为整个评估流程的核心组件:

# 初始化 LangSmith 客户端   
client = langsmith.Client()

1、精确匹配评估方法

精确匹配评估是最基础但至关重要的评估方法之一。该方法通过比较模型输出与预定义的正确答案来验证一致性。

该评估流程的核心机制包括:建立标准答案作为预期响应的基准;向模型提供输入并获取基于该输入的输出;执行逐字符精确匹配检验,若匹配则赋值 1 分,不匹配则为 0 分;最后对所有样本的得分进行平均计算,得出模型的整体精确匹配性能指标。

为了在 LangSmith 中有效实施这种方法,首先需要构建评估数据集。在 LangSmith 框架中,数据集是由示例集合构成,每个示例包含输入和相应的预期输出(参考或标签)。这些数据集构成了模型测试和评估的基础架构。

以下示例创建了包含两个问题的数据集,并为每个问题提供了期望的精确输出:

# 创建数据集作为问答示例的容器   
ds = client.create_dataset(   
    dataset_name=dataset_name,   
    description="A dataset for simple exact match questions."   
)   
 
# 每个示例由输入字典和相应的输出字典组成 
# 输入和输出在独立列表中提供,维持相同的顺序   
client.create_examples(   
    # 输入列表,每个输入都是字典格式   
    inputs=[   
        {   
            "prompt_template": "State the year of the declaration of independence. Respond with just the year in digits, nothing else"   
        },   
        {   
            "prompt_template": "What's the average speed of an unladen swallow?"   
        },   
    ],   
    # 对应的输出列表   
    outputs=[   
        {"output": "1776"},  # 第一个提示的预期输出   
        {"output": "5"}      # 第二个提示的预期输出(陷阱问题)   
    ],   
    # 示例将被添加到的数据集 ID   
    dataset_id=ds.id,   
)

数据准备完成后,需要定义评估组件。首要组件是待评估的模型或链。本示例中创建了 predict_result 函数,该函数接收提示,将其发送至 OpenAI 的 gpt-3.5-turbo 模型,并返回模型响应:

# 定义待测试模型   
model = "gpt-3.5-turbo"   
 
# 被测试系统:接收输入字典,调用指定的 ChatOpenAI 模型,返回字典格式的输出   
def predict_result(input_: dict) -> dict:   
    # 输入字典包含 "prompt_template" 键,与数据集输入中定义的键一致   
    prompt = input_["prompt_template"]   
 
    # 初始化并调用模型   
    response = ChatOpenAI(model=model, temperature=0).invoke(prompt)   
 
    # 输出键 "output" 与数据集输出中的键匹配,用于比较   
    return {"output": response.content}

评估器是对系统性能进行评分的核心函数。LangSmith 提供多种内置评估器,同时支持自定义评估器的创建。内置的 exact_match 评估器是预构建的字符串评估器,用于检查预测与参考输出之间的完全字符匹配。自定义 compare_label 评估器则演示了如何实现自定义逻辑,通过 @run_evaluator 装饰器使 LangSmith 能够在评估过程中识别和使用该函数。

from langsmith.evaluation import EvaluationResult, run_evaluator   
 
# @run_evaluator 装饰器将函数注册为自定义评估器   
@run_evaluator   
def compare_label(run, example) -> EvaluationResult:   
    """ 
    用于检查精确匹配的自定义评估器 
 
    Args:   
        run: LangSmith 运行对象,包含模型输出   
        example: LangSmith 示例对象,包含参考数据   
 
    Returns:   
        包含键和分数的 EvaluationResult 对象   
    """   
    # 从运行输出字典获取模型预测 
    # 键 'output' 必须与 `predict_result` 函数返回内容匹配   
    prediction = run.outputs.get("output") or ""   
 
    # 从示例输出字典获取参考答案 
    # 键 'output' 必须与数据集中定义内容匹配   
    target = example.outputs.get("output") or ""   
 
    # 执行比较操作   
    match = prediction == target   
 
    # 返回结果,键值为结果中分数的命名方式 
    # 精确匹配分数通常为二进制(匹配为 1,不匹配为 0)   
    return EvaluationResult(key="matches_label", score=int(match))

配置完成所有组件后,可以执行评估。RunEvalConfig 用于配置评估测试套件,指定内置的 "exact_match" 评估器和自定义的 compare_label 评估器,确保每个模型运行都被两个评估器评分。client.run_on_dataset 作为主要协调函数,遍历指定数据集中的每个示例,对输入运行 predict_result 函数,然后应用 RunEvalConfig 中的评估器对结果进行评分。

from langchain.smith import RunEvalConfig   
 
# 定义评估运行的配置   
eval_config = RunEvalConfig(   
    # 通过字符串名称指定内置评估器   
    evaluators=["exact_match"],    
 
    # 在列表中直接传递自定义评估器函数   
    custom_evaluators=[compare_label],   
)   
 
# 触发评估执行 
# 对数据集中每个示例运行 `predict_result` 函数 
# 然后使用 `eval_config` 中的评估器对结果评分   
client.run_on_dataset(   
    dataset_name=dataset_name,   
    llm_or_chain_factory=predict_result,   
    evaluation=eval_config,   
    verbose=True, # 打印进度条和链接   
    project_metadata={"version": "1.0.1", "model": model}, # 项目可选元数据   
)

评估执行将在样本数据上启动基于精确匹配方法的评估并显示进度:

View the evaluation results for project 'gregarious-doctor-77' at:   
https://smith.langchain.com/o/your-org-id/datasets/some-dataset-uuid/compare?selectedSessions=some-session-uuid   
 
View all tests for Dataset Oracle of Exactness at:   
https://smith.langchain.com/o/your-org-id/datasets/some-dataset-uuid   
[------------------------------------------------->] 2/2

结果展示了多种统计信息,包括评估数据中实体数量的 count、正确预测实体比例的 mean(0.5 表示一半实体被正确识别),以及其他统计信息。

LangSmith 精确匹配评估主要适用于需要确定性输出的 RAG 或 AI Agent 任务场景。基于事实的问答需要从上下文中获取单一正确事实答案;封闭式问题需要精确的是非判断或选择匹配;工具使用输出需要验证精确的工具调用结果;结构化输出需要检查精确的格式和键值对。

2、非结构化问答评估

由于大语言模型响应为非结构化文本,简单的字符串匹配往往无法满足评估需求。模型可以用多种不同表述方式提供事实正确的答案。为解决这一挑战,可以采用 LLM 辅助评估器来评估系统响应的语义和事实准确性。

该评估流程始于创建包含问题和参考答案(黄金标准)的数据集。基于 RAG 的问答系统随后使用检索到的文档回答每个问题。独立的 LLM(充当"评判者")将预测答案与参考答案进行比较。若答案在事实上正确,评判者给予 1 分;若答案错误或存在幻觉,则给予 0 分。评判者提供推理过程来解释评分依据。最终,开发者可以审查错误案例,改进系统并重新执行评估。

相比精确匹配方法,非结构化场景的关键区别在于"标准答案"现在是正确性的参考基准,而非精确匹配的模板。

# 在 LangSmith 中创建数据集   
dataset = client.create_dataset(   
    dataset_name=dataset_name,   
    description="Q&A dataset about LangSmith documentation."   
)   
 
# 问答示例,答案作为'标准答案'   
qa_examples = [   
    (   
        "What is LangChain?",   
        "LangChain is an open-source framework for building applications using large language models. It is also the name of the company building LangSmith.",   
    ),   
    (   
        "How might I query for all runs in a project?",   
        "You can use client.list_runs(project_name='my-project-name') in Python, or client.ListRuns({projectName: 'my-project-name'}) in TypeScript.",   
    ),   
    (   
        "What's a langsmith dataset?",   
        "A LangSmith dataset is a collection of examples. Each example contains inputs and optional expected outputs or references for that data point.",   
    ),   
    (   
        "How do I move my project between organizations?",   
        "LangSmith doesn't directly support moving projects between organizations.",   
    ),   
]   
 
# 将示例添加到数据集 
# 输入键为 'question',输出键为 'answer' 
# 这些键必须与 RAG 链期望和生成的内容匹配   
for question, answer in qa_examples:   
    client.create_example(   
        inputs={"question": question},   
        outputs={"answer": answer},   
        dataset_id=dataset.id,   
    )

接下来构建使用 LangChain 和 LangSmith 文档的 RAG 管道问答系统。该系统包含四个主要步骤:加载文档(抓取 LangSmith 文档);创建检索器(嵌入文档并存储在 ChromaDB 中以查找相关片段);生成答案(使用 ChatOpenAI 和提示基于检索内容回答);组装链(使用 LangChain 表达语言将所有组件合并为单一管道)。

首先加载和处理文档以创建知识库:

from langchain_community.document_loaders import RecursiveUrlLoader   
from langchain_community.document_transformers import Html2TextTransformer   
from langchain_community.vectorstores import Chroma   
from langchain_text_splitters import TokenTextSplitter   
from langchain_openai import OpenAIEmbeddings   
 
# 1. 从网络加载文档   
api_loader = RecursiveUrlLoader("https://docs.smith.langchain.com")   
raw_documents = api_loader.load()   
 
# 2. 将 HTML 转换为干净文本并分割为可管理的片段   
doc_transformer = Html2TextTransformer()   
transformed = doc_transformer.transform_documents(raw_documents)   
text_splitter = TokenTextSplitter(model_name="gpt-3.5-turbo", chunk_size=2000, chunk_overlap=200)   
documents = text_splitter.split_documents(transformed)   
 
# 3. 创建向量存储检索器   
embeddings = OpenAIEmbeddings()   
vectorstore = Chroma.from_documents(documents, embeddings)   
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

随后定义链的生成部分并组装完整的 RAG 管道:

from operator import itemgetter   
from langchain_core.output_parsers import StrOutputParser   
from langchain_core.prompts import ChatPromptTemplate   
 
# 定义发送给 LLM 的提示模板   
prompt = ChatPromptTemplate.from_messages(   
    [   
        (   
            "system",   
            "You are a helpful documentation Q&A assistant, trained to answer"   
            " questions from LangSmith's documentation."   
            " LangChain is a framework for building applications using large language models."   
            "\nThe current time is {time}.\n\nRelevant documents will be retrieved in the following messages.",   
        ),   
        ("system", "{context}"), # 检索文档的占位符   
        ("human", "{question}"),  # 用户问题的占位符   
    ]   
).partial(time=str(datetime.now()))   
 
# 初始化 LLM,使用大上下文窗口和低温度参数以获得更准确的响应   
model = ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0)   
 
# 定义生成链,将提示传递给模型再传递给输出解析器   
response_generator = prompt | model | StrOutputParser()

准备好数据集和 RAG 链后,可以执行评估。此次使用内置的"qa"评估器替代"exact_match"。该评估器使用 LLM 根据数据集中的参考答案对生成答案的正确性进行评分:

# 配置评估使用"qa"评估器,基于参考答案对"正确性"进行评分   
eval_config = RunEvalConfig(   
    evaluators=["qa"],   
)   
 
# 在数据集上运行 RAG 链并应用评估器   
client.run_on_dataset(   
    dataset_name=dataset_name,   
    llm_or_chain_factory=rag_chain,   
    evaluation=eval_config,   
    verbose=True,   
    project_metadata={"version": "1.0.0", "model": "gpt-3.5-turbo"},   
)

评估执行将触发测试运行,输出中的链接可用于在 LangSmith 仪表板中实时查看结果:

View the evaluation results for project 'witty-scythe-29' at:   
https://smith.langchain.com/o/your-org-id/datasets/some-dataset-uuid/compare?selectedSessions=some-session-uuid   
 
View all tests for Dataset Retrieval QA - LangSmith Docs at:   
https://smith.langchain.com/o/your-org-id/datasets/some-dataset-uuid   
[------------------------------------------------->] 5/5

运行完成后,LangSmith 仪表板提供结果分析界面。除了聚合分数外,更重要的是可以筛选失败案例进行调试。

通过筛选正确性分数为 0 的示例,可以隔离问题案例。例如,发现模型因检索到不相关文档而产生幻觉答案的情况。可以形成假设:"如果信息不在上下文中,模型需要明确被告知不要回答"。通过修改提示并重新运行评估来测试这一假设:

# 定义改进的提示模板   
prompt_v2 = ChatPromptTemplate.from_messages(   
    [   
        (   
            "system",   
            "You are a helpful documentation Q&A assistant, trained to answer"   
            " questions from LangSmith's documentation."   
            "\nThe current time is {time}.\n\nRelevant documents will be retrieved in the following messages.",   
        ),   
        ("system", "{context}"), 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值