需求降临
小明是一名测试工程师,他对着屏幕叹了口气:"每天要在后台检查50个页面的UI是否正常、按钮是否可点、表单是否能提交……能不能让AI帮我干?"
大脑登场 —— 理解与决策
大语言模型就像团队里的「首席策略师」。它不会自己动手操作浏览器,但它能理解自然语言,把模糊的需求翻译成精确的步骤计划。
Step 1 → 打开 https://example.com/login
Step 2 → 在用户名框输入 'admin'
Step 3 → 在密码框输入 'test123'
Step 4 → 点击「登录」按钮
Step 5 → 检查页面是否跳转到 /dashboard
Step 6 → 截图留证"
LLM 的核心价值:把人类的模糊意图,翻译成机器可执行的精确指令。它还能根据页面反馈动态调整策略——比如发现按钮灰了,就换一种操作路径。
调度员登场 —— 编排与中转
Harness 就像「项目经理」或「中控台」,它站在 LLM 和 Playwright 之间,负责:
await page.click('button[type=submit]')——这个翻译工作交给我。
另外,Playwright 执行完操作后返回的结果(成功/失败/截图),我也会整理好反馈给 LLM,让大脑做下一步决策。"
Harness 是胶水层(Glue Layer)。它解决了一个关键问题:LLM 输出的是自然语言或JSON指令,而 Playwright 需要的是代码级API调用。Harness 做了双向翻译。
"手"登场 —— 精准执行
Playwright 就像「机械臂操作员」,它直接控制真实的浏览器——Chrome、Firefox、Safari都可以。
✅ 已打开 https://example.com/login
✅ 已定位到 #username 输入框,填入 'admin'
✅ 已定位到 #password 输入框,填入 'test123'
✅ 已点击 button[type=submit]
✅ 页面跳转到了 /dashboard
📸 截图已保存为 result.png"
Playwright 的能力:像真人一样操控浏览器,但速度更快、更稳定、可并发,而且支持无头模式(headless)——不用打开可见窗口也能跑。
闭环反馈 —— 让AI越来越聪明
执行完成后,Harness 把 Playwright 的结果包装好反馈给 LLM:
这就是 Agent Loop(智能体循环)—— LLM 观察、思考、行动、再观察,循环往复,直到任务完成。而 Harness 始终在中间做翻译和调度。
用户层 · Human
用自然语言描述需求:"帮我测试一下登录功能有没有bug"、"检查所有商品页的价格显示是否正确"。不需要写代码。
智能层 · LLM (大语言模型)
接收自然语言指令,进行意图理解、任务拆解、生成结构化的操作步骤(如JSON格式的Action列表),并根据执行反馈做出下一步决策。这是整个系统的「大脑」。
编排层 · Harness (调度中枢)
核心中间件。向上对接 LLM 的输出(解析JSON指令),向下调用 Playwright API。负责:指令解析、参数映射、错误重试、状态管理、结果格式化、截图管理、上下文拼接后回传给 LLM。
执行层 · Playwright
直接控制真实浏览器引擎(Chromium / Firefox / WebKit)。执行点击、输入、导航、等待、截图、获取DOM等操作,返回精确的执行结果。
浏览器层 · Real Browser
真实渲染的网页,和用户平时看到的完全一样。Playwright 通过 CDP(Chrome DevTools Protocol)等协议与浏览器通信。
👤 用户输入
"帮我检查 example.com 的登录功能,用admin/test123登录,看看能不能成功跳转。"
🧠 LLM 理解 & 拆解
LLM 解析用户意图,输出结构化的 Action 列表:
{ action: "goto", url: "https://example.com/login" }
{ action: "fill", selector: "#username", value: "admin" }
{ action: "fill", selector: "#password", value: "test123" }
{ action: "click", selector: "button[type=submit]" }
{ action: "assert_url", expected: "/dashboard" }
⚙️ Harness 解析指令
逐条读取 JSON Action,映射到 Playwright 的具体 API:
goto → page.goto(url)
fill → page.fill(selector, value)
click → page.click(selector)
同时处理等待策略、超时重试、异常捕获。
🎭 Playwright 执行
在真实浏览器中逐步执行操作:打开页面 → 填写表单 → 点击按钮 → 等待跳转 → 截图保存。每步操作都返回成功/失败状态。
⚙️ Harness 收集结果
将 Playwright 的执行结果(当前URL、页面标题、DOM变化、截图Base64等)格式化为 LLM 能理解的 Observation 文本。
🧠 LLM 判断 & 决策
LLM 收到 Observation,判断:"当前URL包含 /dashboard ✅,任务完成"或者"URL还在 /login ❌,可能密码错了,换一个试试"——然后输出下一步 Action 或最终报告。
📋 返回结果
最终生成人类可读的测试报告:✅ 登录成功 / ❌ 登录失败,附带截图、操作日志和建议修复方案。整个过程无需编写一行测试代码。
const { callLLM } = require('./llm-client');
async function agentLoop(userTask) {
// 1. 启动浏览器 (Playwright)
const browser = await chromium.launch();
const page = await browser.newPage();
// 2. 初始化对话上下文
let messages = [
{ role: 'system', content: '你是一个浏览器自动化助手...' },
{ role: 'user', content: userTask }
];
// 3. Agent Loop — 循环:思考 → 行动 → 观察
while (true) {
// 🧠 LLM 思考下一步
const llmResponse = await callLLM(messages);
const action = JSON.parse(llmResponse);
// 🏁 任务完成?
if (action.type === 'done') {
console.log('✅ 报告:', action.summary);
break;
}
// ⚙️ Harness 翻译 → 🎭 Playwright 执行
let observation;
try {
if (action.type === 'goto')
await page.goto(action.url);
else if (action.type === 'fill')
await page.fill(action.selector, action.value);
else if (action.type === 'click')
await page.click(action.selector);
else if (action.type === 'screenshot')
await page.screenshot({ path: 'result.png' });
// 收集页面状态作为 Observation
observation = {
url: page.url(),
title: await page.title(),
status: 'success'
};
} catch (err) {
observation = { status: 'error', message: err.message };
}
// ⚙️ 把结果反馈给 LLM
messages.push({
role: 'assistant',
content: JSON.stringify(action)
});
messages.push({
role: 'user',
content: 'Observation: ' + JSON.stringify(observation)
});
}
await browser.close();
}
// 启动!
agentLoop('请测试 example.com 的登录功能');
while(true) 就是 Agent Loop。每一轮循环里,LLM 思考(输出 Action),Harness 翻译并调用 Playwright 执行,然后把 Observation 反馈给 LLM。如此往复,直到 LLM 认为任务完成。
🧠 LLM = 大脑(决定"做什么")
⚙️ Harness = 神经系统(翻译"怎么做"、传递信号)
🎭 Playwright = 双手(在浏览器里"真正去做")
三者缺一不可:没有 LLM,系统不能理解人类意图;没有 Harness,LLM 的指令无法到达浏览器;没有 Playwright,一切计划都只是纸上谈兵。