化:Meta-Harness閉環(huán)實(shí)現(xiàn)自動(dòng)糾偏)
前一段時(shí)間在調(diào)一個(gè)“多步驟自主任務(wù)”的系統(tǒng)時(shí)遇到了一個(gè)特別典型的困境提示詞本身看起來沒問題工具調(diào)用鏈也拆得足夠細(xì)可一旦讓 Agent 自主跑完整個(gè)長(zhǎng)周期流程最后的結(jié)果仍然會(huì)在中途某個(gè)環(huán)節(jié)悄悄偏掉。單獨(dú)看每一步都對(duì)連起來卻經(jīng)常返工而且每次失敗的原因都不同。后來把注意力從“模型指令”上挪開轉(zhuǎn)向設(shè)計(jì)層的優(yōu)化方式整個(gè)問題才逐漸清晰起來。這篇文章會(huì)圍繞 Long-Horizon Agentic Design 的工程實(shí)現(xiàn)展開講解如何用 Meta-Harness 的思路去系統(tǒng)化地優(yōu)化長(zhǎng)周期 Agent 任務(wù)編排并給出一個(gè)可運(yùn)行的閉環(huán)優(yōu)化案例。適合閱讀本文的讀者包括正在做 Agent 工作流編排的算法工程師、想給 LLM 應(yīng)用引入自評(píng)價(jià)與回滾機(jī)制的開發(fā)者以及研究 Agent 系統(tǒng)評(píng)測(cè)與自動(dòng)優(yōu)化的同學(xué)。讀完你會(huì)理解 Agentic Design 的復(fù)雜度來源掌握 Harness 層與 Meta 層的分工并能動(dòng)手實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的“采樣—評(píng)估—修正”優(yōu)化閉環(huán)。1. 背景為什么“長(zhǎng)周期 Agent”這么難設(shè)計(jì)1.1 先理解 Long-Horizon 任務(wù)的問題本質(zhì)我們平時(shí)調(diào)用一次模型接口通常只需要一輪問題與回答模型直接輸出一個(gè)答案即可。但在很多真實(shí)業(yè)務(wù)里任務(wù)并不是“問一句就結(jié)束”而是需要多個(gè)工具、多次推理、多次結(jié)果確認(rèn)才能完成整個(gè)流程。比如讓 Agent 從一份線上配置中心拉取規(guī)則再根據(jù)規(guī)則去數(shù)據(jù)庫(kù)查詢多個(gè)維度的指標(biāo)最后生成一段修復(fù)建議。讓 Agent 自主完成測(cè)試代碼生成、本地執(zhí)行、失敗日志分析、再修復(fù)、再回歸的完整循環(huán)。讓 Agent 從幾十份文檔中提取數(shù)據(jù)再按統(tǒng)一模板生成結(jié)構(gòu)化報(bào)表并完成校驗(yàn)。這類任務(wù)就是 Long-Horizon Task。它的持續(xù)時(shí)間長(zhǎng)、中間步驟多、狀態(tài)空間大而且每一輪的輸出都會(huì)影響后續(xù)步驟的輸入。一個(gè)形象的比喻是寫一句帶 Prompt 的對(duì)話像是打一桿臺(tái)球目標(biāo)明確、距離短而讓 Agent 跑通一個(gè)長(zhǎng)周期任務(wù)則像布置一條自動(dòng)化流水線任何一環(huán)的設(shè)計(jì)不合理都會(huì)在后面的環(huán)節(jié)放大成不可控的問題。1.2 Agentic Design 不是一個(gè)“寫提示詞”的問題很多同學(xué)第一次接觸 Agentic Design 時(shí)會(huì)下意識(shí)把它等價(jià)成“如何寫出一個(gè)好 Prompt”。這種理解不能算錯(cuò)但遠(yuǎn)遠(yuǎn)不夠完整。真正落地的 Agent 系統(tǒng)里設(shè)計(jì)對(duì)象包含至少四塊系統(tǒng)提示詞給模型定義角色、目標(biāo)、約束的輸出文本。工具接口定義模型能看到哪些工具、工具參數(shù)如何描述、哪些信息不能暴露。任務(wù)編排邏輯模型在什么條件下調(diào)用工具、什么條件下停止、什么條件下進(jìn)行反思。結(jié)果評(píng)估機(jī)制如何判斷當(dāng)前狀態(tài)是成功、失敗、還是需要繼續(xù)做。這四塊合在一起才是 Agent 的“行為空間”。AutoDesign 這種思路本質(zhì)上就是把 Agentic Design 視作一個(gè)可以被優(yōu)化的連續(xù)過程——它不滿足于“人工寫一版提示詞”而是希望能在多次任務(wù)執(zhí)行過程中自動(dòng)發(fā)現(xiàn)更優(yōu)的行為編排方案。1.3 Agent、Harness、Meta 三層各自的角色初次看到 “Meta-Harness Optimization” 這個(gè)詞很容易被術(shù)語(yǔ)嚇住。我們把英文直接拆開看Harness 在工程領(lǐng)域通常指“裝配、編排、約束裝置”放在 Agent 語(yǔ)境下可以理解為一套用來控制 Agent 運(yùn)行方式的支架Meta 表示“關(guān)于自身”的層面。所以 Meta-Harness Optimization 的含義是不直接去調(diào)整大模型內(nèi)部的權(quán)重而是在運(yùn)行層之上再去設(shè)計(jì)一套機(jī)制用于持續(xù)優(yōu)化 Agent 任務(wù)背后的控制策略。為了方便理解可以畫下面這個(gè)粗糙的分層表層級(jí)解決問題典型可控對(duì)象模型層單次輸入能生成多好的文本預(yù)訓(xùn)練權(quán)重、微調(diào)數(shù)據(jù)、推理參數(shù)Harness 層多個(gè)步驟之間能否穩(wěn)定完成編排提示詞模板、工具 Schema、狀態(tài)回調(diào)邏輯、斷點(diǎn)機(jī)制Meta 層如何根據(jù)歷史效果反推并修改 Harness 層配置自動(dòng)評(píng)估器、候選生成器、策略更新邏輯核心結(jié)論是如果你想讓長(zhǎng)周期 Agent 在無人看守的情況下保持穩(wěn)定光在模型層使勁是不夠的真正需要持續(xù)迭代的是 Harness 層而驅(qū)動(dòng)迭代的正是 Meta 層。AutoDesign 研究中提到的 Meta-Harness Optimization就是希望把這一整套流程形式化讓原來靠直覺試錯(cuò)的編排方式變成可采樣、可比較、可自動(dòng)收斂的方法。2. 核心方法剖析Meta-Harness Optimization 的四個(gè)維度2.1 把完整流程拆成可觀測(cè)的“狀態(tài)片段”為什么人工設(shè)計(jì)長(zhǎng)周期任務(wù)這么困難因?yàn)?Long-Horizon 任務(wù)的反饋信號(hào)非常稀疏。很多時(shí)候Agent 在前 30 步做得都很好最后一步才失敗或者前 20 步里面有一個(gè)隱形偏差直到第 40 步才徹底暴露。這種長(zhǎng)鏈路很難定位問題。Harness 設(shè)計(jì)的前提就是讓 Agent 的執(zhí)行過程具備“可觀測(cè)性”。具體做法是在每一步之間都建立一個(gè)結(jié)構(gòu)化的狀態(tài)封裝。比如工具調(diào)用返回后Agent 先不直接繼續(xù)生成而是先進(jìn)入一個(gè)狀態(tài)更新器把當(dāng)前回合的目標(biāo)、執(zhí)行結(jié)果摘要、已有結(jié)論、尚未解決的問題保存成一個(gè)快照。正是這個(gè)快照讓后續(xù)的 Meta 層能夠拿到大量軌跡樣本來做分析。否則拿到的只是零散的日志文本很難進(jìn)行統(tǒng)一化比較。2.2 三種 Harness 可調(diào)參數(shù)形態(tài)Meta 層要優(yōu)化的是 Agent 的執(zhí)行配置下文統(tǒng)一稱這些配置為 Harness 配置。在工程落地時(shí)常見的可調(diào)對(duì)象可以按類型分成三類第一類是離散型選擇參數(shù)。例如 Agent 最大迭代輪數(shù)、工具超時(shí)時(shí)間、完成后是否執(zhí)行總結(jié)、錯(cuò)誤時(shí)是否自動(dòng)重試。這類參數(shù)不連續(xù)適合用網(wǎng)格搜索或離散差分處理。第二類是模板型參數(shù)。例如系統(tǒng)提示詞里的某段任務(wù)分解引導(dǎo)語(yǔ)可能會(huì)存在多個(gè)候選版本。我們無法直接對(duì)自然語(yǔ)言求梯度但可以通過采樣和效果評(píng)估來選出更優(yōu)的候選。第三類是數(shù)值型參數(shù)。例如“當(dāng)工具結(jié)果置信度低于多少時(shí)觸發(fā)人工確認(rèn)”“每一步最多允許失敗幾次”等。這類參數(shù)可以通過隨機(jī)搜索或貝葉斯優(yōu)化來逼近更優(yōu)區(qū)間。Harness 優(yōu)化的目標(biāo)函數(shù)不一定是單一指標(biāo)。對(duì)于不同的業(yè)務(wù)場(chǎng)景可能是完成率、平均輪數(shù)、成本開銷、用戶滿意度等。通常需要把多個(gè)指標(biāo)加權(quán)成一個(gè)回報(bào)函數(shù)作為 meta 層決策的依據(jù)。2.3 Meta-Harness 優(yōu)化的通用閉環(huán)一個(gè)通用性很強(qiáng)的優(yōu)化閉環(huán)可以概括成四步。第一步初始化候選池第二部并行執(zhí)行長(zhǎng)周期任務(wù)采樣并記錄過程軌跡第三步用離線評(píng)估器給結(jié)果打分第四步根據(jù)分?jǐn)?shù)決定下一輪配置候選。以下是這個(gè)閉環(huán)的流程描述準(zhǔn)備一組初始 Harness 配置。每個(gè)配置在多個(gè)測(cè)試任務(wù)上獨(dú)立運(yùn)行得到任務(wù)軌跡。對(duì)軌跡統(tǒng)一執(zhí)行步驟級(jí)和結(jié)果級(jí)評(píng)估。根據(jù)評(píng)估反饋對(duì)配置執(zhí)行參數(shù)修改、模板重組或隨機(jī)變異。進(jìn)入下一輪直到效果收斂或預(yù)算耗盡。2.4 長(zhǎng)周期任務(wù)中最需要避免的問題在實(shí)際跑過幾個(gè)長(zhǎng)周期案例之后會(huì)發(fā)現(xiàn)有幾類問題是長(zhǎng)周期任務(wù)特有的也是設(shè)計(jì)階段必須想清楚的。第一個(gè)很常見的問題是累積偏差。單步執(zhí)行準(zhǔn)確率是 98%連續(xù)十步真的成功率只有 82% 左右如果關(guān)鍵判斷缺乏校驗(yàn)鏈條越長(zhǎng)越容易斷。要解決這個(gè)問題除了提高每步的提示質(zhì)量更重要的是設(shè)計(jì)檢查點(diǎn)。檢查點(diǎn)不是讓人去看日志而是讓 Agent 在執(zhí)行關(guān)鍵動(dòng)作前主動(dòng)核對(duì)上中游結(jié)果的一致性。第二個(gè)問題是上下文污染。任務(wù)進(jìn)行到中期時(shí)上下文里可能堆積大量中間輸出。這些輸出里可能包含相互矛盾的舊假設(shè)模型很容易被干擾。好的設(shè)計(jì)應(yīng)該裁剪歷史避免把垃圾信息一直帶到最后。第三個(gè)問題是獎(jiǎng)勵(lì)信號(hào)模糊。長(zhǎng)周期任務(wù)很難在每個(gè)步驟都獲得高質(zhì)量標(biāo)記如果只拿最終結(jié)果來反饋容易導(dǎo)致優(yōu)化策略只能看見最后一步的問題。因此實(shí)踐中必須引入過程評(píng)估機(jī)制或結(jié)構(gòu)約束把稀疏反饋折算成密反饋。3. 環(huán)境準(zhǔn)備與實(shí)驗(yàn)樣例設(shè)計(jì)3.1 從論文概念轉(zhuǎn)向可實(shí)現(xiàn)的最小系統(tǒng)既然標(biāo)題中有 AutoDesign我們自然會(huì)思考它能否落地成一個(gè)實(shí)際的工程組件。本文接下來的實(shí)戰(zhàn)部分并不打算復(fù)現(xiàn)某個(gè)具體研究團(tuán)隊(duì)的完整系統(tǒng)因?yàn)槟切枰罅克懔蜕a(chǎn)數(shù)據(jù)。這里會(huì)把關(guān)鍵思想提取出來實(shí)現(xiàn)一個(gè)極簡(jiǎn)但是可以充分理解原理的“Meta-Harness 優(yōu)化演示環(huán)境”。這個(gè)演示環(huán)境里我們會(huì)用一個(gè)模擬函數(shù)扮演 LLM工具鏈的長(zhǎng)周期執(zhí)行器。雖然調(diào)用關(guān)系是模擬的但你會(huì)清楚看到配置參數(shù)如何影響軌跡、如何采樣多輪結(jié)果、如何對(duì)軌跡打分、如何根據(jù)歷史反饋生成下一輪改進(jìn)。把這個(gè)框子替換成真實(shí)模型調(diào)用后核心邏輯可以無縫遷移。3.2 運(yùn)行環(huán)境與依賴說明建議使用 Python 3.9 或以上版本直接使用標(biāo)準(zhǔn)庫(kù)加 PyYAML不需要任何重量級(jí)機(jī)器學(xué)習(xí)框架。python -m venv venv source venv/bin/activate pip install pyyaml如果你的環(huán)境中尚未安裝 PyYAML執(zhí)行上面的最后一行即可。也可以采用最簡(jiǎn)模式直接用 JSON 文件保存配置不安裝任何第三方庫(kù)但為了配置可讀性這里統(tǒng)一采用 YAML。3.3 項(xiàng)目目錄設(shè)計(jì)以下目錄結(jié)構(gòu)適合作為工程起點(diǎn)meta_harness_demo/ ├── configs/ │ ├── base_config.yaml │ └── candidate_pool.yaml ├── meta_harness/ │ ├── __init__.py │ ├── executor.py │ ├── evaluator.py │ ├── optimizer.py │ └── utils.py ├── run_experiment.py └── README.md其中有幾個(gè)文件需要特別說明executor.py執(zhí)行一個(gè) Harness 配置在單個(gè)任務(wù)上的完整軌跡。evaluator.py把執(zhí)行軌跡轉(zhuǎn)成量化分?jǐn)?shù)。optimizer.py根據(jù)歷史采樣結(jié)果生成下一輪候選配置。run_experiment.py編排整個(gè)閉環(huán)循環(huán)。4. 完整實(shí)戰(zhàn)一個(gè)最小化的 AutoDesign 閉環(huán)4.1 用配置定義 Harness 的可調(diào)區(qū)間先創(chuàng)建基礎(chǔ)配置。這個(gè)文件描述的是一個(gè)長(zhǎng)周期邏輯任務(wù)的基礎(chǔ)狀態(tài)包括執(zhí)行路徑、超時(shí)輪次、反思開關(guān)、隨機(jī)種子范圍。# 文件路徑configs/base_config.yaml harness: max_steps: 12 timeout_seconds: 8 enable_reflection: true context_trim_threshold: 4000 tool_call_retry: 2 optimization: population_size: 6 num_rounds: 3 replicate_per_config: 2 evaluation: success_weight: 1.0 step_penalty: 0.1 consistency_weight: 0.5下面解釋一下這些配置項(xiàng)的含義max_steps單個(gè)任務(wù)最多允許 Agent 執(zhí)行多少步超過直接判定失敗。enable_reflection是否在每?jī)刹胶笠竽P瓦M(jìn)行一次自我校驗(yàn)。context_trim_threshold上下文超過這個(gè)字符量時(shí)進(jìn)行歷史裁剪。tool_call_retry工具調(diào)用失敗時(shí)允許重試的次數(shù)。population_size每輪并行評(píng)估多少組配置。replicate_per_config同樣的配置跑幾次取平均分用來降低隨機(jī)性。success_weight、step_penalty、consistency_weight評(píng)分函數(shù)里的三項(xiàng)權(quán)重讀者在真實(shí)項(xiàng)目里要根據(jù)業(yè)務(wù)目標(biāo)改動(dòng)。這里要注意評(píng)分權(quán)重本身就是 Harness 空間的一個(gè)維度。如果你希望 Agent 更節(jié)省成本可以把 step_penalty 調(diào)高如果只在意最終成功那么 success_weight 占比可以更大。4.2 執(zhí)行器模擬帶噪聲的長(zhǎng)周期任務(wù)軌跡executor.py 是整個(gè)項(xiàng)目里的核心執(zhí)行模塊。為了避開真實(shí)第三方依賴我們用一組內(nèi)置函數(shù)模擬“任務(wù)步驟”。每個(gè)模擬步驟的代碼邏輯固定但由于引入隨機(jī)噪聲和配置影響同一配置跑多次會(huì)得到不同結(jié)果。# 文件路徑meta_harness/executor.py import random import time from dataclasses import dataclass, field dataclass class StepRecord: step_index: int status: str info: str score: float 0.0 dataclass class Trajectory: config: dict task_id: str steps: list field(default_factorylist) total_reward: float 0.0 success: bool False step_count: int 0這里定義了兩個(gè)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)。StepRecord 記錄單步狀態(tài)Trajectory 則記錄一整個(gè)配置在一次任務(wù)上的執(zhí)行軌跡。下面實(shí)現(xiàn)一個(gè)模擬執(zhí)行核心函數(shù)。# 文件路徑meta_harness/executor.py追加 def _simulate_step(task_id: str, step_index: int, config: dict) - StepRecord: 模擬執(zhí)行一個(gè)任務(wù)步驟。 實(shí)際項(xiàng)目中這一步往往是一次 LLM 調(diào)用可能會(huì)調(diào)用外部工具。 這里用一個(gè)隨機(jī)噪聲模型代替執(zhí)行效果。 max_steps config[harness][max_steps] reflection_on config[harness][enable_reflection] retry_times config[harness][tool_call_retry] # 隨著步數(shù)增加任務(wù)難度逐漸上升 difficulty (step_index 1) / max_steps base_success_prob 0.93 - difficulty * 0.12 # 開啟反思會(huì)增加微小的時(shí)間開銷但能提升步驟成功率 if reflection_on: base_success_prob 0.03 # 隨機(jī)噪聲 p random.random() if p base_success_prob: if p 0.96 and retry_times 1: return StepRecord( step_indexstep_index, statusretry, info首次失敗觸發(fā)重試機(jī)制, score0.4, ) return StepRecord( step_indexstep_index, statusfailed, info步驟執(zhí)行失敗, score0.0, ) # 模擬一部分中間狀態(tài)不一致的情況 consistency_penalty 0.0 if random.random() 0.08: consistency_penalty 0.2 return StepRecord( step_indexstep_index, statussuccess, info步驟執(zhí)行成功, score1.0 - consistency_penalty, )這段模擬函數(shù)雖然很簡(jiǎn)單但它真實(shí)反映了長(zhǎng)周期任務(wù)的幾個(gè)典型特點(diǎn)越往后越難也就是 difficulty 逐漸上升。失敗可能觸發(fā)重試但與直接失敗相比有代價(jià)。成功不是二元狀態(tài)可能包含中間一致性損耗。接下來實(shí)現(xiàn) execute_trajectory 函數(shù)# 文件路徑meta_harness/executor.py追加 def execute_trajectory(config: dict, task_id: str, seed: int 0) - Trajectory: 執(zhí)行一次完整的長(zhǎng)周期軌跡。 random.seed(seed) max_steps config[harness][max_steps] timeout config[harness][timeout_seconds] trajectory Trajectory(configconfig, task_idtask_id) reflection_on config[harness][enable_reflection] start_time time.time() for step_idx in range(1, max_steps 1): # 模擬每次調(diào)用的耗時(shí) time.sleep(0.005) elapsed time.time() - start_time if elapsed timeout: trajectory.steps.append( StepRecord(step_indexstep_idx, statustimeout, info步驟超時(shí)) ) break record _simulate_step(task_id, step_idx, config) trajectory.steps.append(record) # 反思機(jī)制會(huì)額外產(chǎn)生一步校驗(yàn)這里用狀態(tài)標(biāo)記體現(xiàn) if reflection_on and step_idx % 2 0 and record.status ! failed: trajectory.steps.append( StepRecord( step_indexstep_idx 100, statusreflection, infoAgent 進(jìn)行自我校驗(yàn), score0.15 if random.random() 0.85 else 0.0, ) ) if record.status success: trajectory.success True elif record.status failed: trajectory.success False break trajectory.step_count len(trajectory.steps) return trajectory這個(gè)函數(shù)有幾個(gè)細(xì)節(jié)值得展開講。timeout 是模擬網(wǎng)絡(luò)調(diào)用超時(shí)在實(shí)際系統(tǒng)中經(jīng)常被忽略但一旦任務(wù)鏈變長(zhǎng)單步超時(shí)就會(huì)導(dǎo)致整體失敗。反思機(jī)制被表示成每隔兩步插入一條 reflection 記錄這些記錄也會(huì)被算入總分中開啟后會(huì)讓軌跡步驟變長(zhǎng)但可能帶來更高的成功概率。4.3 評(píng)估器把軌跡轉(zhuǎn)換為可比較得分executor 只產(chǎn)生原始軌跡真正驅(qū)動(dòng)優(yōu)化的是評(píng)估器。評(píng)分規(guī)則設(shè)計(jì)如下成功結(jié)果給予 success_weight 對(duì)應(yīng)的正向得分。每執(zhí)行一步扣除 step_penalty體現(xiàn)成本與延遲損失。軌跡中出現(xiàn) retry 扣分failed 或 timeout 則直接判負(fù)并記錄失敗原因。reflection 記錄若被判定為校驗(yàn)失敗則計(jì)入一致性損失。把評(píng)估邏輯封裝成函數(shù)# 文件路徑meta_harness/evaluator.py from meta_harness.executor import Trajectory def evaluate_trajectory(weight_config: dict, trajectory: Trajectory) - dict: 對(duì)一條軌跡進(jìn)行量化評(píng)分。 success_weight weight_config[evaluation][success_weight] step_penalty weight_config[evaluation][step_penalty] consistency_weight weight_config[evaluation][consistency_weight] final_score 0.0 success trajectory.success consistency_loss 0.0 if success: final_score success_weight for step in trajectory.steps: final_score - step_penalty if step.status retry: final_score - 0.2 elif step.status timeout: final_score - 0.5 elif step.status reflection: final_score 0.02 * step.score if step.score 0.5: consistency_loss consistency_weight * 0.1 elif step.status success: final_score 0.05 * step.score final_score - consistency_loss return { task_id: trajectory.task_id, success: success, step_count: trajectory.step_count, score: round(final_score, 4), success_weight_used: success, }很多剛做 Agent 評(píng)估的同學(xué)會(huì)習(xí)慣只用 success 字段做 0/1 判斷這是不夠的。Long-Horizon 任務(wù)里一個(gè)任務(wù)跑了 8 步成功和一個(gè)任務(wù)跑了 30 步但最終成功用戶體驗(yàn)差異巨大前者顯著更穩(wěn)、成本更低。所以評(píng)估一定要納入步驟成本。真實(shí)系統(tǒng)如果要更細(xì)還建議記錄 token 消耗、工具調(diào)用成功率、平均單步延遲。為了避免單次隨機(jī)性影響判斷實(shí)現(xiàn)一個(gè)批量評(píng)估函數(shù)# 文件路徑meta_harness/evaluator.py追加 def evaluate_config_with_replicates( weight_config: dict, trajectory_list: list, ) - dict: 對(duì)某個(gè)配置多次執(zhí)行結(jié)果做聚合平均。 total_score 0.0 success_count 0 total_steps 0 for traj in trajectory_list: result evaluate_trajectory(weight_config, traj) total_score result[score] total_steps result[step_count] if result[success]: success_count 1 n len(trajectory_list) return { avg_score: round(total_score / n, 4), success_rate: round(success_count / n, 4), avg_step_count: round(total_steps / n, 2), trajectory_count: n, }4.4 優(yōu)化器實(shí)現(xiàn)最簡(jiǎn)單的變異—選擇策略Meta-Harness Optimization 的算法不唯一。本文演示最簡(jiǎn)單且有效的離散優(yōu)化方式隨機(jī)變異 精英保留。這種策略在配置搜索空間不大、單輪采樣成本較高時(shí)非常實(shí)用。# 文件路徑meta_harness/optimizer.py import random def mutate_config(config: dict, mutation_rate: float 0.3) - dict: 對(duì)配置進(jìn)行隨機(jī)變異產(chǎn)生新候選。 new_config { harness: dict(config[harness]), optimization: dict(config[optimization]), evaluation: dict(config[evaluation]), } if random.random() mutation_rate: new_config[harness][max_steps] max(5, new_config[harness][max_steps] random.choice([-2, -1, 1, 2])) if random.random() mutation_rate: new_config[harness][enable_reflection] not new_config[harness][enable_reflection] if random.random() mutation_rate: new_config[harness][tool_call_retry] max(0, new_config[harness][tool_call_retry] random.choice([-1, 1])) if random.random() mutation_rate: new_config[harness][timeout_seconds] max( 1, new_config[harness][timeout_seconds] random.choice([-2, -1, 1, 2]) ) return new_config def select_top_configs(evaluated_pool: list, top_n: int 3) - list: 按平均分排序并返回排名靠前的配置。 sorted_pool sorted(evaluated_pool, keylambda x: x[avg_score], reverseTrue) return sorted_pool[:top_n]可以看到這其實(shí)就是一條經(jīng)典的優(yōu)化鏈路評(píng)估完所有候選后把得分最高的幾組配置保留下來再通過變異生成新一組候選進(jìn)入下一輪。這種方法不會(huì)保證達(dá)到全局最優(yōu)但工程上可解釋性強(qiáng)且實(shí)現(xiàn)簡(jiǎn)單。如果你希望進(jìn)一步增強(qiáng)優(yōu)化能力可以引入交叉操作把兩個(gè)精英配置的部分字段交換。比如將“開啟反思”的字段從配置 A 遷移到配置 B形成更符合預(yù)期的下一代候選。這和進(jìn)化算法的思路很接近。4.5 跑通完整實(shí)驗(yàn)閉環(huán)現(xiàn)在實(shí)現(xiàn) run_experiment.py 來串聯(lián)整個(gè)流程。# 文件路徑run_experiment.py import copy import random from collections import defaultdict import yaml from meta_harness.executor import execute_trajectory from meta_harness.evaluator import evaluate_config_with_replicates from meta_harness.optimizer import mutate_config, select_top_configs def load_config(path: str) - dict: with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def build_initial_pool(base_config: dict, population_size: int) - list: 以基礎(chǔ)配置為中心創(chuàng)建少量變異候選。 pool [base_config] while len(pool) population_size: candidate mutate_config(copy.deepcopy(base_config), mutation_rate0.6) if candidate not in pool: pool.append(candidate) return pool def run_one_round(base_config: dict, config_pool: list, round_index: int): 執(zhí)行一輪評(píng)估。 replicate base_config[optimization][replicate_per_config] seed_base round_index * 100 # 分組評(píng)估 group_results [] for idx, cfg in enumerate(config_pool): traj_list [] for rep in range(replicate): seed seed_base idx * 10 rep traj execute_trajectory(cfg, task_idftask_{idx}_{rep}, seedseed) traj_list.append(traj) agg evaluate_config_with_replicates(base_config, traj_list) group_results.append({**agg, config: cfg}) group_results.sort(keylambda x: x[avg_score], reverseTrue) return group_results下面加一段打印結(jié)果邏輯并執(zhí)行def main(): base_config load_config(configs/base_config.yaml) pool_size base_config[optimization][population_size] num_rounds base_config[optimization][num_rounds] config_pool build_initial_pool(base_config, pool_size) for round_idx in range(num_rounds): print(f Round {round_idx 1} ) round_results run_one_round(base_config, config_pool, round_idx) for i, item in enumerate(round_results): config_snapshot { max_steps: item[config][harness][max_steps], enable_reflection: item[config][harness][enable_reflection], tool_call_retry: item[config][harness][tool_call_retry], } print( fRank {i 1} | avg_score{item[avg_score]} | fsuccess_rate{item[success_rate]} | favg_steps{item[avg_step_count]} | fconfig{config_snapshot} ) top_configs select_top_configs(round_results, top_n3) new_pool [] for top_cfg in top_configs: top_value top_cfg[config] new_pool.append(top_value) new_pool.append(mutate_config(copy.deepcopy(top_value))) new_pool.append(mutate_config(copy.deepcopy(top_value), mutation_rate0.8)) config_pool new_pool[:pool_size] print() if __name__ __main__: main()啟動(dòng)實(shí)驗(yàn)python run_experiment.py由于隨機(jī)種子是固定的每次完整運(yùn)行的結(jié)果會(huì)保持一致便于學(xué)習(xí)者對(duì)照。但這個(gè)實(shí)驗(yàn)的核心目的不在于唯一次數(shù)跑出多高分而在于觀察不同配置在不同輪次中的變化趨勢(shì)開啟反思的配置是不是更容易在更少步驟內(nèi)達(dá)到穩(wěn)定重試次數(shù)多的配置是否拉高了耗時(shí)正常情況下我們會(huì)看到第一輪中配置之間差異很大經(jīng)過幾輪篩選后avg_score 會(huì)緩慢上升。如果某組配置的 success_rate 上升但 avg_step_count 也上升就需要重新審視 step_penalty 的權(quán)重是否合理。5. Meta 層設(shè)計(jì)容易被忽略的關(guān)鍵細(xì)節(jié)5.1 評(píng)測(cè)集不能只覆蓋成功路徑做工程優(yōu)化和做研究實(shí)驗(yàn)最大的不同在于研究可以只挑少量高質(zhì)量測(cè)試集但工程上線要面對(duì)的是大量真實(shí)任務(wù)分布。很多 Agent 優(yōu)化剛開始都很美好換了一批任務(wù)就崩潰。原因在于評(píng)測(cè)樣本單一。建議在實(shí)驗(yàn)階段把評(píng)測(cè)任務(wù)分成至少三類簡(jiǎn)單短期任務(wù)時(shí)長(zhǎng) 3 至 5 步用來驗(yàn)證基礎(chǔ)流程是否正常。中等復(fù)雜任務(wù)時(shí)長(zhǎng) 8 至 15 步用來調(diào)節(jié)反思頻率和上下文管理策略。困難長(zhǎng)周期任務(wù)時(shí)長(zhǎng) 20 步以上用來暴露累積偏差、上下文污染等核心問題。如果全部用簡(jiǎn)單任務(wù)做優(yōu)化Meta 層很容易學(xué)到“直接關(guān)閉反思、增加重試次數(shù)”這種過度自信的策略但這種策略一旦遷移到困難任務(wù)就會(huì)變成災(zāi)難。5.2 過程軌跡比結(jié)果日志更重要傳統(tǒng)監(jiān)控手段通常只打印每步日志比如“步驟 3 調(diào)用了 search 工具”“步驟 4 返回了結(jié)果”。這樣對(duì)我們發(fā)現(xiàn)問題用處不大。要想驅(qū)動(dòng) Meta-Harness 優(yōu)化至少要存儲(chǔ)每步執(zhí)行時(shí)的結(jié)構(gòu)化狀態(tài)包括當(dāng)前步驟的目標(biāo)。當(dāng)前步驟是否偏離主任務(wù)。關(guān)鍵中間結(jié)果的摘要。工具調(diào)用時(shí)的完整入?yún)⑴c出參。模型在步驟間的反思內(nèi)容。這些軌跡數(shù)據(jù)是后續(xù)分析的長(zhǎng)周期反饋信號(hào)。我們可以在沒有人工標(biāo)注的情況下通過規(guī)則自動(dòng)計(jì)算相似度或一致性發(fā)現(xiàn)哪些配置容易出現(xiàn)“重復(fù)調(diào)用同一個(gè)工具”“輸出自相矛盾”“忘記最初指令”等問題。5.3 不要為了對(duì)齊自動(dòng)評(píng)估而犧牲真實(shí)目標(biāo)設(shè)計(jì)評(píng)估函數(shù)時(shí)最怕出現(xiàn)“評(píng)估器與業(yè)務(wù)目標(biāo)不一致”的情況。假如你給 Agent 的核心目標(biāo)設(shè)定為“獲取準(zhǔn)確數(shù)據(jù)并按模板生成報(bào)告”但評(píng)估函數(shù)主要獎(jiǎng)勵(lì)“快速收斂到成功狀態(tài)”和“減少中斷”就可能導(dǎo)致 Agent 學(xué)到取巧的路徑遇到數(shù)據(jù)缺失就自己編一條合理值而不是觸發(fā)人工確認(rèn)。現(xiàn)實(shí)世界中這一點(diǎn)尤其重要。長(zhǎng)周期任務(wù)成功率的定義要盡量貼近業(yè)務(wù)結(jié)果而不是讓評(píng)測(cè)函數(shù)變成游戲規(guī)則的設(shè)計(jì)漏洞。想要安全可以加入一致性校驗(yàn)邏輯把“自動(dòng)補(bǔ)全的結(jié)果必須由評(píng)審節(jié)點(diǎn)確認(rèn)”作為一個(gè)強(qiáng)約束寫入 Harness。6. 常見問題與排查思路問題現(xiàn)象常見原因解決思路放開反思后回合數(shù)大幅上升反思觸發(fā)過于頻繁模型陷入形式化自檢僅在高風(fēng)險(xiǎn)步驟后觸發(fā)或采用按步驟間隔觸發(fā)提高最大步數(shù)后成功率不升反降A(chǔ)gent 在后續(xù)步驟中遇到上下文污染或幻覺啟用裁剪機(jī)制定期壓縮中間日志摘要重試次數(shù)高但任務(wù)仍失敗重試只是重復(fù)同一錯(cuò)誤沒有變更方法對(duì)比兩次執(zhí)行差異要求 Agent 在重試前輸出原因分析評(píng)測(cè)分?jǐn)?shù)穩(wěn)定但線上效果差測(cè)試任務(wù)與真實(shí)分布不一致擴(kuò)充多樣測(cè)試集加入線上采樣任務(wù)自動(dòng)評(píng)估器給出錯(cuò)誤反饋規(guī)則評(píng)估器對(duì)語(yǔ)義理解不足引入大模型裁判或混合評(píng)估模式關(guān)鍵步驟人工抽檢針對(duì)第一類問題如果想精細(xì)調(diào)整可以在反思步驟的提示詞中增加約束“僅當(dāng)存在不確定結(jié)論、潛在沖突或高風(fēng)險(xiǎn)決策時(shí)進(jìn)行反思”這比簡(jiǎn)單設(shè)置開關(guān)更有效。第二類問題在 Long-Horizon 場(chǎng)景里極為高頻。上下文裁剪的實(shí)現(xiàn)可以在每次步驟結(jié)束后把舊日志壓縮成一條摘要記錄只保留最近三到五條原始日志。這樣既能保留信息又不會(huì)讓模型注意力被垃圾字段稀釋。7. 工程落地的建議與風(fēng)險(xiǎn)清單7.1 設(shè)計(jì)上先做輕量級(jí) Harness再做 Meta 層很多團(tuán)隊(duì)在第 1 天就想搭建極其復(fù)雜的自動(dòng)優(yōu)化平臺(tái)這是個(gè)典型誤區(qū)。Meta-Harness Optimization 真正運(yùn)轉(zhuǎn)的前提是 Harness 本身已經(jīng)具備穩(wěn)定的執(zhí)行、日志和可回滾能力。如果當(dāng)前任務(wù)在固定配置下本身就經(jīng)常失敗盲目引入自動(dòng)優(yōu)化只會(huì)放大噪聲甚至讓配置搜索往錯(cuò)誤方向收斂。建議按以下步驟進(jìn)行落地先手工固定一套較優(yōu)配置跑通至少 100 條真實(shí)任務(wù)軌跡。分析失敗任務(wù)軌跡檢查是否存在重復(fù)失敗原因。將修復(fù)經(jīng)驗(yàn)沉淀為規(guī)則校驗(yàn)節(jié)點(diǎn)或提示詞約束。之后再引入配置池與自動(dòng)評(píng)估器。上線自動(dòng)優(yōu)化時(shí)先用影子模式并行比對(duì)推薦配置與當(dāng)前線上的表現(xiàn)。7.2 配置版本管理必須納入代碼倉(cāng)庫(kù)Harness 配置在優(yōu)化過程中可能每輪都會(huì)變化。如果像改普通業(yè)務(wù)配置一樣直接修改運(yùn)行參數(shù)很容易失去審計(jì)能力。推薦把所有候選配置統(tǒng)一存儲(chǔ)在 Git 倉(cāng)庫(kù)或配置中心中候選名遵循清晰的命名規(guī)范例如 reflective_v3_low_penalty方便回滾。Autodesign 的精神在于“自動(dòng)發(fā)現(xiàn)更好的 Harness”但這并不意味著可以繞過工程標(biāo)準(zhǔn)。任何自動(dòng)生成的候選都應(yīng)該經(jīng)過變更評(píng)審流程至少要在測(cè)試環(huán)境跑通回歸樣本。7.3 給每個(gè)軌跡增加可復(fù)現(xiàn)標(biāo)識(shí)長(zhǎng)周期任務(wù)具有不小的隨機(jī)性因此排查問題時(shí)需要精確定位到底是在哪一次執(zhí)行中出了問題。建議每一次 Trajectory 都保存以下元信息配置版本號(hào)。模型版本號(hào)。隨機(jī)種子。時(shí)間戳。工具調(diào)用的實(shí)際入?yún)⒄?。?dāng)前環(huán)境變量標(biāo)簽。當(dāng)后續(xù)發(fā)現(xiàn)線上效果出現(xiàn)抖動(dòng)時(shí)這組元信息能幫助快速鎖定問題源頭是來自配置變化還是模型版本變化。7.4 安全邊界與人工兜底自動(dòng)化優(yōu)化經(jīng)常在困境中得出一些看起來聰明的配置。例如為了降低失敗率Agent 可能會(huì)把工具異常吞掉、只報(bào)成功也可能為了讓用戶滿意而編造不存在的數(shù)據(jù)。這種問題不能完全依靠評(píng)測(cè)函數(shù)去預(yù)防。一個(gè)務(wù)實(shí)的做法是為所有 Agent 工具調(diào)用加入“結(jié)果可回滾”和“高危操作二次確認(rèn)”護(hù)欄。凡涉及數(shù)據(jù)庫(kù)刪除、外部接口寫入、線上配置變更等敏感操作強(qiáng)制要求經(jīng)過獨(dú)立評(píng)審鏈或人工確認(rèn)。Harness 優(yōu)化過程同樣不得繞過這條安全邊界。8. 從演示到生產(chǎn)你還差哪幾步如果你希望把這個(gè)最小演示遷移到真實(shí)的 LLM Agent 環(huán)境中可以按下面的順序替換模塊。首先把 execute_trajectory 中模擬單步執(zhí)行的函數(shù)替換成真實(shí)的模型調(diào)用邏輯保持與外部工具的交互方式不變?nèi)缓蟀衍壽E記錄中增加模型輸入輸出的 token 消耗最后把評(píng)估函數(shù)從規(guī)則計(jì)算改為“規(guī)則計(jì)算 大模型裁判加權(quán)”的混合評(píng)估。在此之上還可以從一次性采樣升級(jí)為流式采樣也就是不等待本輪所有配置全部跑完而是實(shí)時(shí)評(píng)估已完成的軌跡并動(dòng)態(tài)淘汰明顯劣勢(shì)的配置。不過這種策略只適合測(cè)試任務(wù)量大、單條成本較高的場(chǎng)景否則會(huì)引入額外復(fù)雜度。如果你的任務(wù)中存在多種差異很大的業(yè)務(wù)類型建議為每種類型單獨(dú)維護(hù)一套 Harness 配置池與評(píng)估權(quán)重而不是追求單一萬能配置。很多團(tuán)隊(duì)在最開始會(huì)試圖設(shè)計(jì)一套“通用 Agent”結(jié)果在長(zhǎng)周期任務(wù)上發(fā)現(xiàn)不同場(chǎng)景的最優(yōu)節(jié)奏差異巨大強(qiáng)行統(tǒng)一配置后所有任務(wù)的表現(xiàn)都退化成平均水平。本文從設(shè)計(jì)理念到一個(gè)小型閉環(huán)實(shí)現(xiàn)覆蓋了長(zhǎng)周期 Agent 任務(wù)中“配置定義—軌跡執(zhí)行—過程評(píng)估—自動(dòng)優(yōu)化—安全落地”這條完整鏈路。真實(shí)項(xiàng)目里大家不必立刻追求復(fù)雜的強(qiáng)化學(xué)習(xí)或大規(guī)模搜索算法先把手里的 Harness 配置管理好、評(píng)測(cè)指標(biāo)定義好、軌跡可觀測(cè)性做好再逐步引入 Meta 層自動(dòng)優(yōu)化效果會(huì)遠(yuǎn)比空談概念更扎實(shí)。如果想繼續(xù)深入可以進(jìn)一步學(xué)習(xí)過程獎(jiǎng)勵(lì)模型、開放式軌跡搜索、以及基于人工偏好對(duì)齊的評(píng)估函數(shù)設(shè)計(jì)。這些都是 Meta-Harness Optimization 后續(xù)演進(jìn)中非常有價(jià)值的方向。