基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
编程提效2026-10-31 20:05

让AI重写旧代码前,先设行为等价门禁

dev.to · AI#遗留系统#AI编程#回归验证
Editor brief · 编辑速览

文章建议先建立行为等价验证,再让代理替换旧系统实现,以检查用户及依赖系统依赖的行为是否保留。内容是基于公开报道的工程指南,并非Cisco重写项目的实测复盘。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

AI 已经能很快写出一套替代实现,但团队未必能同样快地确认:它还是原来的产品吗?作者借 Cisco 大规模重写遗留代码的报道,提出一个更实用的顺序:先建新旧行为对照门禁,再让 Agent 动手。

这是一份基于公开资料的工程指南,没有 Cisco 项目的内部实测。它值得读的地方,是把「看起来功能一样」拆成了可保存、可复现、可审核的证据,尤其适合准备让 AI 接手旧业务代码的团队。

重写了多少代码,不能证明保住了多少行为

原文引用的消息来自 Fortune 报道,经 Tom's Hardware 转述:Cisco 总裁 Jeetu Patel 给一名 27 岁工程师提供不限量 AI tokens,目标是在 24 个月内重写 98% 的遗留代码,概念验证窗口为四周。

这里的 98% 是目标,不是完成率。公开报道没有证明任务已经完成,也没有证明 token 供应就是项目瓶颈。

遗留系统的麻烦,在于需求并不完整地写在文档里。数据库约束、线上数据、下游接口、错误处理,甚至一个没人记得来历的默认值,都可能属于实际契约。新代码更整洁,也可能悄悄改变金额舍入、结果顺序或失败方式。

因此,普通测试和行为对照测试回答的是两个问题。前者检查新代码是否返回预期结果;后者让相同输入分别经过新旧实现,比较可观察的结果。原文把后者称为 parity test,可以理解为「新旧行为对照测试」。

重写的验收依据,应当是行为证据,而不是生成代码的数量。

作者引用 Microsoft 的迁移验证建议:提前定义验收门禁,保存旧系统基线,让两个版本使用相同数据和环境假设,并逐项调查回归。VS Code 的测试指南还要求保留断言、报告实际执行的测试,没运行的部分仍然未经验证。

先选一个能独立回退的小行为

起点可以是定价规则、日期转换、权限判断或序列化函数。它需要边界清楚、结果可控,而且能在受控条件下同时调用新旧实现。

下面的脚本解决最小对照问题:逐行读取 JSON 用例,交给两个命令执行,保存结果差异,并把进程错误视为失败。

#!/usr/bin/env python3
"""Compare legacy and candidate commands on newline-delimited JSON cases."""
import json
import subprocess
import sys
from pathlib import Path

CASES = Path(sys.argv[1])
OLD_COMMAND = ["python3", "legacy_impl.py"]
NEW_COMMAND = ["python3", "candidate_impl.py"]

def run(command, case):
    completed = subprocess.run(
        command,
        input=json.dumps(case),
        text=True,
        capture_output=True,
        check=False,
        timeout=10,
    )
    if completed.returncode != 0:
        raise RuntimeError(
            f"{command[1]} exited {completed.returncode}: "
            f"{completed.stderr.strip()}"
        )
    return json.loads(completed.stdout)

def main():
    cases = [json.loads(line) for line in CASES.read_text().splitlines() if line]
    mismatches = []
    for index, case in enumerate(cases, start=1):
        old = run(OLD_COMMAND, case)
        new = run(NEW_COMMAND, case)
        if old != new:
            mismatches.append({"case": index, "input": case,
                               "legacy": old, "candidate": new})

    print(json.dumps({
        "cases": len(cases),
        "mismatches": len(mismatches),
        "details": mismatches,
    }, indent=2, sort_keys=True))
    return 1 if mismatches else 0

if __name__ == "__main__":
    raise SystemExit(main())

要看清 if old != new::这里比较的是 json.loads 解析后的值,JSON 对象键顺序不同不会触发差异;数组顺序、字段缺失与 null 等差异则会保留。因此,如果调用方依赖原始序列化的字段顺序,还要补充相应检查。

将输入存入 cases.jsonl,每行一个 JSON 对象,执行 python3 parity.py cases.jsonl。两个命令数组应替换为真实且隔离的入口。脚本设置了 timeout=10,非零退出码会抛错,中途错误也不会被静默跳过。

