news 2026/9/24 11:55:13

字节面试:你的 Agent 单次成功率 60%,敢上线吗?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
字节面试:你的 Agent 单次成功率 60%,敢上线吗?

先说一个数字:60%。

那是我们客服 Agent 在内测集上的单次任务成功率。当时我觉得账算得过来——六成能自己办成,剩下四成转人工兜底。

直到有位做风控的同事问我一句:"那同一个用户连着来八次,是不是至少有一次要翻车?"

我拿计算器按了一下:0.6 的 8 次方,约等于1.7%

也就是说,一个"60 分及格"的 Agent,用户只要用满八次,几乎必然撞上一次失败。而我们当时的监控看板上一片绿色——接口全是 200,平均响应 800ms,错误率 0.3%。

这道题,上周一位学员在字节三面被问住了。面试官的原话是:

"你的 Agent 上线了,怎么证明它没在瞎搞?"

他答了准确率、答了人工抽检、答了看日志。面试官摇摇头,追了三句:

  1. "同一个任务跑八次,它八次都能做对吗?"
  2. "它回复说'退款已处理',你怎么知道系统里真的只退了一笔、金额没退错?"
  3. "下个月模型换版本,你靠什么发现它悄悄变笨了?"

三问,一问比一问狠。答案分别是三个词:pass^k、最终状态断言、回归评测门禁

这三个词,就是这一期要讲的全部。

台阶一:先别谈过程,你的"结果"可能压根没测对

先破一个流传很广的误区。

网上讲 Agent 评测的文章,第一句基本都是"不能只看结果,要看过程"。这话对,但只对了半句——大部分团队连"结果"这一项都没测明白。

他们怎么测结果?拿 Agent 的最后一句回复去做文本匹配,或者让模型打个分。

这就出问题了。因为 Agent 跟传统大模型的本质区别,不是它会思考、会调工具、会规划步骤——这些是能力的量变。真正的质变是:它有行动权,会产生副作用。

传统大模型评测

Agent 评测

产物

一段文本

一段文本 +一系列被改变的世界状态

判分对象

回答对不对

任务办成没有 + 有没有办砸别的事

判分方式

标准答案比对 / 模型打分

终端状态断言

+ 轨迹评估

失败代价

答错了,用户划走

多退一笔钱、改错一条数据、发错一封邮件

稳定性

同一题答案基本稳定

同一任务跑八次,结果可能各不相同

所以 Agent 的结果判定,标准做法是最终状态断言(final state assertion):不读它说了什么,去查它到底把世界改成了什么样。

举个例子。任务是"给 4812 号订单退款并通知客户",断言应该长这样:

refund.count(order=4812) == 1 # 只能退一次 refund.amount == approved_amount # 金额必须等于审批金额 order.status == "refunded" # 订单状态要流转 ledger.net_change == -approved_amount # 账要平 email.count(template="refund") == 1 # 通知只能发一封 unrelated_records.changed == 0 # 没动到不该动的东西

看最后一条。"没动到不该动的东西"也要断言——这才是 Agent 评测和普通接口测试的分界线。

接口测试问的是:"退款接口返回 200 了吗?"<br>Agent 评测问的是:"这笔退款是不是只发生了一次?金额是不是审批金额?订单状态流转了吗?账平不平?邮件是不是只发了一封?有没有误改别人的记录?"

一句顶一万句的话

Agent 可以留下一地鸡毛之后,写出一段非常漂亮的总结陈词。只看它说了什么,你测的是它的文笔,不是它的工作。

台阶二:八次都对吗?—— pass@k 和 pass^k

状态断言解决了"结果对不对",紧接着就是同事问我的那个问题:它对一次不算本事,能不能次次都对?

这里有一对指标,一个上标之差,语义完全相反。我见过太多人在面试里把它们混为一谈。

指标

定义

衡量什么

k 增大时

pass@k

k 次里至少成功 1 次的概率

能力上限(它能不能做到)

单调上升,趋近 100%

pass^k

k 次全部成功的概率

可靠性(它是不是次次都行)

单调下降,趋近 0%

