迭代学习控制开源代码:让重复作业系统一次比一次精准
简介迭代学习控制ILC是一类面向重复性任务的控制策略核心思想是通过多次迭代修正控制输入逐步逼近期望输出在机器人、自动化生产线、航空航天等领域均有广泛应用。这份开源代码以单个MATLAB的m文件呈现压缩包整体仅2KB覆盖系统模型定义、迭代更新律、误差处理、停止准则等ILC核心模块结构紧凑便于快速阅读与二次开发。当前已有1246人浏览学习。借助这份代码研究者与工程师可以直观理解ILC从初始化、数据采集、误差分析到反馈校正的完整闭环流程掌握迭代学习律的更新规则设计思路并可将代码与滑模控制、模糊逻辑等方法结合增强系统鲁棒性与适应性。代码同样适合控制方向学生作为算法验证与教学演示的入门范本也可根据实际被控对象需求进行修改移植用于个人科研项目或工程实践。1. 迭代学习控制开源代码让重复作业的系统一次比一次更精准做过运动控制的开发者多少都遇到过这种场景同一个轨迹机器人每次都走出同样的偏差无论怎么调PID增益残差总是顽固地留在那里。迭代学习控制Iterative Learning Control简称ILC给出的思路很直接——既然每次都跑同一条轨迹那就把上一次的误差记录下来补偿到下一次的控制输入里去。时间轴上的高增益反馈难题被搬到了迭代轴上去解决这是一个反直觉但极其高效的切入角度。这份开源代码把P型、PD型、高阶学习律以及Q滤波器全部落地成可运行的仿真与实机接口适合做运动控制、机器人重复轨迹跟踪、批处理过程控制的开发者直接拿去跑通并二次改造。2. 架构与核心模块先看清控制系统里谁在迭代2.1 ILC在控制系统中的位置要理解这份代码先要摆正ILC的位置。ILC不替代反馈控制器它工作在反馈控制的外层。每一次运行结束时系统记录下输出信号与期望轨迹的误差然后依据学习律计算出修正量叠加到下一次运行的参考输入上。这个“迭代轴”上的运算与“时间轴”上的实时控制解耦所以代码里有一个清晰的层级划分底层是实时反馈控制环上层是迭代学习更新环。从信号流来看第k次运行得到输出轨迹 y_k(t)与期望轨迹 y_d(t) 做差得到误差 e_k(t)。学习律的核心公式通常写成u_{k1}(t) Q(q) * [u_k(t) Γ * e_k(tΔ)]其中 Γ 是学习增益矩阵Q(q) 是Q滤波器的频域表达式Δ 是相对阶次补偿。这份源码里默认实现了P型和PD型两种学习律P型只乘误差项PD型还会对误差求导后再乘一个微分增益。这两种实现放在learning_law/目录下接口统一方便替换。2.2 目录结构与模块职责拿到源码先看目录组织这份代码的结构是为二次开发留了接口的iterative_learning_control/ ├── learning_law/ │ ├── p_law.py │ ├── pd_law.py │ └── base_law.py ├── q_filter/ │ ├── zero_phase_lp.py │ └── fir_design.py ├── plant/ │ ├── linear_system.py │ └── nonlinear_system.py ├── simulation/ │ ├── runner.py │ └── metrics.py ├── config/ │ ├── default.yaml │ └── experiment_1.yaml ├── interface/ │ ├── real_time_io.py │ └── data_logger.py └── examples/ ├── run_basic_sim.py ├── run_compare.py └── run_real_io_demo.pylearning_law/是核心里面base_law.py定义了抽象基类只要实现update(previous_input, previous_error, current_input)这个方法就能接入新的学习律。q_filter/负责设计零相位低通滤波器——这是ILC能不能收敛的关键所在。plant/里是仿真被控对象既有线性传递函数模型也带一个非线性摩擦模型。simulation/把整个迭代过程串起来每次迭代后计算均方根误差、最大绝对误差、收敛速度三个指标。2.3 迭代收敛的数学条件为什么Q滤波器是生死线ILC不是天然收敛的。严格来说学习律的收敛条件要求对于所有频率ω满足|1 - Γ * P(e^{jωT})| 1这里 P 是被控对象的频响。如果对象在高频段有大的相位滞后直接套P型学习律很快就会在迭代轴上发散——误差越学越大这就是所谓的“迭代发散”。工程上的解法是引入Q滤波器把高频段的学习增益压下去。Q滤波器的系数设计成低通特性后收敛条件变成了|Q(e^{jωT}) * [1 - Γ * P(e^{jωT})]| 1高频段的 |Q| 远小于1就把整个表达式压进了单位圆内。这份源码里zero_phase_lp.py生成的滤波器用零相位设计避免了普通低通滤波器带来的相位畸变问题。代码中Q滤波器的截止频率是配置项默认值是采样频率的十分之一实际使用时需要根据对象的频响去调。3. 核心代码拆解一个迭代周期从数据采集到控制修正的完整链路3.1 学习律基类与P型实现一份能二次开发的ILC代码接口设计比算法细节更重要。看base_law.pyclass BaseLearningLaw(abc.ABC): def __init__(self, learning_gain, q_filter): self.learning_gain learning_gain self.q_filter q_filter abc.abstractmethod def update(self, u_prev, e_prev, u_current): 计算下一次运行的控制输入。 Args: u_prev: 上一次运行的控制输入轨迹形状为 (n_steps, n_inputs) e_prev: 上一次运行的误差轨迹形状为 (n_steps, n_outputs) u_current: 当前运行的基础控制输入通常是反馈控制器的输出 Returns: u_next: 下一次运行的控制输入轨迹 pass这里把输入输出都设计成完整轨迹而不是单步值——因为ILC是批处理式学习必须拿到一整次运行的数据才能更新。u_current这个参数容易被忽略它的存在是为了把当前反馈控制器的输出也融合进去。实际系统中ILC修正量与前馈通道并联基础控制通常由PID给出。P型的实现class PLaw(BaseLearningLaw): def update(self, u_prev, e_prev, u_current): # 误差乘学习增益再经过Q滤波器 correction self.learning_gain * e_prev correction_filtered self.q_filter.apply(correction) # 叠加到上一次控制输入上然后与当前基础控制折中 u_next self.q_filter.apply(u_prev) correction_filtered # 实际系统中会和u_current做加权融合 alpha 0.7 u_next alpha * u_next (1.0 - alpha) * u_current return u_next逻辑说明P型学习律的核心是把上一次的误差乘上增益直接作为修正量。这里有几个参数值得推敲。learning_gain的取值通常在0.1到0.9之间太小收敛慢太大会在高频段触发发散。alpha是当前基础控制输入的融合权重这个参数在纯仿真里往往设成1但实机调试时如果设成1容易被执行机构的饱和特性打乱节奏一般我会取0.6到0.8让PID继续承担一部分实时校正的职责。3.2 零相位Q滤波器的实现细节Q滤波器是整个ILC收敛的保险丝。普通低通滤波器会给信号带来群延迟在迭代轴上多绕一圈延迟就会被累积放大。零相位滤波器的做法是先正向滤波再反向滤波把相位偏移互相抵消。zero_phase_lp.py里的关键代码from scipy.signal import butter, filtfilt class ZeroPhaseLowPass: def __init__(self, cutoff_freq, order4, fs1000.0): nyquist 0.5 * fs normalized_cutoff cutoff_freq / nyquist self.b, self.a butter(order, normalized_cutoff, btypelow) def apply(self, signal_traj): # filtfilt 实现零相位正向滤波 反向滤波抵消相位延迟 if len(signal_traj) 15: return signal_traj # pad 处理边界效应 pad_len min(10, len(signal_traj) // 3) padded np.concatenate([ np.tile(signal_traj[0], pad_len), signal_traj, np.tile(signal_traj[-1], pad_len) ]) filtered filtfilt(self.b, self.a, padded, axis0) return filtered[pad_len:-pad_len]逻辑说明filtfilt是SciPy里的零相位滤波函数对同一段数据做正向和反向两次滤波相位畸变相互抵消得到的输出与原始信号之间没有系统性的相位偏移。这个性质对ILC极其关键如果Q滤波器引入相位滞后实际的收敛条件会被进一步恶化——你不再是压低高频正反馈而是在某个频段又引入了新的正反馈风险。参数说明cutoff_freq需要谨慎设置它直接决定了学习频带。取太高高频段的模型不确定性会被学习律放大取太低能学到的频带太窄误差收敛不下来。一个可供参考的起点是用被控对象带宽的1.5到2倍。order4从经验上讲足够陡峭再高容易在边界处出现振铃。状态空间法实现的话state在迭代之间要重置原因在于ILC假设每次运行从相同初始状态开始如果不重置滤波器带进去的残余状态会破坏学习律的严格重复性假设表现就是同一套参数有时收敛有时发散。3.3 仿真主循环与收敛监控simulation/runner.py是连接学习律和被控对象的桥梁也是整个代码库里最值得读的部分class IterativeRunner: def __init__(self, plant, law, q_filter, ref_trajectory, dt0.001): self.plant plant self.law law self.ref ref_trajectory self.dt dt def run(self, n_iter50, init_uNone): n_steps len(self.ref) u_prev np.zeros_like(self.ref) if init_u is None else init_u metrics_history [] for k in range(n_iter): # 第k次运行把u_prev作为前馈施加到对象上 y_curr self.plant.simulate(u_prev, self.ref, self.dt) e_curr self.ref - y_curr # 触发学习律更新生成下一次的控制输入 u_next self.law.update(u_prev, e_curr, u_curru_prev) # 记录本次运行的误差指标 rmse np.sqrt(np.mean(e_curr**2)) max_err np.max(np.abs(e_curr)) metrics_history.append({rmse: rmse, max_err: max_err}) print(fiter {k:3d} | RMSE: {rmse:.6f} | MAX: {max_err:.6f}) u_prev u_next # 迭代轴推进 return u_prev, metrics_history逻辑说明这个循环模拟的是ILC的完整生命周期。每次迭代先让被控对象在上一轮学到的控制输入下跑完一整条轨迹然后对比期望轨迹得到误差再通过学习律把误差转写成修正量叠加到控制输入上进入下一轮。u_prev充当迭代轴上的“记忆”——它是ILC与常规前馈控制最本质的区别所在。参数说明n_iter设50是折中值大多数线性系统在10到20次迭代内就能把RMSE压到初始值的十分之一以下50次足够看到完全收敛和可能出现的发散趋势。print输出里的RMSE曲线是一个重要的诊断信号——如果RMSE在前几轮下降、后面开始反弹通常是Q滤波器截止频率太高或学习增益偏大如果RMSE从头到尾纹丝不动大概率是学习增益太小或误差信号本身在噪声级以下。这段代码还暴露了一个需要警惕的简化plant.simulate(u_prev, self.ref, self.dt)中的self.ref是作为期望轨迹传入的这在正位置反馈型ILC中是合理做法但如果你改造系统加入模型前馈参考轨迹的角色就要重新界定。这个区分在实机调试时很容易翻车第5章会专门展开。4. 环境搭建与运行从拉取代码到跑出第一条收敛曲线4.1 环境依赖与安装这份代码的依赖收敛在常用科学计算栈内不需要额外的实时内核或专有硬件库。推荐用 conda 创建独立环境Python 版本要求3.9以上核心依赖是 NumPy、SciPy、Matplotlib、PyYAML。安装过程在项目根目录有一条命令pip install -r requirements.txtrequirements.txt 里锁定了版本范围而不是精确版本因为ILC仿真对SciPy的接口敏感程度不高只要大于1.8都能正常跑。如果你用的是 Apple Silicon 或 ARM 平台SciPy 的二进制轮子已经齐全不需要源码编译。工程上建议再装一个 jupyterlab迭代过程的RMSE曲线在Notebook里做交互式观察比纯命令行方便得多。4.2 跑通默认仿真的完整步骤拿到代码后最直接的上手路径是从 examples 目录下的示例脚本开始python examples/run_basic_sim.py这个脚本执行三件事加载默认配置文件、构造一个二阶线性被控对象、执行50次迭代学习并绘制收敛曲线。命令输出有两部分值得关注一是每轮迭代打印的RMSE与最大绝对误差二是运行结束后弹出的误差衰减图。正常情况下你会看到RMSE从初始的0.1级别在10轮左右降到0.01以下随后继续缓慢下降最终稳定在一个相对于噪声底的水平。对照config/default.yaml的默认参数plant: type: linear_second_order natural_frequency: 10.0 damping_ratio: 0.8 dc_gain: 1.0 learning_law: type: pd proportional_gain: 0.5 derivative_gain: 0.05 q_filter: cutoff_frequency: 25.0 order: 4 simulation: dt: 0.001 n_iter: 50 reference: step_sine参数说明自然频率10赫兹、阻尼比0.8的欠阻尼二阶系统是典型的ILC仿真对象它有明显的动态滞后但不会剧烈振荡。PD型学习律中derivative_gain设为0.05微分项的作用是感知误差的变化趋势让学习过程更快弥合动态滞后。Q滤波器截止频率25赫兹是被控对象带宽的2.5倍这个余量既保护了高频不散又不至于压掉有效学习频带。reference: step_sine是一个平滑的阶跃-正弦混合轨迹对ILC来说参考轨迹必须是重复的周期信号且最好具有有限带宽这样Q滤波器才有明确的“学习边界”。4.3 对比实验P型与PD型学习律的差异examples/run_compare.py脚本内置了一个对照组——同样的被控对象、同样的Q滤波器分别用P型和PD型学习律跑相同的轨迹最后输出两条RMSE曲线。这个实验能直观地看出微分项的价值python examples/run_compare.py --savefig compare_result.png实测结果通常呈现这样的趋势P型在头5轮收敛速度快但RMSE会在0.01附近卡住PD型初期略慢却在10轮后超过P型最终误差可以再低一个数量级。原因在于纯比例项相当于把一个固定增益的误差反馈叠加到输入轨迹上它只在误差幅值上做文章对相位滞后的补偿能力有限。微分项把误差的时间导数也纳入学习等于让学习律对“误差正在增大还是减小”做出反应能更有效地修正动态滞后的影响。4.4 自定义仿真实验改参考轨迹与被控对象仿真脚本通过配置文件驱动是这份代码设计得比较顺手的地方。新建一个my_experiment.yaml把被控对象换成带一个零点和一个延迟环节的三阶系统参考轨迹换成梯形加速度曲线plant: type: linear_third_order zero: [-5.0] poles: [-8.0, -3.0, -1.5] dead_time: 0.002 reference: type: trapezoid_accel max_velocity: 1.0 accel_time: 0.2然后与默认配置做对照测试这是验证ILC适用范围最直接的手段。带零点系统比二阶系统更容易激发学习律的高频敏感性——零点会放大高频噪声的幅值此时Q滤波器的截止频率不调低迭代发散几乎是必然的。项目的设计意图在这里能看得很清楚config/目录下留了experiment_1.yaml作为这种复杂对象的配置样例跑之前打开看看注释注意dead_time对应的相对阶次补偿是否被学习律正确处理了——这份代码在PD学习律里对纯延迟做了两步前移补偿这是它比许多教学版ILC实现更贴近实机使用的地方。5. 避坑记录ILC调试中的五个典型翻车现场5.1 迭代发散RMSE曲线先降后升现象前5轮误差正常下降第6轮开始RMSE反弹到第10轮直接涨到比初始误差还大两个数量级。控制输入轨迹上能看到明显的高频振荡。原因Q滤波器截止频率设定高于被控对象的高频未建模动态所在频段。学习律在高频区域计算出的修正量是依据不准确的模型信息叠加到控制输入上形成正反馈误差在迭代轴上被逐轮放大。这本质上是把仿真模型拍频响应上的高频尾巴当成了真实对象特性。解决流程先把截止频率降到对象带宽的1/2做对比试验如果RMSE不再发散但收敛速度明显变慢再逐步上调截止频率。调试时观察控制输入轨迹的高频成分比看RMSE曲线更早暴露问题——控制输入出现10赫兹以上的振铃说明Q滤波器已经在失效边界上工作了。5.2 初值漂移首轮误差为零却越学越偏现象首轮运行输出与参考轨迹几乎完全重合误差极小但迭代几次后误差反而增大。检查首轮的控制输入发现它与参考轨迹之间已经存在一个固定的初始偏移。原因ILC隐含的假设是每次运行从相同的初始状态出发。如果仿真对象包含积分环节或者实机系统每次启动时零点位置略有变化首轮的完美跟踪并不能代表学习律真正收敛。误差极小让学习律给出的修正量也几乎为零但系统初始状态和参考轨迹之间的差会在后续运行中逐步暴露出来。解决流程把仿真脚本里的对象初始状态显式设置成与参考轨迹起点不同强制制造初始偏差。观察学习律能否通过迭代把初始偏差消掉。如果不能说明相对阶次补偿有问题——你需要检查学习律中tΔ的偏移量是否与被控对象的最小相位零点个数匹配。5.3 微分项放大噪声PD型学习律在传感器噪声下学不动现象仿真中PD型成绩优异换到带噪声的模型或实机数据后误差下降缓慢甚至在某个迭代轮次后停滞不前。控制输入轨迹上叠加了一层高频毛刺。原因微分环节对噪声敏感是控制理论的常识但在ILC语境里问题被迭代行为放大了。上一轮的噪声被微分放大后写入了这一轮的控制输入这一轮系统跑出来的误差又混合了执行机构对高频输入的响应噪声下一轮再微分——噪声在迭代轴上不断累积。解决流程给误差求导之前先经过零相位低通滤波器或者直接改用D型学习律的变体——只在低频频段做微分补偿高频交给比例项负责。这份源码的PD实现里其实预留了derivative_filter_cutoff这个配置项默认值为None表示不对误差导数的求导做额外滤波建议工程使用时把它设为Q滤波器截止频率的2/3。5.4 参考轨迹突变阶跃指令导致学习律过冲现象参考轨迹中含有一个阶跃跳变点收敛后的误差在跳变点附近始终压不下去且控制输入在跳变点前后出现明显的预补偿冲量。原因ILC学习的是系统对轨迹的动态响应。阶跃点的频谱无限宽Q滤波器不管怎么设计都无法在学习频带内完全解决跟踪问题。学习律为了压低跳变点附近的误差会不断放大该时刻的控制输入最终演变成一个窄而高的冲量看起来像是预补偿过冲。解决流程参考轨迹在进入ILC之前先经过规划器平滑处理用梯形或S形速度曲线替代阶跃位置指令如果阶跃不可避免把误差权重改成时间依赖的形式——跳变点前后各10毫秒的误差不参与学习其余区段正常更新。这个技巧在很多批处理控制现场是标准操作实现上只需要在误差送入学习律前加一个mask向量。5.5 配置漂移与版本不一致换机器后复现不出结果现象同一份代码在自己的机器上收敛速度正常部署到另一台机器上首轮RMSE就差了三倍且迭代行为完全改变。原因filtfilt在SciPy不同版本中的边界处理方式有细微差别特别是对短信号序列的填充策略不一致。另一个常见来源是Matplotlib后端差异导致绘图进程阻塞、仿真的实时性被破坏——虽然纯离线仿真不受影响但如果脚本里加入了实时数据采集演示接口时间步失真会改变误差轨迹的采样密度。解决流程锁定开发环境版本requirements.txt 里的版本范围改成精确版本号针对短信号场景把zero_phase_lp.py里的边界填充逻辑改成长度为信号长度1/8的反射填充reflect模式对信号类型更鲁棒。我自己的习惯是在首次运行时打印一遍SciPy与NumPy版本再输出Q滤波器的实际频率响应曲线留下可复现的记录。这个习惯帮我在多次项目交接时省掉了大量扯皮的时间。6. 二次开发把这份代码改造成自己的迭代学习控制工具6.1 把学习律从P/PD扩展到高阶ILC这份代码的学习律接口是值得保留的BaseLearningLaw.update接收完整轨迹、返回完整轨迹的设计天然兼容高阶学习律。所谓高阶ILC是指第k1次的控制输入不再只由第k次运行决定而是取最近M次运行的加权组合。改造方式是在update签名里加入历史轨迹列表class HighOrderLaw(BaseLearningLaw): def __init__(self, weights, q_filter): self.weights weights # 长度M例如 [0.6, 0.3, 0.1] def update(self, history_u, history_e, u_current): # history_u 和 history_e 都是轨迹列表最新的在末尾 u_next np.zeros_like(history_u[-1]) for i, w in enumerate(self.weights): u_next w * self.q_filter.apply( history_u[-1-i] self.learning_gain * history_e[-1-i] ) return u_next改造思路高阶ILC的结果是收敛速度更快但对噪声更敏感权重序列的和必须严格等于1否则稳态时控制输入会有漂移。实机调试时我不建议M超过3更高阶的收益会被模型不确定性吃掉。6.2 接入实机数据通道从离线仿真到半实物验证仿真跑通后要接实机最顺手的路径是替换plant.simulate这一层。项目里的interface/目录已经给出了一个壳子——real_time_io.py里定义了发送控制输入、接收编码器反馈的抽象方法。你只需要把这两步接到实际硬件上然后把IterativeRunner.run里的plant.simulate换成“写硬件、等待一个运行周期、读反馈”的过程。有一个容易被忽略的细节仿真里常见的“同一时刻读到的误差立即用于下一次控制输入”在实机中不可行——执行机构有零阶保持器的延迟传感器有滤波延迟数据采集卡有传输延迟这些叠加起来等效于系统多了一截纯延迟。此时必须把学习律中的相对阶次补偿调大否则你会看到第5章里那种初始误差为零却越学越偏的诡异现象。另一个实机特有的点限幅。仿真里控制输入可以跑到任意大实机数据写进去会被驱动器限幅截断。ILC遇到限幅会打乱迭代轴的稳定——第k轮的过大修正量被截断第k1轮的误差从本质上并不携带第k轮的完整信息学习变得混乱。我的处理是让u_next在更新前经过一个限幅函数与执行机构的最大能力对齐。6.3 扩展输出指标从单维误差到学习过程可视化调试ILC时单看RMSE远远不够至少要看三条曲线控制输入轨迹判断是否出现振铃、误差轨迹观察残差集中在轨迹的哪一段、以及迭代轴上的收敛曲线判断发散趋势。这份代码里metrics.py只返回RMSE与最大误差你可以在 return 之前追加一个 save 调用把每次迭代的完整误差轨迹和控制输入轨迹存储为.npy文件。离线分析时用这些原始数据可以做频域分解——误差能量集中在哪个频段、对应的学习律增益是否足够都用数据说话。6.4 一个实际改造案例估计被控对象带宽并自动设置Q滤波器截止频率如果不想每次手动调Q滤波器的截止频率可以在仿真主循环前加一个自动识别环节给对象一个扫频激励从响应中估计出带宽频率然后按带宽的1.5倍自动设置Q滤波器。这已经是自适应ILC的雏形。实现方式def auto_configure_q_filter(plant, dt): # 扫频激励 freq_range np.logspace(0.1, 2.0, 30) responses [] for f in freq_range: u_test np.sin(2*np.pi*f*np.arange(0, 0.5, dt)) y_test plant.simulate(u_test, np.zeros_like(u_test), dt) responses.append(np.max(np.abs(y_test)) / np.max(np.abs(u_test))) # 找到增益降到直流增益0.7对应的频率 dc_gain responses[0] bandwidth freq_range[np.argmin(np.abs(np.array(responses) - 0.7*dc_gain))] return bandwidth * 1.5这段代码体现的核心思路是让配置跟随对象特性而非人工试凑。从那以后我每次搭ILC仿真都会强制走一遍这个自动配置流程先扫频认出对象带宽再决定Q滤波器的截止频率节省的调试时间相当可观。希望这分代码和这些经验能帮到你——ILC的关键不在于学得多快而在于知道什么时候该学、什么时候该停。本文还有配套的精品资源点击获取

