Skip to content

AI tooling 逆轉:接駁搞掂咗,架構先係戰場

17 min read · AI Agents ·記憶粒度 ·工具鏈設計

分享

半年前我寫過 香港 AI setup 嗰篇,講電話號碼、DNS routing、點樣過 payment。嗰陣嘅 bottleneck 係地理 — 你連工具都用唔用到?

呢家呢個問題搞掂咗囉。$5 VPS 加 Shadowsocks,接駁平到笑,周圍都係工具。但搞掂接駁冇令件事變簡單,反而浮咗下一個問題上嚟。當你邊個 model 都叫到、邊個 agent 都 run 到,難題就由「接唔接到?」變成「邊樣駁邊樣,邊個話事?」一個 bottleneck 消失,跟住有十幾個 coordination 問題補上個位。

呢個就係 inversion。Failure mode 由外面搬咗入 environment 入面。接駁搞掂咗,orchestration 同 trust 先係硬嘢。好似我喺 Agents Need Architecture, Not Prompts 講過,真正嘅 failure 唔係嚟自你個 prompt 寫咗啲咩,係嚟自你個 architecture 俾唔俾佢咁做。我而家講緊嘅 stack,就係我認真對待呢句說話、再擺落自己環境度之後,長出嚟嘅嘢。

Inversion 係慢慢嚟㗎。每多一樣能力,就拆走一個外部限制,跟住露出一個內部限制。Payment workaround 搞掂咗,叫到 model;叫到 model 就發現一個 agent 頂唔順幾個 context。拆開咗 agent,又發現一個 memory system 應付唔到三種 recall。拆開咗 memory,又發現 toolchain 本身要分類。每個解法都製造下一個問題,stack 就係咁一路長大。

跟住有四個 bottleneck 推住成個 stack 變大,一個跟一個:context collision,一個 system prompt 想包攬全部,啲 domain 互相滲透。memory fragmentation,一個 embedding store 答唔到三種唔同問題。tool sprawl,runtimes、models、subscriptions 愈嚟愈多,隨時擺錯類。trust ambiguity,local 同 hosted 嘢並排擺,又冇清楚邊界。

以下就係最後長出嚟嘅 stack。紙上睇落好複雜,三個 agent profile、三個 memory system、model router、orchestrator、一個 ADE,仲有包晒 runtimes、models、subscriptions 嘅 toolchain。但每一層都唔係因為我鍾意收集,係因為試過更簡單嘅方法,爆咗,先至有佢。

一個 Agent,拆成三個 Profile

臨界點係一個 system prompt 想包攬全部 — ops instruction、writing style guide、social media persona、nutrition tracking logic,全部互相拉扯。

單一 agent 搞唔掂,主要有兩種污染。第一種,social context 滲入 private ops decision。之前傾偈嗰種語氣,會滲入 infrastructure command。Agent 冇 crash,但 output 睇落啱、實際差少少 — 最難捉嗰種 failure,冇人 alert 你,要事後先發現某個決定畀錯誤 context 軟化咗㗎。

第二種,nutrition 嘅專屬 logic 同 governance rule 相撞。Calorie tracking 同 deployment policy 擺埋同一個 prompt,兩邊都攞唔到 full attention。System prompt 變成幾個 concern 喺度傾判,agent 輸咗呢場談判,但係事後先發現。

context collision

Single System Prompt
ops + writing + social + nutrition

Contamination:
social leaks into ops
nutrition collides with governance

Split into three profiles

Norty
private, full access
governance / coding / ops / infra
OmniRoute → GLM 5.2

Nora
public-facing
community, friend circles
SearXNG + Firecrawl

Bento
single-purpose
nutrition tracking
Telegram + SQLite

解法係結構性嘅:唔同 concern 用唔同 agent。System prompt 做唔到 boundary。跨 domain 共用一個 prompt,agent 個 context 就會漏 — 無論你寫幾小心,domain 都會互相滲透。Prompt 可以講「唔好溝亂」,但結構上拆開先至真係溝唔到。

於是我將一個 agent 拆成三個 profile,每個都係 Hermes(Nous Research 開源嘅 agent framework,係成個 stack 嘅 orchestrator)嘅一個配置。唔係獨立 program — 係唔同 personality、唔同 tool access,但跑同一個 runtime。

Norty 係 private、full-access 嗰個。Governance、coding、ops、infrastructure。OmniRoute 做 routing,default 模型係 GLM 5.2,經 Ollama Cloud Pro serve。Norty 有晒所有 key,因為佢嘅 scope 就係我搞同埋 operate 嘅全部嘢。冇 social context、冇 nutrition logic,淨係做嘢。

