これは「Denoを試す2」の続きです。
Denoに挑戦したそもそもの目的は「Gemini AIを使う」ことでした。Denoを試すという話題の最後に、それに挑戦しましょう。
Gemini API (Node.js版)
Gemini APIは、様々な言語で用意されています。詳しくは以下の公式サイトを参照してください。
公式サイト: https://ai.google.dev/gemini-api/docs?hl=ja
サイトで紹介されているシンプルなNode.js用のサンプルコードを以下に示します。(注意: 2024年12月ごろの情報なので、将来的には異なるサンプルコードになっているかもしれません。)
const { GoogleGenerativeAI } = require("@google/generative-ai");
const genAI = new GoogleGenerativeAI("YOUR_API_KEY");
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const prompt = "Explain how AI works";
const result = await model.generateContent(prompt);
console.log(result.response.text());
1行目で、@google/generative-ai パッケージをインポートしています。これで、Gemini API を利用できます。
なお、このパッケージを利用するためには、
npm install @google/generative-ai
でインストールしておかなくてはなりません。
3~4行目で、Gemini のAPIキーを設定し、使用する AI モデルを選択しています。
"YOUR_API_KEY"はAPIキーの文字列です。これは別途入手した文字列を記載します。
"gemini-1.5-flash"は使用するAIの種類を選択しています。
await model.generateContent(prompt); でAIに指示を出し、結果が result に格納されます。
DenoからGemini APIを使う
Node.jsのサンプルコードをDeno用に変更します。以下がそのコードです。
import { GoogleGenerativeAI } from "npm:@google/generative-ai";
const apiKey = Deno.env.get('GEMINI_API_KEY')!;
const genAI = new GoogleGenerativeAI(apiKey);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const prompt = "「赤い」から連想される単語を10個回答してください。";
const result = await model.generateContent(prompt);
console.log(result.response.text());
変更点は主に1行目です。1行目で、npm:
プレフィックスにより、npmパッケージ @google/generative-ai をDenoで利用できるようにしています。
Node.jsでは npm install
コマンドで事前にインストールする必要がありましたが、Denoでは自動でインストールされます。この簡便さは便利です。
それ以外はNode.js用コードとほとんど同じです。APIキーは環境変数GEMINI_API_KEYから取得するように変更しました。
また、プロンプトを簡潔な結果が生成されるように変更しました。
以下が実行ログです。
> deno run --allow-net --allow-env gemini1.ts
1. 赤色
2. 真紅
3. 朱色
4. 緋色
5. 薔薇色
6. 血
7. 炎
8. トマト
9. 危険
10. 情熱
なお、AIの出力はランダム要素を含むため、同じプロンプトでも毎回同じ結果が返るとは限りません。
サーバー化してみる
AIに送る指示を変更したいとき、上のプログラムでは、コードを直接変更する必要があります。これは不便です。
そこでAIへの指示をDenoサーバーに送り、結果を返すようにします。
UIなどの構築まで行うと作業が増えるため、今回は簡潔にURLパラメータで指示を受け取るようにしました。以下がコードです。
import { render } from "npm:preact-render-to-string";
import { GoogleGenerativeAI } from "npm:@google/generative-ai";
const apiKey = Deno.env.get('GEMINI_API_KEY')!;
const genAI = new GoogleGenerativeAI(apiKey);
async function sendPromptToAI(prompt: string | null) {
if (prompt === null) {
return 'プロンプトがありません';
}
try {
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const result = await model.generateContent(prompt);
return result.response.text();
} catch (error) {
return `エラーが発生しました。: ${(error as Error).message}`;
}
}
Deno.serve(handler);
const AiResult = (props: { prompt: string | null, result: string }) => {
const prompt = props.prompt;
if (!prompt) {
return (<div>プロンプトがありません。</div>);
}
const results = props.result.split(/\n/);
return (
<>
<div>プロンプト:</div>
<div>{props.prompt}</div>
<div>結果:</div>
{results.map(line => <div>{line}</div>)}
</>
);
}
async function handler(req: Request) {
const url = new URL(req.url);
const prompt = url.searchParams.get("prompt");
const result = await sendPromptToAI(prompt);
const html = `
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello, world!</title>
</head>
<body>
${render(<AiResult prompt={prompt} result={result} />)}
</body>
</html>
`;
return new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } })
}
コードの概要を説明します。
このコードは、「Denoを試す2」で作成したPreactを使ったWebサーバーをベースに、Gemini APIへのリクエスト処理を追加したものです。
Deno.serve()でDenoサーバーを実行しています。
handler()関数内でURLパラメータをチェックし、AIに送信するプロンプト文字列を取得しています。
sendPromptToAI()関数内でGemini APIを使って、AIへプロンプトを送信し、結果を返しています。
最終的にPreactを使って、プロンプトとAIの結果をHTML化し、クライアントに送信しています。
以下は、Denoでサーバーを立ち上げた後、ブラウザに、
localhost:8000/?prompt=Denoについて200文字で説明して
とURLを入力したときに、ブラウザに返されたHTMLです。(コード中のrender()関数が作成する部分だけ記載しています。)
<div>プロンプト:</div>
<div>Denoについて200文字で説明して</div>
<div>結果:</div>
<div>Denoは、Node.jsの開発者によって作られた、安全で現代的なJavaScriptおよびTypeScriptランタイムです。V8 JavaScriptエンジンとRustで構築され、Node.jsと比べて多くの改善が施されています。</div>
<div></div>
<div>主な特徴として、セキュリティ重視の設計(デフォルトでネットワークアクセスやファイルシステムアクセスを制限)、TypeScriptのネイティブサポート、標準モジュールシステムによる依存関係管理の簡素化、シングル実行ファイルによる配布の容易さなどが挙げられます。 Node.jsからの移行も比較的容易で、特にセキュリティとモダンな機能を重視する開発に適しています。</div>
<div></div>
今回の例はURLパラメータを使いましたが、実用的なものにするにはもっと長いプロンプトを使うことができるようにする必要があります。そのためには、UIを整え、JSONデータでブラウザとDenoサーバーがプロンプトと結果を送受信するようにした方が良いでしょう。
コメント