pass@k最早用在代码生成(HumanEval、Codex)里,因为那个场景你可以生成 5 个候选自己挑一个能用的——"成一次就有价值",所以用 pass@5 合理。

但 Agent 不是。客服 Agent 替用户改签机票,用户没有"从五个结果里挑一个"的机会,他只经历一次,错了就是错了。所以 Agent 场景看的是pass^k

Anthropic 在评测指南里给过一个心算就能验证的例子:单次成功率 75% 的 Agent,连续三次全对的概率是 0.75³ ≈ 42%。

Sierra 的 τ-bench(读 tau-bench,τ = tool-agent-user)把这件事量化到了扎心的程度。它在零售、航空两个领域里,让 Agent 一边跟 LLM 扮演的用户多轮对话,一边调用能读能写数据库的领域工具,还要全程遵守一份业务规则文档;判定不看对话,只看最终数据库状态是否等于标注的目标状态。论文首发版报告的数字是:GPT-4o 在零售域 pass^1 约 61%,而 pass^8 跌破 25%(官方仓库后续复跑数字有波动,量级结论不变)。

翻成大白话:一个单次成功率刚过六成的 Agent,用户用满八次,能八次全对的概率不到四分之一。

这就是"demo 很惊艳、上线就翻车"的数学解释。而且请注意,这些失败不是集中在"它不会做的难题"上,而是散布在"它会做、也做对过"的任务上——方差在任务内部,不在任务之间。

所以这一层的工程结论只有一句:

选指标的判断依据

用户能挑的场景看 pass@k,用户只能接受一次的场景看 pass^k。几乎所有 Agent 上线场景都是后者。

台阶三:把"过程"拆开打分——四层金字塔

结果测对了,稳定性也有了指标,现在才轮到"过程"。

我把 Agent 评测拆成四层。你往上走一层,成本高一档,但漏测的故障少一类。

层级

回答什么问题

具体指标

常见漏测

结果层

事办成了没有

任务成功率、pass^k、终端状态断言、部分得分

重复退款、金额错误、越权改动

过程层

每一步走没走对

工具选择准确率、参数正确率、上下文一致性、失败自愈

中期失忆、参数幻觉、无意义重试

约束层

有没有越线、值不值

安全拒答、业务规则合规、步数/token/时延/金钱成本

工具调对了但违反业务政策

基建层

分数是怎么算出来的

可重置沙箱、裁判与人工对齐率、CI 回归门禁

用例互相污染、裁判本身不准

四层里,最容易被忽略的其实是过程层的两个细分项,我单独拎出来说。

第一,工具调用必须拆成两个独立指标。工具"选对"和参数"填对"是两种完全不同的故障,混在一起测,出问题你不知道该调 prompt 还是该改 schema。还有个高阶指标叫 abstention rate——没有合适工具时,它能不能正确拒绝调用,而不是硬编一个

第二,上下文一致性。这是长任务最典型的故障:中期失忆。第 2 步用户提的关键约束,到第 8 步被彻底忘掉,于是它很努力地完成了一个稍微不同的目标。

用实习生比喻特别好讲:他记得要去订酒店,但忘了你们有 8 个人,订了间 4 人房。每一步单看都自洽,只有跨步断言抓得出来。

业内公开复盘里有个典型案例:某 Agent 反复调用一个返回 "Tool not found" 的工具,毫无进展,最后直接转人工。每一次调用都返回干净的状态码,只看接口监控完全发现不了——全 200,也能整件事办砸。

三种判分器,别让裁判模型干它不该干的活

这一层最容易犯的错,是什么都丢给"大模型当裁判"。

正确做法是三层分工,原则只有一句:能用代码判定的,绝不用模型判。

判分器

判什么

成本

特点

规则判分

死循环、禁用工具、步数/成本超上限、JSON schema 校验

确定性,每次结果一致

状态断言

数据库/外部系统的终端状态、副作用边界

客观,不受措辞影响

裁判模型

推理是否合理、是否忠于检索到的上下文、语气是否合适

主观,必须校准

裁判模型有三个坑,面试里说出来就是分:

  1. 位置偏差:偏爱排在第一个的候选答案。
  2. 长度偏差:偏爱更啰嗦的那个答案,哪怕它更空。
  3. 自恋偏差:偏爱自己家族模型生成的输出。

