AI Agent 任务完成度如何评估?从 Response Evaluation 到 Deliverable Evaluation

简介: 本文提出面向Agent任务的交付物评估新范式,突破传统LLM“文本响应评估”局限,构建Evidence→Verification→Evaluation→Acceptance四阶验收流程。融合确定性规则(代码/CI/运行证据校验)与LLM语义判断,明确划分职责边界,支持PASS/FAIL/NEED_REVIEW三态判定,并已在AI Tutor Engine中落地实践。(239字)

摘要 传统 LLM 评估主要关注模型输出本身,判断回答是否正确、相关、遵循指令。但当模型演进为 Agent,任务往往不再以“一段文本”结束,而是会产出代码、文件、测试结果、部署状态等实际交付物。此时若再让 LLM 直接给出“任务完成度分数”,会面临一个核心问题:

模型说自己完成了,不等于任务真的完成了

本文从这个问题出发,将 Agent 任务验收拆解为 Evidence → Verification → Evaluation → Acceptance 四个阶段,介绍一种“确定性规则 + LLM 语义判断”的工程实现方案,同时分享这套方案在 AI Tutor Engine 中的落地实践与当前的能力边界。


1. Agent 的“回答正确”和“任务完成”不是一回事

我们先看一个最简单的例子:给 Coding Agent 下达任务“实现用户登录功能,并补充测试”,Agent 最后返回一句“功能已经完成,测试通过”。

如果把这段回答交给另一个 LLM 直接评分,很容易得到“完成度 90%”的结论。但我们真正需要验证的其实是:

  • 代码是否真实存在?
  • 登录逻辑是否按需求实现?
  • 测试用例是否真的执行?
  • CI 流水线是否通过?
  • 运行结果是否符合预期?

问题的本质发生了变化: 原来的问题是

“这段回答写得怎么样?”

现在的问题是

“这个任务到底有没有完成?”

这两个问题不应该使用完全相同的评估方式。


2. 从 Response Evaluation 到 Deliverable Evaluation

传统 LLM 应用的结构比较简单,评价对象就是最终输出的文本:

评价维度通常包括:内容是否正确、是否符合上下文、是否遵循指令、是否出现违规内容等。

而 Agent 的执行链路要复杂得多,最终留下的也不只是一段话:

最终产出可能是代码、文件、数据库记录、Git Commit、CI 结果、部署服务、测试报告、Issue 等真实产物。

评价对象不同,评估方式也不应该相同:前者评文本,后者评交付物

因此可以把两类评价明确区分开:

项目 Response Evaluation Deliverable Evaluation
评价对象 模型的文本回复 任务的最终成果
核心问题 说得对不对 事情做没做成
主要证据 Response 文本 Code / CI / Runtime / Report 等
常见场景 Chatbot、知识问答 Coding Agent、自动化 Agent

注:本文中的 Deliverable Evaluation 是为描述这类问题提出的称呼,并非标准化行业术语。真正值得讨论的核心是:当 Agent 开始产生真实交付物以后,评价对象也应该从 Response 向 Deliverable 迁移。


3. 不要一上来就让 LLM 打总分

最直接的验收实现,是把任务直接丢给 LLM,让它输出 PASS / FAIL 或者分数。但这个方案里,模型同时承担了三件事:判断每条标准 + 计算总分 + 决定最终状态。其中至少有两件事,本来就没必要交给模型。

假设一个任务有 5 条权重相同的验收标准,模型判断结果是

A PASS

B PASS

C FAIL

D PASS

E PASS

那么总分就是 4 / 5 × 100 = 80。这一步计算交给Python,比交给 LLM 更稳定、更可复现。

所以在实现里,LLM 的输出契约只有逐条判定,不包含总分:

{
   
  "criteria": [
    {
   
      "rubric_id": "rb_xxx",
      "status": "PASS",
      "evidence": "依据的证据",
      "reason": "判定理由"
    }
  ],
  "next_step": "下一步需要补充什么"
}

这里故意没有 score。

最终分数和状态全部由代码计算:

score = round(passed / total * 100) if total > 0 else 0

if has_fail:
    status = ReviewStatus.FAIL
elif has_need_review:
    status = ReviewStatus.NEED_REVIEW
else:
    status = ReviewStatus.PASS

这个设计的核心不是“让模型少做事”,而是把模型无法稳定保证的部分,尽量从模型手里拿回来。


4. 评估之前,先解决一个更基本的问题:证据够不够

假设某条标准要求必须有 code 和 runtime 两类证据,但实际提交的只有一句“功能已经实现,运行正常”。如果只有 PASS / FAIL 两种状态,评估器就只能靠猜。这也是我不喜欢二值验收的原因。

