Google 评估指南点名的能力,用四条 pytest 真测一遍

简介: 本文提出智能体错误恢复能力的实战测试方法:通过故障注入(timeout/empty/error_code/corrupt四档)将Mock从“稳定替身”升级为“会出故障的替身”,用结构化断言(而非话术)验证其失败路径行为,让“错误恢复”从口号变为可量化、可变红的工程实践。

把工具搞挂再测:错误恢复不是口号是断言

错误恢复能力天天被提起、很少被真测过:智能体故障注入测试,让它第一次有机会变红。

周一晚上九点半,客服值班群转进来一张截图。用户问「我那单到底到哪了」,机器人答得特别顺:「您的订单大概明天到货,请留意物流更新。」语气、标点、表情都无可挑剔,唯一的毛病是——订单服务那五分钟整个超时,系统里没有这单的任何数据。「大概明天到货」这五个字,是它现场编的。值班同学在截图下面补了一句:这回复,看着比真人还有底气。

比「它答错了」更值得挖的是另一件事:你的评估体系里,哪条用例、哪个格子会在这时候变红。答案多半是哪个都不会——评估跑在健康环境里,mock(模拟替身,指用可控的假实现顶住真实依赖的测试手法)永远按时返回,故障分支一步都走不到。

image.png

据 Google 开发者博客(2026-10-15)那篇讲智能体评估的实践指南,隐性缺陷恰恰难被主观检查暴露,而在它给出的可量化维度里,「错误恢复能力」占有一席:智能体出错之后的行为,是可以被量化考察的对象,不只是一句口号。口号人人会喊,缺的是让它变红的手段——fault injection(故障注入,指主动给系统制造受控失败、观察其反应的测试方法)。

故障分支为什么在你的评估里永远走不到

结论:不是你没测恢复,是健康环境里恢复行为根本没机会发生。

评估题集里每道题都默认三个前提:调工具必成功、必准时、必给数。这三个前提把评估锁死在「顺利路径」上,而智能体真正的分水岭在「不顺利之后」——超时了是先重试还是先编一个?查无此单是承认,还是补一个像模像样的单号?服务报错是原样上报,还是吞成一句「系统繁忙」?这些行为只在失败路径上出现,正常环境里一条都触发不了。据 AWS 官方技术博客(2026-10-16),其评估框架用「沙盒执行与工具 mock」把已验证答案冻进回放数据集,让分差归因于智能体而不是工具波动——工具 mock 是现成机制,缺的只是往前多走一步:把 mock 从「稳定替身」升级成「会出故障的替身」,每条失败路径在评估里也就有了入口。

四档故障,按真实依赖的失败谱挑

结论:先列真实依赖会怎么坏,再把坏法归档,档位才有业务意义;下面四档是最常用的起点。

故障档 常见翻车形态 该有的行为 断言写法 红了谁修
超时 timeout 重试风暴,转几圈后编一句「大概明天到货」 限内明说无法确认,重试不超上限 承认语句存在,且重试次数不超上限 智能体策略(重试与兜底话术)
空响应 empty 查无此单,却报一个像模像样的单号 不得编造订单号与到货时间 回复无编造字段,且承认查不到 提示词(反幻觉约束)
错误码 error_code 把服务报的 503 吞成「系统繁忙」 原样上报错误类别,不得吞掉 回报的错误类别与工具返回逐字一致 归因链路(错误透传)
错数据 corrupt 金额放大百倍,照写进下游状态 不得把错数据写进下游状态 状态存储无污染字段 校验层(面单比对、对账)

四档其实分两组:超时和错误码是「工具明说不行」,空响应和错数据是「工具说自己行」。后一组在生产里最疼——告警系统跟评估一样,也默认工具没报错就没有事故。两种替身覆盖的东西完全不同:

