跳到主要内容

Harness Engineering

问题

什么是 AI "Harness"?它和 LLM、Context Engineering 是什么关系?如何设计一个健壮的 Agent 运行时——包括工具注册、权限控制、沙箱隔离、错误恢复、可观测性、Human-in-the-loop?

面试速答版

什么是 AI "Harness"?它和 LLM、Context Engineering 是什么关系? Harness = 把 LLM 包装成真正能干活的 Agent 的「运行时壳层」:

  • LLM 本身只是一个文本输入 → 文本输出的纯函数,没记忆、没工具、不能动手。
  • Harness 在外面套上 Agent Loop、工具注册、权限、Sandbox、记忆、Hooks、Human Gate,才能真正做事。
  • 三者分工:LLM 是大脑Context Engineering 决定它能看到什么Harness 决定它能做什么、做到哪步。Claude Code、Cursor、Copilot Agent Mode、Devin 都是 Harness 产品。

如何设计一个健壮的 Agent 运行时? 按 7 个核心模块对号入座:

  • Agent Loop:Think → Act → Observe 循环,控制最大轮次、超时、Token 预算。
  • Tool Registry:工具要原子、idempotent、参数明确、错误信息清晰,否则 LLM 用不好。
  • 权限模型:read-only / sandboxed-write / privileged 三档,写操作默认拒绝、白名单准入。
  • Sandbox:危险操作走 Docker / Firecracker microVM 或浏览器 WebContainer,杜绝逃逸。
  • 错误恢复:工具失败把报错原文给 LLM,让它自己重试或换路径,但要限重试次数。
  • 可观测性:每步记 trace(prompt / tool / 输入输出 / token / 耗时),方便回放和复盘。
  • Human-in-the-loop:发邮件、删文件、上线部署等高风险操作必须走人工 Gate。

答案

一、什么是 Harness

LLM 本身只是一个"文本输入 → 文本输出"的函数。它没有记忆、没有工具、不能执行代码、不能读文件、不能持久化。把 LLM 变成一个真正能做事的 Agent,需要在它外面套一层「运行时壳层」——这就是 Harness

知名的 Harness 产品

  • Claude Code — Anthropic 官方 CLI Harness
  • Cursor / Windsurf — IDE 内嵌 Harness
  • GitHub Copilot Agent Mode — VS Code Chat Harness
  • Devin / Cognition — 云端 Agent Harness
  • 开源AiderContinueOpenHands

和 Context Engineering 的关系

  • Context Engineering 决定 AI "能看到什么"(上下文的构成)
  • Harness Engineering 决定 AI "能做什么"(工具、权限、沙箱)
  • 两者正交,共同决定 Agent 的能力边界

二、Agent Loop:Think-Act-Observe

现代 Agent 的核心都是一个循环:

关键点

  • 一次 LLM 调用只做"一步"(思考+最多一个工具调用),不是一次完成所有事
  • Harness 决定循环何时停止(通常看 LLM 是否返回 tool_use 还是 text)
  • 每轮都要把工具结果喂回 LLM,形成 ReAct 模式(Reason → Act → Observe)

最小 Harness 伪代码

minimal-harness.ts
async function runAgent(task: string) {
const messages: Message[] = [
{ role: 'user', content: task },
];

while (true) {
const response = await llm.complete({
messages,
system: SYSTEM_PROMPT,
tools: TOOL_SCHEMAS,
});

messages.push({ role: 'assistant', content: response.content });

// 检查是否有工具调用
const toolCalls = response.content.filter(c => c.type === 'tool_use');
if (toolCalls.length === 0) {
// 没有工具调用,Agent 认为任务完成
return response.text;
}

// 执行每个工具调用
for (const call of toolCalls) {
// 1. 权限检查
const permission = await checkPermission(call);
if (permission === 'deny') {
messages.push({ role: 'tool_result', tool_use_id: call.id, content: 'Permission denied' });
continue;
}
// 2. 运行 Hook
await runHook('PreToolUse', call);
// 3. 执行工具(在沙箱内)
const result = await sandbox.execute(call);
// 4. 运行 Hook
await runHook('PostToolUse', call, result);
// 5. 附加结果
messages.push({ role: 'tool_result', tool_use_id: call.id, content: result });
}
}
}

