ESSAY

如何建立AI工程中的三层测试体系

AI工程 测试驱动开发 全栈开发

“测试不是为了限制 AI,而是为了让 AI 更可靠。“

核心观点 / 起源

今年我做了一个博客自动分发系统,把一篇技术文章同时改写成小红书、LinkedIn、X 和知乎四个平台的内容。听起来很美好,但第一次跑批量测试时,17 篇文章的成功率只有 50%。

问题出在哪?小红书验证通过率 0%,因为 AI 生成了 9 个 emoji(要求 3-5 个)和 10 个 hashtag(要求恰好 3 个)。LinkedIn 平均生成 2800 字,超过了我设定的 2500 字限制。X 的推文有些超过 280 字符,有些忘了附上博客链接。

这不是 AI 能力问题,而是工程问题:如何建立测试体系,确保 AI 输出在代码层、流程层、业务层都可靠?

基于这个项目的实践,我构建了三层测试金字塔:

                ┌─────────────────────┐
                │  业务调性验收测试    │  ← Layer 3: 人工审核 + AI 评估
                │  (Prompt Quality)   │
                └─────────────────────┘

            ┌──────────────────────────┐
            │   Flow 节点联调测试       │  ← Layer 2: 端到端集成
            │   (Integration Test)    │
            └──────────────────────────┘

    ┌────────────────────────────────────┐
    │      单脚本单元测试                 │  ← Layer 1: 函数级验证
    │      (Unit Test)                  │
    └────────────────────────────────────┘

每层测试的目标和发现的问题类型不同:

测试层级测试目标发现问题类型通过率平均耗时
Layer 1: 单元测试验证格式规则和数据处理格式错误、数据类型错误100%< 1 秒
Layer 2: 集成测试验证完整 Flow 数据流转数据流转错误、超时问题100%45 秒
Layer 3: 验收测试验证平台调性和业务质量调性不符、质量问题94%人工审核

关键洞察:Layer 1 快速反馈,捕获 80% 的技术问题;Layer 2 发现集成问题,捕获 15% 的流程问题;Layer 3 发现业务问题,捕获 5% 的质量问题。

细节展开

为什么需要三层而非单层测试?

  • Layer 1(单元测试):快速验证格式规则,1 秒内完成,适合频繁执行
  • Layer 2(集成测试):验证完整流程,45 秒完成,适合发布前验证
  • Layer 3(验收测试):验证业务质量,需要人工审核,适合抽样检查

三层测试不是简单的叠加,而是形成了一个漏斗:Layer 1 过滤掉大部分技术问题,Layer 2 确保流程正常,Layer 3 保证业务质量。

过程 / 推演

Layer 1:单元测试 - 用代码锁死格式规则

单元测试的目标是验证单个 Worker 的格式规则,确保生成内容符合平台的硬性要求。

测试维度

平台核心验证规则测试用例数
小红书Emoji 数量、Hashtag 数量、字数、外链5
X推文数量、每条长度、链接存在3
LinkedIn字数范围、链接存在2
知乎字数范围、链接存在2

代码实现:小红书验证函数

def test_xiaohongshu_validation(self, content: str, validation: Dict) -> bool:
    """测试小红书验证规则"""
    print("\n[测试] 小红书平台验证")
  
    # 测试 emoji 数量
    emoji_count = validation.get("emojiCount", 0)
    emoji_valid = 3 <= emoji_count <= 5
    self.log_test(
        "小红书 - Emoji数量",
        emoji_valid,
        f"Emoji数量: {emoji_count} (要求: 3-5)"
    )
  
    # 测试 hashtag 数量
    hashtag_count = validation.get("hashtagCount", 0)
    hashtag_valid = hashtag_count == 3
    self.log_test(
        "小红书 - Hashtag数量",
        hashtag_valid,
        f"Hashtag数量: {hashtag_count} (要求: 恰好3个)"
    )
  
    # 测试字数
    word_count = validation.get("wordCount", 0)
    word_valid = 200 <= word_count <= 900
    self.log_test(
        "小红书 - 字数限制",
        word_valid,
        f"字数: {word_count} (要求: 200-900)"
    )
  
    # 测试外链
    has_link = validation.get("hasLink", True)
    link_valid = not has_link
    self.log_test(
        "小红书 - 无外链",
        link_valid,
        f"包含外链: {has_link} (要求: False)"
    )
  
    # 测试禁用词
    no_banned = validation.get("noBannedPhrases", False)
    self.log_test(
        "小红书 - 无禁用词",
        no_banned,
        f"禁用词: {validation.get('bannedPhrasesFound', [])}"
    )
  
    return emoji_valid and hashtag_valid and word_valid and link_valid and no_banned

关键设计:每个验证规则独立测试,便于定位问题;详细的错误信息输出,包含实际值和期望值;返回布尔值便于汇总统计。

Layer 2:集成测试 - 验证完整 Flow 的数据流转

集成测试的目标是验证完整 Flow 的数据流转和节点协作,确保从输入到输出的整个链路正常。

测试流程代码