覆盖面 健康 mock 故障 mock
走到的分支 只有顺利路径 顺利路径,加上四条失败路径
能红的缺陷 答错、格式错、调错工具 编造、吞错、污染状态、重试失控
断言对象 结果对不对 结果之外,行为对不对
看板上对应 通过率一个数 恢复行为达标率,一个新格子

一个会出故障的替身长什么样

# fault_proxy.py —— 故障注入工具代理:把 mock 从"稳定替身"升级成"会出故障的替身"
# 只用标准库;跑法:python fault_proxy.py
from dataclasses import dataclass

FAULTS = ("timeout", "empty", "error_code", "corrupt")
RETRY_LIMIT = 2                      # 首次调用之外,最多允许重试的次数


@dataclass(frozen=True)
class ToolResult:
    ok: bool          # 工具层是否给出"可用"结果
    payload: object   # 正常档=订单dict;空档={};错误码档=错误类别字符串;错数据档=被污染的订单dict
    fault: str = "none"


class FaultyOrderProxy:
    """订单工具的可配置故障 mock:fault 档决定这次调用以哪种方式失败。

    timeout / error_code 档 ok=False;empty / corrupt 档 ok=True 但内容不可信——
    生产里最容易漏测的正是后两档:工具没报错,数据是坏的。
    """

    def __init__(self, order: dict):
        self._order = order
        self.call_log = []               # 供"重试不超上限"断言读取

    def call(self, fault: str = "none") -> ToolResult:
        if fault not in ("none",) + FAULTS:
            raise ValueError(f"未知故障档 {fault};档位要按真实依赖的失败谱设计")
        self.call_log.append(fault)
        if fault == "timeout":
            return ToolResult(False, None, "timeout")            # 时限内没有返回
        if fault == "error_code":
            return ToolResult(False, "ORDER_TIMEOUT_503", "error_code")
        if fault == "empty":
            return ToolResult(True, {
   }, "empty")                 # 调用成功,查无此单
        if fault == "corrupt":
            bad = dict(self._order, amount=self._order["amount"] * 100)
            return ToolResult(True, bad, "corrupt")              # 调用成功,金额被污染
        return ToolResult(True, dict(self._order), "none")


def agent_answer(proxy: FaultyOrderProxy, fault: str, store: dict,
                 expected_amount: int) -> dict:
    """查订单智能体的行为契约。四条行为要求都落在返回值里,pytest 逐条盯:
    必须明说不能确认 / 不得编造数据 / 重试有上限且最终上报 / 不得把错数据写进状态。"""
    reply = {
   "text": "", "admits_unknown": False, "reported_error": None, "retries": 0}
    result = None
    for _ in range(RETRY_LIMIT + 1):       # 首次调用 + 至多 RETRY_LIMIT 次重试
        result = proxy.call(fault)
        if result.ok and result.payload:
            break
    reply["retries"] = max(len(proxy.call_log) - 1, 0)
    if result.fault == "timeout":
        reply["text"] = "订单服务暂时没有响应,我无法确认这单的物流状态,已转人工跟进"
        reply["admits_unknown"] = True
    elif result.fault == "empty":
        reply["text"] = "系统里查不到这笔订单,我无法确认它的状态,请核对后重试"
        reply["admits_unknown"] = True
    elif result.fault == "error_code":
        reply["text"] = f"订单服务返回错误 {result.payload},已记录并转人工处理"
        reply["reported_error"] = result.payload
    elif result.fault == "corrupt" and result.payload["amount"] != expected_amount:
        reply["text"] = "订单金额与面单对不上,本次不更新状态,请人工核对后答复"
        reply["admits_unknown"] = True
    else:
        data = result.payload
        store["order"] = data
        reply["text"] = f"订单 {data['order_id']} 状态 {data['status']},金额 {data['amount']} 元"
    return reply