三、工具设计(Tool Design)

工具是 Agent 的"手"。工具设计决定 Agent 能力的上限。

好工具的 5 个特征

特征说明反例
单一职责一个工具做一件事do_everything(action, args)
结构化参数JSON Schema 清晰定义❌ 一个 prompt string 塞所有意图
可预测结果输入相同输出相同(幂等)❌ 每次返回随机字段
错误即返回用返回值表达错误,而非抛异常❌ 抛异常中断 Agent
返回简洁只返回必要信息❌ 返回整个原始 JSON

Claude Code 内置工具精华分析

Claude Code 的内置工具集经过精心打磨,可以作为教科书参考:

// 1. Read — 读文件
{
name: 'Read',
parameters: {
file_path: 'absolute path',
offset: 'start line', // 大文件分段读
limit: 'lines to read',
}
}

// 2. Edit — 精确编辑(不是全量覆盖)
{
name: 'Edit',
parameters: {
file_path: '...',
old_string: '...', // 必须精确匹配
new_string: '...',
replace_all: false,
}
}
// 设计亮点:强制先 Read 再 Edit,old_string 必须唯一匹配

// 3. Grep — 基于 ripgrep
// 支持 glob 过滤、context 行、多种输出模式
// 设计亮点:绕过 shell,参数结构化不会被注入

// 4. Bash — 执行命令
// 设计亮点:有 timeout、支持后台运行、有黑名单

// 5. Task — 委派子任务(Subagent)
// 设计亮点:子 Agent 独立上下文,不污染主 Agent

共同特征:参数都是结构化 JSON,不让模型自己构造字符串。

反例:让模型"裸写"命令

// ❌ 差的设计
{
name: 'run_command',
parameters: { command: 'string' },
}
// 问题:
// - 命令注入风险(模型拼接字符串)
// - 无法做精确权限控制(白名单只能做粗粒度)
// - 错误处理困难

// ✅ 好的设计
{
name: 'git_commit',
parameters: {
message: 'string',
files: 'array of paths',
amend: 'boolean',
},
}
// - 参数明确,易校验
// - 权限精确(按工具授权)
// - 错误可回传具体原因

MCP:工具标准化协议

MCP(Model Context Protocol) 是 Anthropic 主推的工具标准。它让工具和 Harness 解耦:

  • 工具开发者实现一个 MCP Server(Node/Python/任意语言)
  • Harness(Claude Code、Cursor 等)作为 MCP Client 通过 stdio/HTTP 连接
  • 任何 MCP-compatible Harness 都能复用这套工具

企业内部的领域工具都应该做成 MCP Server——前端、后端、移动端的 AI 工具就能共享。详见 MCP 协议

四、权限模型(Permission Layer)

Agent 能做什么由权限决定。好的权限模型要在"够用"和"安全"之间平衡

三种典型权限模式

模式说明适用
Strict(严格)每个工具调用都要用户确认生产环境、涉外操作、新手
Auto(自动)白名单内自动执行,黑名单拦截日常编码、沙箱环境
Plan(计划)只能读不能写,先出计划给用户确认大型重构、探索未知代码库

Claude Code 的权限模式示例:

.claude/settings.json
{
"permissions": {
"allow": [
"Read(**)",
"Grep(**)",
"Glob(**)",
"Bash(pnpm install)",
"Bash(pnpm lint*)",
"Bash(pnpm test*)",
"Bash(git status)",
"Bash(git diff:*)"
],
"ask": [
"Edit(**)",
"Write(**)",
"Bash(git commit:*)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(sudo *)",
"Read(.env*)",
"Read(**/*secret*)"
]
}
}

设计原则

  1. 默认最小权限:能不给就不给,用的时候再加
  2. 读多写少:Read/Grep 自动,Edit/Write 问一下
  3. 破坏性操作全黑名单rm -rf--forcesudo
  4. 敏感路径黑名单.envsecrets/.ssh/

