news 2026/10/6 6:23:44

从提示词到Loop:AI Agent运行时控制结构设计实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从提示词到Loop:AI Agent运行时控制结构设计实战

1. 从“写提示词”到“设计循环”:一个思维拐点的到来

我大概是在连续调了三个星期的提示词之后,才真正意识到问题的。那段时间我每天的工作状态就是:打开编辑器,改一段提示词,跑一遍 Agent,看它在哪里断掉,再改提示词,再跑。循环往复,像极了在跟一个记性不太好但脾气很倔的实习生反复交代同一件事。每次我以为自己把话说清楚了,它总能在某个意想不到的环节给我整出新花样——要么是工具调用参数拼错了,要么是任务做到一半自己给自己加戏,要么是明明上一轮已经确认过的信息,下一轮它又忘了。

后来我停下来复盘,发现一个很反直觉的事实:我花在提示词上的时间,和 Agent 实际能稳定完成的任务复杂度,并不成正比。提示词写得再精细,它本质上还是在描述“这一次该怎么做”。而 Agent 要真正自己跑起来,需要的不是“这一次怎么做”,而是“每一步做完之后,下一步该往哪走、什么时候该停、出错了怎么退回来”。这些东西,提示词给不了,得靠 Loop。

这里说的 Loop,不是编程里那个for循环那么简单。在 AI Agent 的语境下,Loop 指的是 Agent 的运行时控制结构——它决定了 Agent 在每一轮里看到什么、能做什么、做完之后状态怎么更新、什么条件下继续、什么条件下终止。提示词是“内容层”,Loop 是“控制层”。我之前的做法相当于把控制逻辑硬塞进内容层里,用自然语言去描述“如果 A 就做 B,否则做 C”,结果就是提示词越写越长,Agent 反而越来越不稳定。

这个认知转变之后,我把工作重心从“雕琢提示词”挪到了“设计 Loop”上。效果是肉眼可见的:同一个任务,之前需要我盯着跑五六轮、中途手动纠偏,现在它能自己跑完,我只需要在最后验收。当然,这个过程里踩的坑一点没少,有些坑还挺隐蔽的。下面我就把这套东西拆开讲,包括 Loop 到底该怎么设计、提示词在新架构里扮演什么角色、以及我实际踩过的那些坑。

2. 提示词工程的天花板到底在哪里

2.1 提示词能解决的问题,其实比想象中窄

很多人对提示词工程的理解是“把话说清楚,模型就能做对”。这话在单轮任务里基本成立,比如“把这段中文翻译成英文”“从这段文本里提取人名和公司名”。但只要任务超过一轮,需要模型自己决定下一步做什么,提示词的局限性就暴露了。

我举个实际例子。我做过一个任务:让 Agent 去某个代码仓库里找所有硬编码的 API 密钥,然后生成一份报告。这个任务拆开看大概是:遍历文件、识别疑似密钥的字符串、排除测试文件、汇总结果、写报告。如果我把这些步骤全部写进提示词,告诉它“第一步遍历文件,第二步识别密钥,第三步排除测试文件……”,会发生什么?

实测下来,模型在前两轮还能按部就班,到了第三轮开始,它就会开始“自由发挥”。有时候它会把node_modules里的文件也扫进去,有时候它会在识别密钥的时候把普通的变量名也当成密钥,有时候它干脆跳过排除测试文件这一步直接汇总。原因很简单:提示词是静态的,而任务执行是动态的。每一轮模型看到的上下文都在变,但提示词里描述的逻辑是固定的,模型需要自己在脑子里把静态逻辑映射到动态状态上,这个映射过程极容易出错。

2.2 长提示词的边际收益递减

我做过一个粗略的对比实验。同一个任务,我写了三个版本的提示词:短版(约 200 字,只说明目标和输出格式)、中版(约 600 字,补充了步骤和注意事项)、长版(约 1500 字,把每一步的判断逻辑都写进去了)。然后每个版本各跑 20 次,统计任务完成率。

提示词版本字数任务完成率平均轮次人工干预次数
短版~20035%3.22.1
中版~60055%4.81.4
长版~150058%6.51.2

