技术

Agent 评测怎样形成闭环:从任务验收到运行证据与平台协作

从任务定义、运行证据与独立判分出发,讨论评测框架、平台、系统设计和版本回归如何组成可复查的闭环。

如果一个 Agent 把当前政策的两项事实都答对了,引用却指向了只描述审计功能的来源,这次回答算通过还是失败?

单看最终文字无法回答。还要知道 Agent 查过哪些资料,实际读到了什么,引用指向了哪份正文,评分依据来自哪里,以及这次运行能不能回到原始证据。评测要处理的正是这些回答之外的事实。

本文从一条知识库问答开始,沿着任务定义、运行记录、独立判分、评测框架、平台协作和版本回归展开。文中的业务材料使用虚构资料和代称;设计方案、工具试用和教学示例分别保留自己的证据范围。

阅读地图:先看完整评测链路

Agent 评测从一条任务开始。任务先要说明用户想要什么、允许使用哪些资源、什么结果才算完成;被测系统随后在目标环境中执行,留下回答、工具调用、来源片段、状态变化和耗时。评分器读取这些证据,分别判断事实、行为、交付和表达,再把分项结果汇总成任务结论。

结论生成后,工作还没有结束。开发者需要回到失败记录,判断问题发生在资料获取、上下文装配、模型决策、工具执行还是结果交付。确认过的失败案例会进入回归集,下一版系统再按相同条件运行。评测由此形成一条循环:定义任务,执行并取证,分项检查,汇总结果,定位原因,再把修复后的要求留在测试集中。

评测如何形成可分析的记录
评测如何形成可分析的记录

图中的每个节点都对应一种产物。题库保存任务,执行器保存运行,采集层保存证据,评分器保存判断,实验报告比较不同运行。平台可以帮助组织这些产物,但任务要求、参考答案和业务检查仍需由使用方定义。

1. Agent 评测到底在评什么

1.1 为什么最终答案不是全部

如果 Agent 只返回一段文字,最容易想到的评测方式是把它交给一个裁判,得到一个分数。这个分数可以作为线索,却很难独立说明任务是否完成。

例如,用户要求系统回答某项政策,并给出支持结论的来源。回答可能出现几种不同的问题:版本范围说对了,却漏掉授权条件;两个必要事实都出现了,引用却指向另一份文档;回答本身没有明显错误,但系统在执行过程中读取了不适用的旧资料;或者 Agent 没有完成交付,却因为文字写得完整而拿到较高的表达分数。

这些情况都需要不同的证据。回答文本可以检查事实是否出现,来源绑定可以检查引用是否支持相应陈述,工具事件可以说明系统实际查过什么,环境状态则能确认文件、记录或外部操作是否真的完成。把它们压成一个总分,开发者很难知道下一步应该修改哪个环节。

评测首先要确定自己支持哪一个决定。比较两个基础模型时,需要固定提示词、工具和执行条件;判断一个 Agent 产品能否完成用户任务时,需要记录整套系统配置;排查检索器或评分器时,则要固定它们的输入,单独观察组件行为。实验对象不同,应该保留的条件也不同。

评分器自身也需要验证。把几条已经人工确认的回答交给检查器,可以知道它是否能区分遗漏、错配和完整交付。这类实验验证的是评分逻辑。评价产品时,证据应来自产品的真实运行。两者可以使用同一份记录,但预期结果和结论不能混在一起。

1.2 任务结果、工具行为、过程证据和交付状态

Agent 的任务通常包含多个层面。最外层是用户是否拿到了需要的结果;往里一层,是系统是否按照允许的方式取得材料和执行操作;再往里,是这些判断能否由保存下来的证据复核。

可以先把评测对象分成四类:

评测对象要回答的问题常见证据
任务结果用户要求是否完成?最终回答、生成文件、环境状态
工具和行为Agent 是否正确使用了工具和权限?工具名、参数、返回值、调用顺序
过程证据结论是否建立在适用材料上?来源身份、版本、时间、实际上下文
执行条件结果是否受到环境或评测设施影响?配置、模型、预算、超时、异常、资源回收

这四类对象不必每次全部检查。一个只要求返回整数的任务,可能只需要结构和数值检查;一份研究报告则需要检查事实覆盖、证据整合、论证和结论边界;涉及写入或外部操作的任务,还要核对状态变化和授权先后。评测协议应把适用范围写清楚,避免用一套固定指标覆盖所有任务。

确定性检查适合处理能够明确计算或匹配的要求,例如数值、日期、单位、字段、调用次数和文件是否存在。语义检查适合判断摘要是否保留了必要信息、结论是否超出了资料范围、引用是否真正支持陈述。模型裁判和人工复核可以参与语义检查,但它们仍需要看到任务约束和实际证据。

效率指标也要放回任务结果中解释。多一次查询如果取得了必要资料,可能是合理成本;重复读取相同内容却没有改善交付,则值得排查。耗时下降也不能单独被当成改进,如果系统因为少读了一份必要材料而提前结束,任务失败和执行代价应同时呈现。

1.3 从一个具体任务看评测对象怎样变多

下面用一个虚构的知识库问答说明这件事。用户询问:“当前哪些版本支持离线部署,需要满足什么条件?请给出依据。”知识库中有一份当前政策、一份审计功能说明和一份已经废止的旧政策。当前政策说明只有企业版支持离线部署,并且需要单独购买授权;旧政策曾经允许团队版和企业版离线部署。

如果只看回答里有没有“企业版”三个字,系统可能把遗漏授权条件的回答判成通过。再检查引用 ID,可以确认回答确实引用了知识库中的某份材料,但还不知道那份材料是否支持部署结论。继续读取来源正文和生效状态,才能发现它引用的是审计功能说明,或者把旧政策当成了当前政策。

这个例子至少需要四项检查:必要事实是否完整,引用是否存在,引用内容是否支持已经写出的陈述,来源是否适用于题目要求的时间。四项检查共享一次运行产生的证据,但各自承担不同责任。回答缺少授权条件属于产品任务失败;评分侧没有保存来源片段,则属于证据不足,不能直接计入同一类失败。

因此,评测记录不能只保存最终答案和一个分数。它还要保留题目条件、系统实际收到的资料、工具返回、回答版本以及每项检查的证据位置。只有这些对象能够互相定位,失败才有机会沿着资料流和执行过程继续排查。

2. 从任务定义到可复查结论

2.1 用例、参考、运行环境和验收条件

一条可执行的用例至少要说明四件事:系统收到什么任务,运行时可以使用什么环境,评分依据从哪里来,哪些条件必须满足。把这些内容写在一起,容易在序列化或接入框架时误把评分标准送进 Agent 的输入。因此,任务条件和评分条件需要从一开始就分开。

仍然沿用前面的离线部署例子。用例可以保存用户问题、查询时点、可用工具和语料快照;评分侧另存必要事实、引用要求和旧政策的处理方式。Agent 需要知道自己要回答什么,以及可以到哪里查资料;它不需要提前看到参考答案中的两个事实。

id: policy_query_demo_001
input:
  question: 当前哪些版本支持离线部署,需要满足什么条件?请给出依据。
  as_of: 指定查询时点
environment:
  corpus_snapshot: policy_demo_v1
  tools: [search_documents, read_document]
acceptance:
  required_facts:
    - 当前支持离线部署的版本范围
    - 离线部署所需的授权条件
  citation_required: true
  citation_must_support_claim: true
  obsolete_policy_must_not_be_presented_as_current: true
evidence_required:
  - answer
  - sources
  - generation_contexts
  - tool_events

input 和 environment 描述执行条件,acceptance 描述判定条件,evidence_required 描述评分时必须留下的材料。它们可以放在同一份配置中,但发送请求、执行任务和判分时应按用途拆开。

独立参考也要绑定自己的适用范围。政策事实至少需要记录来源身份、版本或修订号、生效状态和适用时间。这样评分器才能判断一条回答是否引用了存在的来源,也才能判断这份来源是否支持当前问题。网页上出现“最新”或“支持”这样的词,并不能代替来源身份和时间条件。

用例还应该允许后续修订。业务规则变化时,新的验收版本要有自己的标识,旧运行仍然引用原来的规则。这样重新评分时,报告可以说明结果变化来自产品运行,还是来自判定标准的变化。

2.2 Run、Attempt、Turn、Trace、Dataset、Experiment

不同工具对这些词的定义并不完全相同。为了让全文保持一致,这里采用一组说明用的约定。

Case 是一条任务定义,包含输入、环境条件和验收要求。Dataset 是多条 Case 的集合,通常按任务类型、失败机制或使用阶段组织。Attempt 表示某个版本在一个 Case 上完成的一次尝试;一次 Attempt 可以包含多轮交互。Turn 是其中一轮输入、回答和相关事件。Run 在不同工具中既可能指一次完整尝试,也可能指一条运行记录,本文把它作为泛称,具体记录仍以项目自己的字段契约为准。

Trace 更关注运行过程。它可以包含模型请求、工具调用、检索、重试和返回事件,并通过父子关系或时间顺序还原执行路径。Experiment 则把一组 Case 和固定配置交给执行器,收集多次 Attempt,再汇总结果和版本差异。平台界面可能把一次 Attempt 也叫 Run,因此接入时要检查实际字段,而不能只按名称映射。

这些对象之间的关系可以这样理解:一条 Case 可以产生多个 Attempt;同一个 Attempt 可以留下多个 Turn 和一条 Trace;多个 Case 组成 Dataset;Experiment 选择 Dataset、版本和运行协议,最后生成一批可比较的结果。

同一条用例如何连接运行与评分记录
同一条用例如何连接运行与评分记录

用例条件进入执行端,独立参考留在评分端,运行标识把它们连接起来。固定 run_id 重新评分,改变的是测量方法;生成新的 run_id,才表示系统又执行了一次任务。这个区别决定了两种不同的实验:

  • 调整评分规则时,可以保留原始运行记录,使用新的规则重新判分;
  • 比较新旧 Agent 时,必须让两个版本分别执行任务,并保存各自的运行证据。

一条完整的运行记录通常还需要保存版本、模型条件、提示摘要、数据快照、会话标识、轮次、工具事件、回答版本、停止原因和资源信息。正文、事件和大段工具返回可以分开存储,统一记录只保留路径和摘要。评分结果仍然要能沿 case_id、attempt_id、turn_id 或 call_id 找回原始证据。

如果一次调用发生超时,已经收到的回答和工具事件仍然属于这次 Attempt。外层实验应记录它是完成、中断、未启动还是评测设施异常,不能只留下一个空结果。后续重跑也应生成新的尝试标识,原来的部分产物继续保留,便于判断失败发生在哪一段。

2.3 原始运行记录怎样保存

一次运行记录的作用,是让后来的人能够回答两个问题:系统当时做了什么,以及评分结果依据了哪一部分事实。只保存最终回答,通常只能看到结果,无法判断错误从哪里开始。只保存完整日志,又会让评分器和人工复核者难以找到与当前判定直接相关的片段。

因此,记录需要同时保存运行身份、过程事件和可交付产物。前面用到的 case_id 用来定位任务,attempt_id 用来区分同一任务的不同尝试,turn_id 用来区分多轮交互,call_id 用来关联一次调用的开始、结束和返回。父子调用关系可以用 parent_call_id 表达;异步事件晚到时,评分侧仍能根据这些标识把它放回所属尝试。

一次 Attempt 怎样留下可回查的运行记录
一次 Attempt 怎样留下可回查的运行记录

这张图只画对象和关系。真正的记录还要保留每个对象的内容和来源位置。可以把它分成五组:

记录部分至少需要知道什么用于回答什么问题
身份与版本用例、尝试、Agent、模型、规则和数据快照这次运行到底比较了什么?
输入与轮次每轮用户输入、限制、会话和回答版本Agent 在什么条件下做出这个回答?
工具与事件工具名、参数、返回值、开始结束时间、调用关系它实际查了什么、调用是否完成?
来源与上下文候选来源、读取结果、实际送入模型的文本模型真正看到了哪些材料?
结束与资源停止原因、超时、预算、成本、创建资源和清理结果任务是完成、失败还是被设施中断?

回答也需要按版本保存。流式输出过程中,用户可能已经看到了一个后来被修订的答案;summary_reset 或类似事件发生后,系统又开始生成新的正文。报告如果只保留最终答案,就无法判断系统是否曾经把错误内容展示给用户。至少要区分原始片段、首次完整回答和最终稳定答案,并说明评分采用哪一个版本。

工具事件应尽量保留原始输入和输出的定位信息。大段正文、截图或完整返回值可以放在单独文件中,主记录保存摘要、哈希或相对路径。这样既能减少统一记录的体积,也能让评分器在需要时回到原始内容。摘要不能代替原文,尤其是在检查引用、日期和权限条件时。

运行记录还要容纳不完整的尝试。启动失败时,记录目标环境和失败阶段;某一轮超时后,保存已经收到的回答和事件;远端停止成功或失败,也要留下对应结果。外层实验再把这次尝试标为完成、中断、未启动或评测设施异常。空白结果会掩盖失败发生的位置,后续重跑也无法判断前一次是否已经产生了部分副作用。

时间和资源信息要和业务结果分开保存。请求耗时、首个流式片段时间、模型用量、工具调用次数和总成本可以帮助解释版本差异,但它们不能单独决定任务是否通过。一个版本少调用一次工具,可能是因为检索更有效,也可能是因为它少读了必要资料。只有把这些指标和任务判定放在同一份实验记录中,才有机会继续追查。

2.4 独立参考和证据包怎样进入判分

评分时需要同时看到两类材料。独立参考说明“应当满足什么”,运行证据说明“这次实际发生了什么”。如果参考答案直接混入 Agent 输入,系统完成的可能只是复述;如果只有运行证据而没有独立参考,评分器只能判断文字是否连贯,无法确认任务要求是否满足。

独立参考不等于一段没有来源的标准答案。对于事实任务,它至少要绑定对象、指标、时间、单位、来源身份和适用状态;对于行为任务,它要说明允许的调用、禁止的操作和完成后的环境条件;对于研究或摘要任务,它需要列出必须保留的要点、证据关系和结论边界。参考本身也需要版本,规则变化时不能悄悄覆盖旧版本。