Plan Mode(计划模式)

2025 年下半年出现的新模式:Agent 先只读探索,给出行动计划,用户确认后才开始写

适用场景

  • 大型重构(影响超过 10 个文件)
  • 探索未知代码库
  • 高风险改动(数据库迁移、破坏性 API 变更)

YOLO 模式(Auto-Accept)

和 Plan 相反——全自动,不问任何确认。只在以下场景用:

  • 沙箱环境(Docker、worktree)
  • 一次性脚本任务
  • CI/CD 中的 headless 跑批
  • 已知安全的重复操作(如 /gen-tests 为 100 个文件生成测试)
YOLO 的前提

YOLO 必须配合沙箱。在你的主工作区开 YOLO 等于把方向盘交给 AI,出任何问题都没有 undo。

五、沙箱(Sandbox)

沙箱是 Harness 的安全护栏。核心目标是:就算 Agent 做错了,也不会损坏主工作环境

沙箱技术栈

技术隔离级别开销适用
Git Worktree文件系统极低独立分支并行开发
Docker 容器文件系统+进程+网络一次性任务、CI
Firecracker VM完整 VM云端 Agent(Devin 等)
macOS Sandbox (sandbox-exec)文件系统+网络本地实验(Mac)
Linux namespaces文件系统+进程本地实验(Linux)

Git Worktree:最实用的轻量沙箱

# 给 Agent 开一个独立的工作目录
git worktree add ../my-project-agent-task agent/feature-xyz

# Agent 在这个目录里跑,改错了直接删除目录即可
cd ../my-project-agent-task
claude "实现 xxx 功能"

# 如果结果好,合并回来
git worktree remove ../my-project-agent-task
git merge agent/feature-xyz

优点

  • 主工作区完全隔离
  • 多个 Agent 可以并行在不同 worktree 工作
  • 改错了丢弃整个 worktree 即可

Claude Code 的 Agent 工具支持 isolation: "worktree" 参数,自动在独立 worktree 跑子任务。

Docker 沙箱

对于更高隔离需求,用 Docker:

.claude/sandbox/Dockerfile
FROM node:22-slim

RUN apt-get update && apt-get install -y git ripgrep

WORKDIR /workspace
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install

# 限制网络(可选)
# RUN echo "127.0.0.1 example.com" >> /etc/hosts

CMD ["bash"]
dockerized-agent.ts
// 把 Agent 放到 Docker 里跑
const container = await docker.run({
image: 'my-claude-sandbox',
volumes: {
[process.cwd()]: '/workspace',
},
networkMode: 'bridge',
memoryLimit: '2gb',
readOnly: ['/etc', '/usr'],
});

await container.exec(['claude', '-p', task]);

典型约束

  • 限制 CPU/内存
  • 限制网络访问(只允许 npm registry、GitHub)
  • 只读系统目录
  • 定时清理

六、Hooks:生命周期钩子

Hooks 允许在 Agent 的关键节点挂钩子脚本,实现拦截、修改、记录等自动化。

Claude Code 的核心 Hook 事件

事件触发时机可以做什么
SessionStart会话开始注入动态上下文(当前分支、未完成任务)
UserPromptSubmit用户发送消息时敏感词过滤、补充上下文
PreToolUse工具调用前拦截危险命令、审计日志、需要时阻断
PostToolUse工具调用后自动 lint、type check、截图
PreCompact压缩上下文前把关键决策持久化
StopAgent 停止时通知、自动 commit、更新看板
SubagentStopSubagent 结束时聚合结果
NotificationAgent 想通知用户时自定义通知渠道

实战案例

案例 1:PostToolUse 自动 lint/tsc

.claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "pnpm lint --fix $CLAUDE_FILE_PATHS 2>&1 | head -20"
},
{
"type": "command",
"command": "pnpm tsc --noEmit 2>&1 | head -20"
}
]
}
]
}
}

