讓不可見變得可見:Agent 對話 UI 的元件設計哲學
傳統聊天只需要顯示文字泡泡,但 AI Agent 對話要讓使用者看見思考、工具呼叫、引用來源和執行進度——我們用 12 個 Vue 元件、三種 DisplayMode 和一條 chatBlocks 渲染管線解決了這個問題。
傳統聊天只需要顯示文字泡泡,但 AI Agent 對話要讓使用者看見思考、工具呼叫、引用來源和執行進度——我們用 12 個 Vue 元件、三種 DisplayMode 和一條 chatBlocks 渲染管線解決了這個問題。
使用者在後台把檢索 top_k 設成 15,但監控面板顯示 5、串流 UI 先閃 5 再跳 15。根因是同一個 top_k 值存在於四層——LLM 工具參數、執行時 runtime、trace DB、串流 payload——每層都要個別 override。三次修正,每次修完才發現下一層也錯。
OMP 的 Agent stream 不只是把 token 往終端機吐:它把 agent、turn、message、tool execution 分成不同層級的事件。理解這個事件契約,才能在 UI 顯示增量文字、工具進度與錯誤,同時不把暫存中的 partial message 誤當成已提交的對話。
pi-agent-core 的心臟:agentLoop() → runLoop() 雙層 while(true)。Inner loop 處理 tool calls + steering messages,Outer loop 處理 follow-up + prepareNextTurn(compaction、model switch)。Enter = steering(當前工具跑完插入)、Alt+Enter = follow-up(agent 判定結束插入)。streamAssistantResponse() 如何處理 partial message 更新、tool call 解析、parallel/sequential 執行、before/after hooks。
SSE 以普通 HTTP 傳送 text/event-stream,瀏覽器原生重連並帶 Last-Event-ID;簡單不代表自動 durable,server 仍要保存 cursor 後的事件。
AI SDK v5 把一則 AI 訊息拆成 parts 陣列——text、reasoning、source-url、tool-* 各自是獨立片段。這個資料結構決定了現代 AI 對話介面怎麼寫:render 時 switch part.type,每種片段交給對應元件。這篇拆解 parts 模型的設計邏輯、useChat 的串流機制,以及它如何成為 AI Elements 這類元件庫的地基。
Agent loop 是每個 session 序列化的執行。最值得學的是它處理並行的方式:每個被接受的回合會記下 activeWriterRunId 宣告,之後每次逐字稿寫入都要附上 expectedWriterRunId,在交易裡比對——被取代的回合因此無法提交過期資料。
聊天機器人不只是接 API。對話狀態管理、記憶機制、Streaming、Guardrails、可觀測性、tech stack選型,每一層都影響使用者體驗。
LLM 生成需要 3-5 秒,等全部生成完再顯示體驗很差。SSE 讓 token 一邊生成一邊推送,首個字元出現時間從 5 秒縮到 1 秒以內。