相关新闻

nvidia-smi命令找不到?从驱动到容器彻底排查与修复指南

nvidia-smi命令找不到?从驱动到容器彻底排查与修复指南

“nvidia-smi: command not found”大概是 Linux 装显卡驱动时最经典、也最让人摸不着头脑的报错。我第一次遇到是在一台刚装完系统的服务器上,当时还以为是显卡坏了,折腾半天才发现只是驱动没装上。后来搞多了就明白,这个报错本身不复杂&…

2026/10/16 7:57:16 阅读更多 →
大模型上下文管理实战:Token预算、记忆分层与检索召回

大模型上下文管理实战:Token预算、记忆分层与检索召回

前几天我和一朋友调试他做的对话机器人,本来前期测试一切正常,结果聊到第 20 轮的时候,模型突然开始答非所问。他问了一句“我刚才不是说过了吗”,系统毫无反应。我打开日志看了一眼 Token 消耗,心里大概就有数了&…

2026/10/16 7:57:15 阅读更多 →
多模态Agent实战:Harness编排与MCP工具接入的工程架构解析

多模态Agent实战:Harness编排与MCP工具接入的工程架构解析

1. 多模态 Agent:从“能聊”到“能干”的跨越最近这半年,我几乎把所有业余时间都砸在了一个Agent开发项目上。说实话,市面上讨论Agent的声音很多,但真到了自己动手把一个大模型多模态应用和一个可编排的Harness框架、再加上MCP协议…

