Tips & Tricks (更新: 2026/6/3)

Harness 工程完全指南:用 Claude Code 构建 AI Agent

用 Claude Code 讲清 harness engineering:工具、上下文、权限、验证、Node.js 示例和真实 workflow。

Harness 工程完全指南:用 Claude Code 构建 AI Agent

只会写 prompt,已经不足以做好 AI Agent。2026 年真正重要的能力,是 harness engineering:为模型搭好可以工作的脚手架。这里的 harness 可以理解为“agent scaffold”,也可以类比软件测试里的 test harness:它负责把模型、工具、上下文、权限、验证和循环控制接在一起。

Claude Code 是学习这件事的好样本。它不是一个单纯聊天框,而是把文件读取、编辑、shell 命令、CLAUDE.md、hooks、权限模式、subagent 和记忆系统组合成一个工作环境。本文会从零解释为什么 harness engineering 变热,给出可复制运行的 Node.js mini harness 和 policy JSON,并用 content automation、code review、SaaS integration、cloud operations、security boundaries 五个 use case 说明如何落地。

为什么 harness engineering 正在变热

LLM 很擅长“决定下一步说什么”,但真实工作不止是生成文字。一个可靠的 agent 需要观察环境、选择输入、调用工具、处理失败、保留证据、限制危险操作,并把结果交付成文件、PR、报告或线上页面。模型本身只解决了其中一部分。

Claude Code 的趋势价值就在这里。Claude Agent SDK 官方文档说明,它可以读取 Claude Code 风格的项目指令、skills、hooks 和 permissions;权限文档解释了 allow、deny、permission mode 和运行时回调;prompt caching 文档说明如何复用长的固定上下文。这些都不是“更会写 prompt”,而是模型外层的工程系统。

用 OODA loop 看会更清楚:

阶段内容主要负责人
Observe读取文件、日志、URL、ticket、API 状态Harness
Orient压缩信息、组织上下文、过滤噪声Harness
Decide判断下一步行动LLM
Act执行工具、写文件、调用 API、停止Harness

四个阶段里有三个主要由 harness 负责。模型再强,如果脚手架薄弱,agent 也会不稳定。

一个 harness 应该包含什么

实用的 harness 会在任务开始前回答四个问题:允许读取什么?产物是什么?成功由什么验证?哪些动作自动执行,哪些必须 ask-first,哪些永远禁止?

以博客 workflow 为例,不能只写“生成文章”。更完整的 harness 是:读取已有 slug,选择不重复的主题,写 MDX,检查 frontmatter,验证 code fence,加入官方链接和内部链接,放入 /products//training/ 的转化 CTA,运行构建,查看公开 URL。prompt 只是其中一个输入。

例子pitfall
上下文项目规则、写作风格、历史失败旧前提长期残留
工具read、grep、write、test、API 调用工具太多或职责太宽
策略allow、ask、deny、rate limit、sandbox破坏性操作无人值守
验证test、diff、截图、公开 URL产物看似合理但已损坏
记忆可复用偏好和决策临时备注变成永久规则

概念图

harness 是模型前后的控制层。prompt 很重要,但 policy、context、tools、permission gate 和 verification loop 才决定 workflow 是否可靠。

flowchart LR
  A["Goal"] --> B["Harness policy"]
  B --> C["Context"]
  B --> D["Tools"]
  B --> E["Permissions"]
  C --> F["LLM decision"]
  D --> F
  E --> G["Safe action"]
  F --> G
  G --> H["Verification"]
  H --> I["Artifact"]
  H --> B

可运行的 Node.js mini harness

下面的最小例子包含模型、两个工具、policy、循环、路径边界和可读错误。先设置 ANTHROPIC_API_KEY,再在临时目录运行:

mkdir harness-demo
cd harness-demo
npm init -y
npm install @anthropic-ai/sdk
node -e "const fs=require('node:fs');fs.mkdirSync('sandbox',{recursive:true});fs.writeFileSync('sandbox/README.md','# Demo\nShip a safer agent workflow.\nKeep writes inside sandbox.\n');"

