Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
はてなCMSでFigmaを取り込むシステムに使われている技術
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
NanimonoDemonai
November 29, 2025
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
はてなCMSでFigmaを取り込むシステムに使われている技術
Kyoto.js 24
NanimonoDemonai
November 29, 2025
More Decks by NanimonoDemonai
See All by NanimonoDemonai
LLMを「機能」として組み込む技術:「Figma to はてなCMS」におけるプロンプトエンジニアリングからAIエージェント構築にわたる精度向上の軌跡
nanimonodemonai
0
510
はてなCMSのアーキテクチャ; 巨大な既存システムと共存して最新技術を取り入れる
nanimonodemonai
0
800
ViteでCSSのバージョン違いを作る
nanimonodemonai
0
93
はてなブログのブログ表示に必要なJSを1/6にした話
nanimonodemonai
0
970
はてなブログのESM化
nanimonodemonai
0
420
登壇資料.pdf
nanimonodemonai
0
420
はてなブログのフロントエンドに秩序はもたらされたのか
nanimonodemonai
3
6.1k
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
380
Automating Front-end Workflow
addyosmani
1370
210k
The SEO identity crisis: Don't let AI make you average
varn
0
480
The Curse of the Amulet
leimatthew05
1
13k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
200
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Rails Girls Zürich Keynote
gr2m
96
14k
Become a Pro
speakerdeck
PRO
31
6k
BBQ
matthewcrist
89
10k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Transcript
,ZPUPKT id: nanimono_demonai ͯͳCMSͰFigmaΛऔΓࠐΉγεςϜʹ ΘΕ͍ͯΔٕज़
ࣗݾհɾΠϯτϩ AIΤʔδΣϯτͷߏங FigmaϓϥάΠϯͷߏங Server-Sent Events 2
ࣗݾհɾΠϯτϩ 3
ࣗݾհ • id: nanimono_demonai • @NanimonoDaemon • ͯͳϒϩάɺͯͳCMSͷ։ൃͱɺλεΫཧΛߦ͏ • େֶͰػցֶशʢػց༁ʣΛݚڀ͍ͯͨ͠
4
ͯͳCMSͱ 5 ·Ί͖ͪ͠ ϩΰϖϯϩʔζͷࡾ֯ܗ https://www.hatena.ne.jp/cms/ ײతͳૢ࡞ੑ ڧݻͳηΩϡϦςΟ ॊೈͳίϯςϯπཧ ࠷৽ػೳΛ͍ͭͰ •
ͯͳͷ๏ਓ͚αʔϏε
ͯͳCMSͷΞʔΩςΫνϟ 6 ·Ί͖ͪ͠ https://speakerdeck.com/nanimonodemonai/hatenacmsnoakitekutiya-ju-da-naji- cun-sisutemutogong-cun-sitezui-xin-ji-shu-woqu-riru-reru Next.jsͷTypeScriptΞϓϦέʔγϣϯ ࠷ۙ/FYUʹͯ͠5VSCPQBDLʹ͠·ͨ͠ɻ݁ՌϏϧυߴԽ͞Εͨͷ·ͨผͷʜ
Figma to ͯͳCMSͱ 7
• ʮσβΠϯʯͱʮ࣮ʯͷஅΛຒΊΔαʔϏεΛ࡞Γ͍ͨ • FigmaͷσβΠϯσʔλΛͯͳCMSʹࣗવͳίʔυͱͯ͠ө͍ͨ͠ • ͔͠͠ɺFigmaͷσʔλMarkdownͷΑ͏ʹHTMLͱશવରԠ͍ͯ͠ͳ͍ • ๏ਓ͚ͷαʔϏεͱͯ͠࡞ΔʢͳͷͰɺݸਓͰ͑·ͤΜ…ʣ ՝: FigmaͰ࡞ͬͨσʔλΛऔΓࠐΊΔFigmaϓϥάΠϯΛ࡞Γ͍ͨ
8 ·Ί͖ͪ͠ ࠓ'JHNB3FBDUʹ͢ΔαʔϏεग़͍ͯ͠·͢ AIʹΑΔΞϓϦέʔγϣϯ࡞͕ख़͍ͯ͠Δੈͷத͔ͩΒ AIΛ׆༻ͯ͠ΞϓϦέʔγϣϯΛ࡞Ζ͏
࣌ͷઌߦࣄྫௐࠪ • FigmaΛHTMLʹ͢ΔͨΊͷɺϧʔϧϕʔεͷΦʔϓϯιʔε͕͋Δ • Coding AgentͰFigma৯ΘͤΕɺHTMLͱCSSΛॻ͍ͯ͘ΕΔ • Gemini 2.5 Proʹ৯ΘͤΕɺHTMLͱCSSΛԠͯ͘͠ΕΔ
• ௐࠪͷՌͱͯ͠ϓϩϯϓτҰൃͰม͢ΔPOC࡞ͬͯɺօͷධՁ্ʑ 9 ઌߦࣄྫΛ͋ͨͬͯΈΔͱ… ͔͠͠ɺAIʹ͓ͤͰ͏·͍͔͘ͳ͔ͬͨ
AIΤʔδΣϯτͷߏங 10
Figma࿈ܞͰ • ҰճͷLLMݺͼग़͠Ͱɺͯ͢ͷHTMLΛग़ྗ͢Δ͜ͱ͕Ͱ͖ͳ͍ • ग़ྗτʔΫϯͷݶք͕͋ΔͨΊ • ͔͠͠ɺग़ྗτʔΫϯΛ૿ͨ͢Ίʹɺ࠶ؼతʹೖྗͤͨ͞ͷΛग़ྗͤ͞Δ ΈͰ࣭͕ྼԽͯ͠͠·͏ 11 ᘳͳࢦࣔจʢਆϓϩϯϓτʣʹݶք͕͋ͬͨ
ͦ͜ͰɺAIΤʔδΣϯτతΞϓϩʔνͷ࣮ʹΓସ͑Δ͜ͱʹ
AIΤʔδΣϯτΛ࡞ΔͨΊʹ • ٻΊΔ࣭ͷग़ྗ͕ಘΒΕΔ·Ͱɺग़ྗʹԠͯ͡৽ͨͳਪΛߦΘ͍ͤͨ • ͜Ε·Ͱͷग़ྗΛอଘ͍ͨ͠ • ͜ΕΒΛAIαʔϏεͷΠϯλʔϑΣʔεʹґଘͤͣʹ࡞Γ͍ͨ 12 ʮAIʹ͓ͤʯͰͲΜͲΜखʹෛ͑ͳ͍࣮ͷෳࡶ͕͞ొͯ͘͠Δ ͜ΕΒΛղܾ͢ΔϥΠϒϥϦͱͯ͠զʑLangChainͱLangGraphΛ࠾༻
Agentic Work fl owΛࢧ͑Δٕज़ 13 Agent Framework Agent Runtime Agent
Harness • LangChain.js :͞·͟·ͳAIαʔϏεΛ౷Ұͨ͠ΠϯλʔϑΣʔεͰѻ͑Δ • αʔϏεΛநԽ͢ΔͨΊͷϨΠϠʔ https://blog.langchain.com/agent-frameworks-runtimes-and-harnesses-oh-my/ • LangGraph.js: ΤʔδΣϯτͷ෦ঢ়ଶΛཧ͢Δ • ReactͰ͍͏ͱ͜ΖͷReduxͳͲͷεςʔτཧϥΠϒϥϦͷงғؾ • Deep Agents: جຊతͳΤʔδΣϯτΛ࡞ΔͨΊͷϑϨʔϜϫʔΫ
Figma࿈ܞ࠷ऴతʹͲ͏࡞ΒΕ͍ͯΔΜ͚ͩͬʁ • LangGraph.jsΛ༻͍ͨAgentic Work fl ow • LangChain.jsͰݺͼग़͍ͯ͠ΔAIαʔϏε Vertex AI
(Gemini 2.5 pro) • ΞʔΩςΫνϟRe fl ectionͱݺΕΔ ͷͰɺAIʹࣗͷग़ྗΛఆͤ͞ɺظ͢ Δग़ྗΛಘΒΕΔ·Ͱग़ྗΛॻ͖ͤ͞Δ Έ 14 ·Ί͖ͪ͠ ਪʹ͕͔͔࣌ؒΔ͔Βɺ"QQͷ֎Ͱಈ͔͍ͯ͠·͢ "NB[PO424ͰΩϡʔΠϯά͍ͯ͠Δ
Figma Pluginͷߏங 15
Figma Pluginͷ֎؍ 16 https://developers. fi gma.com/docs/plugins/how-plugins-run/ FigmaͷηΩϡϦςΟʹΑΓɺΠϯλʔωοτͷΞΫηε͕ݫ͍͠
Figma PluginͰͷೝূ 17 ࢀর: https://developers. fi gma.com/docs/plugins/how-plugins-run/ ͜ͷՕॴΛ Ͳ͏ϥΫʹ࡞Ζ͏͔ʁ
Server-Sent Events 18
ͳͥServer-Sent Events͕ඞཁ͔ʁ • AIʹΑΔਪɺΞϓϦέʔγϣϯͷ֎Ͱ͕͔͔࣌ؒΔඇಉظॲཧ • มͷਐḿ݁ՌΛϦΞϧλΠϜʹΫϥΠΞϯτ௨͢Δͱྑ͍ • FigmaϓϥάΠϯͷೝূɺΞϓϦέʔγϣϯͷ֎Ͱ͕͔͔࣌ؒΔඇಉظॲཧ • ͍ͭऴΘΔ͔Θ͔Βͳ͍ϢʔβʔͷॲཧΛͨͳ͍ͱ͍͚ͳ͍
19 Ͳ͔͜ʹɺ؆୯ʹ࣮Ͱ͖Δ௨ٕज़͕ͳ͍͔ͳ͋ʁ
Server-Sent Events 20 https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events • αʔόʔ͔ΒΫϥΠΞϯτʹҰํʹσʔλΛૹ৴͢Δ͜ͱʹಛ Խٕͨ͠ज़ • ํʹ͚ͨ͠ΕWebSocket͕͍͍ͩΖ͏ •
HTTPϓϩτίϧͰಈ࡞ • γϯϓϧ͔ͭɺ࣮͕༰қ • ΫϥΠΞϯτ͕Web APIͷEventSource ʹؚ·Ε͓ͯΓར༻͕༰ қ
Server-Sent Eventsͷ࣮ 21 async function * readPolling(readKey: string) { const
encoder = new TextEncoder(); while (true) { const code = await getCodeForReadKey(readKey); if (code.type = = = 'pending') { yield encoder.encode('event: pending\ndata: pending\n\n'); await sleep(1000); continue; } if (code.type = = = 'expired') { yield encoder.encode('event: expired\ndata: expired\n\n'); return; } if (code.type = = = 'denied') { yield encoder.encode('event: denied\ndata: denied\n\n'); return; } if (code.type = = = 'success') { yield encoder.encode(`event: success\ndata: ${code.code}\n\n`); return; } return; } } • ͜Μͳײ͡ͷδΣωϨʔλ ؔΛ༰қ͢Δ
Server-Sent Events 22 export function GET(request: NextRequest) { const searchParams
= request.nextUrl.searchParams; const readKey = searchParams.get('readKey'); if (!readKey) { return new Response('bad request', { status: 400 }); } const iterator = readPolling(readKey); const stream = iteratorToStream(iterator); request.signal.onabort = async () = > { await clearReadKey(readKey); }; return new Response(stream, { headers: { 'Content-Type': 'text/event - stream', 'Cache-Control': 'no - cache, no - transform', 'Connection': 'keep - alive', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, }); } function iteratorToStream(iterator: AsyncGenerator<Uint8Array>) { return new ReadableStream({ async pull(controller) { const { value, done } = await iterator.next(); if (done) { controller.close(); } else { controller.enqueue(value); } }, }); } • Next.jsͳΒɺ RouteϋϯυϥʹδΣω ϨʔλؔΛ ReadableStreamʹม͠ ͨͷΛͯ͠Ε
Figma to ͯͳCMSʹ͓͚ΔServer-Sent Eventsͷ۩ମతͳར༻γʔϯ • ೝূϑϩʔͰͷϙʔϦϯά • FigmaϓϥάΠϯ͔ΒͷOIDCೝূετϦʔϜʹ͓͍ͯɺreadKeyʹอଘ͞Εͨೝ ূίʔυͷঢ়ଶΛϙʔϦϯά͢Δͷʹར༻ •
ม݁ՌͷετϦʔϛϯά͍ͬͯͳ͍ͷͷ… • ͔͠͠ɺServer-Sent EventsAI͕ੜͨ͠ίʔυยΛϢʔβʔʹܧଓతʹૹ৴ ͠ϦΞϧλΠϜʹө͢Δ͜ͱʹΑ͘ΘΕΔٕज़ 23 Next.jsͰ؆୯ʹServer-Sent EventsΛ࡞Δํ๏͕ݟ͔ͭͬͨͷͰɺ ࠓޙ׆༻͍͖͍ͯͨ͠
·ͱΊ: ࠓճ͝հͨ͠ͷ • AIΤʔδΣϯτΛ࡞͢ΔͨΊͷٕज़ • Figma Pluginͷ࡞ʹ͓͚Δೝূܥϑϩʔෳࡶ • ৭ʑͳՕॴͰར༻ՄೳͳServer-Sent Eventsͷϓϩτίϧ֓ཁ
• ͦͯ͠Next.jsͰͷ࣮ํ๏ 24
ऴΘΓ 25