
在實際的 LLM Coding 評測和 Agent 開發中有一個很反直覺的現象模型權重完全沒動提示詞也沒改只是把模型外層的執行腳手架從“單次生成答案”改成“生成代碼 - 運行測試 - 返回報錯 - 讓模型修改”的閉環許多不同模型的編碼指標會同時上升。標題里的 “Only the harness changed” 說的就是這個場景。harness 在這里不是模型參數也不是 prompt 模板而是包裹在模型之外負責輸入構造、工具調用、代碼執行、結果反饋和重試策略的一整套工程系統。這篇文章會圍繞 harness 展開先說明它是什么為什么能影響 15 個模型的編碼表現再一步步實現一個最小可復現的 coding harness并用它批量評估多個 LLM。適合正在做模型評測、編碼 Agent、AI 編程工具鏈的工程師閱讀。讀完以后你可以把這套方案復制到自己的項目里用同一套 harness 橫向對比不同模型也能理解為什么“換模型不如換 harness”。1. Harness 到底是什么模型之外的執行與評測系統1.1 從一個“模型集體變強”的現象說起如果只看結果很多人會以為某個新版本模型“一夜之間變強了”。但標題里的現象并不是模型參數升級而是推理時的運行方式變了??梢赃@樣理解同樣是做一張數學卷子之前要求直接寫答案現在允許在草稿紙上演算、檢查、改正最后再上交。草稿紙沒有改變考生大腦里的知識但確實提高了最終得分。LLM 也一樣。同一個模型在同樣的權重下如果外部系統允許它先執行代碼、看到報錯、再修改答案它的 coding 指標就可能明顯提升。這就是 harness 的作用它不是一個更大的模型也不是更長的 prompt而是把“推理一次”擴展成“推理、執行、反饋、再推理”的完整循環。這里要特別說明不同評測集、不同模型供應商、不同任務難度下harness 帶來的提升幅度并不一樣。不要把這個現象理解成“任何模型都能被 harness 救活”。模型本身的能力仍然是上限harness 負責把已經存在但未被充分利用的能力釋放出來。1.2 Harness 在 LLM Coding 場景中的技術定位在 LLM coding 場景里harness 通常包含幾個核心部分輸入構造把題目、代碼模板、歷史錯誤、測試結果組裝成模型能理解的上下文。動作執行讓模型有機會運行代碼、執行命令、讀取文件而不是只輸出靜態文本。環境反饋把執行后的 stdout、stderr、退出碼、測試斷言結果返回給模型。迭代控制決定最大嘗試次數、何時停止、何時切換策略。結果評估用隱藏測試、靜態檢查、人工規則判斷最終答案是否真正正確。模型、prompt、harness 是三個不同層面的東西。用一張表可以看得更清楚層面決定因素典型改動影響范圍模型權重和架構換模型、微調基礎語言理解、代碼生成能力Prompt輸入文本和示例改任務描述、Few-shot 示例模型對當前任務的理解方式Harness外部執行和反饋循環增加測試執行、工具調用、重試模型能否利用執行結果自我修正很多團隊在優化 coding 效果時第一反應是換更大模型或寫更多 prompt 示例。實際上如果模型生成的代碼經常只差一個邊界條件harness 里加一輪“跑測試再修復”通常更便宜、更穩定。1.3 Harness 與 Agent 的關系Agent 是 harness 的高級形態但二者不是一回事。最小可用的 coding harness 可以只有四步生成、執行、反饋、重試。Agent 則在此基礎上增加了更復雜的規劃、記憶、多工具選擇和長期目標維護。換句話說Agent 框架本質上是一套加強版 harness。理解 harness 的底層邏輯再去看 LangChain、自研 Agent、MCP 等工具時會更容易抓住核心它們都在解決“模型如何觀察外部世界、如何行動、如何根據反饋調整”的問題。所以這篇文章先從一個最小 harness 開始。它不需要復雜的 Agent 框架也能實驗出“只改 harness 就能提升多個模型”的效果。2. 為什么只改 Harness 就能提升多個 LLM 的編碼能力2.1 單次生成的盲區模型看不到運行結果不接 harness 時LLM 編碼是單向過程用戶給題目模型給代碼結束。如果代碼有語法錯誤、邊界條件錯誤、邏輯缺陷模型完全沒有機會看見。它只能依賴訓練時見過的相似問題模式來推斷。這種模式適合“短答案生成”但不適合“程序必須可運行”的場景。一個函數能否通過所有測試用例不取決于生成時看起來是否合理而取決于在真實 Python 環境中的執行結果。模型無法運行代碼就無法獲得這一關鍵信息。2.2 反饋回路讓“試錯”成為推理的一部分接入 harness 后模型的每次錯誤都不是終點而是下一步推理的輸入。舉個例子模型第一次生成def two_sum(nums, target): for i in range(len(nums)): for j in range(len(nums)): if i ! j and nums[i] nums[j] target: return [i, j]用樣例測試[2, 7, 11, 15], 9可以通過但用邊界測試[3, 2, 4], 6會失敗因為正確答案是[1, 2]而雙重循環可能先返回[0, 0]這種非法組合。如果不執行測試模型永遠不知道這個問題。加了 harness 后反饋信息里會包含斷言失敗assert res [1, 2] failed: expected [1, 2], got [0, 0]模型看到這個反饋后通常會在下一次生成時修正邏輯讓內層循環從i 1開始。這個過程非常接近人類工程師調試代碼。2.3 工具調用擴展了模型的信息邊界更強的 harness 不只是運行代碼還可以讓模型讀取文件、執行 shell 命令、查詢 API 文檔、搜索代碼倉庫。模型訓練數據里沒有的依賴版本、內部 API 簽名、最新框架用法都可以通過工具調用即時獲取。這也解釋了為什么 15 個模型都能從 harness 改動中受益它們不需要共享同一套秘密技巧只需要共用同一個能執行、能反饋、能搜索的外部系統。每個模型都會根據自己的能力從反饋中提取信息最終整體通過率上升。2.4 更合理的評判標準交付前先驗證很多模型在 benchmark 上得分高但實際交付時仍然需要工程師修改。原因之一是評測只檢查“模型輸出是否看起來對”而不檢查“代碼是否真的能運行通過”。harness 改變了評判方式不是模型生成完就交卷而是生成后先進入沙箱執行測試測試通過后才算完成。如果失敗就繼續反饋和重試。這樣最終產物是經過執行驗證的代碼而不是一段沒有運行過的字符串。對于 Coding 類任務這種“執行優先”的評判思路比單純比較生成文本相似度可靠得多。3. 動手實現一個最小可復現的 Coding Harness3.1 場景與工作機制我們要實現一個最小但有完整閉環的 harness。它接收一個編程題目和若干測試用例調用任意 OpenAI 兼容接口的 LLM 生成 Python 代碼在本地沙箱中執行測試。如果測試失敗就把錯誤信息返回給模型讓模型繼續修復最多重試若干次。技術棧選擇Python 3.10 以上openaiPython SDK用于調用 OpenAI 兼容接口PyYAML用于讀取配置文件subprocesstempfile用于隔離運行模型生成的代碼學習環境下使用subprocess加超時已經足夠。生產環境要換成 Docker 容器或云沙箱不要直接在本機執行不受信任的模型代碼。3.2 環境準備與依賴安裝先創建虛擬環境并安裝依賴python -m venv .venv source .venv/bin/activate pip install openai pyyamlOpenAI 兼容接口的模型可以通過環境變量配置export OPENAI_API_KEY替換為你的 API Key export OPENAI_BASE_URLhttps://api.deepseek.com/v1這里使用OPENAI_BASE_URL的好處是可以平滑切換到任意兼容 OpenAI 協議的網關。模型名在配置文件中單獨指定例如deepseek-chat、qwen-plus、gpt-4o-mini等。實際運行時要把密鑰和域名替換成自己環境對應的值。3.3 數據模型與配置文件為了讓評測可重復先用配置文件管理模型參數和 sandbox 參數# config.yaml model: deepseek-chat temperature: 0.2 max_tokens: 2048 max_attempts: 3 sandbox_timeout: 10 test_timeout: 5 truncate_feedback: 2000字段含義參數默認值示例作用modeldeepseek-chat指定要調用的模型名temperature0.2控制生成隨機性越低越穩定max_tokens2048限制單次輸出長度max_attempts3允許模型修復代碼的最大輪數sandbox_timeout10每次運行測試腳本的超時時間單位秒truncate_feedback2000截斷返回給模型的錯誤信息長度避免上下文膨脹任務文件用 JSON 保存題目和測試用例{ id: two-sum, instruction: 實現函數 two_sum(nums, target)返回兩個下標組成的列表使兩個數之和等于 target。, entry_point: two_sum, tests: [ {args: [[2, 7, 11, 15], 9], expected: [0, 1]}, {args: [[3, 2, 4], 6], expected: [1, 2]}, {args: [[0, 4, 3, 0], 0], expected: [0, 3]} ] }這里測試用例不僅僅是樣例。[0, 4, 3, 0], 0這種邊界測試會暴露“返回相同下標”的錯誤是評測 harness 必須覆蓋的場景。3.4 核心代碼實現先定義數據類# harness.py import argparse import json import os import subprocess import sys import tempfile import textwrap from dataclasses import dataclass from openai import OpenAI import yaml dataclass class TestCase: args: list expected: object dataclass class Task: id: str instruction: str entry_point: str tests: list[TestCase] dataclass class HarnessConfig: model: str temperature: float 0.2 max_tokens: int 2048 max_attempts: int 3 sandbox_timeout: int 10 test_timeout: int 5 truncate_feedback: int 2000加載任務和配置def load_task(path: str) - Task: with open(path, r, encodingutf-8) as f: data json.load(f) tests [TestCase(argst[args], expectedt[expected]) for t in data[tests]] return Task( iddata[id], instructiondata[instruction], entry_pointdata[entry_point], teststests, ) def load_config(path: str) - HarnessConfig: with open(path, r, encodingutf-8) as f: data yaml.safe_load(f) return HarnessConfig(**data)構造測試腳本。這里把用戶代碼和斷言拼成一個獨立腳本通過subprocess執行def build_test_script(user_code: str, task: Task) - str: parts [user_code, ] for idx, t in enumerate(task.tests): args_repr , .join(json.dumps(arg) for arg in t.args) expected_repr json.dumps(t.expected, ensure_asciiFalse) parts.append(fres {task.entry_point}({args_repr})) parts.append( fassert res {expected_repr}, fcase {idx} failed: expected {expected_repr}, got repr(res) ) parts.append(print(PASS)) parts.append(print(ALL_PASS)) return \n.join(parts) def run_tests(user_code: str, task: Task, timeout: int) - dict: test_script build_test_script(user_code, task) with tempfile.TemporaryDirectory() as tmpdir: try: proc subprocess.run( [sys.executable, -I, -c, test_script], capture_outputTrue, textTrue, timeouttimeout, cwdtmpdir, ) except subprocess.TimeoutExpired: return { passed: False, stdout: , stderr: TimeoutExpired: 代碼運行超時, } if proc.returncode 0 and ALL_PASS in proc.stdout: return {passed: True, stdout: proc.stdout, stderr: proc.stderr} stderr proc.stderr or proc.stdout return {passed: False, stdout: proc.stdout, stderr: stderr}從模型輸出中提取代碼。為保證兼容性允許模型輸出 Markdown 代碼塊import re def extract_code(raw_output: str) - str: pattern r(?:python)?\s*(.*?) match re.search(pattern, raw_output, re.S) if match: return match.group(1).strip() return raw_output.strip()核心重試循環def solve_task(client: OpenAI, config: HarnessConfig, task: Task) - dict: messages [ { role: system, content: 你是一個 Python 編程助手。只輸出可運行的 Python 代碼不要添加多余解釋。, }, {role: user, content: task.instruction}, ] attempts [] for attempt in range(1, config.max_attempts 1): resp client.chat.completions.create( modelconfig.model, messagesmessages, temperatureconfig.temperature, max_tokensconfig.max_tokens, ) raw_output resp.choices[0].message.content or code extract_code(raw_output) result run_tests(code, task, config.sandbox_timeout) attempts.append( { attempt: attempt, code: code, passed: result[passed], stderr: result[stderr][-config.truncate_feedback :], } ) if result[passed]: return {status: solved, attempts: attempts, final_code: code} feedback f第 {attempt} 次運行失敗請修復代碼\n{result[stderr][-config.truncate_feedback:]} messages.append({role: assistant, content: code}) messages.append({role: user, content: feedback}) return {status: failed, attempts: attempts, final_code: None}最后是命令行入口def main(): parser argparse.ArgumentParser() parser.add_argument(--task, requiredTrue, help任務 JSON 文件路徑) parser.add_argument(--config, defaultconfig.yaml, helpharness 配置文件路徑) args parser.parse_args() config load_config(args.config) task load_task(args.task) client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) result solve_task(client, config, task) print(json.dumps(result, ensure_asciiFalse, indent2)) if __name__ __main__: main()這段代碼有幾個關鍵點需要解釋模型輸出先經過extract_code再進入沙箱執行避免模型在代碼塊外添加解釋導致運行失敗。每次失敗后把模型自己的代碼和報錯一起追加到對話歷史中讓模型在同一上下文里繼續修改。truncate_feedback防止巨型 traceback 撐爆上下文。-I參數讓 Python 以隔離模式運行忽略當前 PYTHONPATH 影響降低環境干擾。3.5 運行與驗證保存好config.yaml、task.json、harness.py后執行python harness.py --task task.json --config config.yaml如果一切正常會輸出類似下面的 JSON{ status: solved, attempts: [ { attempt: 1, passed: false, stderr: assert res [1, 2] failed: expected [1, 2], got [0, 0] }, { attempt: 2, passed: true, stderr: } ], final_code: def two_sum(nums, target):\n seen {}\n for i, n in enumerate(nums):\n if target - n in seen:\n return [seen[target - n], i]\n seen[n] i\n }注意status是solved只代表模型通過了任務里配置的測試用例。它不能證明代碼在所有情況下都正確。這個區分很重要后面專門講。4. 用同一套 Harness 評估 15 個 LLM 的流程設計4.1 為什么必須使用同一套 Harness如果你要橫向對比多個模型必須讓 harness 完全一致。因為不同的重試次數、不同的測試用例、不同的沙箱超時都會直接影響最終得分。有些模型在 1 次嘗試內表現不佳但如果在 3 次嘗試中能通過最終排名就會不一樣?!爸桓?harness 就提升 15 個 LLM”的場景里提升幅度并不只屬于某一個模型。所有模型共享同一個改進后的執行反饋機制。如果你在評測時給 A 模型 5 次重試給 B 模型 1 次重試那結果沒有可比性。統一內容至少包括同一個任務集和測試用例。同一個max_attempts。同一個temperature。同一個沙箱超時時間。同一個反饋截斷長度。同一個系統提示詞。任何一項不一致都應視為不同 harness而不是不同模型的真實對比。4.2 評測集與判定規則評測集不能只有公開樣例還要包含隱藏測試用例。最簡單的方式是像前面task.json一樣把每個任務拆成“展示給模型的 instruction”和“模型看不到的 tests”兩部分。模型自己不能提前看到全部測試否則它可能生成專門針對測試用例的硬編碼。更完整的評測集應該覆蓋基礎功能正常輸入。邊界條件空數組、最小值、最大值、重復元素。異常輸入不符合題目約束的數據是否被合理處理。性能約束大數據量下是否超時。不同難度的題目混合在一起能看出模型在不同復雜度下的表現差異。如果只有一個簡單樣例15 個模型可能全都滿分無法區分 harness 的作用。4.3 批量評估與指標輸出批量評估腳本可以循環遍歷任務文件和模型列表。為了控制成本建議把配置參數單獨抽取出來python evaluate.py \ --task-dir tasks/ \ --models deepseek-chat qwen-plus gpt-4o-mini \ --config config.yaml \ --concurrency 4 \ --output report.jsonl評估腳本內部可以這樣組織def evaluate_one(client, config, task, model): result solve_task(client, config, task) return { task_id: task.id, model: model, status: result[status], attempt_count: len(result[attempts]), token_usage_estimate: estimate_tokens(result[attempts]), } def evaluate_all(client, config, tasks, models): records [] for model in models: for task in tasks: cfg HarnessConfig(**{**config.__dict__, model: model}) records.append(evaluate_one(client, cfg, task, model)) return records收集完記錄后可以統計每個模型的首次通過率、最終通過率和平均嘗試次數指標計算方式首次通過率第 1 次嘗試即通過的任務數 / 總任務數最終通過率在max_attempts內通過的任務數 / 總任務數平均嘗試次數所有已通過任務的嘗試次數平均值平均耗時單任務從開始到結束的墻鐘時間平均值注意這里展示的表格結構是通用指標設計不是任何特定模型的真實分數。你在自己的評測集上得到的結果可以作為內部選型依據。4.4 成本與并發控制批量評估 15 個模型時token 消耗會迅速增加。每個失敗嘗試都會額外消耗一次模型調用和一次反饋上下文??刂瞥杀究梢詮膸追矫嫒胧窒拗苖ax_attempts一般 3 到 5 次足夠。對相同請求做緩存相同模型、相同任務、相同重試不必重復調用。使用并發時控制請求速率避免觸發限流。記錄每次調用的 prompt token 和 completion token便于核算成本。并發不是越高越好。限流和超時會導致評測結果不穩定最終浪費更多重試。更穩妥的做法是先單線程跑通一個小樣本確認流程穩定后再加大并發。5. Harness 關鍵參數與調優5.1 重試次數、溫度與最大 token這幾個參數直接影響評測結果和成本。參數取值范圍參考調小的影響調大的影響max_attempts1 - 5成本低但模型沒有自糾機會成本高可能在簡單錯誤上反復打轉temperature0 - 0.7輸出穩定但容易重復相同錯誤探索更多但可能引入隨機錯誤max_tokens512 - 4096代碼較長時容易被截斷輸出更完整但可能生成多余內容sandbox_timeout5 - 30 秒快速失敗但誤殺復雜計算減少誤殺但死循環會拖慢評測在實際調優中不要一開始就追求高重試次數。先把max_attempts設為 1看模型在不自糾時的基線水平再逐步增加到 3 和 5觀察通過率提升和成本增長曲線。如果 3 次到 5 次的通過率提升很小說明繼續增加重試的意義不大。5.2 測試用例生成策略測試用例來源有三種人工編寫質量最高但覆蓋不全成本高。從題目約束自動生成用枚舉、隨機、邊界值生成覆蓋性好。讓另一個 LLM 生成速度快但可能出現錯誤斷言。更推薦先人工寫題目和核心邊界再用腳本補充隨機測試。模型生成的測試用例可以作為補充但必須經過人工審查。絕不能把 LLM 生成的測試直接當成 ground truth否則可能出現“錯誤測試認定正確代碼”的情況。5.3 反饋信息的長度控制多輪重試時上下文會越來越長。如果每次都把完整 traceback 塞給模型幾輪之后 prompt 會膨脹模型容易丟失最早的任務描述。推薦做法只保留最后一次異常的最后 1000 到 2000 字符。把重復出現的相同錯誤去重避免模型反復看同一個 traceback。在反饋中明確告訴模型當前是第幾次嘗試避免它生成“這是第一次”的回答。如果上下文仍然過長可以把歷史反饋壓縮成“之前嘗試過的修改摘要”。5.4 沙箱安全與資源限制模型生成的代碼不可信。學習環境里用subprocess和超時只是為了快速驗證思路生產環境必須做更強的隔離。生產環境至少做到使用 Docker 容器運行模型代碼限制 CPU、內存和網絡。設置timeout和內存上限避免死循環和內存耗盡。模型代碼沒有網絡訪問權限除非任務明確需要。所有執行結果先落盤再決定是否返回給模型。不要用宿主機的高權限賬號運行任意生成代碼。注意如果你的 harness 會執行模型生成的代碼安全性是第一優先級。寧可犧牲一點執行速度也不要讓不可信代碼直接接觸宿主機。6. 常見問題與排錯路徑6.1 模型輸出不是合法代碼現象run_tests報錯 NameError 或者無法解析??赡茉蚰P蜎]有按“只輸出代碼”的要求返回。模型把代碼放在 Markdown 代碼塊中但extract_code沒匹配到。模型返回了 JSON 包裝的字符串。檢查方式打印raw_output確認模型實際返回內容。處理建議增強解析函數。支持去掉python標記如果模型返回 JSON先嘗試解析code字段如果仍然失敗可以讓模型輸出固定格式例如BEGIN_CODE ... END_CODE6.2 同一個錯誤反復重試現象max_attempts用完但每次錯誤相同??赡茉蚍答佇畔⒈唤財嗟酵耆珱]有錯誤細節。temperature0導致模型每次都輸出相同結果。模型沒有真正“看到”反饋因為消息順序或角色設置錯誤。檢查方式查看attempts中每一輪返回給模型的stderr。處理建議把temperature提高到 0.2 到 0.4確認反饋中保留最后一行錯誤類型和斷言信息如果錯誤信息過長只保留后半段。6.3 公開測試通過但隱藏測試失敗現象harness 輸出solved但人工復測時發現代碼不正確。可能原因測試用例太少模型恰好通過了所有用例。模型學會了針對測試樣例硬編碼。測試用例只有正常輸入沒有邊界。檢查方式把模型生成的final_code放到更大的隱藏測試集上執行。處理建議評測集必須分離公開樣例和隱藏測試。最終指標以隱藏測試為準一次評測同時加入邊界、隨機、性能三類用例。6.4 API 調用超時或限流現象批量評估時大量請求報錯。可能原因并發過高觸發 API 限流。部分模型響應慢超過客戶端默認超時。網絡抖動。檢查方式查看client.chat.completions.create拋出的異常類型和錯誤碼。處理建議加入指數退避重試降低并發數為每次調用設置合理 timeout對相同請求做緩存避免重復調用。6.5 沙箱卡死與資源耗盡現象單個任務執行時間特別長甚至整機變卡??赡茉蚰P蜕伤姥h代碼。代碼創建超大列表或遞歸無終止。subprocess的timeout沒有覆蓋到子進程內部再創建的子進程。檢查方式檢查 sandbox 日志確認是否出現TimeoutExpired。處理建議在subprocess.run中設置嚴格 timeout生產環境用 Docker 的--memory和--pids-limit限制資源不要相信模型生成的代碼天然安全。排錯路徑可以按這個順序走先檢查輸入任務文件、測試數據、配置格式。再檢查解析模型輸出是否正確提取。再檢查執行沙箱能否運行最簡單的腳本。再檢查反饋模型是否收到了完整報錯。再檢查限制超時、token、并發是否導致假失敗。最后檢查評測集測試用例本身是否可靠。7. 生產環境 Harness 的最佳實踐與擴展方向7.1 從評測腳本走向在線編碼 Agent最小 harness 是評測工具但它的核心結構可以直接擴展成生產級的編碼 Agent。區別在于生產系統需要更多工程能力支持多文件倉庫模型可以讀取目錄、打開文件、修改文件。支持工具協議模型能調用格式檢查、靜態分析、測試運行、git 操作。支持持久記憶保存模型已經嘗試過的方案避免重復犯錯。支持人工介入在自動修復多次失敗后把任務轉給工程師處理。支持版本回滾模型對代碼庫的所有修改都記錄 diff異常時可以回滾。這些能力本質上都是“在模型外面加 harness”。模型還是那個模型但外部系統越完善它能完成的任務越復雜。7.2 評測前檢查清單把下面這份清單當作可復用模板每次開始新的評測前過一遍測試用例是否包含隱藏用例而不是只給模型公開樣例。所有模型是否使用完全相同的max_attempts、溫度、超時和系統提示詞。反饋信息是否保留異常類型和關鍵斷言而不是只返回“失敗”。錯誤信息是否做了長度截斷防止上下文膨脹。沙箱是否設置了超時、內存和 CPU 限制。是否記錄每輪 attempt 的原始輸出、最終代碼和錯誤日志。是否固定依賴版本和模型版本保證結果可復現。是否使用passk多次采樣而不是只跑一次。是否區分“通過公開測試”和“通過隱藏測試”兩個指標。是否把隨機種子、并發數、API 端點寫入實驗記錄。這十項做完你的評測結果才有橫向對比價值。7.3 擴展方向MCP、RAG 與更豐富的工具層再往前走harness 可以連接 MCP 協議、向量檢索、內部文檔庫和外部 API。模型在編碼時不再只依靠訓練記憶而是能實時獲取依賴文檔、歷史代碼、團隊規范和安全策略。例如harness 里增加一個search_code工具模型在寫某個函數前先搜索項目里已有的相似實現再生成代碼。另一個read_docs工具讓模型在不確定某個 SDK 參數時先查官方文檔。這些能力都會影響編碼結果而它們仍然屬于“模型之外的系統”。學習建議是先把這個最小 harness 跑通再逐步加入一個工具、一個記憶模塊觀察每次改動對多個模型的影響。你會慢慢理解為什么“只改 harness”能提升 15 個模型——因為 harness 改變的不是參數而是模型與外部世界互動的方式。這種工程能力比單純追新模型版本更可控也更值得長期投入。