Harness、Skills、Workflow——三个概念的关系和我的选择
Harness、Skills、Workflow:三个概念的关系,以及我现在的选择
做了几个比较重的 AI Skill 之后,我开始重新思考一个问题:
我现在做的东西,到底算 Skill、Workflow,还是 Harness?
一开始我把这三个概念放在同一条线上比较,后来发现这样容易混乱。更准确地说,它们不是同一层级的东西。
- Workflow 是一种确定性流程编排方式。
- Skill 是一种能力封装形态。
- Harness 是一套能力运行与治理框架。
它们不是三选一,也不是谁比谁高级,而是解决不同层级的问题。一个成熟的 Agent 系统里,三者甚至可以同时存在。
一、Workflow:确定性流程编排
Workflow 是最传统、最稳定的工程抽象。
它的核心不是“每一步都完全没有判断”,而是:
流程控制权主要在代码或流程引擎手里。
也就是说,开发者提前定义好:
- 有哪些步骤;
- 每一步输入是什么;
- 每一步输出是什么;
- 失败怎么重试;
- 哪些分支可以走;
- 哪些状态可以恢复。
一个典型 workflow 可能长这样:
fetch_data
↓
clean_data
↓
analyze_data
↓
generate_report
如果写成配置,大概是这样:
steps:
- id: fetch_data
action: call_api
next: clean_data
- id: clean_data
action: run_script
next: analyze_data
- id: analyze_data
action: llm_call
next: generate_report
- id: generate_report
action: render_template
Workflow 里当然也可以有 LLM 节点。比如某一步需要分类、总结、生成结构化 JSON,就可以调一次 LLM。
但是在这种模式下,LLM 通常只是流程里的一个节点:
上一步输出 → prompt 模板 → LLM 调用 → JSON 解析 → schema 校验 → 下一步
它不负责决定整个任务下一步怎么走,也不负责和用户自由交互。真正控制流程的是 workflow engine 或代码。
所以 workflow 最适合这些场景:
- ETL;
- 定时任务;
- CI/CD;
- 批量数据处理;
- 固定步骤的自动化任务;
- 要求高可靠、可恢复、可重试的流程。
它的优势是稳定、清晰、可恢复。缺点也很明显:
当用户交互很多、需求很模糊、分支很多时,workflow 会变成巨大的状态机。
每一个“用户中途改主意”、每一个“输入格式不标准”、每一个“这一步想跳过”,都可能变成新的 if/else。
这就是我以前写 workflow 最痛苦的地方。
二、Skill:Agent 可以使用的能力包
Skill 解决的是另一个问题:
如何把一个复杂能力封装起来,让 Agent 能够理解、调用和完成任务。
在 Codex、Cursor、Kiro、Claude Code 这类 Agent 平台里,Skill 往往不是一个简单函数,而是一个能力包。
它可能包含:
amazon-analysis-skill/
INSTRUCTIONS.md
config.json
knowledge/
tools/bin/
templates/
examples/
这里的核心不是“固定流程”,而是:
把领域知识、操作说明、工具入口、约束规则打包给 Agent,让 Agent 在任务中自主使用。
Agent 读了 INSTRUCTIONS.md 之后,可以自己判断:
- 当前应该执行哪一步;
- 用户输入是否缺信息;
- 是否需要追问用户;
- 是否要跳过某个步骤;
- 出错后是重试、降级,还是让用户确认;
- 最后应该怎么组织报告。
所以 Skill 的哲学和 Workflow 不一样。
Workflow 是:
代码控制流程,LLM 只是节点。
Skill 更像是:
Agent 控制过程,Skill 提供能力边界和操作工具。
这也是为什么我会选择 Skill 模式来做很多垂直 AI 应用。
我的场景不是简单的“输入 A 输出 B”,而是:
- 用户会中途补充信息;
- 用户可能不懂自己要什么;
- 数据分析过程中需要判断;
- 报告生成需要理解上下文;
- 很多地方没法提前穷举所有分支。
这时候如果强行 workflow 化,就会写出大量状态机和分支逻辑。
而 Skill 模式的好处是:
我只需要描述正常路径、边界条件和禁止行为,中间的弹性判断交给 Agent。
本质上,这是把“穷举所有情况”的成本,转嫁给了 LLM 的泛化能力。
这句话不是说 Agent 万能。恰恰相反,Agent 不可靠,所以 Skill 不能只靠 prompt。
一个好的 Skill 仍然要有硬边界:
- 后端校验参数;
- CLI 封装复杂调用;
- 凭据不要暴露给 Agent;
- 中间结果写文件;
- 输出格式尽量结构化;
- 高风险操作交给代码拦截。
也就是说:
软约束写在 INSTRUCTIONS.md 里,硬约束放在 CLI、后端和服务端。
凡是不能出错的地方,不要只靠 Agent 自觉。
三、Harness:能力运行与治理框架
我之前对 Harness 的理解偏浅,容易把它理解成“更高级的 workflow”。
现在我觉得更准确的定义是:
Harness 不承载具体业务逻辑,它承载的是能力管理逻辑。
它不关心 Amazon 怎么分析,也不关心博客怎么写,更不关心服务器怎么排障。
这些业务能力属于 Skill。
Harness 关心的是:
- 有哪些 Skills;
- 每个 Skill 怎么声明;
- 输入输出 schema 是什么;
- 如何统一执行;
- 如何记录 run 状态;
- 如何保存中间产物;
- 如何记录 trace;
- 如何统一错误码;
- 如何跑 eval;
- 如何做权限和 guardrails;
- 如何让 Agent 通过稳定接口调用这些能力。
如果用一句话说:
Skill 是能力包,Harness 是能力运行时。
或者更具体一点:
Skill Harness 是一套用于创建、运行、测试、追踪和治理多个 Skills 的统一框架。
这就像 Docker 和应用的关系。
Docker 不知道你的业务是博客、数据库、API 还是爬虫,但它统一管理镜像、容器、日志、端口、环境变量和运行状态。
Skill Harness 也一样。它不写具体业务,但它管理 Skill 的执行方式。
一个最小的 Skill Harness 可能会要求每个 Skill 都有统一结构:
skills/
amazon-analysis/
skill.yaml
SKILL.md
schemas/
input.json
output.json
scripts/
run.py
knowledge/
templates/
eval_cases/
其中 skill.yaml 是 Harness 理解 Skill 的入口:
name: amazon_analysis
version: 0.1.0
description: Analyze Amazon products and generate structured reports
entrypoint: scripts/run.py
input_schema: schemas/input.json
output_schema: schemas/output.json
timeout_seconds: 600
permission_level: normal
eval_cases: eval_cases/
有了这个 manifest,Harness 才能统一做事情:
skill-harness list
skill-harness describe amazon_analysis
skill-harness run amazon_analysis --input input.json
skill-harness trace run_xxx
skill-harness eval amazon_analysis
执行一次 Skill 后,Harness 可以统一生成:
runs/{run_id}/
input.json
state.json
trace.jsonl
outputs/
artifacts/
reports/
logs/
这就解决了我现在最真实的问题:
每开发一个新 Skill,都像从 0 开始。
目录结构不统一,配置不统一,CLI 风格不统一,输出格式不统一,错误处理不统一,trace 不统一,eval 也不统一。
当 Skill 很轻的时候,这些问题不明显。
但当 Skill 变重之后,比如一个 Skill 里已经包含:
- Agent instructions;
- 领域知识;
- Go CLI;
- 后端服务;
- 异步任务;
- 文件状态;
- 报告模板;
- 用户确认;
- 安全边界;
这时候每个 Skill 都手搓一套,就会非常痛苦。
所以我现在理解的 Harness,不是为了显得高级,而是为了解决一个很朴素的问题:
把一堆重型 Skills 统一起来。
四、三者不是一条线,而是不同层级
我以前容易把它们想成这样:
Workflow → Harness → Skill
好像它们是同一条线上的不同阶段。
现在我觉得这样不准确。
更合理的分层是:
Agent
↓ 决策 / 规划 / 选择能力
Skill Harness
↓ 统一运行 / 追踪 / 评测 / 权限 / 状态
Skills
↓ 封装具体业务能力
Tools / CLI / API / Backend
Workflow 则是一种流程控制方式,它可以出现在不同层级里:
- 一个 Skill 内部可以有小 workflow;
- Harness 可以用 workflow 管理固定流程;
- Agent runtime 也可以把部分步骤 workflow 化;
- 完全不需要智能的任务,可以只用 workflow。
所以三者关系不是“谁替代谁”,而是:
Workflow = 确定性流程编排方式
Skill = 能力封装形态
Harness = 能力运行与治理框架
它们可以组合。
比如一个成熟系统可能是:
Agent 负责理解目标
↓
Harness 负责统一调度和治理
↓
Skill 提供具体能力
↓
Skill 内部某些步骤用 Workflow 固化
这才是更准确的关系。
五、我为什么一开始选择 Skill
我选择 Skill,不是因为 Harness 不重要,也不是因为 Workflow 没用。
而是因为我当前的问题更适合先用 Skill 落地。
我的场景有几个特点:
- 用户交互密集;
- 输入经常不标准;
- 中间判断很多;
- 报告生成需要理解上下文;
- 我希望跨 Codex、Cursor、Kiro 等 Agent 平台复用;
- 当前很多 Agent 平台并没有给我完整的外部编排接口。
如果我强行写成 workflow,每个用户意图变化都要变成新的分支。
比如用户可能说:
- “这一步先跳过”;
- “换一个类目”;
- “只分析前 5 个”;
- “这个结果不对,重新筛一遍”;
- “先别生成报告,我要改条件”。
这些都写进代码状态机,会非常痛苦。
Skill 模式让我可以把流程写成自然语言约束,让 Agent 在边界内自由发挥。
所以短期我选 Skill,是务实选择。
但经过这次重新梳理,我也意识到:
长期不能只停留在写一个个复杂 Skill。
因为当 Skill 多起来之后,真正的问题会变成复用、统一、测试、追踪和治理。
这时候就必须往 Skill Harness 方向抽象。
六、复杂 Skill 里的 mini-harness
我现在的很多 Skill,其实已经不是轻量 Skill 了。
它们里面已经长出了很多 mini-harness 能力:
- CLI 封装复杂 API;
- config 管理后端地址和 token;
- 文件系统保存中间状态;
- 后端做参数校验;
- 报告模板统一展示;
- 错误输出给 Agent 处理;
- 关键步骤要求用户确认。
这些能力如果只服务于一个 Skill,就还是 Skill 的内部实现。
但如果它们在多个 Skill 中反复出现,就应该抽出来,变成通用 Harness。
判断标准很简单:
只服务一个 Skill,是 Skill 内部 mini-harness;服务多个 Skills,才是真正的 Skill Harness。
这也是我现在最大的认知变化。
我之前以为自己只是在做 Skill。
现在看,我其实已经在每个复杂 Skill 里重复手搓一小套 Harness。
下一步应该把这些重复部分抽象出来。
七、我理想中的 Skill Harness
我现在想做的,不是一个大而全的 Agent 平台。
第一版只需要解决我自己的痛点:
新 Skill 不再从 0 开始。
所以我理想中的 v0.1 应该包含:
- 统一目录结构;
- 统一
skill.yaml; - 统一 CLI 入口;
- 统一 runs 目录;
- 统一 state.json;
- 统一 trace.jsonl;
- 统一错误格式;
- 统一 eval 入口。
也就是说,它不是先去追求什么复杂 AgentOps,而是先把“重型 Skill 的脚手架和运行器”做好。
未来可以逐步加入:
- checkpoint;
- resume;
- waiting_user;
- waiting_backend;
- approval;
- permission;
- guardrails;
- eval dataset;
- MCP 接入;
- Web UI;
- 多 worker 执行。
但第一步很简单:
统一 Skill。
先统一,才能管理。
先管理,才能治理。
先治理,才能谈 Agent Runtime。
八、Harness 怎么接入 Agent
如果 Skill Harness 做好了,它不一定要直接暴露所有业务细节给 Agent。
Agent 不应该重新读一遍所有 Skill 的内部实现。
更合理的是:
Agent
↓ MCP / CLI / HTTP
Skill Harness
↓ manifest + registry
具体 Skill
MCP 也不应该把所有 Skill 的说明复制一遍。
MCP 只需要暴露几个固定工具:
list_skills
describe_skill
run_skill
get_run_trace
get_run_artifacts
run_eval
真正的 Skill 描述仍然来自 skill.yaml 和 SKILL.md。
也就是说:
MCP 是连接线,Harness 是能力管理层,Skills 是能力本体。
不能维护多份重复说明。
正确做法是:
Skill 只有一份 manifest
Harness 读取 manifest
MCP 通过 Harness 动态返回 describe_skill
Agent 通过 run_skill 调用具体能力
这样不会出现“在 Skill 里写一份说明,在 MCP 里再复述一遍”的混乱。
九、我现在的选择
现在我对三者的选择更清楚了。
如果任务是纯确定性的,比如定时同步数据、清洗数据、跑报表,我会选 Workflow。
如果任务是交互式、模糊的、需要 Agent 理解和判断,我会选 Skill。
如果我已经有一堆复杂 Skills,并且开始遇到复用、统一、测试、追踪、权限和状态管理问题,我就需要 Skill Harness。
所以我当前阶段的判断是:
短期用 Skill 落地垂直 AI 应用,长期把多个重型 Skills 抽象进自己的 Skill Harness。
这不是否定 Skill。
恰恰相反,是因为 Skill 做重了、做多了,才需要 Harness。
十、最后的总结
我现在会这样定义这三个概念:
Workflow:确定性流程编排方式。
Skill:Agent 可以使用的能力封装形态。
Harness:管理多个 Skills 的运行、状态、trace、eval、guardrails 的框架。
它们不是互斥关系。
一个好的系统应该是:
用 Workflow 固化确定性流程;
用 Skill 封装垂直业务能力;
用 Harness 统一管理多个 Skills;
用 Agent 在目标驱动下选择和组合这些能力。
我之前最大的误区,是把 Skill 和 Harness 对立起来。
现在我更愿意这样理解:
Skill 是能力,Harness 是能力管理层。
当只有一个 Skill 时,Harness 可能没必要。
当有很多重型 Skills 时,Harness 就不是可选项,而是必然会长出来的工程底座。
这也是我下一步想做的事情:
把我已经写过的复杂 Skills 里重复出现的结构、CLI、状态、trace、eval、错误处理和执行规范抽出来,形成自己的 Skill Harness。
从写 Skill,到管理 Skill,这应该是我接下来最重要的一次升级。
陕公网安备61011302002223号