KAT-Coder-Pro V2.5 生成代码总跑偏 / 是任务描述太粗还是仓库上下文没给够?

文章导读
KAT-Coder-Pro V2.5 生成代码跑偏,通常不是单一原因。判断顺序建议是:先用同一份输入复现一次,再把“任务描述粒度”和“仓库上下文完整度”分开各调一次,看哪一边变化带来的差异更大。有个大致可用的区分方式——如果模型输出的是一套自己脑补的实现,多半是任务描述太粗;如果模型调用了仓库里不存在的函数、路径或字段,多半是上下文没给够。前者靠改措辞收敛,后者靠补文件收敛,用错方向就会一直反复重
📋 目录
  1. 一 复现一次跑偏的生成结果并记录原始输入
  2. 二 检查任务描述里是否缺少输入、输出和验收条件
  3. 三 检查提交给模型的仓库上下文是否缺失关键依赖文件
  4. 四 用最小改动对比两组输入:只细化描述 vs 只补上下文
  5. 五 根据对比结果固定下一次生成的输入模板
A A

KAT-Coder-Pro V2.5 生成代码跑偏,通常不是单一原因。判断顺序建议是:先用同一份输入复现一次,再把“任务描述粒度”和“仓库上下文完整度”分开各调一次,看哪一边变化带来的差异更大。有个大致可用的区分方式——如果模型输出的是一套自己脑补的实现,多半是任务描述太粗;如果模型调用了仓库里不存在的函数、路径或字段,多半是上下文没给够。前者靠改措辞收敛,后者靠补文件收敛,用错方向就会一直反复重试。

先用同一份输入复现跑偏,把任务描述、提交给模型的文件清单、模型原始输出三类记录留档,再分别做“只细化描述”和“只补上下文”两组对照。判断依据看输出是否引用了仓库中不存在的符号、是否改动了禁止改动的文件、能否通过现有 lint 或测试命令。上下文缺失导致的错误一般更难靠措辞修正,建议先补一跳以内的依赖和类型定义;描述也不是越细越好,过约束同样会让生成结果偏离,需要结合仓库实际确认。

复现一次跑偏的生成结果并记录原始输入

手感判断不可靠,先拿到一份可对比的基线:让同一个任务在同样的输入下再生成一次,并把当时的三类东西原样存下来——任务描述全文、提交给模型的文件路径清单、模型未经手工修改的原始输出。描述不要事后润色,否则之后就无法判断是措辞变了还是上下文变了。

如果目标文件在版本管理里,用一次提交把生成前后的状态钉住,是最省事的做法:

# 每“一轮生成”建一个目录,方便回看
mkdir -p kat-runs/case-01

# 生成前:固定基线
git rev-parse HEAD      > kat-runs/case-01/base_commit.txt
git status `--porcelain`  > kat-runs/case-01/dirty_files.txt

# 把当时发给模型的描述原样粘贴保存,不要重写
# kat-runs/case-01/prompt.md

# 把提交给模型的文件路径逐行记下来
# kat-runs/case-01/context_files.txt

# 生成后:先存原始 diff,再动手改代码
git diff                > kat-runs/case-01/model_output.diff

验证方式很简单:换一个终端或第二天再打开这个目录,只看 prompt 和 context_files 两个文件,能不能复现出同一类错误。如果连当时的输入都拼不回来,后面两组对照就无从谈起。

检查任务描述里是否缺少输入、输出和验收条件

描述太粗最典型的症状,是模型自己补了一堆你没说过的假设。对照下面这份清单逐项核对,缺哪项补哪项,不要一次全写满:

KAT-Coder-Pro V2.5 生成代码总跑偏 / 是任务描述太粗还是仓库上下文没给够?
  • 目标文件:具体到路径,而不是“用户模块”
  • 函数名或类名:要新增还是修改现有实现
  • 输入:参数来源、类型、是否可能为空
  • 输出:返回值形态、错误如何抛出或返回
  • 边界条件:空值、超长、重复调用、权限不足时怎么处理
  • 禁止改动:公共接口、依赖清单、无关目录、生成文件
  • 验收方式:跑哪条 lint、哪个测试命令、哪个编译命令

把粗描述和细化后的描述放在一起看,差别通常很明显:

# 偏粗
帮我给登录接口加一个参数校验。

