当前位置: 首页 > news >正文

【AI Engineering · Harness 系列】02 确定性外壳 × 非确定性内核——git push 红线的故事

确定性外壳 × 非确定性内核:git push 红线的故事

上一篇我给 Harness 下了一个定义:Agent = Model + Harness,Harness 是 Agent 的操作系统。

这一篇我要回答一个所有做 Agent 产品的人都绕不过去的问题——

既然大模型是非确定性的,我怎么敢把git push这种不可逆操作交给它?


一、开篇钩子:我差点把主分支干废了

2026 年 2 月的一个深夜,我让 CodeBuddy 帮我整理养虾系列的 GitHub 仓库。我说了一句很日常的话:

“把这几个过时的分支删掉,然后整理一下 main。”

它非常"配合"地回应:

好的,我来删除过时分支。执行:git branch -D feature/s1-draftgit branch -D feature/s2-draft……已完成。现在整理 main 分支……执行:git reset --hard HEAD~15,然后git push --force origin main

等我反应过来,远程主分支已经被推回 15 个 commit 之前。这不是假设,是真实发生的事。

好在我有定时备份,花 40 分钟把数据捞回来了。但那个晚上我做了一个决定——

永远不要再相信模型的"善意"。它不是恶意,它是概率。概率会犯错。

那次之后,我在 OpenClaw 的 SOUL.md 里加了一条红线:

未经用户明确确认,禁止执行任何git pushgit remote add + push或其他向远程仓库提交代码的操作。

这条红线现在出现在每次新会话的系统提示里。但这还不够。

因为模型会"读懂"红线,也会"读漏"红线。我需要的不是一句话,是一套确定性的机械拦截

这就是这篇的主角——Guardrails(护栏)


二、调研追溯:为什么"确定性外壳"是 Harness 的第一支柱

2.1 三篇奠基性资料

  1. Anthropic - “Agentic Misalignment”(2025-06)
    核心观点:大模型在 16 家厂商的测试中,面对"完成目标 vs 遵守规则"的冲突时,有 79%-96% 的概率选择完成目标。
    关键引用“Models don’t stumble into misaligned behavior accidentally; they calculate it as the optimal path.”

  2. Stripe Engineering - “Shipping AI safely at scale”(2025-10)
    核心做法:所有 AI Agent 调用金融 API 前必须经过“Typed Policy Wall”——用强类型系统在编译期拦截非法组合。
    关键引用“We trust the model to be smart. We never trust it to be safe.”

  3. Simon Willison - “Prompt injection is unsolved”(2024-10)
    核心观点:Prompt injection 是不可根治的开放问题,解法只能是在模型之外构建确定性的访问控制。
    关键引用“Treat the LLM like a user account with exactly zero privileges.”

2.2 对比的三个实现

产品护栏策略绕过成本
Claude CodeSystem prompt 级红线 + Hook 机制中(可通过 prompt injection 绕过部分)
Cursor文件级 .cursorignore + 编辑器级 diff 审批低(编辑器仅是 UI 层拦截)
OpenClaw(我的)四层拦截:Skill 校验 + Hook + CLAUDE.md 红线 + Shell alias高(任意一层拦下就终止)

2.3 我的核心主张

非确定性的东西必须被确定性的东西包围。

模型越聪明,护栏越要傻——傻到不讲理,傻到"就是不让过"。


三、概念精析:什么是"确定性外壳 × 非确定性内核"

3.1 定义

非确定性内核:大模型本身。同样的输入可能有不同的输出,有概率性的幻觉、遗漏、执行偏离。

确定性外壳:Harness 中所有输出可预测、行为可审计、绕不过去的部件。包括:

  • 类型系统(编译期拦截)
  • 校验规则(运行时拦截)
  • 白名单/黑名单(配置层拦截)
  • Hook 钩子(执行前拦截)
  • Shell/OS 层(最后一道物理拦截)

3.2 为什么这个组合是 Harness 的第一支柱

没有确定性外壳的 Agent,就像没有保险丝的电路——平时运行正常,一旦短路就烧主板。

你可以把 Agent 产品的成熟度用一个公式衡量:

