引子

你有没有遇到过这种情况:Agent 跑挂了,翻半天日志也不知道该怪谁?模型?Prompt?还是工具?

一个电商数据分析智能体执行"生成 5 月销售报告"任务失败,团队争论了 2 小时。

开发说是模型问题,测试说是 Prompt 问题,运维说是工具问题。最后查日志发现,是规划阶段 LLM 返回的 JSON 格式错误,解析失败导致后续全部跳过——智能体连 search(经营类) 都没调用就直接进入写报告/总结。

如果有缺陷分类体系,这个问题 5 分钟就能定位:规划缺陷 → LLM 输出格式不稳定 → Prompt 加格式约束。

传统软件的 Bug 分类按模块分(登录模块、支付模块)。智能体的 Bug 不按模块分,按执行阶段分(规划、执行、反思、总结)。同一个模块的 Bug,在不同阶段根因完全不同。

这篇文章讲智能体 Bug 的 7 大类型,以及怎么快速定位根因。

智能体 Bug 的 7 大类型

类型一:规划缺陷(占比 25%)

规划阶段的问题。智能体接到任务后,拆解不合理。

子类型 表现 根因 修复方向
子任务数量失控 >10 个或 <2 个 Prompt 没有限制数量 Prompt 加约束
依赖遗漏 task_2 需要 task_1 但没写依赖 LLM 未识别依赖 Prompt 加示例
依赖环 A→B→A LLM 逻辑错误 环检测 + 报错
工具选择错误 用 calculator 做文本处理 工具描述不清晰 优化工具描述
规划解析失败 JSON 格式错误 LLM 输出格式不稳定 JSON 解析容错

电商场景示例:智能体接到"生成月度销售报告"任务,规划出"先写报告总结,再查销售数据"——依赖顺序完全反了,报告里全是空数据。

类型二:工具缺陷(占比 20%)

工具调用阶段的问题。工具选对了但用错了。

子类型 表现 根因 修复方向
工具不存在 调用 "web_search" LLM 幻觉 Prompt 列出可用工具
参数格式错误 calculator: "2+3*" LLM 参数生成错误 参数验证 + 重试
参数类型错误 calculator: "abc" LLM 不理解工具用途 工具描述加示例
工具冲突 同时调用两个互斥工具 规划阶段未检查 工具互斥检查

电商场景示例:智能体需要分析 CSV 格式的销售数据,却用 web_fetch 去抓整页 HTML,而不是先用 search(经营 Mock) 或 code_executor 读结构化数据——工具选错了,数据根本读不到。

类型三:执行缺陷(占比 15%)

工具执行阶段的问题。工具调用成功了但结果不对。

子类型 表现 根因 修复方向
工具超时 调用超过 10 秒 外部服务慢 超时重试
工具返回错误 工具返回错误信息 外部服务异常 错误处理 + 换工具
代码执行错误 代码跑不通 生成的代码有 bug 代码验证 + 调试
数据格式错误 工具输出格式不匹配 工具间数据传递问题 格式转换

电商场景示例:智能体用 code_executor 计算客单价,生成的代码把订单量(1200 单)当成销售额(1200 元)来除——数据读对了,但计算逻辑写错了,客单价结果完全不对。

类型四:记忆缺陷(占比 10%)

上下文保持的问题。智能体忘了之前提到的信息。

子类型 表现 根因 修复方向
信息遗忘 第 8 轮忘了第 1 轮的信息 上下文窗口截断 扩大窗口或摘要压缩
指代错误 "它"指向错误的实体 注意力分散 指代消解优化
话题丢失 切回去不记得原话题 上下文管理混乱 话题标记
记忆污染 其他对话的信息混入 状态未隔离 每次测试前 reset

电商场景示例:用户第一轮说"帮我按月统计销售额",智能体在第五轮生成报告时却按天统计了——多轮对话中忘记了一开始约定的统计维度。

类型五:知识缺陷(占比 15%)

知识准确性问题。智能体编造答案。

子类型 表现 根因 修复方向
事实错误 回答与事实不符 模型知识不足 RAG 检索增强
幻觉 编造不存在的信息 LLM 通病 幻觉检测 + 拒绝
推理错误 推理过程不合理 模型推理能力不足 思维链提示
过时信息 使用过时的数据 模型训练数据截止 联网检索