# 细化后(字段按实际替换)
目标文件:src/api/login.ts
修改函数:handleLogin(不要改文件内其他导出)
输入:body 来自已有解析中间件,password 可能为空字符串
输出:校验失败时返回现有的 fail(400, code) 格式,不抛异常
边界:password 为空、长度不足、含全角空格三种情况都要拦
禁止:不新增依赖,不改 fail() 的签名,不动 tests 目录
验收:npm run lint 与 npm test -- login 通过

需要注意的边界是:描述写太细也可能过约束,比如把实现路径写死成某种写法,反而限制了模型对仓库既有风格的复用。目标文件、接口形态、禁止项这三类值得写死,内部实现细节可以留白。

检查提交给模型的仓库上下文是否缺失关键依赖文件

上下文缺失的症状很好认:输出里出现了仓库中不存在的函数名、导入路径、配置字段,或者模型开始用“假设有一个 xxx”来兜底。先列出与目标文件存在导入或调用关系的文件,再对比实际提交的清单。

KAT-Coder-Pro V2.5 生成代码总跑偏 / 是任务描述太粗还是仓库上下文没给够?
# 谁引用了目标模块(关键字按语言替换)
rg -n "import .*target_module|from .*target_module|require\(.*target_module" src/

# 谁调用了目标函数
rg -n "targetFunction\(" src/ tests/

# 类型与配置出口
cat tsconfig.json package.json    # 或 pyproject.toml、requirements.txt、go.mod

按下面几类核对是否遗漏,通常补到“一跳以内”就够:

  • 目标文件本身
  • 它直接导入的模块(工具函数、常量、类型)
  • 调用它的上游文件,用来确认签名不能被改坏
  • 接口或类型定义文件、schema、数据库迁移
  • 相关配置:路径别名、构建配置、环境变量示例
  • 已有测试文件,模型从这里能学到本仓库的断言风格

不建议把整个仓库都塞进去。无关文件会稀释注意力,改动范围反而更难收敛。只补进“被目标文件引用”和“引用目标文件”这两圈,通常性价比最高。

用最小改动对比两组输入:只细化描述 vs 只补上下文

要分离这两个变量,做法是固定其余一切,只改一件事。固定项包括:同一个 base commit、同一个目标文件、同一批模型输出配置(模型版本、采样参数)、不带入上一轮的对话历史。然后跑两组:

  • A 组:只细化任务描述,上下文仍用原来那批文件
  • B 组:只补上下文文件,描述尽量照抄原文不动

每组建议同一输入跑两到三次,因为同一份输入本身也会有一定波动,单次结果不足以定论。观察指标按可核查的来:

KAT-Coder-Pro V2.5 生成代码总跑偏 / 是任务描述太粗还是仓库上下文没给够?
  • 是否引用了仓库中不存在的函数、字段或路径
  • 是否改动了明确禁止改动的文件或公共接口
  • 现有 lint、测试、编译命令能否通过
  • diff 涉及的文件数量和人工返工次数
  • 是否反复追问同一个缺失信息

如果 A 组明显收敛、B 组没变化,说明主要问题是描述粒度;反过来则说明是上下文缺口。两边都收敛,说明两个问题同时存在,但仍建议先固化上下文,因为它对后续所有任务都通用。这个对比的结论只在这个仓库、这一版模型和这组文件下成立,换项目需要重新跑一遍。

根据对比结果固定下一次生成的输入模板

把上面验证有效的做法写成一个固定模板,下次直接填空,不再凭记忆组织输入。

## 任务
目标文件:
函数/类名:
输入(来源、类型、可能为空):
输出(返回值、错误处理):
边界条件:
禁止改动:
验收命令:

## 上下文(把文件内容整段附上)
- [ ] 目标文件
- [ ] 直接导入的模块:
- [ ] 调用方文件:
- [ ] 类型 / 接口 / schema:
- [ ] 相关配置:
- [ ] 已有测试:

## 输出要求
只输出改动后的完整文件内容或统一 diff;
不要修改上面未列出的文件;
如需假设,先在回答开头列出假设,不要直接写进代码。

模板里可以留一行“上次有效的上下文清单”,每次跑完把实际提交的文件路径追加到 kat-runs 记录里,积累几轮之后,同类任务直接复用这份清单。验证方式仍然一样:用模板跑一次,对照之前那次跑偏的输出,看是否出现不存在的符号或超范围改动。如果模板在同一项目里连续两三次都需要大改,说明验收命令或禁止改动这两栏还没写准,先补这两项,再动其他字段。