【大模型LLM学习】AutoResearch——AFAC 2026赛题三实践
【大模型LLM学习】AutoResearch——AFAC 2026赛题三实践
0. 前言
今年天池AFAC的赛题三是Auto Research问题,要求实现一个Agent,让这个Agent自动的写代码、做实验、根据准确率反馈自己调整,包括2个数据集,对于每个数据集任务,有在1张4090显卡上总共2个小时运行的时间跑出测试集结果提交。
两个具体子任务:
(1)产品分类任务:以图节点分类的形式进行评测;
(2)产品推荐任务:在用户-产品的二部图上的图链接预测问题。
真的很想吐槽组委会…居然选用的是公开数据集,虽然B榜做了置换等操作,还是有人用codex把测试集标签完整复原了测试集ACC=100%,题目也很有歧义,不同人看理解不一样,是只允许LLM coding,还是可以直接走AutoGL这样的贝叶斯优化调参,最后阶段才看明白它的稀疏的意思是线上测试集的acc也可以当成反馈来过拟合线上测试集…
或许现在是AICoding的时代了,看群里有高中生用CodeX冲到了靠前的位置,不能再古法编程了,最后时刻发现bug也来不及提升了。
代码仓库:AFAC_AutoResearch
1. Auto Research
1.1 Auto Research定义
- 以顶层研究目标作为输入,在低人工干预下自主形成闭环:猜想提出 → 方案落地 → 实验执行 → 结果解读 → 迭代探索。
- 基础形态:自主修改代码、搭建实验、评估结论、调整探索方向
- 理想高阶形态:除完成科研探索之外,还能够基于海量历史实验轨迹反思自身工作缺陷,自动优化智能体提示词、执行流程、决策策略,实现系统自进化。
1.2 Auto Research 演进历程
完整演进链路:从封闭空间参数搜索 → 半开放模板搜索 → LLM 驱动开放科研 → 双层闭环自进化系统
- 网格搜索:【纯调参】无先验暴力枚举,全量遍历离散参数空间寻找最优解;不复用历史信息,高维场景遭遇维度灾难。
- TPE / Optuna:【纯调参】放弃盲目穷举,利用历史实验样本构建概率代理模型,平衡探索与利用,指导下一轮参数采样;参数空间必须人工预先定义固定。
- NAS(神经架构搜索):【模板内架构搜索 + 调参】在人工给定算子库内组合网络结构,同步优化超参;代表论文《Neural Architecture Search with Reinforcement Learning》。自动化模型剪枝(《HYDRA: Pruning Adversarially Robust Neural Networks》)也可以属于NAS范畴,在固定网络内寻找有效子网络。
- AutoGL:【领域专用 AutoML,图 NAS + 调参】面向图学习场景,自动挑选图编码器、聚合方式、超参数;论文 AutoGL: An AutoML Framework for Automated Graph Representation Learning。
- Sortify:【LLM 引导封闭空间调参】LLM 分析实验指标,输出高层优化约束与参数范围,搭配 TPE 贝叶斯优化完成权重搜索;排序策略骨架固定,无法修改业务代码、新增特征、创造全新策略结构。论文《Let the Agent Steer:Closed-Loop Ranking Optimization via Influence Exchange》。
- Data Agent:例如MetaGPT、QwenAgent等,原始的版本能完成一轮轮实验迭代,不能自动修改自身角色 Prompt、优化整套 Agent 工作范式。
- Arbor:【LLM 驱动开放空间自主科研】依靠假设树持久存储全部猜想、代码产物、成功 / 失败实验结论;Coordinator 推进新方向、修剪无效分枝、合并分枝,Executor 执行代码修改与实验;但缺少对智能体自身的优化。论文《Toward Generalist Autonomous Research via Hypothesis-Tree Refinement》。
- AgentX:【LLM 自主科研 + 元自进化双层闭环】快手声称用在了线上推荐,人工只在idea生成阶段参与,其余全部由LLM完成,自动化的coding+AB实验+线上重排等规则+根据AB实验结果coding。LLM还会根据线上结果,来反馈修改当前各个子模块的prompt,完成系统自进化。论文《AgentX: Towards Agent-Driven Self-Iteration of Industrial Recommender Systems》。
2. Auto Research——Arbor
Arbor 是一个自主科研智能体,它把一个长周期目标转化为持续累积的搜索过程。 给它一个基准 (benchmark)和一个目标,它会提出假设、修改代码、运行真实实验、从结果中学习,并保留那些在 留出(held-out)数据上确实站得住脚的改进作为当前最佳,不断迭代。
不同于“一次性尝试、过后即弃”的做法,Arbor 会生长出一棵假设树:每个想法都是一根分支—— 失败则剪枝,成功则保留——而洞见会沿树反向传播,让后续想法从更可靠的起点出发。
Arbor系统包含2个独立角色
- Coordinator(协调者): 维护想法树,通过 arbor cycle 驱动搜索,并派发实验。
- Executor(执行者):给定一个想法,它实现代码改动,在隔离的 git worktree 中运行实验,并汇报证据。
这种角色分工把策略(哪些假设值得验证)与执行(把一个假设变为现实)分开,让每个智能体各司其职。主体循环为:
Coordinator 以一个不断重复的循环驱动搜索。从概念上:
1. 构思(Ideate)。 在一个有潜力的节点下起草候选假设——每个都是真正的机制,而非参数微调。 (由一个 Skill 负责守住质量底线。)
2. 选择(Select)。 挑出下一个最有潜力的想法去验证,在利用当前最优路线与探索新方向之间取得平衡。
3. 实验(Experiment)。 派一个 Executor 去隔离地实现并运行这个想法。
4. 评估(Evaluate)。 读取产生的证据,并对照 dev 信号打分。
5. 反向传播(Backpropagate)。 抽象出学到的东西,把洞见上推到树中,让未来的想法继承它。
6. 合并或剪枝(Merge or prune)。 保留跨过留出闸门的改动;剪掉死分支。
循环持续进行,直到满足停止条件——预算耗尽、搜索收敛,或达成目标。
树的结构——想法树(the Idea Tree)
想法树是 Arbor 的持久记忆。每个节点是一个假设,附带其状态、它产生的证据以及从中提炼的洞见:
root: maximize held-out accuracy
├── stronger augmentation pipeline [merged] +1.4
│ ├── mixup + cutmix [pruned] overfits dev
│ └── test-time augmentation [merged] +0.6
└── swap backbone to ConvNeXt [running]
由于树是共享状态,智能体从不从聊天记录里重建上下文。Coordinator 读取树来决定下一步;Executor 只收到一份简洁、相关的摘要,而不是把先前的每条消息全部传给它。正是这一点,让 Arbor 能在一项长期 研究中持续推进,而不被自身历史淹没。
经验的反向传播:每次实验后,由 LLM 抽象出它为何成功或失败——“折叠构造中的数据泄漏”、“增益来自校准而非新层” ——并把那条洞见写回树的上层。同辈与后代想法于是从该知识出发,而不必重新发现它。
效果超过CodeX和CC
局限性
只有内层coding循环,不存在外层元优化循环,Arbor会学习怎么解决当前科研任务,但是不会持续优化自己这套Agent系统本身的提示词、工作流程、执行规则。 没有类似AgentX的机制反思Agent自身行为缺陷。
3. Auto Research——AgentX