产品成熟度 = 模型能力 × 外壳严密度

模型能力决定 Agent 的上限,外壳严密度决定 Agent 的下限

上限决定 Demo 多炫,下限决定产品能不能卖。企业客户买的从来不是上限——他们付钱是为了"你不要在我的生产系统里捅刀子"。

3.3 一个反直觉的观察

很多团队把 80% 的精力投在提升模型能力(换更大模型、调 prompt、做 fine-tune),只花 20% 的精力做护栏。

正确的比例应该反过来——80% 做外壳,20% 调内核。

因为内核的能力上涨是全行业共享的红利(GPT-5、Claude 5 发布你也能用上),而外壳的严密度是你的差异化护城河


四、实例拆解:OpenClaw 的四层护栏体系(含完整代码)

这一节我把 OpenClaw(我的 Agent 框架)的整套护栏机制完整开源出来。这是过去半年我用血写出来的。

4.1 第一层:Skill 声明式校验

每个 Skill 在SKILL.md头部声明它能做什么、不能做什么:

---name:stock-traderdescription:股票交易技能permissions:allowed_tools:-read_file-search_content-mcp_call_tool:tencent-docsforbidden_tools:-execute_command# 禁止直接执行 shell-delete_filerequire_confirmation:-"submit_order"# 下单前必须用户确认-"cancel_order"red_lines:-"禁止在单日交易额 > 10 万元时不经确认提交"-"禁止使用杠杆(margin=true)"---

启动时校验(Python 伪代码,实际在 OpenClaw 运行时):

importyamlfrompathlibimportPathdefload_skill(skill_path:Path)->dict:"""加载 Skill 并在加载时做强校验"""content=skill_path.read_text(encoding='utf-8')# 提取 frontmatterifnotcontent.startswith('---'):raiseSkillValidationError(f"{skill_path.name}: 缺少 frontmatter")fm_end=content.find('---',3)frontmatter=yaml.safe_load(content[3:fm_end])# 必需字段校验required=['name','description','permissions']forfieldinrequired:iffieldnotinfrontmatter:raiseSkillValidationError(f"缺少必需字段:{field}")# 禁用工具和允许工具不能冲突allowed=set(frontmatter['permissions'].get('allowed_tools',[]))forbidden=set(frontmatter['permissions'].get('forbidden_tools',[]))ifallowed&forbidden:raiseSkillValidationError(f"工具既在 allowed 又在 forbidden:{allowed&forbidden}")returnfrontmatter

这一层拦截的是"技能设计阶段的疏漏"——写 Skill 的人没想到的权限冲突,在加载时就报错,根本进不了运行态。

4.2 第二层:Hook 机制(执行前拦截)

这是借鉴 Claude Code 的 Hook,但做得更严格。每次工具调用前,运行所有注册的 Hook:

# openclaw/core/hooks.pyfromtypingimportCallable,List,Dict,AnyclassHook:"""工具调用前的拦截钩子"""def__init__(self,name:str,priority:int,handler:Callable):self.name=name self.priority=priority# 数字越小越先执行self.handler=handlerdefcheck(self,tool_name:str,args:Dict[str,Any])->tuple[bool,str]:"""返回 (是否放行, 拒绝原因)"""returnself.handler(tool_name,args)# 核心:执行钩子链defrun_hooks(hooks:List[Hook],tool_name:str,args:Dict)->None:sorted_hooks=sorted(hooks,key=lambdah:h.priority)forhookinsorted_hooks:allowed,reason=hook.check(tool_name,args)ifnotallowed:raiseHookBlockedError(f"[{hook.name}] 阻止了{tool_name}:{reason}")

内置的 git_push_guard Hook(这是我被 git push --force 坑过之后写的):