运行证据则来自一次真实尝试或一个明确标注的教学记录。它通常包括最终回答、回答版本、来源表、实际生成上下文、工具事件、外部状态和停止原因。候选来源不等于模型实际看到的内容,来源 ID 出现在记录中也不等于对应正文支持了回答。因此,证据包要把来源候选、读取结果和最终上下文区分开。

从参考和运行证据到任务状态
从参考和运行证据到任务状态

分项检查从不同角度读取同一份证据。以离线部署的教学案例为例,可以分别检查:

检查项参考条件运行证据检查结果可能说明什么
必要事实覆盖当前版本范围和授权条件回答正文回答是否漏掉用户要求的条件
引用 ID来源必须存在回答中的引用和来源表引用编号是否指向实际取得的来源
引用支持来源内容需要支持对应陈述来源正文和实际绑定片段引用是否只是存在,还是确实能支撑结论
时点适用性来源要符合题目时间来源状态、修订号和查询时点是否把历史政策写成当前政策
行为与交付工具、权限和交付条件工具事件、状态变化和最终产物Agent 是否按要求完成了过程和结果

同一份回答可能在不同检查中得到不同结果。回答 B 引用了存在的来源 S2,引用 ID 检查可以通过;如果 S2 只描述审计日志,而回答把它用来支持离线部署,引用支持检查仍然应该失败。回答 A 可能正确引用了 S1,却漏掉授权条件,事实覆盖检查失败,已写出的那部分引用支持仍然可以通过。把这些结果拆开保存,修复方向才不会被总分掩盖。

证据不足和产品失败也要分开。假设回答声称“某个日期范围内每天都有记录”,而评分侧只拿到总行数、最早日期和最晚日期。此时可以确认回答超出了现有证据,任务要求的证据检查应当失败;至于数据实际上是否逐日覆盖,仍然只能标为待核实。另一种情况是产品确实返回了逐日明细,但采集层漏存了工具结果,这属于证据不完整,不能直接归咎于 Agent。

每项检查应保留自己的 check_id、expected、observed、evidence_refs、状态和理由。evidence_refs 可以指向回答字段、事件 ID、来源片段或环境快照。评分理由应当能回到这些位置,人工复核者才能判断错误来自事实、绑定关系、时点还是采集过程。

评分器也需要一组固定的校准样例。校准样例不让产品重新运行,而是固定回答和证据,检查程序或模型裁判是否能复现人工预期。程序检查可以用已知的 PASS、FAIL 和边界输入验证;模型评分则需要人工标签、规则版本和评审配置。评分器的漏放、误杀、ERROR 和待核实样例应分别统计,不能把它们合并成一个平均分。

2.5 PASS、FAIL、REVIEW_REQUIRED 等状态怎样解释

分项检查需要比布尔值更多的状态。PASS 表示当前证据支持这项要求;FAIL 表示已经有足够证据确认要求被违反;INCONCLUSIVE 表示判断所需的材料缺失或范围不足;ERROR 表示评分器、采集设施或外部依赖发生异常。项目也可以把后两类映射为任务级的 REVIEW_REQUIRED 和 EVAL_ERROR,但映射关系要写进协议。

本文的教学聚合规则采用下面的顺序:

FAIL > ERROR > INCONCLUSIVE > PASS

只要一项必要要求已经确认失败,任务就不能因为其他检查通过而变成 PASS。没有失败时,如果评分或采集设施发生异常,任务进入错误处理;如果关键证据缺失,任务进入待复核;只有必要检查全部通过,任务才得到 PASS。这个顺序是当前案例的业务约定,其他项目可以使用不同的状态名称和优先级,但必须提前声明。

聚合前还要检查两类输入错误。没有任何检查结果的记录不能判为通过;出现协议没有定义的状态,也不能静默忽略。评分器应先报告接口或数据问题,汇总器再决定这次任务属于评测错误还是待复核。

任务状态和分项状态承担不同作用。任务状态适合回答“这次交付是否通过”,分项状态用于回答“哪项要求没有满足”。报告应保留完整的分项结果、证据位置和理由,即使聚合结果已经确定。这样可以看到一个任务为什么失败,也能在修改评分规则后对同一份运行重新判分。

任务失败和评测设施失败也要分开。例如,Agent 在预算内没有完成用户要求,属于产品任务失败;评分服务中断,但运行证据已经保存,属于评测错误,之后可以重新评分;来源采集不完整,导致引用无法核验,属于待复核。它们对产品质量和评测覆盖的影响不同,汇总时应分别计数。

对于包含多个必要条件的任务,可以使用下面的聚合逻辑:

def aggregate_required(statuses):
    if not statuses:
        raise ValueError("不能把没有检查的记录判为通过")
    allowed = {"PASS", "FAIL", "ERROR", "INCONCLUSIVE"}
    unknown = set(statuses) - allowed
    if unknown:
        raise ValueError(f"未知判定状态:{sorted(unknown)}")
    if "FAIL" in statuses:
        return "FAIL"
    if "ERROR" in statuses:
        return "ERROR"
    if "INCONCLUSIVE" in statuses:
        return "INCONCLUSIVE"
    return "PASS"

代码只负责执行已经确定的业务规则。它不能替团队决定哪些检查属于必要条件,也不能替代对证据的解释。用例需要声明必要检查,评分器保存每项原始结果,汇总器再按版本化规则生成任务状态。这样,规则变更、评分器重跑和产品版本重测都能保留各自的依据。

3. 评测框架与评测平台:同一份规格的不同工作入口

前面的任务定义和运行记录先于工具存在。应用需要先知道怎样调用 Agent,评分侧也需要先知道哪些证据必须保留。进入本章时,先不要把所有工具放进一张产品清单里,而要区分两个维度:评测从哪里开始,以及工具主要负责什么。

代码驱动和运行数据驱动描述的是评测入口。评测框架和评测平台描述的是职责边界。两组概念会交叉,但不能互相替代:一个平台可以承载评分器,一个框架也可以读取 Trace;这并不意味着它们的中心对象和工作方式相同。

3.1 先区分评测入口、职责和共同对象

3.1.1 两条评测入口:代码驱动与运行数据驱动

代码驱动的入口把 Agent、测试样本和评测逻辑放在代码仓库或配置附近。一次典型流程是:

代码驱动与运行数据驱动的两条评测入口
代码驱动与运行数据驱动的两条评测入口

它适合回答“这批固定任务在当前版本是否通过”“修改 Prompt 或工具定义后,回归结果有没有变化”。DeepEval、Promptfoo 和 Ragas 的主要使用方式都可以从这条入口理解。它的优点是启动快、规则和代码版本容易对应;它的局限是复杂运行过程的长期浏览、线上案例沉淀和多人复核通常需要额外的记录或平台能力。

运行数据驱动的入口从一次真实运行开始。Agent 可以继续运行在本地、测试环境或线上服务中,平台先接收过程记录,再围绕这些记录进行分析:

上图右侧把这条路径画成从 Agent Run 到 Trace、Dataset、Experiment 和 Feedback 的连续工作面。它不是一条只能按顺序执行的命令,而是围绕运行证据反复回看的分析路径。

它更适合回答“这次任务每一步发生了什么”“哪些真实失败值得加入下一轮回归”“不同版本的运行差异来自哪里”。Phoenix、Langfuse 和 LangSmith 更接近这条入口。它的代价是需要接入 Trace、维护平台工作区,并明确运行数据的存储、隐私和长期成本。

两条入口并不互斥。发布前可以用代码驱动的测试建立稳定门禁,运行数据驱动的平台则负责解释失败、积累真实样例和安排复核。本文后面把它们放在同一条评测链路中讨论,而不是把它们当成两个互相排斥的产品类别。

3.1.2 一次评测中的角色链

两条入口虽然不同,但都要经过几类职责。一次评测可以从任务规格开始,由执行器产生真实运行,再由业务检查器和评测框架完成判断,最后由评测平台保存和组织这些结果:

一次评测中的角色链
一次评测中的角色链

图中的上下方向表示事实和结果逐步产生,左右两条路径表示同一份运行记录进入不同的工作入口。业务检查器和评测框架负责形成判断,平台负责保存这些判断所依赖的运行与证据;它们最后共同回到任务结论和回归协作。

角色主要负责什么典型输入典型产物
任务规格或 Benchmark规定任务、环境、预算和验收条件用户问题、参考、约束和工具范围Case、Reference、Acceptance Rule
执行器或 Agent Harness调用被测 Agent,准备环境并收集实际运行Case、版本、环境和会话Run、Attempt、Turn、Trace、交付物
业务检查器判断数值、日期、权限、引用和状态等明确条件参考、运行记录和环境快照逐项状态、理由和证据位置
评测框架组织测试、Metric、Assertion 和回归执行Case、Answer、Context、Trace、ReferenceScore、标签、失败记录和回归结果
评测平台保存运行、维护数据集、比较实验和组织人工复核Trace、Dataset、Experiment、Score、Feedback可浏览的运行、实验对照和协作记录

Benchmark 或任务规格是评测的输入,不是和框架、平台并列的运行层。它规定“要测什么”,但不会自动产生一次真实运行。业务检查器也不是某个特定产品,它是规则的一部分,可以被独立脚本调用,也可以被框架或平台承载。

3.1.3 评测框架与评测平台分别解决什么问题

两者会出现相同的对象名称,也都可能显示分数,但中心工作不同:

比较问题评测框架评测平台
通常从哪里开始测试文件、Provider、Metric、Assertion 或实验函数Trace、Run、Dataset、Experiment 或工作区
核心问题规则怎样执行,结果怎样进入测试或 CI运行怎样保存,案例怎样积累,结果怎样复核
主要产物Score、Assertion、Test Result、回归结果Trace、Dataset、Experiment、Annotation、Feedback
主要使用者开发者和测试工程师开发者、评审者和业务协作者
主要风险输入字段映射错误,评分器口径不清Trace 不完整,分数存在但无法回到可靠证据

平台也可以配置 Evaluator,框架也可以保存运行记录,这属于能力交集。判断一个工具在本章应该放在哪一侧,主要看它的工作入口和中心对象:如果重点是编写测试、调用指标和检查回归,按框架理解;如果重点是接收运行、浏览 Trace、维护 Dataset、比较 Experiment 和安排复核,按平台理解。

3.1.4 同一份评测规格怎样在两类工具中流动

框架和平台最终仍然要围绕同一组对象工作。它们的名称可能不同,但含义需要保持一致:

统一对象在评测框架中的作用在评测平台中的作用
Dataset为测试脚本提供固定样本保存可复用案例、参考和元数据
Run / Trace提供指标读取的实际回答和过程证据保存一次完整运行及其步骤
Reference提供断言、Metric 或检查器所需的预期作为 Dataset Item 或人工复核依据
Metric / Evaluator定义按照什么标准判断读取 Trace 或 Dataset Run 后写回 Score
Score进入测试结果、阈值和回归报告关联到运行、实验、反馈和复核
Feedback记录失败原因或校准结果组织人工标注、争议处理和后续案例沉淀

同一个 Dataset 在代码框架中可能是 JSON、Python 列表或测试对象,在平台中则可能是带版本的数据集页面;同一个 Evaluator 在框架中可能是 Python 函数或 Metric,在平台中可能是配置后批量执行的评分器。接口名称可以改变,任务、运行、参考、判分和证据之间的关系不能改变。

评测入口与工具职责怎样连接到同一条链路
评测入口与工具职责怎样连接到同一条链路

这张图用于说明工具虽然分布在不同入口,但最终都要回到任务、运行证据和分项判定。后面的 3.2 先看规则怎样进入代码框架,3.3 再看运行怎样进入平台,3.4 用同一个案例说明两边怎样映射。

3.1.5 主要工具总览与本章阅读顺序

工具更接近的评测入口主要职责本章采用的材料形态
Promptfoo代码驱动Provider、Test、Assertion、回放和版本比较配置片段、回放图、结果解释
DeepEval代码驱动Test Case、Metric、Python 测试代码、指标流程图、评分理由
Ragas代码驱动数据集、指标和检索诊断指标图、字段表、边界样例
Phoenix运行数据驱动Trace、Dataset、Experiment 和评分本地界面截图、操作路径、验证记录
Langfuse运行数据驱动Trace、Score、Dataset、Experiment 和人工标注官方界面截图、对象关系、部署边界
LangSmith运行数据驱动Run、Thread、Dataset 和评测协作官方能力说明、对象关系和采用条件

这张表表达的是主要入口,不是绝对能力边界。Promptfoo 可以查看部分轨迹,Phoenix、Langfuse 和 LangSmith 也可以执行评分;这些交集会在各自小节中说明,但不会再改变“框架负责执行规则、平台负责组织运行”的主线。

统一评测规格怎样进入框架与平台
统一评测规格怎样进入框架与平台

这张图继续说明同一份评测规格如何进入两类工具:先由执行器产生一次运行记录,再由框架执行检查或指标,由平台保存 Trace、Dataset、Experiment 和反馈。两边可以组合,前提是评分结果仍然能回到同一次运行和原始证据。

3.2 评测框架:把评测规则写成可执行测试

评测框架接在统一运行记录和业务规则之间。它们提供不同的测试入口:有的从配置文件和 CLI 开始,有的从 Python 测试和 Metric 开始,有的从数据集与指标函数开始。下面分别沿每个工具最自然的使用方式展开。

3.2.1 Promptfoo:回放、断言和版本比较

Promptfoo 适合把一批问题、多个 Provider 或版本配置组织成可重复执行的测试。它可以通过 Provider 调用被测 Agent,也可以读取已经保存的输出,让评分器在不重新运行 Agent 的情况下重评历史结果。测试文件负责描述输入和变量,Assertion 负责表达格式、确定值、代码规则或模型辅助判断。

它的工程入口比较直接:配置测试题,选择调用方式,运行 CLI,再查看逐题结果。一个最小测试可以先检查 JSON 结构,再用 JavaScript 或 Python 按字段核对业务条件。contains 这类字符串检查适合做快速筛选,完整业务判定仍然要检查字段、单位、日期和对象关系。

Promptfoo 也可以接入轨迹。应用需要提供规范化的工具事件或 OpenTelemetry 数据,断言才能检查工具是否调用、参数是否符合、调用顺序是否满足任务约束。只看最终回答时,最多能确认结果文本;轨迹检查才能回答 Agent 实际查询了哪个对象、使用了什么日期范围,以及是否在授权之前执行了操作。