快手的AgentX是近乎完全的Auto Research,应用于线上,人只在头脑风暴阶段参与,提升推荐系统迭代的效率,之后人只负责优化Agent和基础模型,让agent进行scaling。Agent的loop流程包括:头脑风暴(人说出需求,产生和筛选下一步迭代的idea)–>代码生成(生成线上规则,或开发训练模型)–>线上AB实验–>结果观测评估–>迭代优化生成的代码 + Agent系统的prompt自进化,包含2层自动化:
第一层:内层科研执行闭环(对应Arbor的能力域)
- Brainstorm Agent:自由生成全新方案提案
- Validation & Handoff:提案准入校验,生成标准化开发契约
- Developing Agent: policy → code↔verify→ exec → final review 多路并发专家、代码迭代自修复,支持线上策略/离线模型;
- Evaluation Agent 评估AB实验,收集完整执行轨迹。
第二层:外层元进化闭环 —— SGPO(Semantic-Gradient Prompt Optimization)
采集海量完整执行轨迹 → Judge分析失败案例 → 产出语义梯度(自然语言诊断) → 自动更新整套Agent的Prompt、约束、工作规范。
3.1 Brainstorm Agent

Brainstorm Agent要完成和用户的交互,输入包括人的模糊需求、历史实验经验,以及数据分析结果(Data Agent)、论文调研信息(Web Agent),结合可选的人工review和检查等,根据人输入的需求,产生出若干idea,最后筛选出一批最合理的idea出来,缩小后续筛选空间,告诉后续代码生成的agent要具体执行的代码生成任务。
这里的核心是前置的这些知识库和Agent的构建,例如System KB要负责把不符合线上pipeline和代码接口逻辑的idea拒绝掉,Model Research Agent要负责调研论文,整合成结构化的知识存储。
在获得一批idea后下发给编码环节之前,由一个validator来验证idea。校验器自动核查一整套条件:是否和顶层核心业务目标对齐、业务语义逻辑无误、满足所有外部约束、模型打分逻辑合规、在代码仓库中具备可落地性、和历史已尝试方案重复度(避免重复造轮子)、A/B 实验参数合法、方案成熟度统一。
3.2 Developing Agent
Developing Agent负责将审批通过的idea,转化为可核验的代码产物,包括两条推荐系统的并行工作流:
- Online strategy track 产出物 = 可合入主干的生产代码变更
面向新增特征、排序策略改动,安全承接真实线上流量,杜绝悄无声息的稳定性故障。 - Offline model track 产出物 = 一套完整训练实验
面向模型结构、网络架构创新提案,产出足够可信的实验结论,沉淀进入长期模型探索知识库。
重点硬核规则: 一次实验结论想要被认定「可信」,四条条件必须同时全部满足
- 最终代码实现,和提案声明的因果逻辑、预期观测现象保持一致【避免偶然随机提升】
- 独立专家组 Agent 评审,形成绝对多数共识
- 指标从原始日志确定性解析,禁止大模型口头解读、脑补指标,规避 LLM 幻觉
- 上报的指标提升(例如 AUC 上涨)必须附带可验证的因果链路归因。单纯数字上涨不算有效成果;找不到归因的指标提升,视作风险警报,不能存入知识库
3.2.1 模型代码开发
无论是online还是offline都可以用并发的方式实现一个LOOP提升效率,以Offline model track为例,每次开发包括下面的步骤:
- policy:依据idea进行代码生成,policy里面需要包含具体的实现和要观测的指标,可观测变量必须命名到可以直接嵌入 tf.print / tf.summary 的程度,并且明确定义什么是“健康”vs“病态”行为(例如:“step 1000 后 gate activation > 0.5 = 正常;≈ 0 = 坍塌”)。
- code与verify交互:在指定文件边界内实现 policy,Verify 模块检查代码实现是否和policy说的一样,可观测变量是否也都在代码里面,这个交互最多三次。
- 专家隔离盲审:专家互相隔离,避免观点传染;投票由程序硬规则执行
- exec:运行代码
- final_review:核心的验证,验证实验是否真正有效
3.2.2 模型效果评价 Final review
最终评审不只是简单看指标涨没涨;逐条核验 Policy 预先声明的整条因果链路。只有整条因果链条全部被观测证据证实,提升才被采信;AI 不能只看结果指标(AUC),必须验证“因果链条”上的每一环是否真的发生了。如果指标涨了但因果链断了,系统会拒绝记录这次成功,将其视为“刹车信号”。
Final review 汇总三类信息:指标数值、专家投票意见、训练日志,产出实验结论,针对 Policy 里提前写好的完整因果链,一环一环单独判定,结果三选一:
(1)verified 得到观测证实
(2) broken 和观测矛盾
(3)unclear 现有证据无法确认
之后由 Python 程序做确定性聚合规则:
(1)整条链条全部 verified → 归因状态 = CLEAR
(2)只要存在任意 broken /unclear → 归因状态 = UNCLEAR
文中有一个很具体的例子,避免随机巧合等被复用沉淀为有效经验:
Round 1:复现论文原始门控 x · tanh(Vₒx)
代码实现无误,离线 AUC 小幅上涨 +0.0003。
(如果没有因果归因校验,系统会直接标记为成功方案)。
Policy 提前定义的观测指标:门控激活值全程趋近于 0。
复盘根因:Glorot 初始化导致Vₒx≈0,tanh(0)≈0。门控持续输出 0、梯度直接被阻断,机制完全没有正常工作。
归因状态:UNCLEAR。本次指标提升不予记录、不采纳。
现象:分数涨了;机制和设想不一致 → 纯粹数值巧合,不可复用,不能沉淀为有效经验。
Round 2:一行代码改造 x · (1+tanh(Vₒx))
当Vₒ≈0时表达式退化为恒等映射,保证梯度通畅;
最终 ΔAUC=+0.0022,整条因果链路全部被观测验证,状态 CLEAR,成果正式收录。
3.4 Evaluation Agent
Evaluation Agent 负责合上 AgentX 整条工业闭环:接收线上 A/B 实验结果,不只是简单输出指标,把嘈杂、滞后的真实流量数据清洗、加工成可靠奖励信号;同时产出可复用约束,指导后续所有智能体迭代。Evaluation Agent 裁决本次代码变更三种去向:(1) 正式保留上线 (2)回滚代码(3)作为负面经验回流迭代
3.5 AgentX Harness Evolution
AgentX还包含了一个prompt自进化的模块,读取历史轨迹判断迭代方向,然后修改了prompt之后,和修改之前的,对同一份数据进行推理(不涉及模型训练的稀疏反馈,仅用LLM对这2份prompt输出的结果 h h h和 h ′ h' h′进行打分,LLM-as-judge的方式),如果打分有提升,就保留修改后的prompt。在自进化时,每次只选一个模块的来迭代,其他的固定住。
论文中提到用这种方式,对例如Model developing agent进行自进化,可以有效提升输出提升:
4. AFAC 2026赛题三实践
赛题三包括图结点分类和推荐系统2个数据集,图结点分类评估测试集ACC,推荐系统评估测试集的NDCG@10。
难点和挑战主要有:(1)仅2个小时运行时间,禁止并行实验,需要尽可能多让GPU训模型(2)要让实验朝着正向方向迭代收敛,节约每次实验机会
我的实现整体上包含3个模块,数据分析Agent、代码生成Agent和冒烟测试Agent:
每个模块负责的任务包括:
- 数据分析Agent:负责根据任务+数据集描述和当前训练情况,针对性生成数据探查代码,探查数据集分布,给出数据层面的模型建议
- 代码生成Agent:负责根据数据集分布、历史训练经验,总结本次最有希望的迭代方向,然后根据该方向生成代码。如果输出的代码被冒烟测试驳回,根据报错信息对代码进行修改,报错次数超过阈值则重新生成。
- 冒烟测试Agent:负责将epoch数修改为10,训练样本数修改为1000,运行冒烟测试,判断训练是否正常、是否报错,通过则正式运行,不通过则把结果返回给代码生成Agent:
- 预测结果后处理:将每次运行的模型结果进行集成和后处理,例如对图结点分类任务,执行GES进行N模型集成、运行LP或者C&S等图分类后处理算法,生成最终提交文件。
4.1 实现细节
4.1.1 迭代方向生成
这个对于结果的影响最大,这个写的好,在实验次数少的情况下模型的冷启动效果就好。可以约束好在实验次数已经较多的情况下小幅度迭代、逐渐收敛。
train_history_analyse_template = """你是图神经网络模型训练与调优专家,专注图节点分类,目标持续拉高验证集ACC。
### 当前状态信息
数据集探查信息:
{data_inspect_result}
所有训练尝试:
{history_train_summary}
### 探索方向和思路
1. **优先排查特征预处理瓶颈**:原始稀疏高维特征易造成注意力失效、收敛困难。ACC低于0.6优先校验标准化+PCA/SVD降维;若预处理后效果下跌,可尝试关闭标准化、减弱特征正则。
2. **分层管控正则强度(区分特征/结构/路径正则)**
特征:普通Dropout;图结构:DropEdge、DropNode;深度正则:DropPath。
中小稠密数据集禁止三类正则高强度叠加,极易欠拟合压制注意力表达;仅保留单一种类轻量正则,推理禁用拓扑扰动TTA,仅可使用Dropout TTA。
3. **架构迭代优先级**:实验不足5轮优先横向对比模型(GATv2/MixHop/JKNet);5轮以上聚焦细粒度结构与超参调优。
4. **图结构校验**:核对边无向化、自环配置、邻接归一化(对称归一/仅自环两种方案对照),拓扑是本数据集核心判别特征,不可随意扰动。
5. **模型容量与训练轮次匹配**:没有严重过拟合时可以提升层数、隐藏维度、注意力头数;epoch上限450,搭配早停。
6. **归一化、深度架构专项调优**
归一化层:对比BatchNorm(BN)、LayerNorm(LN)效果,深层GATv2优先LN,浅层可尝试BN;
深度连接:启用残差块缓解梯度消失,可堆叠3~4层深层GAT,搭配JK跳跃连接(Jumping Knowledge)聚合各层特征;
深度正则:DropPath随机丢弃层路径做轻量化正则,需调低丢弃概率,DropPath丢弃率0.1以内,不和高强度DropEdge叠加。
7. **损失与优化器超参**:可选CE/标签平滑,严控学习率与权重衰减组合,高lr+大weight_decay易训练震荡;如果类别极度不平衡,逆频加权后导致验证集ACC下滑,优先保持无类别加权
8. **连续多轮精度下滑策略**:回溯历史最优实验,对比预处理、归一化、JK、DropPath、正则、lr等差异,回退有效配置再小幅迭代。
### 任务要求
1. 定位验证集ACC瓶颈,覆盖特征预处理、正则组合、归一化(BN/LN)、JK跳跃、DropPath正则、模型容量、图结构、超参全维度;
2. 输出落地调优方案,明确架构、层数、归一化选择、JK开关、DropPath丢弃率、预处理、正则、超参细节;
3. 全文400字以内,纯文本简洁输出。
请开始分析并直接输出文本:
"""
4.1.2 代码生成
整体异步并行的方式,代码生成的输入包括当前全局最佳结果。在每次实验,首次生成时进行全量生成,如果没通过冒烟测试,则基于编辑的方式快速修改。全量生成,以图结点分类为例:
train_code_gen_template = """
你需要完成的任务为:
{task_description}
数据集信息为:
{dataset_description}
为此需要帮我完成一份完整的划分训练集验证集、构建模型、使用训练集训练模型,使用验证集验证ACC、对测试集进行预测并输出B1.csv到文件夹为{model_save_dir}下的代码
特别的,训练集/验证集划分方式为:
1. 加载 B1.npz 中预定义的 train_idx 和 test_idx 作为固定的训练集与测试集节点索引;
2. 验证集的构建方式:从 train_idx 中随机抽取 20% 的节点作为验证集(val_idx),剩余 80% 作为实际训练集(actual_train_idx)。抽取时必须使用种子 666 确保可复现;
可以参考的逻辑为:
def _reproduce_val_split(train_idx: np.ndarray) -> tuple:
rng = np.random.RandomState(666)
shuffled_idx = rng.permutation(train_idx)
n_actual_train = math.ceil(len(shuffled_idx) * 0.8)
actual_train_idx = shuffled_idx[:n_actual_train]
val_idx = shuffled_idx[n_actual_train:]
return actual_train_idx, val_idx
测试集输出文件命名为B1.csv,必须包含表头,且仅允许包含两列,例如:
test_idx,label
18,3
19,7
其中:test_idx:测试节点编号,必须与数据集保持一致。label:选手预测的类别编号,必须为合法整数类别编号。
为了便于调试,你可以比如每隔10个epoch打印一次验证集ACC,便于后续排查是否过拟合、欠拟合等等。
训练过程中,你需要print验证集上准确率,并且在每次新出现效果最好的模型时,立即保存效果最好的模型(该模型命名为best_model.pth,模型保存路径为{model_save_dir}),然后使用这个模型完成测试集推理,输出B1.csv到文件夹为{model_save_dir}下(如果这个文件存在,直接覆盖)。
同时每次新出现效果最好的模型时,还必须输出测试集每个类别的类别的softmax分数候选文件 B1-softmax.csv 和验证集候选文件 validation-softmax.csv以便于后续集成使用。
validation-softmax.csv和B1-softmax.csv格式要求:
- 两个文件表头统一为:test_idx,class_0,class_1,class_2,class_3,class_4,class_5,class_6,class_7
- validation-softmax.csv 的 test_idx 列存放验证集节点编号,B1-softmax.csv 的 test_idx 列存放测试集节点编号
- 每行包括idx以及对应的8个类别的softmax分数,用英文逗号连接,test_idx 必须为整数类型,softmax分数必须是浮点数,保留4位小数,类别列按编号升序排列
【索引对齐铁律 · 必须严格遵守】
保存CSV时,必须直接用 val_idx / test_idx 整数数组索引模型输出,保证行顺序与ID顺序一一对应;
禁止用布尔掩码(val_mask/test_mask)提取输出后再拼接打乱的索引数组,否则ID与概率会错位。
参考写法(核心只看这两行):
val_probs = F.softmax(out[val_idx], dim=1).cpu().numpy() # 验证集:用 val_idx 直接取
test_probs = F.softmax(out[test_idx], dim=1).cpu().numpy() # 测试集:用 test_idx 直接取
训练时计算ACC可以继续使用布尔掩码,不影响准确率。
【测试集TTA增强 · 默认启用】
1. 仅测试集最终输出启用TTA(测试时增强),基于Dropout多次推理取平均,免费提升泛化性能;验证集始终使用纯eval模式,保证与训练过程口径一致。
2. 实现方式:训练全部结束、加载最优模型后,开启模型train模式启用Dropout,重复推理40-50次,对softmax概率取平均后生成最终测试集文件。
3. validation-softmax.csv 不做TTA,保持与训练验证ACC同口径,用于后续集成评估。
为了提升训练效率和效果,你只能使用一种模型(不考虑多模型融合),并且注意准确率和效率(显存20GB以内)。你可以使用torch_geometric库构建模型(例如GAT、GATv2、MixHop和各种变体等)。
在模型准确率持续上升的情况下,即使过拟合程度有略微提升,也可以尝试加大一些epoch和early stopping的patience。如果都还没有发生过拟合,甚至比较欠拟合,更可以大胆的上调epoch和模型复杂度。初期epoch可以在100-200左右,后期可以epoch上调到300-500。patience可以设置大一些,比如30-50。
之前你做了一些尝试,有前景的方向为:
{optimize_direction}
当前代码【重点参考格式】:
{reference_code}
上一轮报错信息(如果有):
{last_error}
# Constraint
要完成这个任务,你需要分析瓶颈和提升方向,完成对当前代码的调整和优化,直接输出可执行的python代码,不要解释。尤其注意数据集导入和最后预测的代码的逻辑准确性,如果之前出错,注意不要重犯错误。
请开始输出:
"""
4.1.3 冒烟测试
冒烟测试负责短时间快速运行,可代码是否报错,并用脚本验证运行结果是否包含所需的输出文件、输出文件格式是否准确。冒烟测试前,需要将代码基于编辑的方式进行修改,修改epoch和训练样本数:
smoking_test_edit_template = """
# Role
你是一个代码冒烟测试专家。你的任务是修改给定的代码片段,使其能以最小代价快速跑通全流程,用于验证代码逻辑和输出格式是否正确。
# Goal
请对以下代码进行冒烟测试级别的修改,具体目标:
1. 将训练轮数 epochs 修改为 10,确保能快速跑完)
2. 在划分完训练集和验证集之后的代码里面,将训练集规模缩小(使训练集仅使用 1000 条数据,注意有可能前半部分和后半代码都要修改,防止取数报索引越界和device不一致错误;禁止缩小测试集和验证集大小,禁止缩小会输出的csv这部分大小,后续有校验)
3. 保持其他核心逻辑(模型结构、损失函数、输出格式、测试集规模和顺序等)完全不变
4. 确保修改后代码语法正确,且能正常产出验证集 loss 和完整的测试集输出文件
5. 尤其关注如果你修改或者引入了index变量,要注意变量tensor的device,确保不会出现cpu和gpu混用导致的报错
# 特别注意
* 千万不要在训练集/验证集划分结束前动训练集大小,否则划分出的验证集将会受到影响,会导致验证报错
# Constraint
修改将通过 llm_diff_edit_tool 执行,该工具要求:
- 每次替换的 original_str 必须在文件中【唯一存在】
- 支持多对替换,按顺序依次执行
- original_str 必须确保唯一,避免匹配到多处相同代码,必须保证和要替换的原文一模一样否则匹配不上。如果是修改某些参数,往往仅当前行局部即可锁定唯一,不要包含过多上下文导致上下文过长
- 对于original_str,建议小型的修改例如就参数的修改,不要把参数前面的空格或者tab内容包含进去,防止匹配不上字符串;长段的修改则需要严格保证特殊字符(缩进换行等)完全一样防止匹配不上,原始代码文件是4个空格缩进而非tab的
# Output Format
你必须且只能输出一个 JSON 数组,每个元素是一对替换,可以有多对替换,格式如下:
[
{{
"original_str": "要替换的原始代码字符串(确保唯一)",
"new_str": "替换后的新代码字符串"
}}
]
⚠️ 禁止输出任何解释、分析、markdown 代码块标记或其他文字,仅输出纯 JSON 数组。
# Last round error
下面是上次编辑时的报错信息(如果有),清注意避免:
{last_edit_error}
# Code to Edit
{code_piece}
"""
def llm_diff_edit_tool(file_path, original_str, new_str, save_path)->bool:
try:
# 判断文件是否存在
if not os.path.exists(file_path):
dual_print(f"⚠️ 文件不存在: {file_path}")
return False,f"⚠️ 文件不存在: {file_path}"
# 读取文件内容
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
# 判断原始字符串是否唯一存在
if content.count(original_str) == 0:
dual_print(f"⚠️ 原始字符串不存在: {original_str}")
return False,f"⚠️ 原始字符串不存在: {original_str}"
elif content.count(original_str) != 1:
dual_print(f"⚠️ 原始字符串不唯一: {original_str}")
return False,f"⚠️ 原始字符串不唯一存在: {original_str}"
# 替换字符串
content = content.replace(original_str, new_str)
# 保存文件
with open(save_path, "w", encoding="utf-8") as f:
f.write(content)
dual_print(f"✅ 替换成功: {original_str} -> {new_str}")
return True,""
except Exception as e:
dual_print(f"❌ 替换失败: {e}")
return False,"❌ 替换失败: {e}"
def apply_code_edits(file_path: str, edits: List[Dict[str, str]], save_path: str = None) -> bool:
"""
串行执行多对 diff 编辑,每对编辑基于上一次编辑后的文件内容。
"""
if save_path is None:
save_path = file_path
current_file = file_path
for i, edit in enumerate(edits):
# 首尾去掉空白,后面看看是否需要
original = edit["original_str"]#.strip()
new = edit["new_str"]#
dual_print(f"🔧 执行第 {i+1}/{len(edits)} 对替换...")
success,error_info = llm_diff_edit_tool(current_file, original, new, save_path)
if not success:
dual_print(f"❌ 第 {i+1} 对替换失败,中止后续编辑")
return False,f"❌ 第 {i+1} 对替换失败,中止后续编辑。"+error_info
# 后续替换基于已保存的文件
current_file = save_path
dual_print(f"✅ 全部 {len(edits)} 对替换执行完毕")
return True,""
同时,冒烟测试还要检查训练过程是否有loss异常的情况,但是注意,冒烟测试样本很少,不能对acc/ndcg要求太高:
smoking_test_judge_template = """
# Role
你是一个冒烟测试结果判定器。请根据提供的训练日志,严格按照以下规则判断代码是否跑通且逻辑基本正常。
# Judgment Rules
满足以下【全部】条件则判定为"正常",否则判定为"异常":
1. 日志中无任何 Error / Exception / Traceback 报错
2. Loss 值全程不为 NaN / Inf
3. 验证集 ACC > 0.1(冒烟测试数据量极小,仅为排除模型完全失效)
4. 训练流程完整执行到了结束或 EarlyStopping,未中途崩溃
# Output Constraint
⚠️ 你必须且只能输出两个字:"正常" 或 "异常"
⚠️ 禁止输出任何分析过程、标点符号、换行符或其他文字
# Training Log
{train_log}
"""
4.2 结果观察
- 好的冷启动很重要,一开始acc很低的后面也很难震荡上去
- 虽然3个code worker异步生成,中间还是有不少时间GPU在等待任务
- 在图结点分类任务上,除了初期的抖动,平均的acc是一直在稳步提升的

- B榜图结点分类的验证集acc(包括带后处理)曲线,B榜里面测试集疑似操纵过,A榜的验证集和测试集acc是比较接近的,B榜线下0.56是线上0.41

更多推荐




所有评论(0)