电商场景示例:用户问"5 月销售额同比增速是多少",智能体把同比(今年 5 月 vs 去年 5 月)算成了环比(今年 5 月 vs 今年 4 月)——业务知识理解错了,分析结论全偏了。

类型六:安全缺陷(占比 10%)

安全问题。智能体被攻击或输出有害内容。

子类型 表现 根因 修复方向
有害内容输出 输出暴力/色情内容 安全过滤不足 加强关键词过滤
Prompt注入成功 系统提示被覆盖 注入检测不足 加强注入检测
Jailbreak成功 角色扮演绕过安全 Jailbreak检测不足 加强Jailbreak检测
隐私泄露 输出敏感信息 隐私检测不足 加强隐私检测

电商场景示例:智能体生成的销售报告中直接明文展示了客户手机号(138****→13812345678),没有做脱敏处理——客户隐私数据泄露,合规风险极高。

类型七:性能缺陷(占比 5%)

性能问题。智能体能完成任务但太慢或太贵。

子类型 表现 根因 修复方向
延迟过高 P90 > 30s 子任务太多或工具慢 减少子任务、优化工具
Token消耗过大 单次 > 8000 Prompt 太长或反思太多 精简 Prompt、减少反思
并发能力差 10 并发成功率 <80% 无并发控制 限流 + 队列
内存泄漏 长时间运行 OOM 状态未清理 定期 reset

电商场景示例:智能体执行"大促期间异常订单预警"任务,对每个订单都单独调用 search 拉详情,而不是批量聚合——1000 个订单跑了 5 分钟,Token 消耗 12000+,用户体验极差。

根因定位流程

缺陷现象(失败/错误/慢)
    ↓
检查日志 → 定位阶段(规划/执行/反思/总结)
    ↓
定位原因(Prompt/工具/模型/环境)
    ↓
分类(7 大类型)
    ↓
修复 → 回归验证

定位步骤:

  1. 看日志:哪个阶段失败?规划、执行、还是总结?比如是 search(经营) 没调用,还是 search(报告)/总结输出异常?
  2. 看错误信息:是 JSON 解析错误、工具调用错误、还是 LLM 返回错误?比如 "search 参数缺失" 还是 "代码执行超时"?
  3. 看上下文:是偶发还是必现?换 temperature 还复现吗?比如每次生成月度报告都失败,还是偶尔失败?
  4. 定位根因
    • 规划阶段失败 → 规划缺陷 → 检查 Prompt(比如任务拆解是否合理、依赖顺序是否正确)
    • 执行阶段失败 → 工具缺陷/执行缺陷 → 检查工具配置(比如 search 的 tool_input、calculator 表达式)
    • 总结阶段失败 → 知识缺陷/记忆缺陷 → 检查上下文(比如同比环比是否搞混、统计维度是否遗忘)
    • 全程失败 → 安全缺陷/性能缺陷 → 检查安全配置/性能配置(比如客户手机号是否脱敏、查询是否批量优化)

严重度与优先级标准

严重度 定义 优先级 修复 SLA 示例
Critical 系统崩溃、数据丢失、安全漏洞 P0 24 小时 客户手机号明文泄露、Prompt 注入成功
High 核心功能失败、成功率 <50% P1 3 天 月度报告规划解析失败、search 全失败
Medium 非核心功能失败、成功率 50-80% P2 1 周 子任务数量失控、同比算成环比
Low 体验问题、性能轻微下降 P3 2 周 报告格式不美观、大促预警延迟略高

代码:缺陷分类与根因定位

#!/usr/bin/env python3
"""
电商数据分析智能体 - 缺陷分类与根因定位

功能:
1. 缺陷自动分类(7 大类型)
2. 根因定位辅助
3. 严重度评估
"""

from typing import Dict, List, Optional
from dataclasses import dataclass, field