已有运行记录还可以通过 providerOutput 进入回放。这个入口适合调试评分规则和比较判定变化。它不能代表新版本已经重新执行任务;要比较两个 Agent 版本,仍然需要分别生成新的运行记录,并保存各自的配置、轨迹和异常。

多轮任务要把会话边界写清楚。每个版本应使用自己的会话,重复运行时重新建立初始状态。服务端自己维护历史时,适配器要传递会话标识;框架维护历史时,则要核对它实际发送给服务的消息。流式接口还需要确定何时取得终态,远端停止和会话清理是否成功也要进入运行记录。

Promptfoo 的结果页面方便查看哪道题发生了变化,但它的通过状态仍然取决于断言。业务层如果有 PASS、FAIL、INCONCLUSIVE 和 ERROR 等多种状态,需要把原始原因另存,不能只把所有非布尔结果压成一项失败。

从固定输出回放到真实版本对照

Promptfoo 的一个适合入门的路径,是先固定一份已有输出,只验证断言,再让 Provider 重新调用 Agent。两次运行看起来都在“执行评测”,实际回答的问题不同:固定输出实验检查评分规则,Provider 运行检查产品当前行为。

重新运行产品与重评已有输出,执行的是不同环节
重新运行产品与重评已有输出,执行的是不同环节

一个最小的固定输出测试可以只保留业务检查需要的字段:

providers:
  - echo

defaultTest:
  vars:
    question: 查询指定对象在指定区间内的记录数
    expected:
      item_code: A
      start: '2026-09-01'
      end: '2026-10-01'
      count: 35
  assert:
    - type: is-json
    - type: javascript
      value: |
        const actual = JSON.parse(output);
        const expected = context.vars.expected;
        return actual.item_code === expected.item_code
          && actual.start === expected.start
          && actual.end === expected.end
          && actual.count === expected.count;

is-json 只能确认输出结构,JavaScript 断言才检查对象、日期范围和数量之间的关系。输出中出现数字 35,不代表业务条件全部满足。实际接入时,Provider 还要返回 run_id、回答、来源和工具事件,方便失败断言回到第 2 章定义的运行记录。

真实版本对照还要确定重复、并发和缓存协议。缓存可以节省评分规则调试的重复执行;比较 Agent 稳定性时,则要确认目标服务和检索服务真的重新运行。重复次数、并发上限、会话重建和远端停止都应进入实验配置,不能只依赖 CLI 的默认值。

3.2.2 DeepEval:Python 测试、Metric 和模型评审

DeepEval 以 Python 测试和 Metric 为主要入口。应用先准备问题、回答、参考答案和上下文,再选择相应指标;单条记录可以先测量,批量样本则进入评测或测试流程。规则稳定后,检查可以接入 pytest,在应用修改后继续执行回归。

DeepEval 和评审模型的职责需要分开。框架负责组织测试记录、调用指标、保存结果并把判定接到测试流程;评审模型负责理解自然语言规则,判断回答是否满足标准。工具调用的名称、类型或参数仍然可以由代码检查,模型评分不应承担所有确定性工作。

常见指标对应不同问题:

评测要求可以使用的入口需要注意的边界
回答是否符合一组自然语言标准G-Eval评分依赖规则、输入字段和评审模型
回答是否得到给定资料支持Faithfulness必须提供实际上下文,分数不能代替来源身份检查
是否调用了预期工具Tool Correctness需要保存实际调用和预期调用,重试口径要先确定
任务是否在过程上完成Task Completion需要完整 Trace,外部状态还要单独核验

例如,某次查询返回 COUNT(*)=35,最早日期为 10 月 1 日,最晚日期为 10 月 26 日。回答写“这段时间每天都有记录”。数量和边界可以直接检查;逐日覆盖则需要日期明细。把这条要求写进 G-Eval 的评分步骤,可以让裁判指出证据缺口,但真实数据是否逐日覆盖仍要由查询或独立参考确认。

使用模型评审时,评分步骤应明确指出它能看到哪些字段,哪些结论需要什么证据。评分理由和原始分数都要保存。阈值也不能脱离校准样例单独决定:先准备人工确认的 PASS、FAIL 和边界记录,再观察模型裁判的漏放和误杀,最后再确定哪些维度进入任务通过条件。

DeepEval 可以接入 Trace 和 Span,进一步评价工具调用或任务完成过程。采集范围不足时,Task Completion 的结果只能说明评分器读到的那部分轨迹。应用接入时要先确认任务标识能够从测试记录回到运行证据,再扩大样本量。

模型与代码怎样共同生成指标分数
模型与代码怎样共同生成指标分数

DeepEval 的一次评分可以拆成四步:测试用例提供问题和实际输出,Metric 选择要读取的字段,评审模型处理需要理解语言的部分,框架再把分数和理由交给阈值或测试断言。代码检查可以在前后加入,例如先核对工具名和参数,再把回答与上下文交给模型评审。

一个最小的 G-Eval 结构可以这样理解:

case = LLMTestCase(
    input="查询指定时间范围内的记录,并说明日期覆盖情况。",
    actual_output="共 35 条,期间每天都有记录。",
    retrieval_context=[
        "查询返回 COUNT、最早日期和最晚日期,没有返回逐日明细。"
    ],
)

metric = GEval(
    name="证据充分性",
    evaluation_steps=[
        "检查回答中的数量和日期边界是否得到上下文支持。",
        "逐日覆盖需要日期集合或等价证据。",
        "如果回答超出证据范围,说明缺少哪一项证据。",
    ],
    evaluation_params=[
        SingleTurnParams.INPUT,
        SingleTurnParams.ACTUAL_OUTPUT,
        SingleTurnParams.RETRIEVAL_CONTEXT,
    ],
    threshold=0.8,
)

这段结构表达了评分器需要什么信息,但不能替代实际调用验证。threshold 也不能脱离校准集解释。应用需要保存评分模型、指标版本、规则文本、原始分数和理由;当阈值或评审模型变化时,旧记录才可以重新比较。

3.2.3 Ragas:检索上下文、回答依据和指标诊断

Ragas 更适合把检索材料、生成回答和参考答案拆成指标输入,观察检索与回答之间的关系。它可以评估上下文相关性、上下文排序、回答是否得到资料支持,也提供工具调用和 SQL 等方向的指标。不同指标读取的字段不同,接入前要先确认数据结构。

检索指标回答的是诊断问题。例如,某段资料排在前面还是后面,会影响 Context Precision;候选资料是否覆盖参考答案中的必要信息,会影响召回方向;回答中的陈述是否能从实际上下文推出,则属于支持性问题。这些结果可以帮助定位检索或上下文装配问题,任务是否通过仍由业务验收规则决定。

Ragas 的指标名称不能直接当作跨框架的统一量尺。不同版本、实现和评审模型可能使用不同的分母、陈述抽取方式和空值处理。某个指标得到 0.8,还需要结合样本、公式、阈值、参考和评审配置来解释。更换模型或指标版本后,应该用同一组校准样例重新比较。

一个常见边界是“回答看起来忠实”与“回答完成了任务”之间的差别。回答可以忠实地复述给定资料,却遗漏用户要求的一个事实;也可以完整覆盖要求,却引用了不适用的旧资料。Ragas 的指标可以提供支持性或检索质量的诊断,事实覆盖、时点适用性和引用对象仍需独立检查。

同一份资料,分别检查参考覆盖与回答支持
同一份资料,分别检查参考覆盖与回答支持

Ragas 的指标至少要先区分两个方向。一个方向从参考答案或必要事实出发,检查检索资料是否覆盖任务需要的内容;另一个方向从回答中的陈述出发,检查这些陈述是否能由实际上下文支持。两者都可能使用资料和回答,但问题不同,分数也不能互换。

排序指标还会受到上下文位置影响。相同数量的相关片段,如果相关片段被放在更靠后的位置,Context Precision 可能发生变化。这个结果可以帮助诊断重排和上下文装配,却不能单独证明最终回答质量。

相同片段数量,排序改变 Context Precision
相同片段数量,排序改变 Context Precision

使用 Ragas 时要把指标输入、参考、评审模型和空值行为一起记录。陈述抽取为空、没有有效参考或评分请求失败,都可能产生无法解释的结果。此类记录应保留为待核实或评分错误,不能和普通低分混在一起。

3.2.4 三个框架的共同字段与差异

三个框架都需要把任务、回答、参考、上下文和过程证据映射到自己的字段,但它们的主入口不同:Promptfoo 以 Provider、Test 和 Assertion 组织运行;DeepEval 以 Test Case 和 Metric 组织 Python 测试;Ragas 以评测样本和指标函数组织检索、回答及 Agent 过程诊断。

统一对象PromptfooDeepEvalRagas
任务输入vars、Prompt 或 Provider 入参input、对话消息或任务字段user_input、问题字段或消息列表
实际回答output 或 providerOutputactual_outputresponse 或回答字段
参考信息vars.expected、参考输出或外部断言expected_output、参考答案或自定义参数reference、参考答案或参考上下文
检索资料测试变量、轨迹或上下文断言retrieval_contextretrieved_contexts、上下文列表
过程证据Trace、工具轨迹和 trajectory assertionTrace、Span、工具字段工具调用消息、Agent 指标所需字段
典型结果Assertion 通过、失败及原因分数、阈值、理由和测试状态指标值、诊断字段和实验结果

字段名称相似并不代表语义完全相同。output 可能只是最终文本,retrieval_context 也可能只是适配器整理后的片段。接入时需要记录字段来源和装配过程,才能解释框架分数对应哪一份实际证据。

三个框架也不应该被强行放在同一条替代关系上。Promptfoo 更适合把版本、Provider、测试题和断言放进一条回归命令;DeepEval 更适合在 Python 测试体系里写语义指标和组件检查;Ragas 更适合围绕检索上下文、回答支持关系和 Agent 指标做诊断。一个项目可以选一个主入口,再把其他框架的指标作为补充,或者把同一份运行记录分别交给它们重评。

3.3 评测平台:把运行、数据集、实验和复核组织起来

评测平台的主要工作对象是运行和案例。它们通常把 Trace、Dataset、Experiment、Evaluator、Score 和人工反馈放在同一条工作流中:先观察一次运行,找到值得保留的失败,再把案例整理成数据集,用新的版本或评分器重跑和比较。

平台和代码框架的差异,首先体现在使用入口。代码框架从测试文件、Metric 或 Assertion 开始,开发者负责调用应用、准备评分输入和维护执行环境;平台从 Trace、Dataset 或 Experiment 开始,重点是保存运行、浏览过程、积累案例、安排评分和支持复核。二者可以组合,平台也可能提供 SDK 或托管评分,但它们解决的日常问题不同。

平台通常需要覆盖几类工作:

工作对象需要回答的问题常见产物
运行追踪一次任务经过了哪些模型、检索和工具步骤?Trace、Span、Observation、异常和耗时
数据集管理哪些失败案例值得长期保留?参考怎样随规则变化?Dataset、样例属性、参考答案和版本
实验对照新版本修复了什么,又造成了哪些退化?Experiment、逐条输出、分数和差异
自动评分评分器是否执行,分数和理由来自哪里?Score、Evaluator、执行状态和版本
人工复核争议案例如何判断,反馈如何回到回归集?Annotation、标签、说明和修正输出
配置与运维数据谁能访问,运行如何保存和导出?项目、权限、保留策略、部署和备份

这些工作对象彼此有关,但不能互相替代。Trace 存在只能说明有记录进入平台,不能证明工具返回和生成上下文完整;Dataset 有参考答案,也不能说明一次新运行真的使用了对应环境;Score 已保存,更不能直接说明评分已经覆盖目标记录。接入时要分别核对数据是否到达、评分是否执行、结果是否关联以及人工复核是否完成。

3.3.1 Phoenix:以标准化追踪连接诊断、数据集和实验

Phoenix 的重心是把应用运行表达成可浏览的 Trace 和 Span,再把运行记录接到数据集、实验和评分。它使用 OpenTelemetry 与 OpenInference 相关的追踪方式,适合从模型调用、检索和工具执行的位置采集结构化事件。已有 Agent 可以继续使用自己的执行入口,再通过埋点或集成把记录发送给 Phoenix 服务。

Phoenix 项目列表与导航
Phoenix 项目列表与导航

Phoenix 的界面入口适合按照一次试用路径来理解:先进入项目,再打开上一条 Trace,随后查看 Dataset 中的样例,最后进入 Experiment 比较 baseline 和 candidate。截图可以帮助读者认出对象,但每个对象的业务含义仍要回到第 2 章的记录定义。

它更适合回答“这次运行具体经过了什么步骤”和“这条失败怎样进入下一轮实验”。开发者可以先在 Trace 中查看模型和工具的输入输出,再挑选运行记录建立 Dataset,随后对照不同版本的 Experiment。评分可以在自有实验程序中执行,也可以使用平台提供的评分路径;两种方式的触发条件、字段映射和结果写回位置需要分别验证。

本地试用时,一个小型规则 Agent 就能展示这条关系:三条输入组成 Dataset,baseline 和 candidate 分别生成一组运行,评分器把答案是否精确匹配写回 Experiment。这个例子可以说明页面怎样组织逐条比较,也能暴露评分触发的问题。界面评分器已经配置成功,并不代表后续 SDK 实验已经自动使用它;已有实验显示空分数时,要先核对评分是否真正执行,再讨论结果质量。

Phoenix 的本地示例支持 Trace、Dataset、Experiment 和代码重评分这些能力。示例 Agent、数据和评分规则都是教学材料,不能推导真实模型的评测质量。共享部署还需要补充持久化、容量、权限、备份和跨进程追踪等条件。OpenTelemetry 提供通用追踪协议,业务字段和平台数据模型之间仍然需要适配。

Phoenix SDK 重评分后的实验对照
Phoenix SDK 重评分后的实验对照

本地试用中的一个细节值得保留:界面评分器已经保存并通过单条测试,不代表 SDK 创建的实验已经自动得到这个评分。实验页面出现空分数时,需要区分“评分器没有配置”“评分没有执行”“评分结果没有关联”三种情况。这个例子比单纯展示一个通过分数更能说明平台接入时要核对的状态。