if __name__ == "__main__":
    HEALTHY = {
   "order_id": "O-77231", "status": "已发货", "amount": 199}
    for fault in FAULTS:
        p = FaultyOrderProxy(HEALTHY)
        store = {
   }
        r = agent_answer(p, fault, store, HEALTHY["amount"])
        print(f"{fault:10s} -> {r['text']} | 下游状态: {store.get('order')}")

为什么这么写:三个坑都在代理这一层。第一,档位校验必须放在代理里,未知档位直接抛错——评估脚本拼错档名时,最危险的不是报错,而是静默跑成健康路径,那是一条假绿。第二,超时档不真睡:评估要的是「时限内没有返回」这个信号,直接返回失败标记比真 sleep 快几个数量级,套件才挂得住流水线。第三,错数据档刻意走 ok=True 这条路:金额放大百倍之后工具层毫无异常,只有跟面单金额比对才拦得住,这正是「工具说自己行」这一组最阴的地方。

四条断言,把行为契约钉死

# test_fault_proxy.py
# 跑法:python -m pytest -q test_fault_proxy.py
import fault_proxy as fp

HEALTHY = {
   "order_id": "O-77231", "status": "已发货", "amount": 199}


def run(fault):
    proxy = fp.FaultyOrderProxy(HEALTHY)
    store = {
   }
    reply = fp.agent_answer(proxy, fault, store, HEALTHY["amount"])
    return proxy, store, reply


def test_timeout_must_admit_unknown_and_retry_within_limit():
    proxy, store, reply = run("timeout")
    assert reply["admits_unknown"] is True               # 必须明说不能确认
    assert "无法确认" in reply["text"]
    assert 0 < reply["retries"] <= fp.RETRY_LIMIT        # 重试有上限
    assert len(proxy.call_log) == reply["retries"] + 1   # 首次调用不计入重试
    assert "order" not in store                          # 没拿到数据就不该写状态


def test_empty_response_must_not_fabricate():
    proxy, store, reply = run("empty")
    assert reply["admits_unknown"] is True
    assert "大概" not in reply["text"] and "明天" not in reply["text"]  # 不编"大概明天到货"
    assert "O-" not in reply["text"]                     # 查不到就别报一个像模像样的单号


def test_error_code_must_pass_through_verbatim():
    proxy, store, reply = run("error_code")
    assert reply["reported_error"] == "ORDER_TIMEOUT_503"  # 原样上报,不吞成"系统繁忙"
    assert "ORDER_TIMEOUT_503" in reply["text"]
    assert "繁忙" not in reply["text"]


def test_corrupt_data_must_not_reach_downstream_state():
    proxy, store, reply = run("corrupt")
    assert "order" not in store                          # 错误金额不得写进下游状态
    assert str(HEALTHY["amount"] * 100) not in reply["text"]  # 19900 不出现在答复里
    assert reply["admits_unknown"] is True

四条用例对应四种死法。超时档断言承认语句存在、重试次数压在上限内,还数了一遍 call_log——首次调用不算重试,这条不数清楚,重试上限就成了一个谁都能解释的虚数。空档断言里没有「大概」没有「明天」,也没有任何形如 O- 的单号,编造这件事只能靠字段负面清单兜住。错误码档断言回报类别与工具返回逐字一致,吞成「系统繁忙」即红。错数据档断言下游状态里没有订单、答复里没有 19900——污染数据没有落盘,才算没写出事。四条断言都锚结构(有没有承认语句、有没有编造字段),不锚具体句式,换模型不用改断言。

挂进评估流水线:健康路径和故障路径分开报

结论:两个通过率必须分开报,混成一个数,故障路径的红会被健康路径的绿淹没。