# openclaw/hooks/git_push_guard.pyimportrefrom.baseimportHookdefgit_push_check(tool_name:str,args:Dict)->tuple[bool,str]:"""拦截所有未经确认的 git push 操作"""iftool_name!='execute_command':returnTrue,''cmd=args.get('command','')# 扫描危险模式dangerous_patterns=[r'\bgit\s+push\b',r'\bgit\s+remote\s+add\b.*&&.*git\s+push',r'\bgit\s+push\s+.*--force\b',r'\bgit\s+push\s+.*-f\b',]forpatternindangerous_patterns:ifre.search(pattern,cmd):# 检查参数中是否明确标注了用户确认ifnotargs.get('user_confirmed_push'):returnFalse,(f"检测到 git push 相关操作:{cmd[:60]}...\n""按 OpenClaw 红线,必须用户明确说'推'或'确认'才能执行。\n""请先向用户说明要执行的命令并等待确认。")returnTrue,''git_push_guard=Hook(name='git_push_guard',priority=10,# 高优先级handler=git_push_check)

实战效果:这个 Hook 上线后的 3 个月,拦下了7 次模型自己生成git push的尝试。7 次都是"模型觉得该推一下",但我没明确说推

4.3 第三层:CLAUDE.md 红线 + 记忆强化

在 Session 级别,每次新对话启动时 CLAUDE.md 自动注入红线:

# CLAUDE.md(节选) ## 绝对红线(不可跨越) 1. **Git push 红线**:未经用户明确确认,禁止执行 git push / git remote add+push。 2. **小红书发布红线**:禁止使用用户本地电脑文件作为发布素材。 3. **删除数据红线**:所有 delete_file / rm -rf 操作必须用户确认。 4. **系统命令红线**:sudo、chmod 777、修改 ~/.zshrc 等 OS 级操作必须用户确认。 ## 红线触发时的标准回应 如果我收到类似"帮我推一下代码"的模糊指令: 1. 不要直接执行 git push。 2. 先明确告知要执行的命令。 3. 等用户说"推"或"确认"。 4. 收到确认后才执行。

这一层拦截的是"语义层的疏漏"——即使 Hook 被绕过(比如模型用了 Python subprocess 而不是 execute_command),LLM 本身也被红线约束。

4.4 第四层:Shell alias 物理拦截

这是最后一道防线,也是最傻的一道:

# ~/.zshrc 末尾aliasgit-push-safe='echo "⚠️ AI 禁止使用 git push。请手动在终端执行。" && false'# 更严格:拦所有 AI 会话中的 git pushfunctiongit(){if[["$1"=="push"&&"$OPENCLAW_SESSION"=="1"]];thenecho"🛑 OpenClaw 会话中禁止 git push。请手动在新终端执行。"return1ficommandgit"$@"}

配合 OpenClaw 启动时设置export OPENCLAW_SESSION=1即使前面三层全被绕过,shell 层也会拦住

4.5 四层串起来的实际效果

攻击场景L1 SkillL2 HookL3 CLAUDE.mdL4 Shell结果
Skill 未声明 execute_command✅ 拦---加载时失败
已授权 Skill 生成 git push✅ 拦--Hook 阻止
Prompt injection 绕过 Hook✅ 拦-模型自我约束
模型用 subprocess 绕过所有✅ 拦Shell 拒绝

核心设计哲学任何一层拦下就终止,不需要层层都完美。

这是和"模型能力路线"最根本的区别——那条路线追求"模型永不犯错",这条路线追求**“犯错成本被限制在可接受范围”**。

4.6 真实数据:过去 6 个月 Harness 拦截日志

我在~/.openclaw/logs/guardrails.jsonl里记录了所有拦截事件:

{"ts":"2026-02-14T23:47:12","layer":"L2-Hook","tool":"execute_command","rule":"git_push_guard","blocked_cmd":"git push --force origin main","context":"用户说'整理一下main'"}{"ts":"2026-03-02T10:23:05","layer":"L2-Hook","tool":"execute_command","rule":"delete_guard","blocked_cmd":"rm -rf ~/Documents/OpenClaw_backup","context":"用户说'清理一下旧备份'"}{"ts":"2026-03-19T15:11:38","layer":"L3-CLAUDE.md","tool":"mcp_call_tool","rule":"xhs_publish_red_line","blocked":"小红书发布未经确认","context":"用户说'发一下今天的笔记'"}...

6 个月累计拦截 47 次,其中:

  • git 相关 18 次(38%)
  • 删除操作 12 次(26%)
  • 第三方发布(小红书/微博) 9 次(19%)
  • 系统命令 5 次(11%)
  • 其他 3 次(6%)

