
关键词:AI 测试|确定性模拟|LLM Mock|模糊测试|回归防护|工具调用验证
AI 系统的测试常被视为“不可能任务”:
若直接对真实 LLM + 真实环境进行端到端测试,结果将不可重复、难以调试、无法 CI/CD 集成。
OpenClaw 的应对策略是:分层测试 + 智能模拟 + 行为断言。通过将系统拆解为“确定性组件”与“非确定性接口”,在保证覆盖度的同时实现95%+ 的自动化测试率。
本文将详解其四大核心测试策略:
OpenClaw 的架构设计本身就为测试友好:
llm.tsexec.ts / process.tsmemory-search.ts测试时,这些模块均可被模拟(Mock)或桩替换(Stub),使核心逻辑变为纯函数。
测试目标不是 LLM,而是“我们如何使用 LLM”。
真实 LLM(如 GPT-4)输出受 temperature、top_p 等参数影响,即使相同 prompt 也可能返回不同 tool_call。
MockLLM 类// test/mocks/mock-llm.ts
class MockLLM {
private responses: Map<string, LLMResponse> = new Map();
// 根据 prompt 哈希返回预设响应
async complete(prompt: string): Promise<LLMResponse> {
const hash = md5(prompt);
const resp = this.responses.get(hash);
if (!resp) throw new Error(`No mock for prompt hash ${hash}`);
return resp;
}
// 注册预期行为
addMock(prompt: string, response: LLMResponse) {
this.responses.set(md5(prompt), response);
}
}test('should call bash_exec when user asks to restart service', async () => {
const llm = new MockLLM();
llm.addMock(
expect.stringContaining('restart the database'),
{
toolCalls: [{
name: 'bash_exec',
args: { cmd: 'kubectl rollout restart deployment/db' }
}]
}
);
const agent = new Agent({ llm });
const result = await agent.handleMessage('重启数据库');
expect(result.toolCalls[0].name).toBe('bash_exec');
expect(result.toolCalls[0].args.cmd).toContain('rollout restart');
});测试的是“意图→工具”的映射,而非 LLM 本身。
每个工具(无论是 SKILL.md 还是内置工具)都需满足输入/输出契约。
# skills/deploy_app.SKILL.md
## 参数契约
- branch (string): Git 分支名,必须匹配 /^[a-z0-9\-_]+$/
- env (string): 环境名,枚举值 ["staging", "prod"]
## 输出契约
成功时返回 JSON:
{
"status": "success",
"url": "https://app-staging.example.com"
}
失败时抛出错误OpenClaw 提供 skill-test-gen 工具:
npx openclaw skill-test-gen skills/deploy_app.SKILL.md生成:
// test/skills/deploy_app.test.ts
test('rejects invalid branch name', async () => {
await expect(
runSkill('deploy_app', { branch: 'feature/NEW!', env: 'staging' })
).rejects.toThrow('Invalid branch');
});
test('returns deployment URL on success', async () => {
const result = await runSkill('deploy_app', { branch: 'main', env: 'staging' });
expect(result.url).toMatch(/^https:\/\/app-staging/);
});文档即测试规范。
AI 系统常因奇怪输入崩溃:
OpenClaw 使用 fast-check 库进行属性测试:
import * as fc from 'fast-check';
test('agent should not crash on arbitrary input', () => {
fc.assert(
fc.property(
fc.string({ maxLength: 10000 }), // 任意字符串
async (input) => {
const agent = createTestAgent();
// 不应抛出未捕获异常
await expect(agent.handleMessage(input)).resolves.not.toThrow();
}
)
);
});
让系统在混乱中保持秩序。
当修改提示词(prompt)或技能逻辑时,可能无意中破坏已有行为。
OpenClaw 使用 对话快照测试(Conversation Snapshot Test):
test('customer refund flow', async () => {
const session = new TestSession();
await session.send('订单 ORD-123 商品破损,请退款');
await session.approveToolCall(); // 自动批准
await session.waitForIdle();
// 保存最终对话历史
expect(session.getMessages()).toMatchSnapshot();
});首次运行生成 __snapshots__/refund.test.ts.snap:
exports[`customer refund flow 1`] = `
Array [
{ role: "user", content: "订单 ORD-123 商品破损,请退款" },
{ role: "assistant", tool_calls: [...] },
{ role: "tool", content: "{\\"status\\":\\"success\\"}" },
{ role: "assistant", content: "退款已提交..." }
]
`;后续运行若输出变化,测试失败并提示 diff。
防止“修复一个 bug,引入三个新问题”。
对于关键路径(如“用户提问 → 工具审批 → 结果返回”),OpenClaw 运行受限端到端测试:
describe('E2E: Approved Tool Execution', () => {
let gateway: FakeGateway;
let agent: Agent;
beforeAll(async () => {
gateway = new FakeGateway();
agent = new Agent({
llm: new DeterministicLLM(),
gateway
});
});
test('waits for user approval then executes', async () => {
const promise = agent.handleMessage('重启服务');
// 模拟用户 2 秒后批准
setTimeout(() => gateway.approveLastRequest(), 2000);
const result = await promise;
expect(result.content).toContain('服务已重启');
});
});端到端,但不依赖外部服务。
OpenClaw 的 GitHub Actions 工作流包含:
任何测试失败,PR 无法合并。
# .github/workflows/test.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
- run: npm run test:fuzz
- run: npm run test:e2e质量门禁,从不妥协。

核心安全模块接近完全覆盖。
测试 AI 系统并非追求“预测 LLM 输出”,而是确保我们的系统在任何 LLM 行为下都能安全、正确地响应。OpenClaw 通过分层模拟、契约验证与回归防护,在混沌中构建了一座可靠的工程堡垒。
这不仅是技术实践,更是对用户负责的承诺——你交付的每一行代码,都经得起机器与时间的双重检验。
在下一篇中,我们将展望未来:OpenClaw 的多模态扩展与自主智能体演进路线。
下一篇预告: 第 17 篇:未来之路 —— 多模态、自主智能体与 OpenClaw 的演进愿景