复杂系统没法一把梭重构:Semi-Autoresearch 怎么小步迁移还不掉功能

Vibe coding 和 Agent 写代码已经很强:改界面、补脚本、在单卡训练里搜更优方案,Karpathy 的 autoresearch 甚至能把「改 train.py、跑固定时长、看 val_bpb」收成可循环的科研试错。这些场景往往目标单一、验收指标清楚,人只要把边界写进 program.md,Agent 就能整夜试错迭代。

业务工程系统不一样。人和 AI 各自掌握的上下文并不重合:线上约定、历史补丁里藏着的语义、别的系统还在依赖的字段口径,大量停在工程师脑子里或散落在旧对话里,并没有完整写进仓库。同一段需求,人对「算不算错、该不该跟旧版一样」常有判断;若把重构或迁移完全交给 AI 主动改代码,结果容易超出预期------不是多写了几个功能,而是按它理解的「正确」改了一版,旧坑没清掉又叠新坑,最后仍是一坨难维护的代码。

复杂系统重构尤其如此。做过的人多半都踩过这几类坑:

  • 历史包袱重,补丁叠补丁,不少逻辑能跑但没人敢动
  • 多人、多阶段、多风格混在同一套代码里,读一遍搞不清边界
  • 文档长期跟不上,真实语义卡在几段 if/else 和线上实际输出里
  • 需求还在变,改动却已是牵一发动全身
  • 底层架构或范式要换:旧逻辑散在补丁和调用链里,没法按模块整包搬迁,只能先保证输出和以前一致,再逐步换实现

难的不在「新代码写不出来」,而在迁移后功能效果不能变差,同时还得把工程从不可维护拉回可持续------中间还要不断对齐「什么叫对」。

这篇讲 Semi-Autoresearch(半监督对齐迭代):自动化评估负责对照、归因和提案,人工卡点负责语义分歧和有效金标准;把迁移拆成可审计的小步,而不是通宵 Agent 或赌一把大 rewrite。下文用订单/成交文本解析举例------旧版 NER+规则迁到 Schema 多阶段 pipeline 时,解析结果仍要让路由和风控照常用,代码也不能再堆回一团;字段与机构名均为构造,不涉及真实业务数据。

Semi 同时管住这两头:双轨 eval、人工前缀裁定、回归守护与规则回写,不默认「旧版永远对」,也不默认「AI 刚改完就算对」。


真正开始重构前:先把分层和契约对齐

很多重构不是栽在实现能力,而是分层边界、业务语义和评估口径还没对齐就动手。动手前至少对齐四件事:

  • 架构分层:抽取、标准化、业务决策、输出适配,各段边界写清楚,改 diff 时有落点。
  • 业务语义:哪些字段是硬契约,哪些允许演进,哪些可能是 legacy 错数,先标出来。
  • 评估契约:raw pass / effective pass 怎么定义,diff 比到字段还是比到条数,先冻结。
  • CODEMAP:核心模块职责、依赖方向写清楚,别只靠口口相传。

缺这层对齐,后面的 Agent 自动修复很容易变成自动加债。

若用 Cursor 一类工具,关键不在某条 prompt,而是把规则沉淀成可执行约束(例如 Cursor Rules):

  • 对齐规则:语义对齐优先,禁止照抄 legacy 调用链
  • 评估规则:每轮必须产出 eval 摘要,不能只说「修好了」
  • 文档规则:代码变更同步更新文档
  • CODEMAP 规则:模块职责变化时同步 CODEMAP
  • 测试规则:输出或逻辑变更时补测试或回归验证

人验收的是可追溯流程:谁改了什么、为什么改、影响了哪些 case,留痕即可,不必逐行盯 diff。


和 Karpathy autoresearch 不是一回事

Karpathy 的 autoresearch 是固定 GPU 时间、固定 val_bpb、代理只改 train.py------变量面极小,适合搜更优方案。

解析系统迁移变量面大得多:旧栈常是 NER + 规则 + 正则,新栈是 Schema 槽位 + 多阶段 pipeline。一边要保证解析输出和旧版一致、别让依赖方踩雷,一边工程上又不能复制 spaghetti;文档和实现还常不一致。全自动容易把旧版 bug 当金标准,或为个别 case 堆特例。

Semi-Autoresearch 拆成两半:Autoresearch 指自动化对照需求、旧实现和双轨 diff,梳理成因、试修复、出提案;Semi 指语义歧义、旧版疑错、方案分歧等卡点必须停,动代码前过回归守护,人用固定前缀指令确认或否决后,才冻结通过。


