延續前一篇,本篇將開始實作,目標如下:
建立一個具備 AI agent 功能的 SidePanel,讓使用者按下 Button 後,LangChain Agent 能夠觸發對頁面的操作。
WXT 專案初始化與 SidePanel 註冊
安裝 wxt 與初始化(目錄為 wxtagent, 使用 react)
1 | npx wxt@latest init wxtagent -t react |
1 | cd wxtagent |
- 註:@types/chrome 套件是 Chrome Extension 的型別定義檔
執行 npm run dev
後,Chrome 會自動開啟,讓我們測試這個 extension。
此時,按下 extension 的 icon 預設會開啟 popup 畫面,如下圖,

按下 icon 改成開啟 SidePanel
將entrypoints
目錄中的popup
目錄名稱改為 sidepanel
,
entrypoints
的設定,請參考 entrypoints Including Other Files
在background.ts
中,設定按下 extension 的 icon 改成開啟 SidePanel,程式如下,
1 | export default defineBackground({ |
執行 npm run dev
後,點擊 extension 的 icon,可以發現,它會顯示 SidePanel,而不是 popup ,如下圖所示,

使用 WXT 開發 Extension 相當方便,能快速進行 SidePanel 的建置。
建立 LangChain Agent
在完成 SidePanel 基礎架構後,接著整合 LangChain,使 AI agent 能與網頁互動。
LangChain 是一種基於語言模型的應用程式開發框架,並且支持使用 JavaScript 進行開發。
接下來,安裝 LangChain 需要的套件,
1 | npm install @langchain/core @langchain/langgraph @langchain/openai browser-extension-url-match |
新增一個 utils
目錄,並在其中建立 types
、handlers
和 tools
子目錄。
以下先建立取得網頁內容 (pageContent)
這個 Tool:
1.定義 message 的 Request 及 Response 的格式(utils/types/message.ts
)
1 | // 定義請求的型別 |
這裡是定義共通的 message/tool 的內容及描述,描述很重要,因為它有助於 LLM 了解是否要呼叫特定的 tool
2.定義 LLM 需要的資訊(utils/types/agentConfig.ts
)
1 | export interface agentConfig { |
相容於 openai 的 LLM 都可以使用
3.建立 sendMessage 向 content-script 傳遞訊息,並等待回應(utils/message.ts
) 方便 tool 使用
1 | import { messageRequest, messageResponse } from "./types/message"; |
4.建立 Agent 需要的取得網頁內容的 Tool (utils/tools/pageContentTool.ts
)
1 | import { tool } from "@langchain/core/tools"; |
此處的 sendMessage 用於向 content-script 傳遞訊息,並等待回應。它是工具與網頁內容交互的核心方法
5.提供依不同網址來取得可使用的 Tools 的 method (utils/tools/index.ts
),match url 的方式跟 extension 相同,所以使用 browser-extension-url-match
這個套件
1 | import { matchPattern } from "browser-extension-url-match"; |
只要有匹配到 url 的設定,就會使用相應的 Tools(可疊加且不重複)
6.建立處理訊息的 Handler(utils/handlers/pageContentHandler.ts
),這裡直接回傳document.body.innerText
的內容
1 | import { messageRequest, messageResponse } from "../types/message"; |
7.建立處理訊息的 Handler 的集合 Handlers(utils/handlers/index.ts
),可讓 content-script 依 message.type 來取得對應的 handler (這裡的 key 用 MESSAGE_TOOL_TYPES
定義的內容)
1 | import { |
8.建立 Agent (utils/agents.ts
)
透過 createReactAgent 來將 LLM 與 tools 結合起來,建立 Agent,而 tools 會依 tab 上的 url 來決定要使用哪些工具
1 | import { ChatOpenAI } from "@langchain/openai"; |
到這裡,已經完成了 message、tools 及 agent 的設計,接下來將實作按下 Button 時,讓 agent 呼叫 LLM 及 tool 取得網頁內容,並由 LLM 進行回答。
透過 Agent 來總結網頁的內容
1.設定manifest(wxt.config.ts)
由於工具需要透過 tabs 權限與網頁互動並傳遞訊息,因此需在 manifest 中加入 tabs 權限。若要將資料存起來,也需要 storage 權限。
1 | import { defineConfig } from "wxt"; |
2.content-script來處理message(entrypoints/content.ts
)
這裡透過 chrome.runtime.onMessage.addListener
來接收訊息,並依 message.type 取得對應的 handler 進行處理。
1 | import { messageRequest, messageResponse } from "../utils/types/message"; |
3.在SidePanel的App.tsx
中,按下 Button 時,向Agent詢問問題
將原本的 Button click event 改成呼叫 handleClick
1 | <button onClick={handleClick}>count is {count}</button> |
1 | const handleClick = async () => { |
最後,執行 npm run dev
,隨意瀏覽任一網頁,然後按下 Button,即可顯示該網頁的總結,如下圖所示:

當按下 Button 時,會做以下幾個動作,
1.取得 tab 的 url ,並設定 LLM 的資訊,透過createChatAgent來建立Agent
2.Agent將請總結選取網頁的內容
傳給 LLM,並提供 Tools (pageContentTool) 資訊
3.LLM 發現需要呼叫 pageContentTool 時,回覆需要進行 call tool
4.Agent呼叫pageContentTool取得結果
4.1.pageContentTool透過chrome.tabs.sendMessage發送訊息
4.2.content.ts監聽到訊息,依 message.type 取得 handler(pageContentHandler),回傳 Handler 的處理結果
5.Agent將pageContentTool的結果連同前面的訊息傳給 LLM
6.LLM 依使用者問題、pageContentTool 結果來進行回答,再回給Agent
7.alert 出最後 LLM 的回答內容
流程如下,

結論
透過 WXT 和 LangChain 的結合,我們展示了如何快速構建一個功能強大的 Chrome 擴充功能,這不僅提升了開發效率,也為實現更智能的瀏覽器交互提供了可能性。
這種機制可以應用於多種場景,例如自動化網頁內容摘要、智能化數據提取,甚至更複雜的網頁操作。
下一步,我們將進一步優化 SidePanel 的 UI,將其轉變為對話機器人的界面,並探索更多與 LLM 結合的可能性。
參考資源
用 Browser Extension 打造具網頁背景感知的 AI 助理,補足 LLM 的視野盲點
為什麼 AI 工具需要瀏覽器擴充功能來補全 Web 背景?
優化 SidePanel 的 UI,將其轉變為對話機器人的界面,並探索更多與 LLM 結合的可能性
wxtagent程式碼