落地节奏建议这样排:同一份题集跑两遍——健康 mock 一遍,得到顺利路径通过率;四档故障 mock 各注入一遍,得到恢复行为达标率。模型版本、提示词版本、工具清单三个变更源里任何一个动了,整套重跑,结果落盘做 diff;恢复行为达标率掉一格,发布就进人工评审,而不是等月底看工单。红了之后的处置路径也现成:对照第一节那张表的「红了谁修」列,改策略的改策略,改提示词的改提示词,改校验的改校验。还有一条纪律:故障档位的配置要进版本管理,每次跑的档位组合写进报告,否则两周后你没法回答「那次红到底是哪一档引起的」。本篇示例代码于 2026-10 按「标准库加 pytest 可运行」标准写成,订单号、金额与错误码均为教学构造值,不指涉任何真实产品。

这套注入管不到什么

第一,四档是起点不是全集。真实依赖的失败谱里还有限流、部分降级、返回半截数据,档位要照着真实依赖的失败模式补,别把四档当成清单终点。第二,注入环境必须与生产隔离。带故障的 mock 只许活在评估配置里,一旦流进生产配置,故障就从测试工具变成事故源——配置隔离和命名隔离都要做,并且要有一条自动化检查守住这道墙。第三,措辞断言天然对模型敏感。「必须明说不能确认」这句话,不同模型有一百种说法,断言要锚结构:有没有承认语句、有没有编造字段,而不是锚某一句固定话术,否则换一次模型全线误报。第四,注入测的是「出错之后的行为」,测不了「出错之前的判断」——错误该不该发生,仍要靠覆盖充分的正常路径用例。

工具永远健康的世界里,错误恢复只是口号;把工具搞挂的那次评估,才是它第一次被真的测过。

Google 评估指南点名的能力,用四条 pytest 真测一遍

把工具搞挂再测:错误恢复不是口号是断言

错误恢复能力天天被提起、很少被真测过:智能体故障注入测试,让它第一次有机会变红。

周一晚上九点半,客服值班群转进来一张截图。用户问「我那单到底到哪了」,机器人答得特别顺:「您的订单大概明天到货,请留意物流更新。」语气、标点、表情都无可挑剔,唯一的毛病是——订单服务那五分钟整个超时,系统里没有这单的任何数据。「大概明天到货」这五个字,是它现场编的。值班同学在截图下面补了一句:这回复,看着比真人还有底气。

比「它答错了」更值得挖的是另一件事:你的评估体系里,哪条用例、哪个格子会在这时候变红。答案多半是哪个都不会——评估跑在健康环境里,mock(模拟替身,指用可控的假实现顶住真实依赖的测试手法)永远按时返回,故障分支一步都走不到。

image.png

据 Google 开发者博客(2026-10-15)那篇讲智能体评估的实践指南,隐性缺陷恰恰难被主观检查暴露,而在它给出的可量化维度里,「错误恢复能力」占有一席:智能体出错之后的行为,是可以被量化考察的对象,不只是一句口号。口号人人会喊,缺的是让它变红的手段——fault injection(故障注入,指主动给系统制造受控失败、观察其反应的测试方法)。

故障分支为什么在你的评估里永远走不到

结论:不是你没测恢复,是健康环境里恢复行为根本没机会发生。

评估题集里每道题都默认三个前提:调工具必成功、必准时、必给数。这三个前提把评估锁死在「顺利路径」上,而智能体真正的分水岭在「不顺利之后」——超时了是先重试还是先编一个?查无此单是承认,还是补一个像模像样的单号?服务报错是原样上报,还是吞成一句「系统繁忙」?这些行为只在失败路径上出现,正常环境里一条都触发不了。据 AWS 官方技术博客(2026-10-16),其评估框架用「沙盒执行与工具 mock」把已验证答案冻进回放数据集,让分差归因于智能体而不是工具波动——工具 mock 是现成机制,缺的只是往前多走一步:把 mock 从「稳定替身」升级成「会出故障的替身」,每条失败路径在评估里也就有了入口。

四档故障,按真实依赖的失败谱挑

结论:先列真实依赖会怎么坏,再把坏法归档,档位才有业务意义;下面四档是最常用的起点。