Nora 係 public-facing:community、friend circle、有限度工具。SearXNG 做 search、Firecrawl 做 web scraping。Nora 唔係 Norty 減少啲權限 — 佢係獨立 persona,有自己角色。限制 tool 先係重點。Nora 唔使 infrastructure access,俾佢就係等緊 scope breach 發生咋。

Bento 單一用途:nutrition tracking。Telegram interface、SQLite database。冇 model routing 嘅複雜嘢、冇 governance rule、冇 social media。Bento 淨係識 calories 同 macros,其他唔識。Bento 做決定嗰陣,冇可能畀 ops context 或者 writing style guide 影響 — 呢啲 context 喺 Bento 個世界根本唔存在。Bento 冇嘅嘢,想漏都漏唔出。

每個 profile 有自己嘅 toolset。Profile 用到咩 tool,就決定到佢做得到咩,上面冇另一層 permission system。Tool list 本身就係 boundary。呢度 stack 第一次撞到兩道結構牆:authority — 邊個做得咩 — 同 scope — 點樣阻止 context 互相污染。拆開 profile,係因為一個 agent 想包攬全部,結果邊度都唔可靠。

Memory 分三層

拆開 profile 解決咗 context 污染,但浮出下一個 bottleneck:memory。

單一 memory system 應付唔到三種唔同 recall。Flat embedding store 為 conversational similarity 而設,你問「三個月前點解咁決定架構?」,佢會返最語義相似嗰段對話,但可能係完全另一個 project 啲相似字眼。Codebase 結構同決定時間線,佢睇唔到。最慘唔係佢返唔到嘢,係返啲似模似樣但錯嘅嘢。

Agent 需要三種 recall:跨 session 嘅對話連貫、對 codebase 結構嘅理解、同埋對過去決定嘅時間推理。呢啲係唔同問題,一個 memory system 包唔晒。所以 stack 有三個,各管各 recall。

Honcho 處理跨 session 對話 memory。Self-hosted,Docker 跑,peer-based,有 dialectic reasoning,答到「上個禮拜傾過啲咩?」直接 integrate 落 Hermes,每個 profile 跨 session 都連貫到,又唔會漏 context。Conversation memory 唔會話畀你知個 function 喺邊個 module,因為佢根本唔係為此而生。

Graphify 處理 code structure indexing。佢用 graph-based knowledge representation 去呈現 codebase,邊個 function call 邊個、邊個 module 依賴邊個、boundary 喺邊,都睇到。取代咗已經 deprecated 嘅 Codebase-Memory MCP。Coding agent 改嘢前要理解架構,Graphify 就俾個 map。但 code indexing 重構唔到上個禮拜嘅 reasoning — 佢識結構,唔識歷史。

Graphiti 處理 temporal knowledge。Zep 搞嘅,bi-temporal knowledge graph,底層 Neo4j,追蹤 valid time(幾時係真)同 system time(幾時學到)。填補咗另外兩個碰唔到嘅 gap:某個時間點 knowledge 嘅狀態,包括點解咁決定,當時已知啲咩。但 temporal knowledge graph 載唔到而家呢個對話 context — 佢為跨時間 reasoning 而生,唔係 session 內連貫。

呢三個唔係同一個問題嘅競爭解法。係三個系統處理三種唔同 recall,似人一個腦入面 short-term、long-term、procedural memory 咁。每個都存在,係因為叫一個 memory system 包三樣,佢會返啲似模似樣但錯嘅答案。

Toolchain 係 Topology,唔係 List

Profile 拆完、memory 專業化之後,下一個 bottleneck 浮現:tool sprawl。零件愈嚟愈多,runtimes、models、subscriptions、router、orchestrator、ADE,數出嚟但唔講關係,就會擺錯類。Model 唔係 runtime,subscription 唔係 router,orchestrator 唔係以上任何一樣。問題由「stack 有咩工具?」變成「邊樣駁邊樣,邊樣唔駁?」

以下係 agent layer 嘅每個 component,按類別同職能分好。

組件類別職能
Claude Code CLIRuntime/CLI主力開發、deep reasoning、多檔案修改
Kimi Code CLIRuntime/CLI後備、快速 patch、外部 review
OpenCode CLIRuntime/CLI跨 provider 開源 coding agent(MIT,~165K GitHub stars)
Codex CLIRuntime/CLI淨係驗證同 code review,留 audit path
GLM 5.2ModelNorty default 模型,經 Ollama Cloud Pro serve
Kimi K3ModelZero-shot coding 模型,經 Kimi Code CLI 喺 Allegro plan 用到
MiniMax M3Model次要幫手,1M-token context,經 direct API 同 OpenCode Go
OpenCode GoSubscription$10/月,14 個模型,同所有 provider 簽咗 ZDR
Ollama Cloud ProSubscriptionHosted Ollama 層,serve GLM 5.2 同 open-weight 模型
Claude Max 20xSubscription$200/月,解鎖 Claude Code
Kimi AllegroSubscription$99/月,解鎖 Kimi Code
OmniRouteModel RouterSelf-hosted 喺 localhost:20128,按 task 同 cost 路由
HermesOrchestrator管理 profile、memory、cron、多平台 gateway
OrcaADEParallel agent 喺獨立 git worktree,自備 agent CLI
CortexEditorial pipeline第二個獨立 OmniRoute consumer,同 Hermes 分開