保存 policy.json

{
  "workspace": "./sandbox",
  "maxSteps": 6,
  "tools": {
    "read_file": {
      "allow": true,
      "risk": "Read UTF-8 text only inside workspace"
    },
    "write_file": {
      "allow": true,
      "risk": "Write UTF-8 text only inside workspace"
    }
  }
}

保存 mini-harness.mjs

import Anthropic from "@anthropic-ai/sdk";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";

const client = new Anthropic();
const policy = JSON.parse(await readFile(new URL("./policy.json", import.meta.url), "utf8"));
const model = process.env.ANTHROPIC_MODEL || "claude-sonnet-4-6";
const workspace = path.resolve(policy.workspace);

function safePath(requestedPath) {
  const resolved = path.resolve(workspace, requestedPath);
  const inside = resolved === workspace || resolved.startsWith(workspace + path.sep);
  if (!inside) {
    throw new Error(`Path escapes workspace: ${requestedPath}. Use a path under ${policy.workspace}.`);
  }
  return resolved;
}

function ensureAllowed(toolName) {
  const rule = policy.tools?.[toolName];
  if (!rule?.allow) {
    throw new Error(`Tool '${toolName}' is not allowed by policy.json.`);
  }
}

const tools = [
  {
    name: "read_file",
    description: "Read a UTF-8 text file from the allowed workspace.",
    input_schema: {
      type: "object",
      properties: { path: { type: "string" } },
      required: ["path"],
      additionalProperties: false
    }
  },
  {
    name: "write_file",
    description: "Write a UTF-8 text file inside the allowed workspace.",
    input_schema: {
      type: "object",
      properties: {
        path: { type: "string" },
        content: { type: "string" }
      },
      required: ["path", "content"],
      additionalProperties: false
    }
  }
];

async function executeTool(name, input) {
  ensureAllowed(name);
  if (name === "read_file") {
    return await readFile(safePath(input.path), "utf8");
  }
  if (name === "write_file") {
    const target = safePath(input.path);
    await mkdir(path.dirname(target), { recursive: true });
    await writeFile(target, input.content, "utf8");
    return `written ${input.path}`;
  }
  throw new Error(`Unknown tool: ${name}`);
}

async function run(goal) {
  const messages = [{ role: "user", content: goal }];

  for (let step = 0; step < policy.maxSteps; step++) {
    const response = await client.messages.create({
      model,
      max_tokens: 1200,
      tools,
      system: "You are a careful file assistant. Use tools when needed. Keep writes under policy workspace.",
      messages
    });

    messages.push({ role: "assistant", content: response.content });
    const toolUses = response.content.filter((block) => block.type === "tool_use");

    if (toolUses.length === 0) {
      const text = response.content
        .filter((block) => block.type === "text")
        .map((block) => block.text)
        .join("\n");
      console.log(text);
      return;
    }

    const results = [];
    for (const toolUse of toolUses) {
      try {
        const output = await executeTool(toolUse.name, toolUse.input);
        results.push({ type: "tool_result", tool_use_id: toolUse.id, content: String(output).slice(0, 8000) });
      } catch (error) {
        results.push({
          type: "tool_result",
          tool_use_id: toolUse.id,
          is_error: true,
          content: error instanceof Error ? error.message : String(error)
        });
      }
    }
    messages.push({ role: "user", content: results });
  }

  throw new Error(`Max steps reached: ${policy.maxSteps}`);
}

const goal = process.argv.slice(2).join(" ") || "Read README.md and write summary.md with three bullet points.";
await run(goal);

运行:

node mini-harness.mjs

这个例子很小,但已经具备核心结构:工具 schema、policy、sandbox 路径、最大步数、可读错误、具体产物。继续加入 grep、测试命令、approval UI、SaaS API 和 hooks,就会接近 Claude Code 的工作方式。

五个具体 use case