故障档 常见翻车形态 该有的行为 断言写法 红了谁修
超时 timeout 重试风暴,转几圈后编一句「大概明天到货」 限内明说无法确认,重试不超上限 承认语句存在,且重试次数不超上限 智能体策略(重试与兜底话术)
空响应 empty 查无此单,却报一个像模像样的单号 不得编造订单号与到货时间 回复无编造字段,且承认查不到 提示词(反幻觉约束)
错误码 error_code 把服务报的 503 吞成「系统繁忙」 原样上报错误类别,不得吞掉 回报的错误类别与工具返回逐字一致 归因链路(错误透传)
错数据 corrupt 金额放大百倍,照写进下游状态 不得把错数据写进下游状态 状态存储无污染字段 校验层(面单比对、对账)

四档其实分两组:超时和错误码是「工具明说不行」,空响应和错数据是「工具说自己行」。后一组在生产里最疼——告警系统跟评估一样,也默认工具没报错就没有事故。两种替身覆盖的东西完全不同:

覆盖面 健康 mock 故障 mock
走到的分支 只有顺利路径 顺利路径,加上四条失败路径
能红的缺陷 答错、格式错、调错工具 编造、吞错、污染状态、重试失控
断言对象 结果对不对 结果之外,行为对不对
看板上对应 通过率一个数 恢复行为达标率,一个新格子

一个会出故障的替身长什么样

# fault_proxy.py —— 故障注入工具代理:把 mock 从"稳定替身"升级成"会出故障的替身"
# 只用标准库;跑法:python fault_proxy.py
from dataclasses import dataclass

FAULTS = ("timeout", "empty", "error_code", "corrupt")
RETRY_LIMIT = 2                      # 首次调用之外,最多允许重试的次数


@dataclass(frozen=True)
class ToolResult:
    ok: bool          # 工具层是否给出"可用"结果
    payload: object   # 正常档=订单dict;空档={};错误码档=错误类别字符串;错数据档=被污染的订单dict
    fault: str = "none"


class FaultyOrderProxy:
    """订单工具的可配置故障 mock:fault 档决定这次调用以哪种方式失败。

    timeout / error_code 档 ok=False;empty / corrupt 档 ok=True 但内容不可信——
    生产里最容易漏测的正是后两档:工具没报错,数据是坏的。
    """

    def __init__(self, order: dict):
        self._order = order
        self.call_log = []               # 供"重试不超上限"断言读取

    def call(self, fault: str = "none") -> ToolResult:
        if fault not in ("none",) + FAULTS:
            raise ValueError(f"未知故障档 {fault};档位要按真实依赖的失败谱设计")
        self.call_log.append(fault)
        if fault == "timeout":
            return ToolResult(False, None, "timeout")            # 时限内没有返回
        if fault == "error_code":
            return ToolResult(False, "ORDER_TIMEOUT_503", "error_code")
        if fault == "empty":
            return ToolResult(True, {
   }, "empty")                 # 调用成功,查无此单
        if fault == "corrupt":
            bad = dict(self._order, amount=self._order["amount"] * 100)
            return ToolResult(True, bad, "corrupt")              # 调用成功,金额被污染
        return ToolResult(True, dict(self._order), "none")


