〈Software Engineering Daily〉-EP-Scaling Agent Workloads at Vercel

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 上跑通了才當補丁加上去。

〈Software Engineering Daily〉-EP-Inside Google’s Database Infrastructure for the AI Era

https://softwareengineeringdaily.com/podcasts/inside-googles-database-infrastructure-for-the-ai-era/

Sylas Krishnamurthy 是 Google Cloud 負責資料庫的 VP of Engineering。他在 IBM 寫過 DB2,在 UC Berkeley 拿串流資料庫的博士,把博士題目做成公司賣給 Cisco,接著在 AWS 待了五年、帶過 Aurora MySQL 與其他 MySQL 引擎,2019 年進 Google。他說自己其實有兩份工作,一份是 Google Cloud 的交易型資料庫,另一份是進來之後才知道的:整個 Alphabet 的營運資料庫。Gemini、Gmail、YouTube 都跑在同一套系統上,Spanner 與 Bigtable。

主持人 Matt Merrill 是個資料庫愛好者,這一集聊了七十幾分鐘,從資料庫五十年的老契約,一路聊到 AI 把契約撐開之後,Google 內外各自發生了什麼事。Krishnamurthy 的判斷很一致:資料庫過去承諾的精確結果,正在被相關性取代;而工程師得學會活在一個非確定性的世界裡。

五十年的契約:不要弄丟資料,給出精確答案

他常開玩笑說,資料庫只有一份工作:不要弄丟存進來的資料,然後對查詢給出精確的答案。這兩句話撐了五十年。2024 年他在 Berkeley 演講前去查了 SQL 原始論文發表的日期,發現幾乎就是同一天,1974 年,跟他出生的年份一樣。

中間當然出現過各種嘗試,非關聯式系統、各種新型資料庫,繞來繞去。但有一條沒變,他把它叫 database dogma:使用者宣告自己要什麼,怎麼做到是系統的事。你講你要什麼,系統自己想辦法生出來,順便保證資料不掉。

另一條沒變的是效能、可用性、耐久性之間的連動。他說,長時間的效能事件實際上就是一場可用性事件,因為延遲拉長到某個程度,站點就等於掛了;長時間的可用性事件,實際上就是一場耐久性事件。三件事綁在一起。

變的部分有兩層。一層是過去十年企業 IT 的體質:以前企業 IT 是買套裝軟體、順便裝一套資料庫,現在不是了。開源軟體把最佳實務帶進企業,企業 IT 自己就很會做,也會對資料庫要求更多。市場上也分成兩條路線,演化式的 scale up 系統,跟革命式的 scale out 系統;Bigtable 是二十多年前 Google 自己做出來的,Spanner 是另一個。

另一層是最近三、四年 AI 帶來的。結構化與非結構化資料開始被放在一起問,資料庫的工作就開始像搜尋,用學術的話說是資訊檢索(information retrieval)。精確結果不夠了,你要給的是最好的結果,相關性與排名變成第一等公民。他說,這不只是資料庫的事,當系統開始產出非確定的結果,你設計系統的方法就得整套換掉。

取捨也開始分家。掉幾個 click event 跟掉一筆金融交易,代價完全不同;有些系統可以選擇不同的約束,這本質上是成本、效能、延遲的取捨。資料庫不再有一套打天下的答案。五十年的契約沒有被廢掉,是第二句話正在被改寫。

Spanner:為了讓廣告系統離開分片倉鼠輪

Spanner 的起源是廣告系統。它大到必須分片,跑在分片的 MySQL 上;每年都要花大量時間想系統接下來要怎麼長,然後動手分片。到了 2008、2009 年左右,他們得到一個結論:等他們分完片,世界又變了。這是一個跑不完的倉鼠輪。

廣告是典型的企業應用。表有成千上萬張,而且不只一個應用。相對地,跑在 Spanner 上的一些消費性服務,DDL 打開來看,十五張、二十張表,盯著看還能看懂。