在当前实现里,我增加了第三种状态:

class ReviewStatus(str, Enum):
    PASS = "PASS"
    FAIL = "FAIL"
    NEED_REVIEW = "NEED_REVIEW"

它解决的是证据不足的场景:

  • 证据完整 → 给出 PASS / FAIL
  • 证据不足 → 返回 NEED_REVIEW

例如:

NEED_REVIEW 缺少必要证据:code、runtime 请补充证据后重新提交。

NEED_REVIEW 不是模糊的“待定”,它明确表达:现有信息不足以负责任地给出 PASS 或 FAIL 结论。对于自动验收系统来说,这是非常必要的中间状态。


5. 当前实现:四道闸门评审流程

实际落地中,我把整个评审流程拆成了四层闸门

四道闸门评审流程:G1、G2、G4 均为纯规则判定,只有 G3 调用 LLM

5.1 Gate 1:Evidence Precheck(证据预检)

第一层完全不调用 LLM,只做一件事:检查 Rubric 要求的证据类型是否齐全。

核心逻辑可以简化为:

needed = set(r.required_evidence) - optional_bonus
missing = needed - present

missing_real = {
   
    m for m in missing
    if m != "description"
}

if missing_real:
    forced.append({
   
        "rubric_id": r.id,
        "missing": sorted(missing_real),
        "reason": "缺少必要证据,无法自动判定"
    })

这里有一个关键细节:任务提交者自己的文字说明(description)不算硬证据。一句“我已经完成了”,不能替代代码、CI、运行结果、测试报告。

这一步的好处很直接:明显缺证据的任务,直接拦截,不需要浪费一次 LLM 调用。

5.2 Gate 2:CI Direct Verdict(CI 直接判定)

有些结果本身就是确定性事实,不需要再交给 LLM 重复判断。

例如一个 Rubric 只要求测试结果,而 GitHub Actions 返回所有 workflow 全部 success,那就可以直接判定通过;全部 failure 就直接判定失败。

当前实现的规则很保守:

if conclusions == {
   "success"}:
    return {
   
        "status": ReviewStatus.PASS,
        "evidence": "CI 自动验收证据"
    }

if conclusions == {
   "failure"}:
    return {
   
        "status": ReviewStatus.FAIL
    }

return None
  • 全部 success → PASS
  • 全部 failure → FAIL
  • 混合结果 / cancelled / timeout 等 → 不直判,流转给 LLM

核心原则就是:确定性证据优先于模型判断。有些场景下,整次评审甚至可以零 LLM 调用——比如全部缺必要证据直接返回 NEED_REVIEW,或者全部 Rubric 都能由 CI 直接判定。


6. LLM 真正需要处理的,只是语义判断

通过前两道闸门之后,剩下的才是 LLM 擅长的问题:代码内容是否真的对应需求?

这一层会把所有收集到的证据整理成文本,交给 Reviewer 模型:代码、README、CI 结果、报告、Issue、描述说明等,然后逐条判断 Rubric 是否通过。

但模型的权限仍然受到严格限制,Prompt 里有几条硬约束:

  • 每条 Rubric 都必须检查,不能遗漏
  • 每条判定都必须给出对应的证据来源
  • 没有运行证据时,不能因为代码看起来合理就判断“运行成功”
  • 不得伪造运行结果
  • 只做客观评价,不负责修改代码

这里有一个非常关键的区别: LLM 可以说“这段代码看起来应该能运行”,但系统会追问“你有运行证据吗?” 没有运行证据,就不能把“看起来可以”直接当作“已经运行成功”。


7. 一个明确的边界:代码只能证明“写了什么”

这件事很容易被高估。比如仓库里存在 def login(username, password): ... 这样的代码,只能证明“项目中确实实现了登录逻辑”,但不能仅凭代码得出“用户真的可以登录”的结论。

实际运行还会受到很多因素影响:依赖版本、环境变量、数据库连接、网络权限、配置文件、部署环境等等。

所以我把这条边界直接写进了评审规则:

代码证据只能证明“写了什么”,不能证明“跑没跑通”。

目前运行类判断主要依赖三类证据:CI 执行结论、运行说明文档、可访问的部署地址。

这里也必须明确一个实现限制:当前引擎本身不执行用户代码,没有内置沙箱,没有测试运行器,也不会直接启动仓库中的程序。

换句话说,这套系统做的是外部执行 + 内部取证 + 自动评估,而不是“引擎自己执行代码再自动验收”。这也是当前最大的技术边界之一。


8. 为什么总分一定放在代码里算?

LLM 完成逐条判定后,会得到类似

A PASS

B PASS

C FAIL

D PASS

E PASS

的结果,然后交给代码做确定性聚合。

