Agent Engineering 101|16|Packages and SDK

当 Harness 边界稳定后,Agent 能力才能从单一 CLI 走向可分享 packages、SDK、RPC 和嵌入式产品形态。

Agent Engineering 101|16|Packages and SDK

核心结论

配套代码仓库: github.com/llm-101/mini-agent-harness

读完本文,你应该能回答

  • 什么时候一个 Harness 能力可以被打包复用?
  • package、SDK、RPC、extension 分别适合什么边界?
  • 如何避免把教学实现直接误用成生产平台?
  • 读完整个系列后,最小 Agent Harness 应该包含哪些部分?

本篇在系列中的位置

  • 上一篇:15 Interactive TUI 展示了一个产品外壳。
  • 本篇:本文收束全系列:稳定边界如何变成 packages、SDK、RPC 和嵌入式能力。
  • 下一篇:读完后,可以回到 mini-agent-harness 仓库,按章节改造自己的最小 Agent Runtime。

贯穿例子

本系列会反复使用同一个任务来连接各章:

用户说:“帮我修复这个 repo 里的 failing tests。”

在这个任务里,Packages and SDK 让同一套“修测试”能力可以从 CLI 复用到 IDE、CI、后台任务或其他产品外壳里。读者要关注的是:只有边界稳定,Harness 才能被打包和嵌入。

  • Packages and SDK 是 Harness 能力产品化的外层形态。它们依赖稳定的公共 API、事件协议、工具注册、扩展 hooks 和状态边界。
  • 如果所有能力只存在于一个 CLI 中,就很难复用到 Web、后台任务、IDE、CI 或其他 Agent 产品里。
  • mini-agent-harness 中,Packages and SDK 代表的是边界稳定之后的外部形态:同一套能力可以被不同产品调用。

定义

Packages and SDK 是 Harness 能力产品化的外层形态。它们依赖稳定的公共 API、事件协议、工具注册、扩展 hooks 和状态边界。

为什么要单独看这一层?

当 Harness 只存在于一个 CLI 里,它很难被复用。Packages and SDK 的价值,是把稳定边界变成其他产品也能调用的能力。

From Harness to SDK

边界

这一层的职责可以拆成几个稳定部分:

  • Public API:prompt、stream、continueStream
  • Event Protocol:跨 UI/SDK/RPC 复用
  • Tool Packages:共享工具与 schema
  • Skill Packages:共享任务知识
  • Extension Packages:共享 policy/telemetry/context hook
  • RPC / SDK:把 Harness 嵌入其他产品

这一层的边界可以用一个问题检验:如果它的内部实现变化,模型适配、工具执行、状态存储和产品外壳是否都不需要跟着重写?如果答案是否定的,说明这个边界还没有真正收束变化。

代码锚点

本篇主要对应这些模块:

  • src/core/harness.ts
  • src/core/agent-events.ts
  • src/tools/tool-runtime.ts
  • src/extensions/extension-api.ts
  • src/cli/rpc-mode.ts

阅读代码时建议先看类型,再看运行路径。

类型定义告诉你这一层暴露什么 contract;运行路径告诉你这个 contract 在 Agent 执行中何时被消费、何时被写回、何时被产品层看见。

运行流程

Capability Packaging Path

一次典型执行可以概括为:

  1. Capability:tool/skill/extension
  2. Package:版本化分发
  3. Register:Harness.load
  4. Stream:统一事件协议
  5. Product:CLI/Web/IDE/CI
  • Shareability:能力复用
  • Stability:接口契约
  • Productization:多外壳

这里最容易被忽略的是“中间态”。生产级 Agent 不是只关心最终答案;它还要在运行过程中展示进度、捕获错误、记录 usage、允许取消,并把可恢复状态写回 session。

读者抓手:哪些边界可以被打包

边界 适合形态 原因
ModelClient package / interface provider 差异可替换
Tool Runtime package + policy hooks 工具生命周期可复用
Session Store adapter interface 存储后端可替换
Context Builder SDK API 产品可传入不同资源
Extensions plugin package 能力按 hook 注入
Product Shell app / CLI / TUI 展示形态通常独立演进

当这些边界稳定后,Harness 才能从一个 repo 里的实现,变成可嵌入、可组合、可分享的 Agent 能力。

最小 Harness 的最终形状

读完整个系列后,可以把最小 Agent Harness 理解为五件事:

  1. 一个稳定模型边界:隔离 provider 差异。
  2. 一个 Agent Loop:把模型意图、工具执行和下一轮上下文连接起来。
  3. 一个状态系统:保存 messages、events、session tree 和 summary。
  4. 一个工具与策略运行时:让外部动作可校验、可审批、可回灌。
  5. 一个产品外壳和扩展层:让同一套 runtime 能被 CLI、TUI、SDK 和插件复用。

这也是 mini-agent-harness 的教学目标:不是做一个大而全的 Agent 平台,而是把这些边界做小、做清楚,让读者能亲手理解每一层为什么存在。

可迁移伪实现:SDK 边界

下面的伪代码是机制抽象,不对应真实 API 或文件结构。它只用来说明这一层的控制点:

const harness = new MiniAgentHarness({ tools, skillsDir, sessionFile, model });
await harness.load();
for await (const event of harness.stream(input)) {
  sdk.emit(event);
}

这个草图的价值在于说明控制点,而不是提供可复制的库代码。

真正的工程实现还要处理错误、取消、并发、token 预算、日志、权限、序列化和 provider 差异。

工程原则

将这一层从 Agent 系统中拆出来,通常带来四个直接收益。

第一,可替换。

外部系统、模型 provider、工具集合或产品外壳变化时,核心运行时不必整体重写。

第二,可观测。

边界清晰后,事件、trace、usage、错误和状态迁移都有稳定落点。

第三,可恢复。

只要状态写入 session,运行时就可以在进程重启、工具失败或长任务中断后继续推理。

第四,可治理。

权限、脱敏、审批、路径保护和执行策略可以放在稳定 hook 或 runtime boundary 上,而不是只靠 prompt 约束。

和 Agent Harness 的关系

Agent = Model + Harness 这个公式的重点,不是把模型之外的所有东西都称为“工程杂活”。

相反,它提示我们:模型之外存在一套必须被设计的运行时系统。

Packages and SDK 就是这套系统中的一个切面。它不替代模型能力,也不替代产品体验;它让模型能力可以被组织成可执行、可观察、可恢复、可治理的任务流程。

小结

Packages and SDK 的核心价值,是把一类容易扩散的复杂性收束到明确边界中。

mini-agent-harness 中,这个边界被刻意写得较小,方便阅读和教学。但它对应的问题并不小:只要一个 Agent 要长期运行、调用工具、管理上下文、支持 UI、保存状态并处理失败,这个边界就会出现。

下一步可以继续沿着系列计划,把这些边界组合成完整 Agent Harness:模型边界、工具边界、状态边界、上下文边界、扩展边界和产品外壳边界。

参考资料

  • OpenAI Agents / Responses API 文档:用于理解现代模型调用、工具调用和结构化响应的运行时边界。
  • Anthropic Claude Messages / Tool Use / Agent Skills 文档:用于理解 content blocks、tool_use/tool_result、stop reason、Skills 与长任务上下文管理。
  • Model Context Protocol Specification:用于理解工具、资源和 prompts 的连接层边界。
  • Martin Fowler, “Agent = Model + Harness”:用于理解模型之外的 harness 概念。