火曜日, 6月 17, 2025
No menu items!
ホーム ブログ ページ 5075

RubyやRailsの様々な知見が集まる勉強会、 TokyoWomen.rb #1 は 2025/3/1(土) 開催です! #tokyowomenrb



お知らせ

先日もこのブログでお知らせした、TokyoWomen.rb #1 がいよいよ 2025/3/1(土) に開催されます!

前回のお知らせではまだ登壇者や登壇内容が未定でしたが、イベントのタイムスケジュールも確定しました。
当日はこんな発表が行われる予定です!

  • 【招待講演】「たのしいSocketのしくみ / Socket Under a Microscope」by しおい
  • 【基調講演】「Rubyと自由とAIと」by 鳥井雪
  • 「Ruby でつくる CLI 横スクロールアクションゲーム〜Road to RubyKaigi〜」by makicamel
  • 「推しメソッドsource_locationのしくみを探る – はじめてRubyのコードを読んでみた」by nobu09
  • 「Ruby on Railsで持続可能な開発を行うために取り組んでいること」by 松嶋瑛奈
  • 「機能が複雑化しても頼りになるFactoryBotの話」by tamiko.f
  • 「AWS LambdaでRuby × LINE Botアプリを開発し、クライアント・サーバーの理解が深まった話」by misamisa
  • 「テストスケルトンで抜け漏れ防止!RSpecを用いた効率的な開発設計の共有」by まっちゃん
  • 「Rails 1.0のコードで学ぶfind_by_*とmethod_missingの仕組み」by maimu
  • 「分岐地獄を脱出した話:抽象メソッド化と動的なインスタンス生成」by 24not
  • 「Ruby、一緒に成長しよう! ~ アップグレード奮闘記 ~」by Hashino Mikiko
  • 「ruby.wasmのはじめかた」by youchan

いずれもRubyプログラマ・Railsプログラマに役立ちそうな、興味深い発表ばかりですね。
僕もとても楽しみにしています😄

各登壇内容の概要はイベントページに記載しているので、そちらをぜひチェックしてみてください!

Q. いつどこでやるの?

TokyoWomen.rbはオフライン開催です。
イベントの開催日時や開催場所は以下の通りです。

  • 日時:2025年3月1日(土)13:00〜18:30
  • 会場:SmartHRイベントスペース(最寄り駅:六本木一丁目駅)
  • 参加人数:約100人(性別不問)
  • 参加費: 1000円(懇親会のケータリング代などに使われます)

Q. 女性しか参加できないんですか?

いえ、男性エンジニアも大歓迎です!!
TokyoWomen.rbは、登壇者は女性エンジニアに限定していますが、イベントの参加者は性別不問です。
RubyやRailsに興味がある方ならどなたでもお気軽にどうぞ!!

Q. 私、Ruby初心者です or 勉強会初心者です😖

Ruby初心者の方も全然ウェルカムです!
今まで勉強会に参加したことがない、という人も大歓迎です!

誰もが最初は初心者なので、初心者だからといって参加をちゅうちょする必要はありません。
必要なのは「気になるな、参加してみたいな」という興味だけで大丈夫です!

まとめ

というわけで、今回は2025/3/1に開催される TokyoWomen.rb #1 の魅力を紹介してみました。
楽しい勉強会にしようと思っているので、初心者の方からベテランの片まで、みなさんぜひお越しください〜!😄

tokyowomenrb.connpass.com





Source link

Views: 0

デッキ構築型カードゲームにRTSの要素を盛り込んだローグライク「Commander Quest」,Steamで配信中


001.jpg

 KRAFTON傘下のFlywayGamesは2025年4月4日,PC向け新作タイトル「CommanderQuest」をSteamでリリースした。価格は1400円(税込)。本作は,デッキ構築型カードゲームにリアルタイムストラテジーの要素を盛り込んだローグライクゲームだ。プレイヤーは歴史的な英雄になって軍隊を編成し,他陣営と戦っていく。



