KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
Agent Harness 教程调研与线性课程设计报告 — keel 龙骨
Agent Harness 的参考信息:Agent Harness 教程调研与线性课程设计报告
0. 报告目的
这份报告先回答一个问题:怎样写一门教程,才能让读者真正理解 Harness,并且能够在代码里完成第一次可控的 Agent 实操,而不是读完一堆框架名词?
本报告不以“我们要实现多少功能”为中心,而以读者的学习过程为中心:读者现在知道什么、下一步会困惑什么、需要看到什么例子、需要亲手改变什么,以及怎样确认自己真的理解了。
资料说明:样本优先选用官方教程、官方产品文档和可核验的学习科学论文。文档页面会变化,因此这里借鉴的是稳定的概念、教学顺序和运行时边界,不把某个版本的 API 当成 Harness 的定义。官方资料链接见下表,学习科学论文链接见第二节。
1. 教程样本调研
1.1 样本范围
| 样本 | 主要教学入口 | 值得借鉴的点 |
|---|---|---|
| Anthropic《Building effective agents》 | 先区分 workflow 与 Agent,再介绍常见编排模式 | 先讲选择和取舍,强调简单、可组合,而不是先推框架 |
| LangGraph《Thinking in LangGraph》 | 从业务流程开始,拆离散步骤,分类节点,设计 state,再连线 | 先有流程和状态,后有框架;错误和人工输入属于流程的一部分 |
| AutoGen AgentChat Quickstart | 先创建单 Agent,再加工具、团队、人工介入和状态 | 从可运行 quickstart 逐步打开能力菜单 |
| OpenAI Agents SDK Quickstart | 创建 Agent、运行、加工具、handoff、看 trace | 把工具、协作和观测放在一条可执行路径上 |
| PydanticAI Agents | 从运行、流式事件、取消、类型安全到 evals | 把“可观察、可取消、可测试”作为 Agent 的正常组成 |
| Google ADK | Agents、Graph Workflows、Sessions、State、Events、Memory | 把单 Agent、工作流、会话和多 Agent 放在能力地图中 |
| Ollama Capabilities | Streaming、Thinking、Structured Outputs、Tool Calling | 提供本地真实模型的逐步实验入口,适合建立反馈回路 |
1.2 样本共同优点
- 先让读者跑起来:读者很快看到一个真实模型或 Agent 结果。
- 能力逐步打开:工具、状态、协作、观测不是第一屏全部出现。
- 提供能力地图:读者知道后续还有什么,但当前只学习一个点。
- 把运行时问题显式化:流式、取消、持久化、人工输入和追踪并非隐藏细节。
- 框架抽象建立在概念之后:先说明流程和状态,再展示框架如何承载它们。
1.3 不应直接照搬的地方
- 许多 quickstart 默认读者已经理解消息、工具 schema、异步和环境配置;初学者会在第一段代码前就失去上下文。
- 能力目录适合查阅,不等于适合学习。把文档导航顺序原样变成课程,会得到名词列表而不是心智模型。
- 多 Agent、handoff、memory 和 workflow 在产品文档中常常并列展示;课程必须延迟它们,直到读者理解单 Agent 循环的边界。
- 框架示例通常把成功路径写得很短,失败路径留给读者自己推测;本课程需要把“模型输出坏了、工具失败、用户取消”作为教学材料。
2. 学习科学依据
2.1 认知负荷:一次只增加一个新的变化
Sweller 的认知负荷研究指出,学习者的工作记忆容量有限;复杂问题中,额外的无关信息会挤占真正需要形成的结构。
课程含义:第一阶段不要同时引入真实模型、工具、数据库、异步队列和框架。每一章只引入一个新的运行时变化,并明确它解决上一章暴露的哪个问题。
参考:Sweller, Cognitive Load During Problem Solving: Effects on Learning
2.2 示例—练习—渐隐:先看懂,再自己改
worked-example 研究表明,新手先研究一个完整的分步示例,再解决结构相似的问题,通常比一开始直接自由探索更有效。
课程含义:每个章节先提供一段可以运行的“教师示范”,随后只要求读者改一个变量、补一个分支或添加一个失败测试。随着章节推进,示范减少,读者自己设计的部分增加。
参考:Ayres, Worked Example Effect
2.3 检索练习:让读者先预测再运行
Roediger 与 Karpicke 的研究显示,主动检索会增强长期保持,而不仅是再次阅读材料。
课程含义:每个代码块前先问一个可预测的问题,例如“模型这次会返回最终回答还是工具调用?”“工具超时后哪一条消息应该进入上下文?”读者先写下预测,再运行代码核对。
参考:Roediger & Karpicke, Test-Enhanced Learning
2.4 真实问题驱动:概念必须有出现的理由
Merrill 的 First Principles of Instruction 强调真实问题、激活已有知识、示范、应用和整合。
课程含义:课程不先讲“持久化的定义”,而先让读者关闭程序再查询运行;不先讲“幂等”,而先模拟工具超时后重复创建工单;不先讲“审批”,而先让模型请求一个有副作用的工具。
参考:Merrill, First Principles of Instruction
2.5 认知学徒制:展示专家如何思考边界
认知学徒制强调示范、教练、支架、反思和逐步撤除帮助。教程不能只给最终代码,还要把工程师判断过程说出来:为什么这是模型问题而不是工具问题?为什么这个结果不能自动重试?
参考:Cognitive Apprenticeship: Teaching the Crafts of Reading, Writing, and Mathematics
2.6 螺旋式回访:同一概念在不同层次重新出现
Bruner 的螺旋课程思想强调,重要结构可以以适合当前理解水平的形式反复回访。
课程含义:state 先作为一张 Python 字典出现,再作为运行状态,再作为持久化记录,最后成为 API、worker 和审计之间的共享契约。读者不是一次记住定义,而是在新场景中不断加深同一个概念。
参考:Bruner, The Process of Education
3. 明确的读者画像
读者已有
- 能阅读和修改基础 Python
- 知道函数、类、异常、JSON 和 HTTP 的大致含义
- 可能使用过聊天模型,但没有构建 Agent Runtime 的经验
读者暂时没有
- 对 tool calling、状态机、上下文窗口和流式事件的稳定心智模型
- 对模型输出不可靠、工具副作用和重试风险的经验
- 对某个 Agent 框架的既有偏好
读者最终需要
不是背诵框架 API,而是能在代码中回答:
- 模型现在提出了什么?
- Harness 是否允许这一步?
- 工具实际发生了什么?
- 结果如何进入下一轮?
- 什么条件会让运行停下?
- 失败后能不能解释、恢复和测试?
4. 新课程的线性结构
第一段:建立一个可说清楚的模型
- 用生活类比解释模型、工具、Agent、Harness。
- 只调用一次 Ollama,让读者看到模型只是生成下一段消息。
- 加入 streaming,让“输出文本”和“运行完成”分离。
第二段:让模型输出成为可编程输入
- 用 structured outputs 让读者看到 schema、解析和业务校验。
- 用一个只读工具展示“模型请求、Harness 执行、结果回传”。
第三段:把一次调用变成运行
- 把上面的闭环写成 Harness loop。
- 引入状态、上下文、停止条件和错误分类。
- 用 thinking、记忆和上下文预算解释“模型看到的内容”与“系统保存的内容”不是一回事。
第四段:面对现实中的不确定性
- 用超时、重试、幂等和取消处理失败。
- 用副作用工具、策略和人工审批处理安全。
- 用事件、回放、评估和故障注入处理不可解释性。
第五段:模拟进入项目
- 把核心 Harness 放进 API/worker/状态存储的项目结构,完成事件诊断助手。
5. 每章固定写法
每章保持同一组教学动作,但不强制使用机械化的固定标题:
- 先把读者带到一个具体问题,说明本章要观察什么。
- 在代码前要求读者做一个小预测,激活已有知识。
- 用边界清楚的类比建立直觉,再给出正式定义。
- 运行一段最小完整代码,让概念变成可观察事实。
- 回到协议、状态、工具和权限,解释代码为什么这样组织。
- 故意破坏一个输入或运行条件,暴露失败语义。
- 用判断标准收束,而不是只复述成功输出。
- 明确下一章要解决的缺口,让知识自然继续。
标题可以更像人在带读者学习,但教学动作必须稳定;这是“有人的语气”和“可复用的教学结构”之间的区别。
6. 语气和视角约束
- 使用“你现在会看到”“我们先做一件事”,而不是“系统必须”“交付物包括”。
- 先解释读者困惑,再介绍术语。
- 每个类比都明确它的边界,避免类比替代定义。
- 代码注释解释“这一步为什么存在”,不重复代码字面意思。
- 不用生产团队口吻命令读者完成大量清单;把检查项放在章节末尾作为自测。
- 不把读者当作已经熟悉框架的工程师,也不把读者当作完全不会 Python 的初学者。
7. 成功标准
读者完成课程后,应该能够口头讲清一次运行:
用户目标
→ 模型提出下一步
→ Harness 解析并检查
→ 工具执行或等待人工
→ 结果写回状态和上下文
→ 下一轮模型决定
→ 以完成、失败、取消或等待结束
然后,他能在代码中找到这六个位置,并独立添加一个只读工具、补一个失败测试、解释一条运行轨迹。这个结果比“完成了多少章节”更重要。