所以裁判模型必须配详细 rubric,必须跟人类标注算对齐率(agreement rate)。未经校准的裁判,不能直接当质量门禁用——我见过团队用裁判模型卡发布,结果它给一堆错误答案打了满分,因为那些答案写得很长很自信。

台阶四:把评测从"报告"变成"门禁"

到这一步,很多人以为完事了。其实还差最后、也是最容易被面试官追问的一层。

同一个 Agent,你今天测 80 分,下个月换个模型版本可能只剩 50 分。

Agent 的行为会随模型更新、prompt 改动、工具 schema 调整、流量分布偏移而漂移。所以评测集不是一次性用品,它是要挂进 CI 的:每次改 prompt、加工具、换模型,都跑一遍评测集,pass^1 或 pass^8 掉出基线就卡住合并。

这是"会评测"和"工程化落地"的分水岭,也是面试官判断你真做过还是背过的地方。

沙箱本身还有两条硬性要求,缺一条分数就不可信:

  • 可重置每次跑完必须回到已知初始状态。否则用例之间互相污染,这一次的分和上一次的分根本不可比。
  • 边界隔离沙箱要在架构上访问不到生产。靠一个TEST_MODE变量、而进程里握着生产支付密钥,那不叫隔离。

Java 实战:一个能直接跑的评测执行器

光说不练假把式。下面这份骨架是纯 Java(JDK 17+),不依赖任何 AI 框架,你能直接抄走改造。(代码里Json.parse(...)是 JacksonObjectMapper.readValue的简写占位,换成你项目里的 JSON 工具即可。)