所以他們要的東西是三件一起來:企業應用的功能、Google 等級的規模、還有當時沒人解過的全球部署。強一致性、交易語意、次要索引,這些是關聯式資料庫的開發者視為理所當然的東西;把這些跟 scale out 的世界放在一起,之前沒有人解出來。Spanner 在 2012 年於 Google 內部進入正式生產,服務的就是廣告系統。

那一般開發者什麼時候該用 Spanner?他說得很乾脆:如果單節點就跑得動,Postgres 很好;需要一堆 replica,Postgres 也還撐得住。Spanner 給的是組合。同步的多區域配置、能隨時擴張也能隨時縮減的規模,還有多模:同一套系統裡有圖、有全文搜尋、有向量搜尋。

他也補了一句,Postgres 這幾年的演化裡,圖資料庫、全文搜尋也慢慢長進去了,所以這些能力最後可能大家都會有,Google 只是稍微早了一點。真正獨特的還是規模、跨區域,跟擴縮的容易程度。

Spanner Omni:一支 binary,沒有原子鐘的 TrueTime

Spanner Omni 要解的是「客戶不在 Google 機房裡」這件事。

第一個理由是銀行這類高度監理的客戶。他們要業務持續性,或者監理機關直接要求:萬一要「壓力退出」,你得有能力回到自己的資料中心跑。他轉述一位銀行客戶的抱怨:那位客戶要把系統從兩個半九(2.5 個 9)的可用性搬到四到五個九,不管單區域還是多區域都更好,結果監理機關要他解釋為什麼要搬。Krishnamurthy 說他也理解監理機關的立場,資料在多個地方有連續性確實重要;但這個「沒有選項」的缺口,實實在在擋住了客戶上 Spanner。很多人說我想押這個注,問題是我要怎麼拿到選項。

第二個理由跟 AI 有關:客戶在到處搶容量與基礎設施。雲端已經不是單極世界,有好幾家供應商,生態很熱。他也提到,以前的雲廠商連 hybrid 這個詞都不愛講,你在某些公司甚至不能用這個字;但客戶的現實不是那樣。客戶手上有很多基礎設施,有時是為了選項,有時是因為生意做大了就是靠併購與整合長出來的。錄音前幾週他在一場客戶諮詢論壇上,聽到一位客戶很激動地說,他們的皇冠珠寶會留在自己的資料中心。他認為這就是 2025、2026 年的現實:複雜、混亂,你得回應這個混亂。當然也有一種客戶,就是因為全世界找不到第二個像 Spanner 的東西,非要它不可。

工程上的故事更硬。在雲端,Spanner 是一堆 microservices 有機演化出來的,Google 自己知道怎麼操作。要讓別人自己跑,第一件事是把操作簡化:他們把所有東西收成一支 binary,你可以跑在筆電上、跑在某個部署裡、指定幾個節點就開跑。主要是 C++。他說聽起來很簡單,做起來非常難,整個團隊花了兩年,快得驚人。他開玩笑說,也許哪天 AI 會幫忙把它全部改寫成 Rust。

儲存層也得重新想。在 Google 內部,Spanner 站在 Colossus 上面。那是一個分散式儲存系統,分區(zonal)的服務,全世界沒有第二家有。靠著它,Spanner 要 split 或 merge、要擴出去的時候,只需要複製 metadata,不用搬資料;別人得留著資料的副本,於是在有負載的時候把資料搬來搬去。他把這個叫超級能力,也說這是 Spanner 與 Bigtable 比別人強的原因之一。出了 Google,這層就沒了,所以儲存要重新建模,用上一堆聰明的技巧。

再來是時間。要讓全域複製的系統跑分散式交易,你得對時間有辦法推理。Google 的作法是在資料中心放特製的硬體原子鐘,用來壓低他所說的 epsilon,也就是不同參與者時間之間的差。交易的語意取決於這個差:commit 要等多久、各個參與者的時間概念怎麼對齊。差壓得夠低,Spanner 在 Google 內部就跑得像飛。

