ESSAY
如何建立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 |
| 字数范围、链接存在 | 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 个 Flow | 100% | 45 秒 | 数据流转错误、超时问题 |
| Layer 3: 验收测试 | 17 篇文章 | 94% (16/17) | 人工审核 | 调性不符、质量问题 |
结语 / 反思
建立三层测试体系的过程,让我对 AI 工程有了新的认识:测试不是为了限制 AI,而是为了让 AI 更可靠。
从单元测试开始,逐步建立完整体系。硬性规则用代码锁死,软性标准用人工审核。每一层测试都有明确的目标和发现问题的类型,三层协同形成完整的质量保障。
这套体系不仅适用于内容分发,也适用于任何需要 AI 输出稳定性的场景。关键是理解分层逻辑,根据实际情况调整验证规则。