第4å SlackããçæAIãåŒã³åºããããã«ãã
æ¬ãšã³ããªã¯Ubie çæAI Advent Calendar 2024ã®12æ¥ç®ãã瀟å çšçæAI Webã¢ããªã±ãŒã·ã§ã³ãã©ã®ããã«äœã£ãŠããããã®ç¬¬4åã§ãã
ååã¯ã第3å çæAIã®ã¢ãã«ãšå€éšããŒã¿ã飿ºå¯èœã«ããã«ã€ããŠèª¬æããŸãããä»åã¯ãSlackããçæAIãåŒã³åºãæ¹æ³ã«ã€ããŠè§£èª¬ããŸãã
çæAIãSlackããåŒã³åºããããªã
第1ã2ã3åã§ã¯ãçæAIãå©çšã§ããWebã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠèª¬æããŸãããçæAIãå©çšã§ããWebã¢ããªã±ãŒã·ã§ã³ã®æ©èœãå å®ããã®ã¯è¯ãããšã§ãããäžæ¹ã§ããªã«ããããæã«WebããŒãžãæ¯åéããªããã°ãªããªãã®ã¯ããé¢åã§ããããŸãã瀟å ã®ãŠãŒã¶ãåžžã«æ»åšããŠããSlackãªã©ã®ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ããçæAIãå©çšã§ãããšäŸ¿å©ããã§ãã
Slack botãäœã
ãªã«ã¯ãªããšãããšããããSlackããå©çšã§ããbotãäœãå¿ èŠããããŸãããã ãã®èŸºãã¯åçŽã«Slack botãäœãã ãã®è©±ãªã®ã§ãå€§å¹ ã«å²æããŸããå ¬åŒã®ããã¥ã¡ã³ããèªãã®ãããã§ãããã
Dev Genius[1]ã¯ã@slack/boltãå©çšããŠãSocket Modeã§Slackã«æ¥ç¶ããŠããŸãã Slackããã®ã€ãã³ããWebhookã§åãåãããšãã§ããŸãããDev Geniusã¯ç€Ÿå éå®ã®ã¢ããªã±ãŒã·ã§ã³ã®ãããå€éšããã®ã¢ã¯ã»ã¹ãå¶éããŠããŸãããã®å¶éãWebhookã§ééãããããšã¯ç ©éã«ãªããããSocket Modeãæ¡çšããŠããŸãã
çŸåšã¯Slackã®æ¬¡ã®ã€ãã³ããåãåãããã«ããŠããŸãã
- app_mention ã¡ã³ã·ã§ã³ããããšã
- reaction_added ãªã¢ã¯ã·ã§ã³ã远å ããããšã
å®è£ ã®ã€ã¡ãŒãžã¯ä»¥äžã®éãã§ãã
import { App } from "@slack/bolt";
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
appToken: process.env.SLACK_APP_TOKEN,
socketMode: true,
});
app.event("app_mention", async ({ event, client }) => {
// åŠç
});
app.event("reaction_added", async ({ event, client }) => {
// åŠç
});
ã¡ã³ã·ã§ã³ã«å¯ŸããŠè¿ä¿¡ãã
ãŸãã¯ã¡ã³ã·ã§ã³ã«å¯ŸããŠè¿ä¿¡ããããšãèããŠã¿ãŸããããã€ãã®ã¢ãããŒããããããšæããŸãããDev Geniusã§ã¯ã¡ã³ã·ã§ã³ã«å¯ŸããŠã¹ã¬ãããäœæãããã®äžã§è¿ä¿¡ããããã«ããŠããŸããããããããšã§ãã¹ã¬ããå šäœãã¹ã³ãŒããšããäŒè©±ãå¯èœã«ãªããŸããã¹ã¬ããå ã§ã®ã¡ã³ã·ã§ã³ã§ããã°ããã®ãŸãŸã¹ã¬ããå ã§è¿ä¿¡ãè¡ããŸãã
app.event("app_mention", async ({ event, client }) => {
// ã¹ã¬ããå
šäœãèªã¿èŸŒã
const messages = await getRawMessages(event.channel, event.ts);
// ããããªåŠçãçµãŠ...
const response = // çæAIã®ã¬ã¹ãã³ã¹
// ã¹ã¬ããã«è¿ä¿¡ãã
await app.client.chat.postMessage({
channel: event.channel,
text: `<@${event.user}> ${response}`,
thread_ts: event.ts,
});
});
export type Message = {
user?: string;
text?: string;
};
// ã¹ã¬ããå
šäœãèªã¿èŸŒã
export const getRawMessages = async (
channelId: string,
messageId: string,
): Promise<Message[] | null> => {
const messageList: Message[] = [];
let hasMore = false;
let cursor = undefined;
do {
try {
const replies = await app.client.conversations.replies({
channel: channelId,
ts: messageId,
cursor: cursor,
});
if (replies == null) {
return null;
}
if (replies.messages != null) {
replies.messages.forEach((message) => {
if (message.text != null) {
const attachmentsText =
message.attachments
?.map((attachment) => attachment.text ?? attachment.fallback)
.filter((text) => text != null)
.map((text) =>
text
.split("\n")
.map((line) => `> ${line}`)
.join("\n"),
)
.join("\n") ?? "";
messageList.push({
...message,
text: attachmentsText
? `${message.text}\n${attachmentsText}`
: message.text,
});
}
});
}
hasMore = replies.has_more ?? false;
cursor = replies.response_metadata?.next_cursor;
} catch (error) {
console.error("Error fetching raw messages:", error);
return null;
}
} while (hasMore);
return messageList;
};
ãããã€ããŠåããã°ãæŽããŠSlackäžã§çæAIãå©çšã§ããŸãã