那出了 Google 呢?他說外面的時間原語(time primitives)比十五年前好太多了,有一部分還是 Spanner 教會大家的;當然比不上 Google 機房裡的硬體鐘,但大概不會比 Google 自己在 2012 年的水準差到哪裡去,而 Spanner 就是為那個世界設計的。所以他們做了 Software TrueTime,可以跑在其他雲、也可以跑在舊的資料中心。有些面向不會跟在 Google 內部一樣好,但他相信對很多使用情境來說,夠用了。他還提到有客戶問:我們能不能在自己資料中心裝一樣的原子鐘?他的回答是「來談」。他說今天資料中心怎麼蓋,很多是來自 Google 過去二十幾年的功課,這些經驗會流到更大的生態裡;撇開他在 Google 的身分,他覺得這對整個產業是好事。

原生圖:在交易資料庫裡跑 PageRank

Spanner 現在可以讓你把資料直接當圖來用,而且不用搬資料。資料留在關聯式 schema 裡,你在上面疊一層:一行 DDL 建立 property graph,接著就能像查圖一樣查它。也可以選擇純圖的介面。查詢還是宣告式的,這點沒丟:幫我找出距離兩跳、三跳、四跳的所有節點。Database dogma 還在。

適合的場景都是關係很多的地方。基礎設施裡的 port 跟網路交換器、安全領域的使用者與帳號、trust graph、customer 360、詐騙偵測。他說最關鍵的好處是不用跑一條麻煩的 ETL,就能對營運資料問更複雜的問題,在原地問完。資料當然可以搬出去、用 pipeline 在某個地方問,但你想要那樣嗎?

圖演算法是後來的事。Google 在內部為了網頁相關的問題,做這些演算法做了幾十年,後來發現它們可以整批轉到客戶的圖問題上。詐騙就是最典型的一個:洗錢或合成身分詐騙,背後常常是一整片共謀的帳號網路。詐騙集團建出複雜的帳號與交易網路來模糊行蹤,而且一直在動。這是貓抓老鼠的軍備競賽。如果你的做法是把營運系統的資料搬到另一個系統再跑,詐騙集團早就移動完了。一筆一筆看交易,也看不到那個協同的全貌。

Spanner Graph 的作法是把帳號當節點、交易當邊,然後在系統裡直接跑社群偵測的演算法:weakly connected components、modularity clustering,找出彼此相關的帳號叢集。找到可疑叢集之後,要再往裡面找誰是關鍵角色,他直接說,這就長得跟 PageRank 一模一樣,實際上就是跑 PageRank。PageRank 當年是給網頁用的,但它在「找出網路裡最有影響力、最核心的節點」這件事上非常好用。於是你不只找到共謀的那一群人,還能看到其中的關鍵人物。

印尼的數位支付公司 DanaPay 就是用 Spanner Graph 做反洗錢。演算法直接在 Spanner 裡跑,不用等 ETL 週期,可以更快找到可疑網路、指認裡面的關鍵角色,而且能即時標記或阻擋交易,避免財務損失與後續的作業負擔。

他的收斂是這樣:一般交易資料庫不見得需要 PageRank,但你真正需要的,是對「新鮮營運資料裡的關係」有快速、可動作的情報。他也提到 SoundCloud,說他們跑圖演算法跑了幾年,都是批次在跑;很多時候大家以為那是唯一的方法。他還說,每次多給開發者一點東西,他們就會找出你沒預期到的用法。

Schema 之外,agent 要的是脈絡

