改完 M3.1-Flash-Preview 相关代码后不敢合并,通常不是 diff 看不懂,而是缺少可对比的基线。要确认“没改坏”,至少需要四件事:改动前的现有测试结果、可整体回退的改动补丁、针对改动点的最小用例,以及同一组输入在改动前后的输出对比。只跑一遍新测试或只看代码风格,不能证明没动到别处逻辑。
处理模型相关改动时,建议把这次改动当成一次待审提交:先用现有测试记录基线,再把改动隔离成独立分支或补丁,针对改动点补一个可执行最小用例,用同一组输入对比前后输出,最后查 diff 中无关文件。边界是只能确认被用例和环境覆盖的行为;未覆盖分支、外部依赖和模型随机性仍需单独确认。
先跑一遍改动前的现有测试
目标不是让所有测试立刻变绿,而是拿到“改动前长什么样”的基线。在干净工作区先记录提交号和状态。测试命令按项目替换,常见形式如下:
git status `--short`
git rev-parse HEAD
pytest -q `--tb`=short 2>&1 | tee baseline-pytest.log
# 或 npm test 2>&1 | tee baseline-npm.log
# 或 go test ./... 2>&1 | tee baseline-go.log
记录通过项与失败项时,不要只看最后一行。建议保留完整日志,并用 `--junitxml=baseline.xml` 或同类报告参数生成结构化结果。已有失败要单独列出,标注“改动前已失败”,否则改动后会把旧失败误判为新问题。可以用一个简单清单:测试文件、用例名、改动前状态、备注。需要结合环境确认依赖版本、环境变量和随机种子是否一致,否则前后结果不可比。
把模型改动单独放在一个分支或补丁里
如果改动已经混在工作区,先不要继续往上叠。创建一个 review 分支,把本次改动收进独立提交,这样合并前能整体回退或单独丢弃。常用动作:
git switch -c review/m3.1-flash-preview
git add -p
git commit -m 'isolate M3.1-Flash-Preview change'
git diff > m3.1-flash-preview.patch
git diff `--stat`
git diff `--name-status`
git format-patch -1
查看改动范围时,优先看 `--stat` 和 `--name-status`,再按目录看具体 diff,例如 `git diff -- src/`。如果补丁要包含未跟踪文件,可先 `git add -N .` 再生成 diff。需要整体回退时,可用 `git apply -R m3.1-flash-preview.patch` 或对独立提交执行 `git revert <commit>`。注意补丁只覆盖代码差异;模型文件、配置项、环境变量如果不在版本控制内,要另做记录。
为改动点补一个最小用例
最小用例要能回答“改完之后,哪个输入必须得到什么输出”。输入数据尽量小、固定、可重复;期望输出不一定要断言完整文本,尤其模型输出可能波动时,建议断言结构、字段、错误码和不变量。下面是一个通用骨架,调用部分替换成项目里的函数或 HTTP 客户端:
def call_model(payload):
# 替换成项目里的调用函数或测试客户端
...
def test_m3_1_flash_preview_min():
payload = {'prompt': 'ping', 'max_tokens': 5, 'temperature': 0}
resp = call_model(payload)
assert resp['error'] is None
assert isinstance(resp['text'], str)
assert len(resp['text']) > 0
assert resp['finish_reason'] in ('stop', 'length')
运行单个用例:`pytest tests/test_m3_1_flash_preview_min.py -q`,或对应测试框架的过滤参数。如果页面行为是改动点,就用浏览器自动化断言元素可见、状态码或文案。边界是:模型输出带随机性时,能固定 seed 就固定;不能固定时只断言不变量,不要断言整段文本相等。
对比改动前后的同一组输入输出
用同一组 cases,在改动前和改动后各跑一次,保存为可 diff 的文件。执行前确认两边依赖、环境变量和调用入口一致。命令示例:
python run_cases.py `--cases` cases.jsonl `--out` before.jsonl
# 切到改动分支后
python run_cases.py `--cases` cases.jsonl `--out` after.jsonl
diff -u before.jsonl after.jsonl > output.diff
# 如果行顺序可能变化,先按 id 排序
jq -s 'sort_by(.id)' before.jsonl > before.sorted.jsonl
jq -s 'sort_by(.id)' after.jsonl > after.sorted.jsonl
diff -u before.sorted.jsonl after.sorted.jsonl > output.sorted.diff
差异清单建议分成三类:本次改动目标字段的预期差异;无关字段、错误码、日志警告、耗时数量级的非预期差异;环境噪声导致的差异。出现意外差异时不要直接合并,先回到 diff 找对应代码,确认是测试环境问题就固定环境并记录,确认是行为变化就补用例或调整改动。只对比同一组输入不等于覆盖所有输入,边界值和异常输入需要另外补。
检查被顺手改动的无关代码
模型改代码时常见越界包括格式化、重命名、依赖版本、配置文件、超时重试、日志级别、注释掉代码和无关模块。先用范围命令把无关文件挑出来:
git diff `--name-status` main...HEAD
git diff `--stat` main...HEAD
git diff main...HEAD -- . ':(exclude)tests/*' ':(exclude)docs/*'
需要还原的是不属于本次目标的 hunk。可以用 `git restore -p` 或 `git checkout -p main -- path` 逐块还原,也可以交互式 rebase 把无关改动拆到单独提交。还原后复查三个动作:`git diff `--stat` main...HEAD` 应只剩目标文件;重跑第 3 节最小用例和第 1 节相关测试;`git status` 确认没有残留补丁文件或临时脚本。如果某个无关改动是构建必需,建议单独提交并写清原因,不要混在模型改动里。