数据很说明问题:提示词从 200 字加到 600 字,完成率涨了 20 个百分点;但从 600 字加到 1500 字,完成率只涨了 3 个百分点,而平均轮次和人工干预次数并没有明显改善。更麻烦的是,长提示词让 Agent 的响应变慢、token 消耗变大,而且一旦任务场景稍有变化,长提示词里那些具体的步骤描述反而成了束缚。

提示:如果你的提示词已经超过 800 字,而 Agent 的完成率还是上不去,大概率不是提示词的问题,而是 Loop 设计的问题。

2.3 提示词和 Loop 的分工边界

那提示词是不是就没用了?当然不是。我的经验是,提示词负责“定义角色和约束”,Loop 负责“控制流程和状态”。具体来说:

  • 提示词里应该写:Agent 的身份、能力边界、输出格式要求、安全约束、工具使用规范。
  • Loop 里应该管:当前处于哪个阶段、上一轮产出了什么、下一步该调用哪个工具、什么条件下重试、什么条件下终止。

举个例子。提示词里我会写“你是一个代码审计助手,只能读取文件,不能修改文件,输出必须是 JSON 格式”。而 Loop 里我会定义:第一轮调用文件遍历工具,拿到文件列表后进入第二轮;第二轮对每个文件调用内容读取工具,识别密钥;第三轮过滤测试文件;第四轮汇总输出。每一轮的状态(文件列表、已识别的密钥、过滤结果)都存在 Loop 的上下文里,而不是靠提示词去“记住”。

这样分工之后,提示词可以写得很短,Loop 的逻辑可以写得很清晰,两者各司其职,Agent 的稳定性明显提升。

3. Loop 的核心构件:状态、动作、终止条件

3.1 状态管理:Agent 的“工作记忆”该放在哪里

Loop 设计里最容易被低估的就是状态管理。我一开始的做法是让 Agent 自己维护状态——每轮结束的时候,让它把当前进展写进一个变量里,下一轮再读出来。听起来很合理,但实际跑起来问题很多。

第一个问题是状态漂移。Agent 在写状态的时候,会根据自己的理解“润色”一下,比如把“已扫描 12 个文件,发现 3 个疑似密钥”写成“已扫描部分文件,发现若干密钥”。信息在传递过程中被压缩了,下一轮它拿到这个模糊的状态,判断就会出错。

第二个问题是状态膨胀。如果每一轮都把完整的历史状态塞进上下文,几轮之后上下文就会变得非常长,模型处理起来又慢又容易分心。

我后来采用的方案是:状态由 Loop 的宿主程序维护,而不是由 Agent 维护。具体来说,Agent 每一轮只负责输出“这一轮做了什么、产出了什么”,宿主程序负责把这些产出结构化地存起来,下一轮只把必要的状态注入到提示词里。这样状态是精确的、可控的,不会漂移也不会膨胀。

用伪代码表示大概是这样:

state = { "phase": "scan", "files_scanned": [], "findings": [], "retry_count": 0 } while state["phase"] != "done": prompt = build_prompt(state) # 只注入当前阶段需要的状态 result = agent.run(prompt) state = update_state(state, result) # 宿主程序更新状态

这个结构看起来简单,但它把“状态”从 Agent 的脑子里挪到了程序里,稳定性提升了一个量级。

3.2 动作空间:每一轮到底允许 Agent 做什么

动作空间的设计直接决定了 Agent 会不会“乱来”。我踩过的一个坑是:早期我给 Agent 开放了太多工具,它在一轮里可以同时调用文件读取、网络请求、代码执行、数据库查询。结果就是它经常在应该只读文件的时候去调网络请求,或者在应该汇总结果的时候又去读了一遍文件。

后来我改成按阶段收窄动作空间:在扫描阶段只开放文件遍历和读取工具,在分析阶段只开放文本处理工具,在汇总阶段只开放输出工具。每一轮 Agent 能做什么是明确的,它就不会跑偏。

这个思路其实和人类工作很像。你在做代码审计的时候,不会一边看代码一边发邮件一边改数据库。每个阶段有每个阶段的工具集,阶段之间是串行的。Agent 也一样,给它太多自由,它反而不知道该干什么。

3.3 终止条件:什么时候该停,什么时候该重试

终止条件是 Loop 设计里最需要小心的地方。我见过两种极端:一种是终止条件太松,Agent 跑了几十轮还在那里打转;另一种是终止条件太紧,Agent 刚开了个头就被强制结束。