3.3.2 Langfuse:把观测、提示词、实验和人工复核放在同一工作区

Langfuse 的工作对象包括 Trace、Observation、Session、Prompt、Dataset、Experiment、Score 和 Annotation Queue。Trace 表示一次运行,Observation 表示其中的模型、工具或程序步骤,Session 可以关联连续交互;Dataset 和 Experiment 则把运行记录转成可重复的测试对象。

Langfuse 官方示例项目首页
Langfuse 官方示例项目首页

这张图适合放在 Langfuse 小节的开头,因为它展示的是工作区形态,而不是一次业务评分结果。页面上的 Trace、Observation、Score 和费用统计属于官方示例项目,读者需要把它们理解成平台对象和界面入口,不能把截图中的数量当作当前 Agent 的实验成绩。

它的特点是把应用观测和评测协作连接得比较紧。线上运行中发现一个回答遗漏条件,可以把输入、参考信息和元数据整理成 Dataset;新的版本执行 Experiment 后,平台展示逐条输出和评分;争议记录进入 Annotation Queue,由业务人员补充判断、说明或修正输出。人工评分和模型裁判的结果也可以并列比较,用来发现评分器的误判。

Langfuse 同时提供 SDK 评分和平台托管评分。SDK 评分在调用者自己的进程中执行,适合依赖内部代码、业务数据库或特殊运行环境的检查;托管评分由平台后台处理,适合集中配置规则和对已有运行进行评估。两条路径在依赖、数据选择、抽样、触发和失败处理方面不同,不能因为界面里存在一个评分器,就认为目标实验已经完成评分。

自托管部署还涉及 Web、Worker、事务数据库、分析数据库、队列缓存和对象存储等组件。一个官方示例项目可以帮助理解页面入口和对象关系,不能直接说明团队的部署成本、权限方案或数据保留策略。接入现有 Agent 时,执行器仍然负责环境启动、会话控制和进程清理,Langfuse 负责记录、展示和复核;如果展示用工具结果被裁剪,就需要补充内部采集,才能判断模型实际使用了哪些资料。

3.3.3 LangSmith:围绕 Agent 调试、多轮运行和评测协作

LangSmith 的主要对象包括 Trace 或 Run、Thread、Dataset、Experiment、Evaluator 和人工反馈。它适合把多轮 Agent 调试、工具步骤和版本实验放在同一套工作流中,尤其适合已经使用相关 Agent 编排生态的团队。

它与 Phoenix、Langfuse 的共同点是都需要完整运行证据,并支持从运行记录积累案例、执行实验和关联评分。差异更多体现在生态连接、数据模型、界面操作和部署条件。选择时要看现有 Agent 的追踪方式、是否需要多轮会话分析、人工复核怎样参与,以及团队能否接受相应的平台服务和权限管理。

三个平台可以用同一组问题比较:

比较维度PhoenixLangfuseLangSmith
运行证据追踪标准和 AI 语义属性Trace、Observation、SessionTrace、Run、Thread
案例和实验Dataset、Experiment、评分和标注Dataset、Experiment、Evaluator、Annotation QueueDataset、Experiment、人工和模型评测
更适合先观察的方向追踪标准、组件步骤和本地实验观测、提示词、评分和人工复核Agent 调试、多轮运行和生态集成
需要重点核对埋点完整性、评分触发和自托管托管评分范围、队列和部署组件运行模型、生态接入和协作权限

这张表只描述工作重心,不能替代版本和部署核对。平台之间的功能名称相近,实际输入字段、评分触发、实验重复方式和数据保存路径仍可能不同。

平台的价值取决于它能否把运行证据保留下来,并让团队回到具体失败。工具调用没有关联,数据集没有可靠参考,或者环境状态没有快照时,页面上的分数也无法说明业务任务是否完成。平台负责组织证据,任务要求、独立参考和必要条件仍由业务方定义。

3.3.4 三个平台的工作重心和采用条件

Phoenix、Langfuse 和 LangSmith 都可以保存运行、数据集、实验和评分,但它们在评测闭环中承担的重点不同。平台不是把一次运行变成一个分数就结束了,真正有用的路径是把运行中的问题沉淀成案例,再用案例验证后续改动。

平台怎样承接一次持续评测
平台怎样承接一次持续评测

一条平台侧的评测闭环通常从 Trace 开始。开发者先看一次任务经过了哪些模型、检索和工具步骤,再判断这条记录是否值得进入 Dataset。Dataset 保存输入、参考、标签和其他元数据;Experiment 让不同版本在同一批案例上运行;Evaluator 或 Annotation 为每条结果补充分数、状态和说明。确认过的失败案例再回到 Dataset,成为后续回归的一部分。

这条路径中有几处需要单独核对。Trace 已经进入平台,不能说明工具返回和生成上下文都完整;Dataset 已经创建,不能说明参考答案适用于当前时间和业务条件;Experiment 已经结束,不能说明评分器已经成功执行;Score 已经显示,也不能说明所有目标运行都被评分。平台对象的存在、评分任务的执行和业务结论的可靠性是三个不同问题。

Phoenix 的重点是沿追踪记录分析运行步骤,再把这些运行接到 Dataset、Experiment 和评分。它适合帮助开发者回答“错误发生在哪一步”和“这条失败如何进入下一轮实验”。本地试用可以从项目、Trace、Dataset、Experiment 和代码重评分逐层观察这条路径。

Langfuse 更适合把观测、提示词、评分和人工复核放在同一个工作区。Trace 和 Observation 说明发生了什么,Score 说明某个评价已经产生,Annotation Queue 则让业务人员处理争议案例。它的价值在于把线上发现的问题转成可复用的案例,再回到 Dataset 和 Experiment。

LangSmith 的重点更接近 Agent 调试、多轮 Thread 和评测协作。它适合已经需要沿多轮运行查看工具步骤、保存失败样例并安排后续复核的团队。实际采用时需要核对生态接入、会话模型、权限和部署条件。

三个平台可以用下面几个问题比较:

问题PhoenixLangfuseLangSmith
如何看一次运行Trace、Span 和 AI 调用属性Trace、Observation、SessionRun、Thread 和多轮步骤
如何积累案例从运行记录建立 Dataset从观测和反馈维护 Dataset从 Run 和人工反馈维护 Dataset
如何做版本实验Dataset、Experiment 和评分Dataset、Experiment、ScoreDataset、Experiment 和 Evaluator
如何处理争议标注和评分结果Annotation Queue、人工评分和修正输出人工反馈、成对评价和协作复核
首要核对项追踪完整性、评分触发、自托管托管评分范围、队列、部署组件多轮运行、生态接入、权限模型

因此,3.3 的三个平台小节保留各自的叙述重点,3.3.4 负责解释共同闭环和采用条件。平台界面的分数只能说明平台记录了某项结果,不能替代对运行证据和业务参考的检查。

3.4 同一份评测规格怎样进入框架和平台

继续使用第 1、2 章的虚构政策案例。用户问当前哪些版本支持离线部署、需要什么条件,并要求给出依据。知识库有现行政策 S1、无关的审计说明 S2、已废止的旧政策 S0。现行政策同时要求答出版本范围和单独购买授权。这个任务能把几个常被混在一起的判断放到同一次运行里:回答是否完整,引用是否支持陈述,旧政策是否被当成现行政策,系统又是怎样取得这些材料的。

假设被测 Agent 给出回答 B:“当前仅企业版支持离线部署,需单独购买部署授权。[S2]”它说对了两项事实,却引用了审计说明。下面不再逐个介绍工具,而是沿这一次尝试看任务、证据、检查结果和平台对象怎样衔接。文中记录与输出均为教学设定,不能当作某个产品的实测成绩。

一次任务怎样从规格走到评测报告
一次任务怎样从规格走到评测报告

图中把主线画成“任务规格→一次尝试→多种检查→任务报告”。它提供阅读方向,具体哪些输入可供 Agent 使用、哪些证据只供评分器读取,要在下面逐层展开。

3.4.1 任务、运行、参考和证据怎样映射

执行器从用例中取出用户问题、查询时点、可用工具和语料快照,交给被测 Agent。评分侧另外保存两项必要事实、引用规则,以及 S0、S1、S2 的来源身份和适用状态。执行器可以从同一份用例配置读取两组信息,但向 Agent 发出的请求只含完成任务所需的条件。

一次尝试应保存 case_id 和 attempt_id,以及实际使用的 Agent 配置、知识库快照和开始结束时间。搜索命中 S1 不等于模型读到了 S1 的政策全文;采集层还需要保存文档读取结果、送入生成器的片段、工具调用的参数与返回,以及用户看到的回答版本。这样回答 B 的引用错误可以沿 S2 找到对应文档,也能检查 S1 是没有被检索到,还是在装配上下文时被丢掉。

三类对象可以分别保存:

对象保存什么可以进入哪里
任务规格用户问题、查询时点、可用工具、环境和预算执行器;必要部分进入 Agent 输入
独立参考两项必要事实、政策有效期、引用与聚合规则评分侧和人工复核
运行记录回答 B、来源片段、实际上下文、工具事件和停止状态逐项检查、框架评分、平台实验

回答 B 在三种记录中扮演不同角色:它是运行记录里的交付内容,是评分器要判断的观察值,也是平台 Trace 可以展示的输出。S1 的当前政策是参考事实;S2 的审计说明是本次引用的证据。把 actual_output、response 或 output 映射到回答 B 时,还应明确使用首次回答还是最终稳定版本。框架字段名称可以改变,这几种事实之间的关系不能随映射改变。

运行证据保持同一含义,框架参数按接口映射
运行证据保持同一含义,框架参数按接口映射

图中用字段名展示这种映射。它只是接口示意,实际接入仍要核对当前版本的指标读取了哪些字段,以及 generation_contexts 中保存的是候选片段还是最终输入。

3.4.2 同一个案例在不同工具中的输入

先由业务检查器处理回答 B 中能够明确判定的部分:引用 ID S2 确实存在,返回 PASS;回答包含版本范围和购买授权两项必要事实,事实覆盖也可判 PASS。接下来检查引用绑定的内容,S2 只说明审计功能,无法支持离线部署结论,因此引用支持判 FAIL。如果 Agent 把 S0 当成当前政策,还应另作时点适用性检查。分项并列保存,任务结论因必要的引用支持失败而为 FAIL。

这时不同框架读取的是同一次尝试,不同字段的作用则由指标决定:

入口从回答 B 的运行记录读取什么这次可以回答的问题
业务检查器答案、来源 ID、S2 正文和政策参考必要事实是否齐全,引用是否支持陈述
Promptfoo测试输入、Provider 输出、断言和可用的轨迹固定输出重评或重新运行后,相关断言是否改变
DeepEvalinput、actual_output、所选 Metric 需要的参考和上下文模型评审对事实覆盖或证据支持给出什么分数与理由
Ragasuser_input、response、实际 retrieved_contexts,必要时加 reference回答是否得到给定上下文支持,检索资料是否覆盖参考
评测平台Trace、案例、实验和已产生的 ScoreB 由哪次运行产生,后续版本是否修复,评分和复核是否完成

Promptfoo 有两条接法。把回答 B 作为已保存输出交给 Assertion,可以检验新规则是否继续识别引用错配;通过 Provider 再调用 Agent,才是在测试新版本是否会重新选用 S1。结果页可以并排展示两次判定,但要让每行结果都能指回原来的 run_id。如果断言只返回布尔值,引用不存在、引用内容不支持、评分缺少来源这三种原因仍应在业务记录中分开。

DeepEval 的 G-Eval 可以读取问题、回答和评分标准,判断回答是否覆盖“版本范围”和“购买授权”;另一项证据支持检查需要实际来源片段。如果只把 S1 的正确政策文本作为 retrieval_context 传入,裁判可能认为回答 B 的事实有依据,却根本看不到 B 实际绑定的是 S2。逐句引用支持必须把引用关系和来源身份一起提供,或继续交给业务检查器。Metric 的分数和理由可作为诊断项,是否进入任务通过条件取决于校准后的用例规则。

Ragas 可以把问题、回答和实际检索上下文整理成样本。Faithfulness 关注回答中的陈述能否从给定上下文推出;检索相关指标则检查资料的覆盖和排序。若评分输入把候选来源和最终送入模型的上下文混为一谈,结果就无法定位资料丢失发生在哪一步。即使 S1 在候选中,回答 B 的引用仍可能错配;对应引用的判定需要读取回答与 S2 的实际绑定关系。

平台部分承担另一种工作。Phoenix、Langfuse 或 LangSmith 可以保存这次运行的 Trace、关联案例与实验,并展示后续分数和人工反馈。它们无需同时安装:在本例中选用一个平台,就足以把失败记录变成回归样例。Phoenix 本地试用中的评分器“已配置但实验未评分”说明还要核对评分触发;Langfuse 的 Score 和 Annotation 需要对应正确的 Trace;LangSmith 的多轮 Thread 也要能找到其中产生回答 B 的具体运行。平台对象的名字不同,业务检查依旧指向同一次尝试。

3.4.3 评分结果怎样回到统一运行记录

每项评分都应关联 case_id、run_id、规则或指标版本、评分器身份、状态、分数、理由和证据位置。回答 B 可以得到这样一组分项结论:事实覆盖 PASS,引用 ID 存在 PASS,引用支持 FAIL,时点适用性 PASS。这个例子里的分项状态是按 S1、S2 的教学设定作出的预期判定,不是某个框架的实际评分结果。

以引用支持这一项为例,统一评分记录可以保存:

{
  "case_id": "policy_query_demo_001",
  "run_id": "run_demo_01",
  "grader_id": "citation_support_v1",
  "status": "FAIL",
  "score": null,
  "reason": "回答中的引用存在,但没有支持对应的部署条件。",
  "evidence_refs": ["$.answer", "source:S2"]
}

source:S2 指向本次来源表中的审计说明,$.answer 指向回答 B。审计者沿这两个位置就能复核“回答引用了一份存在但不支持结论的来源”。如果某个模型指标另外给出一个较高的支持性分数,也应保留它读取的上下文和评分理由,再检查它评的是“整段回答是否有依据”,还是“[S2] 是否支持对应陈述”。