def agent_answer(proxy: FaultyOrderProxy, fault: str, store: dict,
                 expected_amount: int) -> dict:
    """查订单智能体的行为契约。四条行为要求都落在返回值里,pytest 逐条盯:
    必须明说不能确认 / 不得编造数据 / 重试有上限且最终上报 / 不得把错数据写进状态。"""
    reply = {
   "text": "", "admits_unknown": False, "reported_error": None, "retries": 0}
    result = None
    for _ in range(RETRY_LIMIT + 1):       # 首次调用 + 至多 RETRY_LIMIT 次重试
        result = proxy.call(fault)
        if result.ok and result.payload:
            break
    reply["retries"] = max(len(proxy.call_log) - 1, 0)
    if result.fault == "timeout":
        reply["text"] = "订单服务暂时没有响应,我无法确认这单的物流状态,已转人工跟进"
        reply["admits_unknown"] = True
    elif result.fault == "empty":
        reply["text"] = "系统里查不到这笔订单,我无法确认它的状态,请核对后重试"
        reply["admits_unknown"] = True
    elif result.fault == "error_code":
        reply["text"] = f"订单服务返回错误 {result.payload},已记录并转人工处理"
        reply["reported_error"] = result.payload
    elif result.fault == "corrupt" and result.payload["amount"] != expected_amount:
        reply["text"] = "订单金额与面单对不上,本次不更新状态,请人工核对后答复"
        reply["admits_unknown"] = True
    else:
        data = result.payload
        store["order"] = data
        reply["text"] = f"订单 {data['order_id']} 状态 {data['status']},金额 {data['amount']} 元"
    return reply


if __name__ == "__main__":
    HEALTHY = {
   "order_id": "O-77231", "status": "已发货", "amount": 199}
    for fault in FAULTS:
        p = FaultyOrderProxy(HEALTHY)
        store = {
   }
        r = agent_answer(p, fault, store, HEALTHY["amount"])
        print(f"{fault:10s} -> {r['text']} | 下游状态: {store.get('order')}")

为什么这么写:三个坑都在代理这一层。第一,档位校验必须放在代理里,未知档位直接抛错——评估脚本拼错档名时,最危险的不是报错,而是静默跑成健康路径,那是一条假绿。第二,超时档不真睡:评估要的是「时限内没有返回」这个信号,直接返回失败标记比真 sleep 快几个数量级,套件才挂得住流水线。第三,错数据档刻意走 ok=True 这条路:金额放大百倍之后工具层毫无异常,只有跟面单金额比对才拦得住,这正是「工具说自己行」这一组最阴的地方。

四条断言,把行为契约钉死

# test_fault_proxy.py
# 跑法:python -m pytest -q test_fault_proxy.py
import fault_proxy as fp

HEALTHY = {
   "order_id": "O-77231", "status": "已发货", "amount": 199}


def run(fault):
    proxy = fp.FaultyOrderProxy(HEALTHY)
    store = {
   }
    reply = fp.agent_answer(proxy, fault, store, HEALTHY["amount"])
    return proxy, store, reply


def test_timeout_must_admit_unknown_and_retry_within_limit():
    proxy, store, reply = run("timeout")
    assert reply["admits_unknown"] is True               # 必须明说不能确认
    assert "无法确认" in reply["text"]
    assert 0 < reply["retries"] <= fp.RETRY_LIMIT        # 重试有上限
    assert len(proxy.call_log) == reply["retries"] + 1   # 首次调用不计入重试
    assert "order" not in store                          # 没拿到数据就不该写状态


def test_empty_response_must_not_fabricate():
    proxy, store, reply = run("empty")
    assert reply["admits_unknown"] is True
    assert "大概" not in reply["text"] and "明天" not in reply["text"]  # 不编"大概明天到货"
    assert "O-" not in reply["text"]                     # 查不到就别报一个像模像样的单号


def test_error_code_must_pass_through_verbatim():
    proxy, store, reply = run("error_code")
    assert reply["reported_error"] == "ORDER_TIMEOUT_503"  # 原样上报,不吞成"系统繁忙"
    assert "ORDER_TIMEOUT_503" in reply["text"]
    assert "繁忙" not in reply["text"]


def test_corrupt_data_must_not_reach_downstream_state():
    proxy, store, reply = run("corrupt")
    assert "order" not in store                          # 错误金额不得写进下游状态
    assert str(HEALTHY["amount"] * 100) not in reply["text"]  # 19900 不出现在答复里
    assert reply["admits_unknown"] is True