以前專案裡第一個難題是選哪個資料庫、資料怎麼放。現在 LLM 什麼資料都吞,agent 還會自己寫查詢。所以 schema 設計還重要嗎?他很坦白:我們不知道所有會變的東西,這件事變得太快。但有一件事是確定的,為數龐大的既有應用不會一夜消失,而它們有迫切的需要被 agentic 應用用上。在你煩惱 schema 要不要改之前,更急的是怎麼把這些資料庫「點亮」。

他的講法是 agentic data cloud 有三塊。第一塊是 AI 原生的基礎設施:圖、向量搜尋、全文搜尋,因為結構化與非結構化資料正在合流。第二塊是把摩擦拿掉,讓世界沒有邊界:跨雲的 lakehouse、Spanner Omni、給 Postgres 應用用的 AlloyDB Omni。第三塊是信任,而信任的意思是脈絡:你得知道系統裡到底有什麼。

將近三十年前他在 DB2 團隊時,一直不懂 SQL 標準為什麼要讓你能替一個物件加上一段 comment。當時看起來很理論、很累贅。現在這東西有意思了,因為它可以記錄某個東西的意思;但現實一點講,他覺得不會有人真的靠 comment。你要另外想辦法蒐集 schema 的資訊。

他舉了兩個很小的例子。一張表裡有 billing address 跟 shipping address 兩個欄位,如果其中一個是 null,背後有一個沒有寫在 schema 裡的隱含知識:這兩個其實是同一個。那個知識要被抓出來,那才是關鍵脈絡。又或者有個欄位叫 city,值是小寫嗎?是三個字母的機場代碼嗎?一個要生成 SQL 的 agent,得先知道這件事。所以,schema 重要,但脈絡更重要;只有 schema 並不夠。

AI 會不會設計出不同的 schema?他不覺得。AI 會照人類過去設計的方式設計,因為它就是被那些東西訓練出來的,模型會傾向挑同一種結構。他也不太相信「生成者是 AI 還是人」會讓 schema 設計的通則產生根本變化。有人跟他說,他們現在沒那麼在意程式碼的抽象了,反正叫 AI 複製一份改一改就好;他覺得那條路通往更多混亂。

倒是應用的定義在變。今天一個應用有四面牆,有邊界、有 API 介面。新的世界裡,應用會變成免洗的 workflow,那個「應用資產」本身不存在。早上一個知識工作者進辦公室,手上有系統 A 跟系統 B,想湊出一張合併兩邊資訊的採購單。以前的作法可能是跟大型系統整合商簽約、付一大筆錢,半年後才有結果;現在他直接叫 AI 去做。而這些 agent 互動的軌跡得存在某個地方,這就是新的資料問題。系統也得更有彈性:出國前打電話給銀行設個詐騙警示,卡片才不會被擋;那如果你辭掉工作,決定在東南亞每個國家各待一週、三個月後再回來呢?你可能想要越南一週、寮國一週、柬埔寨一週,設二十個不同的警示。銀行系統大概會噎住,因為當初設計的人沒想過這件事。所以 schema 該不該更往前看、更有彈性?他把這當成一個還開著的問題。

寫入先提案,不要直接改

目前整個業界都很保守:大部分只做讀,因為大家都怕。沒有人想在自己家重演 Bobby Tables 那類事故,一句塞進去的查詢就把資料刪光;恐怖故事已經有了,安全與信任沒想清楚,壞事就會發生。

寫入難在哪?agentic 應用、這些免洗 workflow,要怎麼寫入、怎麼改 schema,他說並不清楚。他的提案是:當你要對資料庫做一個變更或修改時,不要真的做那個變更,而是產生一個「變更提案」(proposed change),它不會當場生效,可能要走過一組步驟。他認為資料被改、schema 被改的整套方式,都還會再修。

既有應用不會一夜消失,商業邏輯住在應用裡,所以還是得把它們接上這個新世界。