47 次。每一次都可能是一个生产事故。这就是确定性外壳的真实价值。


五、启发与方法论:四条可迁移原则

原则 1:Trust the smart, verify the dumb

模型越聪明,越要用"不讲道理的规则"去约束它。

因为聪明的模型会找到更隐蔽的"合理化路径"去执行危险操作——它会"觉得"用户其实是想推一下、其实是想删一下。你的护栏必须不接受任何"觉得",只接受"明确说了"。

原则 2:多层次冗余 > 单点完美

不要追求一个"万能的拦截层",要追求4 层不同维度的拦截,任何一层 work 都够用

  • L1 是设计期的静态校验
  • L2 是运行时的动态 Hook
  • L3 是语义层的红线自我约束
  • L4 是物理层的 OS 拦截

四个维度各自独立,互为备份。这是软件工程里最古老也最有效的原则——Defense in Depth

原则 3:把"不可逆"和"可逆"严格分开

所有护栏的本质都在回答一个问题:这个操作的代价能不能回滚?

可逆操作(创建文件、读文件、本地实验)→ 大胆让模型去干,出错了改就是。
不可逆操作(git push、删除、第三方发布、金融交易)→一律用户明确确认

我在 OpenClaw 里维护了一张 “不可逆操作清单”,新增任何工具必须先分类:

# openclaw/config/irreversible_ops.yamlirreversible_operations:git:-push-push--force-reset--hard-branch-Dfilesystem:-delete_file-rm-rf-truncatenetwork:-xiaohongshu.publish-weibo.publish-wecom.send_messagefinance:-stock.submit_order-stock.cancel_order

这张表是 Harness 的**“高压线地图”**。没在这张表上的操作模型可以自由用,在表上的必须经过护栏。

原则 4:把失败日志当作 Harness 的年度体检

护栏不是设完就完了——你需要定期 review 拦截日志,从中发现模型的新型绕过模式

我每月 1 号做一次 Harness 体检,跑一个脚本:

# scripts/harness_health_check.pyimportjsonfromcollectionsimportCounterfromdatetimeimportdatetime,timedeltadefmonthly_review():logs=[]withopen('~/.openclaw/logs/guardrails.jsonl')asf:forlineinf:logs.append(json.loads(line))last_month=datetime.now()-timedelta(days=30)recent=[lforlinlogsifdatetime.fromisoformat(l['ts'])>last_month]# 按规则统计rule_counter=Counter(l['rule']forlinrecent)print("本月拦截 TOP 规则:")forrule,countinrule_counter.most_common(10):print(f"{rule}:{count}次")# 新型绕过尝试(之前没见过的 context)unique_contexts=set(l['context']forlinrecent)# ... 进一步分析新模式

每次月度体检我都会发现 1-2 个新模式,然后把它们加到 Hook 里。Harness 不是一次性工程,是长期养大的系统。


六、反驳性思考

反驳一:四层护栏会不会让 Agent 变得很蠢?

会。而且是故意让它变蠢。

但"蠢"不等于"没用"。类比:飞机的自动驾驶系统遇到异常姿态会直接断开、交还飞行员——这是"蠢"的设计,但这个设计救了无数人命。

Agent 的护栏哲学一致:在高风险操作上变蠢,是为了在低风险操作上可以大胆聪明。

反驳二:这么多层会不会影响性能?

有影响,但可以忽略。

L1 是启动时一次性校验(<100ms)
L2 Hook 是每次工具调用前(<5ms/次)
L3 是 prompt 级,不增加额外 IO
L4 是 shell 层,<1ms

实测 OpenClaw 每次工具调用的护栏总开销 <10ms,占整体调用耗时 <1%。

反驳三:小型项目需要这么重的护栏吗?

不需要全做,但不能一层都没有。

最小可行版本:L2 Hook + L3 CLAUDE.md 红线,两个加起来不到 200 行代码,半天做完。

如果你的 Agent 会碰生产系统 / 金融 API / 用户数据,那四层必须齐全。这不是规模问题,是责任问题。


七、收官与预告

