模型 / 資料集
langchain-ai/agent-chat-ui avatar
langchain-ai/agent-chat-ui

Agent Chat UI:用 Next.js 前端接上任何 LangGraph 伺服器

🦜💬 Web app for interacting with any LangGraph agent (PY & TS) via a chat interface.

3,155 個 Star688 個 ForkTypeScriptMIT

秒懂

它是什麼?
LangChain 官方釋出的聊天前端,把 LangGraph 的 messages 狀態直接映射成對話介面。本文拆解它的連線機制、artifact 側欄設計、生產環境的認證取捨,以及什麼情況下你應該自己寫 UI。
適合誰用?
如果你已經有一個跑得起來的 LangGraph 伺服器,只是想盡快看到對話效果,Agent Chat UI 是最短路徑:npx create-agent-chat-app 之後填三個環境變數就能用。但它的預設連線方式是從瀏覽器直連 LangGraph,README 明講這在生產環境行不通,因為那要求每個使用者自己持有 LangSmith API key。
可以商用嗎?
可以。MIT 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
還在維護嗎?
有在維護。儲存庫最近一次提交在 1 天前。
用什麼語言寫的?
主要是 TypeScript(依據 GitHub 的語言統計)。

以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。

開源專案深度解析

它解決的是 LangGraph 專案的「最後一哩」問題

寫完一個 LangGraph graph,你手上有的是一個跑在 2024 埠的伺服器,以及一串可以用 curl 或 SDK 呼叫的 API。要把它變成別人能點開來用的東西,中間隔著一整個前端:訊息串流、tool call 的呈現、執行狀態、多輪對話的 thread 管理。Agent Chat UI 就是把這一段補起來的 Next.js 應用。README 的定義很直白:一個能與任何透過 messages key 溝通的 LangGraph 伺服器對話的聊天介面。

關鍵在「任何」這兩個字。它不綁定特定 agent 的邏輯,不假設你的 graph 長什麼樣,只要求你的狀態裡有 messages 這個欄位。這讓它的適用範圍比一般範例專案寬:你寫的是 Python 還是 TypeScript 的 graph 都無所謂,因為它只透過 LangGraph 伺服器的協定溝通。

目標讀者因此相當明確:已經在用 LangGraph 開發 agent、需要一個現成介面來驗證行為或給內部同事試用的人。如果你還沒決定要不要用 LangGraph,這個專案對你沒有意義,它是一塊拼圖,不是起點。

連線設定的三個欄位,決定了它是 demo 還是產品

啟動之後,UI 會先要你填三樣東西:Deployment URL、Assistant/Graph ID、LangSmith API Key。第三項只在連接已部署的 LangGraph 伺服器時才需要,用來對請求做認證。另外有一個 Built with Agent Builder 的開關,打開後會自動把認證方案設成 langsmith-api-key。

這三個值可以用環境變數預先塞進去,跳過表單:

NEXT_PUBLIC_API_URL=http://localhost:2024 NEXT_PUBLIC_ASSISTANT_ID=agent NEXT_PUBLIC_AUTH_SCHEME=

README 給的流程是複製 .env.example 成 .env,填好值,重啟應用。這三個變數都帶 NEXT_PUBLIC_ 前綴,意思是它們會被編進前端 bundle、在瀏覽器裡可見。對 API URL 和 assistant ID 來說沒問題,但這也解釋了為什麼生產環境不能照抄這套設定:認證用的 key 不該出現在前端。

值得一提的是 Assistant/Graph ID 這個欄位。它同時接受 graph 名稱和 assistant ID,對應到 fetch 與提交 run 時的識別方式。這個彈性在本地開發很方便,但也意味著你必須清楚自己的部署裡有哪些 graph 是對外可呼叫的。

langsmith:nostream 與 do-not-render 解決的是兩種不同的問題

Agent Chat UI 預設用 on_chat_model_stream 事件來即時渲染訊息。有些情況下你不想讓使用者看到中間過程,README 提供了兩層控制,而且這兩層的語意差別很重要。

第一層是加上 langsmith:nostream 標籤。以 Python 為例,透過 .with_config 掛上去:

model = ChatAnthropic().with_config(config={"tags": ["langsmith:nostream"]})

TypeScript 版本對應的是 .withConfig。效果是那個模型不再發出串流事件,畫面上不會逐字浮現。但 README 特別註明:如果這則訊息最終被存進 graph 的 state,呼叫完成後它還是會出現。所以這只是延後顯示,不是隱藏。

第二層才是真正的隱藏。做法是在訊息進入 state 之前,把它的 id 前面加上 do-not-render- 前綴,同時在模型配置上掛 langsmith:do-not-render 標籤。UI 會明確過濾掉任何 id 以此開頭的訊息。文件裡的範例是 result.id = f"do-not-render-{result.id}",然後才 return 進 messages。

這個設計的意涵是:可見性由後端決定,前端只是被動過濾。好處是控制權留在 graph 作者手上,壞處是你得記得在正確的時間點改 id,一旦訊息已經寫進 state 就來不及了。這種「約定式」的隱藏機制,比提供一個正式的 API 來得脆弱,但它不需要前端配合改動。

Artifact 側欄:一個 hook 換來右側的完整空間

聊天介面的天生限制是寬度。要呈現文件、程式碼、報表這類長內容,塞進對話氣泡裡會很痛苦。Agent Chat UI 的解法是把 artifact 渲染在聊天右側的側欄。