主持人在這裡補了自己的立場:他願意讓 agent 寫很多應用程式碼,但他在資料模型這條線畫下去。Agent 可以提案、可以試著做,但他會狠狠審一遍,用自己的經驗、對未來的判斷跟創意去壓力測試。Krishnamurthy 說這跟他的看法一致。資料模型這條線,目前還是留給人守。

PGVector 之後:filtered vector search 才是真問題

每個 AI 新創的技術棧看起來都是 Postgres 加 PGVector。Krishnamurthy 自己是 Postgres 的愛好者,當研究生時就寫過 Postgres 的程式;他說 PGVector 很棒,好用,整個 Postgres 的擴充生態讓實驗可以一直長出來,搭上 HNSW 演算法在很多情境下都很好用。

但 Google 做向量搜尋超過十五年了,YouTube 與搜尋的底層都有它。他們的技術叫 ScANN,樹狀結構的演算法,可以撐到一百億顆向量以上,延遲表現比單純的 HNSW 好得多。他們把 ScANN 放進 AlloyDB,並且讓它用起來像 PGVector;同時也保留原版的 PGVector,應用程式不用改,跑在 PGVector 上的東西也能跑在 ScANN 上。

數字是這樣:在他們的測試裡,向量查詢比標準 Postgres 上的 HNSW 快六倍,記憶體少用四倍。記憶體這件事對資料庫特別實在,省下來的會進到 buffer cache,效能又跟著好。他們也支援分散式索引建立,也支援 HNSW,還把一些 ScANN 的改進搬了過去。至於這些有沒有回饋到上游開源專案,他說他不確定,不想講不準確的話。

他把向量搜尋看成一種「ensemble」問題:有些情境 HNSW 就夠,而且更簡單;但最高階、最大規模的工作負載,真的需要 ScANN 這類東西。兩邊都有價值。

真正麻煩的是 filtered vector search。很少有人問一個純向量搜尋的問題,實務上查詢會帶多個條件:一個語意搜尋的條件打在向量索引上,另一個是一般的關聯式條件,例如目錄裡的價格。於是你得決定先探哪一個索引。先探向量索引(後過濾),可能拿到二十筆,套上價格低於五十塊,一筆都不符合;再要下二十筆,還是不符合,只能一直往下撈。改成先探非向量索引(前過濾),可能一次拿到一百萬筆,而一百萬筆根本跑不動最近鄰搜尋,那正是你當初做向量索引的原因。哪一種策略對,取決於選擇性,而你在事前不知道。

AlloyDB 的解法是把兩個索引放在同一個系統裡,所以它可以同時探兩邊,很快判斷哪個順序對,並且在過程中隨時換策略。主持人問這算不算分而治之,他說不算,這是一種自適應的技巧:先試幾種,再依你當下的實際狀況調整。

他也不建議另外外掛一套純向量的系統。如果只是對一批不太變動的文字語料做純向量搜尋,那或許合理;但只要開發者蓋完這種系統,幾毫秒之後查詢就會變複雜。向量系統一旦分家,你就要在應用層把兩個系統縫起來,而前過濾、後過濾要誰來做?他說純向量系統對這件事沒有好答案;多個索引在同一套系統的控制之下,才做得出這種聰明的東西。他們另外也把高速向量檢索跟營運資料上的全文搜尋合在一起,混合搜尋(hybrid search)就變得有意思了。

MCP Toolbox 與 managed MCP:兩條路

Google 釋出了 MCP Toolbox for Databases,開源,本質上是一台架在資料庫上面的 MCP server,AlloyDB、Cloud SQL、Spanner 都能接,開發者不用自己從頭刻。另外也有 managed MCP 服務,企業等級、有治理機制。

他自己的團隊是在做資料庫跟基礎設施的,不太用 MCP;但有個地方會用,就是使用者介面。Google Cloud 的代管資料庫本身也是一個應用,實例與資料庫的資訊存在內部的 Spanner 裡。以前每次做一個新功能,就得做一大堆複雜的 UI;現在他們改成連上 MCP 服務,依使用者問的問題即時生成介面。他說這不只是省時間,還能生出更貼著使用者需求的體驗。他也補充,這個 Generative UI 沒有正式的對外名字,他不小心用了內部的專案代號;類似作法在資料庫 console 的觀測性功能裡已經有了。