这只是起点。涉及数据库、服务依赖和消息队列时,还需要快照、服务替身与更强隔离。时间戳等非确定字段可以规范化,但每一项处理都要说明理由,避免把业务回归一起抹掉。

用例要揭露契约,差异要有人裁决

只收集正常输入,门禁很容易变成形式。原文要求覆盖真实常用输入、边界、非法输入、失败行为、兼容细节和历史缺陷。

具体包括空字符串、最小与最大值、时区切换、舍入临界点、大载荷、缺失字段、下游超时、依赖不可用及重试上限。错误码、稳定标识符,以及 null 和字段省略的区别,也可能是调用方依赖的行为。真实数据需要脱敏,或安全地合成。

预期结果不能完全交给 Agent 编造,再让它拿自己的答案判自己正确。依据应尽量来自已有测试、已批准需求、历史行为或业务负责人。

旧实现同样不是真理。它能告诉你系统现在怎么做,却不能证明这样做合理。已知缺陷需要明确决定保留还是修复。

报告也不能只写「17 个测试失败」。每个差异应附输入、新旧输出和稳定用例标识,再按舍入、校验、授权、序列化等行为归类。原文区分三种处理结果:

  • 等价:受支持的调用方观察不到差别,并记录判断理由。
  • 批准变更:行为确实改变,由负责人确认,并配套迁移或兼容计划。
  • 尚未解决:契约还没确定,阻止候选版本晋级。

99% 的通过率,也可能掩盖最关键的授权或计费用例。

Agent 可以梳理调用点、建议用例、解释差异并实现替代代码,但不应在同一个未经审核的步骤里修改验收标准、批准自己的输出。原文建议先让人审核行为地图和用例,再让 Agent 在不改用例及预期值的条件下实现;通过仓库权限或独立审核边界保护这些文件。

运行时还要保存命令、版本标识、环境和报告。合并前检查最终 diff,运行相关现有测试;上线前定义回滚触发条件,通过可逆开关逐步放量。

我的判断

我认同这个顺序。审查一大片生成代码,很难直接判断业务是否等价;把输入和两份输出摆在一起,讨论会具体得多。

但作者没有提供亲手迁移的结果,也没有与人工重写、普通单元测试或其他迁移方式的对照数据。因此,这是一套有工程依据的方法建议,不能当作已验证的效率结论。「稀缺资源可能是可信用例和业务负责人时间」也只是工程推断,不能套成 Cisco 的内部事实。

它还有一个现实前提:旧实现必须能稳定运行,输入、数据和依赖状态可以控制。强依赖外部服务或包含大量副作用的组件,往往要先付出隔离成本。

与只测试新实现相比,对照测试更容易暴露历史兼容行为;与基于需求编写的测试相比,它又容易继承旧缺陷。两者需要互补。功能对齐也不能替代性能、安全、隐私和运维检查。

示例脚本还有简化之处:用例标识是行号,调整文件顺序后并不稳定;进程异常会直接终止,无法留下完整的结构化错误报告。将它接入持续集成前,需要补齐这些证据保存能力。

能拿来做什么

  • 让 AI 重写前端日期格式化、权限判断或 Node 序列化逻辑前,先选一个能独立回退的函数,固定输入语料并保存旧实现输出。
  • 从已有测试、历史故障和调用方约定中补充边界用例,明确检查缺失字段、null、错误码、舍入与数组顺序,别只验证正常路径。
  • 给 Agent 的任务明确写出「不得修改对照用例和预期值」,让它提交差异解释,由负责业务契约的人决定哪些变化可以接受。
  • 把逐项差异审核、相关测试和回滚条件放进发布流程;先确认门禁确实能抓住关心的错误,并演练回退,再扩大重写范围。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
119 行 Node.js 拆解 MCP 服务最小实现
下一篇
AI写的测试全绿,如何验证需求真被满足

资讯速览

dev.to · AI · 2026-10-31 20:05

AI 评分 8.0 / 10

相关标签

#遗留系统#AI编程#回归验证

继续阅读

  • 用进程内熔断拦住大模型失控账单
  • 119 行 Node.js 拆解 MCP 服务最小实现
  • AI写的测试全绿,如何验证需求真被满足
  • 把Twist讨论接入代理记忆,检索团队决策
  • LLM 测试的隐形账单:调用频次放大成本