分類避免 category error。OpenCode CLI 係免費 MIT-licensed runtime。OpenCode Go 係付費 subscription,同個 brand,唔同類。OmniRoute 係 router,唔係 runtime。Orca 係 ADE,唔係 IDE。Model 唔係 runtime;subscription 唔係 model。全部壓扁做一個 list,會搞到 topology 睇唔明。

但分類有意思,係因為彼此之間嘅連線。

routes via

routes via

to

spawns

spawns

spawns

billed directly

billed directly

billed directly

MCP inside

standalone CLI

GitHub app

Norty

Hermes

Nora

Bento

OmniRoute

Cortex

GLM 5.2, DeepSeek V4, Kimi K3, ...

Orca ADE

Claude Code
primary

Kimi Code
secondary

OpenCode CLI

Anthropic

Kimi Allegro

Various providers

Codex
review-only

Direct review

PR trigger

三個 profile 都係 Hermes 嘅 configuration。Profile 需要 model 嗰陣,Hermes call OmniRoute,由佢按 task 同 cost 揀 provider 同 model。Cortex — 即係撐起呢個網站內容 workflow 嘅 editorial 同 radar pipeline — 係第二個獨立 OmniRoute consumer,唔經 Hermes。Hermes 同 Cortex 係兄弟,唔係鏈。

Orca 喺獨立 git worktree 入面 spawn 啲 coding CLI 做 parallel agent。Claude Code 係 primary:deep work、多檔案 project。Kimi Code 係 secondary:快速 patch。OpenCode CLI 係跨 provider 後備。每個 coding CLI 直接 call 自己 provider:Claude Code → Anthropic(Claude Max 20x)、Kimi Code → Kimi Allegro。呢啲唔經 OmniRoute route,係 vendor 產品,用自己 subscription。

Codex 淨係做 review,有三個 surface:Claude Code 入面嘅 Codex MCP 做 in-session review、standalone CLI 做 direct review、同埋由 PR event 觸發嘅 GitHub app。第三個 surface 值得留意 — 由 repository event 觸發,唔係 stack 入面邊個 component 叫佢。冇 component invoke 嘅 reviewer,駁住 repository event 而唔係 call graph。

Coding 層級:Claude(primary)> Kimi(secondary)> Codex(次要,淨 review)> MiniMax M3(次要,broad-context 幫手,唔係日常主力)。

跟住係 non-edges — 同 edges 一樣重要,因為 topology 就係為咗防止呢啲錯誤而存在。

OmniRoute 唔 route 啲 coding CLI。 佢哋係 vendor 產品,用自己 subscription。OmniRoute 只 serve 我自己整嘅嘢 — 經 Hermes 嘅 profile 同 Cortex — 唔 serve 我買返嚟嘅嘢。

冇嘢 call Orca。 佢係人手操作嘅 environment,唔係自動化鏈入面嘅 service。Orca 對外 spawn CLI;冇嘢 call 入嚟。

冇 OmniRoute → Orca → Codex 呢條 pipeline。 呢三樣喺唔同平面:router、人手操作 environment、同 reviewer。佢哋唔會串埋。

Topology 嘅存在唔係因為我鍾意收集零件,係因為 tool sprawl 逼出結構性答案。當 runtimes、models、subscriptions、router、orchestrator、ADE 全部上場,唯一唔亂嘅方法係清楚知道每樣係咩、駁邊樣、唔駁邊樣。IDE 係俾你用。ADE 係俾你同你啲 agent 用。 呢個就係 Orca 嘅分別。IDE host 你個 session。ADE 平行 host 多個 agent session,每個喺自己獨立 worktree,有自己 runtime 同 model assignment。

Trust 係 Boundary,唔係 Feature

第四個 bottleneck 係 trust ambiguity。Local 同 hosted component 並排擺,冇清楚 boundary,預設就變成「全部 private」或者「全部 exposed」,兩個都錯。

Stack 橫跨兩個世界。有啲 component 喺本地 GMKtec NucBox M7 Ultra 跑,呢部係 AMD Ryzen 7 PRO 6850U mini PC,有 64GB DDR5。有啲係 hosted service,有自己政策。Boundary 唔係你 toggle 嘅 feature,係每個 component 擺喺邊、搵得到咩嘅結構特性。

