SystemVerilog中rand与randc的深度解析:约束随机验证的核心机制与应用实践
1. 从“随机”到“可控随机”SystemVerilog约束随机验证的基石如果你写过Verilog的Testbench肯定对$random这个系统任务不陌生。它简单直接但用久了就会发现用它来生成测试激励就像在黑暗中扔飞镖——你永远不知道下一发会打中哪里更别提系统地覆盖那些刁钻的边角情况了。随着芯片设计越来越复杂这种“盲测”的效率低得令人发指。这时候SystemVerilog带来的约束随机验证Constrained Random Verification, CRV就成了救命稻草。而rand和randc这两个关键字就是搭建CRV这座大厦最基础、也最核心的两块砖。简单来说rand和randc是声明随机变量的修饰符。你把一个变量声明为rand仿真器在每次随机化时就有可能注意是“有可能”为它赋一个新值。但光有随机性还不够我们更需要的是“戴着镣铐跳舞”——在指定的规则约束内随机。这就是CRV的精髓用约束constraint来定义合法的值域和变量间的关系让随机引擎自动生成大量符合设计规格的测试向量从而高效地探索状态空间。rand和randc的区别恰恰体现了对随机性“质量”的不同追求。rand是普通的随机每次取值独立而randc是“循环随机”random-cyclic它保证在重复随机化中一个周期内所有可能值都会被不重复地取到一次。这个细微的差别在实际验证场景中会产生巨大的影响。比如你要测试一个8位输入端口用rand可能很久都碰不到某个特定值但用randc就能确保在256次随机化内覆盖所有取值。理解它们是玩转SystemVerilog随机验证的第一步。2.rand详解标准随机变量的行为与陷阱rand是最常用的随机修饰符。它的行为逻辑很直观在调用randomize()方法时被声明为rand的变量会依据其类型和施加的约束在解空间内随机选取一个值。这个“随机”是符合统计学分布的在大量样本下每个合法值出现的概率理论上是均等的在均匀分布约束下。但关键在于每次随机化都是独立事件上次取什么值对这次取值没有任何影响。2.1rand的基本声明与使用场景你可以在类class的内部将任何整数类型bit,logic,int,byte等或枚举类型的成员变量声明为rand。class packet; // 声明随机变量 rand bit [7:0] src_addr; // 8位源地址随机 rand bit [7:0] dst_addr; // 8位目的地址随机 rand bit [3:0] payload[]; // 动态数组其大小和每个元素都可随机化 bit valid; // 普通变量不会随机化 // 约束块 constraint valid_addr_c { src_addr inside {[1:254]}; // src_addr不能是0或255 dst_addr ! src_addr; // 目的地址不能和源地址相同 } constraint payload_size_c { payload.size() inside {[1:64]}; // 载荷长度在1到64之间 } endclass在上面的packet类中src_addr、dst_addr和payload数组包括其大小和内容在调用randomize()时都会被赋予新的随机值并且这些值必须满足valid_addr_c和payload_size_c中定义的约束。而valid变量则保持不变。什么时候用rand绝大多数需要随机化的场景都适用。例如配置寄存器总线的位宽、时钟分频系数、工作模式等。数据包字段源/目的地址、事务ID、数据载荷、错误注入位。延时控制事务间隔、响应延迟等。状态跳转在有限状态机测试中随机决定下一个状态需配合约束避免非法跳转。2.2rand的随机性与“覆盖漏洞”rand的独立性既是优点也是缺点。优点是它简单符合我们对“随机”的直觉。缺点是在验证收敛性上可能效率不高。考虑一个简单的例子我们需要测试一个3位输入值域0-7的模块。我们声明一个rand bit [2:0] data;不加任何约束运行1000次随机化。class simple_test; rand bit [2:0] data; endclass module tb; simple_test t new(); int coverage_bins[8] {default:0}; initial begin repeat(1000) begin assert(t.randomize()); coverage_bins[t.data]; // 统计每个值出现的次数 end $display(Coverage bins: %p, coverage_bins); end endmodule你可能会看到类似这样的输出{0:132, 1:115, 2:128, 3:124, 4:136, 5:118, 6:111, 7:126}。每个值都出现了100多次看起来不错。但如果你只运行10次呢很可能有些值一次都没出现。这就是rand的问题它不保证在有限次随机化内达到均匀覆盖。在验证中我们经常有关注的“角落案例”corner cases比如地址的全0、全1数据的溢出值等。依赖rand的独立随机性来命中这些特定值就像买彩票运气成分很大。你可能需要运行成千上万次测试才能等到那个想要的“特殊值”这极大地拖慢了验证进度。这就是为什么我们需要randc。注意rand变量在数组中的行为需要特别留意。对于定长数组rand修饰的是数组的每个元素每个元素独立随机。对于动态数组rand修饰的是数组本身这意味着数组的大小size和每个元素都可以被随机化但前提是必须在约束中为size指定范围否则随机化会失败。3.randc揭秘循环随机如何保证遍历性randc是“random-cyclic”的缩写我更喜欢把它叫做“循环随机”或“排列随机”。它的核心行为是在同一个随机化周期内变量在其所有可能的取值中每个值恰好被选中一次且顺序是随机的。当一个周期内所有值都被取遍后下一个周期重新开始新一轮不重复的随机排列。3.1randc的工作原理与内部状态你可以把randc变量想象成一个装着所有可能值的“帽子”。每次随机化randomize()时它从帽子里随机抽一个出来并且不放回去。直到帽子被抽空再把所有值放回去重新洗牌开始下一轮抽取。这个“帽子”里具体有哪些值取决于变量的类型和施加的约束无约束的N位向量帽子里的值是0到2^N-1的所有整数。例如randc bit [2:0] a;帽子内容为{0,1,2,3,4,5,6,7}。有约束的变量帽子里的值是所有满足约束的值。例如randc int b; constraint c {b inside {[1:5], 10};}帽子内容为{1,2,3,4,5,10}。每个randc变量在对象实例化时都会初始化一个属于自己的“帽子”和内部状态机。每次调用该对象的randomize()方法时randc变量就会根据其内部状态从帽子里取出下一个值。3.2randc的典型应用场景解放验证工程师的利器randc的价值在于它能确定性地、高效地实现组合空间的遍历特别适用于以下场景枚举类型或小范围值域的穷尽测试 测试一个处理enum {IDLE, START, DATA, STOP}状态的控制单元。用rand可能反复生成IDLE和DATA而START和STOP状态很难出现。用randc声明状态变量可以在最多4次随机化内覆盖所有状态确保每个状态都被测试到。typedef enum {IDLE, START, DATA, STOP} state_e; class fsm_tester; randc state_e curr_state; // 无需复杂约束randc自身保证遍历 endclass端口或寄存器配置的排列组合 一个模块有3个布尔配置位cfg[2:0]你需要测试所有8种配置组合。如果用rand你需要运行很多次才能凑齐所有组合。如果用randc只需要8次。class config_test; randc bit [2:0] cfg; // 自动遍历000到111 endclass作为随机序列的索引 当你有一个固定数组比如预定义的一组测试数据想以随机顺序依次访问所有元素时randc索引是完美选择。class seq_access; int data_array[8] {0,1,2,3,4,5,6,7}; randc int idx; // 声明为randc constraint idx_range {idx inside {[0:7]};} // 约束取值范围 function int get_next_data(); this.randomize(); // 每次调用idx会取一个未用过的0-7的值 return data_array[idx]; endfunction endclass避免随机冲突的ID生成 在总线测试中需要生成多个不重复的事务ID。使用randc可以轻松保证在一个周期内所有ID唯一。class bus_transaction; randc int trans_id; constraint reasonable_id {trans_id inside {[0:255]};} // 在256个事务内ID绝不会重复 endclass重要提示randc的“周期”是针对同一个对象实例的多次randomize()调用而言的。如果你创建了同一个类的两个对象obj1和obj2它们的randc变量是各自独立的有各自独立的“帽子”和周期互不影响。4.randvsrandc深入对比与选型指南理解了各自的行为我们来一场面对面的较量。选择rand还是randc不是一个随意的决定而是基于验证目标和场景的权衡。4.1 行为机制对比我们可以用一个简单的测试来直观展示两者的区别module compare_rand_randc; class rand_example; rand bit [1:0] a; // 2位值域0-3 endclass class randc_example; randc bit [1:0] b; // 2位值域0-3 endclass initial begin rand_example re new(); randc_example rce new(); int ra_count[4] {default:0}; int rc_count[4] {default:0}; $display( rand behavior (8 runs) ); repeat(8) begin assert(re.randomize()); ra_count[re.a]; $write(%0d , re.a); end $display(\nCount: %p, ra_count); $display(\n randc behavior (8 runs) ); repeat(8) begin assert(rce.randomize()); rc_count[rce.b]; $write(%0d , rce.b); end $display(\nCount: %p, rc_count); end endmodule可能的输出 rand behavior (8 runs) 3 1 3 0 2 1 3 1 Count: {0:1, 1:3, 2:1, 3:3} randc behavior (8 runs) 2 0 3 1 1 2 3 0 Count: {0:2, 1:2, 2:2, 3:2}注意看randc的输出前4次2,0,3,1正好是{0,1,2,3}的一个随机排列每个值一次。第5-8次是下一个周期的排列。而rand的输出则可能出现重复如3和1和缺失。4.2 选型决策矩阵什么时候该用谁特性/场景randrandc选型建议核心目标模拟真实世界的随机、独立事件。在有限次尝试内确保覆盖一个集合内的所有值。目标决定选择。要“随机性”选rand要“覆盖性”选randc。值域大小任意大小尤其适合巨大值域如32位地址。适合中小值域通常小于几千。值域太大会导致周期过长失去意义。大范围用rand小集合用randc。性能开销较低。每次独立求解算法相对简单。较高。需要维护“已用值”集合和随机排列消耗更多内存和计算资源。对性能敏感或大规模随机化时慎用randc。约束复杂性与复杂约束兼容性好。与复杂约束兼容性差。约束可能改变解空间大小和内容破坏“循环”语义甚至导致求解失败。有复杂交叉约束时优先用rand。典型用例数据载荷、随机延时、错误概率注入、大范围配置。枚举状态、端口模式、小范围ID、测试序列索引、配置组合遍历。根据上述用例对号入座。一个关键的实操心得不要神话randc。它的遍历性很美好但代价也高。我曾在一个项目中将一个大数组的索引声明为randc该数组理论上限很大尽管约束实际缩小了范围导致随机化速度急剧下降。后来改用rand并配合solve...before和更强的约束来引导分布性能提升了数十倍覆盖率的收敛速度反而更快了。randc是“强保证”但rand“强约束”往往是更灵活、更高效的组合。4.3 混合使用与约束求解的影响一个类中可以同时存在rand和randc变量。仿真器的约束求解器会同时处理它们。但需要注意的是randc的循环周期特性可能会受到与rand变量之间约束的影响。class mixed_example; randc bit [1:0] a; // 值域0-3 rand bit [1:0] b; // 值域0-3 constraint c { b a; } // b必须大于a endclass在这个例子中a的取值仍然遵循randc的循环规则。但是对于a的每一个候选值求解器需要为b找到一个满足b a的值。如果a在当前周期取到了3那么没有任何b0-3能满足b 3这次针对a3的随机化就会失败。randc的循环遍历保证是建立在每次取值都能找到满足所有约束的解的前提下的。如果约束导致某个randc值无解该值会被跳过循环周期会变短。踩坑记录我曾遇到一个棘手的Bug。一个randc变量mode和另一个rand变量data有约束关系data inside {[0:2**mode]};。当mode值较大时data的解空间很大一切正常。但当mode随机到0时约束变成了data inside {[0:1]};data依然有解。问题是在同一个对象的生命周期内mode被声明为randc它必须遍历0,1,2,3...。然而当仿真运行到后期其他复杂的全局约束被激活后导致mode0这个情况再也找不到合法的data赋值因为其他约束与data inside {[0:1]}冲突使得随机化持续失败。调试了很久才发现是randc的遍历特性与后期引入的约束发生了冲突。教训是对randc变量施加的约束尤其是与其他变量的关系约束要尽可能简单、稳定避免在仿真过程中动态变得不可解。5. 高级话题rand/randc在随机化中的实战技巧与排错掌握了基础我们来看看如何在实际项目中用好它们以及当事情不如预期时该如何排查。5.1 结合constraint与solve...before引导分布rand的随机是均匀的但验证场景往往需要非均匀的分布来加速覆盖。例如测试一个错误处理路径我们希望大部分数据是正常的比如99%但有1%的数据是错误注入。单纯用rand很难控制这个比例。class guided_distribution; rand bit error_inject; // 0:正常1:错误 rand int data; constraint normal_vs_error { error_inject dist {0 : 99, 1 : 1}; // 分布权重正常99错误1 } constraint data_based_on_error { if (error_inject 0) { data inside {[0:100]}; // 正常数据范围 } else { data inside {[1000:2000]}; // 错误数据范围 } } endclassdist约束是控制概率分布的利器。而solve...before则用于解决约束求解的优先级问题避免因变量求解顺序导致某些组合概率极低。class solve_before_example; rand bit a; rand bit [1:0] b; constraint c { (a 0) - (b 0); // 如果a是0b必须是0 // 没有solve...before时a0,b0和a1,b0/1/2的概率分布可能不均匀 solve a before b; // 告诉求解器先决定a的值再决定b } endclass对于randc通常不建议与solve...before一起使用因为solve...before会影响求解顺序可能干扰randc内部的状态循环逻辑导致不可预测的行为。5.2 调试随机化失败为什么randomize()返回0调用randomize()方法返回0是每个SystemVerilog验证工程师都会遇到的噩梦。这意味着约束冲突无解。如何定位检查约束矛盾这是最常见的原因。例如两个约束同时限制了同一个变量且范围不相交x inside {[1:10]};和x inside {[20:30]};。检查randc的遍历冲突如前所述randc变量在周期内的某个值可能因为当前其他变量的约束而无法找到合法解导致本次随机化失败。一个技巧是暂时将randc改为rand进行测试。如果改为rand后随机化成功那么问题很可能出在randc的某个特定取值与其他约束冲突。使用调试命令主流仿真器如VCS, Xcelium, Questa都提供了随机化调试功能。-debug或-svseed使用固定的随机种子-svseed value配合调试选项运行可以复现问题。内建方法在randomize()失败后可以调用object.constraint_mode()来禁用部分约束或者使用object.randomize(null)来检查是否有“硬约束”如randc的隐含约束导致失败。仿真器特定功能如VCS的ntb_solve_debug可以打印出约束求解的详细过程看到是哪个约束导致了冲突。5.3 性能优化当随机化成为瓶颈当测试平台变得复杂包含成千上万个随机变量和复杂的约束时随机化求解可能消耗大量仿真时间。减少randc的使用如前所述randc开销大。评估是否真的需要遍历保证能否用rand导向性约束替代。简化约束避免使用复杂的算术运算如乘除、取模、递归约束、以及涉及大型数组或动态数组的约束。尽量使用inside、dist、-等简单的约束操作符。分阶段随机化将一个复杂的随机化过程拆分成多个步骤。先随机化决定“框架”的变量如数据包类型、长度再基于这些结果随机化“内容”变量如具体数据。class two_stage_randomize; rand pkt_type_e type; rand int length; rand byte payload[]; constraint frame_c { // 第一阶段约束 type dist {SHORT:1, LONG:3}; if (type SHORT) length inside {[1:64]}; else length inside {[65:1500]}; } function void post_randomize(); // 第二阶段根据length分配payload数组并随机化其内容 payload new[length]; foreach(payload[i]) begin assert(std::randomize(payload[i])); end endfunction endclass使用rand_mode()和constraint_mode()在运行时动态关闭某些变量或约束的随机化可以简化求解空间提升后续随机化的速度。理解rand和randc远不止于记住语法。它关乎如何构建一个高效、智能的验证环境。rand给了你模拟不确定性的自由而randc给了你达成确定性覆盖的武器。在实际项目中我的习惯是默认使用rand只有当需要明确保证一个小集合内的值在有限步骤内被全部覆盖且约束关系非常简单时才考虑使用randc。大部分所谓的“遍历”需求其实通过精心设计的rand约束和覆盖组Covergroup引导都能更优雅、更高效地实现。把这两个工具放进你的工具箱理解它们的脾气你就能在约束随机验证的路上走得更稳、更远。