package com.fox.agent.eval; import java.time.Duration; import java.util.*; import java.util.function.*; import java.util.stream.*; // ══════════ 0. 轨迹:每一步都必须是可检索的 span ══════════ public record Trajectory( String traceId, List<Step> steps, String finalAnswer, long tokensUsed, long costCents, Duration wallClock ) { public record Step(String thought, String toolName, Map<String, Object> args, String observation) {} public int toolCallCount() { return (int) steps.stream().filter(s -> s.toolName() != null).count(); } /** 死循环检测:同一工具 + 同一组参数重复出现 3 次以上 */ public boolean hasToolLoop() { Map<String, Long> counter = new HashMap<>(); for (Step s : steps) { if (s.toolName() == null) continue; String sig = s.toolName() + "|" + s.args(); if (counter.merge(sig, 1L, Long::sum) >= 3L) return true; } return false; } } // ══════════ 1. 世界状态:Agent 能改的一切,都必须可快照 ══════════ public final class WorldState { private final Map<String, List<Map<String, Object>>> tables; private WorldState(Map<String, List<Map<String, Object>>> tables) { this.tables = new LinkedHashMap<>(tables); } public static WorldState of(Map<String, List<Map<String, Object>>> t) { return new WorldState(t); } public List<Map<String, Object>> select(String table) { return tables.getOrDefault(table, List.of()); } public long count(String table, String field, Object expected) { return select(table).stream() .filter(row -> Objects.equals(row.get(field), expected)).count(); } public Optional<Object> field(String table, String id, String field) { return select(table).stream() .filter(row -> Objects.equals(row.get("id"), id)) .map(row -> row.get(field)).findFirst(); } public List<String> tables() { return List.copyOf(tables.keySet()); } } // ══════════ 2. 状态断言:代码能判的,绝不用模型判 ══════════ @FunctionalInterface public interface StateAssertion { AssertionResult test(WorldState before, WorldState after); } public record AssertionResult(String name, boolean passed, String detail) { public static AssertionResult ok(String n, String d) { return new AssertionResult(n, true, d); } public static AssertionResult fail(String n, String d) { return new AssertionResult(n, false, d); } } public final class Assertions { /** 条数断言:抓"多退了一笔""多发了封邮件" */ public static StateAssertion countIs(String table, String field, Object value, long expected) { return (before, after) -> { long actual = after.count(table, field, value); String detail = "expected=" + expected + ", actual=" + actual; return actual == expected ? AssertionResult.ok(table + ".count", detail) : AssertionResult.fail(table + ".count", detail); }; } /** 字段断言:抓"金额退错了""状态没流转" */ public static StateAssertion fieldIs(String table, String id, String field, Object expected) { return (before, after) -> { Object actual = after.field(table, id, field).orElse(null); String detail = "expected=" + expected + ", actual=" + actual; return Objects.equals(actual, expected) ? AssertionResult.ok(table + "." + field, detail) : AssertionResult.fail(table + "." + field, detail); }; } /** 副作用断言:抓"顺手动了不该动的表" */ public static StateAssertion noSideEffect(Set<String> allowedTables) { return (before, after) -> { List<String> touched = after.tables().stream() .filter(t -> !allowedTables.contains(t)) .filter(t -> !Objects.equals(before.select(t), after.select(t))) .toList(); return touched.isEmpty() ? AssertionResult.ok("noSideEffect", "未触碰白名单外的表") : AssertionResult.fail("noSideEffect", "越界修改: " + touched); }; } } // ══════════ 3. 评测用例:初始状态 + 指令 + 期望终态 ══════════ public record EvalCase( String id, String instruction, String sandboxFixture, List<String> mustCallTools, List<String> forbiddenTools, List<StateAssertion> assertions, int maxSteps, long maxCostCents ) {} // ══════════ 4. 三种判分器:规则 / 断言 / 裁判 ══════════ public record Grade(String grader, boolean passed, double score, String reason) {} public sealed interface Grader permits RuleGrader, StateGrader, LlmJudgeGrader { Grade grade(EvalCase kase, Trajectory traj, WorldState before, WorldState after); } /** 规则判分器:零成本、确定性,负责"一票否决" */ public final class RuleGrader implements Grader { @Override public Grade grade(EvalCase k, Trajectory t, WorldState b, WorldState a) { if (t.hasToolLoop()) return new Grade("rule", false, 0.0, "检测到工具死循环"); Set<String> used = t.steps().stream() .map(Trajectory.Step::toolName).filter(Objects::nonNull) .collect(Collectors.toSet()); List<String> hit = k.forbiddenTools().stream().filter(used::contains).toList(); if (!hit.isEmpty()) return new Grade("rule", false, 0.0, "调用了禁用工具: " + hit); if (t.steps().size() > k.maxSteps()) return new Grade("rule", false, 0.0, "步数超限: " + t.steps().size()); if (t.costCents() > k.maxCostCents()) return new Grade("rule", false, 0.0, "成本超限: " + t.costCents()); return new Grade("rule", true, 1.0, "规则层通过"); } } /** 状态判分器:真正的"结果层",不看它说了什么,看世界变成什么样 */ public final class StateGrader implements Grader { @Override public Grade grade(EvalCase k, Trajectory t, WorldState b, WorldState a) { List<AssertionResult> all = k.assertions().stream() .map(x -> x.test(b, a)).toList(); List<AssertionResult> failed = all.stream().filter(r -> !r.passed()).toList(); double score = all.isEmpty() ? 1.0 : (double) (all.size() - failed.size()) / all.size(); return failed.isEmpty() ? new Grade("state", true, score, "全部状态断言通过") : new Grade("state", false, score, "失败断言: " + failed); } } /** 裁判模型:只判代码判不了的语义部分,且必须与人工标注对齐后才可当门禁 */ public final class LlmJudgeGrader implements Grader { public record JudgeVerdict(boolean passed, double score, String reason) {} private final BiFunction<String, String, String> llm; // (rubric, 待评内容) -> JSON private final String rubric; public LlmJudgeGrader(BiFunction<String, String, String> llm, String rubric) { this.llm = llm; this.rubric = rubric; } @Override public Grade grade(EvalCase k, Trajectory t, WorldState b, WorldState a) { String payload = t.steps().stream() .map(s -> s.thought() + " | " + s.toolName() + s.args()) .collect(Collectors.joining("\n")); try { JudgeVerdict v = Json.parse(llm.apply(rubric, payload), JudgeVerdict.class); return new Grade("llm-judge", v.passed(), v.score(), v.reason()); } catch (Exception e) { // 裁判自己出错,绝不能默认判"通过"——这是最容易埋雷的地方 return new Grade("llm-judge", false, 0.0, "裁判输出解析失败,降级为不通过: " + e.getMessage()); } } } // ══════════ 5. pass^k 无偏估计:C(c,k) / C(n,k) ══════════ public final class PassK { public static double passHatK(int trials, int successes, int k) { if (k < 1) throw new IllegalArgumentException("k 必须 >= 1"); if (trials < k) throw new IllegalArgumentException("试验次数必须 >= k"); if (successes < k) return 0.0; return comb(successes, k) / comb(trials, k); } static double comb(int n, int k) { if (k < 0 || k > n) return 0.0; double r = 1.0; for (int i = 1; i <= k; i++) r = r * (n - k + i) / i; return r; } } // ══════════ 6. 执行器:沙箱必须可重置,异常不能中断整轮 ══════════ public final class EvalRunner { public interface Agent { Trajectory run(String instruction); } public interface Sandbox { void reset(String fixture); WorldState snapshot(); } public record CaseReport(String caseId, int successes, int trials, double pass1, double pass8) {} public record EvalReport(List<CaseReport> cases) { public double meanPass1() { return cases.stream().mapToDouble(CaseReport::pass1).average().orElse(0.0); } public double meanPass8() { return cases.stream().mapToDouble(CaseReport::pass8).average().orElse(0.0); } } private final Supplier<Agent> agentFactory; private final Sandbox sandbox; private final List<Grader> graders; public EvalRunner(Supplier<Agent> f, Sandbox s, List<Grader> g) { this.agentFactory = f; this.sandbox = s; this.graders = List.copyOf(g); } public EvalReport run(List<EvalCase> cases, int repeats) { List<CaseReport> out = new ArrayList<>(); for (EvalCase kase : cases) { int successes = 0; for (int i = 0; i < repeats; i++) { if (runOnce(kase)) successes++; } int k8 = Math.min(8, repeats); out.add(new CaseReport(kase.id(), successes, repeats, PassK.passHatK(repeats, successes, 1), PassK.passHatK(repeats, successes, k8))); } return new EvalReport(out); } private boolean runOnce(EvalCase kase) { try { sandbox.reset(kase.sandboxFixture()); // 每次都回到已知初始状态 WorldState before = sandbox.snapshot(); Trajectory traj = agentFactory.get().run(kase.instruction()); WorldState after = sandbox.snapshot(); return graders.stream() .allMatch(g -> g.grade(kase, traj, before, after).passed()); } catch (Exception e) { return false; // 异常即失败,但绝不能中断整轮评测 } } }