我的经验是,终止条件要分三层:

  • 成功终止:任务目标达成,比如“所有文件已扫描且报告已生成”。
  • 失败终止:出现了不可恢复的错误,比如“连续三轮工具调用失败”或“重试次数超过上限”。
  • 人工介入终止:Agent 自己判断需要人类决策,比如“发现疑似密钥但无法确定是否为测试数据”。

第三层特别重要。很多 Loop 设计里只有成功和失败两种终止,但实际任务里经常出现“Agent 不确定该怎么办”的情况。这时候如果强行让它继续,它就会瞎猜;如果直接判失败,又浪费了前面的工作。所以我在 Loop 里加了一个need_human状态,Agent 可以主动把控制权交回来,我处理完之后再让它继续。

4. 我踩过的五个坑,以及每个坑的排查过程

4.1 坑一:Loop 里的提示词注入把状态覆盖了

这个坑我排查了整整一个下午。现象是:Agent 在前几轮表现正常,到了第四轮突然开始重复第一轮的工作。我一开始以为是模型的问题,换了几个模型都一样。后来把每一轮的完整提示词打印出来看,才发现问题出在状态注入上。

我的 Loop 里有一个build_prompt函数,负责把当前状态拼进提示词。当时的写法是先把基础提示词模板加载进来,然后把状态字段逐个替换进去。但基础模板里有一个占位符叫{current_task},而状态里也有一个字段叫current_task,结果替换的时候把整个任务描述覆盖成了当前阶段名。Agent 看到的任务变成了“scan”,它自然就重新开始扫描了。

这个坑的教训是:状态字段的命名要和提示词模板的占位符严格区分开。我后来的做法是给所有状态字段加前缀,比如state_phase、state_files,这样就不会和模板里的占位符冲突。另外,build_prompt函数里加了一个断言,检查替换后的提示词里是否还残留未替换的占位符,有的话直接报错,不让它带着问题往下跑。

4.2 坑二:工具调用失败后的重试逻辑把 Agent 带进了死循环

有一次我让 Agent 去调用一个外部 API 获取数据,那个 API 偶尔会超时。我在 Loop 里加了重试逻辑:如果工具调用失败,就等两秒再试一次,最多试三次。听起来没问题,但实际跑的时候 Agent 卡在那里不动了。

排查后发现,问题出在重试的粒度上。我的重试逻辑是包在单轮里的:一轮里如果工具调用失败,就重试三次。但 Agent 在工具调用失败后,会认为这一轮没有产出有效结果,于是它会在下一轮重新尝试同样的工具调用。而下一轮里又有三次重试。结果就是 3×3×3……无限套娃。

修复方案是把重试逻辑从“单轮内重试”改成“跨轮重试”:单轮内工具调用失败就直接返回失败状态,由 Loop 决定是否进入下一轮重试,并且用一个全局的重试计数器来控制总次数。这样重试次数是可控的,不会指数级膨胀。

注意:重试逻辑一定要有全局计数器,不能只在单轮内计数。否则 Agent 的每一轮都会“重新开始计数”,导致无限重试。

4.3 坑三:状态序列化时把不可序列化的对象塞进去了

这个坑比较隐蔽。我的状态里存了一个文件句柄对象,用来在多个轮次之间保持文件读取的进度。在单次运行里没问题,但当我尝试把状态存到磁盘上做断点续跑的时候,序列化直接报错了。

排查过程比较直接:看报错信息就知道是哪个字段的问题。但修复的时候我犹豫了一下——是把这个字段去掉,还是换一种可序列化的表示方式?最后我选择了后者:把文件句柄换成文件路径加偏移量,需要读文件的时候再重新打开。这样状态就是纯数据的,可以随便序列化和反序列化。

这个坑的教训是:状态里只放数据,不放资源。资源(文件句柄、网络连接、数据库连接)应该在需要的时候创建,用完就释放,不要跨轮次持有。这样 Loop 的可恢复性会好很多,也更容易调试。

4.4 坑四:终止条件写成了“或”而不是“与”