Source link

Views: 0

【アケアカ】『クレイジーコップ』4月10日配信。限られた弾数でギャングを制圧・逮捕していくアクションシューティング



【アケアカ】『クレイジーコップ』4月10日配信。限られた弾数でギャングを制圧・逮捕していくアクションシューティング



Source link

Views: 0

20年越しに見えた「サガ」の真相!『サガ フロンティア2 リマスター』プレイ感想:今週遊んだゲーム 04/09/2025



IGN JAPAN編集部のスタッフが、最近遊んだゲームについて話す番組

00:00 オープニング
00:08 『サガ フロンティア2 リマスター』
09:25 『HUNDRED LINE -最終防衛学園-』体験版
18:54 『グランディア HDリマスター 』

■出演
クラベ・エスラ
山田集佳(フリーライター)
福山幸司(フリーライター)

■「しゃべりすぎGAMER」の再生リストはこちら

■ポッドキャスト版
iTunes 
Spotify 

■一部使用楽曲
MusMus:http://musmus.main.jp/



Source link

Views: 0

中国 対米報復関税84%に引き上げ



中国 対米報復関税84%に引き上げ

中国 対米報復関税84%に引き上げ



Source link

Views: 0

ベータを開く|パッチ1.16.5



将軍!
次の数日間、あなたはいくつかのことをテストすることができ、 このスレッドですべてのフィードバックを提供してください
あなたはあなたが好きなものについて遊んだり、テストしたり、フィードバックをすることができますが、私たちの焦点はこれらのポイントにあります。

  • 機器デザイナー – ゲームセッション全体でデザインを保存する機能を追加しました。タンク/船/飛行機のデザインを1つのプレイスルーに保存し、別のプレイスルーにロードします。
  • また、インポート/エクスポート機能を使用して、友人とデザインを共有する機能も追加されています。


  • Saadabad Pact支店 – イラク、アフガニスタン、イラン、トルコは、彼らが互いにより協力できるようにする共有支店を手に入れています。
  • イランは、科学者や将軍を含むいくつかの余分なキャラクターと焦点を獲得しています。
  • アフガニスタンはまた、共産主義の田舎の指導者といくつかの新しいアドバイザーの形でいくつかの余分なキャラクターを獲得しています。
  • イラクのクルディスタン支店は拡大されています

私たちは、新しいフォーカス、キャラクター、イベントを追加して、複数の面で帝国のコンテンツの墓地を磨くことに一生懸命取り組んでいます。ベータ版が進むにつれて修正、コンテンツ、バランスに取り組み続けます。この間、ベータコンテンツを更新して、その時点でゲームの状態に関連する特定のフィードバックを提供する機会があることを確認することをお勧めします。
機器設計者の永続性機能は、将来ゲームの他の部分にも拡張したいと思うかもしれませんので、それについてのフィードバックをお願いします! (MTG、NSB、またはBBAが付属の機器デザイナーでは、インポート/エクスポート機能を利用できます)
スズメ そして Aveeebee

ベータパッチ1.16.5を開きます

共有可能な機器設計

– プレイスルー間でタンク、飛行機、船の設計を保存できるようになりました
– タンク、飛行機、船の設計をクリップボードにエクスポートして輸入できるようになりました

バランス