2026/10/16 7:57:15 阅读更多 →

最新新闻

51单片机波形发生器:查表法、DAC0808与Proteus仿真方案

51单片机波形发生器:查表法、DAC0808与Proteus仿真方案

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

2026/10/16 8:35:36 阅读更多 →
RAG技术详解:从原理到最小实现,避开常见坑

RAG技术详解:从原理到最小实现,避开常见坑

RAG这几年在LLM圈子里火得发烫,几乎每场技术讨论都绕不开它。但要真问一句"RAG到底是什么、上手做一版要几步、哪些环节最容易翻车",能讲透的人其实不多。很多人把它当成一个名词贴在文档里,产品评审时说"我们要用RAG解决幻觉…

2026/10/16 8:35:36 阅读更多 →
现场总线技术解析:主流协议、工程难点与智能设备演进

现场总线技术解析:主流协议、工程难点与智能设备演进

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

2026/10/16 8:35:36 阅读更多 →
信息资源管理导论备考攻略:核心框架、高频考点与答题策略

信息资源管理导论备考攻略:核心框架、高频考点与答题策略

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

2026/10/16 8:35:36 阅读更多 →
Python实现WM多模式匹配算法:从原理到优化实战

Python实现WM多模式匹配算法:从原理到优化实战

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

2026/10/16 8:35:36 阅读更多 →
Zephyr速通指南:从零搭建开发环境到点亮开发板

Zephyr速通指南:从零搭建开发环境到点亮开发板

1. 为什么折腾三天没跑通的官方流程,我决定换个姿势如果你点进这篇笔记,大概率是和我一样的人:拿到一块开发板,看完“读文档-装工具-跑Hello World”的步骤,想着半小时总该能点灯了吧,结果卡在了莫名其妙的…

2026/10/16 8:34:34 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/15 9:49:14 阅读更多 →