ã¡ãã£ã¨åã® Kyoto Tech Talk #8 ã¨ããã¤ãã³ãã§ãAIã«å®æ³ããããã¨ããçºè¡¨ãããã®ã§ãããã¡ãã£ã¨è©³ç´°ãªæ å ±ãè£è¶³ãã¤ã¤ç´¹ä»ãã¾ãã
AIに実況させる / AI Streamer - Speaker Deck
ãã£ãã
対æ¦ã²ã¼ã ï¼ãã±ã¢ã³SVã©ã³ã¯ããã«ï¼ã®ä¸éã«ã¤ãªãããæ°æã¡ã§æ¿å®USBãã£ããã£ãã¼ããå ¥æãã¦ãã¬ã¤ãé²ç»ã§ããããã«ãªã£ãã®ããã£ããåã®ãã¨ãé²ç»ã«ä½¿ãOBSãã¡ãã£ã¨è¨å®ããã°é ä¿¡ã¾ã§ã§ãããã¨ãããã£ãã®ã§è©¦ãã«é ä¿¡ããã¦ã¿ãã¨ãã ãã ã宿³é¢¨ã®ãã¨ãããããªã£ã¦ãããã®ã§ãããã°ã©ã ã§ã²ã¼ã ç»é¢ã®åæããã¤ã¤ãã³ã¡ã³ããAIã«çæããã¦ç«ã¡çµµã¨ã¨ãã«é³å£°åããã ãã§ãªãã ãããã£ã½ãããã¡ãã®ã»ããæ¥½ãããªã£ã¦ããã
æåã¯å ¨é¨ã¾ã¨ãã¦ã²ã¨ã¤ã®ããã¸ã§ã¯ãã¨ãã¦ä½ã£ã¦ããã®ã ãã©ãã²ã¼ã ç¹æã®åæããé¢ãããã³ã¡ã³ãçæï¼ç«ã¡çµµï¼é³å£°åãé¨åã ãåãé¢ãã¦ä½ã£ã¦ã¿ããã®ã motemen/ai-streamerã
GitHub - motemen/ai-streamer: AI Stremaer toolkit
æçµçã«ã©ãããæãã«ãªããã¯å®éã®åç»ãè¦ã¦ãããã¨ããããããã§ãï¼ãã¬ã¤ã®è³ªã¯ããã¨ãã¦ï¼ï¼
â» ããä½ã£ã¦ãæä¸ã®ãã¤ã§ã¡ãã£ã¨ããããã¦ãæå°ã§ãéè«ãç¶ãã¦ãã¾ãããã«ãªã£ã¦ãããâ¦â¦ã
æè¡ç詳細
OBS Studio ã¯é ä¿¡ã®ããã¡ã¯ãã¹ã¿ã³ãã¼ããã¼ã«ã§ããã¾ãã¾ãªå ¥åãçµã¿åããã¦é ä¿¡ãé²ç»ãã§ããããã®å ¥åã®ä¸ã¤ã« Browser Source ã£ã¦ã®ãããããã㯠Chrome Embedded Framework ãå©ç¨ãã¦ããããã¦ã§ããã¼ã¸ãåç»ã«ãªã¼ãã¼ã¬ã¤ã§ããããªããªã Web Audio API ã§é³å£°ãåçã§ãããåç»ã¯ãããããã¦ã§ããªããããã£ã¦ãã¨ã§ããã§ãªãã¨ããããã¨ã«ãªãã
ãã¬ã¤åç»åæããï¼ã¹ã©ã¤ãã§ã¯ eapu2ï¼ã¯å®æçã«ãã¬ã¼ã ç»åãåæãã¦åç»ã®ã·ã¼ã³ãã¤ãã³ããæ¤åºã§ããã®ã§ããããai-streamerå´ã«éãã°ãããããã¾ã§æ¥ãã¨è©±ã¯ç°¡åã§ãhonoã§APIã¨ã³ããã¤ã³ããä½ããããã³ãããåãåã£ããAIã§ã³ã¡ã³ããçæãVOICEVOXã§é³å£°åããããã³ãã¨ã³ãã«éã£ããããã ããã®ç«ã¡çµµãåå¹ã¨ã¨ãã«åçãã¦ããã ããREADMEã®ã·ã¼ã±ã³ã¹å³ãåç §ãã¦ãã ããã
ããã¯ãã£ã¦ããããã£ã½ãã宿³ã®ããã«ãç´°ãã工夫ã¯ãããããã£ãã
- ã»ãªããå ¨é¨çæããã¦ããã¾ã¨ãã¦é³å£°åããã¨ã¬ã¤ãã³ã·ã大ãããçºè©±ã¿ã¤ãã³ã°ãç»é¢ã®ç¶æ³ãã大ãããºã¬ã¦ãã¾ãã®ã§ãã¹ããªã¼ãã³ã°ã§åãåããå¥èªç¹ã§åºåããªããéä¸é³å£°åã¨ããã³ãã¨ã³ãã¸éåºãã¦ããã
- åç»ããã¤ãã³ããæ¤åºããããç¡è¨ã«ãªãæéã¯ãã£ããããã人éã®å®æ³è ã¯ããããã¨ãéè«ããã¦ããããªã®ã§ããnç§éçºè©±ããªããã°éè«ãããã¿ãããªæåãã§ããããã«ãã¦ããã
AIãããã¤ããã¢ãã«ã¯å·®ãæ¿ããããããã«ãã¦ããããã®ã§ãVercelã®AI SDKã使ã£ãããããã¤ããæ°ã«ããã«å®è£ ã§ããã®ã§ãªããªã便å©ã ã£ãããã¨ãã°ã»ãªãã«åããã¦ããã ããã®è¡¨æ ãå¤ããæ©è½ãç¨æãã¦ããããããã¯Toolã¨ãã¦å®è£ ãã¦ããããããã¤ããã¨ã«å¼ã³åºãæ¹ãå¤ããã®ã¯ç¸å½ã ãããã ã£ãã®ã§ããã¯å¤§ãã«å©ããããã
å©ç¨æ¹æ³
å®å ¨ã«èªåç¨ã§ç¨éãããããªãã§ãã¾ã親åã«ã¤ããã¦ã¯ãã¾ãããããããªæãã§èµ·å:
# VOICEVOXãèµ·å
% docker run -d -p 50021:50021 voicevox/voicevox_engine:latest
% DEBUG=aistreamer OPENAI_API_KEY=... pnpx @motemen/ai-streamer
aistreamer Loaded configuration: {
aistreamer ai: { model: 'openai:gpt-4o-mini', temperature: 1 },
aistreamer prompt: 'ããªãã¯ã²ã¼ã 宿³ã¹ããªã¼ãã¼ã§ãã\n' +
aistreamer 'ããªãã¯æ
ç·è±ãã§ããã¤ãè¦è´è
ã«æ¥½ããæéãæä¾ãã¾ãã\n' +
aistreamer 'ããããã²ã¼ã ã®ãã¬ã¤ç¶æ³ãä¼ããã®ã§ãããã«åãããã»ãªããçæãã¦ãã ããã',
aistreamer maxHistory: 10,
aistreamer avatar: {
aistreamer enabled: true,
aistreamer directory: '...'
aistreamer },
aistreamer replace: []
aistreamer } +0ms
Listening on http://localhost:7766
http://localhost:7766 ã«ã¢ã¯ã»ã¹ããã¨ãOBSã®ãã©ã¦ã¶ã½ã¼ã¹åãã®ãã¼ã¸ãè¦ããã¾ããã§
% curl localhost:7766/api/chat -d '{"prompt":"ãããã¤ãã¦"}'
ã®ããã«ããã³ãããéã£ã¦ããã°ãããããã«åãå§ãããWeb Audio API ã®é¢ä¿ã§ããã¡ã©ãã¼ã¸å ã§ã¦ã¼ã¶æä½ããã¨ããã»ãããããããããªãã§ãããã®ã¨ã³ããã¤ã³ããããã°ã©ã ããå©ãæ³å®ã§ããããã¡ãã http://localhost:7766/director ã¨ãããã¼ã¸ãä½ã£ã¦ãã¦ãã¾ãæåã§ããããããã¨ã¯ã§ããæãã«ãããã¨ããçè·¡ã¯ããã
è¨å®
è¨å®ã¯ãµã³ãã«ãããã®ã§ãããè¦ãã®ããããã©ãããã¤ãããã¯ã¢ããããã¨ã
ã¢ãã«ã®è¨å®ã¯
[ai] model = "anthropic:`claude-haiku-4-5" # ANTHROPIC_API_KEY # or # model = "google:gemini-2.0-flash-exp" # GOOGLE_GENERATIVE_AI_API_KE
ã¿ããã«æ¸ããããã㯠Vercel AI SDK ã®ãããããããã¤ãã«ãã£ã¦å¿ è¦ã¨ããç°å¢å¤æ°ãéãã®ã«æ³¨æã
ãããªã¨ãã«éè«ããã«ã¯:
[idle] timeout = 30000 # ms prompt = "çæ´»æã®ããéè«ããã¦"
ã¨ããæããèµ·åæã«è¨å®ãã¡ã¤ã«ã渡ããã®ã§ãããã§æå®ãã¦ãã ããã
ã¡ãªã¿ã«è¨å®ãã¡ã¤ã«ãc12ã§ãã¼ããã¦ããã®ã§TOML以å¤ã«ããããããªå½¢å¼ã§æå®ã§ãã¦ããªãã§ã.jsã使ããã®ã§ãããªæå®ãã§ããï¼æç²ï¼:
import { execSync } from "node:child_process";
import { readFileSync } from "node:fs";
import * as path from "node:path";
import { z } from "zod";
export default {
// ã·ã¹ãã ããã³ãã
prompt: `
ããªãã¯å
æ°ã§è¦ªãã¿ãããVTuberãããã ããã§ãã
ä¸äººç§°ã¯ãã¼ãããèªå°¾ã¯ãã®ã ããããªã®ã ããã¤ãã¦è©±ãã¾ãã
仿¥ã¯ä»¥ä¸ã®ã¹ã©ã¤ãããã¬ã¼ã³ããã®ã§ãå°è©ãã¤ãã£ã¦ãã ããã
çºè©±ããå
容ãªã®ã§ãç®æ¡æ¸ããªã©ã¯ä½¿ããªããã¨ã
1ãã¼ã¸ãã¤é²ããå½è©²ãã¼ã¸ã®å
容ã ãã話ãã¦ãã ããã
ã¹ã©ã¤ããé²ããã¿ã¤ãã³ã°ã¯ãã¡ãã§æç¤ºãã¾ãã
...
---
[...ããã«ã¹ã©ã¤ãã®å
容ãè²¼ã£ã¦ãã]
`,
idle: {
prompt:
"nextSlide ãã¼ã«ã§ã¹ã©ã¤ããæ¬¡ã«é²ãã¦ãã ããããã®å¾ãã¹ã©ã¤ãã«åãããå
容ã話ãã¦",
timeout: 3000,
},
tools: {
nextSlide: {
description: "ã¹ã©ã¤ããæ¬¡ã«é²ãã",
inputSchema: z.object({}),
execute: async (_, { aiStreamer }) => {
const currentPage = aiStreamer.store.currentPage || 1;
console.log("nextSlide called", { currentPage });
aiStreamer.store.currentPage = currentPage + 1;
execSync(
`osascript -e 'tell application "Google Chrome" to activate' -e 'tell application "System Events" to key code 124'`,
);
return { currentPage };
},
},
}
};
ã¤ã¾ãçºè©±ãçµãã£ããidleï¼éè«ï¼ãçºåãããã®ã¿ã¤ãã³ã°ã§nextSlideãã¼ã«ãå¼ã°ããAppleScriptçµç±ã§å³ç¢å°ãå ¥åãããã¹ã©ã¤ããæ¬¡ã«é²ãâ¦â¦ã¨ãããã¿ã´ã©ã¹ã¤ããããã®è¨å®ã§åé²ãããã®ã以ä¸ã§ãã夢ã®èªåãã¬ã¼ã³ã
ã¡ãªã¿ã«è£å´ã¯ãããªæãã§ããã
MCPã¨ãã¦ã®å©ç¨
çé¢ç®ã«ããã¨ããã³ããã®éä¿¡ãèªåã§ãããªãããããªãã¦é¢åãªãã ãã©ãhttp://localhost:7766/api/mcp ãMCPã®ã¨ã³ããã¤ã³ãã¨ãã¦ç¨æãã¦ããã®ã§ãAIããããã ãããåããããã¨ãå¯è½ããããªã楽ã§ãã¾ããã
VS Codeã§MCPã¨ãã¦å©ç¨ãã¤ã¤ãAIã«ç·¨éãããã°AIã©ã¤ãã³ã¼ãã£ã³ã°ãã§ããã
ãããããã§ããã

- ãã£ã¨èªã
ã³ã¡ã³ããæ¸ã