– ソビエトAIはこれで重い戦車を利用します
– リーダーが和平交渉を受け入れることを選択した場合、派ion派のリーダーの同盟国が平和になるイラン支部の戦いの一環として追加のイベントを追加しました
-MEFO請求書または征服の経済を持っている場合、消費財の工場要因を下げるために、ドイツ向けのAlt-Historyブランチにさらに多くの場所を追加しました
– ドイツ:ブレスト・リトフスクの道でドイツに領土をあきらめるアイ・リトアニアとポーランドの可能性の低下
– 歴史的な将軍はハジを追加するか、拡大し、アサダドラ・ホセインプールはイランに
– イランに政治顧問のアブドルサマド・カンバフシュ、ロックディン・モフタリ、カリム・ブザリホメリを追加しました
– イラン:フォーカス「Clash of the Titans」はゲームの開始から見えるようになりました。
– 民主的なイランに科学者、施設、画期的な進歩を獲得する機会を与えるために2つの新しい焦点を追加しました
– ゲームルールが非歴史的に設定されている場合、または国がランダムに設定されている場合、GOE諸国がより曖昧なパスが取られる可能性を低下させました
– 24の調整済みイランの焦点は70〜35日であり、時間が下がった結果、それらのいくつかに軽微な調整があります
– インド:「インドの左を集めて」35日かかります(70から減少)
– インド:「影の赤」は35日かかります(70から減少)
– インド:「ガンディズムに対するリーグ」が30の政治力を追加するようになりました
– インド:戦争支援修飾子を削除し、党の人気を減らし、60の政治力を追加しました「すべてのインドのキシャン・サバ」

ゲームプレイ

– トルコ、イラン、イラク、アフガニスタンの間に共同フォーカスツリーを追加して、サーダバードの協定を表し、トルコのコンテンツを更新して、新しい共同フォーカスツリーを説明しました
– アフガニスタン:カントリーリーダーを共産主義の道に加え、フィールドマーシャルとドイツ将軍をファシストパスに追加しました
– クロム、スチールなど、ゲー諸国にさらに多くのリソース品種を追加しました。
– インド:王子様のブレイクアウェイ国家は、南、東、北、中央、西部に細分化されたムガールの蜂起中に、より多くの領土的譲歩を得ることができます。地域のすべての状態を制御することで、ムガール側がそれらを最後に保ち、即座にそれらを埋めます。
– すでにインドのすべてをコントロールしている場合、王子の反乱にバイパスを追加しました。バイパスはあなたが通常取得する人力と戦争のサポートを与えます
– Akhand Bharatの決定で王子様の州を核とする方法を追加しました
– ユナイテッド・マグレブを新しい形成可能な国として追加しました
– イギリスのラージ、パキスタン、バングラデシュのためのカスタムエージェンシーアイコンを追加しました
– アフガニスタンのトルクメン人とタジク州は、それぞれのタグのコアになりました
– アフガニスタン:アフガニスタンの民主的支部に新たな焦点を追加して、より多くの民主的な支持を得るだけでなく、2人の新しいアドバイザーのロックを解除する
-IRAQ:AdvisorとしてMa’ruf al-Rusafiを追加しました
– イラク:イラクのクルディスタンパスに4つの焦点を追加し、クルディスタンが共産主義者に行き、コミンテルンに参加できるようにしました
– インド:共産主義者をインドとしてひっくり返す方法を作り直しました。自律システムを使用する代わりに、独立運動とイギリス人を弱体化させるために浸透の決定を解き放ち、独立運動とイギリス人を弱体化させることができます。
– インド:列車の強盗に改名された人民鉄道に改名された、それはもはや列車強盗の精神を与えず、代わりにオプションの決定を追加し、鉄道の焦点を変更する
– インド:スバス・チャンドラ・ボーズは、彼が揺れた場合、共産主義のインドのアドバイザーになることができます
– 文明のゆりかごの回復を可能にするために、クルディスタン、イラク、シリア、パレスチナ、エジプトのためにフォーマーの「メソポタミア」を追加しました
– アフガニスタン:フォーカスのためにツールチップを作り直しました。

改造

– 改造:存在しない状態へのスコープを試みたときにCTDを修正しました
– 改造:fighting_army_strength_ratioトリガーのダイナミックスコープの解析を修正しました

bugfix

