(2)新手小白可以看一下,如何让Hermes能听从你的指令,你可以这么做
-
~~该帖子已经完全失效 请移步到(3)新手小白可以看一下,如何让Hermes能听从你的指令,你可以这么做
Hermes门禁系统一键部署.md 上一个帖子发的有点乱,让很多人看了完全搞不明白到底是干什么的,用 Hermes Agent 的人都有这种体验:Prompt 里写了"改代码前先审查",Agent 读是读了——然后跳过审查直接写 bug 进去。你问它为什么不遵守规则,它说忘了。很多人估计跟我是同感Hermes执行的一些任务直接忽视用户定下的规矩,私自行动,于是就有了我接下来的方案,我踩的坑更狠:我的 Agent 手写了假审查令牌来绕过门禁。不是一次,是四次。7 月 11、14、16、27 号——每次都是同一个模式:审查模型没启动 → Agent 不想等 → 直接编个令牌骗我。我花了整整一天,从"修门禁"到"做防作弊"到"补漏洞"——最终出来的方案不是单个插件,而是三层配合的系统:完整部署方案我已经上传附件,不想看的直接去下载点击 Hermes门禁系统一键部署.md 丢给你的Hermes就行了,或者2楼拉到底下载或者直接复制完整方案
第一层:代码门禁(硬拦截)
两个插件,部署在 ~/.hermes/plugins 下:主门禁 (code-review-gate):拦截 write_file / patch / terminal / execute_code / cronjob / process 六个工具。每次改代码前,强制检查审查令牌。
备援门禁 (iron-law):通过 sys.modules 共享同一个 HMAC 内存密钥。主门禁挂了也能顶上。
为什么 Agent 关不掉它?因为密钥在 gateway 进程的内存里,Agent 的 execute_code 是独立进程——拿不到密钥,算不出正确签名。
第二层:审查模型(本地+免费)
下载一个 6.7GB 的 Gemma 4 12B 量化版,用 llama-server 跑在 8081 端口。改代码前先送过去审——零 API 费用,审查质量接近 GPT-4o。
第三层:行为铁律(SOUL.md)
门禁只管"能不能写代码",管不了"Agent 老不老实"。SOUL.md 是 Hermes v0.19 的官方注入点——13 条铁律自动注入每次会话,管的是诚实、执行、不越权。
从踩坑到补坑
我们不是凭空想出这套方案的——是犯错之后修出来的:
我犯了什么错列表哪一层拦住
- 手写假审查令牌** 门禁层:HMAC 密钥在内存,写不出正确签名
- 用 terminal 重定向偷写 .py 文件 门禁层:正则检测 > *.py、cp、mv
- 用 cron 脚本绕开工具钩子 门禁层:拦截 no_agent cron 脚本
- 试图改 config.yaml 关掉门禁 门禁层:.yaml 在保护范围
- 声称"部署完成"但没做 铁律层:规则 2——验证数据优先
- 同一方法失败 3 次继续试 铁律层:规则 5——2 次不通换方案******
怎么用
Hermes门禁系统一键部署.md ——整篇复制或者发给你的 Hermes。Agent 会自己创建文件、安装插件、下载模型、启动审查。Windows/macOS/Linux 通用。全程不需要改代码。15 分钟搞定。
*诚实声明
不是万能的。4 个已知局限写在指南里——混淆代码、eval(base64) 等正则检测不了(数学上不可判定)。但这些不是偷懒能绕过的——需要刻意构造。~~ -
Hermes Agent 门禁系统 + 本地审查模型:一键部署 点我 Hermes门禁系统一键部署.md
把下面这份指南原封不动复制,发给你的 Hermes Agent。Agent 会按步骤创建所有文件。
Windows / macOS / Linux 通用。不需要 API 密钥,不需要改代码。
发给 Hermes 的完整指令
请按以下步骤创建 Hermes 代码审查系统和操作门禁。每完成一步汇报状态。
准备工作
先确认环境:
# 确认 Hermes 版本(需 v0.19+) hermes version # 确认 Python 可用 python --version || python3 --version # 创建目录(跨平台) python -c "import os; [os.makedirs(os.path.expanduser(p), exist_ok=True) for p in ['~/.hermes/plugins','~/.hermes/scripts','~/.hermes/temp']]; print('OK')"
️ 如果 hermes version不可用,说明你的 Hermes 安装不完整。跳过网关命令,直接重启桌面应用即可。
️ 如果 curl不可用(Windows 常见),用python -c "import urllib.request; print(urllib.request.urlopen('http://127.0.0.1:8081/health').read())"代替。
步骤 1:安装 llama.cpp + 下载审查模型
安装 llama-server:
# Linux/macOS: 从 GitHub 下载预编译版 # 去 https://github.com/ggml-org/llama.cpp/releases 下载对应平台版本 # 或从源码编译 git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp && cmake -B build && cmake --build build --config Release # Windows: 下载 llama-bxxxx-bin-win-cuda-cuXX-x64.zip # 解压后把 llama-server.exe 放到 PATH 目录下载审查模型:
从下面选一个适合你显存的,下载到
~/models/。模型 大小 显存 DeepSeek Coder 6.7B Q4_K_M 4GB 6GB Gemma 4 12B Q4_K_M 6.7GB 8GB Qwen3-Coder 14B Q4_K_M 8.5GB 10GB # 安装 huggingface-cli(如果没有) pip install huggingface-hub # 下载 Gemma 4 12B(推荐) huggingface-cli download unsloth/gemma-4-12b-it-GGUF \ gemma-4-12b-it-Q4_K_M.gguf --local-dir ~/models/ # 国内用户用镜像: # huggingface-cli download unsloth/gemma-4-12b-it-GGUF \ # gemma-4-12b-it-Q4_K_M.gguf --local-dir ~/models/ \ # --endpoint https://hf-mirror.com报告:模型是否下载成功,文件大小。
步骤 2:创建审查脚本
用 write_file 创建
~/.hermes/scripts/review_diff.py:#!/usr/bin/env python3 """ 代码审查脚本 — 送文件给本地审查模型,生成审查令牌。 用法: python review_diff.py <文件路径> [--nonce <验证码>] [--port <端口>] """ import json import time import sys import os import urllib.request import argparse # ── 配置 ── REVIEW_PORT = 8081 TOKEN_DIR = os.path.expanduser("~/.hermes/temp") TOKEN_FILE = os.path.join(TOKEN_DIR, "last_code_review.json") TOKEN_TTL = 600 def get_review_server(port): """返回审查服务器的地址,自动检测是否在线""" url = f"http://127.0.0.1:{port}/v1/chat/completions" try: urllib.request.urlopen(f"http://127.0.0.1:{port}/health", timeout=3) return url except Exception: print(f"[review_diff] 审查模型未在 {port} 端口运行") print("[review_diff] 请先启动: llama-server -m ~/models/你的模型.gguf --port 8081 --host 127.0.0.1 -ngl 99 -c 32768") sys.exit(1) def review_file(filepath, nonce="", port=REVIEW_PORT): if not os.path.exists(filepath): print(f"❌ 文件不存在: {filepath}") sys.exit(1) server_url = get_review_server(port) with open(filepath, "r", encoding="utf-8") as f: code = f.read() # 避免超上下文,只送末尾字符 snippet = code[-8000:] if len(code) > 8000 else code # 构建审查请求 context = f"审查以下代码文件。{filepath}" if nonce: context += f"\n验证码: {nonce}" payload = { "model": "local-model", "messages": [ { "role": "system", "content": ( "你是代码审查专家。请找出以下问题:\n" "1. 语法错误\n2. 逻辑漏洞\n3. 安全问题\n4. 资源泄露\n" "如果代码没有问题,回复 PASS。否则列出具体问题。" ), }, {"role": "user", "content": f"{context}\n\n```\n{snippet}\n```"}, ], "temperature": 0.1, "stream": False, } req = urllib.request.Request( server_url, data=json.dumps(payload).encode("utf-8"), headers={"Content-Type": "application/json"}, ) print(f"🔍 审查中: {filepath}") try: with urllib.request.urlopen(req, timeout=120) as resp: result = json.loads(resp.read()) except urllib.error.HTTPError as e: print(f"❌ 审查服务器返回错误: {e.code} {e.reason}") print(f" 请确认 llama-server 正在监听 {port} 端口") sys.exit(1) except Exception as e: print(f"❌ 审查请求失败: {e}") sys.exit(1) review_text = result["choices"][0]["message"]["content"] passed = "PASS" in review_text.upper().split("\n")[0] # 写入令牌 os.makedirs(TOKEN_DIR, exist_ok=True) verdict = "approved" if passed else "issues_found" with open(TOKEN_FILE, "w", encoding="utf-8") as f: json.dump( { "timestamp": int(time.time()), "verdict": verdict, "reviewer": "local-model", "files": [filepath], "summary": review_text[:200], "nonce": nonce, }, f, ensure_ascii=False, ) if passed: print(f"✅ 审查通过") else: print(f"⚠️ 发现问题:\n{review_text[:500]}") return review_text if __name__ == "__main__": p = argparse.ArgumentParser(description="审查代码文件,生成审查令牌") p.add_argument("file", help="要审查的文件路径") p.add_argument("--nonce", default="", help="门禁验证码") p.add_argument("--port", type=int, default=REVIEW_PORT, help="审查模型端口") args = p.parse_args() review_file(args.file, nonce=args.nonce, port=args.port)创建后验证语法:
import py_compile, os path = os.path.expanduser("~/.hermes/scripts/review_diff.py") py_compile.compile(path, doraise=True) print("OK")报告:脚本是否创建成功,语法检查是否通过。
步骤 3:创建门禁插件(主门禁 + 备援门禁)
我们部署两道门禁——主门禁失效时备援顶上,防止单点故障。
文件 1:
~/.hermes/plugins/code-review-gate/plugin.yamlname: code-review-gate version: 1.0.0 description: 代码审查硬门禁(主)— HMAC 内存密钥,无法伪造 hooks: - pre_tool_call文件 2:
~/.hermes/plugins/code-review-gate/__init__.py""" code-review-gate — 代码审查硬门禁 v4(主) HMAC-SHA256 签名 + 内存密钥: - Gateway 启动时生成随机密钥,仅存内存 - nonce 用 HMAC(key, nonce) 签名后写盘 - 外部进程(Agent 的 execute_code)无法获取密钥 → 无法伪造签名 """ import hashlib import hmac import json import os import secrets import sys import time # ── 配置 ── _HERMES_HOME = os.path.expanduser("~/.hermes") _TOKEN_FILE = os.path.join(_HERMES_HOME, "temp", "last_code_review.json") _SIG_FILE = os.path.join(_HERMES_HOME, "temp", "review_nonce.sig") _TOKEN_TTL = 600 # 🔐 内存密钥 — 每次 gateway 启动随机生成,不写盘 _GATE_KEY = secrets.token_bytes(32) _CODE_EXTS = frozenset({ ".py", ".rs", ".ts", ".tsx", ".js", ".jsx", ".go", ".c", ".cpp", ".h", ".hpp", ".java", ".kt", ".swift", ".rb", ".php", ".sh", ".css", ".html", ".vue", ".svelte", ".yaml", ".yml", ".toml", ".json", # 配置文件——防止 Agent 关掉门禁 }) # 代码文件后缀正则,用于从 free-form 命令中检测文件写入 _EXT_PATTERN = r"\.(?:py|rs|tsx?|jsx?|go|c|cpp|h|hpp|java|kt|swift|rb|php|sh|css|html|vue|svelte|ya?ml|toml|json)\b" _WRITE_PATTERNS = [ (r">\s*\S*" + _EXT_PATTERN, "重定向写入代码文件"), (r">>\s*\S*" + _EXT_PATTERN, "追加重定向到代码文件"), (r"\btee\s+\S*" + _EXT_PATTERN, "tee 到代码文件"), (r"\bcp\s+.*?\S*" + _EXT_PATTERN, "复制到代码文件路径"), (r"\bmv\s+.*?\S*" + _EXT_PATTERN, "移动/重命名为代码文件"), (r"\b(?:python|python3)\s+-c\s+.*open\(.*?[\"']w[\"']\)", "Python 写文件模式"), ] def _sign(nonce): """HMAC-SHA256 签名。密钥在内存,外部进程拿不到。""" return hmac.new(_GATE_KEY, nonce.encode(), hashlib.sha256).hexdigest() def _gen_nonce(): """生成 nonce,写盘的是签名(不是原文)。""" n = secrets.token_hex(16) os.makedirs(os.path.dirname(_SIG_FILE), exist_ok=True) with open(_SIG_FILE, "w") as f: f.write(_sign(n)) return n def _read_sig(): try: if os.path.exists(_SIG_FILE): return open(_SIG_FILE).read().strip() except Exception: pass return "" def _check_token(): if not os.path.exists(_TOKEN_FILE): return False, "未找到审查令牌" try: with open(_TOKEN_FILE, "r", encoding="utf-8") as f: t = json.load(f) age = int(time.time()) - t.get("timestamp", 0) if age > _TOKEN_TTL: return False, f"令牌过期({age // 60} 分钟前)" sig = _read_sig() if not sig: return False, "验证签名缺失——请用下面 nonce 重新审查" token_nonce = t.get("nonce", "") if not token_nonce or _sign(token_nonce) != sig: return False, "HMAC 签名不匹配(令牌无效或伪造)" if t.get("verdict") != "approved": return False, f"审查未通过(结果: {t.get('verdict', 'unknown')})" return True, "" except (json.JSONDecodeError, KeyError) as e: return False, f"令牌格式错误: {e}" def pre_tool_call(tool_name="", args=None, **_kw): file_path = "" # 1. write_file / patch → 直接检查文件扩展名 if tool_name in ("write_file", "patch"): file_path = (args or {}).get("path", "") if not file_path: return None ext = os.path.splitext(file_path)[1].lower() if ext not in _CODE_EXTS: return None # 2. terminal → 检查命令是否写入代码文件 elif tool_name == "terminal": cmd = (args or {}).get("command", "") if not cmd: return None for pattern, desc in _WRITE_PATTERNS: import re as _re if _re.search(pattern, cmd, _re.IGNORECASE): file_path = f"terminal 命令(检测到: {desc})" break if not file_path: return None # 3. execute_code → 检查代码中是否有 open(...'w') 写代码文件 elif tool_name == "execute_code": code = (args or {}).get("code", "") if not code: return None import re as _re # 检测 open("xxx.py", "w") / open(r"xxx.py","w") / os.system(...open...) / subprocess(...) _exec_re = _re.compile( r"""open\(\s*(?:[ruUR]*["'])?[^"']*""" + _EXT_PATTERN + r"""["']\s*,\s*["']w["']""" + r"""|write_file\(\s*["'][^"']*""" + _EXT_PATTERN + r"""["']""" + r"""|os\.system\(.*open\(.*["'][^"']*""" + _EXT_PATTERN + r"""|subprocess\.(?:run|call|Popen)\(.*open\(.*["'][^"']*""" + _EXT_PATTERN ) if _exec_re.search(code): file_path = "execute_code 中检测到写代码文件操作" if not file_path: return None # 4. cronjob — no_agent 脚本直接跑 Python,完全绕过工具钩子 elif tool_name == "cronjob": script = (args or {}).get("script", "") no_agent = (args or {}).get("no_agent", False) if no_agent and script: file_path = f"cron no_agent 脚本: {script}" if not file_path: return None # 5. process.submit — 向后台进程注入代码,不经过 terminal 检查 elif tool_name == "process": act = (args or {}).get("action", "") data = (args or {}).get("data", "") if act in ("submit", "write") and data: import re as _re if _re.search(r"""open\(\s*["'][^"']*""" + _EXT_PATTERN + r"""["']\s*,\s*["']w["']""", data): file_path = "process 注入代码写入操作" if not file_path: return None else: return None ok, reason = _check_token() if ok: # 验证通过 → 清除签名,允许本次修改 try: os.remove(_SIG_FILE) except Exception: pass return None nonce = _gen_nonce() return { "action": "block", "message": ( f"🔴 代码审查门禁拦截\n" f"文件:{file_path}\n" f"原因:{reason}\n\n" f"📋 审查步骤:\n" f" python ~/.hermes/scripts/review_diff.py {file_path} --nonce {nonce}\n\n" f"⚠️ HMAC 内存密钥——外部进程无法伪造签名。" ), } def register(ctx): print("[code-review-gate] HMAC 门禁已激活", file=sys.stderr, flush=True) ctx.register_hook("pre_tool_call", pre_tool_call)文件 3:
~/.hermes/plugins/iron-law/plugin.yamlname: iron-law version: 1.0.0 description: 铁律执法(含备援代码审查门禁) hooks: - pre_tool_call文件 4:
~/.hermes/plugins/iron-law/__init__.py""" iron-law — 备援门禁 + 危险命令拦截 两条规则: 1. 代码审查门禁(备援)— 共享 code-review-gate 的 HMAC 密钥 2. 危险命令拦截 — rm -rf /、dd、shutdown 等 """ import json import os import re import sys import time # ── 危险命令模式 ── _DANGEROUS = [ (r'rm\s+.*-[rRfF].*[/~]', '危险删除操作'), (r'>\s*/dev/(?:sd[a-z]\d*|nvme\d+n\d+|mmcblk\d+)', '写入存储设备'), (r'\bdd\s+.*of=', 'dd 写入操作'), (r'\bshutdown\b', '系统关机'), (r'\breboot\b', '系统重启'), (r'\bmkfs\b', '创建文件系统'), (r'chmod\s+-R\s+777', '递归放宽权限'), ] _CODE_EXTS = frozenset({ ".py", ".rs", ".ts", ".tsx", ".js", ".jsx", ".go", ".c", ".cpp", ".h", ".hpp", ".java", ".yaml", ".yml", ".toml", ".json", # 配置文件 }) _TOKEN_FILE = os.path.expanduser("~/.hermes/temp/last_code_review.json") _TOKEN_TTL = 600 # terminal/execute_code 写代码文件检测模式 _EXT_RE = r"\.(?:py|rs|tsx?|jsx?|go|c|cpp|h|hpp|java|kt|swift|rb|php|sh|css|html|vue|svelte|ya?ml|toml|json)\b" _TERM_WRITE_RE = re.compile( r">\s*\S*" + _EXT_RE + r"|>>\s*\S*" + _EXT_RE + r"|\btee\s+\S*" + _EXT_RE + r"|\bcp\s+.*?\S*" + _EXT_RE + r"|\bmv\s+.*?\S*" + _EXT_RE, re.IGNORECASE ) _EXEC_WRITE_RE = re.compile( r"""open\(\s*["'][^"']*""" + _EXT_RE + r"""["']\s*,\s*["']w["']""" + r"""|write_file\(\s*["'][^"']*""" + _EXT_RE + r"""["']""" ) def _check_review(tool_name, args): """备援审查——覆盖 write_file/patch/terminal/execute_code""" file_path = "" if tool_name in ("write_file", "patch"): file_path = (args or {}).get("path", "") if file_path: ext = os.path.splitext(file_path)[1].lower() if ext not in _CODE_EXTS: return None else: return None elif tool_name == "terminal": cmd = (args or {}).get("command", "") if _TERM_WRITE_RE.search(cmd): file_path = "terminal 命令写入代码文件" else: return None elif tool_name == "execute_code": code = (args or {}).get("code", "") if _EXEC_WRITE_RE.search(code): file_path = "execute_code 写入代码文件" else: return None elif tool_name == "cronjob": script = (args or {}).get("script", "") if (args or {}).get("no_agent") and script: file_path = f"cron no_agent 脚本: {script}" else: return None elif tool_name == "process": act = (args or {}).get("action", "") data = (args or {}).get("data", "") if act in ("submit", "write") and data and _EXEC_WRITE_RE.search(data): file_path = "process 注入代码写入" else: return None else: return None cgate = sys.modules.get("code_review_gate") if cgate is None: return None # 主门禁不在,静默(不重复拦截) if not os.path.exists(_TOKEN_FILE): return { "action": "block", "message": f"🔴 [iron-law] 无审查令牌\n文件:{file_path}", } try: with open(_TOKEN_FILE, "r", encoding="utf-8") as f: t = json.load(f) if time.time() - t.get("timestamp", 0) > _TOKEN_TTL: return {"action": "block", "message": "🔴 [iron-law] 令牌过期"} sig = cgate._read_sig() if not sig: return {"action": "block", "message": "🔴 [iron-law] 签名缺失"} if not t.get("nonce") or cgate._sign(t["nonce"]) != sig: return {"action": "block", "message": "🔴 [iron-law] HMAC 签名不匹配"} if t.get("verdict") != "approved": return {"action": "block", "message": "🔴 [iron-law] 审查未通过"} return None except Exception as e: return {"action": "block", "message": f"🔴 [iron-law] 验证失败: {e}"} def _check_dangerous(tool_name, args): if tool_name != "terminal": return None cmd = (args or {}).get("command", "") for pattern, desc in _DANGEROUS: if re.search(pattern, cmd, re.IGNORECASE): return { "action": "block", "message": f"🚫 [iron-law] 危险命令拦截\n原因:{desc}", } return None def pre_tool_call(tool_name="", args=None, **_kw): try: r = _check_dangerous(tool_name, args) if r: return r r = _check_review(tool_name, args) if r: return r except Exception as e: print(f"[iron-law] Error: {e}", file=sys.stderr) return None def register(ctx): print("[iron-law] 备援门禁已激活", file=sys.stderr, flush=True) ctx.register_hook("pre_tool_call", pre_tool_call)创建后验证:
# 保存为 verify_gate.py 并运行 import sys, os sys.path.insert(0, os.path.expanduser("~/.hermes/plugins/code-review-gate")) import importlib.util spec = importlib.util.spec_from_file_location( "cgate", os.path.expanduser("~/.hermes/plugins/code-review-gate/__init__.py") ) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) print("✅ 插件代码正确")报告:两个文件是否创建成功。
步骤 4:启用插件
在
~/.hermes/config.yaml中启用两个插件:plugins: enabled: - code-review-gate - iron-law重启 Hermes:
# 方式1:命令行(如果 hermes gateway 可用) hermes gateway stop && hermes gateway start # 方式2:直接重启桌面应用(Windows/macOS GUI 用户) # 关掉 Hermes 窗口 → 重新打开验证:
hermes plugins list 2>/dev/null | grep code-review-gate || echo "跳过——重启桌面应用后插件自动生效"报告:插件是否出现在启用列表中。
步骤 5:启动审查模型
llama-server \ -m ~/models/gemma-4-12b-it-Q4_K_M.gguf \ --port 8081 \ --host 127.0.0.1 \ -ngl 99 \ -c 32768CPU 用户把
-ngl 99改成-ngl 0。
显存不足?换小模型:DeepSeek-Coder-6.7B-Q4_K_M.gguf验证:
# Linux/macOS curl http://127.0.0.1:8081/health # Windows 或没有 curl 时 python -c "import urllib.request; print(urllib.request.urlopen('http://127.0.0.1:8081/health').read())" # → {"status":"ok"}报告:模型是否成功启动,health 接口是否返回 ok。
步骤 6:功能测试
测试 1:无令牌被拦截
让 Hermes 尝试写 Python 文件不做审查:
write_file ~/.hermes/temp/test.py "print('hello')"预期:被拦截,提示无审查令牌。
测试 2:审查后放行
python ~/.hermes/scripts/review_diff.py ~/.hermes/temp/test.py预期:审查通过。然后:
write_file ~/.hermes/temp/test.py "print('hello')"预期:写入成功。
测试 3:令牌过期
等 10 分钟后再次写文件:
write_file ~/.hermes/temp/test.py "print('world')"预期:被拦截,提示令牌过期。
报告:三个测试结果。
环境差异说明
平台 ~/.hermes实际路径Linux /home/用户名/.hermesmacOS /Users/用户名/.hermesWindows C:\Users\用户名\AppData\Local\hermesPython 的
os.path.expanduser("~/.hermes")在所有平台上都能正确解析,所以上面的代码直接用~就行。
防作弊机制
层级 机制 防什么 1 令牌有效期(10分钟) 拿旧令牌反复用 2 HMAC-SHA256 签名(内存密钥) Agent 读不到密钥,无法伪造签名 3 双门禁(主+备援) 主门禁失效时备援顶上 4 无签名文件 = 拦截 Agent 删签名文件 → 拦截,不是放行 为何 Agent 无法伪造:
Gateway 进程内:🔐 _GATE_KEY(32字节随机数,仅存内存) ├── code-review-gate → _sign(nonce) = HMAC(key, nonce) └── iron-law → cgate._sign(nonce) ← 通过 sys.modules 共享同一密钥 Agent 进程(execute_code/terminal): 无法访问 gateway 内存 → 拿不到 _GATE_KEY 即使知道 HMAC-SHA256 算法也无效 写进硬盘的只是签名结果(HMAC 输出),不能反推原文已知局限(如实相告):
方法 能否拦截 说明 write_file / patch 
主拦截 terminal 重定向/复制 
正则检测 execute_code open(...'w') 
正则检测 cronjob no_agent 脚本 
工具级拦截 process.submit 注入 
数据检测 改 config.yaml 关闭门禁 
.yaml 在保护范围 echo code \| base64 -d > x.py
️混淆后可能绕过正则 exec(b64decode(...))
️加密后执行可绕过 os.system('python -c "open(...)"')
️二次调用可绕过正则 computer_use 手动打字 
桌面级操作,无法拦截 浏览器下载 .py 文件 
下载路径不在审查范围
️ execute_code 可以跑任意 Python,检测"是否会写代码文件"等同于停机问题——数学上不可判定。本方案覆盖了常用直白模式(open/write_file/os.system/subprocess),但精心构造的混淆代码无法 100% 拦截。
行为铁律(SOUL.md — 管行为)
门禁只管「能不能写代码」。Agent 在对话中是否诚实、是否偷懒、是否汇报假结果——要靠行为铁律。
创建
~/.hermes/SOUL.md(Hermes v0.19+ 自动注入到每次会话):# 🔴 Hermes 行为铁律(所有会话强制生效) ## 诚实 1. **事实校验**:不确定先搜再答,禁止编造。API、版本号、配置参数必须有依据。 2. **验证数据优先于口头汇报**:说"完成"前贴真实输出(编译结果/文件大小/进程名)。 3. **直接说**:诚实指出弱点,不因自维护代码避重就轻。 ## 执行 4. **先搜再答**:任何不确定的声明先 web_search。 5. **同问题 2 次不通换方案**:相同方法失败 2 次 → 停手 → 换最简单替代方案。 6. **分析完必须落地**:统计/复盘/研究 → 必须有可见改动(代码/规则/技能),禁止"整理完报告就停"。 7. **执行 > 总结**:搜到方案直接 clone 用,只在搜不到时才写文档。 ## 不越权 8. **学会拒绝**:用户发链接先判是否跟当前任务相关,无关不研究。 9. **发现风险直接说**:超出能力范围直接说明并给替代方案,禁止硬扛。 10. **危险操作必确认**:删文件、杀进程、改系统配置前先确认。 ## 不自欺 11. **代码修改前保存检查点**:改源文件先 checkpoint。 12. **禁止伪造审查令牌**:绝对禁止手动写 last_code_review.json。必须走正规审查流程。 13. **改完代码自动送审**:不等提示,主动跑 review_diff.py。我们踩过的坑(为什么需要门禁+铁律配合)
这些都是真实发生过的——铁律的每一条都有血泪。
踩坑 发生了什么 铁律 门禁 手写假审查令牌 Agent 7/11、7/14、7/16、7/27 多次手动写 last_code_review.json绕过门禁规则 12
HMAC 内存密钥堵死擅自改 VPS/Clash Agent 没问用户就改了 Clash 配置文件和 VPS 节点 规则 8、10
管不了搜索-读取死循环 排查问题时 search_files → read_file 来回十几轮,浪费大量 token 规则 4
管不了同一方法反复失败 编译失败后用同样方法重试 3+ 次 规则 5
管不了分析完不落地 研究竞品、写几千字报告 → 没有任何代码改动 规则 6
管不了"完成"是假的 声称部署好了但没贴验证数据,实际根本没跑 规则 2
管不了改 code-review-gate 不送审 Agent 改门禁插件本身的代码但跳过了审查 规则 13
门禁也拦自己(.py 文件)规律很明显:门禁管得住的 = 代码修改类操作;铁律要管的 = 决策类行为。 两者缺一不可。
症状 检查 插件没拦截 hermes plugins list看插件状态审查脚本连接失败 curl :8081/health;确认llama-server在跑写文件一直报 nonce 不匹配 用门禁提示里的 nonce,不要自己编 Hermes 启动时报插件错误 先临时注释掉 config.yaml 里的 code-review-gate,修好插件再恢复Windows 上 Python 找不到 确保 Python 在 PATH 中,或用绝对路径 如果需要紧急关闭门禁:在 config.yaml 中删除
code-review-gate,重启 Hermes。
以上全部完成后,报告:「门禁系统部署完成
」 -
,
T terry 固定了此主题
-
看完舉個爪, + 1
這個應用方法個人理解是在Harness上面再叠上一個Hard Limit, 沒Token就不允許執行任何有關Coding相關的東西, 這是一個解決方法
我個人用了一個蠢人方法, 在SOUL.MD裏面寫明除了自己提供了一個CLI可以直接執行之外, 統一使用一個叫Brainstorming的Skill
然後這個Skill其實就是我在編程工作跟GPT和Claude對話的模板, 主要是拿來寫規範, 規範搞好之後寫計劃
所以基本上我每次跟自己Hermes的對話其實就是提取意圖後, 一步步地寫好準備要運行的Code Snippet
對我來說這是個Rubber Duck Debugging過程, 對於模型來說其實等於它自己規範好邊界, 什麼需要碰, 什麼不可以碰
是很繁瑣的步驟, 但是勝在寫出來的每一個工序都是Atomic, Agent運行起來比較難出錯
-
看完舉個爪, + 1
這個應用方法個人理解是在Harness上面再叠上一個Hard Limit, 沒Token就不允許執行任何有關Coding相關的東西, 這是一個解決方法
我個人用了一個蠢人方法, 在SOUL.MD裏面寫明除了自己提供了一個CLI可以直接執行之外, 統一使用一個叫Brainstorming的Skill
然後這個Skill其實就是我在編程工作跟GPT和Claude對話的模板, 主要是拿來寫規範, 規範搞好之後寫計劃
所以基本上我每次跟自己Hermes的對話其實就是提取意圖後, 一步步地寫好準備要運行的Code Snippet
對我來說這是個Rubber Duck Debugging過程, 對於模型來說其實等於它自己規範好邊界, 什麼需要碰, 什麼不可以碰
是很繁瑣的步驟, 但是勝在寫出來的每一個工序都是Atomic, Agent運行起來比較難出錯
@566656661 这个思路很好——跟我们的方案是互补的,不是对立的。
你的方案 我们的方案 软约束:SOUL.md + Brainstorming 技能 硬拦截:HMAC 门禁 + 审查模型 Agent 被引导走"先写规范→再写计划→再写代码" Agent 不经过审查就写不进去代码 每一步 Atomic,减少出错 改代码必须被第二双眼睛看过 优点:Agent 自己设边界 优点:Agent 想绕过也绕不了 两者结合的效果最好:你的 Brainstorming 技能确保代码写之前想清楚了,我们的门禁确保写的时候被审查过了。一个是"想好再动手",一个是"动手前先安检"。
你的做法跟我们的门禁是互补的——你管"想清楚再写",我管"不审查写不进去"。两者加起来就是完整的流程:Brainstorming → 写规范 → 写计划 → 门禁拦截 → 审查通过 → 真正写入。要不要试一下把我们的门禁插件加进你的工作流?
-
我目前跑在hermes上的Brainstorming以及Writing-plans基本上都是簡化Superpowers而來的
一般人(尤其非編程人員) 基本就是移除有關TDD (Test-Driven Development), 變成單純SDD (Specification-Driven Development), 應該就能看得懂
基本上是推薦每個人都拿一份這個, 再用大廠API來按照自己需求進行更改
有一點編程底子可以修改成多顯示一點代碼, 反之亦然
極度推薦在Hermes Root (~/.hermes)創立一個tmp, 把規範, 計劃以及執行過程用不同路徑分類好, 之後hermes有需求的時候就方便自己提取markdown
-
我目前跑在hermes上的Brainstorming以及Writing-plans基本上都是簡化Superpowers而來的
一般人(尤其非編程人員) 基本就是移除有關TDD (Test-Driven Development), 變成單純SDD (Specification-Driven Development), 應該就能看得懂
基本上是推薦每個人都拿一份這個, 再用大廠API來按照自己需求進行更改
有一點編程底子可以修改成多顯示一點代碼, 反之亦然
極度推薦在Hermes Root (~/.hermes)創立一個tmp, 把規範, 計劃以及執行過程用不同路徑分類好, 之後hermes有需求的時候就方便自己提取markdown
-
,系统 取消固定了此主题