Claude软约束和硬约束的说明
先澄清一个容易混的点:harness.md 这个文件名本身不处理硬约束——它是项目自己写的工作流描述文档,全文都给 LLM 看,属于软约束。
真正承载硬约束的文件是另一批。完整清单:
一、纯硬约束文件(机制直接读取)
这些文件不经过 LLM,由 Claude Code 进程启动时/运行时解析并强制:
项目级:
.claude/settings.json ← 核心:permissions + hooks + mcpServers + env
.claude/settings.local.json ← 个人覆盖(不提交 git)
.mcp.json ← MCP 服务器定义(项目根,可单列)
.worktreeinclude ← worktree 隔离时复制哪些 gitignored 文件
.claude/hooks/*.sh / *.js / *.py ← hook 实际执行的脚本
全局级:
~/.claude/settings.json ← 用户级硬约束
~/.claude.json ← OAuth、MCP、feature flags(敏感,别手动改)
企业级:
/etc/claude-code/managed-settings.json ← Linux/macOS
C:\Program Files\ClaudeCode\managed-settings.json ← Windows
managed-settings.d/*.json ← systemd 风格 drop-in 片段
managed-settings.* 是这里最硬的——管理员部署的策略,配合 allowManagedHooksOnly: true,普通用户和项目都改不了,硬约束的天花板。
二、混合载体文件(frontmatter 硬 + 正文软)
这些是 markdown,但 YAML 头被机制吃掉、正文给 LLM 看:
.claude/agents/*.md ← tools:, model: 是硬
.claude/skills/*/SKILL.md ← allowed-tools: 是硬(仅 CLI 模式)
.claude/commands/*.md ← argument-hint:, allowed-tools: 是硬
.claude/output-styles/*.md ← name:, description: 是元数据
举例 agents/db-admin.md:
--- name: db-admin ← 硬:机制注册这个 agent tools: Read, Bash ← 硬:白名单,正文里说"也能 Write"都没用 model: opus ← 硬:调用时切到 opus --- You are a database admin... ← 软:给 LLM 看的角色 prompt
tools: 写错一个工具名,subagent 拿不到那个工具,与正文写什么完全无关。这就是为什么子代理权限必须靠 frontmatter 而不是靠 prompt 里写"你不许 Write"。
三、运行模式(非文件,但产生硬约束)
这层没有"文件",但属于硬约束体系,列全为了完整:
CLI 标志:
--permission-mode <acceptEdits|plan|bypassPermissions>
--dangerously-skip-permissions
--worktree
--add-dir <path>
--init / --maintenance
环境变量:
CLAUDE_CONFIG_DIR ← 重定向整个 ~/.claude
CLAUDE_PROJECT_DIR ← hook 能读到
CLAUDECODE=1 ← 子进程标识
CLAUDE_CODE_SKIP_PROMPT_HISTORY ← 不写历史
操作系统层:
sandbox-exec (macOS) ← Bash 默认包装
四、纯软约束文件(对照)
为了反衬——这些完全不碰硬约束机制,全文都注入 LLM prompt:
CLAUDE.md / CLAUDE.local.md
AGENTS.md / AGENTS.override.md
.claude/rules/*.md
.cursor/rules/*.mdc
.github/copilot-instructions.md
harness.md / Plans.md / SSOT.md / SPEC.md / PROGRESS.md
ARCHITECTURE.md / RUNBOOK.md / CONTEXT.md
docs/*.md(被 AGENTS.md 引用的)
这些文件再怎么写 "NEVER do X",本质都是 LLM 自觉——模型遵循度差就跑偏。
一图区分
┌─────────────────────────────┐
│ 用户/团队意图 │
└──────────────┬──────────────┘
│
┌──────────────────┴──────────────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ 硬约束载体 │ │ 软约束载体 │
│ │ │ │
│ settings.* │ │ CLAUDE.md │
│ managed-* │ ──── harness ───▶ │ AGENTS.md │
│ .mcp.json │ enforce │ rules/*.md │
│ agents/*.md │ │ harness.md │
│ skills/*.md │ │ SSOT.md, Plans.md│
│ hooks/*.sh │ │ ... │
└──────────────┘ └────────┬─────────┘
│
▼
┌──────────────┐
│ LLM 自觉 │
│ (可绕过) │
└──────────────┘
你截图那 8 条硬约束对应的文件落点
把截图里的清单和上面的文件类型对齐:
| 截图条目 | 承载文件 |
|---|---|
| 1. Hooks |
settings.json (hooks 段) + .claude/hooks/*.sh
|
| 2. Permissions |
settings.json (permissions 段)
|
| 3. Subagent 白名单 |
.claude/agents/*.md 的 frontmatter
|
| 4. Skill 白名单 |
.claude/skills/*/SKILL.md 的 frontmatter
|
| 5. Plan mode | 运行时状态,无文件(CLI 标志 / 用户切换) |
| 6. Sandbox / Permission mode |
CLI 标志 + macOS 的 sandbox-exec
|
| 7. Working directory |
settings.json 的 additionalDirectories
|
| 8. MCP server 权限 |
settings.json 的 mcpServers + .mcp.json
|
| 9. Model |
settings.json 的 model
|
| 10. 环境变量 |
settings.json 的 env
|
所以真正"处理硬约束"的核心就两类文件:
-
settings.json家族(项目 / 用户 / 企业三级 + drop-in) - markdown 的 frontmatter(agents、skills、commands)
harness.md 那种叙述性文档,不管名字起得多硬,只要是正文给 LLM 看,就是软的。
如果你想给项目加一道真正的"防线",编辑面只有:
.claude/settings.json ← deny 列表 + hook 拦截 + MCP 权限
.claude/hooks/*.sh ← 自定义拦截逻辑(prettier、阻断 main 分支等)
.claude/agents/*.md ← 每个 subagent 用 frontmatter 锁工具
.mcp.json ← MCP 服务器接入点收紧
版权属于:BLOG DEWEBSTUDIO 本文作者:狒狒
原文地址: http://blog.dewebstudio.com/?post=159
版权声明:转载时必须以链接形式注明原始出处及本声明。
继续浏览:

发表评论