ããã©ã«ãã§ã¯gemini-1.5-pro-001ãçšããŠè¿ä¿¡ããŸã
Slackäžããããªã»ããã䜿ã
SlackäžããçæAIãå©çšã§ããã ãã§ããããªãã«äŸ¿å©ã§ããããããWebã¢ããªã±ãŒã·ã§ã³çã®æ¢åã®ã¢ã»ããã§ããããªã»ãã[2]ãå©çšã§ãããšãæŽã«äŸ¿å©ã«ãªãããã§ãã
Dev Geniusã§ã¯ãç¹å®ã®èšæ³ãçšããããšã§ãSlackäžããããªã»ãããåŒã³åºããããã«ããŠããŸããã¡ã³ã·ã§ã³äžã« [preset=:id] ãå«ãããšã察å¿ããããªã»ãããæ¢ããã·ã¹ãã ããã³ãããã¢ãã«ãtemperatureãå©çšããŠè¿ä¿¡ãäœæããŸãã

ããã§ã¯å²æããŸãããããªã»ããã«ã¯URLåã蟌ã¿ã®èšå®ãã§ããnotionãªã©ã®åçãªæ
å ±ãœãŒã¹ãå±éããŠå©çšããæ©èœãªã©ããããŸã
èšæ³ã¯åãªãå éšçãªä»æ§ãªã®ã§ãåŠçæ¹æ³çã¯ç¹ã«èª¬æããŸãããæ£èŠè¡šçŸã§idãåãåºããŠæ¢ãããšãã£ãã·ã³ãã«ãªå®è£ ã§ãã
ãªã¢ã¯ã·ã§ã³ã«ããããªã»ããã®åŒã³åºãããµããŒããã
Slackããããªã»ããã䜿ã£ãŠåŒã³åºããã®ã¯äŸ¿å©ã§ãããç¹å¥ãªèšæ³ã䜿ãã®ã¯ããªãããŒãã«ãé«ãã§ããå ¥åããæç« ã»æèããèªåçã«å©çšãã¹ãããªã»ãããéžå®ã§ããã°ããã§ãããããã¯ããã§ããªãé£ããã§ãããã
ããã§ããªã¢ã¯ã·ã§ã³ã«ããããªã»ããã®åŒã³åºãããµããŒãããŸãããã¡ãã»ãŒãžã«ãªã¢ã¯ã·ã§ã³ãã€ãããšããã®ã¡ãã»ãŒãžã«å¯ŸããŠããªã»ãããåŒã³åºãããã«ããŸããããã®ã¢ã€ãã¢ãšå®è£ ã¯ååã®@syu_creamã«ãããã®ã§ãã
ããªã»ããã®ç·šéç»é¢ã§Slackãªã¢ã¯ã·ã§ã³ã®å²ãåœãŠãèšå®ã§ããããã«ããŠããŸãã