# 缺陷分类字典
DEFECT_CATALOG = {
    "规划缺陷": {
        "keywords": ["规划", "子任务", "依赖", "JSON", "解析"],
        "phases": ["planning"],
        "severity": "Medium",
        "ecommerce_example": "智能体先写报告再查数据——依赖顺序错误",
    },
    "工具缺陷": {
        "keywords": ["工具", "不存在", "参数", "格式"],
        "phases": ["executing"],
        "severity": "High",
        "ecommerce_example": "用 web_fetch 抓整页而不是 search/code_executor 读数",
    },
    "执行缺陷": {
        "keywords": ["超时", "失败", "错误", "代码"],
        "phases": ["executing"],
        "severity": "High",
        "ecommerce_example": "计算客单价时把订单量当成销售额",
    },
    "记忆缺陷": {
        "keywords": ["遗忘", "指代", "话题", "上下文"],
        "phases": ["executing", "summarizing"],
        "severity": "Medium",
        "ecommerce_example": "多轮对话中忘记用户说的是按月统计",
    },
    "知识缺陷": {
        "keywords": ["幻觉", "编造", "错误", "不准确"],
        "phases": ["summarizing"],
        "severity": "Medium",
        "ecommerce_example": "把同比算成环比",
    },
    "安全缺陷": {
        "keywords": ["安全", "注入", "Jailbreak", "有害"],
        "phases": ["planning", "executing"],
        "severity": "Critical",
        "ecommerce_example": "报告中明文展示客户手机号",
    },
    "性能缺陷": {
        "keywords": ["超时", "延迟", "Token", "内存", "OOM"],
        "phases": ["planning", "executing", "summarizing"],
        "severity": "Low",
        "ecommerce_example": "逐条查询订单而不是批量查询,Token 消耗过大",
    },
}


def classify_defect(log: Dict, error: str = "") -> Dict:
    """
    根据日志和错误信息自动分类缺陷

    Args:
        log: 智能体日志
        error: 错误信息

    Returns:
        {
            "type": 缺陷类型,
            "phase": 阶段,
            "severity": 严重度,
            "confidence": 置信度,
            "likely_causes": 可能的根因,
        }
    """
    # 合并日志和错误信息
    text = error.lower()
    phase = log.get("phase", "")

    best_match = None
    best_score = 0

    for defect_type, catalog in DEFECT_CATALOG.items():
        score = 0

        # 关键词匹配
        for keyword in catalog["keywords"]:
            if keyword.lower() in text:
                score += 1

        # 阶段匹配
        if phase in catalog["phases"]:
            score += 2

        if score > best_score:
            best_score = score
            best_match = defect_type

    if not best_match:
        best_match = "未知缺陷"

    # 置信度
    confidence = min(best_score / 5.0, 1.0)

    # 可能的根因
    likely_causes = _get_likely_causes(best_match)

    return {
        "type": best_match,
        "phase": phase,
        "severity": DEFECT_CATALOG.get(best_match, {}).get("severity", "Medium"),
        "confidence": confidence,
        "likely_causes": likely_causes,
    }


def _get_likely_causes(defect_type: str) -> List[str]:
    """获取可能的根因"""
    causes = {
        "规划缺陷": [
            "Prompt 中未限制子任务数量",
            "Prompt 中缺少依赖关系示例",
            "LLM 输出格式不稳定",
            "JSON 解析容错不足",
        ],
        "工具缺陷": [
            "Prompt 中未列出可用工具(search / calculator / code_executor / …)",
            "工具描述不清晰",
            "参数验证不足",
            "LLM 不理解工具用途",
        ],
        "执行缺陷": [
            "search 调用超时",
            "工具返回错误未处理",
            "生成的计算代码有 bug(如客单价公式错误)",
            "数据格式不匹配",
        ],
        "记忆缺陷": [
            "上下文窗口截断",
            "指代消解能力不足",
            "状态未隔离",
            "话题管理混乱(如忘记统计维度)",
        ],
        "知识缺陷": [
            "模型电商知识不足(如同比环比混淆)",
            "幻觉检测不足",
            "训练数据过时",
            "缺少 RAG 检索",
        ],
        "安全缺陷": [
            "安全关键词过滤不足",
            "注入检测规则不完善",
            "Jailbreak 检测不足",
            "隐私检测不足(如客户手机号未脱敏)",
        ],
        "性能缺陷": [
            "子任务数量过多",
            "Prompt 过长",
            "反思次数过多",
            "未批量查询导致 Token 消耗过大",
        ],
    }
    return causes.get(defect_type, ["未知根因"])


