Agent 半夜陷入死循环,一夜烧掉上万 token——轨迹测试与熔断

简介: AI测试开发高频题:测Agent≠测接口,核心是验证“决策链是否失控”。本文以深夜烧万元的真实事故切入,详解如何通过轨迹记录、循环检测与三重熔断(步数/Token/时间)保障Agent可靠性,并将“不失控”写入自动化测试用例。

AI 测试开发面试高频题:"测 Agent 和测普通接口有什么本质区别?"
普通接口测的是"一次调用对不对",Agent 测的是"一条决策链会不会失控"。这篇用一次半夜烧钱的真实事故,讲轨迹测试和熔断怎么设计。

一、真实事故:两个工具的结论打架,Agent 在中间荡了一夜秋千

某电商公司的售后 Agent 负责自动处理物流异常:先调 query_order 查订单状态,再调 check_logistics 核实物流,确认异常就创建工单。上线第一周风平浪静,第八天早上,财务同学看着 token 账单找上门:一晚上一个任务烧掉了平时一个月的量,粗算上万元。

拉出那个任务的完整调用日志,画面非常荒诞:

00:12  query_order      → {"status": "物流异常"}
00:12  check_logistics  → {"status": "正常"}
00:13  query_order      → {"status": "物流异常"}
00:13  check_logistics  → {"status": "正常"}
……(重复 1,700 多次,直到 07:40 被值班同学手动停掉)

两个工具的结论互相矛盾,模型每次都"认真"地想 reconcile 这个矛盾:信 A 就去问 B,信 B 就去问 A,永远对不上,永远不放弃。没有步数上限、没有预算上限、没有循环检测——三个保险一个都没装,于是它兢兢业业地荡了一夜秋千。

复盘结论很明确:Agent 的失控不是模型"变笨了",而是系统没给它的决策链设边界。 模型可以犹豫,系统必须兜底。

二、思路:给决策链做三件事——记录、检测、熔断

轨迹(trajectory)就是 Agent 的"作案录像":每一步打算调什么工具、传什么参数、观察到什么。有了录像才能做三件事:

  1. 记录:每步落盘,事后可回放;
  2. 检测:识别"重复调用"和"A-B-A-B 振荡"两类典型死循环;
  3. 熔断:步数、token 预算、墙钟时间,任何一条越线立即终止。

三、核心代码:轨迹记录 + 循环检测 + 三重熔断

第 1 步:轨迹记录与循环检测

import hashlib, time
from dataclasses import dataclass, field

def _h(x):  # 参数/观察结果归一化取哈希,忽略 dict 顺序差异
    return hashlib.md5(repr(sorted(x.items()) if isinstance(x, dict) else x)
                       .encode()).hexdigest()

@dataclass
class Trajectory:
    steps: list = field(default_factory=list)

    def record(self, tool, args, observation):
        self.steps.append({
   "tool": tool, "args": _h(args),
                           "obs": _h(observation), "ts": time.time()})

    def detect_loop(self):
        sig = [(s["tool"], s["args"], s["obs"]) for s in self.steps]
        # 类型一:同一步原地踏步,连续 3 次
        if len(sig) >= 3 and len(set(sig[-3:])) == 1:
            return "stuck"
        # 类型二:A→B→A→B 振荡,连续 4 步两两相同
        if len(sig) >= 4 and sig[-4] == sig[-2] and sig[-3] == sig[-1] \
                and sig[-4] != sig[-3]:
            return "oscillate"
        return None

注意 detect_loop 把观察结果的哈希也算进签名:事故里那种"参数相同、返回相同、还在重复问"的情况,obs 哈希一致才能精准命中;如果模型每次换着花样问但观察结果不变,同样会被 stuck 规则抓住。

第 2 步:带熔断的执行器

def run_agent_with_guard(task, max_steps=8, token_budget=20_000, timeout_s=120):
    traj, total_tokens, start = Trajectory(), 0, time.time()

    for step in range(max_steps):                       # 熔断一:步数上限
        if time.time() - start > timeout_s:             # 熔断二:墙钟超时
            return finish(traj, total_tokens, "timeout")
        if total_tokens > token_budget:                 # 熔断三:token 预算
            return finish(traj, total_tokens, "token_budget")

        action, tokens = agent.plan(task, traj.steps)   # 模型决策
        total_tokens += tokens
        observation = execute(action)                   # 执行工具
        traj.record(action["tool"], action["args"], observation)

        if loop := traj.detect_loop():                  # 循环检测提前终止
            return finish(traj, total_tokens, f"loop:{loop}")
        if agent.is_done(observation):
            return finish(traj, total_tokens, "success")

    return finish(traj, total_tokens, "max_steps")