機制是從 thread.meta.artifact 取得內容。README 提供的 useArtifact hook 內部呼叫 useStreamContext,型別標註為 MetaType: { artifact: [Component, Bag] },回傳 thread.meta?.artifact。取出來的是兩個東西:一個元件,以及包含 open、setOpen、context、setContext 的狀態包。

實際用法是這樣的:元件內先解構 const [Artifact, { open, setOpen }] = useArtifact(),然後自己畫一個可點擊的卡片,點擊時呼叫 setOpen(!open),再把 Artifact 元件放在旁邊,把要顯示的內容當 children 傳進去,順便帶上 title。

這裡有個值得注意的設計取向:專案沒有規定 artifact 長什麼樣,只提供容器和開關。內容完全由你的 graph 決定,透過 meta 傳遞。彈性很大,代價是你得自己處理型別,hook 的泛型參數 TContext 預設是 Record<string, unknown>,等於放棄型別檢查。對內部工具來說這沒問題,對長期維護的產品則是個要自己補上的缺口。

生產環境:README 自己承認預設設定不能用

這是整個專案最誠實也最重要的一段。文件寫得很清楚:Agent Chat UI 預設是為本地開發設計的,直接從客戶端連線到你的 LangGraph 伺服器。要上生產環境就不能這樣,因為那會要求每個使用者都有自己的 LangSmith API key,還要自己設定 LangGraph 配置。

README 給出的方案是 API Passthrough,指向 bracesproul/langgraph-nextjs-api-passthrough 這個套件。它的作用是在伺服器端代理請求到你的 LangGraph 伺服器,把 LangSmith API key 附加在伺服器上,使用者端永遠不需要接觸到 key。

README 原文只寫到這裡就截斷了,所以第二種認證方式我無法從提供的材料確認。這點必須說清楚:如果你要上生產,除了 API Passthrough 之外還有什麼選擇,得自己去看完整文件。

從架構角度看,這個「本地直連、生產代理」的雙軌設計其實是合理的。開發時少一層轉發,除錯容易;上線時把 key 收進伺服器,符合基本的安全原則。但它也意味著從 demo 到上線不是改個環境變數就好,而是要新增一整個代理層。這個落差值得在評估階段就先算進去。

什麼時候該用它,什麼時候該自己寫

替代方案不是某個競品,而是「自己寫前端」。LangGraph 伺服器提供的是標準協定,你完全可以用任何框架接上去。差別在於成本結構:自己寫意味著你要處理串流事件的解析、thread 狀態、tool call 的呈現、artifact 的容器,這些 Agent Chat UI 都已經有了。

反過來說,自己寫的價值在於控制權。如果你的狀態結構不是以 messages 為核心,或者你的介面需要對話以外的互動模式(表單、圖表、多欄工作區),這個專案反而會變成阻力,因為它的假設就是一個聊天視窗加一個側欄。它的 messages key 要求看起來很寬鬆,實際上是一條明確的邊界。

另一個要考慮的是授權。專案採用 MIT,這對商業使用相對友善,但這不是法律建議,實際的合約與合規判斷請找專業人士。真正需要注意的是相依性:Next.js、LangChain 生態的套件更新頻繁,而這個專案本身沒有檢索到任何 release 記錄,代表它的版本節奏未必與上游同步。你要自己評估升級時的成本,特別是當 LangGraph 的協定或事件名稱改變時。

維護成本方面,README 沒有提供任何關於測試、CI 或版本相容性的說明,所以無法從材料判斷它的穩定程度。這是採用前應該自己驗證的部分。

採用前該確認的幾件事

第一,確認你的 graph 狀態裡確實有 messages key,這是硬性前提。第二,確認你的部署方式屬於哪一種:本地開發可以直接跑 pnpm dev,生產環境則要先決定代理層怎麼做,README 只給了 API Passthrough 這條路。第三,如果你打算用 Agent Builder 部署,記得把 NEXT_PUBLIC_AUTH_SCHEME 設成 langsmith-api-key。

第四,也是容易被忽略的:NEXT_PUBLIC_ 前綴的變數會被編進前端。如果你在 .env 裡放了不該公開的值,它會跟著 bundle 出去。這個專案提供的三個變數本身沒有這個問題,但你在擴充時要留意。

最後,隱藏訊息的兩套機制要分清楚。只是想不要逐字顯示,用 langsmith:nostream;要完全不出現,才需要在寫入 state 前改 id 前綴並加上 langsmith:do-not-render。搞混這兩者,你會得到一個「以為藏起來了但其實還在」的介面。

編輯結論

如果你已經有一個跑得起來的 LangGraph 伺服器,只是想盡快看到對話效果,Agent Chat UI 是最短路徑:npx create-agent-chat-app 之後填三個環境變數就能用。但它的預設連線方式是從瀏覽器直連 LangGraph,README 明講這在生產環境行不通,因為那要求每個使用者自己持有 LangSmith API key。要上線就得先確認你打算走 API Passthrough 還是自己寫一層代理,這件事沒做,前端再漂亮也只是內部 demo。反過來說,如果你的產品需要自訂對話以外的互動、非 messages 的狀態結構,或是不用 LangGraph 當後端,這個專案幫不上忙,你需要的是一套自己控制的 UI 層。

官方來源

  1. Issues
  2. langchain-ai/agent-chat-ui on GitHub
  3. License: MIT
  4. Project website
  5. README
社群筆記

社群筆記