機制是這樣:他們的 UI 基礎設施本來就有一堆 widget,於是一邊把底層系統接上 managed MCP,一邊把這些 UI widget 也包成 MCP 工具,模型就能自己決定要怎麼組合。他說任何客戶都可以做一樣的事。真正麻煩的地方,還是回到那個老問題:什麼是讀、什麼是寫,以及你有多準備好讓 agent 寫進營運資料庫。

兩種開發者走兩條路。走在最前線的開發者會用 MCP Toolbox,因為他們需要自訂的身分驗證機制,可能還跑在自己的機房、根本不在 Google Cloud 上。Toolbox 一開始要解的問題就是:不管你人在哪裡,都讓你更容易接到資料庫;開放性是 agentic data cloud 的一部分。在 Google Cloud 裡,managed MCP 是另一條路:控制平面的操作(agent 去建資料庫、跑應用、部署應用)、還有自訂工具(不是下 execute SQL,而是像「查一個航班」這種工具,背後去跑一句特定的查詢)。他也說,他們在 Toolbox 上學到的東西,只要有價值,就會進到 managed MCP。

讓 LLM 接上正式資料庫:PSV、隔離、觀測

主持人開場就說,一個 LLM 接著你的正式資料庫,這是一個等著發生的恐怖故事。Krishnamurthy 的答案從一個對比開始:分析型系統跟營運型系統是兩個世界。

分析型系統裡,進來的人可能是商業分析師或資料科學家,用自己的憑證連線,存取控制長在系統裡,他們通常能看到比較廣的資料,而且 BI 查詢本來就是聚合查詢。營運資料庫不是這樣。1990 年代初期,主從架構的胖客戶端直接連資料庫,終端使用者的憑證真的在裡面;到了 1990 年代後期,網頁與三層式架構把這件事徹底改掉。今天在營運資料庫的 schema 裡,根本沒有終端使用者這回事。資料庫有使用者、角色、群組、權限,但終端使用者不在裡面。原因之一是人數:有了網頁之後,終端使用者從幾百個變成幾千個、幾百萬個、上億個,你沒辦法那樣管。於是應用程式用一個 service principal 連上資料庫,某個登入使用者能看到什麼,是散在應用程式各處 SQL 的 WHERE 子句決定的。

現在你讓一個 agent 用這個看得到全部資料的 service principal,替任何一個使用者問問題,問題就來了。他舉例,一家租車公司如果有兩千個分店,每個店經理應該只能問自己店裡的車。

解法是 parameterized secure views,PSV,建築在 Postgres 的 secure view 上。Postgres 的 secure view 有一個 security barrier 的特性:沒有它的話,你可以用資訊理論的手法把資料挖出來。作法是寫一個會讓系統爆掉的查詢,例如帶 WHERE 子句的除以零;沒擋住的話,查詢優化器會太聰明,把條件推到表裡面去,於是你得到一個錯誤、或得到一個空結果,而那個錯誤本身就洩漏了資訊。security barrier 確保條件不會被推進表裡。

PSV 再往前一步:加上參數。這個參數基本上就是原本散在應用程式 WHERE 子句裡的那道授權檢查,只是現在你把它定義在 schema 旁邊的 DDL 裡。Agent 用的 service principal 只碰得到 PSV,碰不到底層的表;登入使用者的憑證從一條側通道進來,綁到那個參數上。你可以攻擊 LLM、可以騙它、可以讓它生出任何它想生的查詢;查詢送到的時候,它永遠只會看到那個使用者的憑證允許它看的那些列。他說這是關鍵的基礎設施,沒有它,做不出 agentic 應用需要的那種安全。主持人把它翻成一句話:你不需要把角色塞進資料庫,是把原本寫在應用程式裡的查詢,搬進 DDL。

