摘要
大模型出现之后,软件系统里多了一个新的执行单元:LLM 不再只是文本补全接口,而是可以在上下文中理解目标、选择信息、组织推理、调用工具并生成结果的智能组件。围绕这个组件,早期工程实践主要集中在提示工程,即如何把问题写清楚;随后进入上下文工程,即如何把模型需要的信息、约束、工具和状态组织成可使用的工作环境。
但当系统从单次问答走向可复用的 Agent 流程时,仅靠提示词和上下文组织并不够。我们还需要一个更稳定的运行框架:它规定数据如何进入、计算如何完成、模型在什么时候介入、工具输出如何被约束、结果如何被检查、失败如何被记录和修订。本文把这种方法称为 Harness 工程。
Harness 工程不是某个具体库,也不是单个 prompt 模板。它是一套 Agent 设计方法:用确定性的程序、结构化上下文、有限责任的 LLM 节点和可审计日志,把模型能力包进一个可运行、可调试、可演进的工程框架中。
从提示工程到上下文工程
提示工程解决的是“如何问”的问题。
在 LLM 应用早期,很多效果差异来自提示词本身:是否明确角色,是否给出输出格式,是否列出限制条件,是否提供示例。提示工程的核心是把人的意图翻译成模型更容易执行的任务描述。
上下文工程解决的是“模型看见什么”的问题。
当任务变复杂后,单个 prompt 不再是系统的全部。模型需要读取数据、理解历史状态、引用工具结果、遵守业务规则、区分事实和假设。此时工程重点从“写一句好 prompt”转向“构造一个好上下文”:哪些信息应该进入模型窗口,哪些信息应该在代码里计算,哪些信息应该以 schema 形式约束,哪些历史记录应该保留,哪些应该丢弃。
这两者都很重要,但它们仍然偏向模型调用本身。真正的问题是:如果一个任务需要多次模型调用、多种工具、多个检查节点和可重复运行的产物,我们该如何设计整个系统?
这就是 Harness 工程要处理的问题。
动机:为什么需要 Harness 工程
LLM 很强,但它不是数据库、不是计算器、不是任务调度器,也不是天然可靠的审稿人。一个成熟的 Agent 系统不能把所有问题都交给模型自由发挥。
在金融市场报告这样的任务中,这一点尤其明显。模型可以总结市场结构、判断哪些观点有信息增量、组织报告语言;但它不应该自己计算收益率,不应该从原始 CSV 中临时找排名,不应该编造政策原因,也不应该在没有数据支持时声称某个行业上涨来自宏观驱动。
因此,一个可靠的 Agent 系统需要把任务拆成两类:
- 数字计算、数据清洗、格式转换、图表生成,交给确定性脚本。
- 研究取舍、观点组织、语言表达、质量检查,交给 LLM。
Harness 工程的动机,就是把这两类能力放进同一个可控流程里。它不追求让模型“什么都做”,而是让模型在正确的位置做正确的事。
定义:什么是 Harness 工程
Harness 工程是一种面向 LLM Agent 的运行框架设计方法。
它把一个智能任务包装成一个可执行的 harness:外部输入进入系统后,先经过确定性预处理,再被组织成结构化上下文,随后交给一个或多个职责明确的 LLM 节点处理,最后经过检查、修订和静态输出。整个过程有明确的输入输出、日志、错误边界和可替换组件。
一个典型 harness 包含以下部分:
- 输入层:接收用户请求、配置、文件、数据集或交互状态。
- 数据层:读取、清洗、计算和规范化数据。
- 工具层:把确定性能力封装成可调用工具,输出结构化结果。
- 上下文层:选择哪些信息进入模型,并用 schema 限制模型输出。
- LLM 节点层:让模型完成判断、排序、写作、检查等非确定性任务。
- 审查层:检查事实、格式、风格、风险和边界。
- 输出层:生成 Markdown、HTML、PDF、JSON、数据库记录或 UI 状态。
- 日志层:记录每一步输入、输出、模型响应和中间产物。
这个框架的关键,不是“用了多少个模型调用”,而是每个节点是否有清晰职责,每个输出是否能被下游消费,每个失败是否能被定位。
Harness 工程与 Skills 的区别
Skills 和 Harness 工程经常会一起出现,但它们不是同一个层级的东西。
Skill 更像一个局部能力模块。它回答的是:某一类任务应该怎么做?例如扩散度诊断 skill、集中度诊断 skill、标题检查 skill、摘要检查 skill。一个 skill 通常有明确输入、明确输出和相对稳定的提示词或执行逻辑。
Harness 工程则是系统级组织方式。它回答的是:多个 skill、工具、数据和输出如何组成一个完整流程?一个 harness 可以调用多个 skill,也可以在某些步骤完全不调用 LLM。
可以这样区分:
- Skill 是能力单元。
- Harness 是运行框架。
- Skill 解决局部问题。
- Harness 解决端到端任务。
- Skill 关注某个判断或生成动作。
- Harness 关注输入、流程、状态、日志、检查和输出。
在实践中,一个好的 harness 不会让一个超大 skill 承担所有责任。它会把复杂任务拆成有限数量的 skill,并让每个 skill 只回答一个边界清楚的问题。
例子一:静态输入的 Harness 工程
静态输入 harness 指的是输入在运行开始时已经确定,运行过程中不需要用户继续参与。月度市场报告生成就是一个典型例子。
输入可以是:
- 市场:A 股
- 数据集:申万一级行业
- 月份:2026 年 4 月
- 基准:沪深 300
- 输出语言:中文
这个 harness 的流程可以设计为:
load_data()
compute_diagnostics()
generate_charts()
run_analysis_skills()
summarize_findings()
write_report()
review_summary()
review_body()
render_markdown_html_pdf()
write_logs()其中,compute_diagnostics() 不调用 LLM。它负责计算收益率、相对收益、排名变化、上涨扩散度、跑赢基准行业占比、收益集中度等指标。
run_analysis_skills() 才调用 LLM,但每个 skill 的问题被限定得很窄。例如:
- 扩散度分析:本月上涨是否广泛?相比上月扩散度是改善还是收缩?
- 集中度分析:收益是否集中在少数行业?相比上月集中度是否提高?
- 轮动分析:本月领涨是趋势延续还是排名反转?
- 落后行业分析:本月落后行业是持续偏弱还是新近转弱?
模型不负责重新计算这些数字。它只负责解释已经计算好的结构化诊断。
最后,报告写作和审查也可以拆开:摘要由摘要 review skill 检查,正文由报告质量 review skill 检查。这样摘要不会被正文规则拉长,正文也不会被摘要规则压短。
这个例子的重点是:静态输入 harness 的稳定性来自确定性数据层、结构化中间结果和分层 review,而不是来自某个特别长的 prompt。
例子二:需要用户交互的 Harness 工程
另一类 harness 需要用户参与。比如一个研究助理系统,用户不是一次性给出完整任务,而是在过程中不断调整范围:
- 用户先问:“帮我看一下最近一个月哪些行业变化最大。”
- 系统展示初步诊断。
- 用户追问:“只看和沪深 300 的相对表现。”
- 系统重新筛选指标。
- 用户再说:“把电子和通信展开,生成一页简报。”
这种任务不能简单地一次性生成结果。它需要管理会话状态、用户选择、已生成的中间结果和可复用的数据上下文。
一个交互式 harness 可以设计为:
receive_user_message()
classify_intent()
update_session_state()
select_tools_or_skills()
run_deterministic_tools()
call_llm_for_interpretation()
present_intermediate_result()
wait_for_user_feedback()
revise_or_continue()这里的关键是状态管理。系统需要知道用户当前关注的是哪个市场、哪个时间窗口、哪个基准、哪些行业,以及哪些图表已经生成过。
交互式 harness 还需要更严格的边界:
- 用户改变时间范围时,相关诊断必须重新计算。
- 用户要求解释原因时,系统必须区分“数据可支持的结构判断”和“需要外部新闻或宏观数据支持的原因判断”。
- 用户要求导出报告时,系统要把当前会话状态冻结成静态输入,再进入报告生成 harness。
这说明交互式 harness 并不是静态 harness 的替代品。相反,它经常会在最后调用一个静态 harness,把交互过程中形成的选择转化为可复现的报告产物。
设计原则
Harness 工程的核心原则可以概括为五点。
第一,脚本做计算,模型做取舍。
收益率、排名、分位数、聚合统计和格式化数字应该由代码完成。模型负责判断哪些信息重要、如何组织观点、如何表达限制。
第二,节点职责要窄。
一个节点最好只回答一个问题。扩散度、集中度、轮动、摘要、标题、风险提示都可以拆开。节点越窄,错误越容易定位。
第三,中间结果要结构化。
不要只在 prompt 里塞自然语言。能用 JSON 表达的指标、证据、图表引用、分类结果,都应该结构化输出。
第四,审查要分层。
摘要检查、正文检查、事实检查、风格检查、图表检查不应全部混在一个 critic 里。否则某个规则变强时,容易误伤其他部分。
第五,日志是产品的一部分。
Agent 系统的输出不只是最终文本,还包括每一步模型看到了什么、回答了什么、为什么被修订。没有日志,就无法调试,也无法让系统长期演进。
结论
提示工程让我们学会如何向模型表达任务。上下文工程让我们学会如何组织模型需要的信息。Harness 工程则进一步回答:如何把模型放进一个可运行、可检查、可复现的系统。
在这个方法论下,Agent 不是一个自由发挥的聊天机器人,而是一个被工程框架约束的智能执行流程。它既使用 LLM 的判断和表达能力,也保留传统软件工程的确定性、可测试性和可维护性。
未来更成熟的 Agent 系统,竞争力不只来自模型本身,也来自 harness 的质量:数据是否可靠,工具是否清晰,skill 是否内聚,审查是否分层,日志是否完整,输出是否可复现。
一句话概括:
Harness 工程是把 LLM 从“会说话的接口”变成“可运行系统组件”的工程方法。
