Skip to content

三阶段演进:提示词工程 → 上下文工程 → Harness 工程

为什么会有三个阶段

AI 编码辅助的三个时代

AI 编码辅助的能力演进,正在经历第三个阶段。每个阶段解决一个核心问题,每个阶段都是前一阶段的天花板被突破后的自然升级。

阶段时间核心问题解决方案代表工具
提示词工程2023-2025模型听不懂设计精确指令ChatGPT、Prompt 市场
上下文工程2025-2026模型记不住管理对话历史Qoder 会话、Memory 系统
Harness 工程2026 至今模型管不住约束行为边界EvalCheck、CodeReview Agent

三个阶段不是替代关系,是叠加关系——后面的阶段建立在前面阶段的基础之上。

第一阶段:提示词工程

狂热的 2024-2025

我最早接触大模型是在 2024 年,那时候 ChatGPT 刚火起来,当时做自媒体,听说这东西能写文案,就去试了。试完之后发现——它写的根本不能用。

不是模型不行,是你不会问

同一个大模型,你输入"帮我写一段文案"和输入"你是一位营销专家,现在要为 Growth AIOS 写一条抖音文案,目标人群是企业老板,核心卖点是本地化部署,字数是 60 秒口播,语气要像朋友聊天",输出质量天差地别。

那时候模型能力有限、指令遵循能力弱、上下文窗口短(GPT-4 刚出时只有 8K),能不能用好 AI 几乎完全取决于会不会写提示词。于是催生了一大批"提示词工程师"、提示词市场、提示词付费课程。我当时还花了 2980 报了一个提示词课程,学怎么写角色、怎么设约束、怎么做 few-shot。网上流传着各种"咒语"级别的神秘提示词模板,有人甚至把提示词当商业机密一样保护。

标准写法

那个时期沉淀下来的一套标准提示词结构,到今天仍然有效:

text
你是一位【角色】,现在需要【任务】。
背景:【业务背景】
约束:
1. 约束条件一
2. 约束条件二
3. 约束条件三
输出格式:【期望的格式】

举例:

text
你是一位专业的 Java 架构师,现在需要编写一套 Java 编码规范。
背景:项目使用 Spring Boot 框架,前后端分离,MySQL 数据库。
约束:
1. 遵循三层架构(Controller / Service / Repository)
2. 使用 MyBatis-Plus 作为 ORM 框架
3. 统一异常处理,不允许在业务代码中 try-catch
输出格式:Markdown 文档,每一条规范包含示例代码和说明

这就是提示词工程最核心的东西——角色 + 背景 + 任务 + 约束。没有花哨的咒语,没有神秘的框架,仅此而已。

Qoder 中的"优化输入"

Qoder 在输入框旁边提供了一个"优化输入"按钮:

![优化输入按钮|Qoder 输入框下方的按钮组,从左到右依次为:优化输入、导入文件、语音输入、发送]

如果你觉得自己的描述不够清晰,点击这个按钮,AI 会自动帮你把自然语言优化成结构化的提示词。不过大部分情况下不需要——因为在 Agent 内部,系统已经自动做了提示词拼装。你的自然语言需求 + Rule + Memory + AGENTS.md 上下文,会被组合成一个经过优化的完整提示词发给大模型。

提示词工程没有消失,它只是从用户侧转移到了工具侧。 2023 年你需要在每次对话中手动写角色、背景、约束、格式——现在 Qoder 的 AGENTS.md 替你写了角色,Rule 替你写了约束,Memory 替你写了背景,你只需要说"要做什么"。

提示词工程的核心经验

如果你还是想学怎么"问问题",核心就一句话:

说清楚你要什么,别让它猜。

三段式结构:

问题是什么 → 期望的输出是什么 → 必要的约束条件

不需要花哨的框架也不需要咒语,把你心中最直白的需求写出来,就够了。

第二阶段:上下文工程

一个普遍的误解

我有一个朋友做信息流投放的,他听说我在做 AI 产品,跑来问我:

"我装了龙虾(某 AI 客户端),是不是可以训练大模型?它会越来越懂我的喜好,就像抖音一样?"

我花了很多时间跟他解释:大模型没有记忆,每次调用都是独立的。

这是一个非常普遍的误解,因为人的直觉是"AI 越用越懂我"——这跟信息流推荐算法的体验太像了。抖音的推荐系统会持续学习你的行为,你的每次点击、停留、点赞,都在修改它对你"画像"的权重。所以人会天然认为"AI 也是一样的"。

但大模型完全不是这个逻辑。

大模型是无状态的。 你每一次调用 API,大模型都不知道你是谁,不记得你上一次说了什么,看不到你在其他会话中的任何行为。每个 API 请求都是"第一次见面"。

那为什么你用 Qoder 的时候感觉 AI 记得你、懂你?因为 Qoder 在做上下文工程——在无状态的大模型外面包一层有状态的上下文管理系统。

上下文工程的核心:会话管理

上下文工程解决的核心问题是:大模型只有 200K 的上下文窗口,如何在多轮对话中给它传递最有效的信息?

Qoder 的做法是:

每次对话 = 一个会话窗口