1. content automation 薄弱的 prompt 是“写一篇博客”。强 harness 会读取已有文章,避免重复主题,生成 MDX,检查 frontmatter、code fence、内部链接、官方链接、OGP 图像和 /products//training/ CTA,再构建并检查公开页面。pitfall 是为了发布速度牺牲原创视角,最后得到大量浅翻译。

2. code review PR review harness 应读取 git diff、测试输出、变更文件和项目规范,并强制 findings-first:先列 bug、risk、回归和缺失测试,再给摘要。pitfall 是模型只复述改动,看起来礼貌却没有发现问题。

3. SaaS integration Notion、HubSpot、Stripe、CRM 这类场景必须拆成 read-only、dry-run、approved write。比如读取咨询线索、分类、生成 CRM 更新草稿,最后由人确认写入。risk 是误分类的客户、账单或备注被直接写进生产系统。

4. cloud operations 云操作不是一条 deploy 命令。harness 应检查环境变量、build、diff、目标环境、rollback 方案、health endpoint 和公开 URL。pitfall 是模型只看日志最后一行,改错根因。限制重试次数和日志压缩非常重要。

5. security boundaries 安全边界不是最后补丁。Read 可以相对宽,Write 必须限制在 workspace,shell 命令要 allow-list,rm、force push、生产 DB、账单设置、secret 读取要 deny 或 ask-first。harness 是为了避免过度信任模型。

从 Claude Code 借鉴什么

第一,分层上下文。稳定项目规则放进 CLAUDE.md 或等价配置;本次任务进 plan;长期偏好进 memory。这样不会让临时决策污染长期行为。

第二,把确定性检查交给 hooks。format、lint、test、链接检查、截图验证应该由命令完成,Claude 负责解释失败和提出修复。

第三,隔离噪声。长日志、广泛搜索、多语言翻译和大型重构可以交给 subagent 或独立阶段。主上下文应该保留决策,而不是堆满中间过程。

常见 pitfall

工具太多会让模型选择困难。先从 5 到 10 个清晰工具开始。

错误不可读会阻止自我修复。不要返回 Error: failed,要说明缺少什么、在哪里、下一步可以尝试什么。

忽略 prompt caching 会增加延迟和成本。固定长上下文要与动态上下文分开。

没有验证会让“看起来正确”的产物上线。文章要检查 frontmatter 和 code fence,代码要跑测试,云操作要查 health check,SaaS 写入要有审计日志。

权限会漂移。临时方便很容易变成永久风险,所以 allow、ask、deny 规则要定期复查。

下一步

如果你要先做安全边界,请读 Claude Code 权限指南。要整理项目知识,读 CLAUDE.md 最佳实践。需要拆分重任务,读 Claude Code subagent 模式。关注成本时,再看 Claude Code token 优化

想快速查命令,可以保留免费的 Claude Code Quick Reference Cheatsheet。需要模板、工作流和产品化材料时,从 /products/ 开始。团队如果要一起设计权限、review gate、发布验证和收入转化路径,可以从 /training/ 发起咨询。

我实际验证到的结果

在 ClaudeCodeLab 的文章流程里,harness 最大的价值不是让 AI 写得更像人,而是让失败更可见。只靠 prompt 可以生成一篇文章;加入 harness 后,可以知道正文是否足够、code fence 是否闭合、frontmatter 是否正确、链接是否存在、CTA 是否完整、公开 URL 是否能打开。这样运营一个多语言内容站,风险会小很多。

总结

Harness engineering 是设计“模型能看什么、能做什么、在哪里停下、如何验证”的工程能力。Claude Code 之所以值得学习,不只是因为模型强,而是因为它把工具、上下文、权限和验证做成了可运行的脚手架。先运行上面的 mini harness,再为自己的 use case 加一个边界和一个检查点,就是最稳的开始。

参考链接

#claude-code #agent-sdk #harness #prompt-engineering #llm #anthropic
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

把 Claude Code 变成真正能带来结果的工作流

先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。