– ウルガーフォーカスのスペルの問題を修正しました「すべての外部債務の返済」
– アドバイザーを削除するときに、まれなCTDを修正しました
– イギリス:シークレットインテリジェンスサービスタイプミスの修正を拡大する(グレタ戦争ではなくなった)
– インド:彼は実際にロビー議会によってロックされているので、インドの左翼の集会からアドバイザーのジム・コーベットを削除しました
– ドイツがフランスを降伏させた後にバーボンフランスをセットアップすることを選択した場合、フリーフランスはDLC La Resistanceでフォーカスツリーを取得します
– イラン:より明確にするために「抵抗を促進する」ために利用可能なトリガーを更新しました
– イラン:「ユナイテッド・プログレッシブパーティー」からロックされている将軍のロックが解除されていることを説明するツールチップが追加されました
– イラン:特定のイランのキャラクターをイデオロギーに基づいて雇用したり、完成したことに基づいて雇用できるかについてさらに制限を追加しました
– イラン:Jafar KavianとFazlollah Zahediの小さな肖像画を追加しました
– イラン:リソースの権利は、クゼスタンオイルに資源権を購入した国との戦争に参加すると再生されます
– 失われたよりも多くの機器が回収されたバグを修正しました
– スパイネットワーク修飾子が国と戦っていなくても、国に適用されたバグを修正しました
– インド:実際には255日だったとき、ムガール蜂起を終えるのに1年があると述べた誤ったツールチップを修正しました
– イラン:ソビエト連邦が派factにいなくても、「ソビエトの協力」は今や効果があります
– イラン:イランが国家の支配権を獲得した場合に彼らに譲ることができる州に適用される州の「ここでの抵抗の促進」状態修飾子を削除する
– イラン:「イラクがイラクとの戦争を宣言する」を避けるためにツールチップを修正します
– 不足している国家に不足した国家にマケドニア帝国、オスマン帝国、トラン、アクサイト帝国、アル・アンダルス、ペルシャ帝国、ビザンチン帝国、ローマ帝国、聖なるローマ帝国に追加された国に加えた
– エチオピアは、イエメンのターゲットに焦点を当てています今もアデン州を正しく標的にします
– イラン:「掘りと防御」の下で相互に排他的なブランチを修正し、崩壊しない「強制」しない
– イラン:廃止された枝を隠すかどうかをルールが設定されているかどうかを崩壊させてフォーカスブランチを修正
-Rajsの履歴ファイルでのランダムの使用に関連するOOSを修正しました
– イラクのフォーカスで作成された飛行機「代替航空機を購入する」はもう機能しない戦闘機が与えなくなりました
– インドのフォーカス「The Mughal Uprising」の説明でマイナーなタイプミスを修正しました
– イラクの欠落フォーカスフィルターを修正しました
– インディアンフォーカス「投票責任の増加のためのロビー」は、民兵攻撃に機能しないボーナスを与えなくなりました
– アフガニスタン:モハマド・ハシム・カーン、アブドゥル・ハイ・ハビビ、その他の歴史的キャラクターからのボーナスは、ツールチップのキャラクター名で正しく表示されます。
– イギリスが剥離した後、インドはもはや植民地としてとどまりません
– アフガニスタン:ジェネリックアドバイザーのシェルアリシェルカンザイ(ファシストライター)およびその他の非歴史的キャラクターからのボーナスは、ツールチップのキャラクター名で正しく表示されます。
– アフガニスタンのフォーカスツリーを介して構築されたダムを修正し、3Dモデルでマップに表示されません。
-DREADNOMATES決定ツールチップは、船が別の国から購入された場合でも、常に米国への支払いを述べていることを決定しました。
– インド:GOEが無効になった場合、Focus Institute of Fanustital Researchは、核科学者Homi J. Bhabhaに1つの科学者レベルを付与します。
– インド /マドラス:Chithira Thirunal Balarma Varmaは、カントリーリーダー、政治顧問、陸軍指導者としての彼のユニークな肖像画に現れていません。
– インド:ユニットカウンターの間違った小さなフラグを使用して、プリンセスブレイクアウェイ状態を修正しました
– アフガニスタン:Quamiの改革 – 焦点が取られた後にテクノロジーが調査された場合、サポート会社はテンプレートに追加されます。
– インド:プリンセスブレイクアウェイ州が適切な国の旗を示します
– インド:東インド会社にアドバイザーを追加して「ロビー議会」効果とツールチップ
– アフガニスタン:アフガニスタンとソビエト連邦は、「ソビエト研究協力」が採用されたときに、ハイテク共有グループに参加しています。
– アフガニスタン:アフガニスタンのチャクダムフォーカスは今や別の州に建設されました
– レバノンとクウェートを形成可能なメソポタミアに追加します
– アフガニスタン:すでに軸の一部である場合、「イギリスのラージの平原」に焦点を合わせようとすることはもうありません
– アフガニスタン:「グローバルディフェンスのリンクピン」の焦点は、現在、Quami National Spiritを正しく修正しています。
– イラン:イランが「交渉を推進する」場合、メインの扇動者のみがリソースの権利を得るが、他の攻撃者に追加の効果を追加し、すべての攻撃者が平和になることを確認し、すべての関係者に新しいフレーバーイベントを追加したことを明確にします
– イラン:イランの焦点の木にあるべきであるときに隠れていない枝を修正
– イラン:イスラム革命が起こった場合、非同盟党が実際に引き継ぐことを確認する
– イラン:「侵略者に忠誠を誓う」ために降伏の進捗要件を追加して、AIが戦争に勝ったときに降伏しないようにしました。