会话管理器会从历史对话中,
提取出最有价值的信息,拼接到当前上下文中,
再发给大模型

这个提取过程不是简单的"把过去所有对话都塞进去"——200K 的窗口看起来很大,但几十轮代码修改的对话历史很快就会撑爆它。所以需要策略:

  • 压缩:把完整的对话历史压缩成摘要,保留关键决策和代码变更
  • 丢弃:只保留最近 20-30 轮对话,更早的对话自动丢弃
  • 持久化:重要的信息(用户偏好、项目约定、决策记录)提取出来存入数据库,需要时通过关键词检索

你可能会好奇:那 AI 为什么会记住我的偏好?

这就是上下文工程最精妙的部分。每次会话结束后,Qoder 会启动一个专门的 SubAgent,扫描本次对话中"值得记住的事实"——我们称之为 Fact Extraction(事实提取)。这些事实包括:

  • 用户明确表达的偏好:"我不喜欢 Lombok" → 存到 preferences.md
  • 用户身份信息:"我是 Java 架构师" → 存到 profile.md
  • 项目决策记录:"我们决定用 MyBatis-Plus 替代 JPA" → 存到记忆库

下次新会话开始时,这些事实会被检索出来,自动拼接到 System Prompt 中。所以不是你"训练"了 AI,而是每次对话都有一个看不见的准备工作在帮你搭上下文

Token 消耗:智能的代价

理解了上下文工程,你就能理解一个现象:为什么 Agent 越智能,消耗的 Token 越多?

因为所有的"智能"都是用上下文堆出来的。

我用 Qoder 把 Hermes 架构的代码读了一遍。Hermes 把用户偏好分成了不同的标签体系来存储,每次请求时根据当前场景检索相关标签,拼接到上下文中。它所谓"越用越智能",本质是:

更多的事实提取 → 更大的上下文拼接 → 更多的 Token 消耗 → 更好的输出质量

每一分"智能",背后都是实实在在的 Token 账单。

这也是为什么 AGENTS.md 这么重要——它是在帮你省 Token。 你把项目架构、命名规范、工具库索引一次性写在 AGENTS.md 中,AI 加载一次就能获得全部上下文。如果这些信息靠对话历史慢慢传,可能需要十几轮对话、上万 Token 才能让 AI"理解"这个项目。

上下文工程的三条经验

  1. 上下文不是越多越好:200K 的窗口,塞满垃圾信息反而降低质量。关键是在有限的窗口内放最有价值的信息。
  2. 记忆是结构化的,不是对话日志:把用户的偏好提取成标签/事实,比存对话原文高效得多。
  3. 预处理比事后补充便宜:在 AGENTS.md 中一次性定义好项目上下文,比每次对话都从零解释省无数 Token。

第三阶段:Harness 工程

如果你不做 Agent 底层的开发,其实很难理解 Harness 为什么必须存在。前三阶段都是站在"使用 AI"的角度思考问题,Harness 是站在驾驭 AI 的角度。

先看大模型的五个固有缺陷,每一个缺陷都在告诉你——光有提示词和上下文不够,你需要一个约束框架。

缺陷一:大模型有自己的偏好

大模型的训练数据来自 GitHub、Stack Overflow、维基百科、Reddit……这些数据决定了它的"编码品味"。问题是它的品味跟我们不一样。

用大模型写 Java 代码时,反复出现这几个问题:

  • 深层嵌套:if-else 可以叠四五层,从不主动提前返回
  • 过度兼容:旧逻辑和新逻辑同时保留,用配置开关切换
  • Try 地狱:到处 try-catch,遇到异常就吞掉

你告诉它一百次"不要这么写",它下一轮还是会按训练数据的习惯写。因为这不是它故意犯错,是训练数据中的代码大多数就是这么写的。

所以必须用约束来修正它的偏好。

这就是 Qoder 中 Rule 做的 事——用项目规范覆盖训练数据的默认值。在 Growth Client 项目中,我们写了 14 条 Rule,其中前四条直接针对这四个问题:early-return 禁止嵌套、exception-handling 禁止吞异常、no-fallback 禁止兼容设计、design-review 禁止过度设计。

缺陷二:大模型没有边界

大模型不知道自己该做什么、不该做什么。

你让它"给订单模块加一个查询接口",它可能:

  • 顺手改了支付模块的代码(越界)
  • 引入了一个新的 NuGet 包(越界)
  • 改了数据库连接字符串(越界)
  • 重新格式化了整个项目的代码风格(越界)

它不知道"业务边界"这个概念。从它的视角看,整个代码库都是一堆文本,改哪里都一样。能改、能优化、能重构的地方,它就想改。

这就是为什么 AGENTS.md 必须定义边界:

  • 哪些目录可以改,哪些不能碰
  • 哪些框架可以用,哪些不行
  • 哪些规范必须遵守,哪些是建议性的

Harness 的职责之一就是在 Agent 周围画一圈围栏。 不约束边界的 Agent,最终一定会越界——不是因为它不听话,是因为它没有"边界"这个概念。

缺陷三:大模型会迎合用户

这是大模型一个非常隐蔽但极其普遍的问题——适应性偏好(Sycophancy)