框架结果可以保存为外部评分记录,再关联回运行;平台评分可以写入平台对象,但业务报告仍应保留原始记录的位置和聚合规则。报告至少要让读者看出三种变化:同一运行换了评分规则,新的 Agent 产生了新的运行,或者平台重新展示了已经保存的结果。

固定 run_id 重新评分,主要改变测量方法;生成新的 run_id,才表示产品又执行了一次任务。这个区别需要同时传递到框架结果、平台 Experiment 和最终报告。

假设开发者修复了引用绑定,下一版回答同样两项事实,却改为引用 S1。要验证修复,就按相同的语料快照、任务输入和规则生成新的 Attempt,比较 B 与新回答的逐项结果。若只在旧 run_id 上修改引用评分器,看到的则是规则变化对旧行为的重新解释,不能说明 Agent 已经学会引用 S1。

报告还要区分“这次结果怎样”和“这条规则是否可靠”。版本实验比较旧版和新版的真实运行;评分器校准把固定的 A、B、C 回答交给检查器,观察它是否抓住遗漏、错配和正确引用。两类结果可以同时进入平台,但应分别统计。

3.4.4 框架和平台怎样组合

回答 B 最先需要的是可回查的来源身份,以及一个能指出 [S2] 错配的检查。执行器保存记录,业务检查器给出逐项结果,已经可以形成一条小型回归。团队如果希望每次改动都重跑这批题,再由 Promptfoo 的 Provider 和 Test 组织版本对照;如果题目扩大到自由文本报告,DeepEval 的语义标准可以参与评分;当争议集中在检索覆盖或上下文排序时,再用 Ragas 指标定位。Phoenix、Langfuse 或 LangSmith 可以接收同一运行的 Trace,帮助团队查看过程、积累 Dataset 和复核结果。

在这条组合里,各层的产物有清楚的去向。业务检查器的引用支持 FAIL 直接参与任务判定;DeepEval 或 Ragas 的诊断分数先作为观察信息,经过人工校准和用例声明后,才可能成为必要检查;平台的 Trace 和 Score 则为复核提供入口。确认了 B 的失败机制后,团队把“事实完整、引用错配”的输入与参考加入回归集。下一版重新执行时,新的 run_id 与旧版并列,报告展示修复是否出现,同时保留耗时、调用数和新增退化。

这里不要求一个项目同时接入所有框架和平台。最小可用组合可以只有执行器、统一记录、业务检查和一份结果表。增加任何工具,都应指出它让哪一项判断更可靠,或者让哪一段证据更容易回查。接入顺序和取舍在 3.5 结合不同项目条件继续讨论。

3.5 工具组合的选择和证据边界

3.5.1 哪些问题适合代码检查

回答 B 的引用 ID 检查可以由代码完成:从回答提取 [S2],在本次来源表中找到 S2,再确认它对应的文本和修订号。若任务要求文件交付,也可以读取文件是否存在、格式是否有效、内容是否与任务对象对应。数值、日期、单位、工具参数和环境前后状态同样适合用程序核对,但都需要先有明确的参考与比较口径。

代码检查的边界随输入而变。检查器发现 [S2] 存在,说明的是引用标识有效;要判断 S2 是否支持“离线部署需购买授权”,还要比较陈述和来源内容。若政策已结构化存为可核对的事实,程序也可以检查这种关系;若只有自由文本,就可能需要模型或人工读懂含义。选择检查方法取决于证据形态,而不取决于工具名。

3.5.2 哪些问题需要模型评审

当任务要求摘要保留关键要点,或研究报告解释资料之间的关系,固定字段检查就不够了。模型评审可以读取任务要求、参考要点、实际回答和相关证据,给出逐维判断与理由。回答 B 的引用支持也可以交给模型辅助判断,但评分输入必须同时带上 B 的陈述、它绑定的 S2 片段,以及当前政策的适用时点。只给模型一段看起来正确的 S1,无法检验 B 的引用关系。

模型评审需要先在人工确认的样例上校准。用 A(遗漏条件)、B(错配引用)、C(内容与引用均完整)测试时,每条样例都应为对应检查项单独标注预期:B 的“引用 ID 存在”应为 PASS,“引用支持”应为 FAIL。若裁判把两个要求混为一个分数,调整提示、输入字段或拆分指标之后再复测。阈值附近的分数还要检查重复请求的波动,不能凭一次返回就给出稳定性结论。

3.5.3 哪些问题需要平台追踪和人工复核

假如 B 的错误来自搜索阶段只返回了 S2,处理方式会指向检索;如果 S1 和 S2 都进入候选,生成输入却只留下 S2,则要检查读取或装配;若模型同时看到 S1 和 S2,却仍把答案绑定到 S2,则需要看生成和引用组织。平台中的 Trace 可以把这些阶段放在同一次运行下查看,前提是应用确实记录了候选、读取结果和最终上下文。一个只含最终回答的 Trace,不能帮助定位资料在哪里丢失。

平台还适合处理“这条失败之后怎么办”。团队可以把 B 的输入、来源快照和人工确认的预期整理为 Dataset,重跑候选版本,再看逐条实验差异。若自动裁判认为 B 的引用合理,而业务复核者认为错配,人工反馈应记录争议理由,并用于校准检查器。平台可以组织这条工作流;业务判断需要由读得懂任务和来源的人给出。

3.5.4 哪些能力不能从工具分数直接推出

在这个案例里,Promptfoo 的 JSON 断言通过,只说明输出可解析;DeepEval 的事实覆盖高分,只说明它在给定规则和输入下认为两项事实被表达;Ragas 的 Faithfulness 高分,可能说明回答能从输入上下文推出。若引用的来源实际是 S2,任务仍然可能失败。平台展示的 Score 数量也不能说明所有运行都已经完成评分,Phoenix 的本地试用就出现过“评分器已配置、实验却未评分”的情况。

把这些结果放进报告时,应该同时写出各项分数评的是什么、它读到了什么证据、哪些项目直接决定任务通过。代码检查证明当前规则在当前输入上满足;模型评分说明某套评审配置如何判断给定文本;平台记录说明运行、实验和反馈怎样被组织。产品质量结论还需要题库覆盖、运行协议、分母、异常和人工复核共同支撑。

3.5.5 如何安排工具接入顺序

若团队已经有执行器和题库,只缺少固定条件的版本回归,可以先让业务检查器产出逐项结果,再用 Promptfoo 或现有测试命令批量运行。此时接入一个可视化平台,可能让报告更易浏览,却不会自动补齐缺失的独立参考。若团队已经保存大量运行,却难以定位工具和资料流转中的问题,应先检查 Trace 的埋点位置,再选择能够承接这些记录的平台。追踪数据本身不足时,更换平台也看不到未采集的步骤。

需要模型评审时,先拿少量带人工预期的记录校准,再决定将 DeepEval 或其他模型指标放在什么位置。需要诊断检索时,Ragas 可以读取实际上下文与参考,帮助区分“没有找到材料”和“找到材料却没有用好”。这两类指标可以和业务检查并列,只有规则稳定、漏放与误杀经过检查后,才适合参与发布门槛。

对回答 B,最初的组合可以只有运行记录、来源表和引用支持检查;要比较修复版本,再加入固定任务回归;团队需要积累线上失败、比较实验或安排人工复核时,再接平台。每一步都复用同一份 case_id、run_id 和证据位置。增加工具的目的应当是解决一项已经遇到的问题,并留下能证明该工具确实承担了这项工作的记录。

工具的接口和能力会随版本变化,具体配置与采用条件应查看附录 E:资料来源和证据审计中的官方入口;本文的教学例子、Phoenix 本地试用和平台资料说明仍各自保留原来的证据范围。

4. 一个可复查的 Agent 评测系统怎样运转

虚构的知识库里,S1 是现行部署政策,S2 只介绍审计功能,S0 是已废止的旧政策。用户问当前哪些版本支持离线部署、还需要什么条件。Agent 回答了正确的版本和授权条件,却在句尾标了 [S2]。读者看到的是一句话;评测系统需要找回这句话产生时的资料、调用和回答版本,才知道错在何处。

假如过了一周才发现引用检查器漏判,系统最好还能拿这次回答重新评分。假如开发者修复了 Agent 的引用方式,就要让新版重新完成任务。这两件事都可能改变报告,却依赖不同的记录。第四章沿这次虚构尝试讨论执行、取证、判分与归档怎样衔接。这里提炼的是设计底稿中的系统要求,完整执行器和自动判分仍待实现及接入验证。

4.1 执行、评分和报告各有入口

执行器第一次看到这道题时,必须知道用户的问题、可用的知识库、工具和运行时限。它准备环境,向 Agent 发题,记录搜索、阅读、生成和停止的过程。执行结束后,它交出一份运行档案。档案保存的是实际发生的事,不先替评分器认定 [S2] 对不对。

执行、评分与报告从同一份运行档案衔接
执行、评分与报告从同一份运行档案衔接

放大查看执行与评分图

评分器在另一侧读取这份档案,以及事先独立准备的政策参考。它发现回答覆盖了两项必要事实,引用 ID 也确实存在;再读 S2 正文,才能判定这份引用无法支持部署条件。评分器可以在 Agent 停止后运行,因而能在不重新调用产品的情况下测试新的评分规则。它无法判断当时没被记录下来的工具结果。

这两项工作在设计上有不同的入口。下面的名称只表示职责,不声称现有产品已提供这些 API:

execute(执行计划, 待测配置) → 执行台账 + 运行记录集合
score(评分方案, 执行台账) → 判分记录集合 + 评分批次

执行计划和评分方案都是输入数据。计划说明要运行哪些用例和目标;评分方案说明哪些检查适用、参考是什么、怎样汇总。两者可以从同一套业务题库生成,但独立参考只送往评分侧。若把“只有企业版支持、需另购授权”当作提示词发给 Agent,这道题就失去了检验资料获取能力的意义。

报告读取的范围又比评分器宽一些。它要从完整计划台账看到哪些任务原本安排了、哪些实际开始了、哪些因环境问题没有运行;再结合判分记录解释通过、失败与未决。一个框架页面里的 pass 无法独自说明这些情况。

不同故障也会留在不同位置:Agent 读取 S1 时遭遇工具错误,属于被测运行;S1 已返回但归档器漏存,是取证错误;独立评审服务读取档案后超时,则属于评分错误。后面分别讨论这三层怎样保存自己的状态。运行和评分还各有版本身份:前者记录实际 Agent、提示、工具定义与环境,后者记录检查器、参考、裁判配置及所读档案修订。报告把它们同时列出来,读者才能解释一次分数变化来自哪里。

4.2 从执行计划到一次真实尝试

执行计划写着:用这道政策题测试某个 Agent 配置,并按计划重复运行。执行器先把计划展开,逐项分配尝试标识。此时还没有向 Agent 发题,但完整台账已经存在。后来若有一项因为环境准备失败而没有开始,它依然在计划里;报告的分母由这份台账确定。

启动前核对计划与实际环境

计划中的配置说明候选版本应当加载哪份工具定义。服务启动以后,执行器再记录它实际加载的代码和工具。若两者对不上,后续回答即使正确,也不能算作声明配置的成绩。这就是待测配置与环境回执的分工:前者是意图,后者是启动后的事实。

回执还应保存有效提示、可见的模型配置、资料快照、运行目录和就绪情况。模型服务若只提供别名,执行器只能记录这个别名和已知请求参数,底层版本保持未知。写一个看似确定的版本号,会让后面的对照报告虚构出它并没有掌握的条件。

预检还要看题目能否按声明范围执行。若 S1 政策快照没有加载,Agent 无法在这份固定资料上完成“当前政策”题;若工具列表与计划不同,它可选择的动作也发生了变化。这些情况先写入准备结果,再决定任务是否 BLOCKED。连通性探测和预热可帮助发现问题,但它们有独立用途,不进入正式尝试分母。进行新旧版本对照时,两个目标都就绪后再开始正式运行,具体交错顺序留给第五章。

一次任务尝试的执行与中断分支
一次任务尝试的执行与中断分支

放大查看尝试生命周期图

请求发出后保存过程与收口事实

环境就绪后,执行器建立会话,把政策问题发给 Agent。若这道任务还包含“旧政策以前怎样”的追问,后续轮次继续使用同一会话;下一次独立尝试再创建新会话。这样可以分开对话历史,却还没有隔离共享缓存、搜索索引或外部数据。

例如,前一次尝试读了 S0,并把摘要写入一个共享缓存。即使下一次换了 session_id,Agent 仍可能读到旧摘要。执行器需要恢复相关环境,或者在回执中说明这些状态仍然共享。涉及真实写入的任务还要保存操作前后状态。只有看到新会话标识,无法推断整个任务环境已经复位。

回答 B 生成后,执行器会先观察到一组运行事实:服务是否响应、流是否结束、Agent 报告了什么结束原因、是否有最终正文。用户任务是否完成,要等评分侧结合参考再判断。收到 HTTP 200 或一个结束事件,说明请求走到了某个技术阶段,并不能证明引用 [S2] 合格。

如果任务超时,记录要继续往下写。超时保护上限用于防止执行器无限等待;只有用例本身要求限时交付,超时才直接构成该项业务失败。执行器还要分别记录停止请求是否发出、服务是否确认本地轮次收口,以及可观察到的远端操作是否仍在途。停止接口回了“成功”,也可能只表示接收了停止命令。

本地收口一直无法确认时,执行器可以终止本轮创建的进程并停止启动后续计划项。已经开始的尝试保留收到的回答、工具事件、原始故障和清理结果;尚未开始的项目留在台账里。重新执行完整任务会产生新的尝试,旧失败不能被覆盖。图中三条分支分别对应准备失败、请求后中断和后续未启动,评分时再看每条分支究竟影响了哪些要求。

4.3 原始事件怎样成为可评分的证据

先看一段人为构造的事件顺序。它只用于说明采集位置,没有运行过真实 Agent:

任务 policy_query_demo_001 / 尝试 A / 第 1 轮
01 search_documents → 候选:S1、S2
02 read_document(S1) → 当前部署政策
03 read_document(S2) → 审计功能说明
04 生成器实际输入 → S1 正文与 S2 正文
05 最终回答 → 仅企业版支持,需单独购买授权。[S2]