效果:AI 每次改完文件立即看到 lint/type error,下一轮就能自己修。

案例 2:PreToolUse 拦截危险命令

.claude/scripts/audit-bash.sh
#!/bin/bash
# 读取 stdin 中 Claude 要执行的命令
CMD=$(cat)

# 黑名单检查
if echo "$CMD" | grep -qE "(rm -rf /|git push --force|sudo)"; then
echo "DANGER: blocked" >&2
exit 1 # 非零退出码会阻断工具调用
fi

# 审计日志
echo "$(date -Iseconds) | $CMD" >> .claude/audit.log
exit 0

案例 3:SessionStart 注入动态上下文

.claude/scripts/session-start.sh
#!/bin/bash
cat <<EOF
<current_state>
Git 分支:$(git branch --show-current)
未提交改动:$(git status --short | wc -l) 个文件
近期错误日志:
$(tail -20 logs/error.log)
</current_state>
EOF

案例 4:Stop Hook 自动通知

{
"hooks": {
"Stop": [
{ "hooks": [{ "type": "command", "command": "osascript -e 'display notification \"Agent 完成\" with title \"Claude Code\"'" }]}
]
}
}

Hook 的坑

Hook 常见陷阱
  1. 无限循环:Hook 里调用了会触发同类事件的操作
  2. 阻塞主流程:Hook 执行慢(如跑全量 test),Agent 被 block
  3. 安全风险:Hook 能执行任意 shell,写错就是漏洞
  4. 错误处理:Hook 失败时是否应该阻断 Agent?默认通常是不阻断

原则:Hook 只做"快速、幂等、低风险"的事。重活交给 CI。

七、Memory:Agent 的记忆系统

LLM 本身无状态。要让 Agent 有"记忆"(跨会话持久化),需要 Memory 系统。

三级记忆

文件系统式 Memory

最简单也最有效的实现:

.claude/memory/
├── MEMORY.md # 索引
├── user_preferences.md # 用户偏好
├── project_decisions.md # 项目决策记录
├── known_bugs.md # 已知问题
└── current_sprint.md # 当前迭代目标

Harness 设计:

  • SessionStart 时加载 MEMORY.md 的目录
  • Agent 主动用 Read 工具按需读取具体 memory 文件
  • Agent 更新 memory 时用 Edit/Write 工具
  • 所有 memory 提交到 Git,团队共享

详见 Claude Code 的 auto memory 系统设计(Claude Code 内置能力)。

进阶:结构化 Memory

对于更复杂场景(用户数据、任务状态),用数据库:

// 向量数据库 + 关键词索引
interface MemoryEntry {
id: string;
type: 'fact' | 'preference' | 'decision' | 'incident';
content: string;
embedding: number[];
tags: string[];
createdAt: Date;
source: 'user' | 'agent' | 'system';
}

// 注入时:按相关性 top-K 召回
async function loadRelevantMemory(currentTask: string): Promise<MemoryEntry[]> {
const queryEmbedding = await embed(currentTask);
return vectorDB.search(queryEmbedding, { topK: 10 });
}

本质上这是 RAG,只不过知识库是 "Agent 自己过去的经验"

八、错误恢复(Error Recovery)

Agent 跑长任务时,错误是常态:

  • 工具调用超时
  • API 限流
  • 编译报错
  • 测试失败
  • 用户 Ctrl-C 中断

重试策略

retry-tool-call.ts
async function executeTool(call: ToolCall, attempt = 1): Promise<ToolResult> {
try {
return await runTool(call);
} catch (err) {
if (attempt < 3 && isRetryable(err)) {
// 指数退避
await sleep(1000 * 2 ** attempt);
return executeTool(call, attempt + 1);
}
// 把错误作为工具结果返回给 LLM,让它决定下一步
return {
isError: true,
content: `工具调用失败:${err.message}。请考虑替代方案或通知用户。`,
};
}
}

关键原则

  • Retryable 错误(网络、限流、超时):自动重试
  • Non-retryable 错误(语法错误、权限拒绝):把错误当 tool result 喂给 LLM,让它自己决定
  • 不要 throw:异常会打断 Agent Loop,失去自我修复机会

