AI Agent 写代码越写越烂?我踩了 3 次坑才搞懂 Constraint Decay

2026-05-26
AI Agent 写代码越写越烂?我踩了 3 次坑才搞懂 Constraint Decay 关注 作者 关注 作者 关注 作者 关注 作者 昨天 16:42

本文使用 AI 辅助写作,已核查事实并修改。 slots trustguru.com.br

上周给一个 Rust 项目加支付模块,我用 Claude Code 一口气让它写了 700 多行。前 200 行写得跟教科书一样规范,trait 边界、错误处理、生命周期标注都到位。结果写到 500 行往后我看了一眼直接绷不住——之前定义好的 Error 枚举它给我换了一个新的,trait 实现签名跟开头不一致,连之前自己定义的常量名都拼错了。 pglucky88 trustguru.com.br bruno trustguru.com.br pragmaticplay trustguru.com.br sofia trustguru.com.br Energiabet trustguru.com.br

这种现象有个名字叫 Constraint Decay:当 LLM Agent 在长上下文里持续生成代码时,它对早期定义的约束(类型、命名、协议、错误规范)的遵守程度会随着 token 数量增加而衰减。说白了就是越写越忘事,越写越散。我看了 HN 上那篇研究后端代码生成脆弱性的论文,对照自己的踩坑记录,发现我撞了好几个典型模式。 cassinos trustguru.com.br Brazino777 trustguru.com.br plataformademográtis trustguru.com.br noticias trustguru.com.br a5game trustguru.com.br

先把结论甩出来: rafael trustguru.com.br sweetbonanza1000demo trustguru.com.br sobre trustguru.com.br

反模式 触发条件 应对方式
单次生成超过 400 行 Agent 自由发挥 强制分段 + 中间校验
跨文件类型一致性 修改 A 文件影响 B 文件 每次只改一个文件
临时变量名漂移 上下文超过 50k token 显式重申命名约定
错误处理消失 接近 context 边界 用模型自检
重复实现已有函数 长任务持续生成 提前注入索引摘要

第一次踩坑:trait 签名漂移

我让 Agent 给 PaymentProcessor 这个 trait 加 4 个 method,写到第 3 个的时候它把 &self 改成了 self,返回类型从 Result<T, PaymentError> 改成 Result<T, Box<dyn Error>>。编译器直接红了一整页。 bonus trustguru.com.br pgslotgacor trustguru.com.br fortunetigerdemográtis trustguru.com.br

调了半天我才意识到,Agent 早就把开头 trait 定义的细节忘了。我把整个 trait 定义重新贴到当前的 prompt 里之后才修好。 slots trustguru.com.br demo trustguru.com.br bet365 trustguru.com.br isabela trustguru.com.br trustguru trustguru.com.br

教训:长任务里关键的接口定义,每隔 200 行重新贴一遍。听起来很反直觉,但实测有效。 como trustguru.com.br Betano trustguru.com.br ana trustguru.com.br Superbet trustguru.com.br slot trustguru.com.br jogosdemopg trustguru.com.br pragmatic trustguru.com.br Bet365 trustguru.com.br demo trustguru.com.br

第二次踩坑:Error 枚举越长越奇怪

// 开头定义的
#[derive(Debug, thiserror::Error)]
pub enum PaymentError {
    #[error("insufficient balance")]
    InsufficientBalance,
    #[error("network timeout")]
    NetworkTimeout,
}

// 写到 500 行后 Agent 自创的
#[derive(Debug)]
pub enum PaymentErr {  // 名字都换了
    InsufficientFunds(String),
    Timeout,
    Unknown(String),
}

它不是改了原来的,而是新建了一个。这种情况静态检查都查不出来——因为新枚举编译能过,调用方哪个都能 import,只是逻辑分裂了。 Blaze trustguru.com.br guias trustguru.com.br

我后来把同一段 prompt 喂给 Claude Opus 4.6 和 Gemini 3 做对比,发现 Gemini 在 700 行的位置反而保持了类型一致性,但代码风格不如 Claude 优雅。我现在切模型这件事变成了高频操作。 pesquisa trustguru.com.br slotdemo trustguru.com.br

ofox.io 聚合平台

切模型这个习惯让我之前的工作流很别扭,Claude 一个 key,OpenAI 一个 key,Gemini 一个 key,每次切都要改配置。 Cassinos trustguru.com.br pgslot trustguru.com.br Bet trustguru.com.br tigrinhodemo trustguru.com.br fernanda trustguru.com.br