Source link

Views: 0

itch.ioのお勧め:手描きヒット! -itch.io


私は通常、これらの記事のテーマを計画していませんが、時々星が一致し、完璧なことが起こります。今週は、たまたま手描きのアートを持っている2つのゲームを紹介しています。ラッキー、そうですか?偶然にも、両方のゲームは絶対に素晴らしいです!これらの不思議なゲームは何でしょうか?推奨事項を完全にお読みください!

突然変異

私は永遠に感じているもののためにムタジオンをフォローしてきました。技術的には10年近くになりましたが、ゲームは長い開発サイクルで悪化することはありません。 Mutazioneについて聞いたのが初めてである場合は、心と魅力が絶対にひどい変異の文明を通して豪華な冒険を味わいましょう。

ここでは、カラフルな(文字通り、比phor的に)キャラクターのキャストがあります。想像力豊かで完全に実現したアートスタイルのゲームに興味があるなら、これはピックアップするゲームになるでしょう。ゲームの最初の部分で素晴らしい時間を過ごしましたが、ゲームの終わりからまだ数時間離れています。幸いなことに、このゲームは非常に豊かで詳細であるため、奇妙な世界で過ごす毎分を楽しんでいます。

後のワニ

ニューヨークに引っ越すワニが何を持っているのかわかりませんが、会衆全体が後のワニの都市に移動したようです。もちろん、これはいくつかの奇抜な冒険の時であることを意味します。後のワニの世界は美しいもので、ゲームの各住民に手描きのアニメーションがあります。キャラクターといえば、開発者はゲームに100を超える独特のワニがいると主張しており、私はそれを信じていませんでしたが、私はそれを信じたいと思っています。これは、私が探検に時間を費やしたことを楽しんだ創造的に解釈された世界につながります。

幸いなことに、忙しいスケジュールを持っている私たちにとって、後のワニはひどく長いゲームではありません。ほとんどのプレイヤーは、ほんの数回のプレイセッションでそれを打ち負かすことができます、そしてそれはそれにとってより良いです。ニューヨークが提供しなければならないすべてを本当に見たいなら、ゲームでより多くの時間を過ごすことができますが、そのペースは非常にきついので、ゲームでの時間の終わりに満足していると感じました。

この投稿をサポートしてください

この投稿は好きでしたか?教えてください



Source link

Views: 0

ag、“ASMR専用”完全ワイヤレスイヤホン「COTSUBU for ASMR MK2/3D」に数量限定カラー