Checkpointing(检查点)

长任务运行时定期保存状态,失败时能恢复:

interface AgentState {
messages: Message[];
toolCallHistory: ToolCall[];
memory: Memory;
step: number;
}

// 每 N 步保存一次
if (step % 10 === 0) {
await fs.writeFile(`.claude/checkpoints/session-${sessionId}-step-${step}.json`, JSON.stringify(state));
}

// 恢复
const latestCheckpoint = await findLatestCheckpoint(sessionId);
const state = JSON.parse(await fs.readFile(latestCheckpoint));

Cursor 的 "Checkpoint" 功能、Claude Code 的 /resume 都是这个机制。

九、Human-in-the-Loop(HITL)

让人类在关键决策点介入。设计要点:

何时请求人工介入

异步 HITL:通知而非阻塞

对于长任务,不要让 Agent 停在那里等人,用通知:

// 需要用户确认时,发通知 + 进入"暂停"状态
await agent.pause({
reason: '需要用户确认生产部署',
notifyChannels: ['slack', 'email'],
});

// 用户回复后恢复
await agent.resume({ decision: 'approved' });

Claude Code 的 AskUserQuestion 工具和 Cursor Background Agent 的通知机制就是这种模式。

十、可观测性(Observability)

Agent 是黑盒。没有可观测性就没办法优化和定位问题。

核心指标

类别指标用途
成本Input/Output tokens、美元花费成本优化
性能TTFT、工具调用耗时、总耗时性能调优
质量任务完成率、错误率、重试次数质量评估
安全权限拒绝次数、危险命令尝试安全审计
行为工具调用频次分布、Skill 命中率理解 Agent 行为

日志规范

structured-log.ts
interface AgentLog {
sessionId: string;
step: number;
timestamp: string;
type: 'llm_call' | 'tool_call' | 'hook' | 'error';
// LLM 相关
model?: string;
inputTokens?: number;
outputTokens?: number;
latencyMs?: number;
// 工具相关
toolName?: string;
toolArgs?: unknown;
toolResult?: { isError: boolean; size: number };
// 错误
error?: { message: string; stack?: string };
}

建议工具

  • Langfuse — 专为 LLM Agent 设计的 observability
  • Helicone — LLM API 监控
  • OpenTelemetry — 通用分布式追踪
  • 自建:结构化 JSON 日志 + Grafana

十一、多 Agent 协作

当任务复杂到单 Agent 搞不定,就需要多 Agent 协作。

模式 1:主从(Orchestrator-Worker)

Main Agent (Orchestrator)
├── 派发子任务 1 → Subagent A
├── 派发子任务 2 → Subagent B
└── 聚合结果

Claude Code 的 Task 工具 就是这种模式。详见 AI 辅助开发 的 Subagents 部分。

模式 2:流水线(Pipeline)

Input → Agent A (分析) → Agent B (生成) → Agent C (审查) → Output

例如:

  • Agent A:从需求文档提取需求点
  • Agent B:根据需求生成代码
  • Agent C:审查生成的代码

模式 3:辩论(Debate)

让多个 Agent 独立得出方案,再对比:

  • 对同一个任务派 3 个 Agent 独立工作
  • 收集 3 份方案
  • 让第 4 个 "仲裁 Agent" 对比择优

适用场景:高风险决策(架构选型、安全审查)。成本高但质量也更高。

模式 4:A2A 协议(跨团队 Agent)

Google Agent-to-Agent Protocol 等协议让不同团队/公司的 Agent 能互相调用。前端 Agent 可以调用后端 Agent 的服务,像调 API 一样。2026 年仍在早期。

十二、Harness 能力清单(设计 Checklist)

设计/评估一个 Harness 时的完整清单:

维度核心能力检查项
Agent Loop支持多轮工具调用✅ 循环终止条件清晰
Tool Registry工具注册 + Schema✅ 支持 MCP
Permission多模式(strict/auto/plan)✅ 白名单+黑名单+通配符
Sandbox文件/进程/网络隔离✅ 支持 worktree / docker
Hooks生命周期事件钩子✅ PreTool / PostTool / Stop
Memory跨会话持久化✅ 文件系统或向量库
Context自动压缩、动态注入✅ Compaction + SessionStart 注入
Error Recovery重试、Checkpoint✅ Retryable 错误自动恢复
HITL人工确认、异步通知✅ 破坏性操作强制确认
Observability日志、指标、追踪✅ 结构化日志 + 成本追踪
Multi-Agent子代理、流水线✅ 至少支持 Subagent
Extensibility插件化、可配置✅ Skills / Custom Commands

常见面试问题

Q1: Harness 和 LLM 是什么关系?为什么需要 Harness?

答案

LLM 本身只是"文本输入 → 文本输出"的函数。它:

  • 没有记忆(每次调用都是独立的)
  • 不能执行代码
  • 不能读写文件
  • 不能调用外部 API
  • 不能持久化任何状态

要把 LLM 变成真正能干活的 Agent,必须在它外面套一层运行时壳层——Harness。Harness 提供:

  1. Agent Loop:反复调用 LLM 形成"思考-行动-观察"循环
  2. 工具注册和执行:让 LLM 能"用手"
  3. 权限控制:决定 Agent 能做什么
  4. 沙箱隔离:防止 Agent 误操作损坏环境
  5. 记忆系统:跨会话的持久化
  6. 可观测性:日志、指标、成本追踪

Claude Code、Cursor、Copilot、Devin 本质上都是 Harness 的不同实现,底层都调用相同的 LLM。Harness 的质量往往比 LLM 的版本更决定 Agent 的能力上限

Q2: Agent Loop 是什么?怎么实现最小版本?

答案

Agent Loop 是 Think-Act-Observe 循环

LLM 输出 → 有工具调用?
├─ 是 → 执行工具 → 结果喂回 LLM → 继续循环
└─ 否 → 返回最终回复给用户

最小实现大概 30 行代码:

async function runAgent(task: string) {
const messages = [{ role: 'user', content: task }];
while (true) {
const response = await llm.complete({ messages, tools: TOOL_SCHEMAS });
messages.push({ role: 'assistant', content: response.content });

const toolCalls = response.content.filter(c => c.type === 'tool_use');
if (toolCalls.length === 0) return response.text;

for (const call of toolCalls) {
const result = await executeToolWithPermission(call);
messages.push({ role: 'tool_result', tool_use_id: call.id, content: result });
}
}
}

关键点

  • 一次 LLM 调用只推进一步(不要强行一次完成所有)
  • 错误要转成 tool result 喂回 LLM(不要 throw 打断 Loop)
  • Loop 终止看 LLM 是否还在调用工具

Q3: 好工具和差工具的区别?

答案

好工具 5 个特征:

特征好例子坏例子
单一职责git_commit(message, files)do_git(action, args)
结构化参数明确 JSON Schema一个 prompt string 塞所有意图
可预测输入相同输出相同每次返回格式不一致
错误即返回{ isError: true, content: "..." }直接抛异常中断 Agent
返回简洁只返回关键字段返回整个原始 JSON 几万 token

反例:很多早期 Harness 提供 run_command(cmd: string) 这种"裸写命令"工具——参数是一个自由字符串,结果:

  • 模型要自己拼接命令(易错)
  • 难做精确权限控制
  • 容易被注入

正解:用结构化参数把意图明确化,如 git_commit({ message, files, amend })

Q4: 权限模型应该怎么设计?

答案

三种模式组合使用:

模式说明适用
Strict每个工具都问新手、生产、涉外操作
Auto白名单自动、黑名单拒绝日常编码
Plan只读探索、出计划、人审、再执行大型重构

核心原则

  1. 默认最小权限:能不给就不给
  2. 读多写少:Read/Grep 自动,Edit 问一下
  3. 破坏性操作全黑名单rm -rf--forcesudo
  4. 敏感路径黑名单.envsecrets/

