Agent Harness工程 - 从最小循环到生产运行时
Agent Harness 工程:从最小循环到生产运行时
先解释标题里的词:Harness 原意是马具,在 Agent 工程里指包在大模型外面的那一整套运行时代码,负责把用户输入、工具调用、权限检查、上下文管理串起来。
模型只负责”想”,Harness 负责让它能安全地”做”。可以类比 Tomcat 之于 Servlet:你的业务代码(模型)只处理请求本身,容器(Harness)负责连接管理、线程调度、生命周期和安全这些脏活。
这篇笔记把四套资料整合成一张能照着执行的 Harness 学习地图:
- Hello Agents:补 Agent 基础范式、框架构建、上下文工程、协议和评测。
- Agent Learning Hub:给出现代 Agent 的学习优先级和项目阶梯。
- learn-claude-code:用 20 个递进切片(每个切片是一份能独立跑起来的小实现,一步只加一个机制)从零实现 Coding Agent Harness。
- 御舆:Claude Code 架构深度剖析:从真实产品视角观察循环、工具、权限、上下文、Hooks、Skills 和协作。
两个视频的结论也纳入本文:一是 Skills(给 Agent 预先写好的流程说明书,比如”怎么部署博客”这种可复用的操作步骤,按需加载)解决的是流程知识复用问题;二是同一个模型放进不同 Harness 里表现会差很多,所以任务失败不一定是模型能力不足,很可能是外围工程没做好。
资料版本与使用边界
这批资料更新很快,先记下这次对照的是哪个版本,以后发现内容对不上号时好排查。表里的十六进制串是 git commit 短哈希。
| 来源 | 本次对照版本 | 在本文中的作用 |
|---|---|---|
| Agent Learning Hub | d7967513 | 方向与项目优先级 |
| Hello Agents | 6c616938 | 系统教程、经典范式、Context/Eval |
| learn-claude-code | a9cafe95 | 20 个可运行 Harness 切片 |
| claude-code-book | da5b9c39 | Claude Code 架构观察与设计原则 |
| Codex Manual / Claude Code Skills | 2026-07-13 在线版本 | Skills 的公开产品契约 |
claude-code-book 属于外部源码剖析材料,其中内部函数、优先级和实现细节应当视为“版本化观察”,不能替代官方产品契约。本文只吸收可迁移的架构原则;涉及 Codex/Claude Code 当前行为时,以官方文档为准。
核心结论:我们主要是在构建 Harness
一个可工作的 Agent 产品可以先拆成三层:
| 层 | 负责什么 | 不能替代什么 |
|---|---|---|
| Model | 语义理解、推理、生成、选择动作 | 不能直接保证权限、安全和可靠执行 |
| Harness | 工具、观察、上下文、状态、权限、反馈、恢复 | 不能靠 if-else 编出模型没有的能力 |
| Product | 用户入口、部署、SLO(Service Level Objective,服务质量目标,比如承诺”可用率 99.9%”)、成本、合规 | 不能掩盖 Harness 的不可控行为 |
这张表的读法:中间列是每层的本职工作,右列提醒你别指望用这一层去补另一层的锅,比如 Harness 里堆再多 if-else 也造不出模型本身没有的推理能力。
最小 Agent 只有一个不变量(invariant,指无论后面加多少功能都不许被破坏的结构):
后面会冒出一堆新名词:Skills(预置的流程知识)、Memory(跨会话记忆)、Task(持久化的任务记录)、Subagent(派出去独立干活的子 Agent)、MCP(Model Context Protocol,一个让 Agent 统一接入外部工具和数据源的开放协议,相当于给工具定了标准接口)、Hooks(在循环的特定节点插入自定义逻辑,类似 Servlet 的 Filter)、Worktree(git 的多工作目录机制,让并行任务各改各的文件)。
它们全都只是在这个循环周围加运行条件,谁也不许推翻循环本身。
为什么同一模型会得到不同结果
Harness 决定模型本轮能看见什么、能做什么、做完得到什么反馈:
| Harness 部分 | 设计差时的表现 | 设计目标 |
|---|---|---|
| Observation | 看不到关键文件、错误和环境状态 | 高信号、及时、可验证 |
| Tools | 工具重叠、schema(工具参数的 JSON 格式定义,相当于给模型看的接口文档)含糊、输出过长 | 原子、低重叠、结果结构化 |
| Context | 规则被淹没、旧信息污染、新证据缺失 | 有预算、有优先级、按需加载 |
| Permissions | 要么频繁打断,要么危险操作直通 | fail-closed(默认拒绝,白名单放行)、分级、可审计 |
| Feedback | 工具失败只返回一段模糊文本 | 说清错在哪一步(参数校验、执行中还是超时)、建议怎么改、附上原始报错 |
| State | 重复执行、忘记目标、无法停止 | 显式状态机、持久化、停止原因 |
| Eval | 一次演示成功就判断“能用” | 固定任务集、分层归因、版本对比 |
表里两个词补充一下:Observation 指模型每一轮能观察到的环境信息(文件内容、命令输出、报错等);Eval 指评测,用一批固定任务反复测 Agent,作用类似你项目里的回归测试集。
所以在下结论“模型做不到”之前,要先跑一次 Harness 归因:模型是否得到正确观察、合适工具、充分反馈和明确边界。这几项里任何一项缺了,再强的模型也会答错。
什么时候不需要 Harness
上一节把 Harness 说得很重要,但很多任务根本用不上它。这张表从上往下复杂度递增:前三行用普通代码或一次 API 调用就够,后三行才值得上 Agent。
| 任务 | 推荐形态 | 原因 |
|---|---|---|
| 翻译、摘要、分类 | 单次 LLM API | 没有自主循环和副作用 |
| 固定步骤的数据处理 | Script / Workflow | 路径可预测,确定性更重要 |
| 一次查询后调用一个安全工具 | Function Calling(模型 API 的原生功能:模型返回结构化的函数名和参数,由你的代码执行) | 不需要长状态和复杂恢复 |
| 根据中间结果连续行动 | Agent Harness | 需要 observe-act 循环(看到结果再决定下一步) |
| 文件、Shell、网络等副作用 | Agent Harness | 必须加入权限、审计、恢复 |
| 长任务、并发任务、跨会话任务 | 完整 Harness | 需要压缩、任务状态和隔离 |
判断顺序:先问普通代码能不能解决,再问固定 Workflow 能不能解决,最后才让模型决定路径。
四套资料怎样分工
四套资料内容有重叠,别都从头读到尾。用法是:遇到左列的问题,去查中间列的资料,读完把收获落到右列的本地笔记里。
表里两个缩写先说清:ReAct 指 Reasoning + Acting,一种让模型每轮先写一段推理再发一个工具调用的经典范式,第一轮学习会细讲;A2A 指 Agent2Agent,Google 提出的让不同 Agent 之间互相发现、传消息、协作的开放协议。
它和前面讲过的 MCP 分工不同:MCP 管一个 Agent 怎么接工具和数据源,A2A 管两个 Agent 怎么对话,一个向下连资源,一个横向连同伴。
| 学习问题 | 优先资料 | 应落入本地哪篇笔记 |
|---|---|---|
| Agent、Workflow、ReAct 是什么 | Hello Agents 1/4 | 05-AI工程基础入门到精通 |
| 怎样从零写 Agent Loop | learn-claude-code s01 | 07-Agent CLI源码剖析-主循环与状态机 |
| 工具与权限怎样分层 | learn s02-s04、御舆 3/4/8 | 13-Agent CLI深水区-工具执行器权限审计 |
| 上下文为什么会腐蚀 | Hello Agents 9、learn s08、御舆 7 | 14-Agent CLI深水区-上下文预算压缩记忆 |
| Skills 怎样发现和按需加载 | learn s07、御舆 11、官方文档 | 19-Agent CLI深水区-命令技能插件系统 |
| MCP/A2A 等协议怎样归位 | Hello Agents 10、Learning Hub | 22-现代Agent工程扩展-协作协议与Computer Use |
| 怎样评估工具与综合任务 | Hello Agents 12 | 20-Agent CLI深水区-TraceEval调试体系 |
| 怎样研究真实 Coding Agent | 御舆 1-15 | 06-21 源码线 |
| 应该做什么项目 | Learning Hub Project Ladder | 03-项目清单 |
Agent Learning Hub 适合作为索引,不适合逐链接线性阅读;Hello Agents 适合补概念和横向范式;learn-claude-code 适合亲手实现;御舆适合已经有对象地图后做产品级对照。
当前不放进必修主线的内容
下面这些章节先跳过或略读,右列写了原因:
| 内容 | 处理 | 原因 |
|---|---|---|
| Hello Agents 第 2 章发展史 | 快速浏览 | 建立背景,但不直接形成工程能力 |
| 第 5 章低代码平台 | 选修体验 | 能看产品形态,不能替代亲手实现 Loop/Tool |
| 第 6 章 AutoGen/CAMEL 等框架 | 了解抽象,不重押 | 现代主线更应关注 Harness、状态、权限和 Eval |
| 第 11 章 Agentic-RL | 后置研究线 | 它用强化学习去改模型/策略本身,前提是已有稳定环境与评测 |
| 第 13-15 章完整案例 | 三选一复现 | 旅行、Deep Research、赛博小镇不需要全部重做 |
这些内容不进必修只有一个原因:最小 Harness 还没跑通之前,同时铺开框架、产品和训练三条战线只会分散精力。它们本身有价值,跑通之后再回头看。
Harness 的六阶段构建地图
learn-claude-code 的 20 个切片可以压缩成六个阶段。学习时只需要盯住每一章新增了哪个机制,章节号不用记。
| 阶段 | 新增机制 | 解决的失败 | 本地深挖入口 |
|---|---|---|---|
| H1 能行动 | Loop、Tool Dispatch | 模型碰不到环境 | 06, 07, 08, 11, 12, 13 |
| H2 能受控 | Permission、Hooks | 副作用失控、扩展污染主循环 | 08, 13, 本文 Hooks 小节 |
| H3 能聚焦 | Todo、Subagent、Skill、Compact(上下文压缩:把过长的对话历史缩写成摘要,腾出模型窗口空间) | 大任务漂移、上下文膨胀 | 09, 14, 19 |
| H4 能恢复 | Memory、System Prompt、Error Recovery | 压缩后失忆、错误后乱试 | 14, 16, 20 |
| H5 能长期运行 | Task DAG(用有向无环图组织的任务依赖关系)、Background、Cron(定时任务,同 Linux crontab) | 会话结束后状态消失 | 20, 22, 本文任务系统小节 |
| H6 能协作扩展 | Teams、Protocol、Worktree、MCP | 并发冲突、外部能力孤岛 | 15, 19, 22, 本文 Worktree 小节 |
御舆第 15 章总结的五条原则,可以作为每一阶段的架构检查:
| 原则 | 工程含义 | 本地对应 |
|---|---|---|
| 循环优于递归 | 状态恢复、中止、压缩都回到一个固定循环 | 07, 12 |
| Schema 驱动 | 验证、描述、权限和文档共享真源 | 08, 13 |
| 渐进权限 | 校验、规则、Hook、确认逐层短路 | 13, 本文 H2 |
| 流式优先 | 模型、Tool、UI 通过事件增量连接 | 06, 16, 21 |
| 可插拔扩展 | Hooks/Skills/Plugin 不污染主循环 | 19, 本文 H2/H3 |
其中三条展开说一下。Schema 驱动:工具的那份 JSON Schema 参数定义同时用来做参数校验、生成给模型看的工具说明、判断权限级别、生成文档,一份定义四处复用,改一处全生效,思路和你用一个实体类同时驱动建表和接口文档差不多。
渐进权限:检查按成本从低到高排,先做便宜的格式校验,再查静态规则,再核对会话上下文条件(H2 权限管线里的 Context Check,比如文件是否读过、是否已授权过),再跑 Hook,最后才弹窗问人,前面任何一层拒绝就直接短路不走后面,结构和 Servlet 过滤器链一样。
流式优先:这里的”流式”就是你在聊天界面看到的逐字输出,内部靠事件流把模型输出、工具进度和 UI 增量地接起来,不用等全部算完再一次性返回。
新 20 章与旧 12 章不要混用编号
learn-claude-code 当前根目录 s01-s20 是推荐主线;网站 docs/ 仍保留旧 12 章版本。Skill Loading 在新版是 s07、旧版是 s05;Context Compact 在新版是 s08、旧版是 s06。阅读和引用时要写主题名,不能只写 s05。
H1:循环和工具是稳定内核
最小循环
代码块收起展开
while (true) {
const response = await model.call(messages, toolSchemas);
messages.push(response.assistantMessage);
if (response.toolCalls.length === 0) {
return response.finalText;
}
const results = await toolExecutor.execute(response.toolCalls);
messages.push(asToolResults(results));
}这段循环就是全部骨架:模型要么发工具调用,要么给最终答案;发了调用就执行、把结果塞回消息历史、再问模型。生产实现必须再补:
maxSteps与细分StopReason(最多循环多少步,以及停下时记录为什么停:正常结束、超步数、被取消还是出错)。- 用户取消与超时。
- usage(token 用量)、延迟和成本记录。
- 工具结果与原调用 ID 一一对应(模型一轮可能发多个调用,结果乱序回来必须能对上号)。
- 模型错误和工具错误分开恢复(前者重试请求,后者把错误信息喂回去让模型改)。
工具扩展不应该修改主循环
learn-claude-code 的关键教学原则是:加一个工具,只新增 schema 和 handler。
代码块收起展开
const handlers = {
read_file: readFile,
edit_file: editFile,
run_command: runCommand,
};如果每加一个 Tool 都要去改 QueryEngine(教程里主循环引擎的类名)的 if-else,说明 Tool Registry(工具注册表)和执行器的边界没有建立。
对照 Spring 的思路:新加一个 HTTP 接口你只写一个 Controller,不会去改 DispatcherServlet,工具注册应该遵守同样的开闭原则。
工具集也不是越大越好。Hello Agents 的上下文工程强调最小可行工具集:工具职责单一、重叠低、描述明确、错误可恢复。人类都难以判断两个工具的边界时,模型的选择不会稳定。
H2:权限和 Hooks 分工
权限系统回答“这次动作能不能执行”,Hooks 回答“在生命周期节点还要附加什么规则或动作”。前者类似 Spring Security 的鉴权,后者类似 AOP 切面或 Servlet Filter,各管各的,两者都不能写进主循环内部的业务分支。
权限管线
Schema Validate → Static Policy → Context Check → Hook Gate → Human Approval → Execute
五步里唯一名字不直白的是 Context Check:它查的是当前会话的动态状态,静态规则表回答不了的那部分。
比如 edit_file 要改的文件本轮是否已经读过(没读过就改,容易凭想象覆盖内容)、目标路径是否在本次会话允许的工作目录内、同类操作是否已经被用户批准过(批过就不用再问)。
Static Policy 是写死的配置,Context Check 是查运行时状态,就像 Spring Security 里配置文件写的 URL 规则和代码里查当前登录用户会话是两回事。
默认策略应该 fail-closed:新 Tool 在明确声明前,先视为可能写入、不可并发、需要审查。性能可以逐步放开,副作用不能事后补救。
Hooks 的工程位置
Hook 按生命周期节点挂载,名字基本能望文生义(PreToolUse 就是工具执行前,PostToolUse 就是执行后)。表里中间列是这个节点上适合挂什么逻辑,右列讲 Hook 自身出错时怎么兜底:
| Hook | 典型用途 | 失败处理 |
|---|---|---|
| SessionStart | 注入项目状态、检查环境 | 非关键失败可降级 |
| UserPromptSubmit | 分类、补充上下文 | 保留原始用户意图 |
| PreToolUse | 安全校验、修改或拒绝输入 | 超时默认不放行危险操作 |
| PostToolUse | 格式化、审计、触发测试 | 不得篡改已经发生的事实 |
| PreCompact | 保存 transcript(完整对话记录)、提取关键状态 | 压缩失败时保留可恢复快照 |
| Stop | 完整性检查、决定是否继续 | 必须防止重复唤醒循环 |
| SessionEnd | 结算 usage、持久化摘要 | 与任务完成状态分开记录 |
Hook 要有 matcher(匹配规则,声明这个 Hook 只对哪些工具或事件生效,类似 Filter 的 url-pattern)、超时、来源和审计。耗时操作放后台;所有 Tool 都跑同一个重型 Hook 会把扩展点变成性能瓶颈。
H3:Skills 与上下文都是渐进加载
容易误解成 Skills 就是每轮全塞进 Prompt 的大段规则,实际做法相反:平时只让模型看到一行元数据,匹配上任务才加载正文。产品公开契约和教学实现都指向同一模式:
Discover metadata → Match task → Load SKILL.md → Read references/scripts if needed
name 和 description 是发现层,完整正文是执行层。举个最小例子:一个 deploy-blog Skill,元数据只有一句“部署博客到 Cloudflare Pages”,平时上下文里就占这一行;当你说“帮我发布博客”时,Harness 才把整份 SKILL.md(具体步骤、命令、注意事项)读进上下文。
这和 JVM 类加载一个思路:类名先在 classpath 里登记着,真正用到才把字节码加载进内存。
Codex 支持显式 $skill-name 与 description 匹配的隐式选择;Claude Code 支持显式 /skill-name 与相关任务自动加载。
具体内部排序算法没有公开承诺,不能想当然写成“固定用 embedding(把文本转成向量算相似度)做分类”。
上下文也遵循同一原则:先放稳定规则和轻量引用,再让 Agent 通过文件、搜索、RAG(检索增强生成:先从知识库搜出相关内容,再连同问题一起喂给模型)、MCP 按需获取细节。详见 14-Agent CLI深水区-上下文预算压缩记忆。
H4:错误恢复必须改变下一次尝试
无效重试只是再次花钱。恢复策略应根据失败类型改变参数、工具或路径:
| 失败 | 下一次必须改变什么 |
|---|---|
| Rate Limit(触发了 API 的接口限流) | 等待、限速或切换容量路径 |
| Context Overflow(对话内容超出模型上下文窗口上限) | 裁剪结果、压缩历史、减少输入 |
| Tool Schema Error | 返回字段级错误,让模型修参数 |
| Permission Denied | 停止或请求授权,不能换写法绕过 |
| File Conflict | 重新读取版本,生成新 diff |
| Repeated No Progress | 触发 stop、换策略或人工接管 |
举个 Tool Schema Error 的例子:模型调用 edit_file 时把参数名写成了 filename,schema 要求的是 file_path。
差的 Harness 只回一句 “invalid arguments”,模型只能瞎猜着重试;好的 Harness 回 “unknown field: filename, did you mean file_path?“,模型下一次一发就中。
需要记录 attemptNo、previousError、strategyChanged。如果三次请求的输入、工具和策略都没变,那就只是在花钱重复,算不上恢复。
H5:任务状态要活得比对话久
Todo 只帮助本轮聚焦;Task System 才负责跨压缩(上下文被 compact 之后计划还在)、跨进程和多执行者协调。
代码块收起展开
type TaskRecord = {
id: string;
objective: string;
status: "pending" | "in_progress" | "completed" | "blocked";
blockedBy: string[];
owner?: string;
artifactRefs: string[];
worktree?: string;
version: number;
};任务 DAG 应能回答:现在什么可做、什么被阻塞、什么完成后会解锁后续任务。状态必须落盘(写进文件或数据库);否则一次 context compact 就可能把还没写下来的计划压没。道理和 MQ 消息持久化一样:只存在内存(这里就是对话上下文)里的东西,随时可能丢。
Background 与 Cron
这三种机制都在解决“没有用户盯着时 Agent 怎么继续干活”。右列的坑你在 Java 后端见过对应版本:Background Task 的“重复消费”就是 MQ 消费端的幂等问题,Cron 的坑和你用 @Scheduled/Quartz 踩的一样。
| 机制 | 解决什么 | 必须防的坑 |
|---|---|---|
| Background Task | 慢命令不阻塞 Agent 思考 | 完成通知丢失、重复消费 |
| Cron | 无人发消息时按时触发 | 重复执行、时区、错过触发 |
| Heartbeat(心跳:定时醒来看一眼有没有活) | 周期检查是否有工作 | 空转消耗 token、并发唤醒 |
调度器应该先用确定性规则(查任务表、看有没有新消息这类普通代码判断)决定是否需要唤醒模型,不能每个心跳都调用 LLM,每次调用都是真金白银的 token。
H6:协作需要控制面和执行面
多 Agent 协作的核心是三样共享的东西:任务契约(谁负责什么、状态怎么流转)、消息协议(怎么传话)和产物位置(改出来的东西放哪)。
让多个模型自由聊天解决不了这些,只会互相打架。工程上把这套东西拆成两个平面管理,Control Plane(控制面)存“谁在干什么”的元信息,Execution Plane(执行面)放实际干活产生的东西:
| 平面 | 保存什么 | 示例 |
|---|---|---|
| Control Plane | task、owner、status、requestId、审批 | .tasks/ 目录, mailbox(Agent 间的消息信箱), plan approval(计划审批) |
| Execution Plane | 实际代码、命令、构建产物 | Git worktree、sandbox、artifact store |
Worktree 与 Task 绑定
Task #12: in_progress, owner=worker-a ↔ Worktree: wt/task-12, branch=codex/task-12
Worktree 是 git 自带的功能:同一个仓库可以同时检出多个独立的工作目录,各自挂在不同分支上改,互不影响。
任务决定做什么,Worktree 决定在哪里做。并行 Agent 共用同一工作目录会互相污染未提交改动,就像两个线程不加同步写同一个共享变量;隔离目录后仍需要明确的 keep/remove(任务完成后这个目录留还是删)、合并、冲突和清理协议。
协作协议
所有审批、关机和交接都可以复用 request-response 状态机:
pending -> approved | rejected | timed_out | cancelled
消息必须携带稳定 requestId,否则异步响应无法与原请求关联。你在 Netty/RPC 里见过同样的设计:请求发出去先把 ID 存进 pending map,响应回来靠这个 ID 找到是谁在等它。详细多智能体契约见 22-现代Agent工程扩展-协作协议与Computer Use。
评估 Harness,而不只是评估模型
同一固定模型、固定任务集,只替换 Harness 配置,才能判断 Harness 是否有效。这就是控制变量法:表里每一行是一组 A/B 对照实验,只改中间列那一个变量,跑同一批任务,对比右列指标。
| 对照实验 | 只改变什么 | 观察指标 |
|---|---|---|
| Tool Schema A/B | 描述、字段、枚举 | 选择准确率、参数正确率 |
| Context A/B | 检索、排序、压缩 | 成功率、引用、token、长程遗忘 |
| Permission A/B | 自动/确认规则 | 阻断率、误阻断、危险执行率 |
| Skill A/B | description、正文、示例 | 触发准确率、任务完成率 |
| Single/Multi(单 Agent 对比多 Agent) | 协作 Harness | 成功率、成本、重复劳动、延迟 |
上面这些实验需要任务集,业界有现成的公开评测集(benchmark,相当于大家共用的标准化考卷):工具调用可用 BFCL(Berkeley Function Calling Leaderboard,专测模型能否正确发起函数调用)类型用例,综合助手可参考 GAIA(一套需要多步推理加工具使用才能答对的通用助手题集),网页任务可参考 WebArena(在仿真网站上完成操作任务),代码任务可参考 SWE-bench(给模型真实 GitHub issue 让它修 bug)。
公共 benchmark 不能代替自己的项目回归集;最终仍要把真实失败沉淀为 EvalCase,也就是你自己的评测用例:一个输入、一个期望结果、一个判分方式,攒多了就是这套 Harness 的回归测试集。
推荐学习顺序
第一轮:先得到最小心智模型
- Hello Agents 第 1、4 章:Agent/Workflow、ReAct、Plan-and-Solve(先让模型列出完整计划再逐步执行)、Reflection(让模型回头检查自己上一步的输出并修正)。
- learn-claude-code 新版 s01-s04:Loop、Tool、Permission、Hooks。
- 本地
06、07、08、11、12、13:把教程对象映射到完整 Runtime。
第二轮:补上下文与可恢复性
- Hello Agents 第 9 章:上下文工程与 GSSC(书里提出的上下文管理框架缩写,四个字母各对应一个处理环节,先当成“一套系统管理上下文的方法论”理解,具体展开以原书第 9 章为准)。
- learn-claude-code s07-s11:Skill、Compact、Memory、System Prompt、Recovery。
- 本地
09、14、16、19、20。
第三轮:再读真实产品剖析
御舆不要一开始从第 1 章硬读到第 15 章。按当前问题查:
| 当前问题 | 御舆章节 |
|---|---|
| 主循环看不懂 | 2 |
| 工具和权限混在一起 | 3、4 |
| 上下文为什么越来越差 | 7 |
| Hooks 放在哪里 | 8 |
| 子代理与协调 | 9、10 |
| Skills/Plugin | 11 |
| 想自己实现 Harness | 15 |
第四轮:项目化和评测
- Hello Agents 第 10、12、14、16 章:协议、评测、Deep Research、毕业项目。
- Agent Learning Hub 的 Project Ladder:按难度选择项目,不按 star 数扫仓库。
- 回到 03-项目清单 和 04-每周推进计划,用 Demo + Trace(完整运行轨迹:每一轮模型看到什么、调了什么工具、返回了什么,全部留档,出问题时靠它定位)+ Eval 验收。
最小 Harness 实现门槛
Gate 就是关卡:自己动手实现 Harness 时按 G0 到 G7 逐关验收,中间列是这一关要实现的东西,右列是“算过关”的证据。
| Gate | 必须实现 | 通过证据 |
|---|---|---|
| G0 | 单模型对话与 streaming(流式输出) | 20 次请求稳定、各类错误都归一成统一的错误结构 |
| G1 | Agent Loop + 3 个工具 | tool call/result 能连续多轮正确回填进对话历史 |
| G2 | Schema、路径沙箱、权限、Hook | 越权与危险动作被拒绝 |
| G3 | Context Budget、Skill、Compact | 长任务后目标和规则仍保留 |
| G4 | Trace、Recovery、Eval | 失败能归因,改动能回归 |
| G5 | Task 持久化、Background | 重启后能恢复任务,不重复副作用 |
| G6 | Subagent、Protocol、Worktree | 并行任务不污染同一目录 |
| G7 | MCP 与产品入口 | 外部能力统一治理,别人能运行项目 |
每一 Gate 都必须先有失败用例再升级:先构造会出错的场景(越权命令、超长上下文、断网),确认系统的反应符合预期,才算这关过了。只跑 happy path(一切顺利、没有任何异常的理想路径)的功能不能作为下一层依赖。
读资料时的去重规则
- Hello Agents 负责讲“是什么、有哪些范式”;不复制其整套框架代码。
- learn-claude-code 负责讲“每次只增加一个机制”;不把教学实现当生产内部实现。
- 御舆负责讲“真实产品为什么这样设计”;版本化细节必须标注来源。
- Agent Learning Hub 负责选方向与项目;资源链接不整页搬运。
- 本地
06-21继续作为工程对象、伪代码、失败模式和验收门槛的真源。
核心判断
Agent 工程的学习顺序应该是:
先看懂一个循环 → 再给它工具和权限 → 再治理上下文和恢复 → 再让任务持久化 → 最后才做多 Agent、常驻运行和协议扩展
Harness 不替模型思考,它的全部价值就五件事:让模型看得清、做得准、停得下、错了能恢复、改了能评测。