iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0

https://ithelp.ithome.com.tw/upload/images/20260910/20124384rIboI0I19Y.jpg

今天要做什麼外掛(Plugins)

  1. 名稱:antigravity-state
  2. GitHub:https://github.com/AndyAWD/antigravity-state

為什麼要做這個外掛(Plugins)

最近看到一篇 Google 與普渡大學合作發表的論文,標題叫做 SKILL.state: Scalable Long-Horizon Agent SkillsarXiv:2608.26263,作者為 Google 的 Sanket Badhe、Priyanka Tiwari 與普渡大學的 Jonghyun Chung,已被自然語言處理實證方法會議 EMNLP 錄取)。

論文直接切中長程任務的痛點:代理程式(Agent)越聊越長,最後權杖(Token)必定暴增且注意力渙散!

傳統對話機制每走一步,都把前面的對話歷史全部再讀一遍。這會造成三個問題:

  1. 權杖二次方暴增:每步輸入隨步數成長,執行長任務時累積消耗急速膨脹。
  2. 脈絡污染(Context Poisoning):過時的嘗試與冗餘推理混在歷史中,模型注意力開始發散。
  3. 狀態依賴推論重建:模型必須從落落長的歷史記錄中猜測進度,缺少一份確定性的狀態表示。

論文提出的解法是把「整段對話」換成「一張交接單」──只留狀態、不留歷史。每一步只給大型語言模型(Large Language Model)三樣東西,模型也只交回三樣東西:

每一步給模型的輸入:

  • P 規範:規則和做法,整趟不變。
  • Σ 狀態:交接單,做到哪、還缺什麼,只有現況。
  • O 觀察:上一步做完發生了什麼,只留最新一筆。

每一步模型交回來的輸出:

  • R 推理:模型這一步怎麼想的,看完就丟,絕對不留到下一步。
  • ΔΣ 狀態補丁:交接單要改哪幾格。
  • a 動作:接下來要執行的那一個動作。

論文實驗證明:一件要做 100 到 200 步的長任務,每步只看交接單,比每步重讀對話少用 16 到 50 倍權杖,成功率更高;在 100 道解題基準實測中少用 60% 權杖,解出題目反而從 43 題增加到 54 題。更重要的是消融實驗:預算有限時,留「結構化交接單」答對率達 94%,留「自然語言摘要」答對率只有 52%。

把論文搬進終端機:STATE.md 省的是重置的成本

在終端機開發實況中,模型單輪提示往往高達 50k 到 200k 權杖(主要來自系統提示與專案檔案),且寫交接單本身也要花費額外權杖。因此不需要每講一句就寫一次狀態,而是段落結束才寫一次交接單。

終端機裡真正省的是「重置的成本」,而重置一定會發生:

  1. 脈絡過半,要 /clear 或被系統自動壓縮:有 STATE.md,下一輪只讀約 2k 的狀態檔;沒有狀態檔就只能依賴自由摘要,關鍵細節極易遺漏。
  2. 休息超過存活時間(Time To Live,TTL)回來:快取已冷,續舊工作階段(Session)等於 150k 歷史全額冷重算;有 STATE.md 就直接 /clear 開新局,接續成本趨近於零。
  3. 切模型、切推理強度:快取反正沒了,不如順勢以狀態檔重置。
  4. 少走回頭路:狀態中記著已失敗做法與錯誤訊息原文,模型不會重踩,總執行輪數自然變少。

此外,針對長期、多人協作的大專案,業界會採用規格驅動開發(Specification-Driven Development,SDD,將規則寫入 spec、進度寫入 tasks.md);而個人在終端機內幾天完成的小任務,若每次都要寫大規格文件則負擔過重。
兩者精神完全相同:「該知道的放檔案,不放對話歷史」。

這就是我開發 antigravity-state 的核心原因:把論文概念搬進終端機,將規範定義為 /agy-state 技能,狀態落地為專案根目錄的 STATE.md,並透過 Antigravity 的生命週期(Lifecycle)掛鉤(Hook)實現首輪自動注入與結束防呆攔截。

這個外掛做的過程

第一次做

本來想說這小東西,寫在 GEMINI.md 規範中就好,像以下這樣

# 狀態管理

## 開場
- 新 Session 或 /clear、/compact 後,以 SessionStart hook 注入的 STATE.md 內容為起點,從「下一步」第 1 項開始,不重新探索專案;context 中未見注入時才自行讀取專案根目錄的 STATE.md
- 使用者當前指示優先於 STATE.md;STATE.md 與工作區現況(git status、檔案內容)矛盾時,以現況為準並更新 STATE.md
- STATE.md 不存在時,於第一個更新時機才建立;純問答或單輪任務不建立

## STATE.md 固定欄位(只用這七段,順序固定,不增不減)
```
# 任務狀態 ── 最後更新 YYYY-MM-DD HH:mm
## 目標
## 已完成
## 已變更檔案
## 待解決
## 關鍵資料(原樣保留)
## 已試過但失敗
## 下一步
```

## 更新時機(不是每一輪)
- 完成一個里程碑、使用者說「存檔」、使用者表示要 /clear 或 /compact 之前、要切換模型之前

## 寫法
- 只改對應欄位,不重寫整份;除「關鍵資料」外每段最多 5 行,「已完成」只留影響下一步判斷的項目
- 「關鍵資料」最多 5 項,識別碼、路徑、錯誤訊息每項原文照抄,不摘要
- 不把對話歷史或推理過程貼進 STATE.md
- 專案若提供完整交接指令(如 /save-session),跨 agent 交接仍用它;STATE.md 不取代

第二次做