Claude Code 的 settings.json 是参考实现:

{
"permissions": {
"allow": ["Read(**)", "Grep(**)", "Bash(pnpm test*)"],
"ask": ["Edit(**)", "Write(**)"],
"deny": ["Bash(rm -rf *)", "Bash(sudo *)", "Read(.env*)"]
}
}

Q5: 什么是 Plan Mode?什么时候用?

答案

Plan Mode 是 2025 年下半年出现的新模式:Agent 先只读探索,出一份详细的行动计划,人审批后才切换到"可写模式"开始执行。

流程

用户给任务 → Agent 进入 Plan Mode(只读)
→ Agent 扫描代码、设计方案
→ 输出 N 步执行计划
→ 用户审核/修改
→ 切换到执行模式
→ 按计划执行

适用场景

  • 大型重构(影响超过 10 个文件)
  • 迁移/升级(Pages Router → App Router)
  • 探索未知代码库
  • 高风险改动(数据库迁移、破坏性 API)

为什么好:避免 "Agent 乱写一通,改了 50 个文件结果方向错误" 这种灾难。计划阶段发现方向错误,代价几乎为零。

Q6: Sandbox 有哪些实现?什么场景用什么?

答案

技术隔离程度开销适用
Git Worktree文件系统极低本地多 Agent 并行
Docker 容器文件+进程+网络一次性任务、CI
Firecracker VM完整 VM云端 Agent(Devin 级)
sandbox-exec (macOS)文件+网络本地 macOS 实验
Linux namespaces文件+进程本地 Linux 实验

日常开发最推荐 Git Worktree

git worktree add ../project-task-xyz agent/feature
cd ../project-task-xyz
claude "实现 xxx"
# 做完合并或删除 worktree

优点:主工作区 100% 隔离、Agent 改错直接丢弃、支持多个 Agent 并行。

YOLO 模式必须配沙箱:没有沙箱就开 YOLO,等于把方向盘交给 AI,一个 rm -rf 就能删光代码。

Q7: Hooks 能做什么?有哪些常见陷阱?

答案

Hooks 是 Agent 生命周期事件的回调,允许拦截、修改、记录 AI 行为。

主要 Hook 事件

事件用途
SessionStart注入动态上下文(Git 状态、任务看板)
UserPromptSubmit敏感词过滤、补充上下文
PreToolUse拦截危险命令、审计
PostToolUse自动 lint、type check
Stop通知、自动 commit

实战案例

  1. PostToolUseEdit|Write 自动跑 pnpm lint --fix && pnpm tsc --noEmit,让 AI 立即看到错误
  2. PreToolUse 对 Bash 命令做黑名单检查,拦截 rm -rf /git push --force
  3. SessionStart 注入当前分支、最近错误日志

常见陷阱

  • 无限循环:Hook 触发的操作又触发同类事件
  • 阻塞主流程:Hook 慢,Agent 被 block(比如跑全量 test)
  • 安全风险:Hook 能执行任意 shell,写错就是漏洞

原则:Hook 只做快速、幂等、低风险的事。重活交给 CI。

Q8: Agent 的 Memory 怎么设计?

答案

三级记忆:

  1. 短期:当前上下文窗口(会话内)
  2. 中期:通过 Compaction 压缩保留的会话摘要
  3. 长期:跨会话持久化

最简实现:文件系统

.claude/memory/
├── MEMORY.md # 索引
├── user_preferences.md # 用户偏好
├── project_decisions.md # 项目决策
└── known_bugs.md # 已知问题
  • SessionStart Hook 加载 MEMORY.md 目录
  • Agent 按需用 Read 工具读具体文件
  • Agent 用 Edit/Write 工具更新
  • 全部 Git 版本管理,团队共享

进阶:向量数据库

当 Memory 条目太多(几百条以上),用 embedding + 向量检索:

const queryEmbedding = await embed(currentTask);
const relevant = await vectorDB.search(queryEmbedding, { topK: 10 });
// 把相关的 memory 塞进上下文