相关新闻

VSCode调试中No such file or directory错误:彻底解决相对路径与工作目录问题

VSCode调试中No such file or directory错误:彻底解决相对路径与工作目录问题

1. 问题缘起:一个看似简单却困扰无数开发者的“幽灵”错误如果你在用VSCode写Python、JavaScript或者C,大概率遇到过这个让人瞬间血压升高的报错:[Errno 2] No such file or directory。它就像一个幽灵,在你信心满满地按下F5运行调…

2026/8/23 21:54:42 阅读更多 →
2026程序员就业:AI工具从个人试用到团队协作,offer到底在筛什么人

2026程序员就业:AI工具从个人试用到团队协作,offer到底在筛什么人

《别急着重做程序员就业,先看岗位到底在筛什么》看起来是个大话题,但真落到项目里,常常就是几个具体选择。下面我尽量按实际开发时会遇到的问题来讲。摘要> 今年面了十几个转AI开发的候选人,发现一个现象:会调API的…

2026/8/23 21:54:42 阅读更多 →
Linux运维面试100题:核心命令与实战技巧

Linux运维面试100题:核心命令与实战技巧

1. 项目背景与价值在Linux运维工程师和开发者的面试中,命令行操作能力往往是考察的重点。Qwen3-Max这份面试题集整理了100道覆盖Linux核心领域的实战题目,不仅包含常见命令的使用,更深入考察了命令组合、问题排查和系统管理的综合能力。这份题…