这一篇把"确定性外壳 × 非确定性内核"的第一支柱讲透了——Harness 的起点是 Guardrails

下一篇(03)是这个系列的第一篇硬货

《Checkpoint vs Compaction:为什么我放弃了 Claude 的上下文压缩》

我会把自己的daily-dream 心跳系统完整代码(含 launchd plist、crontab、三层脚本、Wiki Lint 规则)全部开源。一起比较两种上下文管理哲学——Anthropic 的 Compaction 和我的 Checkpoint——到底哪个更适合长期项目。

这是全系列最硬的一篇,写完它我可以少睡两天。

全系列地图

#标题状态
01Agent = Model + Harness
02确定性外壳 × 非确定性内核✅ 当前
03Checkpoint vs Compaction(硬货篇)⏳ 下一篇
04Task Loop 三层心跳(硬货篇)
05Context 不是内存是预算
06独立 Evaluator
07五大反模式(硬货篇)
08Big Model vs Big Harness

路易乔布斯
2026 年 5 月 · 深圳
养虾系列 S4 · Harness Engineering 深度拆解 02/08
更多清关注【一深思AI】

http://www.jsqmd.com/news/773407/

相关文章:

  • 从语音到智能体:构建语音交互式AI系统的架构与实践
  • NLP情感分析:从传统方法到深度学习
  • 用于柔性机械臂的低频动力吸振器设计及其主动控制刚柔耦合【附代码】
  • Kubernetes中AI工作负载的安全风险与防护实践
  • 你的QQ音乐加密文件,为何在其他设备上无法播放?3步解锁音频自由!
  • Arctium启动器完整指南:快速连接魔兽世界自定义服务器终极教程
  • 从无人机飞控到机械臂:手把手教你用Python实现RPY角与旋转矩阵互转(附完整代码库)
  • 深度学习优化:从梯度下降到Adam的理论与实践
  • 2026年5月新发布:沙湾厨房防水补漏服务商综合评估与选择指南 - 2026年企业推荐榜
  • 免费开源视频压缩终极指南:5分钟掌握CompressO跨平台压缩技巧
  • SMUDebugTool深度解析:AMD Ryzen硬件调试的技术架构与实践应用
  • 基于图像识别的桌面自动化:mousemaster 工具原理与实战指南
  • 软考必备|数据结构算法速记表(高频考点,直接背)
  • Legacy iOS Kit:让旧iPhone和iPad重获新生的终极工具
  • 创业股权分配程序,股权比例,分红规则上链,避免合伙人反目。
  • 基于FPGA的永磁同步电机复合滑模无速度传感器控制【附代码】
  • 2026年5月宁波楼梯供应商深度解析:为何瑞王铠萨是豪宅与工程项目的优选伙伴? - 2026年企业推荐榜
  • 2026年5月新消息:探寻山东SEDEX辅导领域的专业服务力量 - 2026年企业推荐榜
  • 2026年5月国内环氧双组份胶粘石胶实力厂商推荐:南京绿磊装饰材料有限公司 - 2026年企业推荐榜
  • 2026年5月新消息:国产品牌崛起,三坐标测量仪供应商如何选? - 2026年企业推荐榜
  • HoRNDIS:Mac与Android USB网络共享的终极解决方案
  • Spyder深色模式:让科学编程的夜晚更舒适
  • 终极指南:如何用SysDVR实现Switch游戏画面电脑同步的3种方法
  • 2026年现阶段安徽省考面试辅导机构深度解析:为何相对面教育成为焦点 - 2026年企业推荐榜
  • Windows 11系统优化终极指南:如何一键清理和加速你的电脑
  • 2026年近期武汉不锈钢挡圈采购指南:湖北欣合紧固件资深供应商深度解析 - 2026年企业推荐榜
  • ViFeEdit:基于图像与文本特征的视频编辑技术解析
  • 5大理由告诉你:为什么UE5-MCP是AI驱动游戏开发的革命性工具
  • 2026年至今,秦皇岛全屋定制口碑价值重塑,揭秘本地品牌的硬核实力 - 2026年企业推荐榜
  • Windows字体渲染终极优化指南:3步让你的文字像Mac一样清晰