Install
openclaw skills install @shylamb-token/ai-app-testingLLM/Agent 应用全栈测试 — L0-L4、安全审计、RAG 评估、压力/回归测试。含 14 个可运行脚本和 45 条测试用例。
openclaw skills install @shylamb-token/ai-app-testing专用于 LLM / Agent 类应用的质量保障。覆盖 6 个测试层级 (L0-L4)、Prompt 安全审计(14 种攻击向量)、RAG 三维度评估、性能压力测试、LLM-as-Judge 自动评价和回归对比。所有脚本已落地为可运行文件,可直接在项目中拷贝使用。
ai-app-test/
├── run_tests.py # 统一运行器(编排所有层级)
├── test_config.yaml # YAML 配置
├── llm_core_tester.py # L0: LLM 核心功能 (6 内置用例)
├── prompt_tester.py # L1: Prompt 测试 (12 内置用例)
├── prompt_security_auditor.py # 安全: Prompt 安全审计 (12 攻击向量, 4 类)
├── verify_tool_call.py # L2: 工具调用 (8 内置用例)
├── schema_checker.py # L2: Schema 校验 (3 schema × 12 用例 → 100%)
├── mcp_tester.py # L2.5: MCP 审计
├── trace_analyzer.py # L3: Trace 分析 (5 内置 trace)
├── e2e_session_tester.py # L4: E2E 会话 (4 场景)
├── rag_tester.py # RAG: 准确性 (5 文档, 6 QA, 8 对抗用例)
├── stress_tester.py # 压力: 并发测试 (3 档 profile)
├── auto_judge.py # 评分: LLM-as-Judge (6 内置用例)
├── regression_compare.py # 回归: 基线对比 (6 指标)
├── test_case_generator.py # 生成: 自动生成 10 个用例文件
├── prompts/judge.md # LLM-as-Judge 评审模板
├── test_cases/*.jsonl (×9) + *.json # 45 条测试用例
│ ├── llm_core.jsonl # L0 (8)
│ ├── prompt_basic.jsonl # L1 (6)
│ ├── prompt_security.jsonl # 安全 (8)
│ ├── booking_tools.jsonl # L2 (4)
│ ├── mcp_tools.jsonl # L2.5 (3)
│ ├── rag_retrieval.jsonl # RAG 检索 (3)
│ ├── rag_faithfulness.jsonl # RAG 忠实度 (3)
│ ├── multi_step_booking.jsonl # L3 (3)
│ ├── e2e_scenarios.json # L4 (3 场景)
│ └── redteam.jsonl # 红队 (4)
└── .github/workflows/ai-app-test.yml # CI: 14 jobs
| 层级 | 测试对象 | 核心关注点 | 脚本 |
|---|---|---|---|
| L0 | LLM 基础能力 | 知识/推理/数学/编码/语言 | llm_core_tester.py |
| L1 | Prompt 质量 | 格式/边界/角色/安全边界 | prompt_tester.py |
| 安全 | Prompt 安全 | 注入/越狱/泄漏/混淆 14 种攻击 | prompt_security_auditor.py |
| L2 | 工具调用 | 工具选择/参数/多工具编排 | verify_tool_call.py + schema_checker.py |
| L2.5 | MCP 协议 | 端点/能力/合规性 | mcp_tester.py |
| L3 | 多步推理 | 幻觉/循环/遗忘/效率 | trace_analyzer.py |
| L4 | 端到端+体验 | 任务完成率/轮次/信号 | e2e_session_tester.py |
| RAG | 检索+生成 | Hit Rate / MRR / Faithfulness | rag_tester.py |
| 压力 | 性能 | 延迟 P50/P95/P99 / 吞吐 | stress_tester.py |
| 评分 | 质量评估 | LLM-as-Judge 多维度评分 | auto_judge.py |
| 回归 | 基线对比 | 回归告警/改进追踪 | regression_compare.py |
# 一键运行所有离线可测层级
cd ai-app-test
python3 run_tests.py --levels l2-sch l3 l4 judge gen reg --skip-online
# 生成测试用例文件
python3 test_case_generator.py
# 指定 LLM 端点运行在线测试
python3 llm_core_tester.py http://localhost:8080/v1/chat/completions
python3 prompt_security_auditor.py http://localhost:8080/v1/chat/completions
python3 stress_tester.py light
# 运行所有层级
python3 run_tests.py --endpoint http://localhost:8080
llm_core_tester.py)| ID | 维度 | 输入 | 验证 |
|---|---|---|---|
| l0-001 | 知识 | 中国首都是什么? | 含"北京" |
| l0-002 | 推理 | 鸡兔同笼(头35脚94) | 含"23" |
| l0-003 | 数学 | 2^10 | 含"1024" |
| l0-004 | 编码 | Python斐波那契 | 含"def" |
| l0-005 | 语言 | 今天天气很好→英文 | 含"weather" |
| l0-006 | 知识 | 水化学式 | 含"H2O" |
from llm_core_tester import LLMCoreTester, LLM_CORE_CASES
# 实例化(需 LLM endpoint)
tester = LLMCoreTester(endpoint="http://localhost:8080/v1/chat/completions",
model="deepseek/deepseek-v4-flash")
# 运行全部用例
result = tester.run_suite()
print(f"通过: {result['passed']}/{result['total']}")
# 按维度查看
for dim, stats in result['by_dimension'].items():
print(f" {dim}: {stats['passed']}/{stats['total']}")
# 稳定性测试(同输入多次调用)
stability = tester.run_stability(n_runs=3)
=== L0 LLM Core Test Result ===
Total: 6 | Passed: 5 | Rate: 83.3%
知识: 2/2
推理: 1/1
数学: 1/1
编码: 1/1
语言: 0/1
prompt_tester.py)| 维度 | 用例数 | 验证点 |
|---|---|---|
| 格式约束 | 3 | JSON / Markdown / 长度限制 |
| 边界 | 3 | 空输入 / 超长输入 / 要求空输出 |
| 角色 | 2 | 身份幻觉 / 合理拒绝 |
| 容错 | 2 | 重复输入 / 循环检测 |
| 安全边界 | 2 | 危险请求 / 泄漏 |
from prompt_tester import PromptTester
tester = PromptTester(endpoint)
result = tester.run_suite()
print(f"通过: {result['passed']}/{result['total']} | P50延迟: {result['latency_p50']}s")
prompt_security_auditor.py)| 类别 | 攻击 | ID |
|---|---|---|
| 直接注入 | 指令覆盖、虚假角色、优先级重置 | psa-001~003 |
| 越狱 | DAN角色、开发者模式 | psa-004~005 |
| 泄漏 | 直接索要、分步诱导、Base64绕过 | psa-007~009 |
| 混淆 | 分隔符、多语言、上下文污染、递归 | psa-011~014 |
from prompt_security_auditor import PromptSecurityAuditor, audit_report
auditor = PromptSecurityAuditor(endpoint)
result = auditor.audit()
print(audit_report(result))
# 输出: 总攻击数 / 攻破数 / 通过率 / 按类别统计
verify_tool_call.py + schema_checker.py)| ID | 场景 | 预期工具 |
|---|---|---|
| l2-001 | 创建联系人张三 | create_contact |
| l2-002 | 查北京天气 | get_weather |
| l2-003 | 查上海→北京航班 | search_flights |
| l2-004 | 订深圳酒店 | book_hotel |
| l2-005 | 查天气+提醒(首步) | get_weather |
| l2-006 | 温度转换 | convert_temperature |
| l2-007 | 无需工具(问候) | 不调用 |
| l2-008 | 不完整信息(追问) | get_weather |
from verify_tool_call import ToolCallVerifier
tester = ToolCallVerifier(endpoint)
result = tester.run_suite()
print(f"工具准确率: {result['tool_accuracy']}%")
schema_checker.py)3 个内置 Schema(contact / flight_booking / ai_response)各含 pass 和 fail 用例。
from schema_checker import SchemaChecker
checker = SchemaChecker()
stats = checker.run_all()
# 输出: accuracy/sensitivity/specificity + TP/TN/FP/FN
mcp_tester.py)from mcp_tester import MCPTester, generate_report
tester = MCPTester()
result = tester.run_full_audit()
print(generate_report(result))
# 输出: 端点连通性 / 能力覆盖 / API 合规性 / 综合评分
trace_analyzer.py)| 问题类型 | 检测方法 | 内置 Trace |
|---|---|---|
| 幻觉 | 最终回答含未出现在工具输出中的实体 | hallucination_trace |
| 循环 | 连续 ≥4 次相同工具调用 / ≥3 次重复(工具+输入) | loop_trace |
| 遗忘 | 步骤跳跃 / 回答与上下文矛盾 | forget_trace |
| 效率 | 步骤数、延迟统计 | normal_booking, efficient_trace |
from trace_analyzer import TraceAnalyzer
analyzer = TraceAnalyzer()
results = analyzer.analyze_all()
for name, r in results:
print(f"{name}: {'✅' if r['passed'] else '❌'} score={r['score']}")
e2e_session_tester.py)| ID | 场景 | 轮次 | 成功信号 |
|---|---|---|---|
| e2e-001 | 完整旅游预订 | 4 | 订单/确认/预订/已为您 |
| e2e-002 | 客服售后流程 | 4 | 抱歉/换货/退款/售后服务/订单/处理 |
| e2e-003 | 多轮信息收集 | 5 | 确认/信息/完成/成功 |
| e2e-004 | RAG知识库查询 | 3 | 2018/8.2亿/TLS/AES/加密 |
from e2e_session_tester import E2ESessionTester
# 离线分析模式
tester = E2ESessionTester()
result = tester.dry_run()
# 在线模式(需 endpoint)
tester.endpoint = "http://localhost:8080/v1/chat/completions"
result = tester.run_suite()
rag_tester.py)| 维度 | 方法 | 指标 |
|---|---|---|
| 检索质量 | evaluate_retrieval() | Hit Rate / MRR / 延迟 |
| 生成忠实度 | evaluate_faithfulness() | LLM-as-Judge 裁决 |
| E2E 对抗 | run_rag_eval() | 边界/对抗/准确性 |
from rag_tester import RAGTester, RAG_TEST_DATA, RAG_EVAL_CASES
tester = RAGTester("http://localhost:8080/rag", "http://localhost:8080")
# 检索质量
ret = tester.evaluate_retrieval()
print(f"Hit Rate: {ret['hit_rate']}%, MRR: {ret['mrr']}")
# 忠实度
faith = tester.evaluate_faithfulness()
print(f"忠实度: {faith['faithfulness_rate']}%, 评分: {faith['avg_score']}/5")
5 篇文档(公司介绍/定价/架构/安全/财务)和 6 个 QA 对,覆盖 8 个 E2E 对抗用例。
stress_tester.py)| 档位 | 并发 | 请求数 | 适用场景 |
|---|---|---|---|
| light | 2 | 10 | 快速验证 |
| medium | 5 | 25 | 日常基准 |
| heavy | 10 | 50 | 负载评估 |
from stress_tester import StressTester
tester = StressTester(endpoint)
# 运行单个档位
result = tester.run_concurrent("light")
print(f"吞吐: {result['throughput']} req/s")
print(f"P50: {result['latency_p50']}s, P95: {result['latency_p95']}s")
# 运行多档位
all_results = tester.run_multi_profile(["light", "medium"])
auto_judge.py)| 维度 | 评分范围 | 说明 |
|---|---|---|
| 有用性 | 1-5 | 是否解决用户问题 |
| 准确性 | 1-5 | 事实是否正确 |
| 忠实度 | 1-5 | 是否基于上下文 |
| 安全性 | 1-5 | 是否合规无害 |
| 格式 | 1-5 | 格式是否正确 |
from auto_judge import AutoJudge
judge = AutoJudge(endpoint="http://localhost:8080/v1/chat/completions")
result = judge.run_suite()
for d in result["details"]:
print(f"{d['id']}: 实际评分={d['actual_score']} (期望范围={d['expected_range']})")
规则回退: 当 endpoint 为 None 时,使用基于关键词匹配的规则评分(精度有限)。
regression_compare.py)from regression_compare import RegressionComparator
comp = RegressionComparator()
result = comp.compare(baseline_data, current_data)
if result["overall"] == "PASS":
print("✅ 无回归")
else:
for alarm in result["alarms"]:
print(f"❌ {alarm['message']}")
内置 6 项指标:准确率 / 延迟P50 / 延迟P95 / 成功率 / 幻觉率 / 工具准确率。支持自动阈值判定和基线持久化。
run_tests.py)# 运行全部层级
python3 run_tests.py --endpoint http://localhost:8080
# 运行指定层级
python3 run_tests.py --levels l0 l1 l2 --endpoint http://localhost:8080
# 离线模式(跳过需要 LLM endpoint 的层级)
python3 run_tests.py --skip-online
# 指定 model
python3 run_tests.py --endpoint http://localhost:8080 --model gpt-4
.github/workflows/ai-app-test.yml 包含 14 个 job:
L0 LLM Core → L1 Prompt → Security Audit → L2 Tool Call → L2 Schema
→ L2.5 MCP → L3 Trace → L4 E2E → RAG Eval → Auto Judge → Stress
→ Regression → Notify (Slack) → Test Case Gen
支持:
test_case_generator.py)# 生成全部 10 个用例文件
python3 test_case_generator.py
# 指定输出目录
python3 test_case_generator.py my_cases/
支持编程式生成:
from test_case_generator import generate_llm_core, generate_prompt_security
# 获取 Python 对象
llm_cases = generate_llm_core()
security_cases = generate_prompt_security()
requests)ai-app-test/ 目录直接拷贝到项目中运行| 度量项 | 脚本 | 数据来源 |
|---|---|---|
| 准确率 | llm_core_tester.py | 内置用例通过率 |
| 工具准确率 | verify_tool_call.py | 工具名/参数匹配率 |
| Schema 准确率 | schema_checker.py | TP+TN / Total |
| 幻觉率 | trace_analyzer.py | 幻觉指标计数 |
| 循环率 | trace_analyzer.py | 循环检测次数 |
| 延迟 P50/P95/P99 | stress_tester.py | 并发请求延迟分布 |
| Hit Rate / MRR | rag_tester.py | RAG 检索结果 |
| 忠实度 | rag_tester.py | LLM-as-Judge |
| 安全通过率 | prompt_security_auditor.py | 未被攻破比例 |
| 回归告警 | regression_compare.py | 阈值越界指标数 |
| 综合评分 | auto_judge.py | LLM 多维度评分 |