这样做主要解决两个问题: 第一,总分不会被语言风格影响。“这个项目基本完成了”和“这个项目已经很好地完成了”,不会改变权重计算的结果。 第二,验收结果可以复现。相同的 criteria 和 rubrics,经过同样的聚合逻辑,得到的分数一定是一样的。

简单说:LLM 负责“这一条过不过?”,代码负责“最后是多少分?”,职责边界非常清晰。

8.1Rubric 不能全部算作同一种标准

在实际的验收场景里,还有一个很重要的设计:并不是所有评价项都有“阻断项目”的资格。

我把 Rubric 按角色分成了三类:

  • acceptance:准入项,有阻断权,直接决定交付是否通过
  • theory:理论项,用于产生 learning gap,不直接导致项目失败
  • reflection:复盘项,用于生成复盘信息,不参与项目状态判定

也就是说,答错 ≠ 项目交付失败。

和“所有题目算进一个总分”的简单模式相比,这种设计能更准确地表达真实业务规则。核心不是三个分类的名字,而是“这条评价标准有没有阻断权”这个字段——如果答案不同,就应该在数据模型中明确表达,而不是全部藏进一个总分公式里。


9. 真正容易出问题的地方,不在主流程

主流程其实并不复杂,实际开发里更费时间的是各种边界异常。

9.1 模型输出截断

之前遇到过一种情况:LLM 输出到一半就结束了,JSON 结构不完整,导致 json.loads 失败,接口直接 500。

后来增加了对 finish_reason = length 的判断,遇到输出截断时,第二次请求会提高输出上限,避免把残缺 JSON 直接往后传。

9.2 JSON 合法,不代表语义合法

比如模型返回的 JSON 结构完全正确,但里面的 rubric_id 根本不属于当前任务。这种问题 Pydantic 的结构校验是检查不出来的。

所以现在除了结构校验,还增加了语义校验:

  • rubric_id 必须属于当前送审集合
  • evidence 字段不能为空
  • reason 字段不能为空
  • 所有送审 Rubric 必须逐条覆盖

结构正确,不等于结果正确,这个坑非常典型。

9.3 “出现文件名”不等于“真的有这个文件”

目前证据检查有一个已知的漏洞:通过字符串匹配判断文件是否存在。

if "agent_trace.json" in repo_code_text:
    ev["trace"] = "仓库中包含 agent_trace.json..."

如果 README 里只是写了一句“项目未来会生成 agent_trace.json”,字符串匹配也会认为 trace 证据存在。“出现了文件名”和“真的存在这个文件”显然不是一回事。

后续这里需要改成真正的文件存在性校验、内容可读性校验,而不是简单的字符串匹配。这是一个明确的优化点。


10. 缓存为什么要围绕“证据快照”做?

如果用户连续点 5 次“提交验收”,而代码和证据完全没有变化,没有必要调用 5 次 LLM。

所以当前的缓存不是按请求时间、会话 ID 来做,而是对当前证据做快照,基于快照生成哈希作为缓存键的一部分。

大概逻辑是:

canonical = json.dumps({
   
    "task_id": task_id,
    "evidence": dict(sorted(available.items())),
    "ci": sorted(...)
}, ensure_ascii=False, sort_keys=True)

snapshot_hash = hashlib.sha256(
    canonical.encode("utf-8")
).hexdigest()[:16]

最终的缓存键由这些字段组成:task_id + snapshot_hash + rubric_version + prompt_version + engine_version + model。这样相同的证据快照,不会重复消耗模型额度。

不过这里也存在一个明确的取舍:当前 head_sha 不直接参与缓存键。 好处是,同一份有效证据不会因为 Commit 标识变化就重新评审;坏处是,如果新的 Commit 只修改了当前证据采集范围之外的内容,可能会命中旧的评审结果。

这是缓存效率和版本敏感性之间的权衡,没有脱离业务场景的“绝对正确答案”,最终需要根据证据采集粒度持续调整。


11. 目前这套方案没有做到什么?

我认为,技术文章里主动说清楚自己的边界,比吹完美方案更有价值。当前这套系统还不具备这些能力:

  • 沙箱执行代码
  • 自动运行 pytest 等测试
  • AST 静态分析
  • Lint / 类型检查
  • 多 Agent 协作验收
  • 自动修复代码
  • 正式的评估准确率数据
  • 大规模人工评分一致性实验

也没有足够的数据支持 “准确率 95%” “F1 = 0.9” “与人工评分高度一致” 这类结论。

目前比较严谨的表述只能是:这套实现把一部分可以确定的问题交给代码处理,把需要语义理解的问题交给 LLM,并把证据不足的场景单独定义为 NEED_REVIEW。而不能说“这套方案已经证明比人工评价更准确”——目前还没有这样的实验。