2026/8/23 21:54:42 阅读更多 →

最新新闻

TortoiseGit图形化Git工具:从安装配置到首次提交完整指南

TortoiseGit图形化Git工具:从安装配置到首次提交完整指南

1. 为什么选择TortoiseGit:从命令行恐惧到图形化掌控如果你和我一样,第一次接触Git时,面对黑漆漆的命令行窗口和一堆git add、git commit、git push命令感到头皮发麻,那么TortoiseGit可能就是你的“救星”。它不是Git的替代品&…

2026/8/23 22:38:10 阅读更多 →
DeepSeek给Agent装了“原装眼睛“:社区外挂一星期,官方亲手拆了

DeepSeek给Agent装了“原装眼睛“:社区外挂一星期,官方亲手拆了

昨天我们聊完"社区给 DeepSeek 补眼睛"——ModLens 这些插件,用外部视觉模型当翻译,帮纯文本的 DeepSeek 看懂图片。 结果今天下午,DeepSeek 官方就把"原装眼睛"掏出来了。 8月21日,DeepSeek 上线了 V4 系列首…

2026/8/23 22:38:10 阅读更多 →
群晖NAS上使用Docker部署HomeAssistant智能家居平台完整指南

群晖NAS上使用Docker部署HomeAssistant智能家居平台完整指南

