OpenClaw Coding Agent Harness 编程Agent线束开发
jcode本周拿下2900+Stars。一个用Rust写的Coding Agent Harness——本质上就是给AI编程Agent系上安全带的方向盘。
Harness这个词很妙。不是"框架",是"线束"——像赛车的安全线束,把AI的能力约束在安全范围内,同时让它能在赛道上全力奔跑。
什么是Agent Harness
Agent Harness是介于LLM和操作系统之间的安全层:
- 工具注册:决定Agent能用哪些工具
- 权限控制:细粒度的读写执行权限
- 沙箱隔离:Agent操作限定在安全区域内
- 审批流程:危险操作需要人工确认
- 审计日志:所有操作可追溯
OpenClaw ACP Harness架构
// Harness核心配置
const harness = {
id: "my-coding-harness",
// 允许的Agent ID列表
allowedAgents: [
"claude-code",
"cursor",
"codex"
],
// 默认Agent
defaultAgent: "claude-code",
// 工具策略
toolPolicy: {
mode: "allowlist", // 或 "denylist"
allowed: [
"read", // 读取文件
"write", // 写入文件
"edit", // 编辑文件
"exec", // 执行命令
"browser", // 浏览器操作
"web_fetch", // 网页获取
"search" // 代码搜索
],
denied: [
"exec:rm -rf",
"exec:sudo",
"write:/etc/*",
"write:/usr/*"
]
},
// 沙箱配置
sandbox: {
enabled: true,
rootPath: "/workspace/project",
networkAccess: "restricted", // 允许HTTP/HTTPS,禁止其他
maxDiskUsage: "500MB",
maxMemory: "2GB",
maxCpuTime: "300s"
},
// 审批流程
approval: {
mode: "auto_safe", // 安全操作自动,危险操作需审批
autoApprove: [
"read:*",
"exec:git *",
"exec:npm test",
"exec:npm run lint"
],
requireApproval: [
"write:*",
"exec:npm publish",
"exec:git push"
]
}
};
构建自定义Harness
Step 1: 定义工具集
// tools/coding-tools.ts
export const codingTools = {
// 文件操作工具
read: {
name: "read",
description: "Read file contents",
parameters: {
path: { type: "string", required: true },
offset: { type: "number" },
limit: { type: "number" }
},
security: {
maxFileSize: "1MB",
allowedPaths: ["/workspace/**"]
},
audit: true // 记录审计日志
},
// 代码编辑工具
edit: {
name: "edit",
description: "Edit file with diff-based changes",
parameters: {
path: { type: "string", required: true },
edits: {
type: "array",
items: {
oldText: { type: "string", required: true },
newText: { type: "string", required: true }
}
}
},
security: {
maxEditsPerCall: 10,
requireDiffReview: true
},
audit: true
},
// 命令执行工具
exec: {
name: "exec",
description: "Execute shell commands",
parameters: {
command: { type: "string", required: true },
workdir: { type: "string" },
timeout: { type: "number", default: 30 }
},
security: {
deniedCommands: ["rm -rf /", "sudo", "chmod 777"],
allowedCommands: ["git", "npm", "node", "cargo", "go"],
maxOutputLength: "50KB"
},
approval: {
mode: "conditional",
autoIf: "command matches /^git (status|log|diff|branch)/",
requireIf: "command matches /push|publish|deploy/"
}
},
// 代码搜索工具
search: {
name: "grep",
description: "Search code with regex patterns",
parameters: {
pattern: { type: "string", required: true },
path: { type: "string" },
fileType: { type: "string" }
},
security: {
maxResults: 100
}
}
};
Step 2: 权限矩阵
// 权限矩阵:不同角色不同权限
const permissionMatrix = {
junior_developer: {
read: ["src/**", "test/**", "package.json"],
edit: ["src/**", "test/**"],
exec: ["npm test", "npm run lint", "npm run build"],
deny: ["npm publish", "git push"]
},
senior_developer: {
read: ["**"],
edit: ["**"],
exec: ["**"],
deny: ["sudo", "rm -rf"]
},
reviewer: {
read: ["**"],
edit: [],
exec: ["npm test", "npm run lint"],
deny: ["npm publish", "git push", "git commit"]
}
};
// 运行时切换角色
harness.setRole("junior_developer");
Step 3: 安全沙箱
const sandbox = {
// 文件系统隔离
filesystem: {
root: "/workspace/project",
readonlyPaths: [
"/workspace/project/package.json",
"/workspace/project/tsconfig.json"
],
forbiddenPaths: [
"~/.ssh/*",
"~/.aws/*",
"/etc/*"
],
quota: {
maxFiles: 10000,
maxSize: "500MB"
}
},
// 网络隔离
network: {
allowedHosts: [
"registry.npmjs.org",
"api.github.com",
"api.openai.com",
"*.miaoquai.com"
],
deniedHosts: [
"evil.com",
"*.internal.local"
],
maxRequestsPerMinute: 60
},
// 资源限制
resources: {
maxCpuPercent: 80,
maxMemoryMB: 2048,
maxDiskWriteMB: 500,
maxExecutionTimeSeconds: 300
}
};
审计与监控
// 审计日志配置
const audit = {
enabled: true,
logLevel: "detailed",
// 记录内容
record: {
toolCalls: true,
fileChanges: true,
commandExecution: true,
networkRequests: true,
approvalDecisions: true
},
// 输出格式
format: {
type: "jsonl", // JSON Lines
fields: [
"timestamp",
"agent_id",
"tool_name",
"parameters",
"result",
"duration_ms",
"tokens_used"
]
},
// 实时监控
monitoring: {
webhooks: ["https://hooks.miaoquai.com/audit"],
alertOn: [
"denied_tool_call",
"exceeded_quota",
"suspicious_pattern"
]
}
};
审批流程设计
// 多级审批流程
const approvalFlow = {
// Level 1: 自动审批(低风险)
auto: {
conditions: [
"tool === 'read'",
"tool === 'exec' && command matches /^npm (test|lint|build)/",
"tool === 'exec' && command matches /^git (status|log|diff)/"
]
},
// Level 2: AI审批(中风险)
ai_review: {
conditions: [
"tool === 'edit' && fileCount <= 3",
"tool === 'exec' && !matches(denied_patterns)"
],
reviewer: "claude-3-haiku", // 用便宜模型做审批
criteria: [
"是否超出工作区范围",
"是否有破坏性操作",
"是否符合代码规范"
]
},
// Level 3: 人工审批(高风险)
human_review: {
conditions: [
"tool === 'edit' && fileCount > 5",
"tool === 'exec' && matches(dangerous_patterns)",
"cost_estimate > $1"
],
timeout: "30min", // 30分钟未审批则拒绝
channels: ["feishu", "email"]
}
};
最佳实践
安全第一
- 默认拒绝所有操作,显式允许需要的
- 生产环境禁止写入系统目录
- 敏感操作必须有人工审批
- 保留完整的审计日志
性能优化
- 缓存频繁读取的文件
- 并行执行独立的编辑操作
- 增量搜索,避免全量扫描
- 设置合理的超时时间
常见问题
Q: Harness和Skill有什么区别?
Skill是Agent的能力扩展(工具包),Harness是安全约束层。Skill决定"Agent能做什么",Harness决定"Agent被允许做什么"。
Q: 如何测试Harness的安全性?
编写对抗性测试:尝试让Agent执行被禁止的操作,验证是否正确拦截。建议定期进行安全审计。