def test_end_to_end_flow(self) -> bool:
    """端到端测试:完整Flow执行"""
    print("\n[测试] 端到端Flow执行")
  
    try:
        # Step 1: 触发 Flow
        api_url = f"{WINDMILL_BASE_URL}/api/w/{WORKSPACE}/jobs/run_flow_by_path/f/blog-distribution/blog_distribution_parallel"
        headers = {
            "Authorization": f"Bearer {TOKEN}",
            "Content-Type": "application/json"
        }
      
        response = requests.post(api_url, json=TEST_ARTICLE, headers=headers, timeout=10)
      
        if response.status_code != 200:
            self.log_test("Flow触发", False, f"HTTP {response.status_code}")
            return False
      
        job_id = response.text.strip().strip('"')
        self.log_test("Flow触发", True, f"Job ID: {job_id}")
      
        # Step 2: 等待完成(最多2分钟)
        print("     等待Flow执行完成...")
        completed_url = f"{WINDMILL_BASE_URL}/api/w/{WORKSPACE}/jobs/completed/get/{job_id}"
      
        for i in range(24):  # 24 * 5s = 2分钟
            time.sleep(5)
            check_response = requests.get(completed_url, headers=headers, timeout=10)
          
            if check_response.status_code == 200:
                result = check_response.json()
                success = result.get("success", False)
              
                if success:
                    # Step 3: 验证4个平台都成功
                    aggregate = result.get("result", {}).get("aggregate_results", {})
                    success_count = aggregate.get("success", 0)
                    platforms_valid = success_count == 4
                  
                    self.log_test(
                        "Flow执行成功",
                        True,
                        f"成功平台: {success_count}/4"
                    )
                  
                    return platforms_valid
                else:
                    self.log_test("Flow执行", False, "Flow执行失败")
                    return False
      
        self.log_test("Flow执行", False, "超时(2分钟)")
        return False
      
    except Exception as e:
        self.log_test("Flow执行", False, f"异常: {str(e)}")
        return False

关键特性:异步轮询机制(5秒间隔),避免阻塞;超时保护(2分钟),防止无限等待;完整的错误捕获和日志,便于排查问题。

集成测试数据

测试维度测试结果说明
Flow 触发成功率100%所有测试均成功触发
平均执行时间45 秒并行执行,4 个平台同时处理
平台成功率50% → 100%优化前 2/4,优化后 4/4
超时发生率0%无超时情况

Layer 3:验收测试 - 硬性红线 + 软性评估

验收测试的目标是验证生成内容是否符合平台调性和业务要求。这一层分为两部分:硬性红线(代码锁死)和软性评估(人工审核)。

小红书:视觉导向 + 网感规则

硬性红线(代码锁死):

validation = {
    "hasEmoji": emoji_count >= 2,
    "emojiCount": emoji_count,
    "hasHashtags": hashtag_count >= 2,
    "hashtagCount": hashtag_count,
    "wordCount": word_count,
    "wordCountValid": 200 <= word_count <= 1200,
    "hasLink": has_link,
    "noBannedPhrases": len(found_banned) == 0,
    "bannedPhrasesFound": found_banned if found_banned else None
}

# 禁用词列表(2026 年网络烂梗)
banned_phrases = [
    "绝绝子", "YYDS", "宝子们", "家人们", "狠狠地",
    "天花板", "刺客", "真的会谢", "建议收藏", "干货满满",
    "速速码住", "不看后悔", "神仙"
]

passed = (
    validation["hasEmoji"] and
    validation["hasHashtags"] and
    validation["wordCountValid"] and
    not validation["hasLink"] and
    validation["noBannedPhrases"]
)

软性评估(人工审核):真实性(是否有个人经验表达)、网感(是否符合小红书用户语言习惯)、视觉效果(Emoji 分布是否合理)。

LinkedIn:专业度 + 2000 字红线

为什么是 2000 字而非 2500 字?实际测试数据显示:AI 生成的 LinkedIn 内容平均 1356 字,2500 字限制过于宽松,导致内容冗长。2000 字是最佳平衡点:既保证深度,又避免冗余。

知乎:逻辑链 + 5000 字红线

为什么从 2800 放宽到 5000?真实案例:初始限制 2800 字,实际生成 3236 字(超标 15.6%)。AI 倾向生成高质量长文,解决方案是放宽到 5000 字,允许深度内容。

一点补充

验收测试流程

1. 自动化验证(代码执行)

2. 格式检查通过?
   ├─ 否 → 返回错误,记录失败原因
   └─ 是 → 进入人工审核

3. 人工审核(抽样 10%)
   ├─ 调性符合?
   ├─ 质量达标?
   └─ 无明显错误?

4. 审核通过 → 推送到飞书
   审核不通过 → 标记为需优化

最终,17 篇文章的批量处理结果:

测试层级测试数量通过率平均耗时发现问题类型
Layer 1: 单元测试12 个用例100%< 1 秒格式错误、数据类型错误
Layer 2: 集成测试4 个 Flow100%45 秒数据流转错误、超时问题
Layer 3: 验收测试17 篇文章94% (16/17)人工审核调性不符、质量问题

结语 / 反思

建立三层测试体系的过程,让我对 AI 工程有了新的认识:测试不是为了限制 AI,而是为了让 AI 更可靠。

从单元测试开始,逐步建立完整体系。硬性规则用代码锁死,软性标准用人工审核。每一层测试都有明确的目标和发现问题的类型,三层协同形成完整的质量保障。

这套体系不仅适用于内容分发,也适用于任何需要 AI 输出稳定性的场景。关键是理解分层逻辑,根据实际情况调整验证规则。