ag、“ASMR専用”完全ワイヤレスイヤホン「COTSUBU for ASMR MK2/3D」に数量限定カラー

finalは、agブランドからASMR専用完全ワイヤレスイヤホン「COTSUBU for ASMR MK2」の新色 “BLACK(ブラック)”、および「COTSUBU for ASMR 3D」の新色 “GRAY(グレイ)” を、本日4月9日より数量限定で発売する。



Source link

Views: 0

焼きムラなし!洗練されたデザインの薄型ホットプレート「Everill」登場!



焼きムラなし!洗練されたデザインの薄型ホットプレート「Everill」登場!

アスキーストアでは、速熱性に優れたシートヒーターと焼きムラのないデザインで料理をより楽しむことができる薄型ホットプレート「Everill(エヴリル)」を発売中。



Source link

Views: 0

PGlite + pgvector で100行で実装するベクトル検索 (node/deno/drizzle)



pglite + pgvector で文章の類似度検索を実装します。

動機

とにかく手っ取り早くローカルにデータを突っ込んでおいて検索する RAG の雛形がほしかったんですが、調べても大規模ストレージを前提とした大掛かりな実装が多いです。

スクリプトを書いたらポンと実行できるセットアップ不要なものがあると、色々と実験ができます。

mastra/rag を読んでたら、簡単にできる気がしたのでやりました。ただ、chunk のドキュメント分割相当のものはまだ作ってません。そこまで難しい概念でもないので、雑に作れそうではあります。

qrdrant も検討しましたが、サーバーを建てるのが面倒でした

https://qdrant.tech/

準備: ベクトル化用の関数

今回は @ai-sdk/openai を使ってベクトル化をします


import { openai } from "@ai-sdk/openai";
import { embed } from "ai";
async function generateEmbedding(value: string): number[] {
  const { embedding } = await embed({
    model: openai.embedding("text-embedding-ada-002"),
    value,
  });
  return embedding;
}

この関数は text-embedding-ada-002 で文字列を 1536次元(長)の配列に変換します。

同じ次元のベクトル同士の類似(コサイン類似度)を取ることで、文字列同士の n 次元上の距離を測ることができます。

ここの実装はORAMAでも何でもいいですが、トランスフォーマー上の意味ベクトルの生成なので、同じモデルの同じ次元で embedding を作る必要があります。

pglite + pgvector のセットアップ

deno の node 互換モードで実装したので node でも動くはず。

pglite でデータベースを初期化します。wasmなのでドライバが不要、dataDir が与えられていないのでインメモリにストレージを展開します。


import { PGlite } from "@electric-sql/pglite";
import { vector } from "@electric-sql/pglite/vector";
import { openai } from "@ai-sdk/openai";
import { embed } from "ai";


const pglite = new PGlite({
  extensions: { vector },
  
});
await pglite.exec("CREATE EXTENSION IF NOT EXISTS vector;");


await pglite.exec(`
  CREATE TABLE IF NOT EXISTS memory (
    id SERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    embedding vector(1536)
  );
  CREATE INDEX ON memory USING hnsw (embedding vector_cosine_ops);
`);

CERATE EXTENSION vector で初期化します。text-embedding-ada-002 に合わせて 1536次元で vector 型を初期化します。

セットアップができたので、データを挿入して文書同士の距離を検索します。


async function generateEmbedding(value: string) {
  const { embedding } = await embed({
    model: openai.embedding("text-embedding-ada-002"),
    value,
  });
  return embedding;
}


const seedData = [
  "red apple",
  "green tea",
  "yellow banana",
  "pink blossom",
  "black cat",
];
for (const content of seedData) {
  const embedding = await generateEmbedding(content);
  const vec = JSON.stringify(embedding);
  await pglite.exec(
    `INSERT INTO memory (content, embedding) VALUES ('${content}', '${vec}');`
  );
}