事故任务如果跑在这个执行器里,第 4 步就会命中 oscillate 熔断,成本从一夜上万元变成几分钱。熔断之后不是简单报错,而是降级:把轨迹和矛盾点打包升级给人工("query_order 与 check_logistics 结论冲突,请人工介入")——Agent 允许放弃,不允许空转。

第 3 步:把"不失控"写成测试用例

def test_conflicting_tools_never_loop():
    """两个工具结论矛盾时,Agent 必须在预算内终止并升级人工"""
    with mock_tools({
   
        "query_order":     {
   "status": "物流异常"},
        "check_logistics": {
   "status": "正常"},
    }):
        r = run_agent_with_guard("核查订单 A1002 的物流异常并处理")

    assert r.reason != "max_steps", "跑满步数上限,说明循环检测没生效"
    assert r.steps <= 6, f"决策步数 {r.steps} 超出预期"
    assert r.total_tokens < 20_000, "单任务成本失控"
    assert r.escalated_to_human, "矛盾场景必须升级人工,不允许猜"

def test_normal_task_still_succeeds():
    """熔断不能误伤正常任务:黄金任务集成功率不降"""
    with mock_tools(happy_path_tools):
        r = run_agent_with_guard("查询订单 A1001 状态并回复用户")
    assert r.reason == "success" and r.steps <= 4

第二条用例同样重要:熔断是刹车,刹车太灵车就没法开。 每次收紧阈值,必须用黄金任务集验证成功率没有掉。

四、沉淀成方法:Agent 测试三层 + 线上监控

层级 测什么 核心指标
单步契约层 每次工具调用参数合法吗(见第 4 篇) 参数非法率、重试收敛率
轨迹断言层 决策链合理吗 任务成功率、步数 P95、循环率、单任务 token 成本
熔断与监控层 线上失控能秒级发现吗 熔断触发率、token 消耗曲线告警、轨迹全量可回放

三条工程纪律:一是轨迹全量落日志,工具名 + 参数 + 观察结果 + token 数,出事能像这次一样完整回放;二是熔断阈值从数据来:用黄金任务集跑出步数分布,取 P95 × 1.5 作为 max_steps,token 预算同理,拍脑袋的阈值要么漏报要么误伤;三是熔断触发率本身是发布指标,新版本熔断率明显升高,说明模型决策质量退化,和成功率下降同等严重。

五、面试追问,你答得上来吗

  1. 测 Agent 和测普通接口的本质区别是什么?——答:接口是"一次调用一个契约",断言输入输出即可;Agent 是"一条不确定的决策链",要断言轨迹行为——目标是否达成、路径是否合理(步数、有无循环)、成本是否受控,并且必须给系统装熔断,因为 Agent 的失败模式不是"返回错误",而是"停不下来"。
  2. 怎么定义"Agent 完成了任务"?——答:把目标翻译成可验证的终态谓词:比如"工单已创建且字段正确"直接查工单系统,不靠模型自评;主观目标用 LLM 裁判 + 人工抽检验证。终态能查系统的查系统,查不了的才用裁判。
  3. 循环检测会不会误判"合理的重复"(比如分页翻查同一工具)?——答:会,所以签名里带参数和观察结果哈希:分页调用参数不同,不会命中 stuck;真正该抓的是"参数相同、观察相同、还在重复"。再配合黄金任务集回归误伤率,检测规则和熔断阈值一样,都是要被测试的组件。

下一篇预告:《流式输出只显示半句话——SSE 流式接口的测试点》

