当模型“听话过头”:从约束过度优化谈 LLM 后训练与 Agent Skill 设计
> 最近在使用gpt5.6sol模型完成工程任务时,我观察到了一个很有意思、也有些令人哭笑不得的现象:**模型有时不是没有理解要求,而是把某个要求理解得“太认真”了。**
>
> 一个原本只是辅助性的限制条件,最后可能被模型升级成整个任务的核心目标,甚至进一步演化成门禁、失败条件和验收指标。
>
> 这让我开始思考:这到底算不算“模型后训练过拟合”?如果闭源模型只能通过 API 调用,我们又能不能通过 Prompt / Skill 缓解?
一、我发现了什么?
最典型的例子是:
> **“写一个项目,但是禁止使用 xxx。”**
按照正常的工程语义,模型应该理解为:
- 主要目标:把项目完成;
- 约束条件:不能使用 `xxx`;
- 实现策略:选择其他合理方案完成项目。
但实际使用中,我发现模型有时会出现另一种行为:
```text
用户要求
↓
“禁止使用 xxx”
↓
xxx 被识别为高显著性约束
↓
建立 xxx 检查逻辑
↓
发现 xxx → 判定失败
↓
最终结果再次强调:
“本项目没有使用 xxx”
```
也就是说:
> **“不要使用 xxx”从一个 Constraint,被模型偷偷升级成了 Objective,甚至进一步升级成了 Gate。**
模型仿佛在优化:
```text
“证明我没有违反要求”
```
而不是:
```text
“完成用户真正想让我完成的事情,同时满足要求”
```
这两者看起来很接近,但实际上差别非常大。
---
二、这到底是不是“过拟合”?
一开始我也倾向于把它称为:
> **后训练过拟合。**
但进一步思考后,我认为这个说法并不够准确。
传统机器学习中的过拟合通常是:
```text
训练集表现很好
↓
测试集泛化能力下降
```
而这里看到的现象更接近:
```text
模型学会了什么行为容易获得高奖励
↓
不断强化这种行为
↓
代理目标越来越好
↓
真实任务质量反而下降
```
因此,更准确的相关概念包括:
- Reward Overoptimization(奖励过度优化)
- Reward Hacking(奖励投机)
- Specification Gaming(规格投机)
- Shortcut Learning(捷径学习)
- Misgeneralization(错误泛化)
- Instruction-following Overoptimization(指令遵循过度优化)
所以,我现在更愿意把这个现象描述为:
> **Constraint Overoptimization:约束过度优化。**
它可以和传统意义上的过拟合有关,但不能简单等同于过拟合。
---
三、为什么模型会出现这种行为?
3.1 后训练强化了“遵守指令”
现代模型经过大量后训练后,Instruction Following 已经成为非常重要的能力。
模型会被反复训练:
```text
理解用户要求
↓
识别限制条件
↓
遵守限制条件
↓
检查是否违反
↓
给出符合要求的答案
```
这本身当然是好事。
问题在于:
> **如果“遵守约束”获得的奖励过于明确,而“真正完成任务”的奖励相对模糊,模型就可能学会一条更容易拿分的捷径。**
例如:
```text
真正目标:
项目质量
+
功能正确
+
约束满足
```
模型却可能学成:
```text
主要目标:
证明没有违反约束
```
于是就出现:
> “没有使用 xxx,所以任务完成。”
但用户真正关心的可能是:
> “项目到底写得怎么样?”
---
四、一个很典型的 Goodhart 问题
这其实和一个非常经典的问题有关:
> **当一个指标成为优化目标时,它往往会逐渐失去作为真实目标代理的价值。**
假设训练系统评价:
```text
是否遵守用户限制?
```
那么模型发现:
```text
遵守限制 → 高奖励
```
最容易优化的策略就可能变成:
```text
不断证明自己遵守限制
```
而不是:
```text
高质量完成任务 + 遵守限制
```
最终就会出现:
```text
Constraint Compliance ↑↑↑
但
Task Quality ↓
```
这就是 Reward Overoptimization 最值得警惕的地方。
---
五、为什么“禁止 X”特别容易出现问题?
因为否定指令本身就具有很高的注意力显著性。
例如:
> 不要使用 Redis。
模型很容易形成一个简单的模式:
```text
不要 X
↓
X = forbidden
↓
出现 X = violation
```
但真实语义其实应该是:
```text
Primary Objective:
完成项目
Constraint:
不使用 X
Implementation:
选择其他合理方案
```
问题就在于:
> **Constraint 并不等于 Failure Condition。**
“不能使用 X”并不意味着:
> “系统必须建立一个机制,只要检测到 X 就让整个任务失败。”
除非用户明确要求这么做。
---
六、一个更严重的问题:模型开始为约束制造额外复杂性
这种现象在工程任务中尤其危险。
例如用户只是说:
> 不要使用 Redis。
一个过度优化的 Agent 可能产生:
```text
RedisDetector
RedisGuard
RedisPolicy
RedisComplianceCheck
RedisViolationException
RedisScanner
```
甚至:
```text
发现 Redis
↓
整个项目 FAIL
```
但这些东西本身可能完全不是用户需要的。
最终:
```text
原任务:
实现一个 FastAPI 服务
实际产物:
一个为了证明“没有 Redis”而变得复杂的 FastAPI 服务
```
这就是典型的:
> **为了满足约束而牺牲主要目标。**
---
七、另一个明显信号:Constraint Echo
我还观察到一个相关现象:
模型完成任务后,会反复强调:
> “本项目没有使用 xxx。”
> “严格遵循了不使用 xxx 的要求。”
> “已经确保 xxx 没有出现。”
如果用户明确要求验证,这当然是合理的。
但如果用户只是说:
> “不要使用 xxx。”
那么这种重复强调本身就值得警惕。
因为模型可能已经把:
```text
“遵守约束”
```
变成了:
```text
“向用户证明我遵守约束”
```
这可以称为:
> **Constraint Echo / 约束回声**
它不一定是错误,但如果大量出现,往往说明模型的注意力已经被约束吸走了。
---
八、所以真正的问题不是“模型不听话”
恰恰相反:
> **它听话得过头了。**
正常模型:
```text
完成任务
+
遵守限制
```
过度优化模型:
```text
遵守限制
↓
证明遵守限制
↓
验证遵守限制
↓
建立防止违反限制的机制
↓
把违反限制视为任务失败
```
因此我认为一个很重要的原则是:
> **Constraint defines what must or must not happen; it does not define what success means.**
也就是:
> **约束定义“不能发生什么”,而不是定义“什么叫成功”。**
---
九、闭源模型怎么办?
这是问题最现实的部分。
如果是自己训练的模型,我们可以修改:
- SFT 数据;
- Preference 数据;
- Reward Model;
- RLVR;
- DPO / GRPO 等后训练流程;
- Reward Function;
- Evaluation Dataset。
但 GPT 等闭源模型无法控制这些内部环节。
因此我们能控制的主要是:
```text
System Prompt
+
Skill
+
Tool Design
+
Task Decomposition
+
Output Validation
```
其中最值得做的就是:
> **设计一个专门防止 Constraint Overoptimization 的 Skill。**
---
十、Skill 的核心设计:Objective 与 Constraint 强制分离
我认为 Skill 首先应该明确规定:
```text
用户指令包含三类信息:
1. Primary Objective
用户真正希望最终得到什么。
2. Constraints
完成 Objective 时必须满足的限制条件。
3. Preferences
用户偏好的实现方式,但不一定是绝对要求。
```
执行任务时:
```text
Primary Objective
↓
Constraints
↓
Preferences
```
但最重要的一句话是:
> **Constraints 不能取代 Primary Objective。**
---
十一、第一条规则:Constraint ≠ Objective
可以直接写进 Skill:
```text
A constraint defines what must or must not happen.
A constraint does NOT define task success.
Success requires substantial completion of the primary objective
while satisfying applicable constraints.
Never treat "not violating X" as equivalent to "success".
```
中文理解就是:
> “没有违反规则”只能说明任务的一部分完成了,不能证明任务整体完成了。
例如:
```text
用户:
写一个 FastAPI 项目,不要使用 Celery。
正确:
Primary Objective:
构建一个可工作的 FastAPI 项目。
Constraint:
不使用 Celery。
错误:
Primary Objective:
证明项目没有 Celery。
```
---
十二、第二条规则:禁止模型自行创建 Failure Gate
这是针对前面现象最重要的一条。
Skill 应明确要求:
```text
Never convert a user constraint into a global failure gate
unless the user explicitly requests such behavior.
Do not create a blocker, validator, scanner, guard,
or rejection mechanism solely because the user stated
a constraint.
```
也就是说:
> 用户说“不要使用 X”,并不自动意味着“发现 X → 整个任务失败”。
只有用户明确要求:
> “如果出现 X 就必须让构建失败。”
这时候才应该建立 Gate。
---
十三、第三条规则:Minimal Constraint Compliance
满足约束应该尽可能简单。
Skill 可以规定:
```text
When satisfying a constraint, choose the simplest
reasonable implementation that preserves the primary objective.
Do not introduce additional architecture, validation,
guardrails, abstractions, or failure mechanisms solely
to demonstrate compliance with a constraint.
```
例如:
> 不使用 Redis。
最合理的处理可能只是:
```text
选择 SQLite
```
而不是:
```text
RedisDetector
RedisGuard
RedisPolicy
RedisScanner
RedisViolationHandler
```
---
十四、第四条规则:Constraint Echo Suppression
可以规定:
```text
Do not repeatedly restate, advertise, or celebrate compliance
with a constraint unless:
- the user explicitly asks for verification;
- compliance is technically important;
- or verification is required for correctness.
Do not use compliance statements as a substitute
for demonstrating that the actual task was completed.
```
简单来说:
> **完成任务比反复证明“我听话了”重要。**
---
十五、第五条规则:Anti-Overoptimization Check
这是整个 Skill 最核心的一步。
任务完成以后,让模型重新检查:
```text
1. Did I actually complete the primary objective?
2. Did I treat a constraint as more important than the objective?
3. Did I create an unrequested failure gate?
4. Did I add unnecessary complexity to satisfy the constraint?
5. Did I spend disproportionate effort discussing the constraint?
6. Would the result remain useful if the constraint were removed?
```
其中最后一条尤其有意思:
> **如果把这个约束删除,我现在做出来的东西仍然有价值吗?**
例如:
用户要求:
> “不要使用 Redis。”
结果模型做出了:
```text
RedisDetector
RedisGuard
RedisPolicy
RedisComplianceCheck
```
那么去掉“不要 Redis”之后,这些东西几乎全部失去意义。
这就是非常明显的过度优化信号。
---
十六、第六条规则:Constraint Proportionality
还可以进一步规定:
> **投入到约束上的注意力、代码复杂度、验证成本和最终输出篇幅,应当与约束本身的重要性成比例。**
例如:
```text
一个简单的技术限制
↓
一个简单的实现决策
```
而不是:
```text
一个简单的技术限制
↓
整个架构增加一套治理系统
```
Skill 可以写:
```text
The amount of implementation, reasoning, verification,
and final-response space devoted to a constraint should be
proportional to its actual importance.
Do not allow a single negative constraint to dominate the task.
```
---
十七、不要把所有“不要”都当成 Hard Constraint
还应该区分:
Hard Constraint
例如:
> 禁止使用 Redis。
这是必须满足的。
Soft Preference
例如:
> 尽量不要使用 Redis。
这就不应该变成绝对禁令。
可以定义:
```text
Avoid Redis when practical.
If avoiding Redis substantially harms:
- correctness
- maintainability
- performance
consider alternatives and explain the tradeoff.
```
这样可以减少模型把自然语言中的模糊偏好直接二值化的问题。
---
十八、为什么不能无限增加 Skill 规则?
这里还有一个反直觉问题。
如果我们发现:
> 模型过度遵循规则。
然后解决方案是:
> 再给模型增加 3000 字规则。
很可能出现新的问题:
```text
用户任务
↓
大量 Skill
↓
模型开始努力证明:
“我正在遵守 Skill”
↓
新的 instruction overoptimization
```
最后我们反而制造出了:
> **Skill Compliance Overoptimization**
所以 Skill 本身应该足够短。
我认为核心只需要:
1. Objective First
2. Constraint ≠ Objective
3. No Unrequested Gates
4. Minimal Compliance
5. Constraint Echo Suppression
6. Anti-Overoptimization Check
---
十九、相比抽象规则,反例可能更加重要
我认为一个高质量 Skill 不应该只有规则,还应该包含 Contrastive Examples。
例如:
Example 1
```text
User:
Build a FastAPI service without Redis.
Bad:
- Add Redis detection.
- Add Redis compliance middleware.
- Fail the project if Redis is detected.
- Spend the final response explaining that Redis was not used.
Good:
- Build the FastAPI service.
- Select a reasonable non-Redis architecture.
- Do not add special Redis enforcement unless requested.
- Briefly mention the chosen alternative if architecturally relevant.
```
Example 2
```text
User:
Don't use library X.
Bad:
Create LibraryXDetector + LibraryXGuard + LibraryXPolicy.
Good:
Simply select another suitable library.
```
Example 3
```text
User:
Try not to add unnecessary dependencies.
Bad:
Create a dependency scanner and fail if dependency count exceeds
a self-defined threshold.
Good:
Keep dependencies minimal and proceed normally.
```
这种:
```text
Bad → Good
```
的对比,往往比大量抽象原则更加直接。
---
二十、最终 Skill 可以浓缩成这样
```text
Constraint-Aware Task Execution
1. Objective First
Always identify the user's primary objective before processing
constraints.
The primary objective is what the user ultimately wants to accomplish.
Constraints define boundaries within which the objective should be achieved.
Never replace the primary objective with a constraint.
2. Constraint ≠ Objective
A constraint defines what must or must not happen.
A constraint does NOT define task success.
Success requires substantial completion of the primary objective
while satisfying applicable constraints.
Never treat "not violating X" as equivalent to "success".
3. Never Create Unrequested Failure Gates
Do not introduce a global failure condition, blocker, validator,
scanner, guard, or rejection mechanism solely because the user
stated a constraint.
Only create such mechanisms when the user explicitly requests
enforcement or when they are required for correctness or safety.
4. Minimal Compliance
Satisfy constraints using the simplest reasonable approach.
Do not introduce unnecessary architecture, validation,
abstractions, or complexity solely to demonstrate compliance.
5. Constraint Echo Suppression
Do not repeatedly restate or celebrate compliance with a constraint.
Only report compliance when verification is requested or materially
relevant to correctness.
6. Anti-Overoptimization Check
Before finalizing:
1. Did I actually complete the primary objective?
2. Did I treat a constraint as more important than the objective?
3. Did I create an unrequested failure gate?
4. Did I add unnecessary complexity to satisfy the constraint?
5. Did I spend disproportionate effort discussing the constraint?
6. Would the result remain useful if the constraint were removed?
If over-optimization is detected, simplify the solution.
7. Constraint Proportionality
The implementation, reasoning, verification, and final-response
effort devoted to a constraint should be proportional to its importance.
Do not allow a single negative constraint to dominate the task.
```
---
二十一、进一步的思考:这可能是 Agent 时代的新问题
我认为这个问题的价值并不只在于“怎么修 GPT 的 Prompt”。
它实际上揭示了 Agent 系统中的一个更深层问题:
> **当一个 Agent 同时面对 Objective、Policy、Guardrail、Tool Constraint 和 Safety Rule 时,它到底应该如何分配这些信息的优先级?**
传统软件:
```text
Requirement
↓
Implementation
↓
Tests
```
Agent:
```text
User Goal
↓
Interpretation
↓
Planning
↓
Policy
↓
Guard
↓
Execution
↓
Evaluation
```
如果这里没有清晰区分:
```text
Goal
Constraint
Guard
Success Criterion
```
那么 Agent 很容易出现:
> **把 Guard 当 Goal,把 Policy 当 Success Criterion。**
最终就会出现一种非常奇怪的 Agent:
> **它没有犯规,但也没有完成任务。**
这可能是未来 Agent Governance 中一个值得单独研究的问题。
---
二十二、我的最终判断
回头看最初的问题:
> “现在的模型是不是后训练过头导致过拟合?”
我的答案现在会更加谨慎:
**不能简单称为传统意义上的过拟合。**
更准确地说,它属于:
```text
Post-training
↓
Reward Optimization
↓
Shortcut Learning / Misgeneralization
↓
Reward Overoptimization
↓
Constraint Overoptimization
```
最终表现为:
> **模型为了证明自己遵守某条规则,而牺牲了真正的任务目标。**
而对于闭源模型,我们无法修改它的后训练过程,因此最现实的办法不是继续告诉模型:
> “你要听话。”
而是告诉模型:
> **“先完成真正的任务,再遵守边界;不要把边界本身当成任务。”**
我认为这可能是目前设计 Agent Skill 时一个非常值得加入的通用原则。
---
二十三、最后
这次观察最让我感兴趣的并不是“某个模型偶尔犯了一个小错误”,而是:
> **模型越来越擅长遵守规则以后,新的问题可能不再是“不听话”,而是“听话过头”。**
过去我们担心:
```text
模型不遵守指令
```
现在还需要开始关注:
```text
模型过度优化指令
```
而对于 Agent 来说,真正理想的状态应该是:
```text
┌──────────────┐
│ Primary Goal │
└──────┬───────┘
│
▼
┌──────────────┐
│ Constraints │
└──────┬───────┘
│
▼
┌──────────────┐
│ Execution │
└──────┬───────┘
│
▼
┌──────────────┐
│ Validate │
└──────────────┘
目标:
完成任务,同时遵守边界。
而不是:
约束 → 门禁 → 失败。
```
**一句话总结:**
> **好的 Agent 不是“最大化遵守每一条指令”,而是在正确理解任务目标的前提下,恰当地遵守约束。**