把上面这套挂成 CI 门禁,就差一个测试:

class AgentEvalGateTest { @Test @DisplayName("回归门禁:通过率不得低于基线") void regressionGateMustNotDropBelowBaseline() { EvalReport report = new EvalRunner(AgentFactory::new, sandbox, List.of(new RuleGrader(), new StateGrader(), judge)) .run(suite.cases(), 8); assertThat(report.meanPass1()).isGreaterThanOrEqualTo(0.60); assertThat(report.meanPass8()).isGreaterThanOrEqualTo(0.25); } }

五个工程细节,面试里说出来就是加分项:

  1. 断言写"状态"不写"措辞"Agent 换种说法不算失败,世界状态错了才算。
  2. 顺序约束只加在真有依赖的地方先读后写必须有序,其他用存在性断言。写成固定动作序列,会误杀"换了条同样正确的路"的 Agent。
  3. 裁判解析失败降级为"不通过"默认判过是最隐蔽的埋雷方式。
  4. 异常吞掉记为失败,但不中断整轮一个用例崩了不应该让整晚的评测白跑。
  5. 每次跑之前 reset 沙箱不 reset,你的分数就没有可比性,趋势图全是噪声。

⚠️ 五个避坑清单

坑一:拿最终回复做文本匹配。Agent 可以留下一地鸡毛后写出漂亮总结。改状态断言。

坑二:把评测集写成固定动作序列。会误杀走另一条正路的 Agent。只对有真实依赖的步骤加顺序约束。