从第 01 行只能知道搜索找到过 S1;到第 02 行才能知道系统读到了它;第 04 行进一步说明 S1 的正文进入了生成请求。若第 04 行实际只有 S2,排查就要回到资料读取与上下文装配之间。假设事件确如上所示,问题才可收在可观察的回答生成和引用组织阶段。记录无法展示模型内部推理,也不能单凭事件顺序确定内部的心理式“原因”。

这段序列需要身份才能在实际日志中还原。业务问题有 case_id,一次完整执行有 attempt_id;用户在同一任务中追问时,各轮再用 turn_id 区分。第 02 行的工具请求与返回共享一个 call_id,这样即使返回晚于别的工具事件,也能配回原调用。工具内部另外发出的请求可以用可靠的父调用关系归属。配不上的事件保留在未归属列表,报告同时说明计数缺口。

前文的教学记录把 run_id 当作一次运行的关联字段。第四章改用 attempt_id 明确指向完整任务尝试。框架和平台里的 Run 可能是一轮请求、一次任务或一条 Trace,适配时要保存它们与 attempt_id 的对应关系。若两轮对话分别形成平台记录,任务判分仍要回到这两轮组成的完整尝试。

工具计数也要沿事件身份分层。假设 Agent 只发出一次 read_document,适配器为完成它又重试两次底层请求。“Agent 工具尝试 1 次”与“来源请求 3 次”可以同时成立。把请求开始和返回算成两次,或把底层重试都算作 Agent 的新决策,都会改变效率结论。轨迹缺失时调用数是未知;只有采集范围完整且确实没有调用,才能记为零。

回答本身可能在流式输出时被修订。若系统先把“团队版也支持”显示给用户,随后发出重置事件并改为“仅企业版支持”,最终答案与用户此前见过的内容不同。原始片段和重置事件应留在档案中;整理后的记录分别标出首次可见正文、首次完整回答和最终稳定答案。评分可以针对终稿,体验分析则可能需要前两个时点。

来源经过不同阶段后进入最终回答
来源经过不同阶段后进入最终回答

这张图把候选来源、已读取正文和实际生成输入分开。正文里的事件序列解释每一层保存什么,图本身不替代对丢失位置和引用关系的判断。

可评分视图应保留的原始依据缺失时受到影响的判断
回答版本流片段、重置和结束事件首次可见、最终回答与修订过程
工具调用请求、返回、调用 ID 和工具原文参数、先后关系、次数和动作边界
来源上下文候选、读取结果、最终生成输入来源是否取得、实际看到了什么
终止与资源请求时点、停止回执、用量来源完成状态、耗时和执行代价

持续变化的目标运行目录与单次任务档案也要分开。目标进程可能继续追加会话数据库和服务日志;归档器在一次尝试收口后,把属于它的输入、事件和引用固定下来,保存相对路径、内容摘要及记录修订。后续发现适配器转换错误,可以新增一版统一记录,保留原始事件和旧修订;若当时根本没有采到 S2 正文,修订不能凭空补出这段证据。完整字段、文件布局和 Schema 属于工程规格,文章只保留会影响判断的对象关系。

归档时还要检查引用是否能解析:source:S2 指向本次哪份正文,工具返回的文件是否仍在,内容摘要是否一致。评分器应读取固定档案。如果每次评分都重新打开不断变化的在线知识库,同一个 [S2] 可能已经指向修订后的文本,旧回答的依据便无法复原。后补材料要说明是新参考,还是对当时已有原始证据的恢复;要重新观察 Agent 会怎么行动,仍须发起新尝试。

4.4 独立参考怎样进入逐项评分

归档器已经保存回答 B 和它引用的 S2。评分入口接下来需要知道“正确的部署条件”来自哪里。评分侧另有一份经核验的当前政策 S1:只有企业版支持离线部署,还需单独购买授权。S0 曾经描述旧政策,S2 只介绍审计功能。这些材料都可能出现在 Agent 可检索的知识库中,但评分参考要独立于 Agent 这次回答准备,不能从回答 B 反推“标准答案”。

参考还要说明适用时间。用户问的是“当前”,评分器须按这道题约定的时点读取生效政策。若用户问历史变化,S0 才有不同的用途。对于“最新”一类题目,出题时应先说明是固定快照、源内最新记录,还是运行时可取得的最新披露;评分当天临时打开一个同名网页,不能替换本次运行所依据的版本。

这里的“独立”也有范围。评分规则若另行查询与 Agent 相同的资料库,可以检查 Agent 是否正确取用、传递和表达该库中的事实;资料库本身在外部世界是否正确,还需要进一步核验原始来源。报告应说清楚它验证到了哪一层。参考丢失、损坏或时点不适用时,评分入口先记录这个问题,不能把空参考交给模型裁判,再将得到的低分记到 Agent 头上。

现在把回答 B 分开判断。它写出了两个必要事实,所以事实覆盖通过。它使用的引用 ID 确实存在,因此引用 ID 检查也通过。引用支撑要问得更具体:“回答中这句部署声明,能否由它标出的 S2 支持?”读取 S2 的审计说明后,这项检查失败。S1 在别处包含正确政策,并不能替 S2 完成这份引用。

本次检查观察到的事实教学预期
必要事实覆盖版本范围与购买授权都写出PASS
引用 ID 有效S2 存在于本次来源表PASS
引用支持S2 只说明审计功能FAIL
来源时点已写事实与当前政策一致PASS
回答 B 的逐项检查怎样指向不同证据
回答 B 的逐项检查怎样指向不同证据

图中四个检查共享回答 B,却分别读取必要事实、来源列表、S2 正文和来源状态。后面的任务结论来自这些分项结果的聚合,不来自一个覆盖所有含义的总分。

评分记录分别保存每项的要求、观察值、证据位置和理由。引用支持这一项可以指向“最终回答中的部署声明”和“本次来源快照 S2”,让复核者沿这两个位置重做判断。它不是把全部工具结果拼成一段材料,让裁判搜索有没有相似句子。若后续修复了引用,即使答案文字几乎没变,这项结果也会明确变化。

一套通用检查还要覆盖任务结束和终止、动作权限、结构化事实、文档身份与引用,以及多轮条件继承。每类检查读取的证据不同。数值和日期若已经被可靠提取,适合程序按主体、单位和范围核对;含糊的自然语言、摘要要点或引文支撑可以请模型辅助判断。模型若只负责提取字段,后续计算仍由程序完成。模型若负责语义判定,评分记录应保留它实际读到的证据、规则版本、模型配置、原始输出与理由。

摘要和研究报告还可能有质量维度。摘要侧重要点、压缩与组织;研究报告关注证据整合、论证和结论边界。用例在执行前声明哪些维度适用,先保存逐维结果和缺失原因。某项质量分经过人工样例校准、并被明确写入该用例的门槛后,才参与通过判定。回答 B 是一条事实题,漂亮的行文不能抵消已经确认的引用错配。

4.5 任务失败和评测不完整分别处理

先看证据完整的回答 B。运行档案保存了 S2 正文和最终回答,读者可以复核两者的关系。事实覆盖与引用 ID 两项通过,引用支持失败。这里的 FAIL 有具体依据,修复方向也清楚。

再假设回答 B 完全相同,但采集器漏存了 S2 正文。评分器无法确认它引用的片段究竟是什么;若没有其他已经确定的失败,这次受影响的是评测过程,应记录 EVAL_ERROR 及缺失位置。把它直接判成 Agent 引用错误,会把取证故障错归给产品。

第三种情况是 S2 正文已保存,复核者却对其中一句话能否支持部署声明有合理分歧。这时需要保存争议和各自依据,交给进一步复核。回答文字没有变化,结论却可能不同,因为证据完整性和语义确定性是两回事。

这套设计在任务层保留六种状态,避免把上述情况都压成框架的布尔 pass:

状态使用时机留下什么
PASS适用的必需检查通过,已启用的质量门槛满足各项依据与评分版本
FAIL已可靠确认必需任务要求未满足失败证据与未完成检查
REVIEW_REQUIRED必需判断仍有争议或等待复核争议内容与待确认项
EVAL_ERROR参考、采集或评分故障影响可靠判定故障阶段和受影响范围
BLOCKED执行前缺少已声明的前置条件计划台账中的阻塞原因
NOT_RUN计划中的尝试尚未开始台账中的未启动原因

聚合时先看可靠确认的必需失败。假如 B 的引用支持已确定为 FAIL,另一项必需的模型评审却超时,任务仍保留 FAIL;超时同时写进评分完整性。没有已确认失败时,必需项的评测技术错误进入 EVAL_ERROR,语义未决进入 REVIEW_REQUIRED。全部必需检查通过、启用的质量门槛也满足后,任务才是 PASS。原始分项状态一直保留,任务状态只是方便汇总的结论。

故障发生在哪一侧也要结合用例判断。Agent 的模型调用失败,导致用户任务没有完成,是被测运行的一部分;独立裁判服务超时,则影响评分。如果用例故意注入工具故障,Agent 是否正确解释并停止反而是要检查的行为。执行前就缺少规定资料的任务标为 BLOCKED,批次停止后尚未开始的任务标为 NOT_RUN;这两类记录只在计划台账里,不伪造一条空回答。请求已经发出,即使正文为空,也要留下真实尝试。

单题结论和整批评测的完整性还要并列报告。B 可以因为引用错配确定失败,同时另一项必需检查尚未完成。这样既不会抹掉产品的已知问题,也不会假装整批评分已经全部完成。第五章做版本对照时,两组数都会影响实验能解释到什么程度。

4.6 同一行为的记录修订与重新评分

假设回答 B 的原始流事件清楚写着 [S2],归档器却在第一次整理时错误地把引用映射到了 S1。评分器读取这份整理记录,可能把引用支持判成 PASS。后来复核者打开原始事件发现错位,需要修正的是统一运行记录的转换结果;Agent 当时的行为并没有变化。

归档器应保留原始事件和第一版记录,再生成有依据的新修订。新的判分批次指向新修订,旧批次仍能解释它当时为什么得到另一种结论。这种做法也暴露一个重要边界:若原始事件里根本没有 S2 正文,改记录格式并不能补出当时缺失的资料。

同一尝试的修订、重评与重新执行
同一尝试的修订、重评与重新执行

放大查看版本关系图

另一种变化是记录一直正确,只是团队调整了引用支持规则,或者更换了评审模型。此时固定同一份运行记录和参考,再生成新的评分批次。两个判分结果说明的是“新旧规则怎样判断同一次行为”。如果要证明 Agent 修复了引用错配,就要让新版重新执行这道题,产生新的尝试、会话和运行证据。图中把三种变化放在同一个 Case 下,但分属不同身份:

发生的变化保留什么新增什么结果的含义
修正采集转换原始事件和 attempt_idrecord_revision同一次行为得到修正后的可评分视图
调整评分规则attempt_id 和所读记录修订grading_run_id新规则对旧行为的判断
修复后重新执行case_id 和任务要求新 attempt_id新版本在另一次执行中的表现

这几个身份还需要能解析到具体产物。判分记录应写明它读取了哪一版运行记录、哪份参考和哪套规则;证据引用应能找到对应的原文和内容摘要。评分者不必重新启动 Agent,也能复核旧行为。若要比较新版行为,第五章会继续说明怎样固定任务条件并安排新的尝试。

4.7 一份报告怎样同时呈现质量与完成度

系统完成一批任务后,读者首先需要知道哪些任务真正被执行和判定。下面把回答 B 放进一个四次尝试的纯教学批次,展示报告入口可以怎样写。这些数字只用于解释口径:

一份评测报告中的两个分母
一份评测报告中的两个分母
计划尝试:4        已开始:3
任务状态:PASS 1 / FAIL 1 / EVAL_ERROR 1 / NOT_RUN 1
已判定任务通过率:1 / (1 + 1) = 50%
任务判定覆盖率:  (1 + 1) / 4 = 50%

第一个 50% 表示已经获得确定业务判定的两次尝试中,有一次通过。第二个 50% 说明整批计划只有两次得到 PASS 或 FAIL。若报告只写“通过率 50%”,读者看不出另两次是产品失败、评测故障还是根本没有启动。状态数量和未决原因要与比例放在一起。

即使任务已经因为 B 的引用错配进入 FAIL,其他检查若因裁判超时未完成,也应继续显示这个缺口。任务结论回答“已知交付是否满足必要要求”,检查完成情况回答“本次评分覆盖到了哪里”。报告从完整计划台账开始,而不是只数框架结果页中出现的行;未启动的任务也不会因此消失。

当 PASS + FAIL 为零时,第一项应写“暂无可判定结果”,不写零通过率。质量分也只在适用任务及有效评分中计算;报告同时列出每个维度有多少项适用、多少项完成、多少项因评审故障缺失。语义分数的均值和任务通过率回答不同问题,不能放进同一个未说明分母的百分比里。

执行代价可以帮助解释结果,但应保留各层口径。对回答 B,报告可以同时展示 Agent 发起了几次工具调用、处理器实际执行了几次、底层资料请求是否发生重试。Agent 使用的模型、工具内部模型和独立裁判的用量分别归属。失败尝试已经消耗的资源也入账;采集不到的用量留空并说明原因,确认没有消耗时才记零。

时间也要从用户经历出发:任务请求何时开始,第一段可见正文何时出现,最终稳定回答何时结束。若流式正文发生重置,首次可见与最终答案之间的等待值得单列。多轮任务的各轮等待时间相加,未必等于从首轮请求到末轮结束的墙钟时间;并行工具耗时之和也不能直接当作用户等待时间。这样报告才能在质量变化之外解释代价,而不把少读必要资料造成的提前结束写成性能改进。

本章描述的执行、归档、评分和报告能力仍是设计要求,需由后续实现与接入验证。第五章接着讨论怎样从失败案例建立回归集、安排新旧版本成对运行,以及什么条件下可以把观察到的差异解释为产品改进。

5. 怎样把评测变成版本回归

5.1 从失败案例建立测试集

第四章里的回答 B 暴露了一个具体失败:事实说对了,引用却指向了 S2。开发者修正来源绑定后,下一版是否真的改善,需要让它重新面对这道题,也要检查修复有没有影响其他任务。单次重跑只能说明这道题的这一次结果;回归实验要把它放进一组有明确用途的案例中。

失败案例怎样进入版本回归
失败案例怎样进入版本回归