1. 项目概述:为什么要在群晖上跑HomeAssistant?如果你和我一样,家里有一台群晖NAS,并且对智能家居有点兴趣,那么把HomeAssistant(简称HA)装到群晖上,几乎是顺理成章、性价比最高的选…

2026/8/23 22:38:10 阅读更多 →
深度学习生成医学图像:CBCT生成伪CT的临床可用方案

深度学习生成医学图像:CBCT生成伪CT的临床可用方案

深度学习生成医学图像:CBCT生成伪CT的临床可用方案 摘要 锥形束CT(Cone-Beam CT, CBCT)因其低辐射剂量和高空间分辨率,在放射治疗图像引导中应用广泛,但其图像质量受散射噪声和重建伪影影响,HU值准确性不足,限制了其在剂量计算等临床场景中的应用。本文系统阐述基于深…

2026/8/23 22:38:10 阅读更多 →
DeepSeek开源一周,Agent第一次有了“组织“

DeepSeek开源一周,Agent第一次有了“组织“

上周我们聊了 DeepSeek Harness(DSH)和它背后那篇 Cordis 论文。论文的结尾有一句话,说未来要让 AI"持续生成并替换自己的组件"——也就是 Agent 自己给自己升级。 当时觉得那是个很远的愿景。 结果一周过去,"自进…

2026/8/23 22:37:10 阅读更多 →
OpenKylin虚拟机安装全攻略:从零到精通的详细步骤与避坑指南

OpenKylin虚拟机安装全攻略:从零到精通的详细步骤与避坑指南

1. 项目概述:为什么选择OpenKylin?最近在折腾国产操作系统,OpenKylin(开放麒麟)这个名字出现的频率越来越高。它作为一款基于Linux内核、由国内社区主导开发的开源桌面操作系统,主打安全、易用和良好的中文…

2026/8/23 22:37:10 阅读更多 →

日新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

月新闻

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

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

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

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

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

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

2026/8/23 12:10:44 阅读更多 →
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/22 3:22:48 阅读更多 →