坑三:只看接口返回码。全 200 也可能整件事办砸——那个反复调 "Tool not found" 的案例就是。

坑四:裁判模型直接当门禁。先跟人工标注算对齐率。位置偏差、长度偏差、自恋偏差都会让它的分数系统性失真。

坑五:评测跑一次就归档。模型会更新、prompt 会改、流量会漂移。不挂 CI,你的评测集三个月后就是废纸。

追问连环炮

Q1:pass@k 和 pass^k 到底选哪个?<br>看用户有没有"重试/挑选"的机会。代码补全给你 5 个候选你挑一个,pass@5 合理;客服 Agent 替用户改签机票,用户只经历一次,必须看 pass^k。一句话:能挑看 pass@k,不能挑看 pass^k。

Q2:为什么不能让裁判模型判所有东西?<br>三个理由:成本高、有系统性偏差(位置/长度/自恋)、结果不稳定。规则能判的死循环、成本超限、schema 校验,用代码判,零成本且每次一致。裁判只留给真正需要语义理解的部分。

Q3:Agent 输出自由,怎么保证评测能覆盖所有情况?<br>不要试图覆盖"所有输出",去覆盖"所有故障模式"。从线上事故和人工复核记录里反向沉淀用例,比正向脑补有效得多。业界常见的起点是 30~50 条覆盖关键分支的用例,再随事故增长。

Q4:沙箱和全量复制生产,哪个对?<br>都不要全量复制。建最小忠实沙箱:保留影响 Agent 决策和副作用的部分——带固定数据的库、会记录意图但不能真转账的支付适配器、能收信的邮件汇、可控的时钟、身份夹具,加一个 reset 函数。生产要访问不到。

Q5:工具调用对了但结果还是错的,怎么抓?<br>这正是状态断言存在的意义。工具调用正确不等于业务效果正确——中间可能因为工具实现 bug、环境差异导致结果偏离。必须查终端状态。

答题骨架(2 分钟版)

面试官问"怎么评测一个 Agent",按这四拍说:

第一拍 · 点破差异:Agent 和传统大模型的本质区别不是会思考会调工具,是它有行动权、会产生副作用。所以不能用标准化试卷考,要像考核一个能出去办事的人一样全程跟踪。

第二拍 · 分四层答:结果层看任务成功率和终端状态断言;可靠性层看 pass^k,不是 pass@k;过程层拆规划、工具选择、参数正确率、上下文一致性、失败自愈;约束层看安全、业务规则合规和成本效率。

第三拍 · 说清怎么判分:三种判分器分工——规则判一票否决项,状态断言判业务结果,裁判模型只判语义且必须与人工标注对齐。沙箱要可重置、要隔离。

第四拍 · 落到工程:评测集挂 CI 做回归门禁,每次改 prompt、加工具、换模型都跑一遍,pass^1 / pass^8 掉出基线就卡住合并。

加分收尾:如果只让我留一句话——单次成功率 60% 的 Agent,连做八次全对的概率只有 1.7%。Agent 评测测的不是"它能不能做到",是"它是不是次次都做到"。

资料展示:

下面是我整理的AI大模型 学习资料和工具包预览,适合收藏后按主题逐步学习

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 11:55:02

智能音箱选购指南:从参数到生态,避开智商税选对设备

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 11:45:40

基于ES9038PRO与线性电源的高性能DAC DIY实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 11:43:28

Apache ECharts 6.7 万 Star,数据可视化首选

一、项目背景及简介 做数据可视化时&#xff0c;你还在用 Chart.js 反复调样式&#xff1f;或者用 D3.js 从头画图&#xff1f;前者功能太弱&#xff0c;后者学习成本太高。有没有一个库&#xff0c;既开箱即用又高度可定制&#xff0c;还能在百万级数据量下流畅运行&#xff…

作者头像 李华
网站建设 2026/9/24 11:43:05

SVPWM算法原理与FPGA/MCU实现:从扇区判断到过调制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 11:43:04

MOS管散热孔设计:孔径、间距与阵列的3个关键尺寸

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 11:42:07

MOS管选型核心:跨导效率、截止频率与本征增益深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华