测试集里的每一条案例都需要说明它想保护什么能力。引用错配、历史政策误用、工具参数错误、多轮条件丢失和故障处理错误,虽然都可能在最终回答中表现为“回答不对”,修复位置却不同。案例记录失败机制,后续报告才能判断某次版本变化集中影响了哪一类任务。

Phoenix 数据集中的测试样例
Phoenix 数据集中的测试样例

Phoenix 的 Dataset 页面可以帮助读者看到“失败案例进入测试集”后的形态:输入、参考输出和样例属性被保存为可重复使用的条目。截图只展示平台对象,案例是否真的适合回归,仍要由业务规则和人工确认决定。

可以把测试案例按使用阶段分成三种集合。开发集用于快速观察修改方向,允许频繁重跑;回归集保存已经确认的失败和关键边界,保护原本通过的能力;保留集尽量少参与开发调参,用来观察改进能否推广。三者可以共享案例,但每条案例在当前实验中的用途要明确,不能一边用保留集调参,一边把它当成独立验证。

测试集还要覆盖任务复杂度。单次事实查询适合检查基本事实和工具参数;多工具任务需要检查资料流和调用关系;多轮任务需要保留会话及前轮条件;研究报告或外部交付任务则要加入证据整合、结论边界和最终状态。难度分层可以帮助解释“总体通过率没变,但复杂任务改善了”的情况。

案例还要保留它为什么进入测试集。一个案例可能来自线上失败、人工设计的边界、评分器漏放的反例,或者某次版本对照中出现的退化。来源不同,后续对它的信任和使用方式也不同。把失败截图、原始回答、参考绑定、人工判断和加入时间一并保存,下一次修改测试集时才知道这条题目保护的到底是哪项能力。

同一个失败可以派生出相邻案例。回答 B 的引用错配可以变成三个问题:S1 和 S2 同时出现时是否选对来源;只有 S2 出现时是否诚实说明依据不足;用户明确询问历史政策时是否仍能选择 S0。它们共享一部分机制标签,却分别检查当前政策、证据不足和历史语义。这样扩充测试集,比不断复制原题更容易观察修复是否改变了边界。

5.2 固定条件下比较两个版本

版本比较的第一步是登记改动。假设 candidate 修改了来源绑定规则,报告中需要写明代码、提示、工具定义、模型配置、资料快照和评分规则哪些发生了变化。模型、提示词和资料装配同时变化时,实验可以评价整套 candidate 配置,却不能把变化归因到其中单个因素。

条件比较前需要固定什么
任务Case、变体、题干、轮次和复杂度分层
资料数据快照、文档版本、参考来源和时间口径
Agent代码、提示、工具定义、模型标识和参数
环境会话初始化、缓存、数据库、索引和权限
预算Token、工具次数、超时和并发范围
评分检查器、参考、评审模型、规则和聚合顺序

固定条件不要求两个版本的所有执行路径相同。Agent 可以用不同的合理工具路径完成任务,实验主要比较结果和必要证据;工具轨迹用于解释差异,只有任务明确要求动作边界时才把某个过程条件列为硬门槛。

如果任务使用在线最新来源,实验还要保存运行时点、参考采集时间和来源变化。固定日期回放适合比较行为,在线任务更接近真实使用,却可能受到数据漂移影响。两种任务不应混在同一个结果分组里。

变更登记还要写明“哪些条件允许变化”。只改来源绑定时,模型、题干、工具定义、预算和评分规则都应保持一致;若同时改了上下文装配和提示词,报告写成 candidate 整体配置的比较。配置名称只是阅读标签,真正的比较依据是代码快照、内容哈希和有效请求参数。

实验条件固定的目的,是让失败或改善能够回到一个有限的解释范围。它不保证两个版本每次都会走相同的路径,也不消除模型和服务的自然波动。固定任务和评分口径之后,路径变化可以作为额外观察;如果把路径本身写成唯一验收条件,反而可能把另一条合理解法判成退化。

5.3 成对运行和重复尝试

同一个案例应分别交给 baseline 和 candidate 执行。每次执行使用自己的 attempt_id 和会话,重复运行也产生新的尝试。版本之间可以交错安排,减少服务状态和运行顺序对结果的影响。

baseline 与 candidate 怎样成对运行
baseline 与 candidate 怎样成对运行

一个小规模实验可以按下面的顺序组织:

  1. 展开同一批 Case、目标和重复次数;
  2. 登记 baseline 与 candidate 的允许变化项;
  3. 双方都完成环境预检后开始正式任务;
  4. 按成对协议交错运行,并分别保存会话和运行档案;
  5. 任务结束后再统一评分,或对固定记录重评;
  6. 逐题比较状态、理由、耗时和调用成本。

一次任务内部的工具重试属于同一个 Attempt,完整重跑则生成新的 Attempt。缓存、预热和连通性探测要单独标记。目标服务限流或环境启动失败时,不能只保留成功的一次重跑,否则结果会被无意筛选。

多轮任务要让两个版本分别拥有自己的会话。首轮后用户追问时,后续消息带着该版本自己的历史;重复试验重新建立初始会话。若任务涉及文件、数据库或外部状态,还要在每次尝试前恢复初始条件,或把共享状态写进可比性说明。

Phoenix 中的两组实验比较
Phoenix 中的两组实验比较

实验比较页面适合展示成对运行后的阅读入口:同一批案例的 baseline 和 candidate 输出并列出现,评分和逐条轨迹可以继续展开。页面上的平均值只是汇总视图,逐条修复和退化仍需要回到案例和运行证据。

从实验结果回到 Agent 工具步骤
从实验结果回到 Agent 工具步骤

这张图补上“为什么变化”的下一步。版本差异出现在结果表后,评测者还要打开对应的工具步骤,检查新版是否少读了必要材料,或者只是改变了回答文字。

成对运行的顺序也需要进入实验记录。可以使用 A1、B1、B2、A2 这样的交错顺序,避免某一版本永远在服务刚启动或刚发生限流时运行。预热调用、连通性检查、失败后的诊断重跑和正式尝试分开标记。一个版本因为环境没有就绪而缺失的结果,不能在汇总时悄悄当成“未通过”。

重复次数先服务于诊断,而不是立即宣称统计稳定。三次重复可以帮助发现一次偶发超时、缓存影响或评分波动;如果某个结果在三次中只出现一次,报告应保留逐次记录和波动原因。需要更强稳定性结论时,再扩大样本和分层,不能从小批次的整齐结果直接推出生产表现。

5.4 评分器怎样用反例和人工样本校准

评分器先用固定的人工样例校准。沿用 A、B、C 三个回答:A 漏掉授权条件,B 引用错配,C 内容和引用都完整。对“引用 ID 存在”和“引用支持”分别标注预期,检查器或模型裁判必须针对对应职责给出结果。

人工预期实际结果解释
FAILFAIL校准匹配
FAILPASS漏放
PASSFAIL误杀
INCONCLUSIVE任意确定状态先检查证据范围和标签是否合理

评分器对不匹配回答的测试结果 评分器对匹配回答的测试结果

评分器测试页面可以用来检查一条人工预期是否被实现。失败样例和通过样例要分别保留,不能只截取通过的结果;真正需要比较的是输入、参考、评分理由和返回状态是否与人工标签一致。

校准集和 Agent 成绩分开统计。调整评审提示、模型、指标或阈值后,用同一组固定样例重新检查;新规则通过校准后,再用于产品运行。开发过程中反复查看同一批案例并按其结果调整,会让回归集逐渐被过拟合,保留集应减少这种影响。

校准样例的粒度要和实际使用的检查一致。一条完整回答可以对应任务级人工标签,但引用 ID 是否存在、引用是否支持、事实是否完整,仍应分别准备预期。这样模型裁判在 B 上漏放时,团队能知道它误解了哪个关系,而不是只看到一个总分偏低。人工标签出现分歧时,先解决业务规则的含义,再把确定后的标签用于比较。

5.5 报告怎样同时展示收益、退化和未决项

版本比较先看逐条变化,再看汇总。仍以引用修复为例:

案例baselinecandidate解释
当前政策引用 S2FAILPASS修复
当前政策事实覆盖PASSPASS保持
历史政策问答PASSFAIL退化
资料采集缺失EVAL_ERROREVAL_ERROR评测缺口保持
评分服务超时PASSREVIEW_REQUIRED判定完成度变化

“修复”表示旧版确定失败、新版确定通过;“退化”表示旧版通过、新版确定失败;“保持”表示适用条件下状态一致;“未决”表示至少一边缺少可靠判定。未决项不能自动归入失败,也不能从统计中删除。

修复、保持、退化和未决怎样进入报告
修复、保持、退化和未决怎样进入报告
Phoenix 重评分后的逐条结果
Phoenix 重评分后的逐条结果

逐条评分页面可以帮助读者把“修复”和“退化”落实到具体案例。它仍然只是平台展示,正式报告需要结合项目自己的状态、分母和评分批次解释哪些结果可以计入通过率。

版本总通过率无法说明变化来自哪一类任务。报告要按失败机制、任务难度和质量维度分组,并列出原本通过而 candidate 失败的案例。只要某个退化涉及关键引用、权限或交付状态,就应单独显示,不能被其他普通任务的通过抵消。

逐条差异还要连到运行证据。对于修复案例,报告展示新版引用了哪份来源、对应的上下文是否实际进入生成输入;对于退化案例,报告打开旧版和新版各自的回答、工具事件与停止事实;对于未决案例,报告展示缺少哪一项资料或哪一次评分请求没有完成。这样“修复”才是可复核的变化,而不是状态列里的颜色变化。

5.6 质量、效率和成本怎样一起比较

质量和代价要放在同一份对照里。candidate 修复引用可能多读取一份文档,或者增加一次模型请求;这可能是合理成本,也可能说明检索流程出现重复。判断前先确认任务是否完成,再解释多出的调用取得了什么证据。

质量报告可以分开列出事实准确、内容完整、引用支持、结论边界、工具行为和任务完成。效率报告分别记录端到端耗时、首段可见时间、工具尝试、handler 执行、业务来源请求、主模型请求、评审请求和已知 token。未知值说明采集范围,失败尝试已经消耗的资源继续计入。

调用次数也要保持层次。candidate 可能只发起一次工具调用,却因底层网络重试产生三次来源请求;如果只比较一个总数,无法判断变化发生在 Agent 决策还是适配器执行。并行工具的请求耗时之和也不等于用户等待的墙钟时间。报告需要同时保存资源计数和用户经历的时间。

质量和效率也可能朝不同方向变化。candidate 少调用一次工具,却因为没有读取 S1 而更快结束,这属于失败造成的成本下降;candidate 多读一次政策文件并修复错配,则需要判断额外调用是否换来了必要证据。报告将任务状态放在前面,再写耗时和调用差异,读者才不会把“更快”直接理解为“更好”。

接入可以分阶段完成:先导入历史运行和验证统一记录,再实现数值、日期、范围和终止等确定性检查;接着用反例校准评分器;然后运行少量 baseline/candidate 对照;最后扩展到语义评分、检索诊断、平台实验和完整产品验收。每一步都保存前一步的证据,阶段性结果单独标注,不把受控教学结果写成正式成绩。

5.7 评分器校准、保留集和分阶段接入

评分器的校准和 Agent 的版本比较使用不同的实验对象。校准固定回答和证据,改变评分器配置;版本比较固定任务和评分规则,让两个 Agent 重新执行。两者都可以使用同一批 A、B、C 样例,但报告必须把人工预期、评分器结果和产品成绩分开。

当评分器更换模型、提示、指标版本或阈值时,先用固定校准集观察漏放、误杀和未决比例。调参反复依赖同一回归集,会让它逐渐变成开发集;保留集应减少访问,直到版本比较阶段再使用。测试集还要定期补充真实失败,防止长期只保护旧问题。

分阶段接入的完成条件不是“所有工具都装上”。历史记录应能映射到统一字段,确定性检查应能用反例定位错误,语义评分应有人工标签和规则版本,版本对照应保存完整的 baseline/candidate 证据,平台接入则应能从分数回到 Trace 或本地归档。某一阶段缺少证据,就把它报告为未完成的接入能力。

每个阶段还应有停止条件。历史导入如果无法保持原报告的分母,先修适配器;确定性检查如果连已知反例都分不出来,先不要扩大题集;模型评分若人工标签尚未稳定,暂时作为观察字段;平台如果只能显示分数却回不到原始运行,就先补追踪和证据引用。按问题逐层接入,能让下一阶段的新增信息真正改变诊断,而不是增加一层展示。

6. 评测系统怎样保持可信和可维护

前面几章已经说明了系统怎样运行、框架怎样接入、版本怎样比较。第 6 章把这些机制压缩成几条可以长期维护的原则。它们不是脱离案例的口号,而是从回答 B 的引用错配、运行归档和版本对照中提炼出来的设计要求。

6.1 让每个结论都能回到证据

回答 B 的任务结论是 FAIL,理由不是“模型看起来不可靠”,而是可以沿着引用标识找到 S2,沿着来源记录看到 S2 的正文,再对照用户要求和独立参考,确认这份材料不支持部署声明。结论的可信度来自这条回查路径。

一个评测结论由哪些条件共同支撑
一个评测结论由哪些条件共同支撑

一条评测结论至少需要三种信息相遇:任务要求说明要判断什么,运行证据说明实际发生了什么,参考和规则说明什么算满足。版本、时间和样本范围再给这条结论划出适用边界。缺少任意一层,报告都要降低表述强度。例如,只有回答文本时,可以讨论文字内容;没有来源快照时,不能确认引用是否支持。

这条原则会影响系统的每个对象。用例要保存验收条件,运行记录要保存证据位置,判分记录要保存理由和引用,报告要保存运行与规则版本。平台分数、框架断言和人工标注都需要回到这些对象,不能把一张页面截图当成最终依据。

可追溯也不等于把所有日志全部塞进正文。大段返回、事件和文件可以独立归档,统一记录保存路径、摘要和内容标识。读者需要的是从结论到原始证据的有效路径,系统维护者还需要确认这条路径没有越界、丢失或被后续内容覆盖。

6.2 把业务要求写进用例和检查器

