跳至主要內容
EMil Wu
EN

#26

Agent Team 實戰(四):身份會過期——從 99 行瘦身到 47 行的 Em Refactor

Agent Team in Practice (4): Identity Expires — Em's Refactor from 99 to 47 Lines

Agent Team 實戰 5 分鐘閱讀
一張正在褪色更新的 Agent 身份證 一張正在褪色更新的 Agent 身份證
身份會過期:定義只是起點,維護才是日常

一句話: 身份不是定義了就結束的,他會過期。


身份會過期:Em Refactor 的故事

之前講的都是「怎麼定義身份」,但有一件事在建構過程中讓我印象特別深:身份不是定義了就結束的,他會過期。[3]

Em 是最早建的 Agent,建的時候我還沒有累積那些方法論知識,還沒有 wiki 裡那些 Context Engineering 的原則,還沒有「CLAUDE.md 應該少於 60 行」的規則,所以 Em 的第一版 CLAUDE.md 有 99 行,裡面塞了他的身份定義、目錄結構說明、7 步 ingest workflow、5 步 query workflow、6 步 lint workflow,還有 conventions 和 page format template,總共 99 行,所有東西都在 CLAUDE.md 裡,每次開 session 全部載入[5]。

後來,Em 自己的 wiki 裡累積了一系列方法論知識(context-engineering、methodology-playbook-plan、skill-system 這些 concepts),而當我拿這些方法論回頭檢查 Em 自身的架構時,發現了四個自己違反自己的地方:

  1. CLAUDE.md 99 行太長
  2. Workflow 步驟(HOW 層級的知識)放在 CLAUDE.md 裡,應該是 Skills 或 Commands
  3. 每次對話載入全部 3 套 workflow,違反 JIT loading 原則
  4. 沒有任何 .claude/skills/ 或 .claude/commands/

Em 違反了他自己 wiki 裡記錄的原則。 這蠻有趣的,有點像醫生不聽自己的醫囑,知識管理的 Agent 架構不符合他管理的知識裡所記載的架構原則。

所以我讓 Agent Dm 做一次 refactor,先讓 Dm 的 Architect 讀了 Em 的 wiki 裡的三個相關 concept、閱覽了完整問題分析文件,接著設計一個 refactor plan,因為重點並不是重建 Em 的知識架構, 所以 Em 的 wiki 內容、raw 目錄、METHODOLOGY.md 都抱持不動,只是把身份的「載入方式」從 eager 改成 JIT:

原本在 CLAUDE.md 裡的Refactor 後的位置
Identity + Core Rules留在 CLAUDE.md(這是 always-on 的)
Ingest workflow (7 steps).claude/commands/ingest.md
Query workflow (5 steps).claude/commands/query.md
Lint workflow (6 steps).claude/commands/lint.md
Page format + conventions.claude/skills/wiki-schema/SKILL.md
graph TD subgraph BEFORE["Before: Eager Loading — 99 lines"] S1["Session Start"] --> L1["Load CLAUDE.md"] L1 --> ALL["Identity + Core Rules
Ingest workflow 7 steps
Query workflow 5 steps
Lint workflow 6 steps
Page format + conventions"] ALL --> W1["Available Context ▼
99 lines occupied"] end subgraph AFTER["After: JIT Loading — 47 lines"] S2["Session Start"] --> L2["Load CLAUDE.md"] L2 --> ID["Identity + Core Rules only"] ID --> W2["Available Context ▲
47 lines at start"] W2 -->|"/ingest"| CMD1["Load ingest.md"] W2 -->|"/query"| CMD2["Load query.md"] W2 -->|"/lint"| CMD3["Load lint.md"] end style ALL fill:#c67a50,color:#fff style ID fill:#6b8f71,color:#fff style W1 fill:#c67a50,color:#fff style W2 fill:#6b8f71,color:#fff
Em 的載入模式從 eager(全部塞進 CLAUDE.md)改為 JIT(需要時才載入),省下的 Context 空間用在真正需要的地方

Refactor 之後,CLAUDE.md 從 99 行降到 47 行,Em 的行為完全不變,他還是同一個 Agent,還是用同樣的 workflow 做同樣的事,只是現在他不再每次開 session 都載入所有 workflow,而是在 /ingest 的時候才載入 ingest workflow,/query 的時候才載入 query workflow。

身份的核心沒有改變,改變的是身份的載入方式, 而這個改變讓 Em 每次開 session 時的 Context 負擔從 99 行降到 47 行,省下來的 Context 空間可以用在真正需要的地方,比如閱讀更多的 wiki 頁面來做更好的交叉引用。

同一個時期,C7 也經歷了類似的能力升級,C7 在 Phase 2 建好的時候是 C7-minimal,只有 49 行 CLAUDE.md、2 個 own skills、3 個 commands,到了 Phase 5,C7 新增了 3 個 own skills 和 3 個新 commands,CLAUDE.md 只從 48 行增加到 53 行,因為新增的能力都放在 skills 和 commands 裡,不是塞進 CLAUDE.md。

Em 是身份瘦身(99→47),C7 是能力擴充(2 skills→5 skills),但兩者的邏輯一樣:CLAUDE.md 只放「我是誰」和「我怎麼判斷」,「我會做什麼」放在 commands 裡,「我知道什麼」放在 skills 裡, 需要的時候才載入,不用的時候不佔 Context。

這呼應了之前在精煉循環那篇裡講的概念:好的系統不是一次設計到位的,是在使用中被持續精煉的,能力跟身份也一樣,你不可能在設計階段就知道 Em 的 CLAUDE.md 應該有幾行,你只能在實際使用之後,發現哪些東西載入了但沒用到,哪些東西需要的時候卻不在 Context 裡,然後做調整。


身份混淆的真實代價

回到開頭那個「你是 Agent GM 還是 Agent G?」的場景,那次身份混淆的後果不是 Agent 報錯或停止工作,恰好相反,他很順暢地繼續工作了,只是用了錯誤的身份在做事,那個 session 只跑了 4 分鐘,最後 commit 了一個小修改,但那個小修改是用 Agent G 的邏輯做的,不是用 Agent GM 的邏輯。

graph TD START["New Session Starts"] --> LOAD{"Which identity
gets loaded?"} LOAD -->|"Correct"| GM["GM Identity
對話 before dispatch"] LOAD -->|"Confused"| G["G Identity
盡快建起來"] GM --> GM_Q["先問:修改的理由?
跟哪個 workflow 有關?"] GM_Q --> GM_R["Informed Decision ✓"] G --> G_A["直接執行
4 min → commit"] G_A --> G_R["看起來正確 ✗
判斷框架是錯的"] G_R --> HIDDEN["沒有錯誤訊息
要到後續才發現"] style GM_R fill:#6b8f71,color:#fff style G_R fill:#c67a50,color:#fff style HIDDEN stroke:#c67a50,stroke-dasharray:5 5
身份混淆的代價不是做錯事,而是用錯誤的判斷框架做了看起來對的事——而且沒有任何錯誤訊息

差別在哪裡?Agent G 是 bootstrap agent,他的思維是「盡快把東西建起來」,而 GM 的思維是「對話 before dispatch,確認理解了再動手」,同樣一個修改,如果是 GM 做的,他會先問「這個修改的理由是什麼?跟目前進行中的哪個 workflow 有關?」,而 Agent G 會直接動手。

身份混淆的代價不是「做錯事」,而是「用錯誤的判斷框架做了看起來對的事」,[9] 而後者更危險,因為你不會立刻發現,你會在後續的工作中才慢慢意識到某個決策的邏輯不對,然後回溯到那個 4 分鐘的 session,發現根源是身份載入錯了。

這也是為什麼 GM 的設計裡有一條明確的規則:「GM 的 CLAUDE.md 必須零 references 到 Agent G」,不只是不繼承 Agent G 的 build context,連引用都不行,因為 GM 需要從自己的身份出發思考,如果他的 CLAUDE.md 裡有任何 Agent G 的殘留,他可能會在某些情境下退回到 Agent G 的行為模式,而這種退回是安安靜靜的發生,不會有任何錯誤訊息告訴你「我現在用的是錯誤的身份」。


身份是 Context 的地基

身份定義像漣漪擴散到所有下游決策 身份定義像漣漪擴散到所有下游決策
身份是 Context 的地基——清晰的定義產生有序的漣漪,模糊的定義擴散成混亂

五個 Agent 的身份設計回顧完了,但我想強調的不是「每個 Agent 要有 CLAUDE.md」這種技術細節,因為這很容易做到,我想說的是一個更根本的東西,我在建構 Agent Team 的過程中,我碰到的每一個問題,回溯到最後,幾乎都跟身份有關。

  • Em ingest 出來的 wiki 頁面品質不穩定?回溯到 Em 的 CLAUDE.md 裡沒有明確定義交叉引用的判斷標準
  • C7 的 skill 入庫驗證太寬鬆?回溯到 C7 的 skill-contract.md 沒有涵蓋某些邊界情況
  • GM 太急著派工?回溯到 GM 的身份定義裡沒有足夠強調「對話 before dispatch」

身份是 Context 的地基, 如果你在身份層做了一個模糊的定義(比如「你是知識管理員」但沒說清楚知識的分類體系),這個模糊會像漣漪一樣擴散到所有後續的決策裡,Agent 不會來問你「你說的知識管理到底是什麼意思」,他會用他自己對「知識管理」的理解去做事,而他的理解跟你的理解之間的差距,就是你後續花在修正和校準上的時間成本。

這也是為什麼上一篇說「HANDOFF.md 是第一個產出」,而這一篇要說的是:CLAUDE.md 是最重要的產出。 一份好的 HANDOFF.md 可以讓新 session 快速接手,但一份好的 CLAUDE.md 可以讓 Agent 在整個生命週期裡做出更好、更正確的判斷,前者是一次性的提升,後者是持續的品質保證。

或許 Agent Team 最需要投入時間的不是架構設計、不是通訊協定、不是記憶系統,而是反覆回答同一個問題:「這個 Agent 到底是誰?」而每次你覺得這個問題已經回答完了的時候,就是你該重新審視答案的時候,所以回到大家常說的讓 Agent 在閉環中成長、進化,或許 Agent 的能力會成長(這又是另外一篇),但至少對我來說,Agent 的身份會過期,所以我們更應該要讓他可以自我更新,追上當下的 Agent Team 的”狀態”,繼續跟團隊前進。


參考資料

[3] Preprints.org — Detecting and Repairing Role Drift in Multi-Agent Collaboration(RoleFix 框架,定義 role drift taxonomy) https://www.preprints.org/manuscript/202603.0348

[5] Hugging Face Forums — Solving Agent System Prompt Drift in Long Sessions(system prompt 注意力權重隨 context 增長下降) https://discuss.huggingface.co/t/solving-agent-system-prompt-drift-in-long-sessions-a-300-token-fix/173787

[9] GitHub Issue #32721 — Teammates Receive “Claude Agent SDK” Identity, Not “Claude Code”(identity misconfiguration 在真實系統中的 bug 實例) https://github.com/anthropics/claude-code/issues/32721

支持這個系列

如果這系列文章對你有幫助,考慮請我喝杯咖啡