记一次 Coding Agent 改动带来的bug与启示
è®°ä¸æ¬¡ Coding Agent æ¹å¨å¸¦æ¥çbugä¸å¯ç¤º
桦说ç¼ç¨ 2026-08-17 36 é 读9åéæè¿ä½¿ç¨ Codex + GPT5.6 sol xhighéå°äºä¸ä¸ªå ¸å bugï¼è®°å½ä¸ä¸ï¼ä¸å¡å·²è±æ + 转æå ¶ä»ä¸å¡è¯´æï¼è¿éä» ä¸¾ä¾è¯´æé®é¢ï¼ä¾åèï¼æ ¸å¿ææä¸åã
äºæ ï¼ä¸è¡æ¹å¨è®©æ§çç¥éé»åè´¨
䏿¬¡çå®çç«è½¦ç¥¨å¾è¿è®¡ä»·äºæ ï¼ä¸å¥è¯å°±è½æ¦æ¬æè®ï¼
å ±äº«æ°æ®ä¸çäºå ±äº«è¯ä¹ï¼å¤ç¨è¾å ¥ä¸çäºå¤ç¨çç¥å设ã
ç³»ç»æ¶å°ä¸æ¬¡å¾è¿æ¥è¯¢ï¼ä¼æ¿å°å»ç¨ãè¿ç¨ä¸¤ä»½æ¥ä»·ï¼å»ç¨æ¥ä»·å¯¹åºå»ç¨æ¥æã车次ã座å¸ï¼è¿ç¨æ¥ä»·åç对åºè¿ç¨ãç³»ç»éæä¸¤ä¸ªè®¡ä»·çç¥ï¼é½å®ç°åä¸ä¸ª PricingStrategy æ¥å£ï¼çç¥æ¨¡å¼ï¼ï¼æ åå¾è¿çç¥è®©å»ç¨ãè¿ç¨åèªç¨èªå·±çè½¦æ¬¡ãæ¥ä»·ãæ ¡éªä¸ä¸æç»ååºä»·æ ¼ï¼å»ç¨åºå伿 çç¥ï¼æ°éæ±ï¼ä»¥å»ç¨ç¥¨é¢ä»·ä¸ºåºåï¼å
ä»å»ç¨æ¥ä»·å»ºç«ä¸ç¨ç´¢å¼ï¼åç»å伿 åæ°è®¡ç®ã
ä¸ºäºæ¯ææ°çç¥ï¼Agent æ¹äºå ¬å ±å è½½é»è¾ã忬å®åå«è¯»ä¸¤ä¸ªæ¹åçæ¥ä»·ï¼
List<FareQuote> outboundQuotes = input.getOutbound().getQuotes();
List<FareQuote> inboundQuotes = input.getInbound().getQuotes();
Agent æå®æ¹æäºè¿ç¨ä¹è¯»å»ç¨ï¼
List<FareQuote> outboundQuotes = input.getOutbound().getQuotes();
List<FareQuote> inboundQuotes = input.getOutbound().getQuotes();  // è¿ç¨è¯»æäºå»ç¨
æ¹å¨æ"åç"çè§£éï¼"æ°çç¥éè¦å»ç¨æ¥ä»·ä½åºåï¼å ¬å ±æµç¨ç»ä¸ç¨å»ç¨ï¼å°åä¸å¥é»è¾ã"ä½è¿æ®µå è½½é»è¾ä¸åªæå¡æ°çç¥ï¼æ åçç¥ä¹ç¨å®ãäºæ¯æ åçç¥çå®é è¡ä¸ºåæ"å»ç¨è½¦æ¬¡ + å»ç¨æ¥ä»·ãè¿ç¨è½¦æ¬¡ + å»ç¨æ¥ä»·"ï¼è¿ç¨æ¥ä»·æ¶å¤±äºãæ´ç³çæ¯ï¼ä¸æ¦è¿ç¨æ¢æå»ç¨ï¼è¿ç¨é¾è·¯éçå ¶ä»åæ°ââæ ¡éªä¸ä¸æãæ¥æãå车æ¶é´ãèªæ®µç´¢å¼ââé½å¯è½è¢«é¡ºæå¸¦éãè¿ç¨çè¿æ»¤æ¡ä»¶ãåºåå¤æãæ¶é´éå¶å ¨å¨ç¨å»ç¨ä¿¡æ¯ï¼ç»æå¯¹è±¡ç §å¸¸å建ï¼å´å·²ç»ä¸æ¯çå®ç"å»ç¨ + è¿ç¨"ç»åã
è¿ä¸ª bug æé´é©çå°æ¹å¨äºå®ä¸ä¼ç«å»æ´é²ï¼ç³»ç»ä¸å´©æºï¼ä»ç¶è¿åä»·æ ¼ï¼åªæ¯ä»·æ ¼çå«ä¹éäºãæ°çç¥çæµè¯åªéªè¯äº"è½ç¨å»ç¨æ¥ä»·"ï¼å½ç¶éè¿ï¼æ§çç¥æ²¡äººæµï¼æµè¯æ°æ®ä¹æ²¡æåºå度ã妿æµè¯æ°æ®æ¯"å»ç¨äºç座 100 å ãè¿ç¨äºç座 100 å "ï¼è¿ç¨é读å»ç¨ï¼éé¢ä¹ç¢°å·§ä¸æ ·ãæåºååº¦çæ°æ®åºè¯¥å»æä¸å¯¹ç§°ââå»ç¨æ¥ä»· ID 101ãä»·æ ¼ 100ï¼è¿ç¨æ¥ä»· ID 202ãä»·æ ¼ 230ââå¹¶åæ¶æè¨ï¼æ åçç¥å»ç¨ç¨ 101ãè¿ç¨ç¨ 202ï¼å»ç¨åºåçç¥çç´¢å¼åªå« 101ãåªæè¿æ ·æè½è¯æ"æ°æ§çç¥äºä¸æ±¡æ"åæ¶æç«ã
æ ¹å ï¼å ±äº«è¾å ¥ä¸çäºå ±äº«è¯ä¹
äºå容æè¯´"Agent ä¿®æ¹äºå ¬å ±å¯¹è±¡ï¼æä»¥å½±åäºå ¶ä»çç¥"ãæ´åç¡®çè¯´æ³æ¯ï¼åå§è¾å ¥å¯ä»¥å ±äº«ï¼å ¬å ±ä»£ç ä¸åºè¯¥æ¿æä¸ªçç¥éæ°è§£éè¾å ¥ãå¤ä¸ªçç¥è¯»åä¸ä¸ªåªè¯»ç RoundTripInput å®å ¨åçââæ åçç¥åå«è¯» outbound å inboundï¼æ°çç¥è¯» outbound çæèªå·±çåºåä»·ç´¢å¼ãçæ£å±é©çæ¯ææ°çç¥çç¹æ®å设åè¿å ¬å ±é¢å¤çå¨ï¼"ææçç¥é½æ inbound 彿 outbound"ãè¿ä¸æ¯æ°æ®å¤ç¨ï¼æ¯è¯ä¹æ±¡æã
çç¥æ¨¡å¼å¨è¿é没æèµ·ä¿æ¤ä½ç¨ï¼å¾å¤äººçå°ä¸¤ä¸ª PricingStrategy 就以为已ç»äºç¸é离äºãä½çç¥æ¨¡å¼åªéç¦»ç®æ³å
¥å£ï¼ä¸éç¦»ç®æ³ä¾èµçå
Œ
±é¢å¤çï¼Bug è½å¨ SharedPreprocessor éï¼ä¸¤ä¸ªçç¥é½ä¼ä¸æãçç¥æ¨¡å¼è§£å³çæ¯"éæ©åªä¸ªç®æ³"ï¼ä¸è§£å³"ç®æ³ä¹é´æ¯å¦å
±äº«äºé误çä¸ä¸æ"ã
ä¿®å¤ï¼é离派çç»æ
æ£ç¡®æ¹æ¡ä¸éè¦å¤å¶æ´ä»½å¾è¿è¾å
¥ï¼ä¹ä¸éè¦å¨æ åçç¥é塿¡ä»¶åæ¯ãç»æ°çç¥å¢å ä¸ä¸ªä¸ç¨çæ´¾ç对象 OutboundBenchmarkIndexï¼æµç¨åæï¼å
±äº«åªè¯»ç RoundTripInput ä¹ä¸ï¼æ åçç¥ç»§ç»åèªè¯» outbound / inboundï¼æ°çç¥æ outbound æ¥ä»·åç»èªå·±çç´¢å¼å计ç®ãå
Œ
±è¾å
¥åªæå»ºä¸æ¬¡ï¼æ¯ä¸ªçç¥æ¥æèªå·±çæ´¾çç»æåè§£éæ¹å¼ãè®°ä½ä¸æ¡è§åï¼åªè¯»è¾å
¥å¯ä»¥å
±äº«ï¼æ´¾çç»æå¿
é¡»ç§æãç³»ç»éå·²æç±»ä¼¼çä¸ç¨ç´¢å¼å°±ç´æ¥å¤ç¨ï¼ä¸è¦ä¸ºäº"çèµ·æ¥æ´é离"èå¤å¶ä¸æ´å¥åºå±è¾å
¥æ¨¡åââæ°å¯¹è±¡åºè¯¥è§£å³çå®ççå½å¨ææè¯ä¹å·®å¼ï¼è䏿¯å¢å ç»ææ°éã
ä½¿ç¨ Coding Agent çæ³¨æç¹
è¿ç±»äºæ ï¼Agent æå ¸åçç¯éè·¯å¾ãé¦å ï¼éæ±éå¸¸åªæè¿°æ°å¢è¡ä¸ºï¼"æ°çç¥ä½¿ç¨å»ç¨ç¥¨é¢ä»·"åå¾å¾æç¡®ï¼è"æ åçç¥å¿ 须继ç»ä½¿ç¨è¿ç¨æ¥ä»·"å¾å¾æ²¡åè¿éæ±ï¼åªè卿§ä»£ç çæ°æ®æµéãAgent å´ç»æ°å¢æµè¯è°æ´ä»£ç ï¼å°±å®¹æçºç²è¿ä¸ªéå¼å¥çº¦ãå ¶æ¬¡ï¼å¤ç¨çèµ·æ¥æ¯æ°å¢æ´¾ç对象æ´ç®åï¼ç´æ¥å¤ç¨å·²æçå»ç¨æ¥ä»·ï¼æ¹å¨å°ãçæä¹æ´å¹²åï¼ä½åºè¯¥å¤ç¨çæ¯åå§æ°æ®ï¼ä¸æ¯å ¶ä»çç¥çè§£éæ¹å¼ã忬¡ï¼éç©ºç»æä¼å¶é æåå象ââç¼è¯æåãæµè¯éè¿ãè¿åé颿£å¸¸ï¼è¡¥ä¸çèµ·æ¥å¯é ï¼èä¸å¡è¯ä¹é误ä¸ä¼æå¼å¸¸ï¼åªä¼å¨ç¹å®çä»·æ ¼ãæ¥æã座å¸ç»åä¸åºç°ãæåï¼åç§°åæ³¨éæªå¿ å¯é ï¼å¾è¿ä»£ç é firstãsecondãleg1ãleg2 ä¸ä¸å®ç¨³å®å¯¹åºå»ç¨åè¿ç¨ï¼å¤æå¯¹è±¡å½å±è¦æ²¿ç坿§è¡çæ°æ®æµç¡®è®¤ï¼è¿ä¸ªè½¦æ¬¡æ¥èªåªä¸ªå段ï¼è¿ä¸ªæ¥æå±äºåªä¸ªèªæ®µï¼è¿ä¸ªæ ¡éªä¸ä¸æååªä¸ªæ¥ä»·ä¸èµ·ç¨ï¼è¿ä¸ªç»ææç»åå ¥åªä¸ªçç¥çè¾åºï¼ä»£ç çå®é è°ç¨å ³ç³»æ¯æ³¨éååéåå¯é ã
å¯¹ä½¿ç¨ Agent ç人æ¥è¯´ï¼æå æ¡å¡å®çåæ³ï¼
-
éæ±éå"ç¦æ¢é¡¹"èä¸åªæ¯"æ°å¢é¡¹"ãAgent å颿§è¡ promptï¼æ²¡åç约æä¸æ¯è¢«å¿½ç¥ï¼èæ¯æ ¹æ¬ä¸ç¥éãä¾å¦ï¼
éæ±ï¼æ°å¢å»ç¨åºå伿 çç¥ï¼ä»¥å»ç¨ç¥¨é¢ä»·ä¸ºåºå计ç®ã æ°å¢é¡¹ï¼ - æ°å¢ BenchmarkStrategyï¼ç¨å»ç¨æ¥ä»·å»ºç«ä¸ç¨ç´¢å¼ ç¦æ¢é¡¹ï¼ - æ åå¾è¿çç¥å¿ 须继ç»è¯»è¿ç¨æ¥ä»·ï¼è¡ä¸ºä¸å¾æ¹å - å ¬å ±å è½½å¨ãé¢å¤çå¨ãRoundTripInput ä¸å¾ä¿®æ¹ åªå 许æ°å¢ï¼BenchmarkStrategy åå ¶æµè¯æä»¶ -
æç¡®æå®è§¦ç¢°è¾¹çãåè¯å®åªå 许æ°å¢æä¿®æ¹åªäºç±»ï¼å ¬å ± Contextãå è½½å¨ãé¢å¤çå¨ä¸å¾ä¸è®¸å¨ãAgent 对"ç¸å ³ä»£ç "ççè§£æ¯äººå®½æ³ï¼å¾åæ¹æè¿çå ¬å ±ä»£ç æ¥çäºã
-
å°½æ©ä½¿ç¨ code review åè½ï¼ç»å项ç®èªå®ä¹ä¸ä¼å review 注æç¹ãdiff 审æ¥ç¯å ±äº«è·¯å¾ï¼ä¸æ¯æ°å¢æä»¶ãæ°å¢çç¥ç±»å°çå ç¼é®é¢ä¸å¤§ï¼å ¬å ±ç»ä»¶æè·¯å¾æ¹ä¸è¡å¿ é¡»éå审ââæ¹å¨è¡æ°ä¸æ¯é£é©åº¦éï¼æ¹çæ¯è°ææ¯ã
-
å 让 Agent å"æ§è¡ä¸ºä¸å"çæµè¯ãå è¡¥ä¸æ¡ä¸¤ä¸ªçç¥åæ¶è·ãæ°æ®ä¸å¯¹ç§°çå彿µè¯ï¼ååæ°åè½ï¼æ¹åæ¶ç«å»çº¢ã
-
éªæ¶æ¶å¯¹ç § prompt é®å®å¨äºåªäºå ¬å ±ä»£ç ã为ä»ä¹ã对ä¸ä¸çæ¹å¨åç¬çï¼Agent 叏伿æ"顺æä¼å"ã
-
çææ°æ§çç¥åæ¶å¼å¯æ¶ï¼ä¸é´ç»ææ¯å¦äºä¸è¦çãå ±äº«çæ´¾çæ°æ®ä¸æ ·ä¼äºç¸æ±¡æï¼å³ä¸æè§åï¼åªè¯»è¾å ¥å¯ä»¥å ±äº«ï¼æ´¾çç»æå¿ é¡»ç§æã
-
注æä¸ä¸ªé«é¢å±é©ä¿¡å·ï¼"ä¸ºäºæ¯ææ°çç¥ï¼æå ¬å ±æµç¨ç»ä¸æ¹æä½¿ç¨æä¸ä¾§çæ°æ®ã"è¿å¥è¯é常æå³çå±é¨è§åæ£å¨è¶è¿çç¥è¾¹çã
代ç ä¾§ï¼æçº¦æåæå¼ºå¶
é Agent èªè§ä¸å¯é ï¼æå¥½è®©è¿ç±» bug å¨ç¼è¯æææµè¯æå°±æ´é²ã第ä¸å±æ¯ç±»åç¼ç è¯ä¹ï¼æ ¹å æ¯ outbound å inbound é½ç¨ List<FareQuote>ï¼æ¢éæ¹åç¼è¯ç
§æ ·è¿ã妿䏤侧æ¯ä¸åçè¯ä¹ç±»åï¼æ¯å¦ List<OutboundQuote> å List<InboundQuote>ï¼åªæåªæ¯è½»éå
è£
ç±»ï¼"æå»ç¨å¡ç»è¿ç¨"å°±ç´æ¥åæç¼è¯é误ã第äºå±æ¯è®©å
±äº«è¾å
¥åªè¯»ãæ´¾çç»æç§æï¼RoundTripInput æå»ºåä¸å¯åï¼æ°çç¥çæ°æ®è§å¾åªå¨èªå·±ç±»å
é¨çæãä¸å¤æ³å°å
Œ
±å±ï¼Agent æ³æ¹å
Œ
±é¢å¤ç卿¶ç±»å䏿 å¤ä¸æã第ä¸å±æ¯å¥çº¦æµè¯éæ»æ§çç¥ââ䏿¡æµè¯åæ¶è·ä¸¤ä¸ªçç¥ãç¨ä¸å¯¹ç§°æ°æ®ï¼æè¨åèªå¼ç¨åèªçæ¥ä»·ï¼
@Test
public void strategiesUseOwnLegData() {
  Result std = standardStrategy.calculate(input);   // è¿ç¨æ¥ä»· ID = 202
  Result bench = benchmarkStrategy.calculate(input); // ç´¢å¼åªå«å»ç¨ ID = 101
  assertStdUsesInbound202(std);
  assertBenchmarkIndexOnly101(bench);
}
è¿æ¡æµè¯è¦å¨å æ°åè½ä¹åå°±åå¨ï¼è¿ CIãæ¡åå¹¶ã第å屿¯åè½å¼å ³ï¼æ°çç¥èµ° QConfig å¼å ³ï¼å¼å ³å ³ææ¶è¡ä¸ºå¿ 须䏿¹å¨åéåèä¸è´ï¼å¼å ³å°±æäº"Agent æ¹åå ¬å ±é»è¾"çå åºé¸é¨ã第äºå±æ¯æä¾èµè§ååæä»£ç ï¼ç¨ ArchUnit ä¹ç±»å£°æ"æ°çç¥ç±»ä¸å¾ä¾èµå ¬å ±é¢å¤çå¨"ï¼è¿åå³ CI 失败ââè§ååææµè¯ï¼Agent å°±ä¸ä¼"è§å¾å¯ä»¥"ãè¿äºå±åå·¥ä¸åï¼ç±»åååªè¯»çº¦æå¨ç¼è¯ææ¦æªï¼å¥çº¦æµè¯å ArchUnit 卿µè¯/CI æäº®çº¢ç¯ï¼åè½å¼å ³æ¯è¿è¡æ¶çå åºé¸é¨ââæè¯ä¹æ±¡æä»éé»çè¿è¡æ¶ bugï¼åæç¼è¯éè¯¯ãæµè¯çº¢ç¯æå¯ä¸é®åéçå¼å ³ã
æ»ç»
è¿æ¬¡ä¿®å¤æ¬èº«ä¸å¤æï¼æ¢å¤æ åçç¥å¯¹å»ç¨åè¿ç¨æ¥ä»·çæ£ç¡®æ å°ï¼æ°çç¥ç»§ç»ä½¿ç¨èªå·±çåºåä»·ç´¢å¼ã
ä½è¿æ¬¡äºæ çæ£å¼å¾è®°ä½çï¼æ¯æä¹ç¨ Coding AgentãLLM æ§è¡å强ï¼ä¹ä¼ç¯ä½çº§é误ââæ inbound 读æ outbound å°±æ¯å ¸åä¸ä¾ãè¿ç±»é误æå±é©çæ¯é黿åï¼ç¼è¯è¿ãæµè¯è¿ãé颿£å¸¸ï¼è¯ä¹å´å·²éãLLM èªå·±æè¯ä¸å°ï¼å®å颿§è¡ promptï¼çº¦æä¸å¨ prompt éçäºä¸åå¨ï¼å ä¸å¤©ç¶æ ç¶æãä¸ä¸ææéï¼çä¸å°å®æ´è°ç¨é¾ï¼è¯ä¼°å ¬å ±ä»£ç å½±å颿¶æ´å®¹ææ¼æéå¼ä¾èµã
æä»¥å«å®å ¨ä¿¡ä»» Agentï¼ä¿¡ä»»è¦é éªè¯ã人çå·¥ä½ä¸æ¯æ¿ä»£å®å代ç ï¼èæ¯è¡¥ä¸å®ç¼ºç䏿 ·ä¸è¥¿ï¼
- æçº¦æååºæ¥ãç¦æ¢é¡¹ã触碰边çã"æ§è¡ä¸ºä¸å"ï¼å ¨æåè¿éæ±ãAgent ä¸ç¥éç约æçäºä¸åå¨ã
- 人为代ç 审æ¥ãcode review å diff 审æ¥ä¼å çå ¬å ±ä»£ç ï¼æ°å¢æä»¶å¯ä»¥æ¾å¿ï¼å ¬å ±è·¯å¾æ¹ä¸è¡è¦æ·±å ¥åæã
- æå åºå»ºèµ·æ¥ãå¥çº¦æµè¯ãç±»åç¼ç ãåè½å¼å ³ï¼è®©ä½çº§é误å¨ç¼è¯æãæµè¯ææå¼å ³å¤æ´é²ã
Aitishiku.com