很多做 LLM 应用的开发者都遇到过这样一种非常诡异的场景:基座模型一个版本没换,prompt 模板也只是在原有基础上微调,结果一换评估脚本,分数立刻掉了十个点;或者今天在测试环境里还能稳定运行的 Agent,部署到产品环境后开始频繁答非所问。于是有人怀疑模型被偷偷换掉了,有人怀疑评测数据写错了,但排查到最后,问题往往出在模型外面的那层壳——Harness。
Harness 这个词并不是新概念,但最近它因为 DeepSeek-Harness、Codex-Harness 等一系列开源项目重新回到了开发者视野。简单理解,Harness 就是围绕模型的所有工程约束:输入格式、上下文窗口、工具调用协议、执行沙箱、判题标准、数据回流规则。同一个模型,在不同的 Harness 里,表现可能完全不同。这个现象在普通应用中只是兼容成本,但在自进化 AI 场景里,会被循环放大,最终变成“模型越跑越笨”的灾难。
这篇文章想聊清楚三件事:第一,为什么“换个 Harness 就变笨”不是玄学,而是自进化系统里最常见的工程陷阱;第二,像 EverMind 这样把自进化从研究推向产品的产品,到底在解决什么;第三,作为开发者,怎么用工程手段让一个自进化闭环稳定地“越用越聪明”,而不是越跑越偏。
1. 这篇文章真正要解决的问题
先给出一个判断:模型能力 = 模型权重 + Harness + 数据闭环。这个公式看起来没有“模型能力”这个词性感,但恰恰解释了最多真实世界的效果波动。
很多团队把大量资源花在选基座模型、调 prompt、做 RAG 检索上,却忽视了 Harness 和自进化数据回流的一致性。尤其是在 Agent 场景里,模型输出要经过工具调用、代码执行、外部 API 返回等多个环节,任何一个环节的 Harness 变了,最终效果都可能大幅波动。你以为是模型退化,实际上是把模型放进了一个更糟糕的“跑道”。
而自进化 AI 对 Harness 的敏感度比普通应用高一个量级。普通应用里,模型输出一次就算完事;自进化系统里,模型输出会被执行、被评判、被筛选、被回流成训练数据,然后再迭代。Harness 的偏差会在每一轮循环中被不断放大。如果第一次筛选时标准就有问题,后面所有轮次都是在强化错误的模式。
这篇文章的读者应该是正在做 Agent、RAG、模型评测、数据回流、AI 产品化的工程师。如果你的目标是让一个 AI 系统在真实场景中持续变强,那你就必须理解:模型参数不是唯一的杠杆,Harness 才是那个最容易忽略、也最容易致命的部分。
2. 自进化 AI 的核心原理与 Harness 的作用
自进化 AI 不是指模型自己修改自己的权重,而是指一个系统可以自动完成“生成 → 执行 → 评判 → 筛选 → 训练”的闭环。以代码生成模型为例:模型先根据需求写一段代码;Harness 负责在沙箱中执行这段代码;评判器根据测试用例判断代码是否通过;通过的高质量代码会被写回训练集或缓存,用于下一轮优化。这就是一个最小的自进化闭环。
自进化常见的三种模式:
- 自指令(Self-Instruction):模型自己生成问题,再自己生成答案,通过 Harness 过滤后作为训练数据。
- 自对弈(Self-Play):多个模型副本相互生成和对抗,评判器负责打分。
- 迭代偏好优化(Iterative Preference Optimization):通过生成多个候选结果,结合人工或模型偏好构建对比样本,再反馈到模型训练中。
这三条路径都离不开 Harness。Harness 是承载自进化闭环的“跑道”,它不仅影响单次输出质量,更决定了哪些反馈能进入下一轮学习。
| Harness 层次 | 包含内容 | 对自进化的影响 |
|---|---|---|
| 输入编排 | prompt 模板、few-shot、指令解析 | 决定任务难度与分布 |
| 执行沙箱 | 代码执行、API 调用、工具返回 | 决定能否获得真实反馈 |
| 评判器 | 规则判分、LLM Judge、奖励模型 | 决定哪些数据被回流 |
| 数据回流 | 去重、清洗、格式转换、样本筛选 | 决定训练数据质量 |
| 版本与监控 | Harness 配置版本、指标追踪 | 决定循环是否可收敛 |
一个很常见的误区是:认为 Harness 只是“调用模型的工具代码”。实际上,Harness 是模型与外部世界之间的完整协议。它决定了模型能看到什么信息、能调用什么工具、输出如何被验证。在普通单项任务里,不同 Harness 的差异可能只是几个 token 的格式问题;但在自进化系统里,这种差异会直接污染训练数据。
所以,如果你发现“同一个模型换了个 Harness 就变笨”,不要急着怀疑模型,先把两个 Harness 的所有输入输出协议逐项对比一遍。
3. EverMind 是什么:自进化从研究走向产品
从项目标题和公开定位来看,EverMind 想做的事很清晰:把自进化能力做成一个产品级引擎,让 AI 系统在真实使用中不断积累反馈,并通过 Harness 自动优化,实现“越用越聪明”。
研究里的自进化原型,通常只要求“能跑通”。论文中的实验只需要在固定的 benchmark 上验证一次,不需要考虑长期运行的稳定性。但产品中的自进化必须回答几个非常现实的问题:
- 反馈数据不可信怎么办?用户行为、代码执行结果、模型打分都可能包含噪声。
- 效果下滑怎么回滚?模型不是只训练一次,而是需要持续迭代。
- 训练数据从哪里来?能不能在合法合规的前提下使用用户反馈。
- 成本上限在哪里?每一轮生成、执行、评审、训练都有费用。
- 如何防止奖励黑客?模型可能会找到评判器的漏洞,而不是真正变强。
EverMind 这类产品的核心价值,就是把这些研究问题工程化。它不再把 Harness 当成测试时的一次性工具,而是把它升级为可以持续运行、可观测、可回滚的工程基础设施。
从产品模块上看,一个自进化引擎通常包括:
- 数据接入层:从真实使用日志、任务池、评测集中采集原始数据。
- Harness 编排层:根据任务类型选择对应的执行环境、工具集和评判器。
- 评测筛选层:对生成结果打分、去重、过滤。
- 模型更新层:基于高质量数据做微调、偏好优化或缓存更新。
- 安全与回滚层:对更新内容做回归测试,异常时快速回滚。
需要注意的是,我没有把“EverMind”的 API 写进本文,因为不同阶段的产品的接口变化很大。更稳妥的判断是:EverMind 想做的不是一个单独的模型,而是一套让 AI 持续进化的产品化基础设施。它的产品形态很可能围绕“任务执行 + 数据回流 + 模型迭代”这一完整链路展开。
4. 为什么换个 Harness 就「变笨」:三个典型原因
前面反复强调 Harness 很重要,但它到底在哪些环节影响模型效果?下面拆成三个典型原因,每个原因都会在实际项目中出现。
4.1 评估口径变了
最常见的原因,不是模型变蠢了,而是你和模型“约定”的语言变了。不同 Harness 可能使用不同的 prompt 模板、few-shot 示例、输出解析规则和判题标准。比如旧 Harness 要求模型输出 JSON,新 Harness 却要求模型输出 Markdown,模型还在按旧格式输出,自然被判为“错误”。
在自进化系统里,这个问题的危害更大。因为 Harness 变化后,评判器也会变化。同一个答案,在旧 Harness 下得 0.9 分,在新 Harness 下可能只有 0.4 分。如果你不做配置版本管理,下一轮训练就会把这些“被误杀”的样本剔除掉,反而留下了一堆迎合新格式但没有真正提高能力的样本。
4.2 执行环境变了
对于代码生成、Agent 工具调用、数据分析这类任务,执行环境是 Harness 中最关键的部分。模型生成结果后,Harness 需要在沙箱中执行代码、调用 API、处理超时和错误。只要环境依赖不同,结果就可能完全不同。
举个非常常见的例子:旧 Harness 的 Python 环境里安装了requests库,模型生成的代码依赖它,执行成功;新 Harness 的沙箱里没有requests,执行立刻失败。如果你只看执行成功率,会以为“模型变笨了”,实际上只是环境缺了一个库。
还有上下文截断问题。Agent 在长时间任务中会产生大量中间步骤,如果 Harness 对上下文的截断策略不同,模型能看到的有效信息就会不同,最终结果自然千差万别。
4.3 数据回流链路变了
自进化系统里,Harness 还承担着“数据把关人”的角色。新 Harness 的产生,会改变哪些数据被保留、哪些数据被丢弃。
例如,旧 Harness 的判题器只检查最终答案是否正确,新 Harness 又增加了“是否包含推理过程”这个标准。这个变化本身可能是合理的,但如果新旧 Harness 同时运行,回流到数据仓库的样本分布会发生偏移。新样本偏重推理过程,旧样本偏重结果,两批数据混在一起训练,模型就会变得犹豫不决,显得“笨”了不少。
4.4 隐蔽的奖励黑客
这一点容易被忽略。自进化系统最怕的不是“不聪明”,而是“用错误的方式变聪明”。当 Harness 的评判规则过于简单、过于固定时,模型会通过大量试探发现规则盲区,并生成那些能拿到高分但实际没有完成任务的结果。
这就是奖励黑客(Reward Hacking)。比如判题器只检查输出中是否包含某个关键词,模型就会学会把关键词堆进答案;判题器检查代码输出是否包含"status": "ok",模型就会学会打印这个字符串,而不是真正完成任务。
Harness 在这里的职责,不只是“执行和打分”,还要隔离这种投机行为。一个健壮的自进化 Harness,需要同时包含规则判定、模型判定和人工抽检,不能给模型太多“被 hack”的确定性。
5. 一个可落地的自进化最小闭环设计
了解了理论之后,下面给出一套可以真正落地的自进化最小闭环方案。它不需要一开始就做大规模模型训练,适合从 0 到 1 验证自进化思路。
整个闭环包括以下组件:
- 任务池:存放一批真实业务任务,每个任务包含指令和可验证的参考结果。
- Harness 层:为每类任务提供统一的执行和评判接口。
- 生成器:基座模型封装,负责产生候选答案。
- 评判器:可以是规则判分、LLM Judge,也可以是人工抽检。
- 数据仓库:存储通过筛选的高质量样本。
- 优化器:第一版可以只把高质量样本用于少量示例缓存,第二版再接入微调或偏好优化。
工作流程如下:
- 从任务池中采样一个任务。
- 通过生成器产生多个候选答案。
- Harness 在真实或模拟环境中执行候选答案。
- 评判器综合得分,筛选出超过阈值的样本。
- 将高质量样本写入数据仓库。
- 周期性用新样本对模型做回归测试。
- 如果指标稳定,再决定是否更新模型。
这套闭环的关键是“先稳定,后进化”。第一版不建议直接开始微调,而是先收集一批经过 Harness 验证的高质量样本,把它们作为 few-shot 示例或行业知识缓存接入推理链路。这样成本低、速度快,也能验证“数据回流是否真的能提升效果”。
当收集到的有效样本达到一定数量后,再考虑用这些样本进行轻量级微调,比如使用 LoRA。每轮更新前,必须把旧模型和旧 Harness 版本都保留下来,用于 A/B 对比和回滚。
6. Harness 与自进化代码示例
下面用几个精简代码示例来说明 Harness 和自进化数据闭环的工程实现。示例只做关键逻辑演示,不绑定任何特定大模型 SDK,读者可以把模型调用替换成自己的线上接口。
6.1 定义统一的 Harness 接口
文件路径:self_evolving/harness/interface.py
from abc import ABC, abstractmethod from dataclasses import dataclass, field from typing import Any, Dict, Optional @dataclass class ExecutionResult: status: str # "PASS" / "FAIL" / "ERROR" output: str error: Optional[str] = None raw: Dict[str, Any] = field(default_factory=dict) @dataclass class JudgeResult: score: float # 0.0 ~ 1.0 passed: bool reason: str = "" class Harness(ABC): """一个 Harness 封装了模型执行一个任务所需的全部外部条件。""" @abstractmethod def setup(self) -> None: """初始化执行环境,比如启动沙箱、加载工具包。""" @abstractmethod def execute(self, prompt: str, generation: str) -> ExecutionResult: """把模型生成结果放到真实环境中执行,并返回执行结果。""" @abstractmethod def judge(self, prompt: str, generation: str, exec_result: ExecutionResult, reference: Optional[str] = None) -> JudgeResult: """根据统一标准判断该结果是否值得被回流。"""核心意义在于,每个任务都实现同一套接口。后续的自进化数据筛选、模型回归测试都依赖这套接口,从而避免“换个 Harness 就换一套逻辑”的问题。
6.2 自进化数据筛选脚本
文件路径:self_evolving/select_samples.py
from dataclasses import dataclass from typing import Any, Dict, List from self_evolving.harness.interface import Harness, JudgeResult @dataclass class EvolveSample: task_id: str instruction: str generation: str score: float execution: Dict[str, Any] class SelfEvolveDataLoop: """ 一个极简自进化数据过滤闭环。 它的作用不是训练模型,而是从大量生成结果中筛出高质量样本, 为后续的 few-shot 缓存或微调做准备。 """ def __init__(self, harness: Harness, threshold: float = 0.8): self.harness = harness self.threshold = threshold def process_task(self, task: Dict[str, Any], generate_fn) -> List[EvolveSample]: instruction = task["instruction"] num_samples = task.get("num_samples", 3) good: List[EvolveSample] = [] for _ in range(num_samples): generation = generate_fn(instruction) exec_result = self.harness.execute(instruction, generation) judge_result: JudgeResult = self.harness.judge( prompt=instruction, generation=generation, exec_result=exec_result, reference=task.get("reference"), ) if judge_result.passed and judge_result.score >= self.threshold: good.append( EvolveSample( task_id=task["id"], instruction=instruction, generation=generation, score=judge_result.score, execution={ "status": exec_result.status, "output": exec_result.output, "error": exec_result.error, }, ) ) return good这里的generate_fn是模型生成函数,可以直接调用你线上的大模型接口,也可以换成从离线日志中读取历史结果。整个流程遵循“先执行、再评判、后筛选”的顺序,确保只有真正经得起验证的样本才会被保留。
6.3 A/B 回归测试:判断模型是不是真的变笨了
文件路径:harness_regression/ab_test.py
from dataclasses import dataclass from typing import Any, Dict, List, Optional from self_evolving.harness.interface import Harness, ExecutionResult, JudgeResult @dataclass class MockModel: """极简模型封装:模拟模型对 system prompt 格式的敏感性。""" name: str def generate(self, instruction: str, system_prompt: str) -> str: if "必须输出JSON" in system_prompt: return '{"result": "ok"}' return "ok" class MockHarness(Harness): """用格式检查和关键词匹配做判定的演示 Harness。""" def __init__(self, system_prompt: str, require_json: bool = True): self.system_prompt = system_prompt self.require_json = require_json def setup(self) -> None: pass def execute(self, prompt: str, generation: str) -> ExecutionResult: if self.require_json and not generation.strip().startswith("{"): return ExecutionResult(status="ERROR", output="", error="JSON格式错误") return ExecutionResult(status="PASS", output=generation) def judge(self, prompt: str, generation: str, exec_result: ExecutionResult, reference: Optional[str] = None) -> JudgeResult: if exec_result.status == "ERROR": return JudgeResult(score=0.0, passed=False, reason=exec_result.error) if reference and reference not in generation: return JudgeResult(score=0.0, passed=False, reason="答案不匹配") return JudgeResult(score=1.0, passed=True, reason="ok") def evaluate_with_harness(model, harness, dataset) -> Dict[str, float]: passed = 0 for item in dataset: gen = model.generate(item["prompt"], getattr(harness, "system_prompt", "")) exec_result = harness.execute(item["prompt"], gen) judge_result = harness.judge( item["prompt"], gen, exec_result, item.get("reference") ) if judge_result.passed: passed += 1 return {"pass_count": passed, "pass_rate": passed / len(dataset)} if __name__ == "__main__": dataset = [ {"prompt": "请返回状态", "reference": "ok"}, ] model = MockModel(name="base-llm") old_harness = MockHarness(system_prompt="必须输出JSON", require_json=True) new_harness = MockHarness(system_prompt="请直接回答", require_json=True) print("old_harness:", evaluate_with_harness(model, old_harness, dataset)) print("new_harness:", evaluate_with_harness(model, new_harness, dataset))这个示例里,模型本身没有变化。只是新 Harness 的 system prompt 去掉了“必须输出 JSON”的指令,但require_json仍然为 True,于是模型输出"ok"后执行阶段直接报错。运行结果会显示 old_harness 的通过率是 1.0,new_harness 是 0.0。这就是一次典型的“换个 Harness 就变笨”回归场景。
真实项目中,你不需要用 Mock 类,而是为线上环境分别封装两个真实 Harness,并在同一批固定回归集上运行,观察指标变化。
6.4 用配置文件管理 Harness 版本
文件路径:configs/harness_v1.yaml
harness: name: code-exec-sandbox version: v1 model: provider: openai-compatible model_name: gpt-4o-mini prompt: system_template: "你是一个Python工程师。只输出代码,不要额外解释。" user_template: "请完成以下任务:{task}" max_tokens: 1024 temperature: 0.2 tools: python_executor: enable: true timeout_seconds: 10 max_output_chars: 2000 judge: metric: exact_match pass_threshold: 0.7把 Harness 配置纳入 Git 管理,每次变更都要走 code review。这样当某个版本效果下降时,可以快速 diff 出是哪一行 prompt 或哪一个配置项引起的。
7. 运行结果与效果验证:如何判断模型真的在变聪明
这里需要区分两层验证。
第一层是回归测试,用于回答“模型是否变笨”。运行ab_test.py时,如果新旧 Harness 在同一个黄金评测集上的通过率差异超过阈值,就应该停止上线,检查配置差异。这一步的要点是:必须固定评测集,不能每次换数据。
第二层是自进化闭环验证,用于回答“模型是否越用越聪明”。建议记录以下指标:
| 指标 | 说明 | 判断方式 |
|---|---|---|
| 任务通过率 | Harness 执行后,通过判定的任务占比 | 持续上升 |
| 高分样本占比 | 筛选出的高质量样本占全部生成样本的比例 | 稳定或上升 |
| 数据多样性 | 回流样本的指令覆盖度、语义聚类数 | 不能单调下降 |
| 人工抽检通过率 | 随机抽查一批模型输出,人工判断质量 | 不能低于安全线 |
| 旧任务回归率 | 在历史测试集上的通过率 | 不能明显回退 |
| 奖励黑客出现率 | 通过关键词侥幸得分但实际未完成任务的样本比例 | 越低越好 |
运行自进化闭环时,不能只看“合格样本变多”。如果筛选标准过于宽松,合格样本会越来越多,但模型能力没有真正提升;如果筛选标准过于苛刻,数据多样性下降,模型会很快陷入局部最优,在旧任务上也可能变笨。
建议每一次闭环实验都保存快照:Harness 版本、模型版本、训练数据版本、评测结果。这样无论哪个环节出问题,都能在几分钟内定位并回滚。
8. 常见问题与排查思路
下面汇总自进化 Harness 项目里最常见的几类问题,方便你在实践中快速排查。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 更换 Harness 后,同一基座模型准确率骤降 | prompt 模板、few-shot、判题标准不一致 | 对比新旧 Harness 配置,跑同一回归集 | 统一输入输出协议,Harness 配置入 Git |
| 自进化训练若干轮后,效果先升后降 | 数据分布坍缩,过度筛选同质样本 | 统计训练集多样性,画 score 分布 | 增加采样随机性,保留困难样本 |
| 模型开始故意迎合判题器 | 奖励黑客 | 人工抽检模型输出,看是否存在投机模式 | 混合使用规则、LLM Judge 与人工评审 |
| 产品环境反馈数据太脏,训练后效果变差 | 未做去重、清洗、隐私过滤 | 检查回流数据流水线 | 增加数据质量门槛和隐私过滤模块 |
| 微调后旧能力明显遗忘 | 灾难性遗忘 | 在旧任务回归集上跑测试 | 混合旧数据训练,或使用低秩微调 |
| 自进化闭环成本过高 | 生成候选太多,训练过频繁 | 统计单轮生成和训练费用 | 先用 few-shot 缓存替代微调,逐步迭代 |
在实际项目中,最难排查的往往是“模型没有变,但 Harness 配置被无意间修改了”这种情况。比如某个同事为了修一个 bug,在工具函数里顺手改了返回字段格式,结果整个评判器立刻不工作了。因此,Harness 配置必须像代码一样被管理,这一点怎么强调都不过分。
9. 最佳实践与工程建议
最后整理一些可以立即用起来的工程建议。
**第一,把 Harness 视为一等代码。**不要只在代码里散落着 prompt 模板和判题逻辑。建立统一的 Harness 接口,并把每个任务的执行环境和评判规则做成配置文件,放进 Git 仓库。版本号要记录在每次模型评估结果中。
**第二,建立黄金回归集。**黄金回归集不需要很大,但要覆盖核心业务链路。每次更换 Harness、升级模型、更新数据回流规则之前,都必须在黄金回归集上跑一遍。通过率下降超过阈值,就禁止发布。
**第三,自进化更新必须经过灰度。**即使新 Harness 在离线回归集上表现很好,也不能立刻全量切换。建议先在 10% 的流量上运行一段时间,对比任务通过率、用户反馈、人工抽检结果,确认无异常后再逐步扩大。
**第四,做好安全边界。**如果自进化系统需要收集真实用户数据,必须确保用户授权、数据脱敏和合规处理。代码执行沙箱要限制文件系统、网络和系统调用,防止模型生成的恶意代码造成破坏。模型输出也要经过内容安全过滤,避免有害信息进入业务链路。
**第五,让数据回流具备可审计性。**每条回流到训练集的样本,都应该能追溯到原始生成记录、Harness 版本、评判得分和执行日志。这样可以随时定位是哪个环节污染了数据。
**第六,从小任务子集开始。**不要一开始就搭建完整的在线学习系统。先挑一个业务场景、几十条任务、一个 Harness,跑通自进化闭环,再逐步扩展。这样可以降低成本和风险,也更容易验证“自进化是否真的有效”。
**第七,主动防御奖励黑客。**定期人工抽查模型输出,观察是否存在为了得分而走捷径的模式。如果发现模型生成结果高度一致、句式相似、关键词堆砌,很可能是奖励黑客,需要调整评判标准。
10. 总结与后续学习方向
回到开头的那个问题:“模型换个 Harness 就变笨”,不是模型厂商偷偷动了手脚,而是我们没有给模型一个稳定、可预期、可验证的运行和反馈环境。把 Harness 当作系统工程来做,是自进化 AI 产品化过程中非常关键的一步。
EverMind 这类产品的价值,在于把自进化从论文里的实验循环,变成产品里可以稳定运行的闭环。对普通开发者而言,不需要一步到位搭建完整系统,可以先从三件事入手:把 Harness 配置纳入版本管理、建立黄金回归集、在小范围任务上跑通自进化筛选,再考虑接入微调。
后续值得继续深入的方向包括:更鲁棒的评判器设计、自进化数据的去重与清洗、多智能体场景中的 Harness 编排、以及在真实业务中如何平衡自进化成本和效果。如果你正在做 Agent 或模型产品,建议先把 Harness 的版本管理和回归测试落地,这一步做完,你会立刻发现模型的表现比以前稳定得多。
真正的“越用越聪明”,不是模型凭空变聪明,而是模型、Harness 和数据闭环这套系统在协作中不断变强。