循环与 Harness 工程:7 个文件、5 个步骤,所有配置都在里面

Loop and Harness engineering: 7 files, 5 steps. Every config inside

中文译文 · 17k 字

一句话摘要

循环与 Harness 工程的完整配置

Loop 与 Harness 工程:7 个文件,5 个步骤。所有配置都在这里 2026年6月28日 · 13 分钟阅读 · 查看原文 ↗ Claude MCP 广告 AI 大多数构建者都在和 loop 作斗争。loop 本身没问题。是它底下的文件夹没搭好。 打开任何一个能正常工作的 Claude Code 项目里的 .claude/,你会找到大约七样东西在真正干活:CLAUDE.md、settings.json、hooks/、agents/、skills/、.mcp.json,以及一个像 MEMORY.md 这样的状态文件。 大多数构建者只打开过其中一个文件。也许两个。这就是为什么他们的 loop 在第三次迭代就卡住了。 读完这篇文章,你会知道每个文件做什么、架在上面的五个 loop 步骤、扼杀大多数首次尝试的三种失败模式,以及今晚就该加上去的那一个文件。 没有框架。没有订阅。一次带精确路径和精确内容的走查。 Harness 是地板。先把它浇好。 两层,一套配置 Harness 就是 .claude/ 文件夹。它在两次运行之间不变。 Loop 是在它里面运行的东西:一个目标、一个动作、一个验证步骤、一次记忆写入,以及一个"继续还是停止"的决定。 Harness 是厨房。Loop 是菜谱。 没有对方,两者都会失败。没有菜谱的厨房是闲置的空间。没有厨房的菜谱是痴心妄想。 大多数构建者把整件事当成一团("我的智能体配置"),从而忽略了失败其实发生在不同的层。 Token 爆炸、提示词疲劳、权限被丢弃:Harness 的问题。永不收敛的 loop、验证放行垃圾、定时运行漂移:loop 的问题。 给层命名,就能修正诊断。当真正的 bug 是一个缺失的权限时,你就不会再重写提示词了。 我原以为先搭 loop 会教会我哪些 Harness 文件是需要的。事实恰恰相反。 Harness 决定了每一次迭代被允许做什么。权限决定 loop 能否写入磁盘。子智能体决定验证是否在一个干净的上下文中运行。 技能决定 loop 能否专业化。钩子(hooks)决定 loop 是否能在你想要的那个触发器上被触发。 没有锁定这些决策,loop 就只能靠猜。当 loop 靠猜时,它就会编造:编造文件、编造命令、让什么都测不出来的测试通过。 Harness 终止了猜测。所以顺序永远是 Harness 优先,loop 其次。 Harness,逐个文件 CLAUDE.md Claude Code 每次启动时读取的第一个文件。它的内容会成为整个会话的常驻上下文。 把项目的形态放在里面:目录布局、语言和框架、真正能用的命令、智能体必须遵守的约定,以及一份明确的"不得做"清单。 放在仓库根目录,而不是埋在 docs 里。最小可用形态: # Project: my-app Stack: Next.js 14, TypeScript, Postgres, Tailwind. Layout: `app/` (routes), `lib/` (helpers), `db/migrations/`. ## Commands - `pnpm dev` - local - `pnpm test` - vitest - `pnpm db:migrate` - apply migrations ## Never - Edit `db/migrations/*` after merge. - Add deps without justification in the PR body. - Bypass `lib/auth/` to access user data. 这里的陷阱是臃肿。论文《Less Context, Better Agents》(arXiv 2606.10209)测得,仅仅因为常驻上下文过大,任务完成率就从 91.6% 掉到了 71%。 保持在 300 行以内。每周修剪一次。每增加一段话,都是对未来每一轮对话的一笔税。 权威参考是 centminmod/my-claude-code-setup,它并排放了三个可用的 CLAUDE.md 形态。 settings.json 工具允许清单、环境变量和钩子注册的所在地。 日常工作中两个位置很重要:仓库根目录的 .claude/settings.json 用于仓库级规则,以及 ~/.claude/settings.json 用于你的个人默认值。 作用域层级按 managed > project > local > user 解析,所以 project 总是覆盖 personal。 一个下午就能见效的第一步,是为只读的 Bash 和 MCP 调用加一个 allow 数组: { "permissions": { "allow": [ "Bash(ls:*)", "Bash(git status:*)", "Bash(git diff:*)", "Bash(cat:*)", "Read(*)" ], "deny": [ "Bash(rm -rf:*)", "Bash(git push --force:*)" ] } } 这样,智能体就不会再为每一次 ls、git status、cat 而卡在权限提示上。破坏性操作仍然会被拦截。 完整键位参考:Claude Code docs - Settings。把密钥放在 .claude/settings.local.json 里,并加入 gitignore。 hooks 在工具事件上触发的确定性脚本:PreToolUse 在工具运行前触发,PostToolUse 在之后,Stop 在智能体完成一轮时。 在 settings.json 里用一个匹配模式和一个 shell 命令注册。规范的第一个钩子:一个匹配 Edit|Write 的 PostToolUse,把文件通过 prettier 处理。 { "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ {"type": "command", "command": "npx prettier --write \"$CLAUDE_FILE_PATH\""} ] } ] } } 现在每一次编辑都会以一个已知的状态退出。这是你的策略地板。 没有钩子,每一次运行都是一场"看心情"。让钩子在成功时静默,只在失败时出声。参考:Claude Code docs - Hooks。 subagents 以带 YAML frontmatter 的 markdown 文件形式,存放在 .claude/agents/ 下。主智能体通过 Task 工具调用它们。它们在一个全新的上下文窗口中运行。 最小的验证者(verifier)子智能体: --- name: verifier description: Reviews a diff against the goal spec. Invoke after every code change. model: haiku tools: [Read, Grep, Bash] --- You are a verifier. Read the goal spec in `PROMPT.md`. Read the diff. Return a JSON verdict: {passes: bool, failures: [{line, reason}]}. Do not propose fixes. Do not run code. Do not be polite. 住在创作者上下文里的评审,总是同意它自己。把评审拉进一个全新上下文,就关上了最响亮的失败模式。 参考:wshobson/agents(37K 星标),有 194 个现成形态。想要一个带 11 个命名捷径检查(放宽的测试、吞掉的错误、假重命名)的对抗式验证者,就拉取 moonrunnerkc/swarm-orchestrator。 skills 以包含 SKILL.md(带 YAML frontmatter)的文件夹形式,存放在 .claude/skills/ 下。 渐进式加载:会话开始时,只有名称和描述进入上下文。只有当智能体判定触发器匹配时,完整正文才会加载。 --- name: db-migration-writer description: Writes Postgres migration files for this repo. Use when the user asks to add/alter a table, column, index, or constraint. when_to_use: schema change requested, new feature requires a new column, index missing on a hot query path --- # Steps 1. Read `db/schema.sql` to confirm current state. 2. Write the migration to `db/migrations/NNN_<verb>_<noun>.sql`. 3. Include both up and down. Test with `pnpm db:migrate --dry`. 4. Never touch existing migration files. 这种纪律,让一个五十个技能的库,不至于在每一次提示里都花掉五十个技能的成本。 规范模式:anthropics/skills(155K 星标)。最大号的预构建工具包:affaan-m/ECC(222K 星标)。 三个因为你第三次撞上同一个任务而构建出来的技能,胜过五十个照着教程投机式构建的技能。 MCP 服务器在仓库根目录的 .mcp.json 里声明。模型上下文协议(Model Context Protocol)是让 loop 能调用外部实时工具的规范。 三条规则:只装你当前工作用得上的服务器;对有凭证的工具优先选官方服务器;绝不"以防万一"地装五个。 { "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": {"GITHUB_TOKEN": "${GITHUB_TOKEN}"} }, "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } Anthropic 维护的集合:modelcontextprotocol/servers(87K 星标)。 代码托管集成:github/github-mcp-server(31K 星标)。 实时库文档(解决 API 过时问题):upstash/context7(58K 星标)。 发现索引:punkpeye/awesome-mcp-servers(89K 星标)。 第一个错误,是在你还没有一个记录每次调用的钩子之前,就启用一个带写入权限的服务器。 state 和 memory 第七样东西,也是大多数人直到第三个项目出问题才会跳过的东西。 形态:一个放在已知路径下的 MEMORY.md 索引文件,加上一个存放项目规范的 vault 目录。 ~/.claude/memory/ MEMORY.md # index, links to topic files below user-prefs.md # preferences, terse-vs-verbose, voice project-decisions.md # "we picked Postgres over Mongo on 2026-03-12, here is why" feedback-recent.md # corrections you keep applying ~/vault/ # project canon (does not change session to session) architecture.md api-spec.md post-mortems/ Memory 保存跨会话会变的东西。Vault 保存不会变的东西。 想要生产级的会话压缩(20 万 token 的转录 → 4K token 的复述,而不丢失承重事实):thedotmack/claude-mem(84K 星标)。 这为什么重要的理论:Anthropic 关于上下文工程的论述给这种失败模式起了个名字:上下文腐烂(context rot)。 第一个错误,是把 memory 当成只追加的。每个会话都修剪它,否则它就会变成腐烂本身。 loop,架在 Harness 之上 1. 目标规格 规定"完成"长什么样的外部契约。放在磁盘上,而不是智能体的脑子里。loop 每次迭代都重读它。 命名:PROMPT.md、AGENTS.md 或 AGENT_SPEC.md。重读才是关键。 # Goal Migrate `users.password` from bcrypt to argon2id across the codebase. # Done when - All new password writes use argon2id (`lib/auth/hash.ts`). - Existing bcrypt hashes are rehashed on next successful login. - Test suite green: `pnpm test auth`. # Never touch - `db/migrations/*` already merged. - Anything under `legacy/`. - The session cookie format. # Stop if - More than 3 files outside `lib/auth/` need edits. - A test that already passes starts failing. 没有这个文件,智能体大约三次迭代后就会漂移。最小的可行参考:ghuntley/how-to-ralph-wiggum(1.7K 星标)——一个 PROMPT.md 加上一个 loop 就地更新的 IMPLEMENTATION_PLAN.md 状态文件。 当规格缺失时,失败看起来像进展。代码写出来了,测试通过了,但它解决的目标不是你的。 2. Plan 到 Act 到 Verify 最小的可行 loop 是三步。智能体针对目标规格做规划,然后执行,随后一个独立的验证环节在允许开始下一次迭代之前检查结果。 每次迭代都用全新上下文,这是 Ralph 模式。状态存在磁盘上的规格文件加一个持续日志里。 #!/usr/bin/env bash # minimal loop runner: fresh context each turn, state on disk set -euo pipefail while true; do # plan + act in fresh context claude -p "Read PROMPT.md, IMPLEMENTATION_PLAN.md. Do the next step. Commit on green." # verify in fresh context (different subagent) if claude -p "/verify"; then echo "iter ok" else echo "verify failed, will retry" fi # exit when spec says done grep -q "^STATUS: done$" IMPLEMENTATION_PLAN.md && break sleep 5 done 规范模式和 CLI 起点:cobusgreyling/loop-engineering(3K 星标)。 带 verifyCompletion 的生产级 TypeScript 参考:vercel-labs/ralph-loop-agent(805 星标)。 完整可安装的 Plan-to-Work-to-Review-to-Release 循环:Chachamaru127/claude-code-harness(2.9K 星标)。 丢掉验证步骤,自信的垃圾就会复利。每一个错误的输出,都会成为下一次迭代的输入。 3. 子智能体扇出(fan-out) 当一个目标分叉成许多独立的子任务(分析 10 篇文章、修 5 个文件、搜 8 个来源)时,loop 就派生并行子智能体。编排者做综合。 一个臃肿的上下文做不了这个。十个小的可以。 # claude-agent-sdk-python style fan-out from claude_agent_sdk import Agent, run_parallel orchestrator = Agent.load(".claude/agents/orchestrator.md") workers = [Agent.load(".claude/agents/researcher.md") for _ in range(8)] results = run_parallel([ w.run(source=src) for w, src in zip(workers, sources) ]) synthesis = orchestrator.run(inputs=results) Anthropic 关于多智能体研究的工程实践,在其内部评估上相对单智能体基线测得了 +90.2% 的提升。 官方 SDK:anthropics/claude-agent-sdk-python(7.4K 星标)。最重的公开扇出工具包(60+ 智能体类型,314 个 MCP 工具):ruvnet/ruflo(61K 星标)。 跳过扇出,编排者就会溺水。一个塞满十个任务来源材料的上下文,正是触发上下文腐烂的形态。 4. 调度器和持久化 什么在你不在椅子上时触发 loop。cron、launchctl、systemd、一个队列运行器。 调度器被刻意设计得比智能体更笨。如果调度器试图思考(根据状态分支、决定是否跳过),它会静默地失败好几天。 # crontab: run the loop every 30 min, log to disk */30 * * * * cd ~/my-loop && ./run.sh >> logs/$(date +\%Y-\%m-\%d).log 2>&1 或者在 macOS 上作为一个 launchd plist: <key>StartCalendarInterval</key> <dict> <key>Minute</key><integer>0</integer> </dict> <key>WorkingDirectory</key><string>/Users/me/my-loop</string> <key>ProgramArguments</key> <array><string>/bin/bash</string><string>run.sh</string></array> 持久化是另一半。每一次迭代都必须序列化它做了什么、尝试了什么、接下来是什么。否则调度器醒来时,面对的是一个忘了目标的智能体。 把临时会话晋升为定时运行的模式:Kanevry/session-orchestrator。 5. 失败模式 三种失败模式几乎扼杀了每一次首次尝试: (a) 自信的垃圾。验证步骤缺失或太弱。错误的输出被放行,并在迭代间复利。 (b) 上下文腐烂。单个长上下文里,模型退化到超过某个阈值(Anthropic 的术语)。在积累约 20 万 token 的历史后,准确率崩溃。 (c) Ralph Wiggum 循环。同一次迭代重复,因为磁盘上的状态没有记录进展。智能体重新规划它已经完成的那一步。 《Less Context, Better Agents》论文(arXiv 2606.10209)测得:全历史为 71% 的任务完成率,而剪枝加总结为 91.6%,且只用了一小部分 token。 before: single-context loop, 1.48M tokens, 71% completion, three hidden hallucinations per run after: prune-and-summarize loop with verifier subagent, 553K tokens, 91.6% completion, every figure traced moonrunnerkc/swarm-orchestrator 编目了智能体为了假装完成而走的 11 条捷径:放宽的测试、吞掉的错误、假重命名、桩返回值、把删注释当修复。 记住这些名字。你会在你自己的日志里认出它们。 一套完整的最小配置,把七个 Harness 文件接进一个能工作的 loop。项目目录的形态长这样: my-loop/ ├── .claude/ │ ├── CLAUDE.md # standing context for every session │ ├── settings.json # allow array + PostToolUse prettier hook │ ├── agents/ │ │ └── verifier.md # Haiku, reviews diffs in fresh context │ └── skills/ │ └── db-migration-writer/ │ └── SKILL.md # one skill, used three+ times ├── .mcp.json # github MCP, context7 MCP ├── PROMPT.md # goal spec (loop reads each iteration) ├── IMPLEMENTATION_PLAN.md # state file (loop writes each iteration) ├── MEMORY.md # cross-session preferences ├── run.sh # the loop runner (Plan -> Act -> Verify) └── logs/ # persistence, one file per cron tick 接线是单向的。Harness 定义规则,loop 在规则内运行,状态文件把第 N 次迭代连到第 N+1 次。 一次迭代按这个顺序走过七个 Harness 文件和五个 loop 组件:cron 触发 run.sh,run.sh 调用 claude -p。Claude Code 读取 CLAUDE.md 和 settings.json(Harness 1、2),在每一次编辑时应用 PostToolUse 钩子(Harness 3),读取 PROMPT.md 和 IMPLEMENTATION_PLAN.md(loop 步骤 1),做规划和执行(loop 步骤 2),在一个全新上下文中派出验证者子智能体(Harness 4 + loop 步骤 2 验证),把结果写回 IMPLEMENTATION_PLAN.md(loop 步骤 3),如果学到了新偏好就更新 MEMORY.md(Harness 7),退出。Cron 等待下一次触发(loop 步骤 4)。 如果七个 Harness 文件缺了任何一个,某个具体的 loop 步骤就会退化。没有 CLAUDE.md,规划者每次迭代都要重新推导项目形态。没有验证者子智能体,验证步骤发生在主上下文中,永远通过。没有 MEMORY.md,同一个修正会在每个周二被重新应用。 七个 Harness 文件建一次。loop 永远运行。 今晚该做什么 打开你的 .claude/ 文件夹。运行: ls -la .claude/ 数一数文件。 > 如果你什么都没看到、或只有 settings.json,就从 CLAUDE.md 开始。保持在 300 行以内。从 centminmod/my-claude-code-setup 抄一个形态。 > 如果你有 CLAUDE.md 和 settings.json 但没有 agents/,下一步加一个验证者子智能体。把评审从主上下文中抽出来。形态:wshobson/agents。 > 如果你有 agents/ 但没有 skills/,把一个高频任务晋升为技能。就是你这周复制粘贴了三遍的那个提示词。在写你的第一个之前,先从 anthropics/skills 读三个 SKILL.md 文件。 > 如果你七个 Harness 文件都有了但 loop 没跑起来,挑一个重复性工作,写下它的目标规格,在上面架一个 Plan-Act-Verify loop。最接近的可安装起点:Chachamaru127/claude-code-harness。 选定之后,做一件事:在新标签页打开对应的仓库,克隆它。 Harness 是地板。没有它,每一个 loop 都跑在一个洞上。 标签:# X # Claude # MCP # 广告 # AI # 指南 相关文章 如何把 claude + higgsfield MCP 变成一台每天 1 万美元以上的 AI 创意机器。我要拆解的这个创意生产工作流,每周为我的补剂品牌产出 40 多个广告变体。Claude 广告 MCP AI

原文参考:https://maxed.wiki/posts/loop-and-harness-engineering-7-files-5-steps-every-config-inside/ (Maxed.wiki,本页为站内中文整理)