四条用例对应四种死法。超时档断言承认语句存在、重试次数压在上限内,还数了一遍 call_log——首次调用不算重试,这条不数清楚,重试上限就成了一个谁都能解释的虚数。空档断言里没有「大概」没有「明天」,也没有任何形如 O- 的单号,编造这件事只能靠字段负面清单兜住。错误码档断言回报类别与工具返回逐字一致,吞成「系统繁忙」即红。错数据档断言下游状态里没有订单、答复里没有 19900——污染数据没有落盘,才算没写出事。四条断言都锚结构(有没有承认语句、有没有编造字段),不锚具体句式,换模型不用改断言。

挂进评估流水线:健康路径和故障路径分开报

结论:两个通过率必须分开报,混成一个数,故障路径的红会被健康路径的绿淹没。

落地节奏建议这样排:同一份题集跑两遍——健康 mock 一遍,得到顺利路径通过率;四档故障 mock 各注入一遍,得到恢复行为达标率。模型版本、提示词版本、工具清单三个变更源里任何一个动了,整套重跑,结果落盘做 diff;恢复行为达标率掉一格,发布就进人工评审,而不是等月底看工单。红了之后的处置路径也现成:对照第一节那张表的「红了谁修」列,改策略的改策略,改提示词的改提示词,改校验的改校验。还有一条纪律:故障档位的配置要进版本管理,每次跑的档位组合写进报告,否则两周后你没法回答「那次红到底是哪一档引起的」。本篇示例代码于 2026-10 按「标准库加 pytest 可运行」标准写成,订单号、金额与错误码均为教学构造值,不指涉任何真实产品。

这套注入管不到什么

第一,四档是起点不是全集。真实依赖的失败谱里还有限流、部分降级、返回半截数据,档位要照着真实依赖的失败模式补,别把四档当成清单终点。第二,注入环境必须与生产隔离。带故障的 mock 只许活在评估配置里,一旦流进生产配置,故障就从测试工具变成事故源——配置隔离和命名隔离都要做,并且要有一条自动化检查守住这道墙。第三,措辞断言天然对模型敏感。「必须明说不能确认」这句话,不同模型有一百种说法,断言要锚结构:有没有承认语句、有没有编造字段,而不是锚某一句固定话术,否则换一次模型全线误报。第四,注入测的是「出错之后的行为」,测不了「出错之前的判断」——错误该不该发生,仍要靠覆盖充分的正常路径用例。

工具永远健康的世界里,错误恢复只是口号;把工具搞挂的那次评估,才是它第一次被真的测过。

本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。

