https://softwareengineeringdaily.com/podcasts/scaling-agent-workloads-at-vercel/
讓一千個人在同一秒對同一個 Agent 送出 prompt,會發生什麼事?這是 Andrew Barba 在節目上拿來切開兩種 Agent 世界的問題。一邊是大家熟悉的樣子:Codex、Claude Code、OpenCode 這類跑在自己電腦上的 Harness,一個人對著一個 Agent 來回。另一邊是 Eve,Vercel 開源、雲端原生的 Agent 框架,同一秒的一千個 prompt 要能水平擴充出去,每個 session 各自隔離、持久、出事可以恢復。Barba 在 Vercel 的頭銜是 member of technical staff,Shah Dara 是 Eve 的產品負責人,兩人在這集跟主持人 Kevin Ball(KBall)把這個框架從頭拆到尾。
Barba 進 Vercel 的路有點繞。他 2020 年還是 Vercel 的客戶,可能是最早的一批企業客戶之一,後來進公司待了三年半。前一年半做 CDN,碰的是分散式系統、邊緣網路、防火牆這類很底層的東西,接著換到另一端做帳務,也在那裡認識 Shah。兩人在 2025 年大半時間一起帶帳務團隊,今年二月有個機會去追一個問題:把 Agent 部署到 Vercel 上,到底需要什麼?Eve 就是那個問題的答案。Shah 在 Vercel 待了一年半,之前做了十年的帳務。
底下那層手工地基
Eve 不是憑空長出來的,它是從 Vercel 內部的資料 Agent「DZero」長出來的。DZero 是 Vercel 第一個全公司都在用的 Agent。把它放上 Vercel 的過程,團隊做了一大堆手工系統,把自家的 serverless functions、sandbox、workflow 一層一層包起來。Barba 說,當時光是讓它正確地跑起來,就吃掉整個團隊大量力氣,還沒開始想 DZero 到底要做什麼。
他們也在 DZero 身上看到另一件事:它是資料 Agent,做的事情基本上是在提供一層語意(semantic layer)。同事問「每月活躍使用者有多少」,這句話裡的詞在 Vercel 是什麼意思,得有人告訴 Agent。公司裡不同的人講同一件事會用不同的縮寫,這一整層就是在教育 Agent。Barba 說,DZero 的功能有九成來自 Markdown、YAML 這類規格檔。
兩件事合起來,決定了 Eve 最早的樣子。第一,部署一個 Agent 要像 DZero 一樣耐久,但簡單得多;第二,很多 Agent 幾乎可以完全用英文寫完。早期版本把話講得很滿:Eve 裡沒有程式碼,全部都是英文 Markdown 檔。這兩個極端,就是 Eve 今天的起點。
一個目錄,加一個 instructions.md
想動手的人拿到的是什麼?Barba 說,就是一個目錄。最簡單的 Eve Agent 可以只有一個 instructions.md,其他什麼都沒有。框架有它自己的 grammar 與 slot,這些會編譯成一份 manifest,而 manifest 就是前面說的 infrastructure as code:你加了 Skill,平台就替你開一個 sandbox;你定義了排程,就長出跑排程用的事件基礎設施。Barba 用「把 ChatGPT 裝進盒子」形容這個預設值。丟一個 instructions.md 進去,你得到一個前沿模型,照它訓練好的樣子,加上一份雲端託管的部署。
Skill 給提示,tool 跑程式,channel 是入口
核心的幾個原語裡,instructions 決定身分,這點大部分人都熟。Skill 是漸進揭露(progressive disclosure):Skill 給的是一個「什麼時候該用我」的提示,模型很擅長判斷自己需要多知道什麼,看到提示就會把額外的 context 拉進來。Barba 說 DZero 大概九成都是 Skill。tool 讓 Agent 跑確定性的程式碼,去 Postgres 或某個外部 API 拉一組確定的資料;connection 是 tool 的特化版,專門處理 MCP 這類東西,Eve 讓你直接把一條 MCP 網址丟進去,工具就自動曝光,不用自己想辦法接。
channel 是入口。預設那條是 HTTP route,終端機介面跟接上 Next.js 的應用走的都是它;比較有意思的是 Slack、Teams、GitHub,Eve 支援這些平台第一方的事件,也替常見用法準備了預設,你當然可以改。subagent 最簡單的理解是 context 管理:有些任務太大,塞進母 Agent 會把 context 撐爆,就交給 subagent 自己去做,做完回報。但 subagent 在 Vercel 內部長出了另一種用途,它變成組織單位:整個團隊認養一個 subagent,DZero 是另一個 Agent 的 subagent,由資料團隊擁有;公司裡還有一個專門懂「怎麼建 Eve」的 help Agent,也是母 Agent 的 subagent。eval 則是 Barba 最有興趣的一級公民。
eval 是拿來管非確定性系統的
在 Eve 裡,eval 有兩種。一種偏確定性:你送出查詢,然後確認某個 tool 被呼叫。這件事不是百分之百確定,模型有可能不叫,但寫起來很直接。Barba 舉例,如果做的是天氣 Agent,使用者問天氣,你會希望 get weather 這個 tool 真的被叫到。另一種是 LLM as judge:讓模型去推理、評分、打分。對 DZero 這種東西來說,這裡才開始有趣,你可以拿它替生成的 SQL 打分,檢查它有沒有查對的表。
一個 eval 在 Eve 裡就是一個定義好的函式,你拿到一個測試函式,裡面等於是你 Agent 的完整介面:可以用 prompt 起一輪對話,可以觸發 human in the loop,Eve 有的功能都能在 eval 裡用程式寫。Barba 說,Eve 自己的測試套件就是一整套 eval,這也是他們一天能發好幾個版本的原因。
KBall 在訪談裡岔到一個他自己很在意的方向:既然 eval 描述的是「應該長成什麼樣子」,能不能把 prompting 本身變成一個最佳化函式,讓另一個模型在迴路裡反覆改 Agent,直到行為對了?Barba 說他沒這樣想過,但如果用 coding agent 去建 Eve Agent,實務上會發生很接近的事:coding agent 迭代時會自己寫 eval、自己跑 eval,一部分原因是 Eve 的套件裡帶著給 LLM 看的文件,也提示了「用 eval 測 Eve」,所以 coding agent 看得懂。Vercel 內部有一批 fixture 形式的範例 App,本地開發時 coding agent 就是拿這些在跑 eval。Barba 說他還沒真的看過「先寫 eval、再寫實作」這種順序,但可能已經很接近。
文件要寫給 coding agent 看
KBall 補了一句,這幾年框架開始把文件當成有兩種讀者在設計,一種是人,一種是 coding agent。Barba 說他們從 Next.js 學到很多:模型的訓練資料裡是舊版的 Next,怎麼讓它學會最新的東西是個真問題,而 Eve 對這些模型來說根本不存在。所以他們花了很多時間確定套件裡要附 LLM 友善的文件,效果很好。
scaffolding 裡有一份給 Agent 看的說明檔指向文件,套件裡也放了 changelog。這件事對 pre-1.0 的框架特別關鍵:Agent 只要看版本差異就知道要改什麼,不用從零摸索;框架每週都在破壞相容性,changelog 是讓使用者願意升級的原因之一。KBall 說他在很多程式碼庫裡看到同一招,只要一個 repo 有不只一個人,changelog 對 Agent 的幫助就很明顯。
誰看得到什麼,在 channel 那層就要解掉
話題換到雲端 Agent 最難的那一塊:誰能看什麼。Barba 說 Eve 從第一天就以企業為目標,知道會是 code-first,也預期公司會用它建自己的 Agent 來跑生意,所以權限很早就烤進去了;最近才回頭補更多個人使用的場景。
身分在 channel 那層就解掉了。以 Slack 為例,「你是誰」等於 workspace ID 加上 Slack user ID。Eve 從一開始就是為多人使用而設計,你在 Eve 裡寫的任何程式碼都會拿到一個 context 物件,裡面有「這一輪的目前使用者是誰」,還有「這一輪是誰開始的」;這兩個人可能不是同一個,因為不同的人可以在不同的時間點接力問下去。傳統 REST API 那種看認證標頭、認證完再決定你能做什麼的權限模型,在 Eve 裡就是靠 channel 層解出的身分來做。
再往下是「Agent 能不能做某個動作」。這裡有 tool approvals,會以 human in the loop 的形式出現,長相完全取決於哪個 channel 叫它:同一條規則可以寫成「這個 tool 永遠要人工批准」,從 Slack 進來就用 Slack 的介面呈現,從 SMS 進來又是另一個樣子。你可以看到是誰問的、是誰按下批准,兩個不一定是同一個人。Barba 說這正是 code-first 框架發亮的地方:這些情境沒辦法預先窮舉,Eve 的態度是你自己寫程式碼決定你要的體驗。
最難的一塊,Barba 自己承認還沒完全解掉,就是「你只能看到你該看的」。DZero 技術上能碰到 Vercel 整個 data lake,Guillermo 問一個問題時看得到的東西,Barba 問同一個問題時未必該看到,兩個人的憑證要怎麼分辨?Eve 的做法是一個叫 Define Dynamic 的 API,讓開發者依照當下的呼叫者決定要曝光哪些 tool、哪些 connection,甚至可以做到「這一輪是我在問,這個 tool 就不要出現」。這是進階用法,但文件寫得夠好,只要你 prompt 得對,coding agent 會自己學會怎麼寫。
內部幾百個 Agent,外面從企業到週末專案
Shah 負責講使用者這一側。Eve 一開始鎖定企業,因為多數需求來自那裡,Vercel 自己也剛好有那套基礎設施,加上他們其實是在抓自己的癢處:Vercel 內部的 Agent 全部跑在 Eve 上,數量已經有幾百個。上線沒多久,他們看到數千名使用者開始採用,而且不全是企業客群,很多是 Hobby 或 Pro 方案的使用者。使用範圍從企業自動化一個業務職能,到有人週末做了一個多人 iMessage Agent。Shah 說他們想全部支援,讓大家把框架往自己的需求延伸。
訪談也問到內部 Agent 的分布,工程占了幾成。Shah 說一開始確實從工程長出來,工程也是最早大量生出這些 Agent 的職能;但採用擴散之後,go-to-market 把手上能搬的東西都搬到 Eve,行銷拿它自動化內容製作與社群,產品團隊把產品文件餵給 Agent 回答問題,對內也用,有時直接在 Slack 上跟客戶分享。他指出目前工程還是最重的一塊,工程師是主要的建造者與使用者,但他預期這個分布會越來越平均,因為生出一個 Agent 越來越容易,接下來還有自我演化。
Shah 歸納出三種常見型態。對話型 Agent 主要透過 Slack 出現,Vercel 是一間重度使用 Slack 的公司,最早的案例都在那裡,DZero 主要就是在 Slack 上工作。背景型 Agent 的工作是跑一份報告,然後把結果丟到 Slack 或寄給內部同事。第三種是應用,go-to-market 團隊是這類的大戶:你還是做了一個 Agent,但使用者看到的是網頁應用,網頁應用背後由 Agent 驅動,另外再給一個跟 Agent 對話的介面。Shah 說目前看到的大致就是這三種。
前端只接一條 durable stream
下一個問題是實際的整合:一個由 Agent 驅動的網頁應用,Eve 的目錄要放在哪裡,是塞進前端專案,還是獨立一個 repo?Barba 說他們對 Next.js 有很明確的立場:Next 有 pages 目錄、後來有 app 目錄,那 agent 目錄也該直接能用,所以第一方支援 Agent 就住在 Next.js 應用旁邊。但不是非得這樣,很多團隊還是前後端分開部署,Eve 完全可以照那樣跑:Agent 自己是一個專案,前端單純透過 HTTP 接上去。
那條 HTTP 就是預設的 Eve channel,也是它的串流協定,有送訊息、取消這些動作,最後回給你一條持久串流(durable stream),你可以拿它去驅動任何你想得到的介面。Barba 說他們內部的講法是:Eve 是後端框架,不是前端框架,它跟你的前端相處的方式,跟你其他後端沒有兩樣。
Shah 補了兩個應用案例。一個是開源 CRM:使用者新增一筆 lead、填上名字與 email,背景 Agent 就去研究這筆 lead,把剩下的資料自己補完。另一個是 AI 音樂工具:使用者設定 tempo,Agent 在網站上跟你一起協作,把曲子完成。這類 Agent 原生的應用,Eve 在後面當大腦。
KBall 覺得這一塊還被低估。現在所謂的生成式介面常常只是把聊天機器人塞進去,或者非同步生一份報告出來;真正還沒被開發的是協作式介面,例如協作文件編輯加上 Agent 會長什麼樣子。現在勉強可以拿 Claude 的 artifacts 做,或在 Google Docs 裡配 Gemini,但後者他不推薦。
Barba 承認那條串流很底層。你拿到的是一段一段 delta 的推理內容,Vercel Labs 在做一些把低階協定轉成介面的嘗試,例如 JSON Render。TypeScript client 讓事情好過一點,有型別化的 phase 與 event 可以迭代。不過他同意這還是相當低階的 API,他很想看到這裡有更多東西做出來。
他也提醒,Eve 不只是聊天。送訊息時可以指定 output schema:如果你的介面需要某種形狀的資料,就讓 Agent 生成那種形狀。實作上,schema 一路傳到 AI SDK 的 tool loop agent,最後生出一個叫 submit_result 的 tool 來驗 schema,而且可以重試。Agent 常常第一次交出來的東西缺了必填欄位,系統就提示它漏了什麼,它再交一次。Barba 說這不能保證一定拿到你要的 schema,但以現在的前沿模型來說,表現相當好。
KBall 追問 tool call 的代價:一旦走到 tool call,串流就變成一個同步的阻塞,介面得準備一個等待的畫面,而不是把結果一片一片流出來。Barba 說不完全是這樣。串流本身還是會把中間所有的推理吐出來,只是最後一步從「給你看一段英文訊息」換成「給你看一個 tool call」,中間你一直看得到東西。用高推理設定的時候,那些中間過程是可以檢查的。
每一步換一個 function
雲端規模一旦成立,耐久性與可恢復性就變成非解不可的問題。Barba 說他們很早就決定把 Eve 蓋在 Vercel 的 Workflow 上,那是他們版本的 Temporal。模型很簡單:一個 Workflow 就是一個 Eve session,今天其實是兩個 Workflow,但可以當成一個來看。切分方式是每個 session 跟其他 session 完全分開,需要共用資料的話,Eve 提供指南教你怎麼接自己的儲存。一千個 session 跟一個 session,使用者不該需要想這件事,雲端該替你做掉。
真正的工程在 serverless。傳統 serverless function 有 15 分鐘的上限,Agent 顯然會跑更久,所以他們做了一件有點聰明的事:每次呼叫 tool 就換到下一個 function,Workflow 在那裡繼續跑,因為換了 function,時間等於重新起算。今天他們的作法是每一步都換一個新 function;未來如果時間額度還很多,可能同一個 function 上跑好幾個 tool call。只要 Workflow 夠快又穩定,使用者不會注意到,Agent 就可以一直跑下去。
Memory 分抽屜,自我演化開 PR 給自己
Barba 說他現在手上最大的一件事就是 Memory,而且全部開在 PR 裡,任何人都可以去看。這件事跟前面說的策略轉向有關:Eve 從企業出發,但記憶這種東西未必是企業場景,反而非常個人。所以他們開始回頭補個人使用的功能,自我演化是其中很重要的一部分。他的想像是:你把一個出廠預設的 Agent 部署起來,它跟你一起工作,然後自己慢慢變好。
自我演化有幾種形式,Eve 走的路跟 Hermes 那類東西不同。Hermes 可以直接改自己的程式碼再重啟;Eve 在 Memory 之外的第二條路是改自己,例如加一條連到某個 MCP server 的 connection、寫新的 tool、生出新的 Skill。Skill 可能更接近記憶,但其他東西就得真的寫程式碼,Eve 目前的重心是 Git:客戶都在用 Git,所以目標是讓 Agent 對自己開 PR。開發者可以定義一個 coding subagent 當作自我演化的執行者,部署時 Eve 會幫你準備好帶程式碼的 sandbox,也把 prompt 準備好,讓它知道什麼時候該去叫 coding agent 改東西。要多少人工監督也由你決定,從全部人工審查到讓它自己合併,都是可以配置的自動化。
Memory 的做法是一個一級目錄,裡面可以定義不同的 memory slot。舉例來說,你可以替某個 Slack channel 設一組 workspace memory,那是所有使用者共用的全域記憶;另外再開一個 slot 只放你自己的記憶。Agent 因此有好幾本帳,依照你定義的 scope 去讀跟寫。Barba 說這像是給個人使用者一個很好上手的 provider,同時保留企業級記憶需要的原語。
KBall 也請 Barba 定義他口裡的 slot。Barba 說他講 slot 通常指框架的頂層目錄,Skill、tool、sandbox、channel 都是。Memory 會是一個 authored slot,也就是頂層目錄,裡面再分抽屜:一個抽屜是全域,一個抽屜綁使用者,一個抽屜綁 channel 加使用者,例如只有某些 Slack channel 裡的記憶。這種切法解決一個經典問題:你幾乎不會想要一個把 user ID 當參數的 tool call,因為你不希望 Agent 去猜使用者的 ID。memory slot 會把工具綁死在對應的抽屜上,Agent 就沒有機會猜錯。權限與這類東西要確定性地待在 Agent 行為的下一層。他們內部來回討論過 Memory 該不該是一級公民,最後是這類問題說服了他們:當你開始擔心 Agent 會抓到別人的記憶,就代表這東西需要框架提供護欄跟好用的 API。
暴露給 Agent 的方式是 provider。provider 可以決定自己要給哪些 tool,Eve 對記憶該有哪些 tool 完全沒有意見;它確定性呼叫三個函式:recall、save,以及一個負責給出工具的函式,剩下交給 provider。框架內建的是 file provider,非常簡單:recall 把整個檔案當 context 回傳;save 沒有實作,直接被忽略;工具只有 add memory 與 forget memory。Agent 加一筆記憶,檔案就重新寫回 blob storage;刪一筆記憶,也是拿掉之後再寫回去。
KBall 確認了一次:所以 recall 是確定性會被呼叫的,回傳的內容從一開始就嵌在 Agent 的 context 裡,再加上那兩個工具。以檔案版來說,檔案的內容會出現在每一輪的 prompt 裡。
同樣的介面可以走得很遠。Barba 提到 Super Memory 這類服務:recall 與儲存全在他們的服務上做,provider 可能一個 tool 都不給,因為他們不想讓模型自己喊 add memory;他們在 save 被呼叫時接下整段訊息歷史,跑自己的流程判斷該記什麼。他們的 recall 也不是回傳一份檔案,而是看著進來的那則訊息,動態決定要撈什麼出來。兩者是完全不同的 recall。
KBall 接著問,recall 是每一輪都叫嗎。Barba 說它會在幾個階段被叫,最主要的是每一輪開始;另一個時機是 context 壓縮(compaction)之後,因為不能保證壓縮過的內容還留著記憶,所以要重叫一次。像 Super Memory 這種 provider 可以看壓縮後的 prompt 自己決定這樣夠了、還是要重新注入。注入方式預設是附加在後面,因為不想打破 prompt cache;記憶用 user 角色送進去。你也可以改成 system 角色,對檔案版來說可能更合理,代價是每次 add 或 forget 都會讓 system prompt 失效。
開源,但外部 PR 沒辦法直接測
KBall 注意到 Eve 開源,問起貢獻模式。Barba 說有一個有點尷尬的問題:Eve 的測試套件會去打模型,也會真的把專案部署到 Vercel,用到一堆 secrets,所以外部貢獻的 PR 沒辦法直接測。流程變成小心地拉進 sandbox、確認不是惡意程式,然後用 Vercel 的帳號以共同作者的身分重新提交,才能跑測試。他說這確實很煩,還在想更好的做法。他們想要外部貢獻,也盡量收;Vercel 內部的 Eve Agent 每天在分析這些 PR,找出值得拉進來的。團隊規模從三月到七月中是兩個人全職,之後又加了四個人,現在工程端大約六個人全職在做。
押模型變聰明,以及開公司就是開 Agent
最後 KBall 請兩人談展望。Barba 說 Eve 很早的一個原則就是押注模型會越來越聰明,整個框架是為了吃到這件事而設計。他們看過很多 AI 框架往垂直方向長,程式碼越堆越多,最後看起來不像 Agent,反而像一堆確定性的 workflow API。Eve 要往水平長:多給模型一些東西,讓它自己做決定。目錄結構也是從這裡來的。他認為模型變聰明的速度短期內不會慢下來,Eve 會繼續往這個方向走。
Shah 的版本更大。他說他們的想法是「開公司就是開 Agent」:Eve 比公司的設立登記還根本,你的 Agent 會比你的網站、你的網域、甚至你的公司登記都早出現。你先有一個 Agent,它替你一點一點長出一座軟體工廠,包含完整的軟體開發生命週期;你的工作是去微調那座工廠。他認為 Eve 有機會變成公司的大腦。
最後一個問題是,如果真的拿這個東西開公司,能不能不放在 Vercel 上。Barba 說這件事對他們很重要,內部已經有客戶把 Eve 跑在自己的 Kubernetes 與自己的硬體上。做法是用 Workflow 裡的 world 抽象:他們的端到端測試就是拿不同的 world 在跑,有 Postgres world、有 local world。只要能替自己的基礎設施定義出一個 world,而外面已經有很多現成的,你就能自己託管 Eve。他說這方面還有很多工作要做。Memory、自我演化這些能力最終都需要 adapter 合約,框架本身不可能什麼都自己做;重點是這些 API 與 adapter 要在設計的早期就想到,而不是等 Vercel 上跑通了才當補丁加上去。