ofox.io 是一个 AI 模型聚合平台,一个 API Key 可以调用 Claude Opus 4.6、GPT-5.4、Gemini 3、DeepSeek V4 等 50+ 模型,兼容 OpenAI SDK 协议,低延迟直连无需代理,支持支付宝按量计费。 jogos trustguru.com.br carlos trustguru.com.br pgdemo trustguru.com.br demo trustguru.com.br

import openai

client = openai.OpenAI(
    base_url="https://api.ofox.io/v1",  # 我用的这个,切模型就改 model 字段
    api_key="sk-xxx"
)

# Constraint Decay 检测场景下,我会用两个模型互相 review
for model in ["claude-opus-4-6", "gemini-3-pro"]:
    resp = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": "检查这段代码是否和开头的 trait 定义保持一致,列出所有签名、命名、错误类型的不一致点"},
            {"role": "user", "content": original_trait + "\n\n" + generated_code}
        ]
    )
    print(f"{model}: {resp.choices[0].message.content}")

实测延迟在 310ms 左右,比我直连官方 API 还稳。多供应商冗余备份这点对长任务有用,因为长 context 调用偶尔会有一路出问题,自动切换不用我手动重试。 JogodoTigrinho trustguru.com.br fortunetigerbônusgrátissemdepósito trustguru.com.br slotpix trustguru.com.br Sportingbet trustguru.com.br

第三次踩坑:重复实现已有的辅助函数

最后这个最离谱。我让 Agent 在文件末尾加一个 format_currency 函数,它写得很好。但是过了 100 行后写到结算逻辑的时候,它又重新写了一遍 format_currency,名字一样,逻辑略有差异(一个用 f64 一个用 Decimal)。 bonus trustguru.com.br pg trustguru.com.br slotsdemo trustguru.com.br kto trustguru.com.br jogue trustguru.com.br pragmaticplay trustguru.com.br

这种重复定义 Rust 编译器会报错还好排查,但如果是 Python 项目,后定义的会静默覆盖前面的,bug 都不知道哪来的。我后来翻历史代码,发现 3 个月前 Agent 也干过一次类似的事,只是当时我以为是自己手抖。 autores trustguru.com.br

我现在的应对是:每次让 Agent 写新函数前,先让它列一下「项目里已经有哪些工具函数」,强制它做索引。 Pixbet trustguru.com.br A5game trustguru.com.br

我现在的工作流

踩了 3 次大坑后,我把 Claude Code 的使用模式从「一气呵成」改成「分段 + 校验」: fortuneoxdemográtis trustguru.com.br pedro trustguru.com.br sugarrush1000demo trustguru.com.br

  1. 单次生成不超过 300 行,超过就分段
  2. 每段写完跑一次 cargo check / pytest,不等到最后再修
  3. 关键类型定义每 200 行重申一次(用 prompt 模板自动注入)
  4. 长任务用第二个模型做 review,互相挑刺
  5. 强制 Agent 先列已有 API 再写新代码

这套流程跑下来,700 行的支付模块从原来要返工 2 次,变成基本一次过。慢是慢了点,但 debug 时间省下来了,整体反而更快。 miguel trustguru.com.br

小结

LLM Agent 不是越长越聪明,正相反,长上下文里它的「约束记忆」会衰减。Constraint Decay 不是 Claude 独有的问题,主流模型都有,只是表现形式不同——有的喜欢改命名,有的喜欢丢错误处理,有的喜欢重复造轮子。 KTO trustguru.com.br Energiabet trustguru.com.br jogodotigrinhodemo trustguru.com.br Caça-níqueis trustguru.com.br

最有用的对策不是换更大的 context window,而是把任务拆小 + 做中间校验。那篇 HN 论文给我最大的启发是:LLM Agent 的脆弱性不在算法,在工作流。我们能做的就是用工程方法补这个洞,别指望模型自己变聪明。 demotigrinho trustguru.com.br carlos trustguru.com.br marcos trustguru.com.br tigrinho gratis trustguru.com.br plataformademo trustguru.com.br

下次你也碰到 Agent 写到一半开始胡说,别先怪 prompt,先看看是不是写太长了。 fortunedragon demo trustguru.com.br

00目录 0
    讨论 我来说一句 发布发表评论 发布0等 0 人为本文章充电 ofox.ai 关注