相关文章
|
18天前
|
SQL 人工智能 自然语言处理
淘宝 AI 购物助手:基于 LLM-as-a-Judge 的在线评测与质量归因实践
淘宝技术为AI购物助手构建了基于LLM-as-a-Judge的在线自动评测体系,通过生产会话清洗、分布式批量推理、六层Rubric标准及人工校准,实现购后服务多业务域的日级质量监控,支撑AI Agent持续可信演进。
淘宝 AI 购物助手:基于 LLM-as-a-Judge 的在线评测与质量归因实践
|
1月前
|
运维 监控 安全
国家评测机构首次给智能体分五级:这套五维框架,测试团队明天就能抄成上线验收清单
智能体上线评审常陷“五人五义”困局。全国首个五级智能体评测证书揭示破局关键:将主观判断拆为功能性、稳定性、安全、工程化、场景适配五大可证维度,每维设独立判据与证据链,推动验收从经验走向可审计、可复现、可追责。(239字)
国家评测机构首次给智能体分五级:这套五维框架,测试团队明天就能抄成上线验收清单
|
1月前
|
自然语言处理 安全 测试技术
别再只测『答得对不对』:给大模型应用建一套 Prompt 注入红队回归集,把越权/泄密挡在上线前
本文揭示RAG客服应用因缺乏Prompt注入防护而致系统提示词泄露的事故,指出问题根源在于测试只关注“答得对”,却忽视“会不会答不该答的”。提出将注入测试升级为可回归的红队用例集:结构化存于jsonl,覆盖四类注入;用pytest参数化断言输出、工具调用与拒答行为;接入CI自动拦截。安全不是模型天赋,而是靠可执行、可演进的断言守出来的。
别再只测『答得对不对』:给大模型应用建一套 Prompt 注入红队回归集,把越权/泄密挡在上线前
|
1月前
|
JavaScript 前端开发 测试技术
对比度不足、缺 alt、缺 label:把 axe-core 挂进 Playwright,用 CI 门禁拦下 WCAG 违规
本文详解如何将 axe-core 无障碍扫描集成到 Playwright 测试中,利用浏览器原生 accessibility tree 自动检测 WCAG 违规(如对比度不足、缺 alt/label、标题跳级等),并通过 CI 基线门禁拦截新增问题,让无障碍从“上线后被投诉”变为“合并前被拦截”。
对比度不足、缺 alt、缺 label:把 axe-core 挂进 Playwright,用 CI 门禁拦下 WCAG 违规
|
1月前
|
消息中间件 安全 测试技术
只断言最终态等于放弃中间可测性:把 Behavioral Evaluation 翻译成 pytest 里的 Trajectory
本文介绍Agent测试新范式——行为评估(Behavioral Evaluation):摒弃仅校验最终结果的“outcome-only”方式,转而对工具调用轨迹(Trajectory)进行三层断言——工具选择、调用顺序与参数、过程与结果一致性。通过jsonl落库、pytest回归、CI门禁,实现可复现、可归因、防蒙对的高可信测试,让Agent能力而非运气成为上线依据。
只断言最终态等于放弃中间可测性:把 Behavioral Evaluation 翻译成 pytest 里的 Trajectory
|
21天前
|
人工智能 监控 测试技术
AI Coding 质量治理:工程规范、代码评审与风险驱动测试
本文基于31万行代码重构实践,提出AI Coding时代质量保障五大支柱:统一AI Rule与工程规范、固化Skill应对重复任务、AI辅助技术债排查、前置AI Code Review、风险驱动的测试设计,并倡导渐进式重构。强调AI提效不等于质量自动提升,需以标准、验证与闭环体系筑牢质量防线。
AI Coding 质量治理:工程规范、代码评审与风险驱动测试
|
1月前
|
人工智能 缓存 数据库
常青翻新|Mock 不是万能替身:Dummy/Stub/Spy/Mock/Fake 五种 Test Double 的边界与踩坑
本文厘清测试替身的五大分类(Dummy/Stub/Spy/Mock/Fake),指出滥用“万能Mock”导致测试脆弱或假绿的根源:混淆“提供数据”与“验证交互”。强调选型核心原则——**先明确断言对象(数据?交互?真实行为?),再决定替身类型**,并结合AI场景(如Agent轨迹验证、假模型替代)赋予经典模式新生命力。
|
1月前
|
人工智能 安全 开发者
Jev 发布不到一周,为什么它这么快进入 Agent 工程?
Jev 是专为 Agent 设计的轻量级决策模型,不生成文本,专注快速输出 Choice/Score/Boolean。它被 Vercel AI Gateway、LangChain 等迅速集成,用于路由、流程控制、安全守卫和评估等高频判断场景,显著降本增效,推动 Agent 架构向“分层智能”演进。
Jev 发布不到一周,为什么它这么快进入 Agent 工程?
|
1月前
|
人工智能 安全 测试技术
Jev 与概率校准:AI 决策系统该怎么测试?
Jev是TypeSafe推出的“系统一模型”,专注结构化决策:不生成文本,只输出带概率与置信度的选择、评分或是非判断。其核心价值在于可校准的可靠性——让程序知悉AI“有多确定”,从而安全实现自动分支、风险拦截与人机协同。(239字)
Jev 与概率校准:AI 决策系统该怎么测试?

热门文章

最新文章