def assess_severity(defect_type: str, success_rate: float,
                    error_count: int) -> Dict:
    """
    评估严重度

    Args:
        defect_type: 缺陷类型
        success_rate: 成功率
        error_count: 错误数量

    Returns:
        {
            "severity": 严重度,
            "priority": 优先级,
            "sla": 修复 SLA,
        }
    """
    # 安全缺陷直接 Critical
    if defect_type == "安全缺陷":
        return {"severity": "Critical", "priority": "P0", "sla": "24 小时"}

    # 基于成功率评估
    if success_rate < 0.5:
        severity = "High"
        priority = "P1"
        sla = "3 天"
    elif success_rate < 0.8:
        severity = "Medium"
        priority = "P2"
        sla = "1 周"
    else:
        severity = "Low"
        priority = "P3"
        sla = "2 周"

    # 错误数量增加严重度
    if error_count > 10:
        if severity == "Low":
            severity = "Medium"
            priority = "P2"
            sla = "1 周"

    return {"severity": severity, "priority": priority, "sla": sla}


def print_defect_report(defects: List[Dict]):
    """打印缺陷报告"""
    print(f"\n{'='*60}")
    print(f"电商数据分析智能体 - 缺陷分类与根因分析报告")
    print(f"{'='*60}")

    # 按类型统计
    type_counts = {}
    for d in defects:
        t = d["type"]
        type_counts[t] = type_counts.get(t, 0) + 1

    print(f"\n缺陷分布:")
    for t, count in sorted(type_counts.items(), key=lambda x: -x[1]):
        print(f"  {t}: {count} 个")

    # 按严重度统计
    severity_counts = {}
    for d in defects:
        s = d["severity"]
        severity_counts[s] = severity_counts.get(s, 0) + 1

    print(f"\n严重度分布:")
    for s in ["Critical", "High", "Medium", "Low"]:
        count = severity_counts.get(s, 0)
        if count > 0:
            print(f"  {s}: {count} 个")

    # 缺陷详情
    print(f"\n缺陷详情:")
    for i, d in enumerate(defects[:15], 1):
        print(f"  {i}. [{d['severity']}] {d['type']} (置信度 {d['confidence']:.0%})")
        print(f"     可能根因: {', '.join(d['likely_causes'][:2])}")

    print(f"{'='*60}\n")


def run_demo():
    """演示 - 电商数据分析智能体缺陷场景"""
    print("=" * 60)
    print("电商数据分析智能体 - 缺陷分类与根因定位演示")
    print("=" * 60)

    # 模拟电商场景缺陷日志
    mock_defects = [
        {"phase": "planning", "error": "JSON 解析失败:月度报告子任务数量 12 个"},
        {"phase": "executing", "error": "工具 'browser_read' 不适用于 CSV 分析,应使用 code_executor 或 search"},
        {"phase": "executing", "error": "search 执行超时(10 秒限制)"},
        {"phase": "summarizing", "error": "促销效果分析输出过短,缺少关键指标"},
        {"phase": "planning", "error": "安全拦截:检测到 Prompt注入"},
        {"phase": "executing", "error": "代码执行失败:客单价计算中 order_count 字段误用为 sales_amount"},
        {"phase": "planning", "error": "依赖环检测:查询数据 → 生成报告 → 查询数据"},
        {"phase": "executing", "error": "search(报告类)执行超时(10 秒限制)"},
        {"phase": "summarizing", "error": "幻觉检测:编造了不存在的销售数据(618 大促数据在 5 月报告中)"},
        {"phase": "planning", "error": "JSON 解析失败:格式错误"},
        {"phase": "executing", "error": "安全拦截:报告中明文展示客户手机号 13812345678"},
        {"phase": "summarizing", "error": "记忆缺陷:用户要求按月统计,结果按天输出了"},
        {"phase": "summarizing", "error": "知识缺陷:同比增速计算错误,实际是环比增速"},
        {"phase": "executing", "error": "性能缺陷:逐条查询 1000 个订单详情,Token 消耗 12000+"},
    ]

    defects = []
    for log in mock_defects:
        result = classify_defect(log, log["error"])
        severity = assess_severity(result["type"], 0.7, len(mock_defects))
        result.update(severity)
        defects.append(result)

    print_defect_report(defects)

    print("=" * 60)


if __name__ == "__main__":
    run_demo()

数据:缺陷分布统计

下表为教学示意分布(与文首声明一致)。本轮 DeepSeek 实测(第 16 篇 MVP)已观察到的真实缺陷类型:规划缺陷(子任务数量 12 / 18)。样本不足以重算七类占比。

对示意用的 100 个缺陷样本的分类统计:

缺陷类型 数量 占比 平均定位时间
规划缺陷 25 25% 8 分钟
工具缺陷 20 20% 5 分钟
执行缺陷 15 15% 12 分钟
知识缺陷 15 15% 15 分钟
记忆缺陷 10 10% 10 分钟
安全缺陷 10 10% 3 分钟
性能缺陷 5 5% 20 分钟