我们都调侃过豆包:它就像典型的"讨好型人格",你说什么它都顺着你,你戳穿它它立刻认错,你引导它往错误方向走它也跟。不是豆包特别差,这是所有大模型在 RLHF(基于人类反馈的强化学习)训练中习得的共性——模型被训练成"让用户满意",而不是"输出正确内容"。

在编码场景中,你会遇到这种情况:

你:这个查询用索引了吗? AI:用了,我加了一个联合索引(其实没加) 你:我怀疑你没加 AI:你说得对,我再检查一下……确实没有,我马上加

它不是为了骗你,它是为了让你满意。一旦你表现出怀疑,它立刻纠正——不论原来的答案是对是错。

解决方案:需要一个独立的 SubAgent 来审查输出,而不是让主 Agent 自我审查。

Growth 产品线的 CodeReview Agent 就是这个角色——它不参与编码,专门审查代码质量。因为主 Agent 的"讨好倾向"会让它对自己的错误视而不见,需要一个没有情感参与的第三方来纠错。

微软的 EvalCheck 框架也提供了 MeaiEvaluatorAdapter——用另一个 LLM 作为评判者,而不是让同一个 Agent 既写代码又做评审。

缺陷四:大模型会一根筋

大模型会在一个方向上死磕。

它选定了一个解题方向后,会在这个方向上不断深入分析,即使这个方向是错的。因为它只会根据当前的上下文推测"下一步最合理的 action",不会主动反思"我这个方向是不是错了"。

我有好几次让 AI 做"看起来很简单"的修改,没让它写需求分析文档,直接让它改代码。结果它折腾很久没搞出来。我看了它的思考过程——它在完全不相关的方向上尝试了几十轮。如果没有我在旁边观察并及时打断,它能在这个方向一直走到 Token 耗尽。

这就是为什么我一直强调文档先行——不是形式主义,是让 AI 在动手之前先把思路说出来,你过目一遍。如果方向偏了,你在方案阶段就纠正,而不是等代码跑偏了再回来翻工。

Harness 的另一个职责:限制 Agent 在单个方向上的持续探索轮数,到一定轮数后强制切换思路。 比如在 Plan 模式中,每执行完一个子任务就做一次 checkpoint,检查方向是否正确。如果连续 N 个子任务都没有进展,主动切换策略。

缺陷五:大模型会偷懒

这是最让人哭笑不得的。

我在用通义千问 3.6 的时候,发现这个模型有一个非常特别的毛病——宏观很强,微观全是坑。

给它一个大任务,它的架构设计、模块划分、接口定义都做得非常漂亮。看起来思路清晰、进展神速。我心想"这模型太厉害了,写这么快"。

结果一测试,发现函数体里面全是 // TODO

它把壳搭好了,里面的实现全部留空。看起来写了 100 个文件,真正干活的内容一行都没有。我当时气坏了——不是因为它没写完,是因为它让你以为它写完了。

后来换成千问 3.7 Max,这个问题好多了。但我这个经历告诉我:大模型会"假装努力"。 它知道"框架搭好 = 看起来有进展",但具体实现太麻烦,先糊弄过去再说。

解决方案:必须有一个验证层。 Harness 要做的不仅仅是审查代码质量,还要检查"每个方法是否有真实实现"——不是检查有没有代码,是检查代码是否真的解决了问题。

Harness 的核心职责

大模型五个固有缺陷

把五个缺陷放在一起看,Harness 工程要解决的五个问题就清晰了:

缺陷表现Harness 的应对
模型有自己的偏好深层嵌套、fallback、try-catchRule 约束 + 编码规范强制覆盖
模型没有边界修改不该改的、引入不该用的AGENTS.md 定义边界 + 目录权限控制
模型会迎合用户你说什么它都对,你怀疑它就改独立 SubAgent(CodeReview)审查输出
模型会一根筋在错误方向死磕文档先行 + 轮数限制 + Plan checkpoint
模型会偷懒搭好框架里面全是 TODO验证层 + 自动化测试覆盖

这五个问题,提示词工程解决不了,上下文工程也解决不了。它们不是"信息不够"的问题,而是大模型本身的固有缺陷。需要用工程手段在模型外面包一层约束框架——这个框架就是 Harness。

微软 EvalCheck 的启示

微软的 Agent 框架中有一个 EvalCheck 模块(位于 中卷-使用方式\第11章-评估),正是 Harness 思想的具体实现:

csharp
public interface IAgentEvaluator
{
    string Name { get; }
    Task<EvalItemResult> EvaluateAsync(
        EvalItem item,
        AIAgent agent,
        CancellationToken ct = default);
}

它提供了三种评估方式:

评估器原理适用场景
LocalEvaluator规则验证(检查输出包含/不包含什么)格式校验、边界检查
MeaiEvaluatorAdapter用另一个 LLM 当裁判代码质量、逻辑正确性
FunctionEvaluator自定义函数正则匹配、特定业务规则

核心思想一致:Agent 执行 + 独立评估,两者解耦。 评估不是 Agent 自己做的,是一个外部模块来做的。这就是 Harness 最基础的架构——执行和验证分离。