举例:订单/成交文本解析

某企业有「订单文本 → 结构化字段」服务,供路由与风控使用。旧版:模型只到 NER 槽位,后面靠规则补全;新版:结构化输出 + Schema 多阶段 pipeline。

输出字段(节选):order_idsidebridge_partyclearing_speeddialogue_send_to;一条输入可能拆多条成交,条数也要比。

语料示意:

"

编号 DEMO-20260615-001 买入 BOND-260205 04.28+0 甲银行出给乙农商 对话发丙证券

旧版基线:side=buybridge_party=乙农商clearing_speed 空,dialogue_send_to 空,条数 1。

新版:clearing_speed=+0dialogue_send_to=丙证券,其余同上。

双轨会标红 clearing_speeddialogue_send_to。默认「以旧版为准」就逼新版改回空;默认「以文档为准」又可能和线上还在跑的约定冲突。Semi 要做的是:系统主动标出分叉,等人定,且禁止为凑通过率静默把新版改错。


流程长什么样

回归守护卡在动代码之前:先看已冻结和已通过 case 会不会被带崩,再让人选方案。正文把流程收成五类机制,可按下表对照读。

五类机制 机制要点
双层目标 + 双轨对比 功能效果与工程结构两层;双轨 eval 与 diff 报告
旧版疑似错误 + 有效金标准 主动判定、待确认、动态白名单
单差异修复 + 能力门禁 语义提炼、唯一阶段;Schema/兜底门禁
人工指令 + 分歧提案 六类前缀;结构化决策材料
回归守护 + 同步 + 回写 + 冻结 副作用对比;实现同步;规则沉淀

双轨对比:两种 pass,两个目标

同一请求进旧接口和新接口。diff 不止 pass/fail,还有字段名、旧值、新值、条数偏差,以及相对原始旧基线与相对有效金标准两种通过态。

一边看功能效果:关键字段在有效金标准下是否一致、依赖方能不能照常用;一边看工程结构:修复是否落在唯一处理阶段、有没有乱加全文兜底。两个目标一起进 eval,免得测过了功能却又把代码结构弄烂。

上面订单例里,报告会写清 clearing_speeddialogue_send_to 旧空新非空,两种 pass 态都留着,后面走纠错或对齐分支。


旧版疑似错误:不能默认逼新版改回去

这和「出 diff」不是一步。clearing_speed 旧空、新版 +0,若业务规则写明应从 +N 解析,系统应主动标旧版疑似错误,写入纠错登记簿,状态待确认,把争议字段、旧值、新版值和依据推给人裁定。收到指令前:禁止为变绿静默改回空;待确认条目只接受 确认:坚持旧版行为:否决:问题: 四类前缀,不能无指令自动定案。

发出 确认:clearing_speed 以新版解析为准,纳入有效金标准 后,字段和覆盖规则进动态白名单(不事先穷举全集)。有效通过用新标准;原始基线对比仍保留审计。已冻结 case 不会再逼新版改回空。

dialogue_send_to 若语义本身不清(这个字段到底要不要输出),走 问题: 出分歧提案,不要硬套「旧版疑似错误」。


单差异怎么修:先语义,再阶段,再过门禁

每个差异按固定顺序来,不复制旧版调用链:用业务语言说清旧版在该字段上的规则;映射到新版管线唯一阶段(抽取修正、标准化、业务逻辑、协议适配等);过模型能力门禁;修完再跑双轨。

订单例:clearing_speed 应在抽后修正/标准化阶段做 +N 归一,别在协议层加全局正则抄旧代码。dialogue_send_to 要先看 Schema 槽位和命中率,再谈兜底。

拟加「全文扫 +\d」前,门禁要问:槽位有没有、命中率如何、会不会误吸别的数字。只有槽位稳定失败才允许兜底,并记来源类型(模型/规则/混合)。结构化模型已在该槽位稳定命中时,不必再叠正则------RegexValidator 那类补刀也是这个意思:补格式,不替代 schema。


人工指令与分歧提案

规范冲突、条数分歧、旧版疑错、文档和实现各说各话时,人用固定前缀发指令,系统按约定路由:

