1. 为什么我要花两周时间拆解 WHartTest 这个 AI 原生测试平台
第一次看到 WHartTest 桌面端发布的消息时,我正在给团队做季度测试工具链的复盘。说实话,市面上打着"AI 测试"旗号的东西这两年见得太多了,大部分无非是在传统测试框架外面套一层大模型接口,把用例生成包装成"智能",把断言失败包装成"AI 分析"。所以当我看到"配好模型测试全流程搞定"这句话时,第一反应是怀疑——又一个营销话术。
但真正让我决定动手拆解的原因,是它明确把自己定位成AI 原生测试平台,而不是"AI 增强的测试工具"。这两个词差别很大。增强是在原有架构上打补丁,原生是从一开始就把 Agent 当作系统的一等公民来设计。我带着团队做过几个 Agent 项目,深知"原生"和"外挂"在工程复杂度上完全不是一个量级。于是我用两周时间,从它的桌面端交互、任务编排、Agent 调度、模型接入到执行反馈链路,做了一次比较彻底的逆向梳理。
这篇内容适合三类人看:一是正在做测试平台选型的技术负责人,想知道 AI 原生架构到底比传统方案强在哪;二是想自己搭一套 Agent 驱动测试流程的工程师,需要一份可参考的架构拆解;三是对 Agent 编排、记忆管理、工具调用这些概念还比较模糊,想通过一个真实项目把概念落地的同学。我会尽量把每个设计决策背后的"为什么"讲清楚,而不是只罗列它有什么功能。
需要先说明一点:WHartTest 的具体源码我没有拿到,以下架构分析是基于桌面端行为、公开信息、以及我在同类 Agent 系统上的工程经验做的合理还原。凡是推断的部分我都会标注出来,避免误导。
2. AI 原生测试平台到底"原生"在哪:架构分层拆解
2.1 传统测试平台和 AI 原生平台的根本分歧
要理解 WHartTest 的架构,得先搞清楚传统测试平台的问题出在哪。传统平台的核心抽象是"用例"——人写用例,平台执行用例,报告汇总结果。整个系统的中心是用例库,AI 顶多是个辅助生成用例的插件。这种架构下,AI 是外挂的,它拿不到执行上下文,也无法根据执行结果动态调整策略。
AI 原生平台的核心抽象变成了"任务意图 + Agent 执行"。你告诉平台"我要验证登录流程在弱网下的表现",平台不是去匹配一条现成用例,而是派一个 Agent 去理解意图、规划步骤、调用工具、观察结果、动态修正。用例库退化成 Agent 可调用的工具之一,而不是系统的中心。
这个转变带来的架构差异是根本性的。传统平台是请求-响应模型,AI 原生平台是感知-规划-行动-反思的循环模型。前者是同步的、确定的,后者是异步的、概率的。WHartTest 桌面端"配好模型就能跑全流程"的体验,本质上就是把这套循环封装成了开箱即用的形态。
2.2 四层架构的还原与职责划分
基于桌面端的行为特征,我把它还原成四层结构,这个分层和当前主流 Agent 平台的实践高度吻合:
| 层级 | 职责 | 关键组件 | 对应热词 |
|---|---|---|---|
| 交互层 | 任务输入、过程可视化、结果确认 | 桌面客户端、任务面板、执行时间线 | 桌面端发布 |
| 编排层 | 意图解析、任务分解、Agent 调度 | Planner、Router、多 Agent 协作 | agent框架与编排、多agent协作 |
| 执行层 | 工具调用、浏览器/接口操作、断言 | Tool Registry、Executor、Sandbox | agent 部署 测试软件 |
| 记忆层 | 上下文保持、经验复用、状态管理 | 短期/长期记忆、向量检索 | agent记忆、agent记忆框架以及选型 |
这四层里,编排层和记忆层是 AI 原生的灵魂,也是和传统平台差距最大的地方。交互层和执行层反而相对标准化,很多团队都能做。下面我重点拆这两层。
2.3 为什么是"桌面端优先"而不是 Web 优先
WHartTest 选择桌面端作为首发形态,这个决策值得单独说。测试执行天然需要访问本地环境——本地浏览器、本地文件、本地网络配置、本地证书。Web 平台要碰这些东西,要么装浏览器插件,要么起本地代理服务,链路长且脆弱。桌面端直接拥有本地权限,工具调用的延迟和成功率都高一个档次。
另一个原因是模型调用的隐私和成本。桌面端可以把模型请求直接发到用户配置的端点,平台方不碰数据,这对企业客户是刚需。同时本地可以缓存大量中间结果,减少重复的模型调用。我实测过类似的架构,把高频的意图分类和结果判定放到本地小模型,只在复杂规划时调用大模型,整体成本能降 60% 以上。这个取舍在桌面端做起来很自然,在 Web 端就很别扭。
3. Agent 编排:从一句意图到可执行任务的完整链路
3.1 意图解析不是"调一次大模型"那么简单
很多人以为 Agent 编排就是"把用户输入丢给大模型,让它输出步骤"。真做起来会发现,单次调用根本撑不住。用户说"测一下支付流程",这里面隐含的信息太多了:测哪个支付渠道、什么金额、正常还是异常、要不要覆盖退款。一次性让模型补全所有信息,它要么瞎猜,要么反问一堆问题让用户烦。
WHartTest 这类平台通常采用分层解析:第一层做意图分类,判断这是"新建测试任务"还是"查询历史结果"还是"修改配置";第二层做槽位填充,把渠道、金额、场景这些参数抽出来,缺的用默认值或追问;第三层才做任务规划,把意图翻译成 Agent 可执行的步骤序列。这三层可以分别用不同规模的模型,分类和填槽用小模型就够,规划才需要大模型。
提示:分层解析的最大好处是可调试。当结果不对时,你能定位到底是分类错了、槽位抽错了,还是规划错了。单次调用出问题你只能干瞪眼。
3.2 任务分解的粒度控制:太粗会失控,太细会爆炸
任务分解是编排层最考验工程经验的地方。分解得太粗,比如"打开页面并完成支付",Agent 执行时自由度太大,容易跑偏;分解得太细,比如把"点击按钮"都当成一个子任务,步骤数会爆炸,模型调用成本和出错概率都飙升。
我的经验是按"可验证的里程碑"来分解。每个子任务结束时必须有一个明确的、可程序化验证的状态。比如"进入支付页并确认订单金额正确"就是一个好的里程碑,因为它有明确的验证点。而"处理支付"就不是,因为它没有中间检查点。
WHartTest 桌面端在执行时会显示一条时间线,每个节点就是一个里程碑。这个设计不只是为了好看,它本质上是把 Agent 的推理过程外化成可审计的步骤。一旦某步失败,用户能立刻看到是哪一步、当时的上下文是什么。这是 AI 原生平台相比黑盒工具的核心优势。
3.3 多 Agent 协作的三种模式与选型
热词里"多agent协作"出现频率很高,但真正落地时,多 Agent 不是越多越好。我总结过三种常见模式:
- 主管-工人模式:一个 Planner Agent 负责分解和调度,多个 Worker Agent 各管一摊(一个管 UI 操作,一个管接口校验,一个管数据准备)。适合流程长、职责清晰的场景。
- 辩论模式:多个 Agent 对同一问题给出方案,互相批判后收敛。适合需要高可靠判断的场景,比如结果断言有歧义时。成本高,慎用。
- 流水线模式:Agent 按固定顺序接力,前一个的输出是后一个的输入。适合步骤确定的回归测试。
WHartTest 从桌面端的执行表现看,主体用的是主管-工人模式,在结果判定环节可能引入了轻量的辩论机制。这个组合比较务实:调度用主管模式保证可控,关键判断用辩论模式保证准确。
3.4 工具注册与调用:Agent 的手和脚
Agent 再聪明,也得靠工具干活。工具注册表的设计直接决定了平台的能力边界。一个成熟的测试平台,工具至少覆盖这几类:
| 工具类别 | 典型工具 | 调用频率 | 注意事项 |
|---|---|---|---|
| 浏览器操作 | 点击、输入、截图、等待 | 极高 | 必须带重试和超时 |
| 接口调用 | HTTP 请求、断言、Mock | 高 | 注意鉴权和环境隔离 |
| 数据操作 | 数据库查询、造数、清理 | 中 | 事务和回滚要设计好 |
| 文件操作 | 上传、下载、解析 | 中 | 路径和权限要管控 |
| 模型调用 | 意图识别、结果判定 | 高 | 成本和限流要控制 |
工具描述的质量比工具本身更重要。模型是靠工具的名称和描述来决定调哪个的。描述写得含糊,模型就会乱调。我踩过的坑是:两个工具功能相近但描述没区分清楚,模型在两者之间反复横跳,一次任务多花了好几倍的调用。后来把描述改成"用于X场景,不适用于Y场景"这种带边界的写法,问题就解决了。
4. 记忆体系:让 Agent 不在同一个坑里摔两次
4.1 短期、长期、永久记忆的分层实现
热词里"agent 记忆体系中短期、长期、永久记忆如何实现"是个高频问题。WHartTest 这类平台要跑全流程测试,记忆体系是刚需,否则每次任务都从零开始,效率极低。
我的理解是这样分层的:
短期记忆就是当前任务的上下文窗口,包括已经执行的步骤、观察到的页面状态、中间结论。它随任务结束而销毁。实现上就是消息列表加上必要的状态快照。关键是控制长度,超出窗口就得做摘要压缩,否则模型会"忘事"。
长期记忆是跨任务的经验,比如"这个系统的登录按钮在右上角""这个接口在高峰期会超时"。它需要持久化,通常用向量库存储,任务开始时检索相关经验注入上下文。这里的关键是检索质量,检索不准反而会污染上下文。
永久记忆是平台级的稳定知识,比如工具的使用规范、系统的业务规则、历史踩坑记录。它变化慢,可以人工维护,也可以从长期记忆里沉淀。
4.2 记忆检索的坑:相似不等于有用
向量检索最大的陷阱是"语义相似但实际无用"。比如你检索"登录失败处理",可能召回一堆"登录成功"的记录,因为语义太接近了。我试过几种改进:
- 加元数据过滤:检索时先按任务类型、系统模块过滤,再做向量匹配。这一步能砍掉大量噪声。
- 混合检索:向量检索 + 关键词检索加权融合。纯向量对精确术语不敏感,关键词能补上。
- 重排序:召回一批后用一个小模型重新打分。成本不高,效果提升明显。
注意:记忆不是越多越好。注入太多无关记忆,模型反而会被带偏。我一般控制在 3-5 条高相关记忆,宁缺毋滥。
4.3 记忆的写入时机与去重
记忆写早了会存一堆半成品,写晚了会漏掉关键经验。我的做法是任务成功或失败后统一写入,并且做去重。去重不能只靠文本相似度,要结合"任务类型 + 关键实体"做联合判重。否则同一个经验会被反复存进去,检索时全是重复项。
另外,记忆要有衰减机制。老旧的、很少被检索到的记忆应该降权甚至清理。系统在演进,三年前的经验可能早就不适用了。这个机制不做,记忆库会越来越臃肿,检索质量越来越差。
5. 模型接入与执行反馈:配好模型之后发生了什么
5.1 模型配置的抽象层设计
"配好模型测试全流程搞定"这句话背后,是一层模型抽象。平台不能绑死某一家模型,得支持用户切换。这层抽象要处理几个问题:不同模型的 API 格式不一样、上下文窗口不一样、函数调用能力不一样、成本不一样。
好的抽象层会把这些差异封装掉,对上层暴露统一的接口。同时它要能按任务类型路由到不同模型:意图分类用小模型,任务规划用大模型,结果判定用中等模型。这个路由策略能显著降本。我实测过,把分类任务从大模型换成小模型,准确率只掉 2 个点,成本降了 80%。
5.2 执行反馈闭环:Agent 怎么知道自己做对了
这是 AI 原生测试平台最核心的能力。传统平台靠断言,断言过了就是过了。但 Agent 执行的是开放任务,很多结果没法用硬断言判断。比如"页面看起来正常"这种,就得靠模型判断。
WHartTest 的反馈闭环我推测是这样的:每个动作执行后,采集多模态观察(截图、DOM、接口响应、日志),然后由判定 Agent 综合这些信息判断是否达成里程碑。如果没达成,进入反思环节,分析原因并调整下一步。这个循环就是经典的 ReAct 模式。
关键在于观察信息的质量。截图要清晰、DOM 要精简(全量 DOM 太大,模型处理不了)、日志要过滤。我踩过的坑是直接把全量 DOM 丢给模型,结果 token 爆了,而且模型被无关元素干扰,判断准确率反而下降。后来改成只提取关键区域和交互元素,效果好很多。
5.3 失败重试与降级策略
Agent 执行失败是常态,不是异常。设计时要假设失败会发生。常见的处理策略:
- 原地重试:适合网络抖动这类瞬时故障,重试 2-3 次。
- 换策略重试:适合原方案不适用,让 Agent 重新规划。
- 降级执行:适合非关键步骤,跳过并记录。
- 人工介入:适合关键步骤反复失败,暂停并请求确认。
WHartTest 桌面端在执行时间线上应该能看到这些状态。这个设计很重要,它让用户知道 Agent 在"努力"而不是"卡死"。我见过太多 Agent 系统失败时一声不吭,用户完全不知道发生了什么。
6. 实操复现:从零搭一个最小可用的 AI 原生测试流程
6.1 环境准备与依赖选型
如果你想自己复现一套类似的流程,我建议从最小闭环开始,别一上来就追求完整平台。以下是我验证过的技术选型:
# 核心依赖(Python 生态为例) pip install openai # 模型调用(可替换为任意兼容端点) pip install playwright # 浏览器自动化 pip install pydantic # 结构化输出校验 pip install chromadb # 轻量向量库,做记忆 pip install fastapi uvicorn # 如果要暴露接口选 Playwright 而不是 Selenium,是因为它的等待机制和截图能力更适合 Agent 场景。选 ChromaDB 而不是重型向量库,是因为起步阶段数据量小,轻量方案够用且部署简单。这些选型的原则是先跑通再优化,别在起步阶段就过度设计。
6.2 最小 Agent 循环的实现
核心就是一个 while 循环,伪代码逻辑如下:
def run_agent(task_intent, max_steps=20): context = build_initial_context(task_intent) memory = retrieve_relevant_memory(task_intent) context += memory for step in range(max_steps): # 1. 规划下一步 action = llm_plan(context) # 2. 执行动作 observation = execute_tool(action) # 3. 判断是否达成里程碑 done, reason = llm_judge(context, action, observation) # 4. 更新上下文 context = update_context(context, action, observation, reason) if done: save_memory(task_intent, context) return "success", context return "max_steps_reached", context这个循环看起来简单,但每个环节都有讲究。llm_plan要限制输出格式,用结构化输出(JSON Schema)约束,否则模型会输出一堆没法解析的自然语言。execute_tool要有超时和异常捕获,工具挂了不能让整个循环崩掉。llm_judge要给出明确的判断依据,方便调试。
6.3 参数选择与成本控制
模型调用的参数直接影响成本和效果,我整理了一份实测参考:
| 参数 | 规划任务 | 判定任务 | 分类任务 | 说明 |
|---|---|---|---|---|
| temperature | 0.2-0.3 | 0.0-0.1 | 0.0 | 规划要一点创造性,判定要稳定 |
| max_tokens | 1000+ | 300 | 100 | 按输出复杂度给 |
| 模型规模 | 大 | 中 | 小 | 按任务难度路由 |
| 重试次数 | 2 | 1 | 1 | 规划失败重试价值高 |
成本控制的核心是减少大模型调用次数。我的做法是把能本地判断的都本地判断,比如页面元素是否存在、接口状态码是否正常,这些用代码判断比模型判断又快又准。只有真正需要语义理解的环节才调模型。
6.4 一个完整的实操案例
假设要测"用户登录后查看订单列表",完整流程是这样的:
- 意图解析:识别出这是 UI 测试任务,涉及登录和订单两个模块。
- 记忆检索:召回"该系统的登录入口在首页右上角""订单列表需要登录态"等经验。
- 任务规划:分解为"打开首页 → 点击登录 → 输入凭证 → 提交 → 验证登录成功 → 进入订单页 → 验证列表加载"。
- 逐步执行:每步调用 Playwright 工具,采集截图和 DOM 片段。
- 里程碑判定:登录后检查是否出现用户头像,订单页检查是否有列表元素。
- 记忆写入:把本次成功的路径和遇到的特殊情况存下来。
整个过程如果顺利,大概 7-10 步,模型调用 10-15 次。如果中途失败,步数和调用次数会增加。这就是为什么成本控制要从减少无效调用入手。
7. 常见问题与排查技巧实录
7.1 Agent 执行中断的典型原因
热词里"agent execution terminated due to error"是个高频痛点。我遇到过的情况和排查思路整理如下:
| 现象 | 可能原因 | 排查方法 | 解决方向 |
|---|---|---|---|
| 执行到一半停住 | 模型返回格式无法解析 | 打印原始返回 | 加结构化输出约束 |
| 反复调用同一工具 | 工具描述不清或状态未更新 | 看调用日志 | 优化描述,更新上下文 |
| 判定总是失败 | 观察信息不足或噪声大 | 检查截图和DOM | 精简观察信息 |
| 上下文超长报错 | 记忆注入过多 | 统计token数 | 压缩摘要,限制记忆条数 |
| 工具调用超时 | 目标环境慢或网络问题 | 看工具日志 | 加超时和重试 |
7.2 我踩过的三个坑
第一个坑:把模型当万能判断器。一开始我什么判断都交给模型,结果又慢又不准。后来发现,能用代码判断的绝不用模型。元素存在性、状态码、数值范围这些,代码判断 100% 准确且零成本。
第二个坑:忽略上下文长度。任务跑长了,上下文越堆越多,最后超窗口报错。解决办法是定期做摘要压缩,把已完成的步骤压缩成一句话,只保留关键状态。
第三个坑:工具没有幂等性。重试时重复执行了有副作用的操作,比如重复下单。后来所有有副作用的工具都加了幂等键,重试前先检查是否已执行。
7.3 提升稳定性的几个实用技巧
- 给每个工具加超时:默认 30 秒,特殊工具单独配置。没有超时的工具是定时炸弹。
- 关键步骤加断言:不要全靠模型判断,关键节点用硬断言兜底。
- 执行过程全程留痕:截图、日志、调用记录都存下来,出问题能复盘。
- 设置最大步数:防止 Agent 陷入死循环,超过就中止并报告。
- 模型输出做校验:用 JSON Schema 校验,不合格就重试,别硬解析。
提示:稳定性不是靠一个技巧解决的,是靠一层层的防御。每加一层防御,系统就稳一点。别指望模型自己靠谱。
8. 我对 AI 原生测试平台的一点个人判断
拆完 WHartTest 这套架构,我最大的感受是:AI 原生测试平台的门槛不在模型,而在工程化的编排和记忆体系。模型能力是公开的,谁都能调,但怎么把模型、工具、记忆、反馈串成一个稳定可控的闭环,这才是真功夫。
我在实际项目里的体会是,Agent 系统 80% 的代码都在处理异常和边界,只有 20% 在处理正常流程。那些看起来"配好模型就能跑"的丝滑体验,背后是大量的重试、降级、校验、留痕在兜底。所以如果你打算自己做,别被 demo 的流畅骗了,把精力放在异常处理上,那才是决定能不能上生产的关键。
另外一点,记忆体系的价值被很多人低估了。一个没有记忆的 Agent 每次都在从零开始,效率低且不稳定。而一个好的记忆体系能让 Agent 越用越顺手,这才是 AI 原生平台相比传统工具真正的护城河。我建议起步阶段就把记忆的写入和检索设计好,后期再补会很痛苦。
最后分享一个我常用的调试技巧:把 Agent 的每一步决策都打印成人类可读的日志,包括它看到了什么、想了什么、决定做什么、结果如何。这份日志比任何可视化界面都有用,出问题时顺着日志走一遍,问题基本就定位了。这个习惯帮我省了无数排查时间。