控制论12 分钟阅读5 天内
11李雅普诺夫稳定性 · Lyapunov Stability
控制论 · 用于 Agent 流水线鲁棒性设计
11
李雅普诺夫稳定性 · Lyapunov Stability
控制论 · 用于 Agent 流水线鲁棒性设计
核心概念
李雅普诺夫稳定:系统从任意接近均衡点的初始状态出发,
都能保持在均衡点附近(不发散)。
渐近稳定:不仅不发散,还能最终收敛回均衡点。
不稳定:微小扰动会导致系统状态无界发散。
直觉:弹簧振子 = 李雅普诺夫稳定
倒立摆(未控制)= 不稳定
自动纠偏的倒立摆 = 渐近稳定
关键直觉:不要只针对"正常输入"测试你的 agent,要针对"边界扰动"测试。真正的鲁棒性 = 遇到扰动后能回到正轨,而不是一路偏离。
Agent 流水线的稳定性问题
典型失稳场景
你的摘要 agent 在正常输入下输出很好。但当输入文章包含大量代码块时,它开始输出格式混乱的内容;当输入是非常短的文本时,它又开始过度发挥"编造"内容。这是一个不稳定的系统——小扰动(非典型输入)导致系统发散到你不想要的状态。
| 系统行为 | 稳定性类型 | 对应动作 |
|---|---|---|
| 异常输入 → 仍然输出合理结果 | 李雅普诺夫稳定 | 继续,可以上线 |
| 异常输入 → 短暂偏离后自动回正 | 渐近稳定 | 最佳状态,继续 |
| 异常输入 → 输出越来越奇怪 | 不稳定 | 加边界检查,截断异常路径 |
| 正常输入偶尔触发完全错误的路径 | 临界稳定 | 找到触发条件,加断路器 |
代码模式 — 稳定性测试框架
stability-test.ts
Agent 鲁棒性测试
// 李雅普诺夫稳定性测试:用"扰动"检验系统是否发散 interface StabilityTest { name: string baseInput: string // 正常输入(均衡点附近) perturbations: string[] // 各种扰动 isStable: (output: string) => boolean // 是否仍在可接受范围 } const summaryAgentStabilityTests: StabilityTest[] = [ { name: '短文本扰动', baseInput: '一篇正常长度的技术文章...', perturbations: [ 'ok', '.', '', ], isStable: (output) => output.length < 200 && !output.includes('根据文章'), }, { name: '代码块扰动', baseInput: '普通文章', perturbations: [ '```python\n' + 'x = 1\n'.repeat(200) + '```', // 超长代码块 ], isStable: (output) => !output.includes('```'), // 摘要不应包含代码块 }, ] async function testStability(agent: Agent, tests: StabilityTest[]) { const results = [] for (const test of tests) { for (const perturbation of test.perturbations) { const output = await agent.run(perturbation) const stable = test.isStable(output) results.push({ test: test.name, perturbation: perturbation.slice(0, 30), stable, output: output.slice(0, 100), }) if (!stable) { console.warn(`⚠ 不稳定:${test.name} | 扰动:${perturbation.slice(0, 30)}`) } } } const unstableCount = results.filter(r => !r.stable).length console.log(`稳定性评分:${((1 - unstableCount / results.length) * 100).toFixed(0)}%`) return results }
⚠ 反模式
只用"正常用例"测试 agent 性能,然后在生产环境遇到边界输入时崩溃。真实用户输入的分布远比你预期的宽——空字符串、超长文本、特殊字符、非目标语言,都会出现。
✓ 实践原则
为每个 agent 定义"稳定域":什么样的输入范围是可接受的,超出范围后系统应该怎么降级(拒绝处理 / 返回默认值 / 触发人工审核),而不是静默地输出错误结果。
四种常见扰动类型
- 长度扰动:空字符串、超长输入(>10倍正常长度)
- 格式扰动:全是代码、全是数字、全是特殊字符
- 语言扰动:非目标语言输入(日文、阿拉伯文等)
- 语义扰动:与任务完全无关的内容、对抗性输入
拿走就能用 — 粘贴进你的 CLAUDE.md
CLAUDE.md
Agent 鲁棒性规则
## Agent 鲁棒性规则(李雅普诺夫原则)
### 必须处理的边界输入
- 空输入:返回明确错误,不要静默失败
- 超长输入(>预期 5 倍):截断 + 告知,不要崩溃
- 非预期语言:检测后明确告知,不要乱猜
### 稳定域定义
- 每个 agent 的 system prompt 开头必须声明"本 agent 处理什么类型的输入"
- 超出稳定域的输入应触发 fallback,不是随机输出
### 发散预防
- 不允许 agent 在单次对话中无限追加内容(设置最大 token 限制)
- 不允许 agent 自我引用上一轮输出作为新的输入(防止雪球效应)