const queryVec = await generateEmbedding("fruit");
const searchVec = JSON.stringify(queryVec);
const res = await pglite.exec(`
  SELECT
    content,
    embedding  '${searchVec}' AS distance
  FROM memory
  ORDER BY distance ASC
  LIMIT 2;`);

console.log(res[0].rows);




文書同士の距離が小さいほうが似ていることになります。一応入力から fruit っぽいものが上位にでていますね。

今回は文書が短すぎてあまり意味のある検索ができていませんが、もう少し長い文書を食わせると精度がよくなります。

pglite + pgvector

同じことを drizzle ORM でやります。

ただ、migration をスキップするために直接スキーマを定義します。ここは drizzle-kit でマイグレーションするなら不要です。


import { PGlite } from "@electric-sql/pglite";
import { vector as pgVector } from "@electric-sql/pglite/vector";
import { index, integer, pgTable, vector, text } from "drizzle-orm/pg-core";
import { drizzle, type PgliteDatabase } from "drizzle-orm/pglite";
import { openai } from "@ai-sdk/openai";
import { embed } from "ai";
import { cosineDistance, sql, desc, gt } from "drizzle-orm";


async function generateEmbedding(value: string) {
  const { embedding } = await embed({
    model: openai.embedding("text-embedding-ada-002"),
    value,
  });
  return embedding;
}


export const memory = pgTable(
  "memory",
  {
    id: integer().primaryKey().generatedAlwaysAsIdentity(),
    content: text("content").notNull(),
    embedding: vector("embedding", { dimensions: 1536 }),
  },
  (table) => [
    index("embeddingIndex").using(
      "hnsw",
      table.embedding.op("vector_cosine_ops")
    ),
  ]
);

const pglite = new PGlite({
  extensions: { vector: pgVector },
  
});
await pglite.exec("CREATE EXTENSION IF NOT EXISTS vector;");


await pglite.exec(`
  CREATE TABLE IF NOT EXISTS memory (
    id SERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    embedding vector(1536)
  );
  CREATE INDEX ON memory USING hnsw (embedding vector_cosine_ops);
`);

const db = drizzle({
  client: pglite,
  schema: { memory },
});

async function insert(content: string) {
  const embedding = await generateEmbedding(content);
  await db.insert(memory).values({
    content: content,
    embedding,
  });
}
async function query(
  text: string,
  opts: {
    threshold?: number;
    limit?: number;
  }
) {
  const embedding = await generateEmbedding(text);
  const similarity = sqlnumber>`1 - (${cosineDistance(
    memory.embedding,
    embedding
  )})`;
  return db
    .select({
      id: memory.id,
      content: memory.content,
      similarity,
    })
    .from(memory)
    .where(gt(similarity, opts.threshold ?? 0.7))
    .orderBy((t) => desc(t.similarity))
    .limit(opts.limit ?? 5);
}


await insert("red apple");
await insert("green tea");
await insert("yellow banana");
await insert("pink blossom");
await insert("black cat");


const result = await query("fruit", {
  threshold: 0.7,
  limit: 5,
});
console.log(result);

(1 - 距離) なので similarity が高いほど意味が類似しています。

Drizzle上だとここがちょっとテクニカルですが、うまく型が付いてます。偉い

  const similarity = sqlnumber>`1 - (${cosineDistance(
    memory.embedding,
    embedding
  )})`;
  return db
    .select({
      id: memory.id,
      content: memory.content,
      similarity,
    })
    .from(memory)
    .where(gt(similarity, opts.threshold ?? 0.7))
    .orderBy((t) => desc(t.similarity))
    .limit(opts.limit ?? 5);

おわり

最終的にORM付きの 100 行のコードになりました。自分は今後これを使い回すと思います。

pglite から別の postgres adapter に切り替えればプロダクション移行も簡単そうではあります。

とにかくストレージのセットアップが不要なのが嬉しく、ドライバ不要の pglite のインメモリでローカルのテストが完結します。

https://zenn.dev/mizchi/articles/deno-drizzle-pglite



Source link

Views: 0