“回答正确”“引用可靠”“任务完成”都太宽,不能直接作为一个总评分。第 4 章的政策案例把它们拆成事实覆盖、引用 ID、引用支持和来源时点四项检查,回答 B 才能表现出“事实通过、引用支持失败”的具体形状。

业务要求应当在用例中声明,再映射到检查器。用例保存用户问题、时间条件、可用工具和必要条件;实例合同说明本次使用的是固定政策快照还是在线来源;检查器输出期望、观察值、证据位置和状态。这样业务规则可以被程序、模型或人工分别消费,结果仍然回到同一份任务契约。

检查器的职责要保持窄。引用 ID 检查通过,不代表引用支持;COUNT、MIN、MAX 正确,不代表日期连续;平台 Trace 完整,不代表任务交付成功。多个窄检查组合起来,才形成可解释的任务结论。检查器若承担了没有证据支持的推断,分数会变得好看,失败却更难定位。

这也决定了测试集怎样维护。业务规则新增一项必要条件时,先修改用例和参考,再补检查器与校准样例;规则不应该只写在某次 Prompt、某个评分器配置或人工口头约定中。历史运行可用新规则重评,旧规则和旧结果仍要保留,方便解释版本变化。

6.3 让平台结果服务于业务判定

平台提供了 Trace、Dataset、Experiment、Score 和人工复核入口,但业务判定仍由任务要求决定。Phoenix 中一个实验分数显示出来,说明评分结果进入了平台对象;它不能单独说明评分覆盖完整,更不能替代必要引用、权限或交付检查。Langfuse 的 Score、Promptfoo 的 Assertion 和 DeepEval 的 Metric 也要按同样方式读取。

平台最有价值的地方是把运行和案例连接起来。开发者从 Trace 找到回答 B 的错误引用,把这次失败整理为 Dataset,再用 candidate 运行 Experiment,最后让人工复核解释新旧结果。这个过程让分数成为调查入口,而不是把平台分数当成业务结论。

报告可以同时展示平台原生结果和项目任务状态,但两者的名称和分母要分开。框架的通过率可能只统计有输出的记录,项目报告还要包含 BLOCKED、NOT_RUN、EVAL_ERROR 和 REVIEW_REQUIRED。平台实验可能只对一个 Dataset 运行,项目报告则要回到完整计划台账。不同对象的差异如果不写出来,读者会把一个局部视图误读成整体成绩。

6.4 同时看质量、效率和成本

candidate 修复引用后,如果多读取一份文档,调用次数和耗时可能增加。这个变化不能简单归为好或坏:额外读取可能取得了必要证据,也可能只是重复查询。质量结果先回答任务是否完成,效率指标再解释完成任务付出了什么代价。

质量至少要按事实、完整性、引用支持、结论边界、工具行为和任务完成等维度保存。效率要区分 Agent 发起的工具尝试、进入 handler 的执行、实际业务来源请求和内部重试;时间要区分用户等待、流式首段、各轮等待和取证;成本要区分主模型、工具内部模型、评审模型和参考采集。一个总分或一个总耗时会遮住这些关系。

报告还要显示质量与代价的共同变化。少调用一次工具但漏掉 S1,不应被写成效率提升;多调用一次工具并修复引用,如果额外请求没有重复或越界,则可以作为质量与成本的取舍。不同任务类型、冷热状态和数据条件要分组,避免把一次超时或一次缓存命中解释成系统整体趋势。

6.5 保留未知、争议和失败

评测系统的可信度也来自它承认不知道什么。S2 正文缺失时,引用支持不能被强行判成 FAIL;评分服务超时,不能把空分数当作低分;任务没有开始,不能生成一条空回答占用通过率分母。未知、争议、技术故障和产品失败各有状态,状态之间不能互相替代。

保留失败同样重要。回答 B 的 FAIL 不能因为后来重跑成功就被覆盖;修复后的 Attempt 产生新证据,旧 Attempt 仍然用于解释修复前的问题。评分规则改变时,旧评分批次继续存在,新评分批次说明规则变化带来了什么判断差异。

这条原则会影响报告语言。可以说“在本批 4 次计划中,2 次得到确定判定,其中 1 次通过”,不能只说“通过率为 50%”而省略另外两次的状态。可以说“该设计要求系统保存 Trace 和判分记录”,不能说系统已经具备这项能力,除非有实现和运行证据支持。

7. 总结:从一次任务到可持续的评测闭环

Agent 评测需要解决的事情,始终围绕一条任务展开:用户提出要求,Agent 在指定环境中执行,系统保存回答、工具调用和来源证据,评分器按照独立参考进行检查,报告再把结果放回版本和任务范围中解释。

从一次任务到可持续的评测闭环
从一次任务到可持续的评测闭环

这条链路中,执行、评分和报告承担不同职责。执行阶段负责产生真实运行,评分阶段负责判断这些运行是否满足要求,报告阶段负责说明哪些任务通过、哪些失败、哪些还没有得到可靠判定。三者使用同一组身份和证据连接起来,后续才能重新评分,也才能判断一次修改究竟改变了产品行为,还是改变了测量方法。

评测结果不能只由一个总分代表。事实准确、内容完整、引用支持、工具行为、任务完成、耗时和调用成本需要分别保存。回答 B 的例子说明,一段回答可以同时满足必要事实,却因为引用指向错误来源而失败。只有把这些检查拆开,开发者才知道问题发生在资料获取、上下文装配、引用组织还是评分过程。

评测框架和平台分别承担不同工作。Promptfoo、DeepEval 和 Ragas 把任务、断言和指标变成可以重复执行的检查;Phoenix、Langfuse 和 LangSmith 保存运行、数据集、实验和人工反馈。它们可以组合使用,但业务题库、独立参考、统一运行记录和任务状态仍然需要由评测系统维护。平台中的分数和框架中的通过状态,只有回到具体运行和任务规则后才有业务含义。

一套可持续的评测系统还要保留失败和不确定性。已确认的业务失败、评测技术错误、等待复核、执行前阻塞和未启动任务不能被压成同一种状态。旧运行需要继续保存,新的评分规则应产生新的评分批次,修复后的 Agent 则应产生新的尝试。这样,报告才能同时说明当前结果、历史变化和证据缺口。

评测报告怎样同时保存质量、状态与历史变化
评测报告怎样同时保存质量、状态与历史变化

从目前的设计和材料中,可以建立一套评测闭环:用例定义任务,执行器产生运行,归档器固定证据,检查器和评审模型给出分项结果,平台组织实验与复核,回归集保存已经确认的问题。它为后续工程实现、版本比较和持续监测提供了结构。

真正进入产品使用时,还需要继续验证完整 Agent 接入、真实检索和多轮状态、评分器校准、保留集表现以及长期运行中的质量变化。当前设计已经说明系统应该怎样工作,后续实现和实验再决定它在真实条件下能够稳定做到什么程度。

后续每次补充真实实验,都应沿同一条证据链修订结论,并保留原来的运行与判分记录。

附录 A:术语表

术语本文中的含义
Case一条业务任务定义,包含输入、环境和验收要求
Variant从同一任务派生出的具体范围或条件变化
Attempt某个 Agent 配置在一个 Case 上完成的一次完整尝试
Turn一次尝试中的一轮输入、回答和相关事件
Run工具或平台中的运行记录名称,实际粒度需结合字段确认
Trace用于还原一次运行过程的模型、检索、工具和程序事件
Dataset可以反复执行或评分的案例集合
Experiment按固定配置在一组案例上执行并比较结果的实验批次
Evaluator / Metric按规则、模型或人工判断输出评分和理由的组件
Reference与 Agent 本次回答独立的事实、答案或评价依据
Evidence支持某项检查的回答、来源、上下文、事件或环境状态
Calibration set带有人工预期结果,用来检查评分器的固定样例
Regression set用来保护已经确认能力和失败边界的测试集合
PASS适用的必要条件已经满足
FAIL已有证据确认必要条件被违反
REVIEW_REQUIRED需要补充证据或人工复核
EVAL_ERROR评测过程、参考或采集异常影响了可靠判定
BLOCKED任务开始前缺少已声明的前置条件
NOT_RUN计划中的任务尚未启动

这些名称在不同框架和平台中可能有不同粒度。本文优先使用项目语义解释对象关系,接入工具时再做字段映射。

附录 B:一个通用评测案例的完整展开

本附录把正文中反复使用的教学案例集中写一遍,方便读者回查。

用户问题:

当前哪些版本支持离线部署,需要满足什么条件?请给出依据。

教学资料包括:

来源内容在本题中的作用
S1当前仅企业版支持离线部署,需要单独购买部署授权当前政策参考
S2企业版提供审计日志功能存在但不支持部署结论的干扰来源
S0旧政策曾允许团队版和企业版离线部署历史政策,不能当作当前结论

必要检查包括:

  1. 回答是否说明当前支持的版本范围;
  2. 回答是否说明授权条件;
  3. 引用 ID 是否存在;
  4. 引用的正文是否支持对应陈述;
  5. 来源是否适用于题目要求的时间。

三份教学回答如下:

回答内容结果
A只说企业版支持离线部署,并引用 S1必要事实遗漏,FAIL
B两项事实都说出,但引用 S2引用 ID 存在,引用支持失败,FAIL
C两项事实都说出,并引用 S1必要检查通过,PASS

回答 B 的逐项结果:

检查结果
事实覆盖PASS
引用 IDPASS
引用支持FAIL
来源时点PASS
任务结论FAIL

这个案例可以分别用于业务检查器、Promptfoo 回放、DeepEval 语义诊断、Ragas 检索诊断,以及 Phoenix、Langfuse 或 LangSmith 的运行和实验记录。案例中的 S0、S1、S2 和 A、B、C 都是教学设定,不代表真实业务政策或产品成绩。

附录 C:统一运行记录字段

运行记录可以按下面几组字段组织。字段名称是说明用的契约,完整必填性和枚举需要在工程实现中固定。

字段组代表字段说明
任务身份case_id、variant_id、experiment_id这次运行属于哪条任务和哪批实验
尝试身份attempt_id、target_id、repeat_index哪个 Agent 配置的第几次尝试
环境身份environment_id、来源快照、运行目录实际加载了什么环境
会话轮次session_id、turn_id、输入、回答同一尝试的多轮上下文
回答版本首次正文、修订事件、最终正文用户看到什么,最终保存什么
工具事件call_id、工具名、参数、返回引用怎样关联请求、处理和返回
来源证据来源 ID、修订、状态、正文引用模型看到了哪些材料
生成上下文候选片段、实际输入片段、装配版本资料在哪一步进入模型
完成与停止HTTP、流结束、Agent 原因、停止回执运行是否正常收口
时间和资源开始结束时间、轮次耗时、Token、调用数质量与成本比较的基础
采集完整性SSE、工具、来源、模型请求状态哪些证据可靠,哪些未知
归档定位相对路径、内容摘要、记录修订如何回到原始产物

统一运行记录不要求把所有正文和事件放进一个 JSON。大段工具返回、原始事件、会话数据库和截图可以单独存储,主记录保存相对路径、内容摘要和引用位置。评分结果应能沿 case_id、attempt_id、turn_id 和 call_id 找回相关证据。

修订时保留原始记录。转换错误产生新的 record_revision,重新评分产生新的 grading_run_id,Agent 重新执行产生新的 attempt_id。这三种变化的身份不能混用。

附录 D:框架与平台对照表

工具主要入口主要对象适合解决的问题当前材料范围
PromptfooProvider、Test、Assertion、CLIProvider、Test、Assertion、结果矩阵固定输出回放、断言、版本比较、轨迹检查有教学配置和机制图,真实 Agent 接入待验证
DeepEvalPython Test Case、Metric、pytestTest Case、Metric、Trace语义质量、工具调用、任务完成和模型评审有算术脚本和评分流程说明,模型实评待验证
Ragas数据集、指标函数、实验样本、上下文、参考、Metric检索覆盖、上下文排序、回答支持和 Agent 诊断有固定标签脚本和指标图,真实指标待校准
PhoenixTrace、Dataset、Experiment、EvaluatorTrace、Span、Dataset、Experiment本地追踪、实验比较、评分和重评有本地规则 Agent 试用和多张截图
LangfuseTrace、Observation、Dataset、Score、AnnotationTrace、Session、Experiment、Score观测、提示词、评分、人工复核和部署有官方只读示例截图,未完成同案例本地实验
LangSmithRun、Thread、Dataset、Experiment、FeedbackRun、Thread、Dataset、EvaluatorAgent 调试、多轮分析和评测协作依据官方资料整理,未做本地试用

选型不能只看功能数量。还要核对运行证据能否完整进入、评分是否真正执行、结果能否回到原始尝试、权限和部署是否符合使用条件。框架和平台可以组合,但业务题库、独立参考、统一运行记录和任务状态仍由项目侧维护。

附录 E:资料来源和证据审计

第 3 章的工具说明分别依据以下材料。官方文档用于核对能力和接口;本地教学脚本、截图和自绘图用于解释机制。完整长文的逐项证据审计仍待其他章节写完后补齐。

工具官方入口当前材料的验证范围
Promptfoo配置、Provider、Test、Assertion 和回放固定输出教学配置有本地执行记录;真实 Agent 接入仍需验证
DeepEvalTest Case、Metric 和 Python 测试计分算术有本地教学脚本;模型评分代码为接入示意
Ragas检索、回答与 Agent 指标固定标签的指标算术有本地脚本;真实模型指标待接入验证
Phoenix追踪、数据集、实验与评分有本地规则 Agent 试用、截图和 SDK 重评记录
LangfuseTrace、Experiment、Score 和人工复核有官方只读示例项目截图;未完成同案例本地实验
LangSmithDataset、Experiment 和 Evaluator依据官方资料整理,未做本地试用

第 3 章的主要底稿为 Agent评测基础与框架调研笔记.md、Agent评测平台统一调研报告.md、Phoenix本地试用与Agent接入笔记.md 和 Langfuse功能概览与评测流程笔记.md。第 4 章主要从 Agent产品评测架构设计记录.md 提取系统边界、运行身份、参考绑定、任务状态和报告口径;较早的 Agent产品评测整合方案.md 只用于补充设计取舍。当前写法是对设计基线的通用化说明,不代表执行器和自动判分已经实现。第 3、4 章中的 S0、S1、S2 政策及回答 A、B、C 都是虚构教学案例。