相关文章
|
18天前
|
人工智能 自然语言处理 供应链
API接口:为AI装上“手脚”,打通数字世界的“任督二脉
API是AI的“神经系统”与“执行层”,赋能大模型从思考走向行动。作为AI Agent调用外部工具的核心载体,它支撑任务拆解、工具调用与结果整合。通过统一接入、MCP协议、API网关等模式,API正构建繁荣AI生态,并在电商等场景实现智能选品、对话购物与供应链协同。
|
18天前
|
安全 Java API
Spring Boot 3.5月底停维了,4.0迁移的五个坑你踩了没
Spring Boot 3.5已于2026年6月终止支持,升级至4.0刻不容缓。本文详解迁移五大关键坑:虚拟线程默认化、Starter模块化重构、Jackson 3升级、JSpecify空安全强化、Spring Framework 7原生API版本控制,助你规避踩坑,平稳过渡。
|
18天前
|
安全 关系型数据库 MySQL
切换从32秒缩到10秒,MHA到InnoDB Cluster升级复盘
从MHA停维护近十年、份额跌至12%的现实切入,完整记录从MHA一主两从升级到InnoDB Cluster的路径,含MySQL Shell建集群、Router切换、数据迁移与验证下线
|
18天前
|
人工智能 IDE API
TokenPlan 套餐焕新上线!四大 AI 场景组合购,算力 + 云产品成套采购,最低 43.45 元起
阿里云TokenPlan焕新上线,推出四大AI场景组合购(Coding/Agent托管/轻量部署等),43.45元起,一站式集成Qwen3.8-Max旗舰模型(2.4T参数)、算力Credits与云资源,支持夜间错峰折扣,开箱即用,大幅降低AI开发配置与成本。
|
18天前
|
人工智能 运维 Rust
Codex终端AI编程助手完整实操|功能详解、跨平台部署与百炼Coding Plan、Token Plan接入教程
软件工程迭代速度持续加快,传统IDE普遍存在体积庞大、启动缓慢、操作流程繁琐等问题。各类图形界面AI编码插件高度依赖可视化操作环境,无法适配纯终端远程服务器开发、轻量化脚本快速迭代、服务器运维编码等真实业务场景。市面上多数终端编程工具功能较为单薄,仅支持简单代码补全,缺失项目全局理解、多步骤任务自主执行、批量工程重构、安全沙箱防护等高阶能力,同时海外模型还会遇到网络访问不稳定、成本难以管控、不符合国内合规开发体系等一系列现实阻碍。
170 0
|
18天前
|
缓存 人工智能 API
DeepSeek‑V4完整实操指南|Flash/Pro双模型参数、计费规则、缓存机制与API调用实战
超长上下文大模型一直存在两大行业痛点,要么推理速度缓慢,无法支撑高并发实时业务,要么调用成本居高不下,中小企业很难大规模落地。DeepSeek‑V4系列采用双版本差异化产品策略,同时推出deepseek‑v4‑flash与deepseek‑v4‑pro两款MoE混合专家架构模型,分别面向轻量化高频业务、复杂深度推理两大应用方向,全系标配100万Token超长上下文窗口,将百万级长文本处理能力下放到普通开发者与中小企业,打破长上下文大模型的落地门槛。
276 0
|
18天前
|
人工智能 运维 IDE
零成本AI编程实战|Qoder CN免费社区版全解,额度规则、多端部署与CLI实操命令完整指南
AI赋能研发已经成为软件开发领域的主流趋势,AI编码助手可以极大降低重复编码工作量,提升学习与开发效率。但市面上大量高质量AI编程工具普遍采用订阅付费模式,对于编程学生、业余爱好者、初级开发者来说,长期订阅会带来不小的经济负担,抬高了AI编程的入门门槛。为了普惠广大基层开发群体,降低AI编程落地门槛,原通义灵码完成品牌迭代升级,正式更名为Qoder CN,并且推出永久可用的免费社区版本。该版本配套独立Credits额度体系,普通用户不需要付费订阅,就可以使用专业级AI编码智能体能力,覆盖代码学习、脚本编写、小型项目开发、代码调试等轻量化开发场景。
375 0
|
18天前
|
人工智能 自然语言处理 API
阿里云Token Plan怎么样?支持模型与AI工具,收费标准及最新活动参考
阿里云Token Plan凭借 统一计量、多模态覆盖、工具兼容性强、数据安全可靠 等优势,已成为个人与企业拥抱AI生产力的理想入口。
|
17天前
|
人工智能 监控 测试技术
大促流量一来,大模型服务就卡——推理性能压测
本文揭秘大模型性能测试核心差异:告别传统QPS/RT,聚焦TTFT(首字延迟)、TPOT(逐字间隔)等流式指标。通过真实大促事故(首字延迟从0.8秒飙至15秒),剖析容量规划缺失、KV cache打满、无降级等痛点,并给出阶梯压测、拐点识别、混长文本等实战方法,助你应对AI面试高频题。