他還把這件事接回 1975 年的一篇經典論文,end-to-end argument in system design。他在 Berkeley 開始讀博士時讀到,論文的意思是:分散式系統要談加密、談安全,你得在系統的兩端解決,不能在管子裡解決。同樣的道理搬到這裡,安全得坐在資料那一層,因為我們活在一個 agent 什麼都做得出來的非確定性世界。

另一半是隔離。分析查詢打交易資料庫本來就會互相傷害,這也是為什麼大家會把資料卸載出去;Google 花了很多年處理這件事。他轉述一位銀行客戶的反應:我們花了好幾年確保批次掃描不能打在營運資料庫上,現在你要我在上面跑 agent?你瘋了嗎?他說這問題問得對。Agent、甚至一整群 agent 在問問題,同一堂課還是要再上一次:agentic 應用要被隔離。而且可能更麻煩,因為 agent 不好控制,它會跑爛查詢,也會跑惡意查詢。

再來是觀測。他說你需要的觀測性要細到這種程度:你能不能對著你的 Postgres 資料庫問,把 agent 來的查詢跟應用程式來的查詢分開列給我。有了這個,才談得上在周圍架護欄。主持人說這幾乎就是對資料的即時威脅偵測。

誰 commit 誰負責,然後接受混亂

主持人提到他先前的說法:Google 的工程師想用多少 AI 都可以,但程式碼是誰 commit 的,責任就歸誰;節目裡也提到,Google 現在大約有四分之三的新程式碼是 AI 生成的。Krishnamurthy 的反應很老實:三個月後會怎樣,他真的不知道。但他確定一件事,六個月前的先驗假設現在該重新檢查一遍,能做的事情比大家想的多。

不過數字要小心,因為變異非常大,取決於你在講哪一種程式碼。他的直覺是:像 Paxos 這種分散式共識協定,也就是 Spanner 的心臟,大概還是很難讓 AI agent 直接大改,他們也會非常小心。而「AI 生成的程式碼」是一個連續光譜:一端是在 IDE 裡做例行重構;另一端是一整個 pull request、一整塊自成一體的程式碼,而寫的人從頭到尾沒有進過 IDE。

他們在團隊裡的做法是因材施教:針對每一群做同一件事的工程師,建對應的 harness 與技能,然後量測。就像 AI 與 agent 世界裡的每一件事,關鍵是 evals:你需要一個客觀的方法知道它到底有沒有在動。他說這對大部分人應該都適用。

還有一件事他特別強調:留空間給實驗。挑一個專案,專門用來推你在 AI 上能推到多遠。撞到瓶頸的時候,工程師的慣性反應是切回原本的做法,把問題解掉,因為我們被要求的本來就是把事情做完;但他認為也需要有一部分努力是這樣:撞到瓶頸就修瓶頸,不要繞過去,並且接受交付會變慢。

最後他給的那個總結是這樣。他們花了二十五年學怎麼蓋確定性、可規模化的系統,確定、可預測幾乎變成信仰。現在是一個不同的時代,資料是亂的、不再確定。他觀察到很多人像在走悲傷的五階段:一開始都在吵怎麼把 AI 弄成確定性的,他覺得那條路不會成功。兩個世代的軟體工程師都照舊方法訓練出來,產業得接受自己身處混亂,然後與它共處。至於怎麼在混亂裡看懂事情,還是回到他前面講的:用 evals 去看品質與商業結果。因為資料庫真正變掉的那件事是結構化與非結構化資料一起進來,而它要交付的東西,已經從精確結果變成最相關的結果。主持人接話說,已經沒有對或錯的答案,只有一片相關性的光譜。Krishnamurthy 說,對,而我們全都還在那片光譜上的某個位置。