前缀 含义 订单例
确认: ① 按旧版语义修所列字段;或 ② 旧版疑似错误时,把新版正确输出纳入有效金标准 确认:dialogue_send_to 对齐旧版为空;② 确认:clearing_speed 以新版 +0 为准,入有效金标准
采纳建议: 输出一致,但采用更优工程路径 采纳建议:+N 归一放标准化配置,不新增全局正则
坚持旧版行为: 与旧版最大程度一致(纠错场景也可坚持对齐旧基线) 坚持旧版行为:clearing_speed 保持空
补充: 追加语料或用例 补充:追加 20 条含「对话发」话术
否决: 允许该字段长期与旧版不同 否决:dialogue_send_to 允许与旧版不同
问题: 语义不清 → 分歧提案 问题:dialogue_send_to 要不要作为输出字段?

当 AI 裁决不了时,出分歧提案:标题、旧版业务语义、旧版实现问题、建议落点、坚持旧版的工程代价、待选选项。人裁定后流程才继续。


回归守护、同步、回写、冻结

dialogue_send_to 可能误伤已通过 clearing_speed 的 case。动刀前先拉守护集合:已冻结通过的进硬守护,其余 effective pass 的进观察集合。接着列出候选修法(只动标准化配置 vs 加全局正则),对每套方案估一遍会影响哪些 case、哪些字段可能翻车,再等人选方案------和改共享模块前先问「会不会割到别处」是一类习惯,只是这里由双轨 eval 把影响面摊开给你看。

改完后对守护集合重跑双轨。已冻结 case 从过变不过,阻断冻结并告警;字段静默偏移则列入 diff,等人确认或回滚。

即使 effective pass 已为真,仍要交实现同步报告(用例、目标输出、变更模块、规则/配置变更、前后 diff 计数)。人工确认或无异议等待期结束后,才可冻结。

冻结前还要把裁定写回业务规则文档(例如 dialogue_send_to 要不要输出、clearing_speed 口径)。否则知识只留在 diff 和聊天里,下轮还会踩同一坑。这是硬门禁,不是顺手补文档。

差异常成簇,不必一次清完。订单迁移可以按批推进:条数切分、清算速度标准化、对话发送归属,一批只攻一种模式。已冻结 case 默认不再动,除非走纠错流程重新裁定。


边界

订单解析纯属举例;细节以团队工程约束为准。Semi-Autoresearch 不替代单测或 code review,管的是迁移期功能效果对齐与知识沉淀。Karpathy autoresearch 在目标单一、文档完备时仍有用;Semi 用于文档不全、旧版不可信、字段有歧义的生产迁移。守护层级、等待期长度按项目定。

方法有开源示例:github.com/GuiminChen/semi-autoresearch。主仓是方法论加最小 demo(toy legacy/v2 parser、双轨 eval、回归守护、人工前缀指令);另附示例 case study。跑一遍应能看到 raw pass 与 effective pass,legacy 疑错经 human confirm 后 corrections 生效,guard 能拦住 pass→fail。

收束一下:迁移要同时管住功能效果和工程结构,双轨报告保留两种 pass,旧基线不是唯一真理。旧版疑似错误要主动标、待确认、禁止静默迁就;确认: 在纠错场景是入有效金标准,不等于永远跟旧版一样。改代码前先回归守护,改完后同步报告和规则回写,再冻结------Semi 不是通宵 Agent,是带门禁的协作迭代。


本文为复杂系统迁移场景下的工程实践整理;Karpathy autoresearch 见 github.com/karpathy/autoresearch;示例仓库 github.com/GuiminChen/semi-autoresearch。

相关推荐
ctxinf1 小时前
Vercel Eve 实际上手初探
人工智能
HelloDong1 小时前
Loop Engineering 实战:用 Claude Code 工程化一个会自己验收、会自己停的 AI 循环
ai编程
HjhIron1 小时前
工具调用:当LLM学会使用"武器",AI Agent的底层逻辑拆解
llm·agent
用户5191495848451 小时前
利用ShellcodePack实现DLL劫持与COM对象劫持技术详解
人工智能·aigc
武子康1 小时前
调查研究-195 从 AmEx 支付系统看 Cell-based Architecture:真正的高可用,不是无限重试,而是控制失败边界
人工智能·openai·agent
米小虾1 小时前
Prompt Engineering —— 意图的精确表达
人工智能·agent
IT_陈寒2 小时前
React状态更新总是慢半拍?你可能忘了这个默认行为
前端·人工智能·后端
aneasystone本尊2 小时前
学习 turbovec 的混合检索与框架集成
人工智能
火山引擎开发者社区13 小时前
火山AgentPlan/CodingPlan同步上线GLM-5.2
人工智能