关于设计取舍的补充说明 没有做上述能力,并非技术上不可行,而是基于当前项目的定位与成本考量:

  • 这套系统的核心定位是验收评估器,而非执行引擎。沙箱运行、自动测试属于执行态能力,纳入核心链路会模糊职责边界。
  • 静态分析、代码修复等增强能力,更适合以 MCP 协议或插件的形式扩展,不堆叠到核心验收流程中,避免核心逻辑过重。
  • 大规模人工标注与准确率验证需要极高的时间与经济成本,在项目早期阶段优先验证核心流程的可行性,后续逐步补充基准数据。
  • 全链路 LLM 调用的 Token 成本也是重要考量,过度堆叠能力会带来不必要的资源消耗。

用更通俗易懂的语言表示就是:多余


12. 这套设计落地在 AI Tutor Engine

前面讨论的是通用的 Agent 任务验收问题,而这套系统最终落地到了我正在开发的项目:AI Tutor Engine(信科院智能助手),一个面向编程类项目制学习的系统。

这个系统的工作流不是“学生问问题 → AI 给答案”,而是完整的项目式学习闭环:

项目式学习闭环:真正进入评审系统的是仓库中的代码、CI 结果、Issue 与运行证据

在这个系统里,学生说“我已经做完了”并不是验收依据,真正进入评审系统的是 GitHub 仓库中的代码、CI 结果、Issue、报告、运行证据等真实产物。

这也解释了为什么这个系统没有往“让 Tutor 自己写代码”的方向发展。它和 Coding Agent 的职责并不相同:

  • Coding Agent:负责把东西做出来
  • AI Tutor:负责理解任务、指导过程
  • Evaluation:负责判断最终是否达标

三个角色可以协作,但没有必要全部塞进同一个 Agent 里。


13. 最后总结

现在回头看,整个问题其实可以压缩成一句话:

不要问 LLM“你觉得这个任务完成了吗”,先问系统“我有什么证据可以证明它完成了”。

整个验收链路可以归纳为:

验收全链路与职责分工:确定性事实交给代码,语义判断交给 LLM,总分与最终状态回到代码

对应的职责划分也很明确:

  • 确定性事实 → 代码处理
  • 语义判断 → LLM 处理
  • 总分和最终状态 → 代码处理
  • 证据不足 → NEED_REVIEW

目前这套方案还有很多可以持续优化的地方,比如运行环境、静态分析、证据真实性、缓存粒度、评估基准、人工对照实验等等。我不会把它称为一个已经解决了 Agent Evaluation 的方案,它更像是一次具体的工程尝试:

当 Agent 的输出不再只是文字,而是一个需要交付的结果时,评价系统也应该围绕“证据”重新设计。

相关文章
|
20天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
8878 26
|
19天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
3803 16
|
18天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2240 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
5天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型深度拆解:原理解读、实战测评与保姆级落地教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为**System One Model(系统一模型)**,对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
408 1
|
13天前
|
人工智能 Linux 开发者
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
Codex是OpenAI推出的AI编程智能体,可读取本地项目、理解需求并自动修改代码。支持桌面GUI、命令行(CLI)及VS Code/Cursor插件三种形态,覆盖可视化操作、终端高效开发与编辑器无缝集成场景,助开发者用自然语言驱动编码全流程。(239字)
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
|
6天前
|
存储 人工智能 并行计算
大模型本地部署终端选型方法论:以 Qwen3.8-27B 为例的四档分层完整流程
本文提出一套大模型本地部署终端选型方法论:定约束、定档位、定框架、定参数四步决策法,配合入门、主力、质量、无损四档分层模型。以 Qwen3.8-27B 实测数据为例,逐环节解读显存、带宽、存储、散热、系统、预算等要素,给出面向不同预算的优选方案、决策自查清单与市场观察框架。文末前瞻 AI 笔记本的 CPU+GPU 与统一内存两条路线,论证四步决策法在新品类上的延续性。
|
7天前
|
人工智能 Linux Windows
千问办公(QwenWork)官网入口:其实有2个,一个是网页端千问办公,一个是介绍指南页面
千问办公(QwenWork)是阿里云推出的AI智能办公平台,支持网页端直接使用及Windows/Mac/Linux客户端下载。提供PPT生成、财报分析、网页搭建等AI功能,个人版免费,企业版198元/席/月。详情见官网qwenwork.cn或阿里云产品页。
946 0
千问办公(QwenWork)官网入口:其实有2个,一个是网页端千问办公,一个是介绍指南页面
|
19天前
|
云安全 人工智能 安全

热门文章

最新文章