Agent Brief 工作台 — 一個會操作本站 API 的 Weft agent
用 Weft SDK 在這個作品集裡蓋出來的 Agent 工作區——LLM agent 透過呼叫本站自己的 OpenAPI 來建立招募 Brief,背後有一台狀態機負責擋掉不合法的步驟。
利益揭露
我是 Percena 的共同創辦人, Weft 是我們的 產品——所以我對它不是中立的評論者。SDK 不是我寫的。我在 Weft 的角色是產品方向、 點子與行銷;在這個網站上,我是整合的人。這個分工正是這篇的重點:這是我第一次得 真正去「用」自己參與形塑的東西,而整合的現場,就是產品意見撞上真實程式碼的地方。
概述
這個作品集有三種模式。人類模式就是你正在讀的網站。機器模式是給爬蟲看的
llms.txt 風格覆蓋層——被動、唯讀。AI 代理模式則是一個真正的工作區:由 Weft
驅動的 agent,透過呼叫本站自己的 API 來建立一份招募 Brief。
一句話講完:
人類給人看,機器給爬蟲看,代理給操作者用。
你給它一個目的(「我在找 agent memory 方向的人」),它會從真實的內容裡挑出專案與
文章、擬出 Brief,最後給你一份可以直接帶走的 markdown。它不是硬黏在行銷頁上的
聊天機器人——它不是在回答關於這個網站的問題,而是在操作這個網站,走的是你自己
也能 curl 的那組 HTTP endpoint。
為什麼這樣做
在作品集上放個聊天機器人證明不了什麼:那只是一個文字框,後面接著一個讀過你首頁的 模型。真正有意思的主張比較窄,也比較難:如果給 agent 一個真實、有狀態的產品介面, 它能不能被信任、不把事情搞砸?
所以這個 demo 刻意做得不花俏。Agent 不會「憑感覺亂逛」。它是透過明確的狀態轉移去 改動一份 session 產出物,而哪些轉移合法,由後端說了算。
運作方式
三個信任domain,全部 fail-closed:
BROWSER THIS SITE CONTROL PLANE
(untrusted) (trusted) (weftd)
+------------------+ +------------------+ +-------------+
| Weft chat panel | | holds dev key, | | brokers the |
| |-ask->| mints scoped |-key->| LLM run |
| scoped token |<-tok-| sessions | | |
| only | | | | |
+-------+----------+ +------------------+ +-----^-------+
| |
| REST + SSE, via the |
+---same-origin /api/weft proxy ------------------+
| (strips cookies, allowlists headers)
|
| client-executed tools: same-origin, your cookie
v
+------------------------------------------------+
| /api/v1/* -- Brief Desk API |
| every mutation runs the state machine; |
| illegal step -> 409 { error, allowed_actions } |
+------------------------------------------------+(圖裡刻意全用英文與純 ASCII:CJK 和方框繪製字元都不是等寬字型裡的字,混進去會讓 對齊在瀏覽器裡直接爛掉。圖說在下面。)
幾個值得點名的地方:
Developer key 永遠不會進到瀏覽器。 後端簽發一個受限的 session token,瀏覽器 只拿得到這個。所有瀏覽器↔控制平面的流量——包含 SSE timeline——都走同源 proxy, proxy 會剝掉 cookie 並只放行白名單 header,所以訪客的 session cookie 不會外洩到 控制平面。
Tools 來自 OpenAPI 規格,不是來自散文。 Toolset 是從本站自己的 OpenAPI 文件
推導出來的,也就是說 agent 的能力和 API 的真實契約不可能各走各的。Tools 以
execution: client 執行——同源、從瀏覽器發出、帶訪客的 cookie——所以 agent 的權限
就是訪客的權限,一點都不多。
狀態機是最後一道防線。 Brief 的流程是 empty → scoping → collecting → drafted → ready → exported,另外有回頭修改的 back-edge。如果你在還沒挑任何東西的時候就
叫它送出 Brief,API 會回 409,並附上 allowed_actions 清單。Agent 會把這個訊息
轉述出來、然後改走合法的路,而不是傻傻重試。系統提示詞是從 API 實際使用的同一份
狀態機模組算出來的,所以模型看到的規則和伺服器執行的規則不會對不起來。
Agent 會把過程攤開。 每次 tool 呼叫都會以具名步驟出現在 timeline 上,而不是 一個黑箱回答泡泡;action bridge 還會把 tool 剛剛碰到的那張卡片或那一列高亮起來—— 所以你可以親眼看到項目確實落在 agent 說的位置。
核准關卡。 權限模式預設是 ask:agent 可以草擬聯絡訊息,但要送出,得由人在
對話裡按下核准。
如果你要挑我毛病,我會先自己講
誠實的限制,因為只列好處的 case study 沒什麼價值:
- 狀態存在記憶體裡,而且是 per-instance。 多實例部署可能在 session 中途把 Brief 弄丟。這是為了 demo 刻意做的 v1 取捨,不是我會替真實產品辯護的設計; 下一步顯然是換成 KV。
- Agent 模式有 flag 擋著,預設關閉。 它需要控制平面的憑證才能跑,而人類模式 被設計成完全不需要這一整套也能運作——作品集絕不能依賴 agent stack 活著。
- 流量限制只是基本款。 Per-IP 固定視窗、body 大小上限、有界的事件串流。這是 對一個個人網站來說剛好的規模,不是 WAF。
- 濫用風險是真的。 一個公開網站前面掛著 LLM runtime,是會把 token 預算燒光的。 另外,任何宣稱「這個動作來自 agent」的東西都只是標籤,永遠不能拿來當授權依據 ——瀏覽器想寫什麼就能寫什麼。
狀態,以及怎麼試
開發中,藏在 feature flag 後面。Domain API、工作台 UI、action bridge 與 tool 接線 都已經做完並測過;本地協定也已經用替身控制平面做過端到端驗證。
Agent 模式由 NEXT_PUBLIC_AGENT_BRIEF 控制,預設隱藏——關閉時,模式切換選單只會
出現「人類」與「機器」,而且整包 agent 的 JavaScript 完全不會被下載。要打開它,
還需要伺服器端的控制平面憑證(WEFTD_BASE、WEFT_API_KEY、WEFT_TENANT_ID);
沒有這些,聊天會直接 fail closed 給出明確錯誤,而不是半殘地跑。SDK 本身在
percena/weft-sdk。