寫完後才想到,這樣我不就每一台電腦都要手動複製貼上嗎,這也太蠢惹吧,所以改成用 Plugins 來做,然後加上 Hooks 確保他真的會記錄狀態

目錄結構

antigravity-state/
├── plugin.json               # 外掛程式資訊清單(定義名稱 antigravity-state 與版本 v0.1.0)
├── package.json              # Node.js 模組配置與測試腳本(node --test,24 項測試)
├── hooks.json                # 生命週期掛鉤定義(註冊 PreInvocation 與 Stop)
├── hooks/
│   └── hooks.json            # 掛鉤設定備援檔
├── skills/
│   └── agy-state/
│       ├── SKILL.md          # 技能指示檔(定義作業規範,註冊 /agy-state 指令)
│       ├── scripts/
│       │   └── state-check.mjs  # 狀態驗證與掛鉤處理核心腳本(零外部依賴,支援 CLI 與 JSON 雙模)
│       └── tests/
│           └── state-check.test.mjs # 24 項自動化單元測試套件
├── settings-hook-snippet.json # 手動註冊至 settings.json 之設定範例
├── README.md                 # 繁體中文說明文件
└── README.en.md              # 英文說明文件

這外掛怎麼用

外掛程式支援 GitHub 遠端安裝,並涵蓋手動存檔、重置接續與自動防呆三大情境。

安裝方式

  1. 透過 GitHub 遠端安裝(推薦):

    agy plugin install https://github.com/AndyAWD/antigravity-state
    
  2. 從本機路徑安裝:

    agy plugin install .
    
  3. (建議)設定全域 Git 排除清單,防止狀態暫存檔誤入版本庫:

    echo "/STATE.md" >> ~/.gitignore_global
    git config --global core.excludesfile ~/.gitignore_global
    

完整使用生命週期

情境 1:完成子目標後執行存檔(/agy-state)

在完成具體子目標並通過測試後,於終端機輸入 /agy-state(或以自然語言表示「存檔」):

────────────────────────────────────────────────
> /agy-state
────────────────────────────────────────────────
已更新 STATE.md(變更段落:已完成、已變更檔案、下一步)驗證通過。可以執行 /clear 了。

此時專案根目錄將產生標準化之 STATE.md

# 任務狀態 ── 最後更新 2026-09-09 23:40

## 目標
issue #4412:重構資料庫連線池與斷線重試機制

## 已完成
- [x] 實作連線重試指數退避演算法|驗證:npm test tests/retry.test.mjs 全部通過

## 已變更檔案
- M src/pool.ts
- A tests/retry.test.mjs

## 待解決
- 重試逾時上限需要自環境變數讀取

## 關鍵資料(原樣保留)
- 錯誤訊息:ECONNRESET: Socket hung up at TCP.onStreamRead
- 預設重試參數:MAX_RETRIES=5, BASE_DELAY=200ms

## 已試過但失敗
- 固定 1 秒間隔重試:高併發情境下造成伺服器連線雪崩

## 下一步
- [>] 實作連線健康檢查定時器|驗證:模擬斷線並檢查 3 秒內自動重連
- [ ] 將重試參數抽離至 config.ts
- [!] 整合 Prometheus 監控指標|原因:等 PR #4410 合併後才有 Metric API

情境 2:清空歷史與跨工作階段接續(/clear)

存檔後輸入 /clear 清空對話歷史,新工作階段啟動時 PreInvocation 自動注入看板:

────────────────────────────────────────────────
> /clear
────────────────────────────────────────────────
Clear conversation history?
> Yes
────────────────────────────────────────────────
=== STATE.md(專案任務狀態)===
以下為上個 session 存檔。從「下一步」第 1 項開始,不重新探索專案...
# 任務狀態 ── 最後更新 2026-09-09 23:40
## 目標
...
## 下一步
- [>] 實作連線健康檢查定時器|驗證:模擬斷線並檢查 3 秒內自動重連
────────────────────────────────────────────────
> 請繼續執行下一步
────────────────────────────────────────────────

情境 3:Stop 掛鉤防呆把關

若程式修改中途遇到問題或尚未完成驗證即嘗試結束回答,Stop 掛鉤自動介入阻擋:

────────────────────────────────────────────────
⎿  [Stop Hook Intercepted]
   STATE.md 有進行中子目標:「實作連線健康檢查定時器」。結束前擇一處理後執行 /agy-state:已完成則移到「已完成」並附「|驗證:」;要暫停則改回 [ ];受阻改為 [!] 並附「|原因:」。
────────────────────────────────────────────────

情境 4:任務達成與自動封存

當所有子目標驗證完成,「下一步」已無任何待辦項目時,執行 /agy-state 將觸發自動歸檔:

────────────────────────────────────────────────
> /agy-state
────────────────────────────────────────────────
目標完成,STATE.md 已歸檔至 ~/.gemini/state-archive/my-project-20260910-1015.md

專案根目錄的 STATE.md 自動清除,維持工作區乾淨。


上一篇
115/21 - Agy 知識庫 Agent 實作 - agy-help
系列文
第一次用 Antigravity CLI 做出 Plugin 就上手22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
chiaominchang222
iT邦新手 4 級 ‧ 2026-09-10 20:11:53

歐no 我只會下載extension:O

0
饅頭
iT邦新手 5 級 ‧ 2026-09-11 00:14:28

22 天了,我發現你的封面圖越來越黑了 wwwww

AndyAWD iT邦新手 1 級 ‧ 2026-09-11 00:56:07 檢舉

一直讓 AI 重複生圖,畫質越來越爛,我來看讓他重複三十天會怎麼樣

我要留言

立即登入留言