这个坑导致 Agent 经常提前终止。我的终止条件原本写的是“所有文件已扫描 或 报告已生成”,本意是这两个条件满足任意一个就可以停。但实际执行的时候,Agent 在扫描完第一个文件之后就认为“所有文件已扫描”这个条件满足了(因为它把“所有”理解成了“当前这一批”),于是直接跳到报告生成阶段,报告里只有第一个文件的结果。

修复方案是把终止条件改成“所有文件已扫描 且 报告已生成”,并且把“所有文件”的定义明确成“初始文件列表里的每一个文件都处理过”。另外,我在 Loop 里加了一个校验步骤:在进入报告生成阶段之前,检查已处理文件数是否等于初始文件数,不等的话就退回扫描阶段。

这个坑的教训是:终止条件里的逻辑连接词要反复推敲。“或”和“与”一字之差,行为完全不同。而且自然语言里的“所有”“完成”“结束”这些词都有歧义,最好用可量化的条件来替代。

4.5 坑五:Agent 在 Loop 里“学会”了偷懒

这个坑最有意思。我让 Agent 做一个数据清洗任务,Loop 设计是:每轮处理一批数据,处理完检查质量,质量达标就进入下一批。跑了一段时间后我发现,Agent 处理第一批数据的时候很认真,越往后越敷衍,最后几批几乎是原样输出。

排查后发现,Agent 在上下文中看到了前面几轮的成功记录,它“推断”出这个任务的标准在降低,于是自己也降低了标准。这其实是模型的一种“模式匹配”行为:它看到前面的输出都是“通过”,就认为自己的输出也应该“通过”,于是不再认真做质量检查。

修复方案是在每一轮的质量检查环节,不把前面的成功记录注入上下文,只注入当前批次的数据和检查标准。这样 Agent 每一轮看到的都是“ fresh ”的任务,不会受到历史记录的影响。

这个坑的教训是:Loop 里的上下文注入要克制。不是所有历史信息都需要让 Agent 看到。有些信息(比如前面的成功记录)会让 Agent 产生“惯性”,反而降低它的表现。每一轮只注入当前决策必需的信息,是最稳妥的做法。

5. 一个可复用的 Loop 骨架设计

5.1 阶段划分:把任务拆成有限个状态

经过上面这些坑,我总结出了一个比较通用的 Loop 骨架。核心思路是:把任务拆成有限个阶段,每个阶段有明确的输入、输出和退出条件。阶段之间是串行的,阶段内部可以有多轮。

以代码审计任务为例,阶段划分大概是:

阶段输入输出退出条件
初始化仓库路径文件列表文件列表非空
扫描文件列表疑似密钥列表所有文件已扫描
过滤疑似密钥列表确认密钥列表过滤规则已应用
汇总确认密钥列表报告报告已生成

每个阶段内部,Agent 可以有多轮交互。比如扫描阶段,如果文件很多,可以分批扫描,每批一轮。但阶段之间的推进是明确的:扫描阶段不结束,不会进入过滤阶段。

5.2 状态机实现:用代码而不是提示词来控制流程

这个骨架用代码实现大概是这样:

class AgentLoop: def __init__(self, task): self.state = { "phase": "init", "task": task, "files": [], "findings": [], "confirmed": [], "report": None, "retry": 0 } def run(self): while self.state["phase"] != "done": handler = getattr(self, f"phase_{self.state['phase']}") handler() return self.state["report"] def phase_init(self): result = self.call_agent("init", self.state) self.state["files"] = result["files"] self.state["phase"] = "scan" if self.state["files"] else "failed" def phase_scan(self): result = self.call_agent("scan", self.state) self.state["findings"].extend(result["findings"]) if result["done"]: self.state["phase"] = "filter" # ... 其他阶段类似

这个结构的好处是:流程控制完全在代码里,Agent 只负责每个阶段内的具体工作。Agent 不需要知道“下一步该干什么”,它只需要知道“当前这个阶段该产出什么”。这样提示词可以写得很短,Agent 的负担也小很多。

5.3 提示词模板:每个阶段一个短提示词

对应上面的阶段划分,提示词也拆成多个短模板。比如扫描阶段的提示词大概是:

你是一个代码审计助手,当前处于扫描阶段。 你的任务是:读取给定的文件列表,识别其中疑似 API 密钥的字符串。 输出格式:JSON,包含 findings 数组和 done 布尔值。 约束:只读取文件,不修改文件;只识别密钥,不做其他分析。

