基于Playwright与多Agent架构的网站行为流自动化还原工程实践
1. 项目概述从“一键还原”到工程化实践最近在折腾自动化测试和爬虫项目时我遇到了一个挺有意思的挑战如何稳定、高效地“克隆”一个目标网站的行为流包括它的页面状态、交互逻辑乃至背后的数据请求。这不仅仅是简单的截图或保存HTML而是要能完整复现用户在网站上的操作路径和状态变化。传统的工具链比如Selenium配合Requests或者单纯的Playwright脚本在面对复杂的SPA单页应用、动态加载、反爬机制时总显得有些力不从心脚本脆弱、维护成本高是常态。于是我开始探索将Playwright与多智能体Multi-Agent的工程思想结合起来构建一套更健壮、更智能的自动化流程。这套流程的目标很明确给定一个目标网站URL系统能自动分析其结构规划操作路径执行交互并最终将整个过程包括中间状态、网络请求、最终渲染完整地“还原”出来形成一个可复现、可审计的报告或脚本。这听起来有点像自动化测试的逆向工程但其应用场景远不止于此比如竞品分析、工作流自动化、甚至为AI训练提供高质量的交互数据。核心的驱动力在于“工程流”。它不是一个简单的脚本而是一套包含角色分工、错误处理、状态管理和质量评估的体系。Playwright提供了强大的浏览器自动化能力而多Agent的架构思想则让我们可以将复杂的“还原”任务分解为分析、决策、执行、验证等多个子任务由不同的“智能体”各司其职协同完成。这大大提升了整个系统的鲁棒性和适应性。2. 核心架构与多Agent角色设计这套工程流的核心在于将“还原网站”这个宏观目标拆解成一系列可被独立管理和执行的微观任务。我们借鉴了软件工程和分布式系统中的Agent概念这里每个Agent并非指必须使用大语言模型驱动的AI智能体而是指一个具有特定职责、能感知环境、做出决策并执行动作的功能模块。它们通过清晰定义的接口和共享状态进行协作。2.1 四大核心Agent的职责解析在我们的设计中主要包含以下四个核心Agent它们构成了一个处理管道Pipeline1. 侦察与分析Agent (Reconnaissance Analysis Agent)这是流程的起点。它的任务是“读懂”目标网站。它接收一个初始URL然后利用Playwright打开页面但并不急于交互。它的工作包括静态结构分析快速扫描页面的DOM树识别关键的结构化元素如导航栏、主内容区、表单、列表等。它会生成一个初步的页面元素地图。动态行为嗅探监听页面加载初期及空闲时触发的网络请求XHR/Fetch分析API端点、请求参数和响应格式。这有助于理解网站的数据获取方式。技术栈推断通过检查全局变量如window.React、window.Vue、特征性的CSS类名或脚本判断网站可能使用的框架React, Vue, Angular等这对后续的元素定位策略有指导意义。初始状态快照保存页面加载后的初始HTML、CSSOM以及完整的网络请求瀑布图。这个快照是后续所有操作的“基线”。实操心得这个Agent的关键是“轻”和“快”。它不应该执行任何可能改变页面状态的操作如点击、滚动。我们通常会将Playwright的page.goto()的waitUntil参数设置为‘networkidle’并配合page.on(‘request’)和page.on(‘response’)事件监听器来捕获网络活动。分析结果会结构化成一份JSON报告传递给下一个Agent。2. 策略规划Agent (Strategy Planning Agent)拿到分析报告后这个Agent负责回答“我们应该如何与这个网站交互”它需要模拟一个真实用户的探索路径。其决策逻辑可以基于规则也可以引入简单的启发式算法或轻量级模型路径生成基于分析报告中的可交互元素按钮、链接、输入框生成一系列可能的操作序列。例如对于一个电商网站典型路径可能是“首页 - 点击某个商品分类 - 滚动浏览商品列表 - 点击进入商品详情页 - 查看商品评价”。风险评估预判某些操作可能带来的风险比如点击一个按钮可能导致弹窗、页面跳转或触发复杂的JS验证。规划时需要准备应对策略如等待弹窗出现后关闭。目标定义明确本次“还原”的深度和广度。是只还原主流程还是需要遍历所有主要标签页策略规划Agent需要根据配置制定一个清晰的、可执行的任务清单。3. 执行与交互Agent (Execution Interaction Agent)这是最“实干”的Agent直接驱动Playwright执行规划好的操作序列。它的核心要求是稳定和容错。健壮的元素定位绝不依赖脆弱的XPath或易变的CSS选择器。优先使用>import { defineConfig, devices } from playwright/test; export default defineConfig({ timeout: 120000, // 单个操作超时设为2分钟给复杂页面足够时间 use: { headless: false, // 开发调试时可设为false生产环境为true viewport: { width: 1920, height: 1080 }, // 固定视口保证一致性 ignoreHTTPSErrors: true, screenshot: only-on-failure, // 协调器会管理自己的截图逻辑这里仅备灾 video: off, // 视频录制开销大通常由我们的状态捕获替代 trace: off, // 同理使用自定义追踪 userAgent: Mozilla/5.0 ... (一个常见的桌面浏览器UA), // 模拟真实用户 }, // 可以配置多个项目来模拟不同浏览器环境 projects: [ { name: chromium, use: { ...devices[Desktop Chrome] } } ], });3.2 侦察分析Agent的深度实现分析Agent的代码核心在于信息收集的全面性和非侵入性。以下是一个简化的示例// src/agents/analyzer/index.ts import { Page, Browser } from playwright; import { AnalysisResult } from ../../core/types; export class AnalyzerAgent { async analyze(page: Page, url: string): PromiseAnalysisResult { const result: AnalysisResult { url, timestamp: new Date().toISOString(), initialDom: , networkActivities: [], interactiveElements: [], techStackHints: [], }; // 1. 导航并等待网络空闲 await page.goto(url, { waitUntil: networkidle, timeout: 60000 }); // 2. 捕获初始DOM清理敏感信息 result.initialDom await this.sanitizeDom(await page.content()); // 3. 监听并记录网络请求在goto之前就开始监听 page.on(request, request { if (this.isRelevantRequest(request)) { result.networkActivities.push({ url: request.url(), method: request.method(), resourceType: request.resourceType(), // 注意不记录postData等可能包含敏感信息的字段 }); } }); // 4. 识别可交互元素使用更稳健的选择器 const buttons await page.locator(button, [rolebutton], a, input, select, textarea).all(); for (const element of buttons.slice(0, 50)) { // 限制数量避免过多 const tag await element.evaluate(el el.tagName.toLowerCase()); const text await element.innerText().catch(() ); const placeholder await element.getAttribute(placeholder); const id await element.getAttribute(id); result.interactiveElements.push({ tag, text: text?.trim(), placeholder, id }); } // 5. 技术栈推断启发式 const techDetect await page.evaluate(() { const hints []; if (window.React) hints.push(React); if (window.Vue) hints.push(Vue); if (window.angular) hints.push(Angular); // 检查特定类名或属性 if (document.querySelector([data-reactroot], [data-reactid])) hints.push(React (by DOM)); return hints; }); result.techStackHints techDetect; return result; } private isRelevantRequest(request: any): boolean { const ignoreTypes [image, stylesheet, font, media]; return !ignoreTypes.includes(request.resourceType()); } private sanitizeDom(html: string): string { // 简易的DOM清理移除脚本、样式、表单值等可根据需要扩展 // 这里可以使用类似cheerio的库进行更精细的操作 return html.replace(/script\b[^]*(?:(?!\/script)[^]*)*\/script/gi, ) .replace(/style\b[^]*(?:(?!\/style)[^]*)*\/style/gi, ); } }3.3 执行交互Agent的容错与状态捕获执行Agent是稳定性的关键。我们必须假设页面环境是不稳定的。// src/agents/executor/index.ts import { Page, Locator } from playwright; import { PlannedAction, StepSnapshot } from ../../core/types; import { Logger } from ../../utils/logger; export class ExecutorAgent { constructor(private page: Page, private logger: Logger) {} async executeAction(action: PlannedAction, stepIndex: number): PromiseStepSnapshot { const snapshot: StepSnapshot { step: stepIndex, action, before: {}, after: {} }; const { selector, actionType, value } action; // 步骤A执行前状态捕获 snapshot.before await this.capturePageState(Step ${stepIndex} - Before); try { const locator this.resolveLocator(selector); await locator.waitFor({ state: visible, timeout: 30000 }); switch (actionType) { case click: await locator.click({ delay: 100 }); // 加入微小延迟模拟真人 break; case fill: await locator.fill(value || ); break; case select: await locator.selectOption(value || ); break; case scroll: await this.page.mouse.wheel(0, parseInt(value || 500)); break; // ... 其他操作类型 } // 步骤B等待操作后的副作用稳定这是避免Flaky测试的核心 await this.waitForStability(); // 步骤C执行后状态捕获 snapshot.after await this.capturePageState(Step ${stepIndex} - After); snapshot.success true; } catch (error) { this.logger.error(Step ${stepIndex} failed: ${error.message}); snapshot.success false; snapshot.error error.message; // 即使失败也尝试捕获失败后的状态 snapshot.after await this.capturePageState(Step ${stepIndex} - Error State); // 根据策略决定是重试、跳过还是终止流程 } return snapshot; } private async capturePageState(label: string) { const state { domHash: , // 可以计算DOM的哈希值用于快速比较 screenshotPath: , networkSinceLastStep: [], }; // 1. 获取并清理DOM const rawHtml await this.page.content(); state.domHash this.computeHash(this.sanitizeDom(rawHtml)); // 2. 截图仅针对视口或特定区域 state.screenshotPath ./outputs/snapshots/${label.replace(/[^a-z0-9]/gi, _)}.png; await this.page.screenshot({ path: state.screenshotPath, fullPage: false }); // 3. 记录此阶段新增的网络请求需要与全局网络监听器配合 // ... 实现略 return state; } private async waitForStability(timeout 10000) { // 实现一个自定义的“稳定”等待例如 // - 等待没有新的网络请求持续1秒 // - 等待某个加载指示器消失 // - 或者简单等待一个固定时间最后手段 await this.page.waitForTimeout(1000); // 基础等待 // 更高级的实现可以监听 networkidle 或特定元素状态 } private resolveLocator(selector: string): Locator { // 智能定位器解析可以支持多种选择器格式 // 例如如果selector以text开头使用 page.getByText if (selector.startsWith(text)) { return this.page.getByText(selector.substring(5)); } // 默认使用CSS选择器 return this.page.locator(selector); } }4. 策略规划Agent的智能决策逻辑规划Agent是这套流程的“大脑”。最简单的实现是基于配置的规则模板。例如针对常见网站类型博客、电商、后台管理系统预定义操作模板。更高级的实现可以引入轻量级的决策逻辑基于元素优先级的探索给“登录按钮”、“搜索框”、“查看更多链接”这类元素赋予更高的操作优先级。广度优先搜索BFS将页面视为图可点击元素是边新页面/状态是节点进行有限深度的遍历。与LLM结合进阶将分析Agent的报告发送给大语言模型如通过API调用GPT-4提示它“作为一个用户请规划探索这个网站的5个关键步骤”。LLM可以生成更接近人类、更语义化的操作序列如“点击右上角的头像然后选择‘个人设置’菜单”。然后我们需要一个翻译层将这些自然语言描述转换回Playwright可执行的定位器和操作指令。// 一个简单的基于规则的规划器示例 // src/agents/planner/rule-based-planner.ts import { AnalysisResult, PlannedAction } from ../../core/types; export class RuleBasedPlanner { generatePlan(analysis: AnalysisResult, config: any): PlannedAction[] { const plan: PlannedAction[] []; const { interactiveElements, url } analysis; // 规则1如果页面有搜索框先执行一次搜索使用配置的关键词 const searchInput interactiveElements.find(el el.tag input (el.placeholder?.toLowerCase().includes(搜索) || el.id?.includes(search))); if (searchInput config.defaultSearchTerm) { plan.push({ selector: input[placeholder*${searchInput.placeholder}], // 简化示例 actionType: fill, value: config.defaultSearchTerm, description: 在搜索框输入“${config.defaultSearchTerm}” }); plan.push({ selector: button[typesubmit], actionType: click, description: 点击搜索按钮 }); } // 规则2点击第一个看起来是主要内容的链接非导航、非页脚 const mainLinks interactiveElements.filter(el el.tag a el.text el.text.length 5); if (mainLinks.length 0) { plan.push({ selector: text${mainLinks[0].text}, actionType: click, description: 点击链接“${mainLinks[0].text}” }); } // 规则3向下滚动以加载更多内容针对无限滚动页面 plan.push({ selector: body, actionType: scroll, value: 2000, description: 向下滚动页面 }); return plan.slice(0, config.maxSteps || 10); // 限制最大步骤数 } }5. 验证、汇编与最终输出所有步骤执行完毕后验证与汇编Agent开始工作。它的任务不仅是打包更是质量守门员。// src/agents/verifier/index.ts import { ExecutionResult, StepSnapshot, FinalReport } from ../../core/types; import * as fs from fs/promises; import * as path from path; export class VerifierAgent { async verifyAndAssemble(result: ExecutionResult, outputDir: string): PromiseFinalReport { const report: FinalReport { summary: { totalSteps: result.snapshots.length, successfulSteps: 0, failedSteps: 0 }, startUrl: result.startUrl, startTime: result.startTime, endTime: new Date().toISOString(), snapshots: [], analysis: result.initialAnalysis, }; for (const snapshot of result.snapshots) { report.snapshots.push({ ...snapshot, // 可以在这里计算前后状态的差异度例如DOM哈希值是否变化 domChanged: snapshot.before.domHash ! snapshot.after?.domHash, }); if (snapshot.success) { report.summary.successfulSteps; } else { report.summary.failedSteps; } } // 生成可读的HTML报告 await this.generateHtmlReport(report, outputDir); // 生成结构化的JSON日志便于其他程序分析 await fs.writeFile( path.join(outputDir, execution-log.json), JSON.stringify(report, null, 2) ); return report; } private async generateHtmlReport(report: FinalReport, outputDir: string) { // 这是一个简化的示例实际可以生成非常丰富的报告 const html !DOCTYPE html html headtitle网站还原报告 - ${report.startUrl}/titlestyle/* 样式省略 *//style/head body h1还原报告/h1 p目标URL: ${report.startUrl}/p p成功率: ${report.summary.successfulSteps}/${report.summary.totalSteps}/p hr ${report.snapshots.map(s div classstep ${s.success ? success : failed} h3步骤 ${s.step}: ${s.action?.description}/h3 p状态: ${s.success ? 成功 : 失败}/p ${s.before.screenshotPath ? img src${path.basename(s.before.screenshotPath)} width400 : } ${s.after?.screenshotPath ? img src${path.basename(s.after.screenshotPath)} width400 : } /div ).join()} /body /html; await fs.writeFile(path.join(outputDir, report.html), html); // 同时需要将截图文件复制到outputDir下 } }6. 常见问题、排查技巧与进阶优化在实际搭建和运行这套工程流时你会遇到不少挑战。以下是我踩过坑后总结的一些核心要点。6.1 元素定位失败稳定性第一生命线这是自动化脚本的头号杀手。我们的执行Agent已经采用了稳健的定位策略但还需要更多防御性编程。问题页面元素加载慢、动态生成、被遮挡、或选择器因前端改动而失效。排查与解决优先使用面向用户的定位器Playwright推荐的page.getByRole(),page.getByText(),page.getByLabel()是首选。它们基于可访问性属性比CSS选择器稳定得多。组合定位不要依赖单一的属性。可以组合角色、文本和邻近元素。例如page.getByRole(button).filter({ hasText: Submit }).and(page.locator(.primary))。自定义测试属性如果目标网站是你可控的强烈建议推动开发团队为关键交互元素添加>// 生成的Playwright脚本示例 import { test, expect } from playwright/test; test(replicated-flow-from-2024-05-27, async ({ page }) { await page.goto(https://target-website.com); await page.getByPlaceholder(搜索商品...).fill(笔记本电脑); await page.getByRole(button, { name: 搜索 }).click(); await page.locator(.product-item:first-child).click(); // ... 更多步骤 });这样你就实现了从“记录”到“生成测试用例”的闭环极大地提升了编写端到端E2E测试的效率。构建这样一套Playwright结合多Agent思想的工程流初期投入确实比写一个直线脚本要大。但当你需要处理数十个、上百个不同结构的网站或者对一个网站进行长期、稳定的监控和回归验证时它的模块化、可维护性和鲁棒性优势就会淋漓尽致地展现出来。它不再是一个脆弱的“脚本”而是一个真正意义上的“工程系统”。

相关新闻

实测10款AI写小说工具|挑选合适的写小说软件不再踩坑

实测10款AI写小说工具|挑选合适的写小说软件不再踩坑

这两年各类AI模型快速普及,身边不少网文作者都会备上多款写小说工具辅助创作。 老实说,长期卡文、坚持日更赶稿的创作者,大多都会尝试小说软件生成器,依靠ai写小说缓解创作压力。但市面上工具水平参差不齐,有的生成文…

2026/8/13 4:20:14 阅读更多 →
新手写小说软件怎么选?实测8款靠谱AI写小说工具

新手写小说软件怎么选?实测8款靠谱AI写小说工具

写小说的谁没崩溃过?脑洞想炸了,人设打磨半天,结果一写就卡文,剧情接不上,写出来的文字还干巴巴的,完全没看点。 写网文这几年,我踩烂了一堆坑,试过各种各样的写小说软件&#xff0…

2026/8/13 4:20:14 阅读更多 →
双向带头循环链表:原理、实现与应用场景

双向带头循环链表:原理、实现与应用场景

1. 双向带头循环链表概述双向带头循环链表是一种特殊的链表结构,它结合了双向链表、带头节点和循环链表的特性。这种数据结构在实际开发中有着广泛的应用场景,特别是在需要频繁进行前后遍历操作的场景下表现优异。我第一次接触这种数据结构是在开发一个音…

2026/8/13 4:20:14 阅读更多 →

最新新闻

多模态大模型的“诅咒”:视觉能力为何会干扰文本推理?

多模态大模型的“诅咒”:视觉能力为何会干扰文本推理?

1. 项目概述:当“多模态”遇上“诅咒”最近在跟几个做模型落地的朋友聊天,大家不约而同地提到了一个有点反直觉的现象:给原本只擅长文本的LLM(大语言模型)加上视觉能力,让它变成多模态大模型,按…

2026/8/13 5:07:33 阅读更多 →
基于SpringBoot+Vue的校园交流信息化管理平台设计与实现

基于SpringBoot+Vue的校园交流信息化管理平台设计与实现

背景随着信息技术的迅猛发展和教育信息化的深入推进,校园交流信息化管理平台的建设成为高校数字化转型的重要环节。当前,高校师生在日常教学、科研、社团活动等场景中面临信息传递效率低、资源整合不足、跨部门协作困难等问题,传统线下或单一…

2026/8/13 5:07:33 阅读更多 →
基于微信小程序+SpringBoot的智能停车场管理系统设计与实现

基于微信小程序+SpringBoot的智能停车场管理系统设计与实现

智能停车场管理系统的选题背景随着城市化进程的加速和汽车保有量的快速增长,停车难问题日益突出。传统停车场管理方式依赖人工收费、纸质记录或简单的电子设备,存在效率低下、资源浪费、用户体验差等问题。例如,车主需花费大量时间寻找空余车…

2026/8/13 5:07:33 阅读更多 →
Linux终端快捷键:从基础操作到效率倍增的完整指南

Linux终端快捷键:从基础操作到效率倍增的完整指南

1. 项目概述:为什么终端快捷键是效率的基石如果你在Linux世界里待过一段时间,无论你是运维工程师、后端开发者,还是像我一样喜欢折腾桌面环境的爱好者,你一定会发现一个现象:高手们的手指在键盘上飞舞,屏幕…

2026/8/13 5:07:33 阅读更多 →
基于SpringBoot+随机森林算法的医院药品管理系统设计与实现

基于SpringBoot+随机森林算法的医院药品管理系统设计与实现

背景医院药品管理作为医疗体系中的重要环节,其效率和精准性直接影响患者用药安全和医疗服务质量。传统药品管理多依赖人工操作,存在库存盘点耗时长、药品效期监控滞后、处方审核主观性强等问题,易导致药品浪费、过期风险或用药错误。随着医疗…

2026/8/13 5:07:33 阅读更多 →
Claude Code架构解析:构建有记忆、可协作的AI编程伙伴

Claude Code架构解析:构建有记忆、可协作的AI编程伙伴

1. 项目概述:为什么我们需要一个全新的AI编程架构?如果你和我一样,在过去一年里深度使用过各种AI编程助手,从GitHub Copilot到Cursor,再到各种本地部署的开源模型,你可能会有一个共同的感受:它们…

2026/8/13 5:06:33 阅读更多 →

日新闻

Visual Studio新建项目解决方案为空:系统性排查与修复指南

Visual Studio新建项目解决方案为空:系统性排查与修复指南

1. 问题现象与本质剖析如果你是一位.NET开发者,或者正准备踏入这个领域,那么Visual Studio(后面简称VS)绝对是你绕不开的伙伴。但有时候,这个伙伴会跟你开一个不大不小的玩笑:你满怀期待地点击“创建新项目…

2026/8/13 0:00:09 阅读更多 →
长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

说实话,每次提起“长春建设厅网站”这几个字,我心里都挺有感触的。不是因为它有多高大上,也不是因为那里藏着什么不可告人的秘密,恰恰相反,是因为它太“接地气”了,或者说,它是咱们普通人想要在这个城市好好生活、安稳买房时,必须得翻过的一座“数据山”。很多新朋友第…

2026/8/13 0:00:09 阅读更多 →
Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾为Windows家庭版无法支持多用户远程桌面…

2026/8/13 0:00:09 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/12 1:11:09 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/12 1:11:08 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/11 17:09:45 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/12 1:11:10 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/11 17:09:45 阅读更多 →