LobeHub Agent Chaos 实验管理:Fixture 契约、安全护栏与故障注入机制
LobeHub 将混沌工程(Chaos Engineering)应用到 Agent 系统的可靠性验证中:应用专属的故障实验 Fixture 统一存放于 .agents/chaos/ 目录,由 @achaos/* 混沌基础设施包负责解析与执行。本文基于该目录的官方说明,结合 Fixture Schema 定义、Runner 执行引擎 与三个真实 Fixture 示例,完整讲解混沌实验契约的每个字段、安全策略的生产级护栏,以及"概率性故障发现 → 确定性回归 Fixture"的沉淀流程,帮助读者理解如何在 Agent 编排系统中安全地注入并验证故障。
.agents/chaos 目录:应用专属实验 Fixture 的存放地
.agents/chaos/README.md 给出了该目录的核心约定:所有应用专属的实验 Fixture 都存放在这里(Application-specific experiment fixtures live here),每个 Fixture 必须满足一组强制性声明要求:
| 强制项 | 含义 |
|---|---|
| 环境允许清单(environment allowlist) | Fixture 只能在声明的环境中运行,如 test、ci |
| 确定性种子(deterministic seed) | 用固定 seed 驱动可复现的伪随机序列 |
| 有界超时(bounded timeout) | timeoutMs 必须为正整数,保证实验不会无限挂起 |
| 目标适配器(target adapter) | 声明故障注入通过哪个适配器、命中哪个选择器 |
| 故障效应(effect) | 声明注入什么类型的故障(抛错、延迟、重复等) |
| 至少一个独立 Oracle | 独立于被测系统自身的判定器,用于评估实验结果 |
同时该文档划定了生产环境的边界:生产环境要求外部审批策略(external approval policy),且可移植 Runner(portable runner)不会默认启用生产注入。这与 Runner 源码 中的设计一致:RunChaosExperimentOptions 提供了 approveProduction 回调与 environmentTier 主机分类字段,且注释明确"未知环境名默认按生产安全策略处理"(Unknown environment names default to production-safe handling)。
从源码结构看,Runner 在执行前会先用 chaosExperimentSchema.safeParse 对实验做严格校验(run.ts#L98-L115),任何不满足契约的 Fixture 会被标记为 ChaosConfigError 并直接以 aborted 状态终止——这就是"每个 Fixture 必须声明上述字段"在工程上的强制执行点。
Fixture 契约全解:字段、取值范围与默认值
Schema 定义 使用 zod 的 .strict() 构建,即不允许出现任何未声明的字段。以下是完整契约:
| 字段 | 类型与约束 | 说明 |
|---|---|---|
id |
字符串,匹配 ^[a-z0-9]+(?:-[a-z0-9]+)*$ |
小写 kebab-case 实验标识,如 tool-failure |
description |
非空字符串 | 实验的一句话描述 |
layer |
枚举 L0-infra / L1-model-runtime / L2-agent-runtime / L3-orchestration / L4-business-logic / L5-human-trust |
故障注入所属的抽象层级 |
discoveredFrom |
可选字符串 | 实验来源(事故、评估发现或显式假设),详见下文"来源沉淀" |
seed |
非空字符串 | 确定性随机种子,Runner 用它初始化 createSeededRandom(run.ts#L120) |
timeoutMs |
正整数 | 整个实验的有界超时 |
cleanup |
枚举 always / on_success / never,默认 always |
清理策略,保证注入不残留 |
safety |
对象,必含非空 allowedEnvironments;可选 destructive 布尔、maxInjections 正整数 |
安全策略 |
target |
对象:adapter(非空字符串)+ selector(记录) |
故障目标定位 |
trigger |
对象:when 枚举 immediate / before / after,可选 probability(0–1) |
注入时机与概率 |
effect |
判别联合,见下表 | 故障效应本体 |
oracles |
至少 1 个元素;每项含 name、可选 params 与 timeoutMs |
独立判定器规格 |
tags |
可选字符串数组 | 分组标签 |
六种故障效应(effect)
effect 契约 是一个以 type 为判别键的 strict 联合类型:
delay:需durationMs(非负整数),注入延迟;duplicate:需count(最小 2,即重复至少两次),用于验证消费端幂等性;drop:无参数,直接丢弃(如工具调用、完成消息);throw:需非空errorType,可选message,模拟提供商风格的类型化错误;replace_result:需content字符串,替换执行结果(如返回不完整或矛盾的验收证据);kill_process:可选signal: 'SIGKILL',进程级破坏性注入。
在 Agent Runtime 钩子 中可以看到效应如何落到真实调用链上:executeToolAttemptWithChaos 包裹每次 executeToolWithRetry 尝试,命中 delay 时挂起、命中 drop 时返回 ChaosDroppedToolCall(kind: 'retry',让真实重试策略接管)、命中 throw 时返回带指定 errorType 的失败尝试——故障被设计为"可重试的类型化失败"而非进程崩溃,从而真正演练系统的重试与降级逻辑。
三个真实 Fixture:分层注入示例
.agents/chaos/fixtures/ 下按层级目录组织,现存三个代表性 Fixture,恰好覆盖 L1/L2/L3 三层:
L1 模型运行时:工具故障与重试
tool-failure.yaml 让选定的 search 工具在 tool_attempt 阶段确定性收到一次 RateLimited 风格故障:
id: tool-failure
layer: L1-model-runtime
seed: tool-failure-v1
timeoutMs: 5000
cleanup: always
safety:
allowedEnvironments: [test, ci] # 环境允许清单
maxInjections: 1 # 单次运行最多注入 1 次
target:
adapter: runtime
selector:
apiName: search
phase: tool_attempt
trigger:
when: before
probability: 1 # 确定性触发(概率固定为 1)
effect:
type: throw
errorType: RateLimited
oracles:
- name: tool-failure-observed
timeoutMs: 1000
注意 probability: 1 与 seed 的组合:Fixture 虽允许概率触发(probability 取值 0–1),但沉淀下来的回归 Fixture 通过固定种子和概率 1 保证每次运行行为一致。
L2 Agent 运行时:过期操作回收
operation-reclaim.yaml 针对"运行中的操作租约(lease)过期后,旧尝试不能被复活、必须由替换尝试接管"的不变量,通过 state 适配器对 operationStatus: running 的状态做 delay(300 秒)注入,Oracle operation-reclaimed 在 5 秒窗口内验证回收发生。
L3 编排层:完成消息重复投递
duplicate-completion.yaml 用 duplicate 效应(count: 2)把同一完成消息投递两次,Oracle completion-idempotent 验证消费端幂等。
这三个示例与 [Fixture 契约] 的强制项一一对应:各自声明了 allowedEnvironments: [test, ci]、maxInjections: 1、确定性 seed、有界 timeoutMs、target 适配器与至少一个 Oracle。
安全护栏:环境允许清单与生产审批
安全边界在三层实现:
- Fixture 声明层:
safety.allowedEnvironments必填且非空;maxInjections限制单次运行的注入次数;破坏性效应可通过destructive: true显式标注。 - Runner 执行层:runChaosExperiment 接收
environment实际环境名并比对允许清单;生产环境注入必须经过approveProduction审批回调。Runner 源码中environmentTier注释表明未知环境名按生产安全策略兜底——即"默认拒绝"原则。 - 组织流程层:.agents/chaos/README.md 明确"生产环境要求外部审批策略,且不被可移植 Runner 启用",即审批是仓库外的独立策略,而非 Runner 内建开关。
配套的 cleanup 策略(默认 always)与 适配器契约 进一步保证注入可回滚:ChaosAdapter 可选实现 cancelInjection 与 cleanup,保证未完成的注入不会在超时后"迟到生效"。
故障来源(Provenance)与"概率发现 → 确定性 Fixture"生命周期
.agents/chaos/README.md 的后半段定义了 Fixture 的来源与沉淀规则,这是混沌体系从"一次性实验"变成"回归资产"的关键:
- 来源(provenance) 有三类:事故(通过
discoveredFrom字段追溯)、评估发现(evaluation finding)、或显式假设。对照真实 Fixture 可见:tool-failure 标注discoveredFrom: first-phase reference scenario(显式假设),而 operation-reclaim 标注discoveredFrom: Goal runtime resilience canary incident(事故沉淀)。 - 沉淀规则:"一旦概率性运行发现故障,必须保留其种子(seed),并将其归约(reduce)为稳定 Fixture"。即:概率触发用于发现,确定性 Fixture 用于回归——这与 Goal 集成文档 末尾的表述一致:"A discovered probabilistic failure becomes a reduced deterministic fixture before it is accepted as regression coverage",且每个 campaign 必须保留种子、结果 JSON、trace id、基线修订与候选修订。
执行管线:从 Fixture 加载到 Oracle 裁决
Runner 包 提供 loadChaosExperiments(校验式加载)、ChaosRegistry(适配器/Oracle 注册表)与 runChaosExperiment(确定性生命周期执行)。结合 Runner 实现 与 核心类型,一次实验运行遵循固定时间线:
run_started → steady_state_checked → fault_injected → system_exercised → oracle_evaluated → cleanup_started → cleanup_completed → run_completed
每个阶段受 timeoutMs 约束(内部通过 Promise.race + AbortController 强制超时并中止,见 run.ts#L41-L65)。最终产出 ChaosRunResult(状态为 passed / failed / inconclusive / aborted),其中包含完整 timeline、Oracle 结果、注入回执(injection receipt,含 injectionId、adapter、details)与种子。Reporter 提供 writeChaosResult / formatChaosResult 将其落盘或格式化,供后续作为验收证据(Acceptance evidence)引用。
随机性由 createSeededRandom 基于 experiment.seed 生成并注入 ChaosRunContext.random,这是"同一 Fixture 多次运行可复现"的实现基础。
应用侧集成边界:机制与业务模型分离
packages/achaos/README.md 划定了清晰的分层原则:包代码只包含机制,不包含 LobeHub 业务模型(package code contains mechanisms, not LobeHub business models);应用事故与 Fixture 归属 .agents/chaos。@achaos/* 命名空间包含:
@achaos/core— 实验、效应、安全、Oracle、回执与结果的可移植契约;@achaos/runner— 校验式 Fixture 加载与确定性生命周期执行;@achaos/runtime— Agent Runtime 钩子与完成投递适配器(即上文executeToolAttemptWithChaos所在处);@achaos/database— 与 schema 无关的变更与回滚端口;@achaos/process— 带所有权校验的破坏性进程注入;@achaos/testing— 确定性测试目标与场景辅助。
这一边界由 Goal 集成规范 反向确认:Goal 通过应用自有适配器消费 Agent Chaos,@achaos/* 不得反向导入 Goal、Task、Drizzle schema、QStash 或服务器服务。具体集成代码放在 apps/server/src/services/goal/__chaos__/,测试装配流程为:在 getTestDB() 中构造真实 Goal Graph / Work Task / Topic / Agent Operation → 注册 createRuntimeChaosHooks(controller) 做 preflight 结果替换/丢弃故障 → 注册 @achaos/database 端口做作用域化 lease/state 变更 → 用生产动作(如 GoalService.tick)驱动实验 → 用应用自有 Oracle 评估持久化状态,绝不把构建器 Agent 的文本输出当作证明 → 将 ChaosRunResult JSON 与 trace 事件附到 Acceptance evidence。
分层与 CI 梯队
layer 字段对应的 L0–L5 六层模型(ChaosLayer 类型)把故障定位到从基础设施到人类信任的抽象高度,而 goal-integration.md 定义了与之配套的 CI 梯队:
- PR 级:确定性进程内 + PGlite/Postgres campaign;不做真实进程杀死或网络故障;
- Nightly 级:服务器重启、QStash 重复/乱序、异构 Agent 与真实子进程 kill;
- Canary 级:允许清单内的非破坏性实验,配 kill switch 与严格爆炸半径;
- Production 级:在独立审批策略存在之前,仅做观测与 trace 采集。
小结
LobeHub 的 Agent Chaos 体系可以概括为三条设计主线:
- 契约先行:Fixture 是 strict schema 校验的 YAML 声明,环境清单、种子、超时、适配器、效应、Oracle 六项强制声明缺一不可,生产注入被 Runner 默认拒绝并要求外部审批;
- 机制与业务分离:
@achaos/*只提供可移植的注入/判定机制,应用事故知识全部沉淀在.agents/chaos的 Fixture 与集成规范中; - 概率发现、确定性回归:
discoveredFrom+seed构成故障溯源链,概率性发现必须归约为固定种子的稳定 Fixture 才能进入回归覆盖,且每个 campaign 需保留种子、结果 JSON、trace id 与代码修订基线。
这套机制让"Agent 在故障下是否保持安全(safety)、存活(liveness)、一致(consistency)"从口头承诺变成了可执行、可复现、可审计的持续验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00