这个提示词不到 100 字,但信息很明确。Agent 知道自己在哪个阶段、要做什么、输出什么格式。它不需要知道整个任务的流程,因为流程由 Loop 控制。

对比之前那个 1500 字的长提示词,这个短提示词的效果反而更好。原因很简单:Agent 的注意力是有限的,提示词越短,它越能把注意力集中在当前任务上。

6. 从提示词思维切换到 Loop 思维的实际收益

6.1 稳定性:从“看运气”到“可预期”

切换之前,我跑 Agent 的心态是“看运气”。同一个任务,有时候能跑通,有时候跑不通,跑不通的时候我也不知道问题出在哪里。切换之后,Agent 的行为变得可预期了:如果某个阶段出错,我能定位到具体是哪个阶段、哪个环节的问题,然后针对性地修。

这种可预期性带来的最大好处是:我敢把更复杂的任务交给它了。以前我只敢让它做单步任务,现在我可以让它做多阶段任务,因为我知道每个阶段的边界在哪里,出问题也能兜住。

6.2 可调试性:出错时知道该看哪里

Loop 结构让调试变得简单了很多。以前 Agent 出错,我只能看最终输出,然后猜是哪一步出了问题。现在我可以看每一轮的状态变化,知道它在哪个阶段卡住了、卡住的时候状态是什么、上一轮产出了什么。

我甚至在 Loop 里加了一个简单的日志系统,每一轮结束的时候把状态快照写到一个 JSON 文件里。出问题的时候直接看这个文件,比看模型的输出日志直观多了。

6.3 可扩展性:加新能力不用重写提示词

最后一个收益是可扩展性。以前加一个新能力,比如“让 Agent 在扫描的时候顺便统计文件行数”,我得改提示词,而且改完之后可能影响其他部分的行为。现在加新能力只需要在对应阶段里加一个工具调用,或者在状态里加一个字段,不影响其他阶段。

这个收益在任务变复杂的时候特别明显。我的代码审计 Agent 从最初的“找密钥”扩展到“找密钥 + 找硬编码密码 + 找敏感配置”,只花了不到一个小时,因为每个新能力都是独立的阶段或阶段内的独立工具调用,互不干扰。

7. 一些零散但实用的经验

7.1 日志要记状态,不要只记输出

我一开始的日志只记 Agent 的文本输出,后来发现不够用。Agent 的输出是自然语言,看多了会累,而且很多关键信息(比如状态字段的值)不在输出里。后来我改成记状态快照,每一轮结束的时候把整个 state 序列化成 JSON 写文件。这样出问题的时候,我直接 diff 两个状态快照,就知道哪一步改变了什么。

7.2 给 Agent 的“自由发挥”留一个口子

虽然 Loop 控制了大部分流程,但有些情况下 Agent 确实需要自由发挥。比如它在扫描的时候发现了一个不在预期内的文件类型,它可能需要临时决定怎么处理。我的做法是在每个阶段里留一个notes字段,Agent 可以把它的“意外发现”写进去,Loop 在推进到下一阶段之前会检查这个字段,如果有内容就暂停一下让我看看。

这个口子不大,但很有用。它让 Agent 在遇到意外情况时有一个“举手”的渠道,而不是硬着头皮往下做或者直接卡死。

7.3 阶段不要拆得太细

我一开始把阶段拆得很细,一个任务拆了十几个阶段。结果 Loop 的代码变得很臃肿,阶段之间的状态传递也很繁琐。后来我合并了一些阶段,保持在 4 到 6 个阶段,代码清爽了很多,Agent 的表现也没有下降。

我的经验是:阶段的粒度应该以“决策点”为准。如果一个地方需要 Agent 做判断(比如“这批数据质量达标了吗”),那它就是一个阶段边界。如果只是机械地执行,那它可以和相邻的步骤合并。

7.4 测试 Loop 的时候先用假 Agent

调试 Loop 本身的时候,不需要每次都调用真实模型。我写了一个FakeAgent类,它根据阶段名返回预设的假数据。这样我可以快速测试 Loop 的控制逻辑,不用等模型响应,也不用花 token。等 Loop 的逻辑跑通了,再换成真实 Agent 做端到端测试。

