嗨大家,我是 Debuguy。
昨天聊了為什麼要做 Slack AI ChatBot,今天來分享一個看似簡單但其實很關鍵的決定:選什麼技術來開發?
這不只是技術問題,更是一個關於「在企業環境中如何做產品」的現實課題。
一開始,我的想法很單純:
「做 AI 當然要用 Python 啊,這還用想嗎?」
腦海中的完美藍圖:
從早期的 Machine Learning 框架 TensorFlow、PyTorch,到現在各種 LLM 相關的套件,Python 在 AI 領域累積的整個生態系都相對完整。OpenAI、Anthropic、Google 的官方 SDK 都是以 Python 優先,社群資源也最豐富。
「這麼多現成的工具,應該可以很快就做出來吧?」
從技術角度看,Python 幾乎是 AI 應用開發的標準答案。我甚至已經開始想像自己優雅地 pip install
各種套件的畫面了。
但當我開始認真考慮「這個 ChatBot 要怎麼在公司內推廣」時,內心開始出現雜音:
「等等... 如果我用 Python 寫,到時候誰來維護?」
「我們的 CI/CD 都是針對 .NET 和 JS 設計的,要重新搞一套?」
「萬一我要 handover,這個專案是不是會變成大家無法維護?」
並且考量到「這個 ChatBot 的影響力要能很快在公司內發酵」時,現實的問題接踵而來:
部署與維運的挑戰
團隊協作的現實
這些不是技術問題,而是組織問題。再好的技術,如果團隊駕馭不了,就不是好的選擇。
技術選型不能只看語言本身以及語言生態系,還要看整個公司的開發生態系統:
開發生態
企業生態
產品生態
當我重新評估 JavaScript / TypeScript 時,發現 AI 相關的生態系統其實已經迎頭趕上:
AI 生態系統已經足夠成熟
企業整合優勢明顯
Slack 整合也很完整
選定語言只是開始,接下來面臨的是更關鍵的問題:要怎麼跟 LLM 溝通?
最初的天真想法:
「反正都是 API 呼叫,直接用官方 SDK 不就好了?」
我一開始的想法很單純,既然決定以 Gemini 為主,那就直接用 Google 的官方 SDK:
import {GoogleGenAI} from '@google/genai';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
async function main() {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: 'Why is the sky blue?',
});
console.log(response.text);
}
main();
「這樣最直接,功能最完整,還有官方支援,完美!」
現實又來敲門了:
但當我開始思考長期規劃時,內心開始不安:
「等等,如果之後要換成 Claude 怎麼辦?整個 API 都不一樣啊...」 「更麻煩的是,如果要接 Ollama 這種自部署的模型,我是不是要自己寫抽象層?」 「自己寫抽象層?那不就變成要維護一個迷你版的 LangChain?」
想到這裡,我開始想著 AI 技術變化這麼快,今天用 Gemini,明天說不定 Claude 更好,甚至考量到資訊安全可能還要支援自行部署的 LLM 例如使用 Ollama 部署的 Gemma。如果每次都要重寫整合程式碼,這不是找自己麻煩嗎?
尋找救星的過程:
於是我開始尋找有沒有現成的解決方案。
「Vercel AI SDK 看起來不錯啊!」
import { generateText } from "ai"
import { google } from "@ai-sdk/google"
const { text } = await generateText({
model: google("models/gemini-2.5-flash-lite"),
prompt: "What is love?"
})
API 設計很現代化,TypeScript 支援也很好。但仔細研究後發現:
「這個主要是給前端用的吧?我要做的是後端服務啊...」
而且對於複雜的對話管理、trace 除錯這些企業級需求,支援似乎還不夠完整。
意外發現 GenKit:
就在我快要放棄,準備自己寫抽象層的時候,偶然發現了 Firebase 的 GenKit:
import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
const ai = genkit({
plugins: [googleAI()],
});
const response = await ai.generate({
model: googleAI.model('gemini-2.5-flash-lite'),
prompt: 'Tell me something interesting about Google AI.',
});
console.log(response.text());
「咦?這個看起來不錯誒...」
一開始我還有點懷疑:「Google 出的框架,會不會只支援自家的模型?」但研究後發現,它的設計思路正好解決了我的所有痛點:
1. 模型切換超簡單
const ai = genkit({
plugins: [
googleAI(),
openAI(),
ollama({
models: [
{
name: 'gemma3',
type: 'generate',
},
],
serverAddress: 'http://127.0.0.1:11434',
}),
],
});
「哇,這樣就能支援三種模型了?」
2. 完整的企業級工具鏈
當我看到 GenKit 提供的功能清單時,內心 OS
「這根本就是為了解決我所有問題而生的啊!」
3. 未來擴展性
最重要的是,GenKit 的 plugin 架構,既使沒有開源的人提供,需要自己撰寫 plugin 接入自己開發的模型也是保有這個彈性的。
最終拍板:就是它了!
當然,選擇新框架也不是沒有風險。我心裡也有些擔心:
「GenKit 社群還不大,遇到問題怎麼辦?」
「文檔還在完善中,會不會踩到坑?」
「學習新的概念和開發模式,會不會拖慢開發速度?」
但仔細權衡後,我覺得這個投資是值得的。畢竟:
「就決定是你了,GenKit!」
選擇如何與 Slack 連接是另一個關鍵決定,這會影響整個部署架構。
選項 1: HTTP Mode(傳統方式)
選項 2: Socket Mode(我的選擇)
1. 企業環境的現實考量
2. 部署簡化
3. 安全性優勢
當然,Socket Mode 也有一些限制需要考慮:
1. 連接數量限制
基於這些選擇,第一個可運行的版本長這樣:
import 'dotenv/config';
import slackBolt from '@slack/bolt';
import { genkit, z } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
import { startFlowServer } from '@genkit-ai/express';
import { runFlow } from 'genkit/beta/client';
async function startSlackBolt() {
const app = new slackBolt.App({
token: process.env['SLACK_BOT_TOKEN']!,
appToken: process.env['SLACK_APP_TOKEN']!,
socketMode: true,
});
app.event('app_mention', async ({ event, say }) => {
const response = await runFlow({
url: 'http://127.0.0.1:3400/chatFlow',
input: event
});
await say({ text: response, thread_ts: event.thread_ts || event.ts });
});
await app.start();
}
async function startGenkitFlow() {
const ai = genkit({
plugins: [
googleAI({
apiKey: process.env['GEMINI_API_KEY']!,
}),
],
});
const chatFlow = ai.defineFlow(
{
name: 'chatFlow',
inputSchema: z.object({
text: z.string(),
user: z.string(),
ts: z.string(),
}),
},
async ({ text }) => (await ai.generate({
model: googleAI.model('gemini-2.5-flash-lite'),
prompt: text,
})).text
);
startFlowServer({
flows: [chatFlow],
});
}
async function main() {
await Promise.all([
startGenkitFlow(),
startSlackBolt()
]);
console.log('Service Started');
}
await main().catch(console.error);
GenKit 帶來的即時好處:
這裡附上原始碼
有興趣玩玩看的朋友可依照 README.md 操作
技術選型看起來是技術問題,但其實更多時候是組織和產品問題。選擇 JavaScript/TypeScript + GenKit 這個組合,不是因為它在技術上最完美,而是因為它在我們的環境中最適合:
明天我們來聊一個更有趣的話題:如何讓 LLM 知道「自己」是誰?這個看似哲學的問題,其實是 ChatBot 和普通 Bot 最根本的差異。
後記:
一開始嘗試使用官方的 Gemini SDK 套件時
用了 @google/generative-ai
結果過陣子才注意到
Deprecated !!!
後來才改用 @google/genai
... 有種被坑了的感覺
AI 的發展變化很快
目前這個想法以及專案也還在實驗中
但也許透過這個過程大家可以有一些經驗和想法互相交流
歡迎大家追蹤這個系列
也歡迎追蹤我的 Threads @debuguy.dev