你前面已經有互動元件、資料層、部署和排程,現在只差一塊就能變成完整社群助理:AI 對話。
這篇我們用 Groq 做 /ask 和 /reset,把 Bot 升級成可持續追問的助手。
為什麼選 Groq
Groq 對 Node.js 的整合很簡單,速度也很適合聊天型場景。對 Discord 來說,回覆延遲低非常重要,使用者體感會明顯好很多。
安裝與環境變數
npm install groq-sdkGROQ_API_KEY=你的金鑰
GROQ_MODEL=llama-3.3-70b-versatile封裝 AI 服務
import Groq from "groq-sdk";
const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });
const MODEL = process.env.GROQ_MODEL || "llama-3.3-70b-versatile";
// 每個頻道各自維護上下文
const channelHistory = new Map();
const MAX_MESSAGES = 20;
function getSystemPrompt() {
return "你是 Discord 伺服器的助理。回答要精準、口語、條列清楚,必要時給可執行步驟。";
}
export async function askGroq({ channelId, userMessage }) {
const history = channelHistory.get(channelId) ?? [];
history.push({ role: "user", content: userMessage });
const response = await groq.chat.completions.create({
model: MODEL,
messages: [{ role: "system", content: getSystemPrompt() }, ...history],
temperature: 0.4,
});
const reply = response.choices?.[0]?.message?.content?.trim() || "我目前沒有產生回覆,請再試一次。";
history.push({ role: "assistant", content: reply });
// 只留最近 N 則,避免上下文無限成長
channelHistory.set(channelId, history.slice(-MAX_MESSAGES));
return reply;
}
export function resetChannelHistory(channelId) {
channelHistory.delete(channelId);
}在 Discord 指令中接上 /ask 與 /reset
import { askGroq, resetChannelHistory } from "./aiChat.js";
const COMMANDS = [
{
name: "ask",
description: "向 AI 提問",
options: [
{
name: "question",
description: "你的問題",
type: 3,
required: true,
},
],
},
{
name: "reset",
description: "清除本頻道 AI 對話歷史",
},
];
client.on("interactionCreate", async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === "ask") {
const question = interaction.options.getString("question", true);
await interaction.deferReply();
try {
const answer = await askGroq({
channelId: interaction.channelId,
userMessage: question,
});
await interaction.editReply(answer.slice(0, 1900));
} catch (error) {
console.error("Groq 呼叫失敗", error);
await interaction.editReply("AI 服務暫時不可用,請稍後再試。");
}
return;
}
if (interaction.commandName === "reset") {
resetChannelHistory(interaction.channelId);
await interaction.reply({ content: "本頻道 AI 對話歷史已清除。", flags: 64 });
}
});成本與穩定性建議
- 每個頻道限制歷史長度(如 20 則)就很有效。
- 問題長度可限制在 500 字,避免惡意灌 token。
- 回覆做字數裁切,避免超過 Discord 訊息上限。
- 發生 API 錯誤時給固定文案,並記錄 log。
實際運作效果
首次提問
使用者輸入問題後,Bot 先 defer(顯示「思考中」),等 Groq 回傳後再把答案完整送出。

多輪追問
同一頻道繼續追問,Bot 知道前面提過的話題,回覆有延續性。

重置對話
使用 /reset 後收到 ephemeral 確認訊息,只有自己看得到。

重置後再問同樣的問題,Bot 不再記得之前的內容。