有分类体系 vs 无分类体系的根因定位时间对比:

缺陷类型 无分类体系 有分类体系 改善
规划缺陷 25 分钟 8 分钟 3 倍
工具缺陷 15 分钟 5 分钟 3 倍
执行缺陷 30 分钟 12 分钟 2.5 倍
知识缺陷 40 分钟 15 分钟 2.7 倍
安全缺陷 10 分钟 3 分钟 3.3 倍
平均 24 分钟 8.6 分钟 2.8 倍

交付物

1. 缺陷分类字典(7 大类型,35 个子类型)

类型 子类型数 关键词 阶段 严重度
规划缺陷 5 规划、子任务、依赖、JSON planning Medium
工具缺陷 4 工具、不存在、参数 executing High
执行缺陷 4 超时、失败、代码 executing High
记忆缺陷 4 遗忘、指代、上下文 executing/summarizing Medium
知识缺陷 4 幻觉、编造、错误 summarizing Medium
安全缺陷 4 安全、注入、Jailbreak planning/executing Critical
性能缺陷 4 超时、延迟、Token 全阶段 Low

2. 根因定位流程图

缺陷现象
  ↓
检查日志 → 定位阶段
  ↓
定位原因(Prompt/工具/模型/环境)
  ↓
分类(7 大类型)
  ↓
查找可能根因(每个类型 4 个可能根因)
  ↓
修复 → 回归验证

3. 严重度/优先级标准表

严重度 定义 优先级 SLA 示例
Critical 系统崩溃、安全漏洞 P0 24 小时 客户手机号明文泄露、Prompt 注入成功
High 核心功能失败、成功率 <50% P1 3 天 月度报告规划解析失败、search 全失败
Medium 非核心功能失败、成功率 50-80% P2 1 周 子任务数量失控、同比算成环比
Low 体验问题、性能轻微下降 P3 2 周 报告格式不美观、大促预警延迟略高

4. 缺陷记录模板

字段 说明
ID 缺陷编号(DEF-001)
类型 7 大类型之一
子类型 35 个子类型之一
严重度 Critical/High/Medium/Low
优先级 P0/P1/P2/P3
阶段 planning/executing/reflecting/summarizing
描述 缺陷描述
可能根因 4 个可能根因
实际根因 定位后的实际根因
修复方案 修复方法
状态 新建/修复中/已修复/已验证

总结

智能体的 Bug 和传统软件 Bug 不同,需要新的分类体系。7 大类型覆盖规划、工具、执行、记忆、知识、安全、性能。

以电商数据分析智能体为例:规划缺陷可能导致"先写报告再查数据",工具缺陷可能让智能体用 web_fetch 读整页而不是 search/code_executor 取数,知识缺陷可能把同比算成环比——每种缺陷都有对应的定位方法和修复方向。

有分类体系 vs 无分类体系:根因定位时间从 24 分钟降到 8.6 分钟,改善 2.8 倍。

核心流程:看日志 → 定位阶段 → 定位原因 → 分类 → 查找可能根因 → 修复 → 回归验证。

下一篇是最后一篇:测试报告与质量门禁。


面试题模块

Q1:智能体 Bug 的 7 大类型中,哪种最难排查?

A:上下文污染。因为它的表现非常隐蔽——任务 A 跑过了,任务 B 跑挂了,看起来像是两个独立的任务。实际上是因为任务 A 在 Agent 的对话历史中留下了状态,影响了任务 B 的工具选择或参数传递。排查需要完整的检查点日志。

Q2:LLM 幻觉导致的 Bug 怎么和系统 Bug 区分?

A:复现测试。同一条数据跑 5 次,如果每次失败的轮次不同,大概率是 LLM 概率性输出问题。如果每次都在同一个环节失败,且失败模式相同,说明是系统 Bug。幻觉 Bug 很难修复(涉及模型层面),系统 Bug 可以通过改代码解决。

Q3:Agent 的 Bug 优先级怎么定?和传统 Bug 优先级有什么区别?

A:标准类似但多了一个维度——"对用户体验的影响程度"。比如"规划时漏掉一个中间步骤"和"工具调用时报了技术错误",前者对用户体验影响更大(沉默失败),后者至少告知了用户出错。如果 Agent 连"我失败了"都不说,那就是 P0 Bug。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