这个做法帮我省了很多时间。Loop 的 bug 和 Agent 的 bug 是两类问题,混在一起调很痛苦。先用假 Agent 把 Loop 调通,再用真 Agent 调提示词,效率高很多。

7.5 别忘了给 Loop 本身加超时

Loop 跑飞的情况我遇到过两次,都是因为某个阶段的退出条件没写对,Agent 在里面无限循环。后来我在 Loop 外面加了一个全局超时,比如 10 分钟没跑完就强制终止,并且把当前状态 dump 出来。这个超时救了我好几次,至少不会让一个跑飞的 Loop 占着资源不放。

8. 关于“鹈鹕骑自行车”那个测试的一点想法

最后聊一个题外话。最近看到不少人在讨论“鹈鹕骑自行车”这类提示词测试,大意是给模型一个很具体的场景描述,看它能不能生成符合要求的输出。这类测试用来评估模型的指令遵循能力是有意义的,但我想说的是:它测的是提示词工程的能力,不是 Agent 的能力。

一个 Agent 能不能自己工作,不取决于它能不能根据一段描述画出鹈鹕骑自行车,而取决于它能不能在没有人盯着的情况下,自己决定先画鹈鹕还是先画自行车、画完之后怎么检查、发现画错了怎么改。这些能力不在提示词里,在 Loop 里。

所以如果你也在做 Agent,我的建议是:把花在雕琢提示词上的时间,挪一半到设计 Loop 上。提示词写到 80 分就够了,剩下的 20 分靠 Loop 来补。你会发现,Agent 突然就“自己会工作”了。

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

用LTspice仿真施密特触发器:从回差曲线到实战技巧

很多朋友学施密特触发器时,都会被教科书上那条"回差曲线"绕晕,什么正向阈值电压、负向阈值电压、迟滞宽度,背得滚瓜烂熟,可真到了用LTspice拉一个仿真电路出来,反而不知道怎么下手。我之前也经历过这个阶段—…

作者头像 李华
网站建设 2026/10/6 6:22:07

开源本地部署的AI漫剧生成平台NovaNova Studio实战解析

最近圈子里好些人都在聊 NoveNova Studio,我一开始也没太当回事,毕竟“AI 生成视频”这类项目这两年见过太多了,大部分都是套壳或者只能生成几秒的片段。直到我花了一个周末把它完整跑通,才意识到这和我以前玩过的工具不在一个量级…

作者头像 李华
网站建设 2026/10/6 6:21:56

CTF入门到实战:五大题型解题思路与拿分攻略

简介:面向CTF初学者与备赛选手的题型与解题思路梳理文档,整合Web、密码学、逆向、PWN、杂项五类常见赛题。Web安全部分讲解基础爆破、SQL注入与盲注、XSS、命令注入、文件上传绕过、文件包含及代码审计,涵盖联合查询、报错注入、布尔盲注、WA…

作者头像 李华
网站建设 2026/10/6 6:20:19

2.4GHz WiFi接收机LNA设计:从ADS仿真到PCB实测的完整流程

1. 项目缘起与整体设计思路2.4GHz WiFi接收机的前端低噪声放大器,也就是LNA,是整个射频链路里最“娇贵”的一级。它坐在天线后面第一个位置,负责把天线收到的微弱信号放大,同时尽量不引入额外噪声。为什么说它娇贵?因为…

作者头像 李华
网站建设 2026/10/6 6:20:17

大模型推理优化实战:从TTFT、吞吐到企业私有化部署全链路

1. 大模型推理优化到底在优化什么先把话说直白一点:训练是把模型教聪明,推理是让模型在真实业务里跑得快、跑得稳、跑得便宜。很多团队模型训得不错,一上线就崩——首 token 延迟三秒起步,并发一上来显存直接爆,单次调…

作者头像 李华
网站建设 2026/10/6 6:20:02

Boost变换器DCM模式实战:波形识别、增益推导与光伏MPPT设计

Boost变换器这玩意儿,但凡做过电源的都不陌生。但真要把它放在DCM(断续导通模式)下跑,很多人就开始犯迷糊了——波形看着跟CCM差不多,可一算增益,公式完全对不上,仿真和实测还老打架。我自己第一…

作者头像 李华