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
Supabase Edge Functions で最近追加された AI 機能を使ってみた
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
4geru
May 14, 2024
Technology
620
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Supabase Edge Functions で最近追加された AI 機能を使ってみた
toranoana.deno #16 での登壇資料です。
https://yumenosora.connpass.com/event/316556/
4geru
May 14, 2024
More Decks by 4geru
See All by 4geru
1ヶ月Vizを眺めた話
4geru
0
20
年齢で見るチームの特徴
4geru
0
18
Boom!ヒーロー!! - ポーズを決めろ!その瞬間、キミは主役のヒーローだ -
4geru
0
63
AIと考える MCP tools の実装
4geru
0
31
AI様、あとは"よしなに"やっといて! 〜MCPサーバ開発「裏」入門〜
4geru
0
68
その物件でホントにいいの君?_第3回_Dify_Studio_ハッカソン
4geru
0
69
How OpenAPI Is Transforming API Client Development
4geru
0
89
AI時代のハンズオン:未来の“相棒”と出会う実践体験
4geru
0
61
ツンデレさんと考える LINE bot MCP の使い方
4geru
0
1.2k
Other Decks in Technology
See All in Technology
Amazon Bedrock AgentCore ワークショップ JAWS UG TOHOKU / amazon-bedrock-agentcore-workshop-jawsug-tohoku-2026
gawa
9
470
社内 AI エージェント Synapse と セマンティックレイヤーの育て方
hiroakis
0
480
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
4
1.8k
Agentic Web
dynamis
1
180
タクシーアプリ『GO』の実践的データ活用
mot_techtalk
3
170
新規ゲーム開発におけるAI駆動開発のリアル
202409e2
0
3k
10倍の生産性を実現するAI駆動並列エージェントのすべて
kumaiu
4
1.1k
Dynamic Workersについて
yusukebe
2
630
機械学習を「社会実装」するということ 2026年夏版 / Social Implementation of Machine Learning June 2026 Version
moepy_stats
2
270
LLMにもCAP定理があるという話
harukasakihara
0
220
AI活用を推進するために ファインディが下した、一つの小さな決断
starfish719
0
270
2026.06.13_AI時代に事業会社が「SIer出身エンジニア」を求める理由 / Why Businesses Seek Engineers with a System Integrator Background in the AI Era
jumtech
0
920
Featured
See All Featured
New Earth Scene 8
popppiees
3
2.3k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
320
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
230
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Evolving SEO for Evolving Search Engines
ryanjones
0
210
Joys of Absence: A Defence of Solitary Play
codingconduct
1
390
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.4k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Visualization
eitanlees
152
17k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Transcript
4VQBCBTF &EHF'VODUJPOTY"* UPSBOPBOBEFOP!HFSV
͛͠Δ!HFSV 9 چ5XJUUFS ɿ!@HFSV ॴଐɿϚωʔϑΥϫʔυ झຯɿ📷🎱🐟🤿✈ ՝֎׆ಈɿ-*/&"1*&YQFSU ࣗݾհ
4VQBCBTFY-*/&#PUͷ૬ੑͷྑ͞ w 4VQBCBTF&EHF'VODUJPOTͷσϓϩΠ͕؆୯ʂ w $-*ૢ࡞ͰσϓϩΠՄೳ w ଞͷαʔόʔϨεϑϨʔϜϫʔΫͱൺͯ6*͕γϯϓϧ w σʔλϕʔεϩάͷத͕ϒϥβ͔Β֬ೝͰ͖Δ w
DPOTPMFMPHͰϩάग़ྗՄೳʢ+40/Ͱ֬ೝՄೳʣ w -*/&#PUͷ6*͔Βͷจࣈྻը૾Ի(14͕ѻ͑Δ w ༷ʑͳใΛೖྗͰ͖Δ
-*/&#PUҎ֎ /FYU 7VF 'MVUUFSFUD αϯϓϧίʔυ͕ͨ͘͞Μ
4VQBCBTF-PWF🩷
Ұ൪͍͍ͱ͜Ζɺ ʂγϯϓϧʂ
ࠓճͷΰʔϧɿ 4VQBCBTF&EHF'VODUJPOT Λ͍ͨ͘ͳΔʂ
4VQBCBTFͷ (" ਖ਼ࣜ൛ϦϦʔε
ੈք֤Ͱ ϛʔτΞοϓ ͕։࠵ʂʂ
4VQBCBTF("8FFL d w 4VQBCBTF͕(" (FOFSBM"WBJMBCJMJUZਖ਼ࣜ ϦϦʔε w "VUIʹಗ໊ϩάΠϯػೳՃ w 4UPSBHF͕4ϓϩτίϧରԠ
w &EHF'VODUJPOT͕"*ωΠςΟϒରԠ w ΠϯσοΫεΞυόΠβʔػೳՃ
4VQBCBTFY"* ͷ
4VQBCBTF("8FFL d w 4VQBCBTF͕(" (FOFSBM"WBJMBCJMJUZਖ਼ࣜ ϦϦʔε w "VUIʹಗ໊ϩάΠϯػೳՃ w 4UPSBHF͕4ϓϩτίϧରԠ
w &EHF'VODUJPOT͕"*ωΠςΟϒରԠ w ΠϯσοΫεΞυόΠβʔػೳՃ
4VQBCBTF"*ػೳͷϦϦʔε #MPH"**OGFSFODFOPXBWBJMBCMFJO4VQBCBTF&EHF'VODUJPOT 8IZZPVTIPVMEVTF&EHF'VODUJPOTGPS"* -MBNBXJUI7FSDFM"*
4VQBCBTF"*ػೳͷϦϦʔε #MPH"**OGFSFODFOPXBWBJMBCMFJO4VQBCBTF&EHF'VODUJPOT &NCFEEJOH"1*Λఏڙ ྨࣅݕࡧ͕͍͢͠Έ --. -MBNB.JTUSBM Λఏڙ $IBU(15ͷΑ͏ͳνϟοτػೳ
4VQBCBTF"*ػೳͷϦϦʔε #MPH"**OGFSFODFOPXBWBJMBCMFJO4VQBCBTF&EHF'VODUJPOT ཁ͕·ͱΊΒΕͨ ͷಈը ϋϯζΦϯελΠϧͷ ͷಈը
"*ؔ࿈ίʔυ ߦͷΈ
--. -MBNB.JTUSBM Λఏڙ $IBU(15ͷΑ͏ͳνϟοτػೳ -MBNBXJUI7FSDFM"*
-MBNBXJUI7FSDFM"* w ·ͩɺϩʔΧϧͷΈରԠ w MMBNB NJTUSBMNPEFMͷΈରԠ w ଞͷNPEFMͰ͖ΔΑ͏ʹܭըத w PMMBNBΛϩʔΧϧͰڥߏங͢Δඞཁ͋Γ
w কདྷతʹ4VQBCBTFͷதʹΈࠐ·ΕΔ༧ఆ
σϞ
1 // / <reference types="https://esm.sh/@supabase/functions-js/src/edge- runtime.d.ts" /> 2 // const
session = new Supabase.ai.Session('mistral') 3 const session = new Supabase.ai.Session('llama2') 4 import { notifyMessage } from './messages.ts' 5 6 Deno.serve(async (req: Request) => { 7 const params = new URL(req.url).searchParams 8 const prompt = params.get('prompt') ?? '' 9 notifyMessage(`user prompt: ${prompt}`) 10 11 // Get the output as a stream 12 const output = await session.run(prompt, { stream: true }) NPEFMͷઃఆ͕؆୯
1 // / <reference types="https://esm.sh/@supabase/functions-js/src/edge- runtime.d.ts" /> 2 // const
session = new Supabase.ai.Session('mistral') 3 const session = new Supabase.ai.Session('llama2') 4 import { notifyMessage } from './messages.ts' 5 6 Deno.serve(async (req: Request) => { 7 const params = new URL(req.url).searchParams 8 const prompt = params.get('prompt') ?? '' 9 notifyMessage(`user prompt: ${prompt}`) 10 11 // Get the output as a stream 12 const output = await session.run(prompt, { stream: true }) NPEFMͷݺͼग़͕͠؆୯
18 // Create a stream 19 const stream = new
ReadableStream({ 20 async start(controller) { 21 const encoder = new TextEncoder() 22 23 try { 24 let message = '' 25 for await (const chunk of output) { 26 controller.enqueue(encoder.encode(chunk.response ?? '')) 27 message = [...message, chunk.response].join('') 28 } 29 notifyMessage(message) 30 } catch (err) { 31 console.error('Stream error:', err) 32 } finally { 33 controller.close() 34 } 35 }, 36 }) 37 DIVOL͝ͱʹׂͯ͠ड͚औΔ
18 // Create a stream 19 const stream = new
ReadableStream({ 20 async start(controller) { 21 const encoder = new TextEncoder() 22 23 try { 24 let message = '' 25 for await (const chunk of output) { 26 controller.enqueue(encoder.encode(chunk.response ?? '')) 27 message = [...message, chunk.response].join('') 28 } 29 notifyMessage(message) 30 } catch (err) { 31 console.error('Stream error:', err) 32 } finally { 33 controller.close() 34 } 35 }, 36 }) 37 DPOUSPMMFSͰॲཧΛ͢Δ
&NCFEEJOH"1*Λఏڙ ྨࣅݕࡧ͕͍͢͠Έ 8IZZPVTIPVMEVTF&EHF'VODUJPOTGPS"*
8IZZPVTIPVMEVTF&EHF'VODUJPOTGPS"* w 4VQBCBTF&EHF'VODUJPOTͷΈͰɺ݁ɻ w 4VQBCBTFͰใΛอଘͰ͖Δɻγϯϓϧʂʂ w ྨࣅݕࡧ͕ؔͱ࣮ͯ͠ࡁΈ w ςΩετ͚ͩͰͳ͘ɺը૾ͳͲՄೳ
σϞ
10 const session = new Supabase.ai.Session('gte-small'); 11 12 serve(async (req)
=> { 13 const { events } = await req.json() 14 console.log(events) 15 if (events && events[0]?.type === "message") { 16 const input = events[0].message.text 17 // Generate the embedding from the user input 18 const embedding = await session.run(input, { 19 mean_pool: true, 20 normalize: true, 21 }); 22 23 // จࣈྻԽͨ͠ϝοηʔδσʔλ 24 let messages:any = [ 25 { 26 "type": "text", 27 "text": events[0].message.text 28 }, 29 ] NPEFMͷݺͼग़͕͠؆୯ ϕΫτϧใ͕SFUVSO͞ΕΔ
31 // Store the vector in Postgres 32 const supabase
= supabaseClient() 33 const { data: documents } = await supabase.rpc('match_documents', { 34 query_embedding: embedding, // Pass the embedding you want to compare 35 match_threshold: 0.78, // Choose an appropriate threshold for your data 36 match_count: 3, // Choose the number of matches 37 }) 38 console.log({documents}) 39 documents.map((doc) => { 40 messages.push({ 41 "type": "text", 42 "text": `Matched: ${doc.body}` 43 }) 44 }) 45 const { data, error } = await supabase.from('documents').insert({ 46 body: events[0].message.text, 47 embedding, 48 }) 49 replyMessage(events, messages) 50 } Ұக͢ΔυΩϡϝϯτΛݕࡧ
31 // Store the vector in Postgres 32 const supabase
= supabaseClient() 33 const { data: documents } = await supabase.rpc('match_documents', { 34 query_embedding: embedding, // Pass the embedding you want to compare 35 match_threshold: 0.78, // Choose an appropriate threshold for your data 36 match_count: 3, // Choose the number of matches 37 }) 38 console.log({documents}) 39 documents.map((doc) => { 40 messages.push({ 41 "type": "text", 42 "text": `Matched: ${doc.body}` 43 }) 44 }) 45 const { data, error } = await supabase.from('documents').insert({ 46 body: events[0].message.text, 47 embedding, 48 }) 49 replyMessage(events, messages) 50 } ೖྗͨ͠ϕΫτϧͷใΛอଘ
31 // Store the vector in Postgres 32 const supabase
= supabaseClient() 33 const { data: documents } = await supabase.rpc('match_documents', { 34 query_embedding: embedding, // Pass the embedding you want to compare 35 match_threshold: 0.78, // Choose an appropriate threshold for your dat 36 match_count: 3, // Choose the number of matches 37 }) 38 console.log({documents}) 39 documents.map((doc) => { 40 messages.push({ 41 "type": "text", 42 "text": `Matched: ${doc.body}` 43 }) 44 }) 45 const { data, error } = await supabase.from('documents').insert({ 46 body: events[0].message.text, 47 embedding, 48 }) 49 replyMessage(events, messages) 50 } ϩάͷ֬ೝ͕؆୯ʂ
ϩάͷ֬ೝ͕؆୯ʂ
4VQBCBTF͚ͩͰ "*ͷ1P$͕Ͱ͖Δʂ
4VQBCBTFY-*/&#PU ૬ੑ࠷ߴʂ
-*/&#PUҎ֎ /FYU 7VF 'MVUUFSFUD αϯϓϧίʔυ͕ͨ͘͞Μ
ࠓճͷΰʔϧɿ 4VQBCBTF&EHF'VODUJPOT Λ͍ͨ͘ͳΔʂ