研究問題 Apodex AI 開源的 FrontierAgent(agent_team harness + AgentOS 概念)在 DGX Spark 上跑本地模型,Apodex-1.1-mini (:8083) 與 Qwen3.8-27B (:8080) 誰能真正交付長流程任務? 失敗模式是什麼、框架哪些機制實測有效?
兩天的 A/B 對照測試(7+ 次執行,同一審計任務:a2a-watch.sh 健壯性審計)。結論先講:唯一在合理 budget 內交付的是 Apodex + agent_team;Qwen 分析深度其實更強,但被 framework 的 runaway detector × 本地模型速度的交互殺了七次。
環境矩陣
| 元件 | 設定 |
|---|---|
| Qwen3.8-27B | llama.cpp :8080,ctx 262144(256K),MTP speculative(draft acceptance ~92%),--parallel 1 |
| Apodex-1.1-mini | llama.cpp :8083 on-demand(apodex-text.service),同 ctx,35B MoE agent-tuned |
| FrontierAgent | ~/ai-labs/frontier-agent/(uv sync,Python 3.12),react / agent_team 兩 mode |
| 沙箱 | bubblewrap — 需要 kernel.apparmor_restrict_unprivileged_userns=0(Ubuntu 24.04 預設禁用 unprivileged userns,fail-closed 設計無 bypass flag;已持久化 /etc/sysctl.d/99-userns.conf) |
| 關鍵 profile keys(tui.yaml) | reasoning_only_timeout_s: 120→600、reasoning_only_max_tokens: 16384→32768(env-overridable)、extra_body.chat_template_kwargs.enable_thinking: true、FRONTIER_AGENT_LLM_MAX_CONCURRENT=1 |
踩坑一:bwrap fail-closed
--no-sandbox不是 bypass — react workflow 明確「refusing unisolated host fallback」。解鎖只有兩條路:sysctl(本機)或 docker compose(ghcr.io/apodexai/frontieragent,但 image gated 拉不到)。
測試矩陣與結果
| Run | Backend / Mode | 修正/變數 | 結果 |
|---|---|---|---|
| A | Apodex react | — | ✗ turn 7 reasoning runaway ×3,誠實回報 incomplete(best-effort 模式實演) |
| B | Qwen react | — | ✗ 40min timeout;context 漲到 184K tokens(KV 10.3GB > 8GB prefix-cache 上限 → 失去 cache 重用 → 每 turn 越來越慢) |
| A′ | Apodex agent_team | — | ✗ timeout kill;單 slot 排隊 → subagent stall → lead 燒 turn 在協調(collect_reports wait_timeout ×2) |
| A″ | Apodex agent_team | + LLM_MAX_CONCURRENT=1 + 增量寫入指示 | ✅ 唯一交付:完整報告(132 lines,evidence+confidence 標注),verifier 給 20/23 並抓出 3 處行號錯誤 + 1 處無根據論述 |
| B′/B″/B‴ | Qwen react ×3 | 範圍約束 / 明確路徑 / 「分析即寫入」紀律 | ✗ 全部死於同一模式:reasoning cascade(turn 4/10/6) |
| B-final v1-v3 | Qwen agent_team ×3 | reseed / ctx cap 30K / handover contract | ✗ subagent context 失控(141K→169K)+ timeout 錯位 |
失敗模式分類學(核心收穫)
1. Reasoning cascade — framework detector × thinking model 行為衝突
Qwen 是 thinking model:深度分析時把大量推理堆在 reasoning channel。Framework 的 runaway guardrail(reasoning_only_timeout_s: 120 / max_tokens: 16384)為雲端/SGLang 端點調校 — 本地 ~15 tok/s 下,健康推理也超過門檻 → 被判 runaway → resample(reduced cap 8192→4096 + 「keep reasoning concise」提醒)→ 模型不聽 meta-instruction → 再觸發 → 空 turn → stopped_by=no_tool 死亡。
實測修正 profile 改
reasoning_only_timeout_s: ${REASONING_ONLY_TIMEOUT_S:-600}、reasoning_only_max_tokens: ${REASONING_ONLY_MAX_TOKENS:-32768}(token cap 是 load-invariant,wall-clock 不是 — 本地信任 token cap)。但壓不住「分析累積在推理」的模型行為 — prompt 紀律(<200 tokens)對 meta-behavior 無效。
2. Context bloat → throughput collapse
Qwen subagent 傾向整檔 dump:141K→169K tokens。後果鏈:
141K prefill(~10min)+ decode(~15-30min/turn)→ 單 slot 串行 →
collect_reports(30min) 永遠等不到 → lead 空轉燒 turn → budget 耗盡
對照:Apodex A″ 的 lead context 只 ~27K — subagent 讀取紀律(定向 grep/sed)才是收斂關鍵,不是模型智商。OPENAI_MAX_INPUT_TOKENS=30000 只 cap 住 coordinator,擋不住 subagent 的 tool results 累積(tiered compaction 觸發點在 max_len 80% ≈ 210K)。
3. Timeout 錯位(最隱蔽)
外部 timeout 5400s (90min) < framework 內部 research_wall_time_s=9000s (2.5hr)
→ 外部先殺 wrapper → framework 的 wall-deadline salvage/force_final_answer 來不及 fire
→ handover contract 永遠沒機會執行
正確配對:RESEARCH_WALL_TIME=3600 REPORT_WALL_TIME=600 + timeout 5400 — 讓內部 deadline 先觸發 salvage,外部 kill 只是保險。
4. Path ambiguity trap
Task prompt 寫 ./reports/ → agent 在「workspace vs /outputs vs cwd」之間燒掉 turn 1 的 499-844 tokens 猶豫(B′ 直接因此死於 turn 4)。永遠給絕對路徑。
實測有效的機制(研究宣稱 vs 實測)
| 機制 | 實測 |
|---|---|
| Verifier 迴路(delivery contract + claim refuter) | ✅ A″ 的 final_verifier 逐條核對行號(60→56、67→68),抓出無根據論述「5分鐘重疊餘裕」要求刪除 — 研究裡的 claim refuter 真的有用 |
| Subagent fresh context | ✅ 結構性避開單 context 膨脹與 reasoning cascade — agent_team 勝 react 的根本原因 |
| Incremental write 紀律 | ✅ A″ subagent 逐 section append;Qwen B‴ 的 log salvage 證明分析品質在、只是沒落盤 |
| Best-effort delivery(軟截止降級) | ✅ Run A 實演:reasoning 崩了 → 誠實回報 incomplete 而非幻覺報告 |
Tiered compaction + spill + recover_result | ⚠️ 機制存在且 subagent tools 含 recover_result,但觸發太晚(210K),救不了 throughput |
Per-turn _persist() → session.json + --resume | ✅ react mode 完整恢復 history+todos;agent_team 是薄壳(history=0)→ 靠 artifacts 重種 |
| Wall-deadline salvage | ⚠️ 存在但被外部 timeout 錯位搶跑(見上) |
「最低 reasoning effort」開關在哪 FrontierAgent 沒有 per-request
reasoning_effort參數。真正的 lever:profileextra_body.chat_template_kwargs.enable_thinking: true→false= Qwen 完全不思考(快但淺,審計類任務是負資產)+reasoning_only_*guardrails(已調校)。
Handover protocol(自建,實測通過)
agent_team 的 session.json 是薄壳 → 接續靠 artifacts。~/ai-labs/frontier-agent/frontier-handover.sh:
collect <run-dir>— 彙整 workspace/spill/trajectories/session.json + candidate deliverablesseed <run-dir> [task]— 產生 reseed prompt(必讀 artifacts + 已知狀態 + 紀律 + handover contract)- Task prompt 加 handover contract:「無法完成時收尾前必須寫
/outputs/handover.md:(1) 已完成+已驗證發現(行號)(2) 未完成清單 (3) 下一步精確動作」
順帶收穫:a2a-watch.sh 審計成果
A″ + Qwen log salvage + 人工驗證,修掉 5 個真實 bug(全部逐行驗證):
- P0
:68health check 無 timeout → client 掛住 = watcher 靜默死亡(持 flock)→timeout 30 - P1
:30flock 無command -vguard → 缺失時靜默雙重處理 - P1 settings.yaml ×3 寫入非原子 → crash = config 損毀 → tempfile + os.replace
- P1 unit 無
Restart=→ crash 後乾等 20min →Restart=on-failure(oneshot 合法,systemd ≥247) - P1-B1(fix_auditor subagent 抓到):timeout 只包 client 不包 downstream parser → grandchild 持 pipe 仍會無限阻塞 → parser 加自己的
timeout 45
結論與路由建議
| 用途 | 建議 |
|---|---|
| agent_team 長流程(審計/研究/多階段交付) | Apodex :8083 — 唯一收斂配置;subagent 讀取紀律是關鍵變數 |
| react 單線、小 scope 任務 | Qwen :8080 可用,但 scope 必須小(≤~15K context)+ 絕對路徑 + 增量寫入 |
| 深度分析品質 | Qwen 原始分析較強(抓到 Apodex 漏的 P0/P1)— 是 framework threshold 殺了它,不是模型不行 |
讓 Qwen agent_team 收斂還差什麼 單 slot :8080 上 subagent context 失控是主因。需要 framework 層級的 per-subagent context 強制(目前只有 coordinator 級 input guard)或
--parallel 2(q4_0 KV 每 slot 只多 ~1.4GB)。在那之前:Qwen 留給小 scope react,重型 agent_team 工作走 Apodex。
Option A pipeline:Qwen 規劃 → Apodex 執行(實測驗證)
框架現況:build_swarm_model_profile 硬編碼 subagent 用 coordinator 同 model(profile.py:495),無原生 per-role model。外部兩階段管線可繞過:
Stage 1: Qwen :8080 react → plan.md(機制圖譜 + 任務分解 + 驗收標準)
Stage 2: Apodex :8083 agent_team → 以 plan 為輸入執行驗證
實測結果(ctx-mechanism audit 任務):
- Qwen planner 極強:125-line plan,機制圖譜完整、4 個語義矛盾預判準確、發現 plan 之外的事實(swap_alert 第三寫入者、雙 timer)。react mode 調校後(
stateful_react_agent/profiles/tui.yaml同樣改 600s/32K — 兩個 profile 都要改,react 用的是另一份)首次收斂(turns=23, tool_calls=28) - Apodex executor 紀律好:T2/T4 完整交付,log 量化證據(10,596+10,223 行),沙箱限制誠實回報,主動推翻 planner 假設(雙 timer 其實只有 enabled 一個 = zombie,無競態)
- 結構性失敗點:
T1/T3 卡於長 LLM call→ 2026-09-02 forensics 推翻:實為 wall-deadline teardown 同毫秒砍斷 in-flight call(見下方後續章節);lead 在 wall-deadline 後卡在 collect polling loop,沒走到「用現有 findings fallback synthesis」— lead 層級的收尾邏輯仍需加強 - timeout 對齊成功:
RESEARCH_WALL_TIME=3600+timeout 5400→ 內部 deadline 如期 fire(swarm done at turn 10, stopped_by=wall_deadline)
審計本身收穫(見 ZCodeProject/reports/ctx-mechanism-audit.md):P0 = guardian active-server emergency drop 確定性失效(restart_service active→return False,改檔不重啟 → OOM 風險);雙 timer 競態被推翻(zombie unit);last-writer 不可歸屬到時間戳。
Option B:原生 per-role model(sub_llm patch,已套用 + 驗證)
外部兩階段的原生版:profile 加 sub_llm: section → subagents 跑不同 endpoint。Patch 3 檔(~/ai-labs/frontier-agent/patches/sub-llm-complete.patch,80 lines):
build_swarm_model_profile(profile, sub_llm_section=None)— 簽名向後相容- main_agent:有
sub_llm:時create_swarm_llm建獨立 client →set_role_llm(SUB_ROLE_ID)+ ModelProfile 指向 sub model - tui.yaml 文件化
sub_llm:(env-overridable)
驗證:compile ✓ / YAML ✓ / unit test PASS(legacy 不變、sub model 解析正確)。PR ⛔:5 把 token 全無該 repo 寫入權 — 需 owner 授權。維護:upstream update 後 git apply patches/sub-llm-complete.patch。
2026-09-02 更新 unit-level PASS ≠ 實戰生效:首測發現
_bind_sub_agent_llm以runtime.sub_agent_llm短路get_llm(role_id)— routing 從未生效。真修法是同步覆寫sub_agent_llm變數本身;patch 現為 439 行 8 檔(含 F1-F5 framework 修復),完整實戰驗證 ✓ — 詳見下方「後續(2026-09-02)」章節。
Pipeline 結論 「Qwen 規劃 + Apodex 執行」概念成立:planner 品質超過人工 task prompt,executor 驗證紀律好且敢推翻假設。瓶頸仍是單 slot throughput(T1/T3 卡死)與 lead fallback synthesis 邏輯。原生 per-role model 只需 ~15 行 patch(
sub_llm:section +build_swarm_model_profile讀取),值得做。
後續(2026-09-02):T1/T3 根因結案 + sub_llm 實戰 + 五項 framework 修復
T1/T3 根因結案(forensics + 修復後重跑雙重驗證)
兩輪獨立調查(人工 forensics 直接讀原始證據 + 修復後 agent_team 4-subagent 重跑)結論一致:
根因 run 級 wall-deadline(17:51:41)觸發 teardown,把 in-flight/排隊中的 LLM call 連線同毫秒砍斷;subagent 無 graceful submit、零 partial 落盤。 t3 停於 deadline 前 44.7s、t1 晚 79.8s — 都死於「調查深處未交卷」。
三個先前假設全被排除:
LLM hang::8083 server log 顯示 task launch 與srv stop: cancel同一毫秒,之後 server 沉默 10 分鐘(客戶端砍的,不是 server 卡)context 耗盡:完成組 t2 用 80,219 prompt tokens > 停滯組 t1 51,431 / t3 60,111orchestrator 顯式 cancel:lead log 無任何 stop_subagent;原 run engine.log 直錄LLM call refused: 0s to wall_deadline (< 20s floor; turn=10, reason=pre_gate)
存活變數只有一個:deadline 前有沒有 submit_report(t2 距死線 95 秒交卷存活;t1 挖到 turn 27 才發現關鍵線索 — 死於太認真)。
sub_llm 首測抓出真 bug → 修復 → 完整驗證
unit-level 驗證通過 ≠ 實戰生效。首測 trajectory 顯示 subagent 的 call 全走了 coordinator 的 Qwen(:8083 零流量)。追蹤鏈:role_id 正確 → registry 同 singleton → 真兇:
# create_subagent.py — _bind_sub_agent_llm()
if runtime.sub_agent_llm is not None:
llm = runtime.sub_agent_llm # ← 永遠命中(coordinator 的 client)
else:
llm = resource_mgr.get_llm(role_id) # ← set_role_llm 註冊在這,被短路
修法:patch block 同步覆寫 sub_agent_llm = _sub_client(一行)。Echo run 端到端驗證 ✓(:8083 收到流量、trajectory 帶 apodex model)。
五項修復上線(全部 smoke pass + v3 實戰)
| # | 修復 | 一句話 |
|---|---|---|
| F1 | run-aware sub ceiling | SpawnGuard.set_timeout_s() ← main node 依 research wall 收緊 — framework 自己的 docstring 記錄過 52.8% sub-agents 被硬砍,WallClockGuard soft stop 機制本來就在,只差把 run deadline 接進去 |
| F2 | failure_salvager hook | bus 三條 failure 路徑呼叫 spec 掛鉤 → 從增量落盤的 trajectory 撈回最後 working notes → findings-<name>-partial.md + 回填 result |
| F3 | collect_reports 死亡逃逸 | 深查後確認既有機制已覆蓋(aborted/failed surface + wall 鉗制)— 不重複造輪 |
| F4 | :8083 --parallel 2 | 262144 總 ctx 拆兩槽 131K/slot(覆蓋實測 80K),KV q4_0 總量不變 |
| F5 | lead timeout env-overridable | logical_call_timeout_s: 900 硬編碼曾殺掉 lead 的 15 分鐘 reasoning turn(v2 死因 stopped_by=llm_error, logical_call_deadline)→ ${LOGICAL_CALL_TIMEOUT_S:-900} |
v2 的 meta 教訓 修復驗證 run 自己重演了 T1/T3 失敗類別:Qwen lead 單 turn 連續 reasoning 15 分鐘(規劃+起草全在腦內)→ 撞 900s per-call deadline →
tool_calls=0連 subagent 都沒派。deadline 殺長 call、無 salvage、零落盤 — lead 層同樣成立。 解法:LOGICAL_CALL_TIMEOUT_S=2400+ prompt 紀律(規劃 ≤3 句、第一 turn 內派工)。
v3 run:原生「Qwen 規劃 + Apodex 執行」首次完整交付
sub_llm: 啟用後的 agent_team(Qwen :8080 lead + Apodex :8083 × 4 subagents 並行):
- 4 個 subagent(q1_tails / q2_stall_nature / q3_tokens / q4_controls)全部交付,
notes-*.md增量落盤紀律生效 - lead 收齊報告自行整合 Q5 → 15KB 結構化報告(時間線 + 證據鏈 + 排他分析 + 三層修復建議)
- 獨立得出與人工 forensics 相同的根因,且挖到原 run engine.log 的直接記錄(
wall deadline reached mid-turn 10; ending with wall_deadline for salvage)— 雙重驗證閉合 - 對比 Option A 時代:同類任務從「2 subagent 歸零交付」→「4/4 交付 + 報告出版」
產物:ZCodeProject/reports/t1-t3-stall-analysis.md(forensics)、t1-t3-stall-analysis-v3-run.md(agent run)、patches/sub-llm-complete.patch(439 行 8 檔,含 F1-F5 + routing 修復)。A2A 廣播:dsh-to-all@20260902_083259。
組裝失敗研究(2026-09-02 晚)
最終 T1-T4 報告的「組裝」步驟連續三次 run 失敗,forensics 找到 一個 framework bug + 一個歸因污染缺陷:
- denial 渲染二次崩潰(
_deliverable_policy.py _paths()):agent 對/outputs的寫入被攔後,denial 訊息生成時對無效路徑(裸目錄'/outputs')再拋 ValueError → 整條錯誤說明消失 → agent 收到空回饋,9 次重試全部盲目。integrator 實質工作 9 分鐘完成,後 14 分鐘全燒在無回饋的授權探索。 - wall-deadline 後的無意義 retry:deadline 過後 pre_gate 必拒,框架仍重試 5 次 →
stopped_by=llm_error污染歸因(實為 wall_deadline)。 - 授權模型斷層:正確模式是「agent 寫
/workspace(無限制)+ submit_report → lead publish」,但任務書沒教 — integrator 在 /outputs 政策迷宮裡找不到出路。 - 結構性:44KB 報告 = 15K tokens 單體生成 ≈ 本地模型 12 分鐘,是 wall-deadline 下最脆弱的環節;v3 成功印證「subagent 分章生產素材 + 收尾編輯分離」才是在地化正解(R4/R5 已寫入任務書模板)。
詳細解剖與修復建議(R1-R3 小 patch + R4/R5 紀律):ZCodeProject/reports/final-assembly-failure-analysis.md。
R1-R5 已修復上線(2026-09-02,45 tests passed + smoke ✓)
- R1
_paths()per-entry try — 無效路徑渲染成<invalid declared path>,denial 必達 agent- R2
LLMCallExhausted不再被 generic retry handler 吞掉(except LLMCallExhausted: raise)+ Abandoning 分支保留wall_deadline歸因 — 消滅 deadline 過後的 5 次盲目重試,stopped_by不再被污染成 llm_error(agent_loop L554 本來就等這個 reason 做 salvage,只是沒人送達)- R3 bus 兩條 result_adapter 路徑包 try/except → 崩潰降級為 default adaptation(杜絕 never-retrieved task exception)
- R4/R5 任務書模板
~/ai-labs/frontier-agent/task-templates/assembly-task-template.md:授權模型句式(agent 寫 /workspace + submit,lead publish)+ 分章組裝(每章一個 create_file = 天然 checkpoint,拼接最後一步)- Patch:
patches/assembly-resilience.patch(291 行,3 檔)
相關筆記
- LFM2.5-2.6B 本地 Agent 小模型評估 - 2026-08-30(本地小模型 agent 的另一條線)
- 結構化逐字稿摘要產生研究(Clipto 式)- 2026-08-24(schema 遵守與小模型可靠性的前例)
- 產物:
~/ai-labs/frontier-agent/ab-test/run-*(執行軌跡)、ZCodeProject/reports/a2a-watch-audit-consolidated.md(91 lines 合併報告)
📚 參考來源
- 實測環境:
~/ai-labs/frontier-agent/(7+ 次執行,同一審計任務) - 框架論文:arxiv.org/abs/2608.23283
- a2a-watch.sh 審計產物:a2a-watch-audit-consolidated.md(91 lines 合併報告)
- 執行軌跡:
~/ai-labs/frontier-agent/ab-test/run-* - sub_llm patch:
patches/sub-llm-complete.patch(439 行 8 檔)