ããã«ãããSlackäžã§ãªã¢ã¯ã·ã§ã³ããããšãåå¿ããŠãããããã«ãªããŸããã

ãã¡ããã¡ããããããªãå±ãŸããããŠãããããªã»ããã瀟å
ã§ã人æ°ã§ã
çµç¹ã§èªç±ã«æ¡åŒµãå¯èœã§ããããšã®äŸ¡å€
ãªã¢ã¯ã·ã§ã³ã«ããããªã»ããã®åŒã³åºãããµããŒããããšãæ©é䟿å©ãªèšå®ã远å ãããŠãããŸãããå人çã«æ°ã«å ¥ã£ãŠããæ©èœããµãã€ã»ã©ç޹ä»ããŸãã
次ã®äŸã¯ã瀟å
ã®PBI(ãããã¯ãããã¯ãã°ã¢ã€ãã )ã®æžãæ¹ã«æ²¿ã£ãŠãPBIæ¡ãäœæããŠãããããªã»ããã§ããSlackã§æµããèŠæã課é¡ã«ãªã¢ã¯ã·ã§ã³ãã€ããã ãã§ãããå°ããµããšäœããŸããã¿ã€ãã«ã ãã®äžèº«ãªãPBIã®æ²æ»
ã«åœ¹ç«ã€ã®ã§ã¯ãšæã£ãŠããŸãã

å
容ããã®ãŸãŸã§äœ¿ããããã§ã¯ãªããããããå°ãšããŠã¯ããªã圹ç«ã€
ãŸããæ¬¡ã®ããã«ãGithub URLãå«ãã ã¡ãã»ãŒãžã«ãªã¢ã¯ã·ã§ã³ããããšã§ãå 容ã説æããŠãããŸããããã¯ç¬¬3å çæAIã®ã¢ãã«ãšå€éšããŒã¿ã飿ºå¯èœã«ãããšãè€åããããªã»ããã§ãã

ããããåããåããŠãããããªã¢ã¯ã·ã§ã³åããŠäœ¿ããã®ã§ã¯ãªããããšãã£ãäŒè©±ãåæã§çºçããŠãããçµç¹ã§èªç±ã«æ¡åŒµã§ããä»çµã¿ã®äŸ¡å€ã宿ããŠããŸãã瀟å ã®æ§ã ãªããŒãºã«å¿ããŠãããŒã ç¬èªã®ããªã»ãããäœæããSlackãªã¢ã¯ã·ã§ã³ãšçµã¿åãããããšã§ãæ¥ã ã®æ¥åã«åœ¹ç«ã€ãã®ãèªåŸçã«äœããããã«ãªããŸããã
ãŸãšã
SlackããçæAIãåŒã³åºãæ¹æ³ã«ã€ããŠç޹ä»ããŸãããã©ã¡ãããšãããšãã©ã®ããã«åŒã³åºããŠãããããšããã»ããæ£ç¢ºãªãã¥ã¢ã³ã¹ãããããŸãããSlack botãšããŠåç¬ã§åŒã³åºããã ãã§ã¯ããç©è¶³ããªããšããã§ãããããªã»ãããå€éšæ å ±ãšã®é£æºãã§ããããšã§ãSlackããå©çšã§ãã䟡å€ãé«ãŸã£ãŠãããšæããŠããŸãã
-
Ubieã®ç€Ÿå ã§å 補ããŠããçæAI Webã¢ããªã±ãŒã·ã§ã³ã§ããæ®æ®µã¯devçºãšåŒã°ããŠããŸãã â©ïž
-
ããªã»ããã«ã€ããŠã¯ç¬¬2å ããã³ãããåå©çšãããããªã»ããã¹ãã¢ãšå ±ææ©èœãåç §ããŠãã ããã â©ïž
Ubieæ ªåŒäŒç€Ÿã®ããã¯ããã°ã§ãã æ¡çšæ å ±ïŒrecruit.ubie.life
Discussion