組件擺喺邊跑Trust 模式
Ollama BGE-M3Local完全 private,淨係做 embedding,冇 internet route
OmniRouteLocal (router)橋接兩邊,按 task 路由去 local 或 hosted
OpenCode GoHosted (third-party)視乎 service,同所有 provider 簽咗 ZDR
Claude CodeHosted (Anthropic)視乎 service,受 Anthropic data policy 規管
Kimi CodeHosted (Moonshot)視乎 service,受 Kimi data policy 規管

Ollama BGE-M3 真係本地跑,處理 semantic search 同 code indexing 嘅 embedding,冇 internet route。呢個先係 private 喎。OpenCode Go 係 hosted service,model inference 行佢哋 API,雖然佢哋同所有 provider 簽咗 zero data retention,但 trust model 同本地 process 唔同。OmniRoute 橋接兩邊:可以按 task 路由去本地 Ollama 攞 embedding,或者去 hosted backend 做 inference。Stack 冇 blanket「zero data retention」嘅聲明,每個 service 有自己政策。重點係分得清邊個係邊個。

Trust boundary 喺 profile level 都執行緊。每個 profile 嘅 toolset 決定佢搵得到咩,toolset 本身就係 trust perimeter。Norty 有 full access,有晒所有 key,配合佢嘅 scope。Nora 淨係有 SearXNG 同 Firecrawl,public-facing,冇 infrastructure access。Bento 淨係有 Telegram 同 SQLite,trust perimeter 最細,搵唔到 model 同 infrastructure。

對外 access-control layer 係一體嘅:Cloudflare Tunnel 加 Google SSO,Google Workspace 做 identity provider。cloudflared 向外駁去 Cloudflare edge,冇 inbound port,冇嘢喺 public interface 度聽。Cloudflare Access 坐喺前面,淨係經 Google Workspace authenticate 到嘅身份先過到。Free tier,最多 50 個 user。

Trust 唔係一次過 set 好嘅設定。係每層都劃嘅 boundary:component 喺邊跑、profile 搵到咩、network 俾咩入嚟。Stack 唔會 blanket 聲稱幾 private,係劃清楚每條 boundary,每條都有原因。

撞過嘅牆,砌出嚟嘅樣

Stack 睇落好複雜。三個 profile、三個 memory system、runtimes 同 routers 同 subscriptions 嘅 topology、多層 trust boundary。自然會問:點解要搞到咁複雜?

答案唔係個人偏好。係每個 multi-agent setup 遲早都會撞到嘅三道結構牆。

Authority 係第一道牆。邊個做得咩?一個 agent 有晒 access,問題好簡單,答案係「全部都得」。但一拆開 profile,authority 就變成設計問題。Norty 可以 deploy infrastructure,Nora 唔得,Bento 連 model 都搵唔到。Tool list 就係 authority boundary,要結構上執行,唔係靠 prompt 講「唔好用呢啲 tool」,而係 configuration 令到佢根本用唔到。

Scope 係第二道牆。每個 agent 揸住咩 context?單一 prompt 失敗,係因為 scope 漏。Social context 滲入 ops,nutrition 同 governance 相撞。拆開 profile 解決咗 agent level 嘅 scope,但浮出 memory level:一個 memory system 應付唔到三種 recall。Scope 唔係淨係隔開啲 agent,係要令每個 component 淨係揸住佢需要嘅 context,其他唔好揸。

Verification 係第三道牆。點知 output 啱唔啱?一個 agent 包攬全部,verification 就係隨心,你睇完覺得啱就算。多個 agent 互相餵 output,verification 就要有結構。Codex 存在係做 review-only 路徑,同 primary coding CLI 分開。Topology 入面啲 non-edges — OmniRoute 唔 route coding CLI、冇嘢 call Orca、冇 OmniRoute → Orca → Codex pipeline — 就係 verification boundary。確保寫 code 嘅 component 同 review 嘅唔係同一個。

三道牆對應四個 bottleneck。Context collision 係 scope 問題,domain 互相滲透因為 boundary 係 prompt 而唔係結構。Memory fragmentation 係另一個粒度嘅 scope 問題,一個 store 要應付三種 recall。Tool sprawl 係 authority 問題,component 冇分類、邊緣唔清楚,你就唔知邊個搵到咩。Trust ambiguity 係 authority 同 verification 問題,local 同 hosted 冇清楚 boundary、profile 冇 tool scope,你就係度估咩係 private。

呢啲牆唔係 bug。係無論你認唔認都要面對嘅限制。Stack 就係當你唔再繞路,開始順住佢哋起嘢,就會出現嘅嘢囉。

呢篇講完 stack。下一篇會講正面撞埋道牆會點:failure mode、設計決定、同 authority、scope、verification 變成 first-class concern(而唔係事後諗返起)嗰陣會出現嘅 pattern。

分享