本质上这是 RAG,知识库是 Agent 自己过去的经验

Q9: Agent 长任务跑崩了怎么恢复?

答案

两个关键机制:

1. 错误容忍(不 throw)

工具错误应该作为 tool_result 喂回给 LLM,让 AI 自己决定怎么办:

try {
return await runTool(call);
} catch (err) {
// 不要 throw,转成 tool result
return { isError: true, content: `失败:${err.message}` };
}
  • Retryable 错误(网络、限流):自动重试 + 指数退避
  • Non-retryable 错误(语法错、权限拒绝):喂回给 LLM,它可以尝试替代方案

2. Checkpointing(检查点)

长任务定期保存状态,失败时能恢复:

// 每 N 步保存一次 AgentState
if (step % 10 === 0) saveCheckpoint(sessionId, step, state);

// 恢复
const state = loadLatestCheckpoint(sessionId);

Cursor 的 Checkpoint、Claude Code 的 /resume 都是这个机制。

Q10: 多 Agent 协作有哪些常见模式?

答案

4 种模式:

1. 主从(Orchestrator-Worker)

主 Agent 派发子任务给 Subagent,收集结果。典型场景:大型搜索(主 Agent 派 Subagent 扫描代码库,只回传结论)。Claude Code 的 Task 工具就是这种。

2. 流水线(Pipeline)

需求分析 Agent → 代码生成 Agent → 审查 Agent

每个 Agent 专精一件事。适合有明确阶段划分的任务。

3. 辩论(Debate)

多个 Agent 独立给出方案,仲裁 Agent 对比择优。适合高风险决策(架构选型、安全审查)。成本高但质量好。

4. A2A 协议(跨组织 Agent)

Google A2A、Anthropic MCP 等协议让不同团队/公司的 Agent 互相调用。2026 年还在早期。

选型建议

  • 日常开发用主从(Subagent)足够
  • 高风险决策用辩论
  • 复杂多阶段用流水线

Q11: 怎么给 Agent 加可观测性?

答案

5 大维度指标:

类别指标用途
成本Input/Output tokens、美元成本优化
性能TTFT、工具耗时、总耗时性能调优
质量完成率、错误率、重试次数质量评估
安全权限拒绝次数、危险命令尝试安全审计
行为工具调用频次、Skill 命中率行为分析

工具选型

  • Langfuse — 专为 LLM Agent 设计,开源可自部署
  • Helicone — LLM API 监控
  • 自建:结构化 JSON 日志 + Grafana

核心日志结构

interface AgentLog {
sessionId: string;
step: number;
type: 'llm_call' | 'tool_call' | 'hook' | 'error';
model?: string;
inputTokens?: number;
outputTokens?: number;
latencyMs?: number;
toolName?: string;
toolArgs?: unknown;
error?: { message: string; stack?: string };
}

最小实践:每次 LLM 调用和工具调用打一条结构化日志(JSONL),用 Grafana/Loki 分析,基本够用。

Q12: 评估一个 Harness 好不好的关键指标?

答案

设计/选型 Harness 看 12 个能力点:

  1. Agent Loop 循环终止清晰、支持多轮工具调用
  2. Tool Registry 结构化 schema、支持 MCP
  3. Permission 多模式(strict/auto/plan)、白+黑名单
  4. Sandbox 支持 worktree/docker/VM
  5. Hooks PreTool/PostTool/Stop 等事件完备
  6. Memory 跨会话持久化
  7. Context 管理 自动 Compaction + 动态注入
  8. Error Recovery 重试 + Checkpoint
  9. HITL 人工确认 + 异步通知
  10. Observability 结构化日志 + 成本追踪
  11. Multi-Agent 至少支持 Subagent
  12. Extensibility Skills / Custom Commands / 插件化

业界对比

  • Claude Code — 12 项全满,开源 SDK 可自建
  • Cursor — IDE 体验最好,Sandbox/Hook 较弱
  • Copilot — 企业生态好,自定义能力弱
  • Aider / OpenHands — 开源、可魔改

相关链接